diff options
-rw-r--r-- | gdb/ChangeLog | 11 | ||||
-rw-r--r-- | gdb/Makefile.in | 3 | ||||
-rw-r--r-- | gdb/rom68k-rom.c | 80 |
3 files changed, 92 insertions, 2 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 2954beb..28acf24 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,14 @@ +2001-09-07 Jim Blandy <jimb@redhat.com> + + Correctly parse register values provided by the monitor. + * rom68k-rom.c: #include "value.h". + (is_hex_digit, hex_digit_value, is_whitespace, + rom68k_supply_one_register): New static functions. + (rom68k_supply_register): Call rom68k_supply_one_register, instead + of monitor_supply_register; the latter was incorrectly parsing + the values. + * Makefile.in (rom68k-rom.o): Note that this now #includes value.h. + 2001-09-07 Mark Kettenis <kettenis@gnu.org> * config/rs6000/xm-rs6000.h (setpgrp): Remove macro. GDB defaults diff --git a/gdb/Makefile.in b/gdb/Makefile.in index ec281ac..5844aea 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -1912,7 +1912,8 @@ remote-nrom.o: remote-nrom.c $(bfd_h) gdb_wait.h $(defs_h) $(gdbcmd_h) \ $(inferior_h) $(remote_utils_h) $(symfile_h) terminal.h rom68k-rom.o: rom68k-rom.c monitor.h $(bfd_h) gdb_wait.h $(defs_h) \ - $(gdbcmd_h) $(inferior_h) $(target_h) serial.h terminal.h $(regcache_h) + $(gdbcmd_h) $(inferior_h) $(target_h) serial.h terminal.h \ + $(regcache_h) $(value_h) rs6000-nat.o: rs6000-nat.c $(bfd_h) $(defs_h) $(inferior_h) $(target_h) \ $(gdbcore_h) xcoffsolib.h $(symfile_h) objfiles.h gdb-stabs.h \ diff --git a/gdb/rom68k-rom.c b/gdb/rom68k-rom.c index 5ef2fe5..0b1c9ed 100644 --- a/gdb/rom68k-rom.c +++ b/gdb/rom68k-rom.c @@ -25,9 +25,87 @@ #include "monitor.h" #include "serial.h" #include "regcache.h" +#include "value.h" static void rom68k_open (char *args, int from_tty); +/* Return true if C is a hex digit. + We can't use isxdigit here: that is affected by the current locale; + ROM68K is not. */ +static int +is_hex_digit (int c) +{ + return (('0' <= c && c <= '9') + || ('a' <= c && c <= 'f') + || ('A' <= c && c <= 'F')); +} + + +/* Convert hex digit A to a number. */ +static int +hex_digit_value (int a) +{ + if (a >= '0' && a <= '9') + return a - '0'; + else if (a >= 'a' && a <= 'f') + return a - 'a' + 10; + else if (a >= 'A' && a <= 'F') + return a - 'A' + 10; + else + error ("Invalid hex digit %d", a); +} + + +/* Return true iff C is a whitespace character. + We can't use isspace here: that is affected by the current locale; + ROM68K is not. */ +static int +is_whitespace (int c) +{ + return (c == ' ' + || c == '\r' + || c == '\n' + || c == '\t' + || c == '\f'); +} + + +/* Parse a string of hex digits starting at HEX, supply them as the + value of register REGNO, skip any whitespace, and return a pointer + to the next character. + + There is a function in monitor.c, monitor_supply_register, which is + supposed to do this job. However, there is some rather odd stuff + in there (whitespace characters don't terminate numbers, for + example) that is incorrect for ROM68k. It's basically impossible + to safely tweak monitor_supply_register --- it's used by a zillion + other monitors; who knows what behaviors they're depending on. So + instead, we'll just use our own function, which can behave exactly + the way we want it to. */ +static char * +rom68k_supply_one_register (int regno, unsigned char *hex) +{ + ULONGEST value; + unsigned char regbuf[MAX_REGISTER_RAW_SIZE]; + + value = 0; + while (*hex != '\0') + if (is_hex_digit (*hex)) + value = (value * 16) + hex_digit_value (*hex++); + else + break; + + /* Skip any whitespace. */ + while (is_whitespace (*hex)) + hex++; + + store_unsigned_integer (regbuf, REGISTER_RAW_SIZE (regno), value); + supply_register (regno, regbuf); + + return hex; +} + + static void rom68k_supply_register (char *regname, int regnamelen, char *val, int vallen) { @@ -71,7 +149,7 @@ rom68k_supply_register (char *regname, int regnamelen, char *val, int vallen) if (regno >= 0) while (numregs-- > 0) - val = monitor_supply_register (regno++, val); + val = rom68k_supply_one_register (regno++, val); } /* This array of registers need to match the indexes used by GDB. |