* configure.ac: Switch license to GPLv3.
[deliverable/binutils-gdb.git] / gdb / gdbserver / regcache.c
CommitLineData
0a30fbc4 1/* Register support routines for the remote server for GDB.
6aba47ca 2 Copyright (C) 2001, 2002, 2004, 2005, 2007 Free Software Foundation, Inc.
0a30fbc4
DJ
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 2 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, write to the Free Software
6f0f660e
EZ
18 Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA. */
0a30fbc4
DJ
20
21#include "server.h"
22#include "regdef.h"
23
24#include <stdlib.h>
25#include <string.h>
26
a7f48742
DJ
27/* The private data for the register cache. Note that we have one
28 per inferior; this is primarily for simplicity, as the performance
29 benefit is minimal. */
30
c04a1aa8
DJ
31struct inferior_regcache_data
32{
0d62e5e8 33 int registers_valid;
f450004a 34 unsigned char *registers;
c04a1aa8
DJ
35};
36
0a30fbc4
DJ
37static int register_bytes;
38
39static struct reg *reg_defs;
40static int num_registers;
41
42const char **gdbserver_expedite_regs;
43
c04a1aa8 44static struct inferior_regcache_data *
0d62e5e8 45get_regcache (struct thread_info *inf, int fetch)
c04a1aa8
DJ
46{
47 struct inferior_regcache_data *regcache;
48
49 regcache = (struct inferior_regcache_data *) inferior_regcache_data (inf);
50
51 if (regcache == NULL)
52 fatal ("no register cache");
53
0d62e5e8
DJ
54 /* FIXME - fetch registers for INF */
55 if (fetch && regcache->registers_valid == 0)
56 {
57 fetch_inferior_registers (0);
58 regcache->registers_valid = 1;
59 }
60
c04a1aa8
DJ
61 return regcache;
62}
63
0d62e5e8
DJ
64void
65regcache_invalidate_one (struct inferior_list_entry *entry)
66{
67 struct thread_info *thread = (struct thread_info *) entry;
68 struct inferior_regcache_data *regcache;
69
70 regcache = (struct inferior_regcache_data *) inferior_regcache_data (thread);
71
72 if (regcache->registers_valid)
73 {
74 struct thread_info *saved_inferior = current_inferior;
75
76 current_inferior = thread;
77 store_inferior_registers (-1);
78 current_inferior = saved_inferior;
79 }
80
81 regcache->registers_valid = 0;
82}
83
84void
85regcache_invalidate ()
86{
87 for_each_inferior (&all_threads, regcache_invalidate_one);
88}
89
0a30fbc4
DJ
90int
91registers_length (void)
92{
93 return 2 * register_bytes;
94}
95
0d62e5e8
DJ
96void *
97new_register_cache (void)
c04a1aa8
DJ
98{
99 struct inferior_regcache_data *regcache;
100
101 regcache = malloc (sizeof (*regcache));
102
2a68b70e
DJ
103 /* Make sure to zero-initialize the register cache when it is created,
104 in case there are registers the target never fetches. This way they'll
105 read as zero instead of garbage. */
106 regcache->registers = calloc (1, register_bytes);
c04a1aa8
DJ
107 if (regcache->registers == NULL)
108 fatal ("Could not allocate register cache.");
109
0d62e5e8
DJ
110 regcache->registers_valid = 0;
111
112 return regcache;
c04a1aa8
DJ
113}
114
115void
0d62e5e8 116free_register_cache (void *regcache_p)
c04a1aa8 117{
0d62e5e8
DJ
118 struct inferior_regcache_data *regcache
119 = (struct inferior_regcache_data *) regcache_p;
120
121 free (regcache->registers);
122 free (regcache);
c04a1aa8
DJ
123}
124
0a30fbc4
DJ
125void
126set_register_cache (struct reg *regs, int n)
127{
128 int offset, i;
129
130 reg_defs = regs;
131 num_registers = n;
132
133 offset = 0;
134 for (i = 0; i < n; i++)
135 {
136 regs[i].offset = offset;
137 offset += regs[i].size;
138 }
139
140 register_bytes = offset / 8;
0a30fbc4
DJ
141}
142
143void
144registers_to_string (char *buf)
145{
f450004a 146 unsigned char *registers = get_regcache (current_inferior, 1)->registers;
c04a1aa8 147
0a30fbc4
DJ
148 convert_int_to_ascii (registers, buf, register_bytes);
149}
150
151void
152registers_from_string (char *buf)
153{
154 int len = strlen (buf);
f450004a 155 unsigned char *registers = get_regcache (current_inferior, 1)->registers;
0a30fbc4
DJ
156
157 if (len != register_bytes * 2)
158 {
159 warning ("Wrong sized register packet (expected %d bytes, got %d)", 2*register_bytes, len);
160 if (len > register_bytes * 2)
161 len = register_bytes * 2;
162 }
163 convert_ascii_to_int (buf, registers, len / 2);
164}
165
166struct reg *
167find_register_by_name (const char *name)
168{
169 int i;
170
171 for (i = 0; i < num_registers; i++)
172 if (!strcmp (name, reg_defs[i].name))
173 return &reg_defs[i];
174 fatal ("Unknown register %s requested", name);
175 return 0;
176}
177
178int
179find_regno (const char *name)
180{
181 int i;
182
183 for (i = 0; i < num_registers; i++)
184 if (!strcmp (name, reg_defs[i].name))
185 return i;
186 fatal ("Unknown register %s requested", name);
187 return -1;
188}
189
190struct reg *
191find_register_by_number (int n)
192{
193 return &reg_defs[n];
194}
195
196int
197register_size (int n)
198{
199 return reg_defs[n].size / 8;
200}
201
f450004a 202static unsigned char *
0d62e5e8 203register_data (int n, int fetch)
0a30fbc4 204{
f450004a
DJ
205 unsigned char *registers
206 = get_regcache (current_inferior, fetch)->registers;
c04a1aa8 207
0a30fbc4
DJ
208 return registers + (reg_defs[n].offset / 8);
209}
210
58caa3dc 211void
0729219d 212supply_register (int n, const void *buf)
58caa3dc 213{
0d62e5e8 214 memcpy (register_data (n, 0), buf, register_size (n));
58caa3dc
DJ
215}
216
217void
0729219d 218supply_register_by_name (const char *name, const void *buf)
58caa3dc
DJ
219{
220 supply_register (find_regno (name), buf);
221}
222
223void
0729219d 224collect_register (int n, void *buf)
58caa3dc 225{
0d62e5e8
DJ
226 memcpy (buf, register_data (n, 1), register_size (n));
227}
228
229void
230collect_register_as_string (int n, char *buf)
231{
232 convert_int_to_ascii (register_data (n, 1), buf, register_size (n));
58caa3dc
DJ
233}
234
235void
0729219d 236collect_register_by_name (const char *name, void *buf)
58caa3dc
DJ
237{
238 collect_register (find_regno (name), buf);
239}
This page took 0.435472 seconds and 4 git commands to generate.