OSDN Git Service

r284@cf-ppc-macosx: monabuilder | 2008-12-07 10:57:41 +0900
[pf3gnuchains/pf3gnuchains3x.git] / gdb / gdbserver / regcache.c
1 /* Register support routines for the remote server for GDB.
2    Copyright (C) 2001, 2002, 2004, 2005, 2007, 2008
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 /* The private data for the register cache.  Note that we have one
27    per inferior; this is primarily for simplicity, as the performance
28    benefit is minimal.  */
29
30 struct inferior_regcache_data
31 {
32   int registers_valid;
33   unsigned char *registers;
34 };
35
36 static int register_bytes;
37
38 static struct reg *reg_defs;
39 static int num_registers;
40
41 const char **gdbserver_expedite_regs;
42
43 static struct inferior_regcache_data *
44 get_regcache (struct thread_info *inf, int fetch)
45 {
46   struct inferior_regcache_data *regcache;
47
48   regcache = (struct inferior_regcache_data *) inferior_regcache_data (inf);
49
50   if (regcache == NULL)
51     fatal ("no register cache");
52
53   /* FIXME - fetch registers for INF */
54   if (fetch && regcache->registers_valid == 0)
55     {
56       fetch_inferior_registers (0);
57       regcache->registers_valid = 1;
58     }
59
60   return regcache;
61 }
62
63 void
64 regcache_invalidate_one (struct inferior_list_entry *entry)
65 {
66   struct thread_info *thread = (struct thread_info *) entry;
67   struct inferior_regcache_data *regcache;
68
69   regcache = (struct inferior_regcache_data *) inferior_regcache_data (thread);
70
71   if (regcache->registers_valid)
72     {
73       struct thread_info *saved_inferior = current_inferior;
74
75       current_inferior = thread;
76       store_inferior_registers (-1);
77       current_inferior = saved_inferior;
78     }
79
80   regcache->registers_valid = 0;
81 }
82
83 void
84 regcache_invalidate ()
85 {
86   for_each_inferior (&all_threads, regcache_invalidate_one);
87 }
88
89 void *
90 new_register_cache (void)
91 {
92   struct inferior_regcache_data *regcache;
93
94   if (register_bytes == 0)
95     return NULL; /* The architecture hasn't been initialized yet.  */
96
97   regcache = malloc (sizeof (*regcache));
98
99   /* Make sure to zero-initialize the register cache when it is created,
100      in case there are registers the target never fetches.  This way they'll
101      read as zero instead of garbage.  */
102   regcache->registers = calloc (1, register_bytes);
103   if (regcache->registers == NULL)
104     fatal ("Could not allocate register cache.");
105
106   regcache->registers_valid = 0;
107
108   return regcache;
109 }
110
111 void
112 free_register_cache (void *regcache_p)
113 {
114   struct inferior_regcache_data *regcache
115     = (struct inferior_regcache_data *) regcache_p;
116
117   if (regcache)
118     {
119       free (regcache->registers);
120       free (regcache);
121     }
122 }
123
124 static void
125 realloc_register_cache (struct inferior_list_entry *thread_p)
126 {
127   struct thread_info *thread = (struct thread_info *) thread_p;
128
129   free_register_cache (inferior_regcache_data (thread));
130   set_inferior_regcache_data (thread, new_register_cache ());
131 }
132
133 void
134 set_register_cache (struct reg *regs, int n)
135 {
136   int offset, i;
137   
138   reg_defs = regs;
139   num_registers = n;
140
141   offset = 0;
142   for (i = 0; i < n; i++)
143     {
144       regs[i].offset = offset;
145       offset += regs[i].size;
146     }
147
148   register_bytes = offset / 8;
149
150   /* Make sure PBUFSIZ is large enough to hold a full register packet.  */
151   if (2 * register_bytes + 32 > PBUFSIZ)
152     fatal ("Register packet size exceeds PBUFSIZ.");
153
154   /* Re-allocate all pre-existing register caches.  */
155   for_each_inferior (&all_threads, realloc_register_cache);
156 }
157
158 void
159 registers_to_string (char *buf)
160 {
161   unsigned char *registers = get_regcache (current_inferior, 1)->registers;
162
163   convert_int_to_ascii (registers, buf, register_bytes);
164 }
165
166 void
167 registers_from_string (char *buf)
168 {
169   int len = strlen (buf);
170   unsigned char *registers = get_regcache (current_inferior, 1)->registers;
171
172   if (len != register_bytes * 2)
173     {
174       warning ("Wrong sized register packet (expected %d bytes, got %d)", 2*register_bytes, len);
175       if (len > register_bytes * 2)
176         len = register_bytes * 2;
177     }
178   convert_ascii_to_int (buf, registers, len / 2);
179 }
180
181 struct reg *
182 find_register_by_name (const char *name)
183 {
184   int i;
185
186   for (i = 0; i < num_registers; i++)
187     if (!strcmp (name, reg_defs[i].name))
188       return &reg_defs[i];
189   fatal ("Unknown register %s requested", name);
190   return 0;
191 }
192
193 int
194 find_regno (const char *name)
195 {
196   int i;
197
198   for (i = 0; i < num_registers; i++)
199     if (!strcmp (name, reg_defs[i].name))
200       return i;
201   fatal ("Unknown register %s requested", name);
202   return -1;
203 }
204
205 struct reg *
206 find_register_by_number (int n)
207 {
208   return &reg_defs[n];
209 }
210
211 int
212 register_size (int n)
213 {
214   return reg_defs[n].size / 8;
215 }
216
217 static unsigned char *
218 register_data (int n, int fetch)
219 {
220   unsigned char *registers
221     = get_regcache (current_inferior, fetch)->registers;
222
223   return registers + (reg_defs[n].offset / 8);
224 }
225
226 void
227 supply_register (int n, const void *buf)
228 {
229   memcpy (register_data (n, 0), buf, register_size (n));
230 }
231
232 void
233 supply_register_by_name (const char *name, const void *buf)
234 {
235   supply_register (find_regno (name), buf);
236 }
237
238 void
239 collect_register (int n, void *buf)
240 {
241   memcpy (buf, register_data (n, 1), register_size (n));
242 }
243
244 void
245 collect_register_as_string (int n, char *buf)
246 {
247   convert_int_to_ascii (register_data (n, 1), buf, register_size (n));
248 }
249
250 void
251 collect_register_by_name (const char *name, void *buf)
252 {
253   collect_register (find_regno (name), buf);
254 }