* server.c (handle_query) <qSupported>: Do two passes over the
[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 63
45ba0d02
PA
64 if (regcache == NULL)
65 return;
66
0d62e5e8
DJ
67 if (regcache->registers_valid)
68 {
69 struct thread_info *saved_inferior = current_inferior;
70
71 current_inferior = thread;
442ea881 72 store_inferior_registers (regcache, -1);
0d62e5e8
DJ
73 current_inferior = saved_inferior;
74 }
75
76 regcache->registers_valid = 0;
77}
78
79void
442ea881 80regcache_invalidate (void)
0d62e5e8
DJ
81{
82 for_each_inferior (&all_threads, regcache_invalidate_one);
83}
84
219f2f23
PA
85struct regcache *
86init_register_cache (struct regcache *regcache, unsigned char *regbuf)
87{
88 if (regbuf == NULL)
89 {
90 /* Make sure to zero-initialize the register cache when it is
91 created, in case there are registers the target never
92 fetches. This way they'll read as zero instead of
93 garbage. */
94 regcache->registers = xcalloc (1, register_bytes);
95 regcache->registers_owned = 1;
96 }
97 else
98 {
99 regcache->registers = regbuf;
100 regcache->registers_owned = 0;
101 }
102
103 regcache->registers_valid = 0;
104
105 return regcache;
106}
107
442ea881 108struct regcache *
0d62e5e8 109new_register_cache (void)
c04a1aa8 110{
442ea881 111 struct regcache *regcache;
c04a1aa8 112
5822d809
PA
113 if (register_bytes == 0)
114 return NULL; /* The architecture hasn't been initialized yet. */
115
bca929d3 116 regcache = xmalloc (sizeof (*regcache));
219f2f23 117 return init_register_cache (regcache, NULL);
c04a1aa8
DJ
118}
119
120void
442ea881 121free_register_cache (struct regcache *regcache)
c04a1aa8 122{
5822d809
PA
123 if (regcache)
124 {
125 free (regcache->registers);
126 free (regcache);
127 }
c04a1aa8
DJ
128}
129
219f2f23
PA
130void
131regcache_cpy (struct regcache *dst, struct regcache *src)
132{
133 memcpy (dst->registers, src->registers, register_bytes);
134 dst->registers_valid = src->registers_valid;
135}
136
d61ddec4
UW
137static void
138realloc_register_cache (struct inferior_list_entry *thread_p)
139{
140 struct thread_info *thread = (struct thread_info *) thread_p;
442ea881
PA
141 struct regcache *regcache
142 = (struct regcache *) inferior_regcache_data (thread);
d61ddec4 143
5d267c4c
PA
144 if (regcache != NULL)
145 regcache_invalidate_one (thread_p);
442ea881 146 free_register_cache (regcache);
d61ddec4
UW
147 set_inferior_regcache_data (thread, new_register_cache ());
148}
149
0a30fbc4
DJ
150void
151set_register_cache (struct reg *regs, int n)
152{
153 int offset, i;
1b3f6016 154
45ba0d02
PA
155 /* Before changing the register cache internal layout, flush the
156 contents of valid caches back to the threads. */
157 regcache_invalidate ();
158
0a30fbc4
DJ
159 reg_defs = regs;
160 num_registers = n;
161
162 offset = 0;
163 for (i = 0; i < n; i++)
164 {
165 regs[i].offset = offset;
166 offset += regs[i].size;
167 }
168
169 register_bytes = offset / 8;
d61ddec4 170
bb9c3d36
UW
171 /* Make sure PBUFSIZ is large enough to hold a full register packet. */
172 if (2 * register_bytes + 32 > PBUFSIZ)
173 fatal ("Register packet size exceeds PBUFSIZ.");
174
d61ddec4
UW
175 /* Re-allocate all pre-existing register caches. */
176 for_each_inferior (&all_threads, realloc_register_cache);
0a30fbc4
DJ
177}
178
219f2f23
PA
179int
180register_cache_size (void)
181{
182 return register_bytes;
183}
184
0a30fbc4 185void
442ea881 186registers_to_string (struct regcache *regcache, char *buf)
0a30fbc4 187{
442ea881 188 unsigned char *registers = regcache->registers;
c04a1aa8 189
0a30fbc4
DJ
190 convert_int_to_ascii (registers, buf, register_bytes);
191}
192
193void
442ea881 194registers_from_string (struct regcache *regcache, char *buf)
0a30fbc4
DJ
195{
196 int len = strlen (buf);
442ea881 197 unsigned char *registers = regcache->registers;
0a30fbc4
DJ
198
199 if (len != register_bytes * 2)
200 {
1b3f6016
PA
201 warning ("Wrong sized register packet (expected %d bytes, got %d)",
202 2*register_bytes, len);
0a30fbc4
DJ
203 if (len > register_bytes * 2)
204 len = register_bytes * 2;
205 }
206 convert_ascii_to_int (buf, registers, len / 2);
207}
208
209struct reg *
210find_register_by_name (const char *name)
211{
212 int i;
213
214 for (i = 0; i < num_registers; i++)
215 if (!strcmp (name, reg_defs[i].name))
216 return &reg_defs[i];
217 fatal ("Unknown register %s requested", name);
218 return 0;
219}
220
221int
222find_regno (const char *name)
223{
224 int i;
225
226 for (i = 0; i < num_registers; i++)
227 if (!strcmp (name, reg_defs[i].name))
228 return i;
229 fatal ("Unknown register %s requested", name);
230 return -1;
231}
232
233struct reg *
234find_register_by_number (int n)
235{
236 return &reg_defs[n];
237}
238
239int
240register_size (int n)
241{
242 return reg_defs[n].size / 8;
243}
244
f450004a 245static unsigned char *
442ea881 246register_data (struct regcache *regcache, int n, int fetch)
0a30fbc4 247{
442ea881 248 return regcache->registers + (reg_defs[n].offset / 8);
0a30fbc4
DJ
249}
250
58caa3dc 251void
442ea881 252supply_register (struct regcache *regcache, int n, const void *buf)
58caa3dc 253{
3327ccf7
L
254 if (buf)
255 memcpy (register_data (regcache, n, 0), buf, register_size (n));
256 else
257 memset (register_data (regcache, n, 0), 0, register_size (n));
58caa3dc
DJ
258}
259
219f2f23
PA
260void
261supply_regblock (struct regcache *regcache, const void *buf)
262{
263 if (buf)
264 memcpy (regcache->registers, buf, register_bytes);
265 else
266 memset (regcache->registers, 0, register_bytes);
267}
268
58caa3dc 269void
442ea881
PA
270supply_register_by_name (struct regcache *regcache,
271 const char *name, const void *buf)
58caa3dc 272{
442ea881 273 supply_register (regcache, find_regno (name), buf);
58caa3dc
DJ
274}
275
276void
442ea881 277collect_register (struct regcache *regcache, int n, void *buf)
58caa3dc 278{
442ea881 279 memcpy (buf, register_data (regcache, n, 1), register_size (n));
0d62e5e8
DJ
280}
281
282void
442ea881 283collect_register_as_string (struct regcache *regcache, int n, char *buf)
0d62e5e8 284{
442ea881
PA
285 convert_int_to_ascii (register_data (regcache, n, 1),
286 buf, register_size (n));
58caa3dc
DJ
287}
288
289void
442ea881
PA
290collect_register_by_name (struct regcache *regcache,
291 const char *name, void *buf)
58caa3dc 292{
442ea881 293 collect_register (regcache, find_regno (name), buf);
58caa3dc 294}
219f2f23
PA
295
296/* Special handling for register PC. */
297
298CORE_ADDR
299regcache_read_pc (struct regcache *regcache)
300{
301 CORE_ADDR pc_val;
302
303 if (the_target->read_pc)
304 pc_val = the_target->read_pc (regcache);
305 else
306 internal_error (__FILE__, __LINE__,
307 "regcache_read_pc: Unable to find PC");
308
309 return pc_val;
310}
311
312void
313regcache_write_pc (struct regcache *regcache, CORE_ADDR pc)
314{
315 if (the_target->write_pc)
316 the_target->write_pc (regcache, pc);
317 else
318 internal_error (__FILE__, __LINE__,
319 "regcache_write_pc: Unable to update PC");
320}
This page took 0.903775 seconds and 4 git commands to generate.