Correctly parse register values provided by the monitor.
authorJim Blandy <jimb@codesourcery.com>
Fri, 7 Sep 2001 21:27:36 +0000 (21:27 +0000)
committerJim Blandy <jimb@codesourcery.com>
Fri, 7 Sep 2001 21:27:36 +0000 (21:27 +0000)
* 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.

gdb/ChangeLog
gdb/Makefile.in
gdb/rom68k-rom.c

index 2954beb5e0fdd25e1d9e3463c3da0e422823b4d5..28acf240e89de8c0f1050de2de6c7a363a38fcef 100644 (file)
@@ -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
index ec281ac7dce085c9ba80cb399ed5f541ac4be80d..5844aeace91567ae79f9048bece664f4fdea3b68 100644 (file)
@@ -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 \
index 5ef2fe5c4ced131b8fd3c7816df2d294c0d1022e..0b1c9ed01570dcafb9354aec5369302389dadb40 100644 (file)
 #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.