gdb/gdbserver:
[deliverable/binutils-gdb.git] / gdb / gdbserver / regcache.c
1 /* Register support routines for the remote server for GDB.
2 Copyright (C) 2001-2002, 2004-2005, 2007-2012 Free Software
3 Foundation, Inc.
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
9 the Free Software Foundation; either version 3 of the License, or
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
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20 #include "server.h"
21 #include "regdef.h"
22 #include "gdbthread.h"
23
24 #include <stdlib.h>
25 #include <string.h>
26
27 static int register_bytes;
28
29 static struct reg *reg_defs;
30 static int num_registers;
31
32 const char **gdbserver_expedite_regs;
33
34 #ifndef IN_PROCESS_AGENT
35
36 struct regcache *
37 get_thread_regcache (struct thread_info *thread, int fetch)
38 {
39 struct regcache *regcache;
40
41 regcache = (struct regcache *) inferior_regcache_data (thread);
42
43 if (regcache == NULL)
44 fatal ("no register cache");
45
46 if (fetch && regcache->registers_valid == 0)
47 {
48 struct thread_info *saved_inferior = current_inferior;
49
50 current_inferior = thread;
51 fetch_inferior_registers (regcache, -1);
52 current_inferior = saved_inferior;
53 regcache->registers_valid = 1;
54 }
55
56 return regcache;
57 }
58
59 void
60 regcache_invalidate_one (struct inferior_list_entry *entry)
61 {
62 struct thread_info *thread = (struct thread_info *) entry;
63 struct regcache *regcache;
64
65 regcache = (struct regcache *) inferior_regcache_data (thread);
66
67 if (regcache == NULL)
68 return;
69
70 if (regcache->registers_valid)
71 {
72 struct thread_info *saved_inferior = current_inferior;
73
74 current_inferior = thread;
75 store_inferior_registers (regcache, -1);
76 current_inferior = saved_inferior;
77 }
78
79 regcache->registers_valid = 0;
80 }
81
82 void
83 regcache_invalidate (void)
84 {
85 for_each_inferior (&all_threads, regcache_invalidate_one);
86 }
87
88 #endif
89
90 struct regcache *
91 init_register_cache (struct regcache *regcache, unsigned char *regbuf)
92 {
93 #ifndef IN_PROCESS_AGENT
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;
102 regcache->register_status = xcalloc (1, num_registers);
103 gdb_assert (REG_UNAVAILABLE == 0);
104 }
105 else
106 #else
107 if (regbuf == NULL)
108 fatal ("init_register_cache: can't allocate memory from the heap");
109 else
110 #endif
111 {
112 regcache->registers = regbuf;
113 regcache->registers_owned = 0;
114 #ifndef IN_PROCESS_AGENT
115 regcache->register_status = NULL;
116 #endif
117 }
118
119 regcache->registers_valid = 0;
120
121 return regcache;
122 }
123
124 #ifndef IN_PROCESS_AGENT
125
126 struct regcache *
127 new_register_cache (void)
128 {
129 struct regcache *regcache;
130
131 if (register_bytes == 0)
132 return NULL; /* The architecture hasn't been initialized yet. */
133
134 regcache = xmalloc (sizeof (*regcache));
135 return init_register_cache (regcache, NULL);
136 }
137
138 void
139 free_register_cache (struct regcache *regcache)
140 {
141 if (regcache)
142 {
143 if (regcache->registers_owned)
144 free (regcache->registers);
145 free (regcache->register_status);
146 free (regcache);
147 }
148 }
149
150 #endif
151
152 void
153 regcache_cpy (struct regcache *dst, struct regcache *src)
154 {
155 memcpy (dst->registers, src->registers, register_bytes);
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
160 dst->registers_valid = src->registers_valid;
161 }
162
163 #ifndef IN_PROCESS_AGENT
164 static void
165 realloc_register_cache (struct inferior_list_entry *thread_p)
166 {
167 struct thread_info *thread = (struct thread_info *) thread_p;
168 struct regcache *regcache
169 = (struct regcache *) inferior_regcache_data (thread);
170
171 if (regcache != NULL)
172 regcache_invalidate_one (thread_p);
173 free_register_cache (regcache);
174 set_inferior_regcache_data (thread, new_register_cache ());
175 }
176 #endif
177
178 void
179 set_register_cache (struct reg *regs, int n)
180 {
181 int offset, i;
182
183 #ifndef IN_PROCESS_AGENT
184 /* Before changing the register cache internal layout, flush the
185 contents of valid caches back to the threads. */
186 regcache_invalidate ();
187 #endif
188
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;
200
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
205 #ifndef IN_PROCESS_AGENT
206 /* Re-allocate all pre-existing register caches. */
207 for_each_inferior (&all_threads, realloc_register_cache);
208 #endif
209 }
210
211 int
212 register_cache_size (void)
213 {
214 return register_bytes;
215 }
216
217 #ifndef IN_PROCESS_AGENT
218
219 void
220 registers_to_string (struct regcache *regcache, char *buf)
221 {
222 unsigned char *registers = regcache->registers;
223 int i;
224
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';
240 }
241
242 void
243 registers_from_string (struct regcache *regcache, char *buf)
244 {
245 int len = strlen (buf);
246 unsigned char *registers = regcache->registers;
247
248 if (len != register_bytes * 2)
249 {
250 warning ("Wrong sized register packet (expected %d bytes, got %d)",
251 2*register_bytes, len);
252 if (len > register_bytes * 2)
253 len = register_bytes * 2;
254 }
255 convert_ascii_to_int (buf, registers, len / 2);
256 }
257
258 struct reg *
259 find_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
270 int
271 find_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
282 struct reg *
283 find_register_by_number (int n)
284 {
285 return &reg_defs[n];
286 }
287
288 #endif
289
290 int
291 register_size (int n)
292 {
293 return reg_defs[n].size / 8;
294 }
295
296 static unsigned char *
297 register_data (struct regcache *regcache, int n, int fetch)
298 {
299 return regcache->registers + (reg_defs[n].offset / 8);
300 }
301
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
306 void
307 supply_register (struct regcache *regcache, int n, const void *buf)
308 {
309 if (buf)
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 }
317 else
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 }
325 }
326
327 /* Supply register N with value zero to REGCACHE. */
328
329 void
330 supply_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
343 void
344 supply_regblock (struct regcache *regcache, const void *buf)
345 {
346 if (buf)
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 }
358 else
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 }
370 }
371
372 #ifndef IN_PROCESS_AGENT
373
374 void
375 supply_register_by_name (struct regcache *regcache,
376 const char *name, const void *buf)
377 {
378 supply_register (regcache, find_regno (name), buf);
379 }
380
381 #endif
382
383 void
384 collect_register (struct regcache *regcache, int n, void *buf)
385 {
386 memcpy (buf, register_data (regcache, n, 1), register_size (n));
387 }
388
389 #ifndef IN_PROCESS_AGENT
390
391 void
392 collect_register_as_string (struct regcache *regcache, int n, char *buf)
393 {
394 convert_int_to_ascii (register_data (regcache, n, 1),
395 buf, register_size (n));
396 }
397
398 void
399 collect_register_by_name (struct regcache *regcache,
400 const char *name, void *buf)
401 {
402 collect_register (regcache, find_regno (name), buf);
403 }
404
405 /* Special handling for register PC. */
406
407 CORE_ADDR
408 regcache_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
421 void
422 regcache_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 }
430
431 #endif
This page took 0.042242 seconds and 4 git commands to generate.