OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [gdb/] [gdbserver/] [regcache.c] - Blame information for rev 841

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 330 jeremybenn
/* Register support routines for the remote server for GDB.
2
   Copyright (C) 2001, 2002, 2004, 2005, 2007, 2008, 2009, 2010
3
   Free Software 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
 
23
#include <stdlib.h>
24
#include <string.h>
25
 
26
static int register_bytes;
27
 
28
static struct reg *reg_defs;
29
static int num_registers;
30
 
31
const char **gdbserver_expedite_regs;
32
 
33
#ifndef IN_PROCESS_AGENT
34
 
35
struct regcache *
36
get_thread_regcache (struct thread_info *thread, int fetch)
37
{
38
  struct regcache *regcache;
39
 
40
  regcache = (struct regcache *) inferior_regcache_data (thread);
41
 
42
  if (regcache == NULL)
43
    fatal ("no register cache");
44
 
45
  if (fetch && regcache->registers_valid == 0)
46
    {
47
      struct thread_info *saved_inferior = current_inferior;
48
 
49
      current_inferior = thread;
50
      fetch_inferior_registers (regcache, -1);
51
      current_inferior = saved_inferior;
52
      regcache->registers_valid = 1;
53
    }
54
 
55
  return regcache;
56
}
57
 
58
void
59
regcache_invalidate_one (struct inferior_list_entry *entry)
60
{
61
  struct thread_info *thread = (struct thread_info *) entry;
62
  struct regcache *regcache;
63
 
64
  regcache = (struct regcache *) inferior_regcache_data (thread);
65
 
66
  if (regcache == NULL)
67
    return;
68
 
69
  if (regcache->registers_valid)
70
    {
71
      struct thread_info *saved_inferior = current_inferior;
72
 
73
      current_inferior = thread;
74
      store_inferior_registers (regcache, -1);
75
      current_inferior = saved_inferior;
76
    }
77
 
78
  regcache->registers_valid = 0;
79
}
80
 
81
void
82
regcache_invalidate (void)
83
{
84
  for_each_inferior (&all_threads, regcache_invalidate_one);
85
}
86
 
87
#endif
88
 
89
struct regcache *
90
init_register_cache (struct regcache *regcache, unsigned char *regbuf)
91
{
92
#ifndef IN_PROCESS_AGENT
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
103
#else
104
  if (regbuf == NULL)
105
    fatal ("init_register_cache: can't allocate memory from the heap");
106
  else
107
#endif
108
    {
109
      regcache->registers = regbuf;
110
      regcache->registers_owned = 0;
111
    }
112
 
113
  regcache->registers_valid = 0;
114
 
115
  return regcache;
116
}
117
 
118
#ifndef IN_PROCESS_AGENT
119
 
120
struct regcache *
121
new_register_cache (void)
122
{
123
  struct regcache *regcache;
124
 
125
  if (register_bytes == 0)
126
    return NULL; /* The architecture hasn't been initialized yet.  */
127
 
128
  regcache = xmalloc (sizeof (*regcache));
129
  return init_register_cache (regcache, NULL);
130
}
131
 
132
void
133
free_register_cache (struct regcache *regcache)
134
{
135
  if (regcache)
136
    {
137
      if (regcache->registers_owned)
138
        free (regcache->registers);
139
      free (regcache);
140
    }
141
}
142
 
143
#endif
144
 
145
void
146
regcache_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
 
152
#ifndef IN_PROCESS_AGENT
153
static void
154
realloc_register_cache (struct inferior_list_entry *thread_p)
155
{
156
  struct thread_info *thread = (struct thread_info *) thread_p;
157
  struct regcache *regcache
158
    = (struct regcache *) inferior_regcache_data (thread);
159
 
160
  if (regcache != NULL)
161
    regcache_invalidate_one (thread_p);
162
  free_register_cache (regcache);
163
  set_inferior_regcache_data (thread, new_register_cache ());
164
}
165
#endif
166
 
167
void
168
set_register_cache (struct reg *regs, int n)
169
{
170
  int offset, i;
171
 
172
#ifndef IN_PROCESS_AGENT
173
  /* Before changing the register cache internal layout, flush the
174
     contents of valid caches back to the threads.  */
175
  regcache_invalidate ();
176
#endif
177
 
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;
189
 
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
 
194
#ifndef IN_PROCESS_AGENT
195
  /* Re-allocate all pre-existing register caches.  */
196
  for_each_inferior (&all_threads, realloc_register_cache);
197
#endif
198
}
199
 
200
int
201
register_cache_size (void)
202
{
203
  return register_bytes;
204
}
205
 
206
#ifndef IN_PROCESS_AGENT
207
 
208
void
209
registers_to_string (struct regcache *regcache, char *buf)
210
{
211
  unsigned char *registers = regcache->registers;
212
 
213
  convert_int_to_ascii (registers, buf, register_bytes);
214
}
215
 
216
void
217
registers_from_string (struct regcache *regcache, char *buf)
218
{
219
  int len = strlen (buf);
220
  unsigned char *registers = regcache->registers;
221
 
222
  if (len != register_bytes * 2)
223
    {
224
      warning ("Wrong sized register packet (expected %d bytes, got %d)",
225
               2*register_bytes, len);
226
      if (len > register_bytes * 2)
227
        len = register_bytes * 2;
228
    }
229
  convert_ascii_to_int (buf, registers, len / 2);
230
}
231
 
232
struct reg *
233
find_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
 
244
int
245
find_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
 
256
struct reg *
257
find_register_by_number (int n)
258
{
259
  return &reg_defs[n];
260
}
261
 
262
#endif
263
 
264
int
265
register_size (int n)
266
{
267
  return reg_defs[n].size / 8;
268
}
269
 
270
static unsigned char *
271
register_data (struct regcache *regcache, int n, int fetch)
272
{
273
  return regcache->registers + (reg_defs[n].offset / 8);
274
}
275
 
276
void
277
supply_register (struct regcache *regcache, int n, const void *buf)
278
{
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));
283
}
284
 
285
void
286
supply_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
 
294
#ifndef IN_PROCESS_AGENT
295
 
296
void
297
supply_register_by_name (struct regcache *regcache,
298
                         const char *name, const void *buf)
299
{
300
  supply_register (regcache, find_regno (name), buf);
301
}
302
 
303
#endif
304
 
305
void
306
collect_register (struct regcache *regcache, int n, void *buf)
307
{
308
  memcpy (buf, register_data (regcache, n, 1), register_size (n));
309
}
310
 
311
#ifndef IN_PROCESS_AGENT
312
 
313
void
314
collect_register_as_string (struct regcache *regcache, int n, char *buf)
315
{
316
  convert_int_to_ascii (register_data (regcache, n, 1),
317
                        buf, register_size (n));
318
}
319
 
320
void
321
collect_register_by_name (struct regcache *regcache,
322
                          const char *name, void *buf)
323
{
324
  collect_register (regcache, find_regno (name), buf);
325
}
326
 
327
/* Special handling for register PC.  */
328
 
329
CORE_ADDR
330
regcache_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
 
343
void
344
regcache_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
}
352
 
353
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.