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