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