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#include "pub_core_debuginfo.h"
35b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
36b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "valgrind_low.h"
37b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
38b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "libvex_guest_arm.h"
39b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
40b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstruct reg regs[] = {
41b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "r0", 0, 32 },
42b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "r1", 32, 32 },
43b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "r2", 64, 32 },
44b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "r3", 96, 32 },
45b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "r4", 128, 32 },
46b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "r5", 160, 32 },
47b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "r6", 192, 32 },
48b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "r7", 224, 32 },
49b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "r8", 256, 32 },
50b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "r9", 288, 32 },
51b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "r10", 320, 32 },
52b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "r11", 352, 32 },
53b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "r12", 384, 32 },
54b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "sp", 416, 32 },
55b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "lr", 448, 32 },
56b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "pc", 480, 32 },
57b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "", 512, 0 }, // It seems these entries are needed
58b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "", 512, 0 }, // as previous versions of arm <-> gdb placed
59b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "", 512, 0 }, // some floating point registers here. So, cpsr
60b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "", 512, 0 }, // must be register 25.
61b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "", 512, 0 },
62b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "", 512, 0 },
63b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "", 512, 0 },
64b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "", 512, 0 },
65b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "", 512, 0 },
66b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "cpsr", 512, 32 },
67b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "d0", 544, 64 },
68b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "d1", 608, 64 },
69b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "d2", 672, 64 },
70b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "d3", 736, 64 },
71b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "d4", 800, 64 },
72b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "d5", 864, 64 },
73b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "d6", 928, 64 },
74b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "d7", 992, 64 },
75b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "d8", 1056, 64 },
76b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "d9", 1120, 64 },
77b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "d10", 1184, 64 },
78b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "d11", 1248, 64 },
79b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "d12", 1312, 64 },
80b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "d13", 1376, 64 },
81b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "d14", 1440, 64 },
82b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "d15", 1504, 64 },
83b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "d16", 1568, 64 },
84b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "d17", 1632, 64 },
85b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "d18", 1696, 64 },
86b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "d19", 1760, 64 },
87b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "d20", 1824, 64 },
88b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "d21", 1888, 64 },
89b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "d22", 1952, 64 },
90b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "d23", 2016, 64 },
91b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "d24", 2080, 64 },
92b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "d25", 2144, 64 },
93b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "d26", 2208, 64 },
94b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "d27", 2272, 64 },
95b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "d28", 2336, 64 },
96b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "d29", 2400, 64 },
97b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "d30", 2464, 64 },
98b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "d31", 2528, 64 },
99b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov  { "fpscr", 2592, 32 }
100b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov};
101b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic const char *expedite_regs[] = { "r11", "sp", "pc", 0 };
102b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define num_regs (sizeof (regs) / sizeof (regs[0]))
103b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
104b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic
105b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovCORE_ADDR get_pc (void)
106b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
107b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   unsigned long pc;
108b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
109b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   collect_register_by_name ("pc", &pc);
110b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
111b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   dlog(1, "stop pc is %p\n", (void *) pc);
112b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return pc;
113b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
114b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
115b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic
116b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid set_pc (CORE_ADDR newpc)
117b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
118b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Bool mod;
119b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   supply_register_by_name ("pc", &newpc, &mod);
120b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (mod)
121b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      dlog(1, "set pc to %p\n", C2v (newpc));
122b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   else
123b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      dlog(1, "set pc not changed %p\n", C2v (newpc));
124b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
125b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
126b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovAddr thumb_pc (Addr pc)
127b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
128b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   // If the thumb bit (bit 0) is already set, we trust it.
129b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (pc & 1) {
130b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      dlog (1, "%p = thumb (bit0 is set)\n", C2v (pc));
131b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return pc;
132b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
133b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
134b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   // Here, bit 0 is not set.
135b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   // For a pc aligned on 4 bytes, we have to use the debug
136b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   // info to determine the thumb-ness.
137b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   // else (aligned on 2 bytes), we trust this is a thumb
138b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   // address and we set the thumb bit.
139b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
140b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (pc & 2) {
141b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      dlog (1, "bit0 not set, bit1 set => %p = thumb\n", C2v (pc));
142b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return pc | 1;
143b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
144b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
145b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   // pc aligned on 4 bytes. We need to use debug info.
146b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   {
147b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Char fnname[200]; // ??? max size
148b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Addr entrypoint;
149b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Addr ptoc; // unused but needed.
150b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      // If this is a thumb instruction, we need to ask
151b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      // the debug info with the bit0 set
152b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      // (why can't debug info do that for us ???)
153b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      // (why if this is a 4 bytes thumb instruction ???)
154b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (VG_(get_fnname_raw) (pc | 1, fnname, 200)) {
155b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (VG_(lookup_symbol_SLOW)( "*", fnname, &entrypoint, &ptoc )) {
156b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            dlog (1, "fnname %s lookupsym %p => %p %s.\n",
157b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                  fnname, C2v(entrypoint), C2v(pc),
158b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                  (entrypoint & 1 ? "thumb" : "arm"));
159b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            if (entrypoint & 1)
160b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               return pc | 1;
161b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            else
162b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               return pc;
163b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
164b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         } else {
165b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            dlog (1, "%p fnname %s lookupsym failed?. Assume arm\n",
166b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                  C2v (pc), fnname);
167b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            return pc;
168b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         }
169b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      } else {
170b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         // Can't find function name. We assume this is arm
171b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         dlog (1, "%p unknown fnname?. Assume arm\n", C2v (pc));
172b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         return pc;
173b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
174b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
175b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
176b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
177b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* store registers in the guest state (gdbserver_to_valgrind)
178b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   or fetch register from the guest state (valgrind_to_gdbserver). */
179b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic
180b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid transfer_register (ThreadId tid, int abs_regno, void * buf,
181b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        transfer_direction dir, int size, Bool *mod)
182b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
183b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ThreadState* tst = VG_(get_ThreadState)(tid);
184b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int set = abs_regno / num_regs;
185b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   int regno = abs_regno % num_regs;
186b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *mod = False;
187b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
188b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VexGuestARMState* arm = (VexGuestARMState*) get_arch (set, tst);
189b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
190b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   switch (regno) {
191b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   // numbers here have to match the order of regs above
192b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   // Attention: gdb order does not match valgrind order.
193b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 0:  VG_(transfer) (&arm->guest_R0,   buf, dir, size, mod); break;
194b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 1:  VG_(transfer) (&arm->guest_R1,   buf, dir, size, mod); break;
195b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 2:  VG_(transfer) (&arm->guest_R2,   buf, dir, size, mod); break;
196b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 3:  VG_(transfer) (&arm->guest_R3,   buf, dir, size, mod); break;
197b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 4:  VG_(transfer) (&arm->guest_R4,   buf, dir, size, mod); break;
198b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 5:  VG_(transfer) (&arm->guest_R5,   buf, dir, size, mod); break;
199b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 6:  VG_(transfer) (&arm->guest_R6,   buf, dir, size, mod); break;
200b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 7:  VG_(transfer) (&arm->guest_R7,   buf, dir, size, mod); break;
201b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 8:  VG_(transfer) (&arm->guest_R8,   buf, dir, size, mod); break;
202b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 9:  VG_(transfer) (&arm->guest_R9,   buf, dir, size, mod); break;
203b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 10: VG_(transfer) (&arm->guest_R10,  buf, dir, size, mod); break;
204b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 11: VG_(transfer) (&arm->guest_R11,  buf, dir, size, mod); break;
205b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 12: VG_(transfer) (&arm->guest_R12,  buf, dir, size, mod); break;
206b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 13: VG_(transfer) (&arm->guest_R13,  buf, dir, size, mod); break;
207b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 14: VG_(transfer) (&arm->guest_R14,  buf, dir, size, mod); break;
208b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 15: {
209b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(transfer) (&arm->guest_R15T, buf, dir, size, mod);
210b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (dir == gdbserver_to_valgrind && *mod) {
211b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         // If gdb is changing the PC, we have to set the thumb bit
212b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         // if needed.
213b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         arm->guest_R15T = thumb_pc(arm->guest_R15T);
214b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
215b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      break;
216b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
217b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 16:
218b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 17:
219b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 18:
220b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 19:
221b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 20: /* 9 "empty registers". See struct reg regs above. */
222b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 21:
223b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 22:
224b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 23:
225b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 24: *mod = False; break;
226b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 25: {
227b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      UInt cpsr = LibVEX_GuestARM_get_cpsr (arm);
228b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (dir == valgrind_to_gdbserver) {
229b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(transfer) (&cpsr, buf, dir, size, mod);
230b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      } else {
231b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#      if 0
232b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         UInt newcpsr;
233b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(transfer) (&newcpsr, buf, dir, size, mod);
234b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         *mod = newcpsr != cpsr;
235b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         // GDBTD ???? see FIXME in guest_arm_helpers.c
236b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         LibVEX_GuestARM_put_flags (newcpsr, arm);
237b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#      else
238b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         *mod = False;
239b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#      endif
240b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
241b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      break;
242b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
243b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 26: VG_(transfer) (&arm->guest_D0,  buf, dir, size, mod); break;
244b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 27: VG_(transfer) (&arm->guest_D1,  buf, dir, size, mod); break;
245b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 28: VG_(transfer) (&arm->guest_D2,  buf, dir, size, mod); break;
246b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 29: VG_(transfer) (&arm->guest_D3,  buf, dir, size, mod); break;
247b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 30: VG_(transfer) (&arm->guest_D4,  buf, dir, size, mod); break;
248b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 31: VG_(transfer) (&arm->guest_D5,  buf, dir, size, mod); break;
249b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 32: VG_(transfer) (&arm->guest_D6,  buf, dir, size, mod); break;
250b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 33: VG_(transfer) (&arm->guest_D7,  buf, dir, size, mod); break;
251b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 34: VG_(transfer) (&arm->guest_D8,  buf, dir, size, mod); break;
252b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 35: VG_(transfer) (&arm->guest_D9,  buf, dir, size, mod); break;
253b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 36: VG_(transfer) (&arm->guest_D10, buf, dir, size, mod); break;
254b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 37: VG_(transfer) (&arm->guest_D11, buf, dir, size, mod); break;
255b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 38: VG_(transfer) (&arm->guest_D12, buf, dir, size, mod); break;
256b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 39: VG_(transfer) (&arm->guest_D13, buf, dir, size, mod); break;
257b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 40: VG_(transfer) (&arm->guest_D14, buf, dir, size, mod); break;
258b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 41: VG_(transfer) (&arm->guest_D15, buf, dir, size, mod); break;
259b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 42: VG_(transfer) (&arm->guest_D16, buf, dir, size, mod); break;
260b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 43: VG_(transfer) (&arm->guest_D17, buf, dir, size, mod); break;
261b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 44: VG_(transfer) (&arm->guest_D18, buf, dir, size, mod); break;
262b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 45: VG_(transfer) (&arm->guest_D19, buf, dir, size, mod); break;
263b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 46: VG_(transfer) (&arm->guest_D20, buf, dir, size, mod); break;
264b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 47: VG_(transfer) (&arm->guest_D21, buf, dir, size, mod); break;
265b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 48: VG_(transfer) (&arm->guest_D22, buf, dir, size, mod); break;
266b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 49: VG_(transfer) (&arm->guest_D23, buf, dir, size, mod); break;
267b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 50: VG_(transfer) (&arm->guest_D24, buf, dir, size, mod); break;
268b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 51: VG_(transfer) (&arm->guest_D25, buf, dir, size, mod); break;
269b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 52: VG_(transfer) (&arm->guest_D26, buf, dir, size, mod); break;
270b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 53: VG_(transfer) (&arm->guest_D27, buf, dir, size, mod); break;
271b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 54: VG_(transfer) (&arm->guest_D28, buf, dir, size, mod); break;
272b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 55: VG_(transfer) (&arm->guest_D29, buf, dir, size, mod); break;
273b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 56: VG_(transfer) (&arm->guest_D30, buf, dir, size, mod); break;
274b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 57: VG_(transfer) (&arm->guest_D31, buf, dir, size, mod); break;
275b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   case 58: VG_(transfer) (&arm->guest_FPSCR, buf, dir, size, mod); break;
276b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   default: vg_assert(0);
277b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
278b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
279b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
280b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic struct valgrind_target_ops low_target = {
281b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   num_regs,
282b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   regs,
283b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   13, //SP
284b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   transfer_register,
285b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   get_pc,
286b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   set_pc,
287b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   "arm",
288b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   "arm-with-vfpv3.xml",
289b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   "arm-with-vfpv3-valgrind.xml"
290b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov};
291b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
292b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid arm_init_architecture (struct valgrind_target_ops *target)
293b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
294b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *target = low_target;
295b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   set_register_cache (regs, num_regs);
296b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   gdbserver_expedite_regs = expedite_regs;
297b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
298