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