Add qsupported to gdbarch.
[deliverable/binutils-gdb.git] / gdb / gdbserver / regcache.c
CommitLineData
0a30fbc4 1/* Register support routines for the remote server for GDB.
4c38e0a4 2 Copyright (C) 2001, 2002, 2004, 2005, 2007, 2008, 2009, 2010
9b254dd1 3 Free Software Foundation, Inc.
0a30fbc4
DJ
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
0a30fbc4
DJ
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
0a30fbc4
DJ
19
20#include "server.h"
21#include "regdef.h"
22
23#include <stdlib.h>
24#include <string.h>
25
0a30fbc4
DJ
26static int register_bytes;
27
28static struct reg *reg_defs;
29static int num_registers;
30
31const char **gdbserver_expedite_regs;
32
442ea881
PA
33struct regcache *
34get_thread_regcache (struct thread_info *thread, int fetch)
c04a1aa8 35{
442ea881 36 struct regcache *regcache;
c04a1aa8 37
442ea881 38 regcache = (struct regcache *) inferior_regcache_data (thread);
c04a1aa8
DJ
39
40 if (regcache == NULL)
41 fatal ("no register cache");
42
0d62e5e8
DJ
43 if (fetch && regcache->registers_valid == 0)
44 {
442ea881
PA
45 struct thread_info *saved_inferior = current_inferior;
46
47 current_inferior = thread;
48 fetch_inferior_registers (regcache, -1);
49 current_inferior = saved_inferior;
0d62e5e8
DJ
50 regcache->registers_valid = 1;
51 }
52
c04a1aa8
DJ
53 return regcache;
54}
55
0d62e5e8
DJ
56void
57regcache_invalidate_one (struct inferior_list_entry *entry)
58{
59 struct thread_info *thread = (struct thread_info *) entry;
442ea881 60 struct regcache *regcache;
0d62e5e8 61
442ea881 62 regcache = (struct regcache *) inferior_regcache_data (thread);
0d62e5e8
DJ
63
64 if (regcache->registers_valid)
65 {
66 struct thread_info *saved_inferior = current_inferior;
67
68 current_inferior = thread;
442ea881 69 store_inferior_registers (regcache, -1);
0d62e5e8
DJ
70 current_inferior = saved_inferior;
71 }
72
73 regcache->registers_valid = 0;
74}
75
76void
442ea881 77regcache_invalidate (void)
0d62e5e8
DJ
78{
79 for_each_inferior (&all_threads, regcache_invalidate_one);
80}
81
442ea881 82struct regcache *
0d62e5e8 83new_register_cache (void)
c04a1aa8 84{
442ea881 85 struct regcache *regcache;
c04a1aa8 86
5822d809
PA
87 if (register_bytes == 0)
88 return NULL; /* The architecture hasn't been initialized yet. */
89
bca929d3 90 regcache = xmalloc (sizeof (*regcache));
c04a1aa8 91
442ea881
PA
92 /* Make sure to zero-initialize the register cache when it is
93 created, in case there are registers the target never
94 fetches. This way they'll read as zero instead of
95 garbage. */
bca929d3 96 regcache->registers = xcalloc (1, register_bytes);
c04a1aa8 97
0d62e5e8
DJ
98 regcache->registers_valid = 0;
99
100 return regcache;
c04a1aa8
DJ
101}
102
103void
442ea881 104free_register_cache (struct regcache *regcache)
c04a1aa8 105{
5822d809
PA
106 if (regcache)
107 {
108 free (regcache->registers);
109 free (regcache);
110 }
c04a1aa8
DJ
111}
112
d61ddec4
UW
113static void
114realloc_register_cache (struct inferior_list_entry *thread_p)
115{
116 struct thread_info *thread = (struct thread_info *) thread_p;
442ea881
PA
117 struct regcache *regcache
118 = (struct regcache *) inferior_regcache_data (thread);
d61ddec4 119
442ea881 120 free_register_cache (regcache);
d61ddec4
UW
121 set_inferior_regcache_data (thread, new_register_cache ());
122}
123
0a30fbc4
DJ
124void
125set_register_cache (struct reg *regs, int n)
126{
127 int offset, i;
1b3f6016 128
0a30fbc4
DJ
129 reg_defs = regs;
130 num_registers = n;
131
132 offset = 0;
133 for (i = 0; i < n; i++)
134 {
135 regs[i].offset = offset;
136 offset += regs[i].size;
137 }
138
139 register_bytes = offset / 8;
d61ddec4 140
bb9c3d36
UW
141 /* Make sure PBUFSIZ is large enough to hold a full register packet. */
142 if (2 * register_bytes + 32 > PBUFSIZ)
143 fatal ("Register packet size exceeds PBUFSIZ.");
144
d61ddec4
UW
145 /* Re-allocate all pre-existing register caches. */
146 for_each_inferior (&all_threads, realloc_register_cache);
0a30fbc4
DJ
147}
148
149void
442ea881 150registers_to_string (struct regcache *regcache, char *buf)
0a30fbc4 151{
442ea881 152 unsigned char *registers = regcache->registers;
c04a1aa8 153
0a30fbc4
DJ
154 convert_int_to_ascii (registers, buf, register_bytes);
155}
156
157void
442ea881 158registers_from_string (struct regcache *regcache, char *buf)
0a30fbc4
DJ
159{
160 int len = strlen (buf);
442ea881 161 unsigned char *registers = regcache->registers;
0a30fbc4
DJ
162
163 if (len != register_bytes * 2)
164 {
1b3f6016
PA
165 warning ("Wrong sized register packet (expected %d bytes, got %d)",
166 2*register_bytes, len);
0a30fbc4
DJ
167 if (len > register_bytes * 2)
168 len = register_bytes * 2;
169 }
170 convert_ascii_to_int (buf, registers, len / 2);
171}
172
173struct reg *
174find_register_by_name (const char *name)
175{
176 int i;
177
178 for (i = 0; i < num_registers; i++)
179 if (!strcmp (name, reg_defs[i].name))
180 return &reg_defs[i];
181 fatal ("Unknown register %s requested", name);
182 return 0;
183}
184
185int
186find_regno (const char *name)
187{
188 int i;
189
190 for (i = 0; i < num_registers; i++)
191 if (!strcmp (name, reg_defs[i].name))
192 return i;
193 fatal ("Unknown register %s requested", name);
194 return -1;
195}
196
197struct reg *
198find_register_by_number (int n)
199{
200 return &reg_defs[n];
201}
202
203int
204register_size (int n)
205{
206 return reg_defs[n].size / 8;
207}
208
f450004a 209static unsigned char *
442ea881 210register_data (struct regcache *regcache, int n, int fetch)
0a30fbc4 211{
442ea881 212 return regcache->registers + (reg_defs[n].offset / 8);
0a30fbc4
DJ
213}
214
58caa3dc 215void
442ea881 216supply_register (struct regcache *regcache, int n, const void *buf)
58caa3dc 217{
442ea881 218 memcpy (register_data (regcache, n, 0), buf, register_size (n));
58caa3dc
DJ
219}
220
221void
442ea881
PA
222supply_register_by_name (struct regcache *regcache,
223 const char *name, const void *buf)
58caa3dc 224{
442ea881 225 supply_register (regcache, find_regno (name), buf);
58caa3dc
DJ
226}
227
228void
442ea881 229collect_register (struct regcache *regcache, int n, void *buf)
58caa3dc 230{
442ea881 231 memcpy (buf, register_data (regcache, n, 1), register_size (n));
0d62e5e8
DJ
232}
233
234void
442ea881 235collect_register_as_string (struct regcache *regcache, int n, char *buf)
0d62e5e8 236{
442ea881
PA
237 convert_int_to_ascii (register_data (regcache, n, 1),
238 buf, register_size (n));
58caa3dc
DJ
239}
240
241void
442ea881
PA
242collect_register_by_name (struct regcache *regcache,
243 const char *name, void *buf)
58caa3dc 244{
442ea881 245 collect_register (regcache, find_regno (name), buf);
58caa3dc 246}
This page took 0.579072 seconds and 4 git commands to generate.