* symtab.c (Symbol::init_base_output_data): Add version
[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
0a30fbc4
DJ
89int
90registers_length (void)
91{
92 return 2 * register_bytes;
93}
94
0d62e5e8
DJ
95void *
96new_register_cache (void)
c04a1aa8
DJ
97{
98 struct inferior_regcache_data *regcache;
99
100 regcache = malloc (sizeof (*regcache));
101
2a68b70e
DJ
102 /* Make sure to zero-initialize the register cache when it is created,
103 in case there are registers the target never fetches. This way they'll
104 read as zero instead of garbage. */
105 regcache->registers = calloc (1, register_bytes);
c04a1aa8
DJ
106 if (regcache->registers == NULL)
107 fatal ("Could not allocate register cache.");
108
0d62e5e8
DJ
109 regcache->registers_valid = 0;
110
111 return regcache;
c04a1aa8
DJ
112}
113
114void
0d62e5e8 115free_register_cache (void *regcache_p)
c04a1aa8 116{
0d62e5e8
DJ
117 struct inferior_regcache_data *regcache
118 = (struct inferior_regcache_data *) regcache_p;
119
120 free (regcache->registers);
121 free (regcache);
c04a1aa8
DJ
122}
123
d61ddec4
UW
124static void
125realloc_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
0a30fbc4
DJ
133void
134set_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;
d61ddec4
UW
149
150 /* Re-allocate all pre-existing register caches. */
151 for_each_inferior (&all_threads, realloc_register_cache);
0a30fbc4
DJ
152}
153
154void
155registers_to_string (char *buf)
156{
f450004a 157 unsigned char *registers = get_regcache (current_inferior, 1)->registers;
c04a1aa8 158
0a30fbc4
DJ
159 convert_int_to_ascii (registers, buf, register_bytes);
160}
161
162void
163registers_from_string (char *buf)
164{
165 int len = strlen (buf);
f450004a 166 unsigned char *registers = get_regcache (current_inferior, 1)->registers;
0a30fbc4
DJ
167
168 if (len != register_bytes * 2)
169 {
170 warning ("Wrong sized register packet (expected %d bytes, got %d)", 2*register_bytes, len);
171 if (len > register_bytes * 2)
172 len = register_bytes * 2;
173 }
174 convert_ascii_to_int (buf, registers, len / 2);
175}
176
177struct reg *
178find_register_by_name (const char *name)
179{
180 int i;
181
182 for (i = 0; i < num_registers; i++)
183 if (!strcmp (name, reg_defs[i].name))
184 return &reg_defs[i];
185 fatal ("Unknown register %s requested", name);
186 return 0;
187}
188
189int
190find_regno (const char *name)
191{
192 int i;
193
194 for (i = 0; i < num_registers; i++)
195 if (!strcmp (name, reg_defs[i].name))
196 return i;
197 fatal ("Unknown register %s requested", name);
198 return -1;
199}
200
201struct reg *
202find_register_by_number (int n)
203{
204 return &reg_defs[n];
205}
206
207int
208register_size (int n)
209{
210 return reg_defs[n].size / 8;
211}
212
f450004a 213static unsigned char *
0d62e5e8 214register_data (int n, int fetch)
0a30fbc4 215{
f450004a
DJ
216 unsigned char *registers
217 = get_regcache (current_inferior, fetch)->registers;
c04a1aa8 218
0a30fbc4
DJ
219 return registers + (reg_defs[n].offset / 8);
220}
221
58caa3dc 222void
0729219d 223supply_register (int n, const void *buf)
58caa3dc 224{
0d62e5e8 225 memcpy (register_data (n, 0), buf, register_size (n));
58caa3dc
DJ
226}
227
228void
0729219d 229supply_register_by_name (const char *name, const void *buf)
58caa3dc
DJ
230{
231 supply_register (find_regno (name), buf);
232}
233
234void
0729219d 235collect_register (int n, void *buf)
58caa3dc 236{
0d62e5e8
DJ
237 memcpy (buf, register_data (n, 1), register_size (n));
238}
239
240void
241collect_register_as_string (int n, char *buf)
242{
243 convert_int_to_ascii (register_data (n, 1), buf, register_size (n));
58caa3dc
DJ
244}
245
246void
0729219d 247collect_register_by_name (const char *name, void *buf)
58caa3dc
DJ
248{
249 collect_register (find_regno (name), buf);
250}
This page took 0.442475 seconds and 4 git commands to generate.