* rs6000-tdep.c (rs6000_fetch_instruction)
[deliverable/binutils-gdb.git] / gdb / gdbserver / regcache.c
CommitLineData
0a30fbc4 1/* Register support routines for the remote server for GDB.
9b254dd1
DJ
2 Copyright (C) 2001, 2002, 2004, 2005, 2007, 2008
3 Free Software 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
a7f48742
DJ
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
c04a1aa8
DJ
30struct inferior_regcache_data
31{
0d62e5e8 32 int registers_valid;
f450004a 33 unsigned char *registers;
c04a1aa8
DJ
34};
35
0a30fbc4
DJ
36static int register_bytes;
37
38static struct reg *reg_defs;
39static int num_registers;
40
41const char **gdbserver_expedite_regs;
42
c04a1aa8 43static struct inferior_regcache_data *
0d62e5e8 44get_regcache (struct thread_info *inf, int fetch)
c04a1aa8
DJ
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
0d62e5e8
DJ
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
c04a1aa8
DJ
60 return regcache;
61}
62
0d62e5e8
DJ
63void
64regcache_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
83void
84regcache_invalidate ()
85{
86 for_each_inferior (&all_threads, regcache_invalidate_one);
87}
88
0d62e5e8
DJ
89void *
90new_register_cache (void)
c04a1aa8
DJ
91{
92 struct inferior_regcache_data *regcache;
93
94 regcache = malloc (sizeof (*regcache));
95
2a68b70e
DJ
96 /* Make sure to zero-initialize the register cache when it is created,
97 in case there are registers the target never fetches. This way they'll
98 read as zero instead of garbage. */
99 regcache->registers = calloc (1, register_bytes);
c04a1aa8
DJ
100 if (regcache->registers == NULL)
101 fatal ("Could not allocate register cache.");
102
0d62e5e8
DJ
103 regcache->registers_valid = 0;
104
105 return regcache;
c04a1aa8
DJ
106}
107
108void
0d62e5e8 109free_register_cache (void *regcache_p)
c04a1aa8 110{
0d62e5e8
DJ
111 struct inferior_regcache_data *regcache
112 = (struct inferior_regcache_data *) regcache_p;
113
114 free (regcache->registers);
115 free (regcache);
c04a1aa8
DJ
116}
117
d61ddec4
UW
118static void
119realloc_register_cache (struct inferior_list_entry *thread_p)
120{
121 struct thread_info *thread = (struct thread_info *) thread_p;
122
123 free_register_cache (inferior_regcache_data (thread));
124 set_inferior_regcache_data (thread, new_register_cache ());
125}
126
0a30fbc4
DJ
127void
128set_register_cache (struct reg *regs, int n)
129{
130 int offset, i;
131
132 reg_defs = regs;
133 num_registers = n;
134
135 offset = 0;
136 for (i = 0; i < n; i++)
137 {
138 regs[i].offset = offset;
139 offset += regs[i].size;
140 }
141
142 register_bytes = offset / 8;
d61ddec4 143
bb9c3d36
UW
144 /* Make sure PBUFSIZ is large enough to hold a full register packet. */
145 if (2 * register_bytes + 32 > PBUFSIZ)
146 fatal ("Register packet size exceeds PBUFSIZ.");
147
d61ddec4
UW
148 /* Re-allocate all pre-existing register caches. */
149 for_each_inferior (&all_threads, realloc_register_cache);
0a30fbc4
DJ
150}
151
152void
153registers_to_string (char *buf)
154{
f450004a 155 unsigned char *registers = get_regcache (current_inferior, 1)->registers;
c04a1aa8 156
0a30fbc4
DJ
157 convert_int_to_ascii (registers, buf, register_bytes);
158}
159
160void
161registers_from_string (char *buf)
162{
163 int len = strlen (buf);
f450004a 164 unsigned char *registers = get_regcache (current_inferior, 1)->registers;
0a30fbc4
DJ
165
166 if (len != register_bytes * 2)
167 {
168 warning ("Wrong sized register packet (expected %d bytes, got %d)", 2*register_bytes, len);
169 if (len > register_bytes * 2)
170 len = register_bytes * 2;
171 }
172 convert_ascii_to_int (buf, registers, len / 2);
173}
174
175struct reg *
176find_register_by_name (const char *name)
177{
178 int i;
179
180 for (i = 0; i < num_registers; i++)
181 if (!strcmp (name, reg_defs[i].name))
182 return &reg_defs[i];
183 fatal ("Unknown register %s requested", name);
184 return 0;
185}
186
187int
188find_regno (const char *name)
189{
190 int i;
191
192 for (i = 0; i < num_registers; i++)
193 if (!strcmp (name, reg_defs[i].name))
194 return i;
195 fatal ("Unknown register %s requested", name);
196 return -1;
197}
198
199struct reg *
200find_register_by_number (int n)
201{
202 return &reg_defs[n];
203}
204
205int
206register_size (int n)
207{
208 return reg_defs[n].size / 8;
209}
210
f450004a 211static unsigned char *
0d62e5e8 212register_data (int n, int fetch)
0a30fbc4 213{
f450004a
DJ
214 unsigned char *registers
215 = get_regcache (current_inferior, fetch)->registers;
c04a1aa8 216
0a30fbc4
DJ
217 return registers + (reg_defs[n].offset / 8);
218}
219
58caa3dc 220void
0729219d 221supply_register (int n, const void *buf)
58caa3dc 222{
0d62e5e8 223 memcpy (register_data (n, 0), buf, register_size (n));
58caa3dc
DJ
224}
225
226void
0729219d 227supply_register_by_name (const char *name, const void *buf)
58caa3dc
DJ
228{
229 supply_register (find_regno (name), buf);
230}
231
232void
0729219d 233collect_register (int n, void *buf)
58caa3dc 234{
0d62e5e8
DJ
235 memcpy (buf, register_data (n, 1), register_size (n));
236}
237
238void
239collect_register_as_string (int n, char *buf)
240{
241 convert_int_to_ascii (register_data (n, 1), buf, register_size (n));
58caa3dc
DJ
242}
243
244void
0729219d 245collect_register_by_name (const char *name, void *buf)
58caa3dc
DJ
246{
247 collect_register (find_regno (name), buf);
248}
This page took 0.50819 seconds and 4 git commands to generate.