Updated copyright notices for most files.
[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
0a30fbc4
DJ
124void
125set_register_cache (struct reg *regs, int n)
126{
127 int offset, i;
128
129 reg_defs = regs;
130 num_registers = n;
131
132 offset = 0;
133 for (i = 0; i < n; i++)
134 {
135 regs[i].offset = offset;
136 offset += regs[i].size;
137 }
138
139 register_bytes = offset / 8;
0a30fbc4
DJ
140}
141
142void
143registers_to_string (char *buf)
144{
f450004a 145 unsigned char *registers = get_regcache (current_inferior, 1)->registers;
c04a1aa8 146
0a30fbc4
DJ
147 convert_int_to_ascii (registers, buf, register_bytes);
148}
149
150void
151registers_from_string (char *buf)
152{
153 int len = strlen (buf);
f450004a 154 unsigned char *registers = get_regcache (current_inferior, 1)->registers;
0a30fbc4
DJ
155
156 if (len != register_bytes * 2)
157 {
158 warning ("Wrong sized register packet (expected %d bytes, got %d)", 2*register_bytes, len);
159 if (len > register_bytes * 2)
160 len = register_bytes * 2;
161 }
162 convert_ascii_to_int (buf, registers, len / 2);
163}
164
165struct reg *
166find_register_by_name (const char *name)
167{
168 int i;
169
170 for (i = 0; i < num_registers; i++)
171 if (!strcmp (name, reg_defs[i].name))
172 return &reg_defs[i];
173 fatal ("Unknown register %s requested", name);
174 return 0;
175}
176
177int
178find_regno (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 i;
185 fatal ("Unknown register %s requested", name);
186 return -1;
187}
188
189struct reg *
190find_register_by_number (int n)
191{
192 return &reg_defs[n];
193}
194
195int
196register_size (int n)
197{
198 return reg_defs[n].size / 8;
199}
200
f450004a 201static unsigned char *
0d62e5e8 202register_data (int n, int fetch)
0a30fbc4 203{
f450004a
DJ
204 unsigned char *registers
205 = get_regcache (current_inferior, fetch)->registers;
c04a1aa8 206
0a30fbc4
DJ
207 return registers + (reg_defs[n].offset / 8);
208}
209
58caa3dc 210void
0729219d 211supply_register (int n, const void *buf)
58caa3dc 212{
0d62e5e8 213 memcpy (register_data (n, 0), buf, register_size (n));
58caa3dc
DJ
214}
215
216void
0729219d 217supply_register_by_name (const char *name, const void *buf)
58caa3dc
DJ
218{
219 supply_register (find_regno (name), buf);
220}
221
222void
0729219d 223collect_register (int n, void *buf)
58caa3dc 224{
0d62e5e8
DJ
225 memcpy (buf, register_data (n, 1), register_size (n));
226}
227
228void
229collect_register_as_string (int n, char *buf)
230{
231 convert_int_to_ascii (register_data (n, 1), buf, register_size (n));
58caa3dc
DJ
232}
233
234void
0729219d 235collect_register_by_name (const char *name, void *buf)
58caa3dc
DJ
236{
237 collect_register (find_regno (name), buf);
238}
This page took 0.413021 seconds and 4 git commands to generate.