summaryrefslogtreecommitdiffstats
path: root/contrib/gdb/gdb/gdbserver/regcache.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gdb/gdb/gdbserver/regcache.c')
-rw-r--r--contrib/gdb/gdb/gdbserver/regcache.c118
1 files changed, 105 insertions, 13 deletions
diff --git a/contrib/gdb/gdb/gdbserver/regcache.c b/contrib/gdb/gdb/gdbserver/regcache.c
index bec20bb..bc64ebc 100644
--- a/contrib/gdb/gdb/gdbserver/regcache.c
+++ b/contrib/gdb/gdb/gdbserver/regcache.c
@@ -1,5 +1,5 @@
/* Register support routines for the remote server for GDB.
- Copyright 2001, 2002
+ Copyright 2001, 2002, 2004
Free Software Foundation, Inc.
This file is part of GDB.
@@ -25,7 +25,16 @@
#include <stdlib.h>
#include <string.h>
-static char *registers;
+/* The private data for the register cache. Note that we have one
+ per inferior; this is primarily for simplicity, as the performance
+ benefit is minimal. */
+
+struct inferior_regcache_data
+{
+ int registers_valid;
+ char *registers;
+};
+
static int register_bytes;
static struct reg *reg_defs;
@@ -33,12 +42,87 @@ static int num_registers;
const char **gdbserver_expedite_regs;
+static struct inferior_regcache_data *
+get_regcache (struct thread_info *inf, int fetch)
+{
+ struct inferior_regcache_data *regcache;
+
+ regcache = (struct inferior_regcache_data *) inferior_regcache_data (inf);
+
+ if (regcache == NULL)
+ fatal ("no register cache");
+
+ /* FIXME - fetch registers for INF */
+ if (fetch && regcache->registers_valid == 0)
+ {
+ fetch_inferior_registers (0);
+ regcache->registers_valid = 1;
+ }
+
+ return regcache;
+}
+
+void
+regcache_invalidate_one (struct inferior_list_entry *entry)
+{
+ struct thread_info *thread = (struct thread_info *) entry;
+ struct inferior_regcache_data *regcache;
+
+ regcache = (struct inferior_regcache_data *) inferior_regcache_data (thread);
+
+ if (regcache->registers_valid)
+ {
+ struct thread_info *saved_inferior = current_inferior;
+
+ current_inferior = thread;
+ store_inferior_registers (-1);
+ current_inferior = saved_inferior;
+ }
+
+ regcache->registers_valid = 0;
+}
+
+void
+regcache_invalidate ()
+{
+ for_each_inferior (&all_threads, regcache_invalidate_one);
+}
+
int
registers_length (void)
{
return 2 * register_bytes;
}
+void *
+new_register_cache (void)
+{
+ struct inferior_regcache_data *regcache;
+
+ regcache = malloc (sizeof (*regcache));
+
+ /* Make sure to zero-initialize the register cache when it is created,
+ in case there are registers the target never fetches. This way they'll
+ read as zero instead of garbage. */
+ regcache->registers = calloc (1, register_bytes);
+ if (regcache->registers == NULL)
+ fatal ("Could not allocate register cache.");
+
+ regcache->registers_valid = 0;
+
+ return regcache;
+}
+
+void
+free_register_cache (void *regcache_p)
+{
+ struct inferior_regcache_data *regcache
+ = (struct inferior_regcache_data *) regcache_p;
+
+ free (regcache->registers);
+ free (regcache);
+}
+
void
set_register_cache (struct reg *regs, int n)
{
@@ -55,14 +139,13 @@ set_register_cache (struct reg *regs, int n)
}
register_bytes = offset / 8;
- registers = malloc (offset / 8);
- if (!registers)
- fatal ("Could not allocate register cache.");
}
void
registers_to_string (char *buf)
{
+ char *registers = get_regcache (current_inferior, 1)->registers;
+
convert_int_to_ascii (registers, buf, register_bytes);
}
@@ -70,6 +153,7 @@ void
registers_from_string (char *buf)
{
int len = strlen (buf);
+ char *registers = get_regcache (current_inferior, 1)->registers;
if (len != register_bytes * 2)
{
@@ -116,32 +200,40 @@ register_size (int n)
return reg_defs[n].size / 8;
}
-char *
-register_data (int n)
+static char *
+register_data (int n, int fetch)
{
+ char *registers = get_regcache (current_inferior, fetch)->registers;
+
return registers + (reg_defs[n].offset / 8);
}
void
-supply_register (int n, const char *buf)
+supply_register (int n, const void *buf)
{
- memcpy (register_data (n), buf, register_size (n));
+ memcpy (register_data (n, 0), buf, register_size (n));
}
void
-supply_register_by_name (const char *name, const char *buf)
+supply_register_by_name (const char *name, const void *buf)
{
supply_register (find_regno (name), buf);
}
void
-collect_register (int n, char *buf)
+collect_register (int n, void *buf)
+{
+ memcpy (buf, register_data (n, 1), register_size (n));
+}
+
+void
+collect_register_as_string (int n, char *buf)
{
- memcpy (buf, register_data (n), register_size (n));
+ convert_int_to_ascii (register_data (n, 1), buf, register_size (n));
}
void
-collect_register_by_name (const char *name, char *buf)
+collect_register_by_name (const char *name, void *buf)
{
collect_register (find_regno (name), buf);
}
OpenPOWER on IntegriCloud