diff options
Diffstat (limited to 'contrib/gdb/gdb/gdbserver/regcache.c')
-rw-r--r-- | contrib/gdb/gdb/gdbserver/regcache.c | 118 |
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); } |