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 &reg_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 &reg_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