198944Sobrien/* Register support routines for the remote server for GDB. 2130803Smarcel Copyright 2001, 2002, 2004 398944Sobrien Free Software Foundation, Inc. 498944Sobrien 598944Sobrien This file is part of GDB. 698944Sobrien 798944Sobrien This program is free software; you can redistribute it and/or modify 898944Sobrien it under the terms of the GNU General Public License as published by 998944Sobrien the Free Software Foundation; either version 2 of the License, or 1098944Sobrien (at your option) any later version. 1198944Sobrien 1298944Sobrien This program is distributed in the hope that it will be useful, 1398944Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 1498944Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1598944Sobrien GNU General Public License for more details. 1698944Sobrien 1798944Sobrien You should have received a copy of the GNU General Public License 1898944Sobrien along with this program; if not, write to the Free Software 1998944Sobrien Foundation, Inc., 59 Temple Place - Suite 330, 2098944Sobrien Boston, MA 02111-1307, USA. */ 2198944Sobrien 2298944Sobrien#include "server.h" 2398944Sobrien#include "regdef.h" 2498944Sobrien 2598944Sobrien#include <stdlib.h> 2698944Sobrien#include <string.h> 2798944Sobrien 28130803Smarcel/* The private data for the register cache. Note that we have one 29130803Smarcel per inferior; this is primarily for simplicity, as the performance 30130803Smarcel benefit is minimal. */ 31130803Smarcel 32130803Smarcelstruct inferior_regcache_data 33130803Smarcel{ 34130803Smarcel int registers_valid; 35130803Smarcel char *registers; 36130803Smarcel}; 37130803Smarcel 3898944Sobrienstatic int register_bytes; 3998944Sobrien 4098944Sobrienstatic struct reg *reg_defs; 4198944Sobrienstatic int num_registers; 4298944Sobrien 4398944Sobrienconst char **gdbserver_expedite_regs; 4498944Sobrien 45130803Smarcelstatic struct inferior_regcache_data * 46130803Smarcelget_regcache (struct thread_info *inf, int fetch) 47130803Smarcel{ 48130803Smarcel struct inferior_regcache_data *regcache; 49130803Smarcel 50130803Smarcel regcache = (struct inferior_regcache_data *) inferior_regcache_data (inf); 51130803Smarcel 52130803Smarcel if (regcache == NULL) 53130803Smarcel fatal ("no register cache"); 54130803Smarcel 55130803Smarcel /* FIXME - fetch registers for INF */ 56130803Smarcel if (fetch && regcache->registers_valid == 0) 57130803Smarcel { 58130803Smarcel fetch_inferior_registers (0); 59130803Smarcel regcache->registers_valid = 1; 60130803Smarcel } 61130803Smarcel 62130803Smarcel return regcache; 63130803Smarcel} 64130803Smarcel 65130803Smarcelvoid 66130803Smarcelregcache_invalidate_one (struct inferior_list_entry *entry) 67130803Smarcel{ 68130803Smarcel struct thread_info *thread = (struct thread_info *) entry; 69130803Smarcel struct inferior_regcache_data *regcache; 70130803Smarcel 71130803Smarcel regcache = (struct inferior_regcache_data *) inferior_regcache_data (thread); 72130803Smarcel 73130803Smarcel if (regcache->registers_valid) 74130803Smarcel { 75130803Smarcel struct thread_info *saved_inferior = current_inferior; 76130803Smarcel 77130803Smarcel current_inferior = thread; 78130803Smarcel store_inferior_registers (-1); 79130803Smarcel current_inferior = saved_inferior; 80130803Smarcel } 81130803Smarcel 82130803Smarcel regcache->registers_valid = 0; 83130803Smarcel} 84130803Smarcel 85130803Smarcelvoid 86130803Smarcelregcache_invalidate () 87130803Smarcel{ 88130803Smarcel for_each_inferior (&all_threads, regcache_invalidate_one); 89130803Smarcel} 90130803Smarcel 9198944Sobrienint 9298944Sobrienregisters_length (void) 9398944Sobrien{ 9498944Sobrien return 2 * register_bytes; 9598944Sobrien} 9698944Sobrien 97130803Smarcelvoid * 98130803Smarcelnew_register_cache (void) 99130803Smarcel{ 100130803Smarcel struct inferior_regcache_data *regcache; 101130803Smarcel 102130803Smarcel regcache = malloc (sizeof (*regcache)); 103130803Smarcel 104130803Smarcel /* Make sure to zero-initialize the register cache when it is created, 105130803Smarcel in case there are registers the target never fetches. This way they'll 106130803Smarcel read as zero instead of garbage. */ 107130803Smarcel regcache->registers = calloc (1, register_bytes); 108130803Smarcel if (regcache->registers == NULL) 109130803Smarcel fatal ("Could not allocate register cache."); 110130803Smarcel 111130803Smarcel regcache->registers_valid = 0; 112130803Smarcel 113130803Smarcel return regcache; 114130803Smarcel} 115130803Smarcel 11698944Sobrienvoid 117130803Smarcelfree_register_cache (void *regcache_p) 118130803Smarcel{ 119130803Smarcel struct inferior_regcache_data *regcache 120130803Smarcel = (struct inferior_regcache_data *) regcache_p; 121130803Smarcel 122130803Smarcel free (regcache->registers); 123130803Smarcel free (regcache); 124130803Smarcel} 125130803Smarcel 126130803Smarcelvoid 12798944Sobrienset_register_cache (struct reg *regs, int n) 12898944Sobrien{ 12998944Sobrien int offset, i; 13098944Sobrien 13198944Sobrien reg_defs = regs; 13298944Sobrien num_registers = n; 13398944Sobrien 13498944Sobrien offset = 0; 13598944Sobrien for (i = 0; i < n; i++) 13698944Sobrien { 13798944Sobrien regs[i].offset = offset; 13898944Sobrien offset += regs[i].size; 13998944Sobrien } 14098944Sobrien 14198944Sobrien register_bytes = offset / 8; 14298944Sobrien} 14398944Sobrien 14498944Sobrienvoid 14598944Sobrienregisters_to_string (char *buf) 14698944Sobrien{ 147130803Smarcel char *registers = get_regcache (current_inferior, 1)->registers; 148130803Smarcel 14998944Sobrien convert_int_to_ascii (registers, buf, register_bytes); 15098944Sobrien} 15198944Sobrien 15298944Sobrienvoid 15398944Sobrienregisters_from_string (char *buf) 15498944Sobrien{ 15598944Sobrien int len = strlen (buf); 156130803Smarcel char *registers = get_regcache (current_inferior, 1)->registers; 15798944Sobrien 15898944Sobrien if (len != register_bytes * 2) 15998944Sobrien { 16098944Sobrien warning ("Wrong sized register packet (expected %d bytes, got %d)", 2*register_bytes, len); 16198944Sobrien if (len > register_bytes * 2) 16298944Sobrien len = register_bytes * 2; 16398944Sobrien } 16498944Sobrien convert_ascii_to_int (buf, registers, len / 2); 16598944Sobrien} 16698944Sobrien 16798944Sobrienstruct reg * 16898944Sobrienfind_register_by_name (const char *name) 16998944Sobrien{ 17098944Sobrien int i; 17198944Sobrien 17298944Sobrien for (i = 0; i < num_registers; i++) 17398944Sobrien if (!strcmp (name, reg_defs[i].name)) 17498944Sobrien return ®_defs[i]; 17598944Sobrien fatal ("Unknown register %s requested", name); 17698944Sobrien return 0; 17798944Sobrien} 17898944Sobrien 17998944Sobrienint 18098944Sobrienfind_regno (const char *name) 18198944Sobrien{ 18298944Sobrien int i; 18398944Sobrien 18498944Sobrien for (i = 0; i < num_registers; i++) 18598944Sobrien if (!strcmp (name, reg_defs[i].name)) 18698944Sobrien return i; 18798944Sobrien fatal ("Unknown register %s requested", name); 18898944Sobrien return -1; 18998944Sobrien} 19098944Sobrien 19198944Sobrienstruct reg * 19298944Sobrienfind_register_by_number (int n) 19398944Sobrien{ 19498944Sobrien return ®_defs[n]; 19598944Sobrien} 19698944Sobrien 19798944Sobrienint 19898944Sobrienregister_size (int n) 19998944Sobrien{ 20098944Sobrien return reg_defs[n].size / 8; 20198944Sobrien} 20298944Sobrien 203130803Smarcelstatic char * 204130803Smarcelregister_data (int n, int fetch) 20598944Sobrien{ 206130803Smarcel char *registers = get_regcache (current_inferior, fetch)->registers; 207130803Smarcel 20898944Sobrien return registers + (reg_defs[n].offset / 8); 20998944Sobrien} 21098944Sobrien 21198944Sobrienvoid 212130803Smarcelsupply_register (int n, const void *buf) 21398944Sobrien{ 214130803Smarcel memcpy (register_data (n, 0), buf, register_size (n)); 21598944Sobrien} 21698944Sobrien 21798944Sobrienvoid 218130803Smarcelsupply_register_by_name (const char *name, const void *buf) 21998944Sobrien{ 22098944Sobrien supply_register (find_regno (name), buf); 22198944Sobrien} 22298944Sobrien 22398944Sobrienvoid 224130803Smarcelcollect_register (int n, void *buf) 22598944Sobrien{ 226130803Smarcel memcpy (buf, register_data (n, 1), register_size (n)); 22798944Sobrien} 22898944Sobrien 22998944Sobrienvoid 230130803Smarcelcollect_register_as_string (int n, char *buf) 23198944Sobrien{ 232130803Smarcel convert_int_to_ascii (register_data (n, 1), buf, register_size (n)); 233130803Smarcel} 234130803Smarcel 235130803Smarcelvoid 236130803Smarcelcollect_register_by_name (const char *name, void *buf) 237130803Smarcel{ 23898944Sobrien collect_register (find_regno (name), buf); 23998944Sobrien} 240