1 /* Register support routines for the remote server for GDB. 2 Copyright (C) 2001, 2002, 2004, 2005, 2011 3 Free Software Foundation, Inc. 4 5 This file is part of GDB. 6 It has been modified to integrate it in valgrind 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 2 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 51 Franklin Street, Fifth Floor, 21 Boston, MA 02110-1301, USA. */ 22 23 #include "server.h" 24 #include "regdef.h" 25 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 30 struct inferior_regcache_data 31 { 32 int registers_valid; 33 unsigned char *registers; 34 Bool *register_supplied; /* set to True once it has been supplied */ 35 }; 36 37 static int register_bytes; 38 39 static struct reg *reg_defs; 40 static int num_registers; 41 42 const char **gdbserver_expedite_regs; 43 44 static 45 struct inferior_regcache_data * get_regcache (struct thread_info *inf, 46 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\n"); 54 55 /* FIXME - fetch registers for INF */ 56 if (fetch && regcache->registers_valid == 0) { 57 valgrind_fetch_registers (0); 58 regcache->registers_valid = 1; 59 } 60 61 return regcache; 62 } 63 64 void regcache_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 struct thread_info *saved_inferior = current_inferior; 73 74 current_inferior = thread; 75 valgrind_store_registers (-1); 76 current_inferior = saved_inferior; 77 } 78 79 regcache->registers_valid = 0; 80 } 81 82 void regcache_invalidate () 83 { 84 for_each_inferior (&all_threads, regcache_invalidate_one); 85 } 86 87 int registers_length (void) 88 { 89 return 2 * register_bytes; 90 } 91 92 void *new_register_cache (void) 93 { 94 struct inferior_regcache_data *regcache; 95 96 regcache = malloc (sizeof (*regcache)); 97 98 /* Make sure to zero-initialize the register cache when it is created, 99 in case there are registers the target never fetches. This way they'll 100 read as zero instead of garbage. */ 101 regcache->registers = calloc (1, register_bytes); 102 if (regcache->registers == NULL) 103 fatal ("Could not allocate register cache.\n"); 104 105 regcache->register_supplied = calloc (1, num_registers); 106 if (regcache->register_supplied == NULL) 107 fatal ("Could not allocate register_supplied cache.\n"); 108 109 regcache->registers_valid = 0; 110 111 return regcache; 112 } 113 114 void free_register_cache (void *regcache_p) 115 { 116 struct inferior_regcache_data *regcache 117 = (struct inferior_regcache_data *) regcache_p; 118 119 free (regcache->registers); 120 free (regcache->register_supplied); 121 free (regcache); 122 } 123 124 /* if a regcache exists for entry, reallocate it. 125 This is needed if the shadow registers are added. 126 In such a case, a 2nd call to set_register_cache is done 127 which will cause the reallocation of already created caches. */ 128 static 129 void regcache_realloc_one (struct inferior_list_entry *entry) 130 { 131 struct thread_info *thread = (struct thread_info *) entry; 132 struct inferior_regcache_data *regcache; 133 134 regcache = (struct inferior_regcache_data *) inferior_regcache_data (thread); 135 136 if (regcache) { 137 free_register_cache (regcache); 138 set_inferior_regcache_data (thread, new_register_cache ()); 139 } 140 } 141 142 void set_register_cache (struct reg *regs, int n) 143 { 144 int offset, i; 145 146 reg_defs = regs; 147 num_registers = n; 148 149 offset = 0; 150 for (i = 0; i < n; i++) { 151 regs[i].offset = offset; 152 offset += regs[i].size; 153 } 154 155 register_bytes = offset / 8; 156 157 for_each_inferior (&all_threads, regcache_realloc_one); 158 } 159 160 void registers_to_string (char *buf) 161 { 162 unsigned char *registers = get_regcache (current_inferior, 1)->registers; 163 164 convert_int_to_ascii (registers, buf, register_bytes); 165 } 166 167 void registers_from_string (char *buf) 168 { 169 int len = strlen (buf); 170 unsigned char *registers = get_regcache (current_inferior, 1)->registers; 171 172 if (len != register_bytes * 2) { 173 warning ("Wrong sized register packet (expected %d bytes, got %d)\n", 174 2*register_bytes, len); 175 if (len > register_bytes * 2) 176 len = register_bytes * 2; 177 } 178 convert_ascii_to_int (buf, registers, len / 2); 179 } 180 181 int find_regno (const char *name) 182 { 183 int i; 184 185 for (i = 0; i < num_registers; i++) 186 if (!strcmp (name, reg_defs[i].name)) 187 return i; 188 fatal ("Unknown register %s requested\n", name); 189 return -1; 190 } 191 192 struct reg *find_register_by_number (int n) 193 { 194 return ®_defs[n]; 195 } 196 197 int register_size (int n) 198 { 199 return reg_defs[n].size / 8; 200 } 201 202 static 203 unsigned char *register_data (int n, int fetch) 204 { 205 unsigned char *registers 206 = get_regcache (current_inferior, fetch)->registers; 207 208 return registers + (reg_defs[n].offset / 8); 209 } 210 static 211 unsigned char *register_data_for_supply (int n, int fetch, Bool *mod) 212 { 213 struct inferior_regcache_data * cache 214 = get_regcache (current_inferior, fetch); 215 unsigned char *registers = cache->registers; 216 217 if (cache->register_supplied[n]) 218 *mod = False; 219 else 220 *mod = True; 221 cache->register_supplied[n] = True; 222 return registers + (reg_defs[n].offset / 8); 223 } 224 225 void supply_register (int n, const void *buf, Bool *mod) 226 { 227 Bool new; 228 VG_(dmemcpy) (register_data_for_supply (n, 0, &new), 229 buf, register_size (n), mod); 230 if (new) 231 *mod = True; 232 } 233 234 void supply_register_from_string (int n, const char *buf, Bool *mod) 235 { 236 Bool new; 237 unsigned char bytes_register[register_size (n)]; 238 convert_ascii_to_int ((char *) buf, bytes_register, register_size (n)); 239 VG_(dmemcpy) (register_data_for_supply (n, 0, &new), 240 bytes_register, register_size (n), mod); 241 if (new) 242 *mod = True; 243 } 244 245 void supply_register_by_name (const char *name, const void *buf, Bool *mod) 246 { 247 supply_register (find_regno (name), buf, mod); 248 } 249 250 void collect_register (int n, void *buf) 251 { 252 VG_(memcpy) (buf, register_data (n, 1), register_size (n)); 253 } 254 255 void collect_register_as_string (int n, char *buf) 256 { 257 convert_int_to_ascii (register_data (n, 1), buf, register_size (n)); 258 } 259 260 void collect_register_by_name (const char *name, void *buf) 261 { 262 collect_register (find_regno (name), buf); 263 } 264