GDBserver
regcache.c
Go to the documentation of this file.
1 /* Register support routines for the remote server for GDB.
2  Copyright (C) 2001-2015 Free Software Foundation, Inc.
3 
4  This file is part of GDB.
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>. */
18 
19 #include "server.h"
20 #include "regdef.h"
21 #include "gdbthread.h"
22 #include "tdesc.h"
23 #include "rsp-low.h"
24 #ifndef IN_PROCESS_AGENT
25 
26 struct regcache *
27 get_thread_regcache (struct thread_info *thread, int fetch)
28 {
29  struct regcache *regcache;
30 
31  regcache = (struct regcache *) inferior_regcache_data (thread);
32 
33  /* Threads' regcaches are created lazily, because biarch targets add
34  the main thread/lwp before seeing it stop for the first time, and
35  it is only after the target sees the thread stop for the first
36  time that the target has a chance of determining the process's
37  architecture. IOW, when we first add the process's main thread
38  we don't know which architecture/tdesc its regcache should
39  have. */
40  if (regcache == NULL)
41  {
42  struct process_info *proc = get_thread_process (thread);
43 
44  gdb_assert (proc->tdesc != NULL);
45 
46  regcache = new_register_cache (proc->tdesc);
47  set_inferior_regcache_data (thread, regcache);
48  }
49 
50  if (fetch && regcache->registers_valid == 0)
51  {
52  struct thread_info *saved_thread = current_thread;
53 
54  current_thread = thread;
55  /* Invalidate all registers, to prevent stale left-overs. */
56  memset (regcache->register_status, REG_UNAVAILABLE,
57  regcache->tdesc->num_registers);
58  fetch_inferior_registers (regcache, -1);
59  current_thread = saved_thread;
60  regcache->registers_valid = 1;
61  }
62 
63  return regcache;
64 }
65 
66 /* See common/common-regcache.h. */
67 
68 struct regcache *
70 {
71  return get_thread_regcache (find_thread_ptid (ptid), 1);
72 }
73 
74 void
76 {
77  struct regcache *regcache;
78 
79  regcache = (struct regcache *) inferior_regcache_data (thread);
80 
81  if (regcache == NULL)
82  return;
83 
84  if (regcache->registers_valid)
85  {
86  struct thread_info *saved_thread = current_thread;
87 
88  current_thread = thread;
89  store_inferior_registers (regcache, -1);
90  current_thread = saved_thread;
91  }
92 
93  regcache->registers_valid = 0;
94 }
95 
96 static int
98  void *pid_p)
99 {
100  struct thread_info *thread = (struct thread_info *) entry;
101  int pid = *(int *) pid_p;
102 
103  /* Only invalidate the regcaches of threads of this process. */
104  if (ptid_get_pid (entry->id) == pid)
106 
107  return 0;
108 }
109 
110 void
112 {
113  /* Only update the threads of the current process. */
114  int pid = ptid_get_pid (current_thread->entry.id);
115 
117 }
118 
119 #endif
120 
121 struct regcache *
123  const struct target_desc *tdesc,
124  unsigned char *regbuf)
125 {
126  if (regbuf == NULL)
127  {
128 #ifndef IN_PROCESS_AGENT
129  /* Make sure to zero-initialize the register cache when it is
130  created, in case there are registers the target never
131  fetches. This way they'll read as zero instead of
132  garbage. */
133  regcache->tdesc = tdesc;
134  regcache->registers = xcalloc (1, tdesc->registers_size);
135  regcache->registers_owned = 1;
136  regcache->register_status = xcalloc (1, tdesc->num_registers);
138 #else
139  gdb_assert_not_reached ("can't allocate memory from the heap");
140 #endif
141  }
142  else
143  {
144  regcache->tdesc = tdesc;
145  regcache->registers = regbuf;
146  regcache->registers_owned = 0;
147 #ifndef IN_PROCESS_AGENT
148  regcache->register_status = NULL;
149 #endif
150  }
151 
152  regcache->registers_valid = 0;
153 
154  return regcache;
155 }
156 
157 #ifndef IN_PROCESS_AGENT
158 
159 struct regcache *
161 {
162  struct regcache *regcache;
163 
164  gdb_assert (tdesc->registers_size != 0);
165 
166  regcache = xmalloc (sizeof (*regcache));
167  return init_register_cache (regcache, tdesc, NULL);
168 }
169 
170 void
172 {
173  if (regcache)
174  {
175  if (regcache->registers_owned)
176  free (regcache->registers);
177  free (regcache->register_status);
178  free (regcache);
179  }
180 }
181 
182 #endif
183 
184 void
185 regcache_cpy (struct regcache *dst, struct regcache *src)
186 {
187  gdb_assert (src != NULL && dst != NULL);
188  gdb_assert (src->tdesc == dst->tdesc);
189  gdb_assert (src != dst);
190 
191  memcpy (dst->registers, src->registers, src->tdesc->registers_size);
192 #ifndef IN_PROCESS_AGENT
193  if (dst->register_status != NULL && src->register_status != NULL)
194  memcpy (dst->register_status, src->register_status,
195  src->tdesc->num_registers);
196 #endif
197  dst->registers_valid = src->registers_valid;
198 }
199 
200 
201 #ifndef IN_PROCESS_AGENT
202 
203 void
205 {
206  unsigned char *registers = regcache->registers;
207  const struct target_desc *tdesc = regcache->tdesc;
208  int i;
209 
210  for (i = 0; i < tdesc->num_registers; i++)
211  {
212  if (regcache->register_status[i] == REG_VALID)
213  {
214  bin2hex (registers, buf, register_size (tdesc, i));
215  buf += register_size (tdesc, i) * 2;
216  }
217  else
218  {
219  memset (buf, 'x', register_size (tdesc, i) * 2);
220  buf += register_size (tdesc, i) * 2;
221  }
222  registers += register_size (tdesc, i);
223  }
224  *buf = '\0';
225 }
226 
227 void
229 {
230  int len = strlen (buf);
231  unsigned char *registers = regcache->registers;
232  const struct target_desc *tdesc = regcache->tdesc;
233 
234  if (len != tdesc->registers_size * 2)
235  {
236  warning ("Wrong sized register packet (expected %d bytes, got %d)",
237  2 * tdesc->registers_size, len);
238  if (len > tdesc->registers_size * 2)
239  len = tdesc->registers_size * 2;
240  }
241  hex2bin (buf, registers, len / 2);
242 }
243 
244 struct reg *
245 find_register_by_name (const struct target_desc *tdesc, const char *name)
246 {
247  int i;
248 
249  for (i = 0; i < tdesc->num_registers; i++)
250  if (strcmp (name, tdesc->reg_defs[i].name) == 0)
251  return &tdesc->reg_defs[i];
252  internal_error (__FILE__, __LINE__, "Unknown register %s requested",
253  name);
254 }
255 
256 int
257 find_regno (const struct target_desc *tdesc, const char *name)
258 {
259  int i;
260 
261  for (i = 0; i < tdesc->num_registers; i++)
262  if (strcmp (name, tdesc->reg_defs[i].name) == 0)
263  return i;
264  internal_error (__FILE__, __LINE__, "Unknown register %s requested",
265  name);
266 }
267 
268 struct reg *
269 find_register_by_number (const struct target_desc *tdesc, int n)
270 {
271  return &tdesc->reg_defs[n];
272 }
273 
274 #endif
275 
276 #ifndef IN_PROCESS_AGENT
277 static void
279 {
280  struct regcache *regcache
281  = (struct regcache *) inferior_regcache_data (thread);
282 
283  if (regcache != NULL)
284  {
286  free_register_cache (regcache);
287  set_inferior_regcache_data (thread, NULL);
288  }
289 }
290 
291 static void
293 {
294  struct thread_info *thread = (struct thread_info *) entry;
295 
297 }
298 
299 void
301 {
302  /* Flush and release all pre-existing register caches. */
304 }
305 #endif
306 
307 int
308 register_cache_size (const struct target_desc *tdesc)
309 {
310  return tdesc->registers_size;
311 }
312 
313 int
314 register_size (const struct target_desc *tdesc, int n)
315 {
316  return tdesc->reg_defs[n].size / 8;
317 }
318 
319 static unsigned char *
320 register_data (struct regcache *regcache, int n, int fetch)
321 {
322  return regcache->registers + regcache->tdesc->reg_defs[n].offset / 8;
323 }
324 
325 /* Supply register N, whose contents are stored in BUF, to REGCACHE.
326  If BUF is NULL, the register's value is recorded as
327  unavailable. */
328 
329 void
330 supply_register (struct regcache *regcache, int n, const void *buf)
331 {
332  if (buf)
333  {
334  memcpy (register_data (regcache, n, 0), buf,
335  register_size (regcache->tdesc, n));
336 #ifndef IN_PROCESS_AGENT
337  if (regcache->register_status != NULL)
338  regcache->register_status[n] = REG_VALID;
339 #endif
340  }
341  else
342  {
343  memset (register_data (regcache, n, 0), 0,
344  register_size (regcache->tdesc, n));
345 #ifndef IN_PROCESS_AGENT
346  if (regcache->register_status != NULL)
347  regcache->register_status[n] = REG_UNAVAILABLE;
348 #endif
349  }
350 }
351 
352 /* Supply register N with value zero to REGCACHE. */
353 
354 void
356 {
357  memset (register_data (regcache, n, 0), 0,
358  register_size (regcache->tdesc, n));
359 #ifndef IN_PROCESS_AGENT
360  if (regcache->register_status != NULL)
361  regcache->register_status[n] = REG_VALID;
362 #endif
363 }
364 
365 /* Supply the whole register set whose contents are stored in BUF, to
366  REGCACHE. If BUF is NULL, all the registers' values are recorded
367  as unavailable. */
368 
369 void
370 supply_regblock (struct regcache *regcache, const void *buf)
371 {
372  if (buf)
373  {
374  const struct target_desc *tdesc = regcache->tdesc;
375 
376  memcpy (regcache->registers, buf, tdesc->registers_size);
377 #ifndef IN_PROCESS_AGENT
378  {
379  int i;
380 
381  for (i = 0; i < tdesc->num_registers; i++)
382  regcache->register_status[i] = REG_VALID;
383  }
384 #endif
385  }
386  else
387  {
388  const struct target_desc *tdesc = regcache->tdesc;
389 
390  memset (regcache->registers, 0, tdesc->registers_size);
391 #ifndef IN_PROCESS_AGENT
392  {
393  int i;
394 
395  for (i = 0; i < tdesc->num_registers; i++)
396  regcache->register_status[i] = REG_UNAVAILABLE;
397  }
398 #endif
399  }
400 }
401 
402 #ifndef IN_PROCESS_AGENT
403 
404 void
406  const char *name, const void *buf)
407 {
408  supply_register (regcache, find_regno (regcache->tdesc, name), buf);
409 }
410 
411 #endif
412 
413 void
414 collect_register (struct regcache *regcache, int n, void *buf)
415 {
416  memcpy (buf, register_data (regcache, n, 1),
417  register_size (regcache->tdesc, n));
418 }
419 
420 #ifndef IN_PROCESS_AGENT
421 
422 void
423 collect_register_as_string (struct regcache *regcache, int n, char *buf)
424 {
425  bin2hex (register_data (regcache, n, 1), buf,
426  register_size (regcache->tdesc, n));
427 }
428 
429 void
431  const char *name, void *buf)
432 {
433  collect_register (regcache, find_regno (regcache->tdesc, name), buf);
434 }
435 
436 /* Special handling for register PC. */
437 
438 CORE_ADDR
440 {
441  CORE_ADDR pc_val;
442 
443  if (the_target->read_pc)
444  pc_val = the_target->read_pc (regcache);
445  else
446  internal_error (__FILE__, __LINE__,
447  "regcache_read_pc: Unable to find PC");
448 
449  return pc_val;
450 }
451 
452 void
454 {
455  if (the_target->write_pc)
456  the_target->write_pc (regcache, pc);
457  else
458  internal_error (__FILE__, __LINE__,
459  "regcache_write_pc: Unable to update PC");
460 }
461 
462 #endif
const struct target_desc * tdesc
Definition: regcache.h:41
int registers_valid
Definition: regcache.h:48
CORE_ADDR(* read_pc)(struct regcache *regcache)
Definition: target.h:312
struct thread_info * current_thread
Definition: inferiors.c:28
void collect_register(struct regcache *regcache, int n, void *buf)
Definition: regcache.c:414
struct thread_info * find_thread_ptid(ptid_t ptid)
Definition: inferiors.c:141
bfd_vma CORE_ADDR
Definition: common-types.h:41
struct regcache * new_register_cache(const struct target_desc *tdesc)
Definition: regcache.c:160
void supply_register_by_name(struct regcache *regcache, const char *name, const void *buf)
Definition: regcache.c:405
CORE_ADDR regcache_read_pc(struct regcache *regcache)
Definition: regcache.c:439
void supply_register_zeroed(struct regcache *regcache, int n)
Definition: regcache.c:355
void warning(const char *fmt,...)
Definition: errors.c:26
struct reg * find_register_by_number(const struct target_desc *tdesc, int n)
Definition: regcache.c:269
void regcache_release(void)
Definition: regcache.c:300
int bin2hex(const gdb_byte *bin, char *hex, int count)
Definition: rsp-low.c:136
void set_inferior_regcache_data(struct thread_info *inferior, void *data)
Definition: inferiors.c:240
void internal_error(const char *file, int line, const char *fmt,...)
Definition: errors.c:50
struct process_info * get_thread_process(struct thread_info *thread)
Definition: inferiors.c:349
void for_each_inferior(struct inferior_list *list, void(*action)(struct inferior_list_entry *))
Definition: inferiors.c:47
ptid_t id
Definition: inferiors.h:31
const char * name
Definition: tracepoint.c:178
int registers_owned
Definition: regcache.h:49
void regcache_write_pc(struct regcache *regcache, CORE_ADDR pc)
Definition: regcache.c:453
struct target_ops * the_target
Definition: target.c:24
const struct target_desc * tdesc
Definition: inferiors.h:69
Definition: ptid.h:35
struct inferior_list_entry entry
Definition: gdbthread.h:30
unsigned char * registers
Definition: regcache.h:50
static void free_register_cache_thread(struct thread_info *thread)
Definition: regcache.c:278
unsigned char * register_status
Definition: regcache.h:53
void collect_register_by_name(struct regcache *regcache, const char *name, void *buf)
Definition: regcache.c:430
void regcache_invalidate(void)
Definition: regcache.c:111
void collect_register_as_string(struct regcache *regcache, int n, char *buf)
Definition: regcache.c:423
int num_registers
Definition: tdesc.h:34
#define gdb_assert_not_reached(message)
Definition: gdb_assert.h:56
int register_size(const struct target_desc *tdesc, int n)
Definition: regcache.c:314
#define gdb_assert(expr)
Definition: gdb_assert.h:33
void regcache_cpy(struct regcache *dst, struct regcache *src)
Definition: regcache.c:185
int register_cache_size(const struct target_desc *tdesc)
Definition: regcache.c:308
struct reg * find_register_by_name(const struct target_desc *tdesc, const char *name)
Definition: regcache.c:245
struct inferior_list all_threads
Definition: inferiors.c:26
static int regcache_invalidate_one(struct inferior_list_entry *entry, void *pid_p)
Definition: regcache.c:97
int registers_size
Definition: tdesc.h:37
int ptid_get_pid(ptid_t ptid)
Definition: ptid.c:52
struct regcache * init_register_cache(struct regcache *regcache, const struct target_desc *tdesc, unsigned char *regbuf)
Definition: regcache.c:122
int find_regno(const struct target_desc *tdesc, const char *name)
Definition: regcache.c:257
static void free_register_cache_thread_one(struct inferior_list_entry *entry)
Definition: regcache.c:292
#define fetch_inferior_registers(regcache, regno)
Definition: target.h:477
void * inferior_regcache_data(struct thread_info *inferior)
Definition: inferiors.c:234
void regcache_invalidate_thread(struct thread_info *thread)
Definition: regcache.c:75
void registers_to_string(struct regcache *regcache, char *buf)
Definition: regcache.c:204
struct regcache * get_thread_regcache(struct thread_info *thread, int fetch)
Definition: regcache.c:27
struct reg * reg_defs
Definition: tdesc.h:30
void free_register_cache(struct regcache *regcache)
Definition: regcache.c:171
static unsigned char * register_data(struct regcache *regcache, int n, int fetch)
Definition: regcache.c:320
#define REG_VALID
Definition: regcache.h:32
PTR xmalloc(size_t size)
Definition: common-utils.c:34
Definition: inferiors.h:29
int hex2bin(const char *hex, gdb_byte *bin, int count)
Definition: rsp-low.c:115
void supply_register(struct regcache *regcache, int n, const void *buf)
Definition: regcache.c:330
struct regcache * get_thread_regcache_for_ptid(ptid_t ptid)
Definition: regcache.c:69
PTR xcalloc(size_t number, size_t size)
Definition: common-utils.c:71
#define store_inferior_registers(regcache, regno)
Definition: target.h:480
void(* write_pc)(struct regcache *regcache, CORE_ADDR pc)
Definition: target.h:315
void registers_from_string(struct regcache *regcache, char *buf)
Definition: regcache.c:228
void supply_regblock(struct regcache *regcache, const void *buf)
Definition: regcache.c:370
struct inferior_list_entry * find_inferior(struct inferior_list *list, int(*func)(struct inferior_list_entry *, void *), void *arg)
Definition: inferiors.c:188
#define REG_UNAVAILABLE
Definition: regcache.h:29