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