aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog21
-rw-r--r--gdb/config/mips/tm-tx39.h17
-rw-r--r--gdb/config/mips/tm-tx39l.h17
-rw-r--r--gdb/config/mips/tx39.mt2
-rw-r--r--gdb/config/mips/tx39l.mt2
-rw-r--r--gdb/defs.h6
-rw-r--r--gdb/dsrec.c31
-rw-r--r--gdb/dve3900-rom.c466
-rw-r--r--gdb/monitor.c247
-rw-r--r--gdb/monitor.h4
-rw-r--r--gdb/utils.c99
11 files changed, 792 insertions, 120 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index a72276f..b15f4eb 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,24 @@
+Mon Dec 29 21:25:34 1997 Mark Alexander <marka@cygnus.com>
+
+ * dve3900-rom.c: New file to support Densan DVE-R3900/20 board.
+ * monitor.c (monitor_debug): Move to utils.c, rename to puts_debug.
+ (monitor_write_memory, monitor_read_memory, monitor_insert_breakpoint,
+ monitor_remove_breakpoint): Remove useless address bits if current
+ monitor has MO_ADDR_BITS_REMOVE flag.
+ * monitor.h (MO_ADDR_BITS_REMOVE): Define.
+ * utils.c (puts_debug): Formerly monitor_debug from monitor.c;
+ move here and make public. Add better support for carriage returns.
+ * defs.h (puts_debug): Declare.
+ * dsrec.c (load_srec): Use puts_debug to print remotedebug information.
+ Output header record correctly.
+ (make_srec): Output a header record instead of a termination record
+ if sect is non-NULL (value is ignored), but abfd is NULL.
+ * config/mips/tm-tx39.h (DEFAULT_MIPS_TYPE): Remove definition.
+ (REGISTER_NAMES): Define to add R3900-specific registers.
+ * config/mips/tm-tx39l.h: Ditto.
+ * config/mips/tx39.mt (TDEPFILES): Add dve3900-rom.o and support files.
+ * config/mips/tx39l.mt: Ditto.
+
Wed Dec 24 12:48:48 1997 Stan Shebs <shebs@andros.cygnus.com>
* dsrec.c: Cosmetic improvements.
diff --git a/gdb/config/mips/tm-tx39.h b/gdb/config/mips/tm-tx39.h
index f46ee21..7db466a 100644
--- a/gdb/config/mips/tm-tx39.h
+++ b/gdb/config/mips/tm-tx39.h
@@ -21,5 +21,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "mips/tm-bigmips.h"
-#undef DEFAULT_MIPS_TYPE
-#define DEFAULT_MIPS_TYPE "r3900"
+#undef REGISTER_NAMES
+#define REGISTER_NAMES \
+ { "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", \
+ "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", \
+ "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", \
+ "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", \
+ "sr", "lo", "hi", "bad", "cause","pc", \
+ "", "", "", "", "", "", "", "", \
+ "", "", "", "", "", "", "", "", \
+ "", "", "", "", "", "", "", "", \
+ "", "", "", "", "", "", "", "", \
+ "", "", "", "", \
+ "", "", "", "", "", "", "", "", \
+ "", "", "config", "cache", "debug", "depc", "epc", "" \
+ }
diff --git a/gdb/config/mips/tm-tx39l.h b/gdb/config/mips/tm-tx39l.h
index 7da1320..53be627 100644
--- a/gdb/config/mips/tm-tx39l.h
+++ b/gdb/config/mips/tm-tx39l.h
@@ -21,5 +21,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "mips/tm-mips.h"
-#undef DEFAULT_MIPS_TYPE
-#define DEFAULT_MIPS_TYPE "r3900"
+#undef REGISTER_NAMES
+#define REGISTER_NAMES \
+ { "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", \
+ "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", \
+ "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", \
+ "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", \
+ "sr", "lo", "hi", "bad", "cause","pc", \
+ "", "", "", "", "", "", "", "", \
+ "", "", "", "", "", "", "", "", \
+ "", "", "", "", "", "", "", "", \
+ "", "", "", "", "", "", "", "", \
+ "", "", "", "", \
+ "", "", "", "", "", "", "", "", \
+ "", "", "config", "cache", "debug", "depc", "epc", "" \
+ }
diff --git a/gdb/config/mips/tx39.mt b/gdb/config/mips/tx39.mt
index 6ae1dad..8b4c1a9 100644
--- a/gdb/config/mips/tx39.mt
+++ b/gdb/config/mips/tx39.mt
@@ -1,5 +1,5 @@
# Target: Big-endian mips board, typically an IDT.
-TDEPFILES= mips-tdep.o remote-mips.o remote-array.o
+TDEPFILES= mips-tdep.o remote-mips.o dve3900-rom.o monitor.o dsrec.o
TM_FILE= tm-tx39.h
SIM_OBS = remote-sim.o
SIM = ../sim/mips/libsim.a
diff --git a/gdb/config/mips/tx39l.mt b/gdb/config/mips/tx39l.mt
index fe339d6..3508329 100644
--- a/gdb/config/mips/tx39l.mt
+++ b/gdb/config/mips/tx39l.mt
@@ -1,5 +1,5 @@
# Target: Big-endian mips board, typically an IDT.
-TDEPFILES= mips-tdep.o remote-mips.o remote-array.o
+TDEPFILES= mips-tdep.o remote-mips.o dve3900-rom.o monitor.o dsrec.o
TM_FILE= tm-tx39l.h
SIM_OBS = remote-sim.o
SIM = ../sim/mips/libsim.a
diff --git a/gdb/defs.h b/gdb/defs.h
index 7532548..aa5dd5f 100644
--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -118,7 +118,7 @@ enum command_class
all_classes = -2, all_commands = -1,
/* Classes of commands */
no_class = -1, class_run = 0, class_vars, class_stack,
- class_files, class_support, class_info, class_breakpoint,
+ class_files, class_support, class_info, class_breakpoint, class_trace,
class_alias, class_obscure, class_user, class_maintenance,
class_pseudo
};
@@ -309,6 +309,8 @@ extern void puts_filtered PARAMS ((const char *));
extern void puts_unfiltered PARAMS ((const char *));
+extern void puts_debug PARAMS ((char *prefix, char *string, char *suffix));
+
extern void vprintf_filtered PARAMS ((const char *, va_list))
ATTR_FORMAT(printf, 1, 0);
@@ -771,7 +773,7 @@ extern void set_architecture_from_file PARAMS ((bfd *));
/* Notify target of a change to the selected architecture. Zero return
status indicates that the target did not like the change. */
extern int (*target_architecture_hook) PARAMS ((const bfd_arch_info_type *ap));
-extern void set_architecture PARAMS ((char *arg, int from_tty));
+extern void set_architecture_from_arch_mach PARAMS ((enum bfd_architecture arch, unsigned long mach));
/* Number of bits in a char or unsigned char for the target machine.
Just like CHAR_BIT in <limits.h> but describes the target machine. */
diff --git a/gdb/dsrec.c b/gdb/dsrec.c
index 03b5517..6a40e7e 100644
--- a/gdb/dsrec.c
+++ b/gdb/dsrec.c
@@ -82,9 +82,12 @@ load_srec (desc, file, load_offset, maxrecsize, flags, hashmark, waitack)
is no data, so len is 0. */
reclen = maxrecsize;
- make_srec (srec, 0, NULL, NULL, 0, &reclen, flags);
+ make_srec (srec, 0, NULL, (asection *)1, 0, &reclen, flags);
if (remote_debug)
- fprintf_unfiltered (gdb_stderr, "%.*s\\r\n", reclen-1, srec);
+ {
+ srec[reclen] = '\0';
+ puts_debug ("sent -->", srec, "<--");
+ }
SERIAL_WRITE (desc, srec, reclen);
for (s = abfd->sections; s; s = s->next)
@@ -93,8 +96,7 @@ load_srec (desc, file, load_offset, maxrecsize, flags, hashmark, waitack)
int numbytes;
bfd_vma addr = bfd_get_section_vma (abfd, s) + load_offset;
bfd_size_type size = bfd_get_section_size_before_reloc (s);
- char * section_name = bfd_get_section_name (abfd, s);
-
+ char * section_name = (char *)bfd_get_section_name (abfd, s);
printf_filtered ("%s\t: 0x%08x .. 0x%08x ",
section_name, (int) addr, (int) addr + size);
gdb_flush (gdb_stdout);
@@ -108,7 +110,10 @@ load_srec (desc, file, load_offset, maxrecsize, flags, hashmark, waitack)
i, &reclen, flags);
if (remote_debug)
- fprintf_unfiltered (gdb_stderr, "%.*s\\r\n", reclen-1, srec);
+ {
+ srec[reclen] = '\0';
+ puts_debug ("sent -->", srec, "<--");
+ }
/* Repeatedly send the S-record until a good
acknowledgement is sent back. */
@@ -145,11 +150,16 @@ load_srec (desc, file, load_offset, maxrecsize, flags, hashmark, waitack)
make_srec (srec, abfd->start_address, NULL, NULL, 0, &reclen, flags);
if (remote_debug)
- fprintf_unfiltered (gdb_stderr, "%.*s\\r\n", reclen-1, srec);
+ {
+ srec[reclen] = '\0';
+ puts_debug ("sent -->", srec, "<--");
+ }
+
SERIAL_WRITE (desc, srec, reclen);
/* Some monitors need these to wake up properly. (Which ones? -sts) */
SERIAL_WRITE (desc, "\r\r", 2);
+ puts_debug ("sent -->", "\r\r", "<---");
SERIAL_FLUSH_INPUT (desc);
@@ -215,6 +225,7 @@ make_srec (srec, targ_addr, abfd, sect, sectoff, maxrecsize, flags)
const static char hextab[] = "0123456789ABCDEF";
const static char data_code_table[] = "123";
const static char term_code_table[] = "987";
+ const static char header_code_table[] = "000";
const static char *formats[] = { "S%c%02X%04X",
"S%c%02X%06X",
"S%c%02X%08X" };
@@ -226,8 +237,8 @@ make_srec (srec, targ_addr, abfd, sect, sectoff, maxrecsize, flags)
if (sect)
{
- tmp = flags; /* Data record */
- code_table = data_code_table;
+ tmp = flags; /* Data or header record */
+ code_table = abfd ? data_code_table : header_code_table;
binbuf = alloca (*maxrecsize/2);
}
else
@@ -249,7 +260,7 @@ make_srec (srec, targ_addr, abfd, sect, sectoff, maxrecsize, flags)
/* Now that we know the address size, we can figure out how much
data this record can hold. */
- if (sect)
+ if (sect && abfd)
{
payload_size = (*maxrecsize - (1 + 1 + 2 + addr_size * 2 + 2)) / 2;
payload_size = min (payload_size, sect->_raw_size - sectoff);
@@ -257,7 +268,7 @@ make_srec (srec, targ_addr, abfd, sect, sectoff, maxrecsize, flags)
bfd_get_section_contents (abfd, sect, binbuf, sectoff, payload_size);
}
else
- payload_size = 0; /* Term packets have no payload */
+ payload_size = 0; /* Term or header packets have no payload */
/* Output the header. */
diff --git a/gdb/dve3900-rom.c b/gdb/dve3900-rom.c
new file mode 100644
index 0000000..511b4fe
--- /dev/null
+++ b/gdb/dve3900-rom.c
@@ -0,0 +1,466 @@
+/* Remote debugging interface for Densan DVE-R3900 ROM monitor for
+ GDB, the GNU debugger.
+ Copyright 1997 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "monitor.h"
+#include "serial.h"
+
+static void r3900_open PARAMS ((char *args, int from_tty));
+
+/* Pointers to static functions in monitor.c for fetching and storing
+ registers. We can't use these function in certain cases where the Densan
+ monitor acts perversely: for registers that it displays in bit-map
+ format, and those that can't be modified at all. In those cases
+ we have to use our own functions to fetch and store their values. */
+
+static void (*orig_monitor_fetch_registers) PARAMS ((int regno));
+static void (*orig_monitor_store_registers) PARAMS ((int regno));
+
+
+/* This array of registers needs to match the indexes used by GDB. The
+ whole reason this exists is because the various ROM monitors use
+ different names than GDB does, and don't support all the registers
+ either. */
+
+static char *r3900_regnames[NUM_REGS] =
+{
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+ "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+
+ "S", /* PS_REGNUM */
+ "l", /* LO_REGNUM */
+ "h", /* HI_REGNUM */
+ "B", /* BADVADDR_REGNUM */
+ "Pcause", /* CAUSE_REGNUM */
+ "p" /* PC_REGNUM */
+};
+
+
+/* Table of register names produced by monitor's register dump command. */
+
+static struct reg_entry
+{
+ char *name;
+ int regno;
+} reg_table[] =
+{
+ { "r0_zero", 0 }, { "r1_at", 1 }, { "r2_v0", 2 }, { "r3_v1", 3 },
+ { "r4_a0", 4 }, { "r5_a1", 5 }, { "r6_a2", 6 }, { "r7_a3", 7 },
+ { "r8_t0", 8 }, { "r9_t1", 9 }, { "r10_t2", 10 }, { "r11_t3", 11 },
+ { "r12_t4", 12 }, { "r13_t5", 13 }, { "r14_t6", 14 }, { "r15_t7", 15 },
+ { "r16_s0", 16 }, { "r17_s1", 17 }, { "r18_s2", 18 }, { "r19_s3", 19 },
+ { "r20_s4", 20 }, { "r21_s5", 21 }, { "r22_s6", 22 }, { "r23_s7", 23 },
+ { "r24_t8", 24 }, { "r25_t9", 25 }, { "r26_k0", 26 }, { "r27_k1", 27 },
+ { "r28_gp", 28 }, { "r29_sp", 29 }, { "r30_fp", 30 }, { "r31_ra", 31 },
+ { "HI", HI_REGNUM },
+ { "LO", LO_REGNUM },
+ { "PC", PC_REGNUM },
+ { "BadV", BADVADDR_REGNUM },
+ { NULL, 0 }
+};
+
+
+/* The monitor prints register values in the form
+
+ regname = xxxx xxxx
+
+ We look up the register name in a table, and remove the embedded space in
+ the hex value before passing it to monitor_supply_register. */
+
+static void
+r3900_supply_register (regname, regnamelen, val, vallen)
+ char *regname;
+ int regnamelen;
+ char *val;
+ int vallen;
+{
+ int regno = -1;
+ int i;
+ char valbuf[10];
+ char *p;
+
+ /* Perform some sanity checks on the register name and value. */
+ if (regnamelen < 2 || regnamelen > 7 || vallen != 9)
+ return;
+
+ /* Look up the register name. */
+ for (i = 0; reg_table[i].name != NULL; i++)
+ {
+ int rlen = strlen (reg_table[i].name);
+ if (rlen == regnamelen && strncmp (regname, reg_table[i].name, rlen) == 0)
+ {
+ regno = reg_table[i].regno;
+ break;
+ }
+ }
+ if (regno == -1)
+ return;
+
+ /* Copy the hex value to a buffer and eliminate the embedded space. */
+ for (i = 0, p = valbuf; i < vallen; i++)
+ if (val[i] != ' ')
+ *p++ = val[i];
+ *p = '\0';
+
+ monitor_supply_register (regno, valbuf);
+}
+
+/* Fetch the BadVaddr register. Unlike the other registers, this
+ one can't be modified, and the monitor won't even prompt to let
+ you modify it. */
+
+static void
+r3900_fetch_badvaddr()
+{
+ char buf[20];
+ int c;
+
+ monitor_printf ("xB\r");
+ monitor_expect ("BadV=", NULL, 0);
+ monitor_expect_prompt (buf, sizeof(buf));
+ monitor_supply_register (BADVADDR_REGNUM, buf);
+}
+
+
+/* Certain registers are "bitmapped", in that the monitor can only display
+ them or let the user modify them as a series of named bitfields.
+ This structure describes a field in a bitmapped register. */
+
+struct bit_field
+{
+ char *prefix; /* string appearing before the value */
+ char *suffix; /* string appearing after the value */
+ char *user_name; /* name used by human when entering field value */
+ int length; /* number of bits in the field */
+ int start; /* starting (least significant) bit number of field */
+};
+
+/* The monitor displays the cache register along with the status register,
+ as if they were a single register. So when we want to fetch the
+ status register, parse but otherwise ignore the fields of the
+ cache register that the monitor displays. Register fields that should
+ be ignored have a length of zero in the tables below. */
+
+static struct bit_field status_fields [] =
+{
+ /* Status register portion */
+ { "SR[<CU=", " ", "cu", 4, 28 },
+ { "RE=", " ", "re", 1, 25 },
+ { "BEV=", " ", "bev", 1, 22 },
+ { "TS=", " ", "ts", 1, 21 },
+ { "Nmi=", " ", "nmi", 1, 20 },
+ { "INT=", " ", "int", 6, 10 },
+ { "SW=", ">]", "sw", 2, 8 },
+ { "[<KUO=", " ", "kuo", 1, 5 },
+ { "IEO=", " ", "ieo", 1, 4 },
+ { "KUP=", " ", "kup", 1, 3 },
+ { "IEP=", " ", "iep", 1, 2 },
+ { "KUC=", " ", "kuc", 1, 1 },
+ { "IEC=", ">]", "iec", 1, 0 },
+
+ /* Cache register portion (dummy for parsing only) */
+ { "CR[<IalO="," ", "ialo", 0, 13 },
+ { "DalO=", " ", "dalo", 0, 12 },
+ { "IalP=", " ", "ialp", 0, 11 },
+ { "DalP=", " ", "dalp", 0, 10 },
+ { "IalC=", " ", "ialc", 0, 9 },
+ { "DalC=", ">] ", "dalc", 0, 8 },
+
+ { NULL, NULL, 0, 0 } /* end of table marker */
+};
+
+
+static struct bit_field cache_fields [] =
+{
+ /* Status register portion (dummy for parsing only) */
+ { "SR[<CU=", " ", "cu", 0, 28 },
+ { "RE=", " ", "re", 0, 25 },
+ { "BEV=", " ", "bev", 0, 22 },
+ { "TS=", " ", "ts", 0, 21 },
+ { "Nmi=", " ", "nmi", 0, 20 },
+ { "INT=", " ", "int", 0, 10 },
+ { "SW=", ">]", "sw", 0, 8 },
+ { "[<KUO=", " ", "kuo", 0, 5 },
+ { "IEO=", " ", "ieo", 0, 4 },
+ { "KUP=", " ", "kup", 0, 3 },
+ { "IEP=", " ", "iep", 0, 2 },
+ { "KUC=", " ", "kuc", 0, 1 },
+ { "IEC=", ">]", "iec", 0, 0 },
+
+ /* Cache register portion */
+ { "CR[<IalO="," ", "ialo", 1, 13 },
+ { "DalO=", " ", "dalo", 1, 12 },
+ { "IalP=", " ", "ialp", 1, 11 },
+ { "DalP=", " ", "dalp", 1, 10 },
+ { "IalC=", " ", "ialc", 1, 9 },
+ { "DalC=", ">] ", "dalc", 1, 8 },
+
+ { NULL, NULL, NULL, 0, 0 } /* end of table marker */
+};
+
+static struct bit_field cause_fields[] =
+{
+ { "<BD=", " ", "bd", 1, 31 },
+ { "CE=", " ", "ce", 2, 28 },
+ { "IP=", " ", "ip", 6, 10 },
+ { "SW=", " ", "sw", 2, 8 },
+ { "EC=", ">]" , "ec", 5, 2 },
+
+ { NULL, NULL, NULL, 0, 0 } /* end of table marker */
+};
+
+
+/* Read a series of bit fields from the monitor, and return their
+ combined binary value. */
+
+static unsigned long
+r3900_fetch_fields (bf)
+ struct bit_field *bf;
+{
+ char buf[20];
+ int c;
+ unsigned long val = 0;
+ unsigned long bits;
+
+ for ( ; bf->prefix != NULL; bf++)
+ {
+ monitor_expect (bf->prefix, NULL, 0); /* get prefix */
+ monitor_expect (bf->suffix, buf, sizeof (buf)); /* hex value, suffix */
+ if (bf->length != 0)
+ {
+ bits = strtoul (buf, NULL, 16); /* get field value */
+ bits &= ((1 << bf->length) - 1); /* mask out useless bits */
+ val |= bits << bf->start; /* insert into register */
+ }
+
+ }
+
+ return val;
+}
+
+static void
+r3900_fetch_bitmapped_register (regno, bf)
+ int regno;
+ struct bit_field *bf;
+{
+ char buf[20];
+ int c;
+ unsigned long val;
+ unsigned long bits;
+ unsigned char regbuf[MAX_REGISTER_RAW_SIZE];
+
+ monitor_printf ("x%s\r", r3900_regnames[regno]);
+ val = r3900_fetch_fields (bf);
+ monitor_printf (".\r");
+ monitor_expect_prompt (NULL, 0);
+
+ /* supply register stores in target byte order, so swap here */
+
+ store_unsigned_integer (regbuf, REGISTER_RAW_SIZE (regno), val);
+ supply_register (regno, regbuf);
+
+}
+
+/* Fetch all registers (if regno is -1), or one register from the
+ monitor. For most registers, we can use the generic monitor_
+ monitor_fetch_registers function. But others are displayed in
+ very unusual fashion and must be handled specially. */
+
+static void
+r3900_fetch_registers (regno)
+ int regno;
+{
+ switch (regno)
+ {
+ case BADVADDR_REGNUM:
+ r3900_fetch_badvaddr ();
+ return;
+ case PS_REGNUM:
+ r3900_fetch_bitmapped_register (PS_REGNUM, status_fields);
+ return;
+ case CAUSE_REGNUM:
+ r3900_fetch_bitmapped_register (CAUSE_REGNUM, cause_fields);
+ return;
+ default:
+ orig_monitor_fetch_registers (regno);
+ }
+}
+
+
+/* Write the new value of the bitmapped register to the monitor. */
+
+static void
+r3900_store_bitmapped_register (regno, bf)
+ int regno;
+ struct bit_field *bf;
+{
+ unsigned long oldval, newval;
+
+ /* Fetch the current value of the register. */
+ monitor_printf ("x%s\r", r3900_regnames[regno]);
+ oldval = r3900_fetch_fields (bf);
+ newval = read_register (regno);
+
+ /* To save time, write just the fields that have changed. */
+ for ( ; bf->prefix != NULL; bf++)
+ {
+ if (bf->length != 0)
+ {
+ unsigned long oldbits, newbits, mask;
+
+ mask = (1 << bf->length) - 1;
+ oldbits = (oldval >> bf->start) & mask;
+ newbits = (newval >> bf->start) & mask;
+ if (oldbits != newbits)
+ monitor_printf ("%s %x ", bf->user_name, newbits);
+ }
+ }
+
+ monitor_printf (".\r");
+ monitor_expect_prompt (NULL, 0);
+}
+
+static void
+r3900_store_registers (regno)
+ int regno;
+{
+ switch (regno)
+ {
+ case PS_REGNUM:
+ r3900_store_bitmapped_register (PS_REGNUM, status_fields);
+ return;
+ case CAUSE_REGNUM:
+ r3900_store_bitmapped_register (CAUSE_REGNUM, cause_fields);
+ return;
+ default:
+ orig_monitor_store_registers (regno);
+ }
+}
+
+static void
+r3900_load (monops, filename, from_tty)
+ struct monitor_ops *monops;
+ char *filename;
+ int from_tty;
+{
+ extern int inferior_pid;
+
+ generic_load (filename, from_tty);
+
+ /* Finally, make the PC point at the start address */
+ if (exec_bfd)
+ write_pc (bfd_get_start_address (exec_bfd));
+
+ inferior_pid = 0; /* No process now */
+}
+
+
+static struct target_ops r3900_ops;
+
+/* Commands to send to the monitor when first connecting:
+ * The bare carriage return forces a prompt from the monitor
+ (monitor doesn't prompt after a reset).
+ * The "Xtr" command causes subsequent "t" (trace) commands to display
+ the general registers only.
+ * The "Xxr" command does the same thing for the "x" (examine
+ registers) command.
+ * The "bx" command clears all breakpoints.
+*/
+
+static char *r3900_inits[] = {"\r", "Xtr\r", "Xxr\r", "bx\r", NULL};
+
+static struct monitor_ops r3900_cmds;
+
+static void
+r3900_open (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ monitor_open (args, &r3900_cmds, from_tty);
+}
+
+void
+_initialize_r3900_rom ()
+{
+ r3900_cmds.flags = MO_HANDLE_NL |
+ MO_NO_ECHO_ON_OPEN |
+ MO_ADDR_BITS_REMOVE |
+ MO_CLR_BREAK_USES_ADDR;
+
+ r3900_cmds.init = r3900_inits;
+ r3900_cmds.cont = "g\r";
+ r3900_cmds.step = "t\r";
+ r3900_cmds.set_break = "b %Lx\r"; /* COREADDR */
+ r3900_cmds.clr_break = "b %Lx,0\r"; /* COREADDR */
+ r3900_cmds.fill = "fx %Lx s %x %x\r"; /* COREADDR, len, val */
+
+ r3900_cmds.setmem.cmdb = "sx %Lx %x\r"; /* COREADDR, val */
+ r3900_cmds.setmem.cmdw = "sh %Lx %x\r"; /* COREADDR, val */
+ r3900_cmds.setmem.cmdl = "sw %Lx %x\r"; /* COREADDR, val */
+
+ r3900_cmds.getmem.cmdb = "dx %Lx s %x\r"; /* COREADDR, len */
+ r3900_cmds.getmem.resp_delim = " : ";
+
+ r3900_cmds.setreg.cmd = "x%s %x\r"; /* regname, val */
+
+ r3900_cmds.getreg.cmd = "x%s\r"; /* regname */
+ r3900_cmds.getreg.resp_delim = "=";
+ r3900_cmds.getreg.term = " ";
+ r3900_cmds.getreg.term_cmd = ".\r";
+
+ r3900_cmds.dump_registers = "x\r";
+ r3900_cmds.register_pattern =
+ "\\([a-zA-Z0-9_]+\\) *=\\([0-9a-f]+ [0-9a-f]+\\b\\)";
+ r3900_cmds.supply_register = r3900_supply_register;
+ /* S-record download, via "keyboard port". */
+ r3900_cmds.load = "r0\r";
+#if 0 /* FIXME - figure out how to get fast load to work */
+ r3900_cmds.load_routine = r3900_load;
+#endif
+ r3900_cmds.prompt = "#";
+ r3900_cmds.line_term = "\r";
+ r3900_cmds.target = &r3900_ops;
+ r3900_cmds.stopbits = SERIAL_1_STOPBITS;
+ r3900_cmds.regnames = r3900_regnames;
+ r3900_cmds.magic = MONITOR_OPS_MAGIC;
+
+ init_monitor_ops (&r3900_ops);
+
+ r3900_ops.to_shortname = "r3900";
+ r3900_ops.to_longname = "R3900 monitor";
+ r3900_ops.to_doc = "Debug using the DVE R3900 monitor.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
+ r3900_ops.to_open = r3900_open;
+
+ /* Override the functions to fetch and store registers. But save the
+ addresses of the default functions, because we will use those functions
+ for "normal" registers. */
+
+ orig_monitor_fetch_registers = r3900_ops.to_fetch_registers;
+ orig_monitor_store_registers = r3900_ops.to_store_registers;
+ r3900_ops.to_fetch_registers = r3900_fetch_registers;
+ r3900_ops.to_store_registers = r3900_store_registers;
+
+ add_target (&r3900_ops);
+}
diff --git a/gdb/monitor.c b/gdb/monitor.c
index b7a56aa..97f5a50 100644
--- a/gdb/monitor.c
+++ b/gdb/monitor.c
@@ -1,5 +1,5 @@
/* Remote debugging interface for boot monitors, for GDB.
- Copyright 1990, 1991, 1992, 1993, 1995, 1996
+ Copyright 1990, 1991, 1992, 1993, 1995, 1996, 1997
Free Software Foundation, Inc.
Contributed by Cygnus Support. Written by Rob Savoye for Cygnus.
Resurrected from the ashes by Stu Grossman.
@@ -88,15 +88,17 @@ static void monitor_kill PARAMS ((void));
static void monitor_load PARAMS ((char *file, int from_tty));
static void monitor_mourn_inferior PARAMS ((void));
static void monitor_stop PARAMS ((void));
-static void monitor_debug PARAMS ((char *prefix, char *string, char *suffix));
static int monitor_read_memory PARAMS ((CORE_ADDR addr, char *myaddr,int len));
static int monitor_write_memory PARAMS ((CORE_ADDR addr, char *myaddr,int len));
static int monitor_expect_regexp PARAMS ((struct re_pattern_buffer *pat,
char *buf, int buflen));
+#if 0
static int from_hex PARAMS ((int a));
static unsigned long get_hex_word PARAMS ((void));
+#endif
+static void parse_register_dump PARAMS ((char *, int));
static struct monitor_ops *current_monitor;
@@ -129,68 +131,18 @@ static DCACHE *remote_dcache;
static int first_time=0; /* is this the first time we're executing after
gaving created the child proccess? */
-/* monitor_debug is like fputs_unfiltered, except it prints special
- characters in printable fashion. */
+/* Convert hex digit A to a number. */
-static void
-monitor_debug (prefix, string, suffix)
- char *prefix;
- char *string;
- char *suffix;
+static int
+fromhex (a)
+ int a;
{
- int ch;
-
- /* print prefix and suffix after each line */
- static int new_line=1;
- static char *prev_prefix = "";
- static char *prev_suffix = "";
-
- /* if the prefix is changing, print the previous suffix, a new line,
- and the new prefix */
- if (strcmp(prev_prefix, prefix) != 0 && !new_line)
- {
- fputs_unfiltered (prev_suffix, gdb_stderr);
- fputs_unfiltered ("\n", gdb_stderr);
- fputs_unfiltered (prefix, gdb_stderr);
- }
- prev_prefix = prefix;
- prev_suffix = suffix;
-
- /* print prefix if last char was a newline*/
-
- if (new_line == 1) {
- fputs_unfiltered (prefix, gdb_stderr);
- new_line=0;
- }
- if (strchr(string,'\n')) /* save state for next call */
- new_line=1;
-
- while ((ch = *string++) != '\0')
- {
- switch (ch) {
- default:
- if (isprint (ch))
- fputc_unfiltered (ch, gdb_stderr);
-
- else
- fprintf_unfiltered (gdb_stderr, "\\%03o", ch);
-
- break;
-
- case '\\': fputs_unfiltered ("\\\\", gdb_stderr); break;
- case '\b': fputs_unfiltered ("\\b", gdb_stderr); break;
- case '\f': fputs_unfiltered ("\\f", gdb_stderr); break;
- case '\n': fputs_unfiltered ("\\n", gdb_stderr); break;
- case '\r': fputs_unfiltered ("\\r", gdb_stderr); break;
- case '\t': fputs_unfiltered ("\\t", gdb_stderr); break;
- case '\v': fputs_unfiltered ("\\v", gdb_stderr); break;
- }
- }
-
- if (new_line==1) { /* print suffix if last char was a newline */
- fputs_unfiltered (suffix, gdb_stderr);
- fputs_unfiltered ("\n", gdb_stderr);
- }
+ if (a >= '0' && a <= '9')
+ return a - '0';
+ else if (a >= 'a' && a <= 'f')
+ return a - 'a' + 10;
+ else
+ error ("Invalid hex digit %d", a);
}
/* monitor_printf_noecho -- Send data to monitor, but don't expect an echo.
@@ -219,7 +171,7 @@ monitor_printf_noecho (va_alist)
vsprintf (sndbuf, pattern, args);
if (remote_debug > 0)
- monitor_debug ("sent -->", sndbuf, "<--");
+ puts_debug ("sent -->", sndbuf, "<--");
len = strlen (sndbuf);
@@ -256,7 +208,7 @@ monitor_printf (va_alist)
vsprintf (sndbuf, pattern, args);
if (remote_debug > 0)
- monitor_debug ("sent -->", sndbuf, "<--");
+ puts_debug ("sent -->", sndbuf, "<--");
len = strlen (sndbuf);
@@ -297,7 +249,7 @@ readchar (timeout)
char buf[2];
buf[0] = c;
buf[1] = '\0';
- monitor_debug ("read -->", buf, "<--");
+ puts_debug ("read -->", buf, "<--");
}
}
@@ -478,6 +430,7 @@ monitor_expect_prompt (buf, buflen)
/* Get N 32-bit words from remote, each preceded by a space, and put
them in registers starting at REGNO. */
+#if 0
static unsigned long
get_hex_word ()
{
@@ -501,6 +454,7 @@ get_hex_word ()
return val;
}
+#endif
static void
compile_pattern (pattern, compiled_pattern, fastmap)
@@ -536,7 +490,6 @@ monitor_open (args, mon_ops, from_tty)
int from_tty;
{
char *name;
- int i;
char **p;
if (mon_ops->magic != MONITOR_OPS_MAGIC)
@@ -725,7 +678,7 @@ monitor_resume (pid, step, sig)
form REG=VAL. Each description is split up into a name and a value
string which are passed down to monitor specific code. */
-static char *
+static void
parse_register_dump (buf, len)
char *buf;
int len;
@@ -899,7 +852,13 @@ monitor_fetch_register (regno)
searching from the start of the buf. */
if (current_monitor->getreg.resp_delim)
- monitor_expect (current_monitor->getreg.resp_delim, NULL, 0);
+ {
+ monitor_expect (current_monitor->getreg.resp_delim, NULL, 0);
+ /* Handle case of first 32 registers listed in pairs. */
+ if (current_monitor->flags & MO_32_REGS_PAIRED
+ && regno & 1 == 1 && regno < 32)
+ monitor_expect (current_monitor->getreg.resp_delim, NULL, 0);
+ }
/* Skip leading spaces and "0x" if MO_HEX_PREFIX flag is set */
if (current_monitor->flags & MO_HEX_PREFIX)
@@ -957,7 +916,8 @@ monitor_fetch_register (regno)
/* Read the remote registers into the block regs. */
-static void monitor_dump_regs ()
+static void
+monitor_dump_regs ()
{
char buf[1024];
int resp_len;
@@ -1007,19 +967,26 @@ monitor_store_register (regno)
val = read_register (regno);
- /* send the register deposit command */
+ /* send the register deposit command */
if (current_monitor->flags & MO_REGISTER_VALUE_FIRST)
monitor_printf (current_monitor->setreg.cmd, val, name);
+ else if (current_monitor->flags & MO_SETREG_INTERACTIVE)
+ monitor_printf (current_monitor->setreg.cmd, name);
else
monitor_printf (current_monitor->setreg.cmd, name, val);
-/* It's possible that there are actually some monitors out there that
- will prompt you when you set a register. In that case, you may
- need to add some code here to deal with TERM and TERM_CMD (see
- monitor_fetch_register to get an idea of what's needed...) */
+ if (current_monitor->setreg.term)
+ {
+ monitor_expect (current_monitor->setreg.term, NULL, 0);
- monitor_expect_prompt (NULL, 0);
+ if (current_monitor->flags & MO_SETREG_INTERACTIVE)
+ monitor_printf ("%x\r", val);
+
+ monitor_expect_prompt (NULL, 0);
+ }
+ else
+ monitor_expect_prompt (NULL, 0);
}
/* Store the remote registers. */
@@ -1067,6 +1034,9 @@ monitor_write_memory (memaddr, myaddr, len)
char *cmd;
int i;
+ if (current_monitor->flags & MO_ADDR_BITS_REMOVE)
+ memaddr = ADDR_BITS_REMOVE (memaddr);
+
/* Use memory fill command for leading 0 bytes. */
if (current_monitor->fill)
@@ -1117,6 +1087,19 @@ monitor_write_memory (memaddr, myaddr, len)
if (current_monitor->flags & MO_NO_ECHO_ON_SETMEM)
monitor_printf_noecho (cmd, memaddr, val);
+ else if (current_monitor->flags & MO_SETMEM_INTERACTIVE)
+ {
+
+ monitor_printf_noecho (cmd, memaddr);
+
+ if (current_monitor->setmem.term)
+ {
+ monitor_expect (current_monitor->setmem.term, NULL, 0);
+
+ monitor_printf ("%x\r", val);
+
+ }
+ }
else
monitor_printf (cmd, memaddr, val);
@@ -1247,9 +1230,9 @@ monitor_read_memory_single (memaddr, myaddr, len)
return len;
}
-/* Copy LEN bytes of data from debugger memory at MYADDR to inferior's memory
- at MEMADDR. Returns length moved. Currently, we only do one byte at a
- time. */
+/* Copy LEN bytes of data from debugger memory at MYADDR to inferior's
+ memory at MEMADDR. Returns length moved. Currently, we do no more
+ than 16 bytes at a time. */
static int
monitor_read_memory (memaddr, myaddr, len)
@@ -1258,18 +1241,22 @@ monitor_read_memory (memaddr, myaddr, len)
int len;
{
unsigned int val;
- unsigned char regbuf[MAX_REGISTER_RAW_SIZE];
char buf[512];
char *p, *p1;
- char *name;
int resp_len;
int i;
+ CORE_ADDR dumpaddr;
+
+ if (current_monitor->flags & MO_ADDR_BITS_REMOVE)
+ memaddr = ADDR_BITS_REMOVE (memaddr);
if (current_monitor->flags & MO_GETMEM_READ_SINGLE)
return monitor_read_memory_single (memaddr, myaddr, len);
len = min (len, 16);
+ dumpaddr = memaddr & ~0xf;
+
/* See if xfer would cross a 16 byte boundary. If so, clip it. */
if (((memaddr ^ (memaddr + len - 1)) & ~0xf) != 0)
len = ((memaddr + len) & ~0xf) - memaddr;
@@ -1278,6 +1265,8 @@ monitor_read_memory (memaddr, myaddr, len)
if (current_monitor->flags & MO_GETMEM_NEEDS_RANGE)
monitor_printf (current_monitor->getmem.cmdb, memaddr, memaddr + len - 1);
+ else if (current_monitor->flags & MO_GETMEM_16_BOUNDARY)
+ monitor_printf (current_monitor->getmem.cmdb, dumpaddr);
else
monitor_printf (current_monitor->getmem.cmdb, memaddr, len);
@@ -1333,6 +1322,27 @@ monitor_read_memory (memaddr, myaddr, len)
#endif
}
+ if (current_monitor->flags & MO_GETMEM_16_BOUNDARY)
+ {
+ i = len;
+ while (!(*p == '\000' || *p == '\n' || *p == '\r') && i > 0)
+ {
+ if (isxdigit (*p))
+ {
+ if (dumpaddr >= memaddr && i > 0)
+ {
+ val = fromhex (*p) * 16 + fromhex (*(p+1));
+ *myaddr++ = val;
+ --i;
+ }
+ ++dumpaddr;
+ ++p;
+ }
+ ++p;
+ }
+ return len;
+ }
+
for (i = len; i > 0; i--)
{
/* Skip non-hex chars, but bomb on end of string and newlines */
@@ -1341,6 +1351,7 @@ monitor_read_memory (memaddr, myaddr, len)
{
if (isxdigit (*p))
break;
+
if (*p == '\000' || *p == '\n' || *p == '\r')
error ("monitor_read_memory (0x%x): badly terminated response from monitor: %.*s", memaddr, resp_len, buf);
p++;
@@ -1421,20 +1432,24 @@ monitor_insert_breakpoint (addr, shadow)
char *shadow;
{
int i;
- /* This is only used to compute the size of a breakpoint. */
-#ifdef BREAKPOINT
- static unsigned char break_insn[] = BREAKPOINT;
-#else
- /* In the bi-endian case we assume breakpoints are the same size. */
- static unsigned char break_insn[] = BIG_BREAKPOINT;
-#endif
+ unsigned char *bp;
+ int bplen;
+
+ if (current_monitor->set_break == NULL)
+ error ("No set_break defined for this monitor");
+
+ if (current_monitor->flags & MO_ADDR_BITS_REMOVE)
+ addr = ADDR_BITS_REMOVE (addr);
+
+ /* Determine appropriate breakpoint size for this address. */
+ bp = memory_breakpoint_from_pc (&addr, &bplen);
for (i = 0; i < NUM_MONITOR_BREAKPOINTS; i++)
{
if (breakaddr[i] == 0)
{
breakaddr[i] = addr;
- monitor_read_memory (addr, shadow, sizeof (break_insn));
+ monitor_read_memory (addr, shadow, bplen);
monitor_printf (current_monitor->set_break, addr);
monitor_expect_prompt (NULL, 0);
return 0;
@@ -1453,14 +1468,22 @@ monitor_remove_breakpoint (addr, shadow)
{
int i;
+ if (current_monitor->clr_break == NULL)
+ error ("No clr_break defined for this monitor");
+
+ if (current_monitor->flags & MO_ADDR_BITS_REMOVE)
+ addr = ADDR_BITS_REMOVE (addr);
+
for (i = 0; i < NUM_MONITOR_BREAKPOINTS; i++)
{
if (breakaddr[i] == addr)
{
breakaddr[i] = 0;
/* some monitors remove breakpoints based on the address */
- if (current_monitor->flags & MO_CLR_BREAK_USES_ADDR)
+ if (current_monitor->flags & MO_CLR_BREAK_USES_ADDR)
monitor_printf (current_monitor->clr_break, addr);
+ else if (current_monitor->flags & MO_CLR_BREAK_1_BASED)
+ monitor_printf (current_monitor->clr_break, i + 1);
else
monitor_printf (current_monitor->clr_break, i);
monitor_expect_prompt (NULL, 0);
@@ -1477,10 +1500,25 @@ monitor_remove_breakpoint (addr, shadow)
static int
monitor_wait_srec_ack ()
{
- /* FIXME: eventually we'll want to be able to handle acknowledgements
- of something other than a '+' character. Right now this is only
- going to work for EST visionICE. */
- return readchar (timeout) == '+';
+ int i, ch;
+
+ if (current_monitor->flags & MO_SREC_ACK_PLUS)
+ {
+ return (readchar (timeout) == '+');
+ }
+ else if (current_monitor->flags & MO_SREC_ACK_ROTATE)
+ {
+ /* Eat two backspaces, a "rotating" char (|/-\), and a space. */
+ if ((ch = readchar (1)) < 0)
+ return 0;
+ if ((ch = readchar (1)) < 0)
+ return 0;
+ if ((ch = readchar (1)) < 0)
+ return 0;
+ if ((ch = readchar (1)) < 0)
+ return 0;
+ }
+ return 1;
}
/* monitor_load -- download a file. */
@@ -1496,12 +1534,23 @@ monitor_load (file, from_tty)
current_monitor->load_routine (monitor_desc, file, hashmark);
else
{ /* The default is ascii S-records */
+ int n;
+ unsigned long load_offset;
+ char buf[128];
+
+ /* enable user to specify address for downloading as 2nd arg to load */
+ n = sscanf (file, "%s 0x%lx", buf, &load_offset);
+ if (n > 1)
+ file = buf;
+ else
+ load_offset = 0;
+
monitor_printf (current_monitor->load);
if (current_monitor->loadresp)
monitor_expect (current_monitor->loadresp, NULL, 0);
-/* FIXME Should add arg here for load_offset (already done for generic_load) */
- load_srec (monitor_desc, file, 32, SREC_ALL, hashmark,
+ load_srec (monitor_desc, file, (bfd_vma) load_offset,
+ 32, SREC_ALL, hashmark,
current_monitor->flags & MO_SREC_ACK ?
monitor_wait_srec_ack : NULL);
@@ -1563,6 +1612,7 @@ monitor_command (args, from_tty)
/* Convert hex digit A to a number. */
+#if 0
static int
from_hex (a)
int a;
@@ -1576,6 +1626,13 @@ from_hex (a)
error ("Reply contains invalid hex digit 0x%x", a);
}
+#endif
+
+char *
+monitor_get_dev_name ()
+{
+ return dev_name;
+}
static struct target_ops monitor_ops =
{
diff --git a/gdb/monitor.h b/gdb/monitor.h
index cf1e0ce..f6c22c6 100644
--- a/gdb/monitor.h
+++ b/gdb/monitor.h
@@ -197,6 +197,10 @@ struct monitor_ops
#define MO_SREC_ACK_ROTATE 0x80000
+/* If set, then remove useless address bits from memory addresses. */
+
+#define MO_ADDR_BITS_REMOVE 0x100000
+
#define SREC_SIZE 160
extern void monitor_open PARAMS ((char *args, struct monitor_ops *ops,
diff --git a/gdb/utils.c b/gdb/utils.c
index a2699d6..182ed34 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -74,6 +74,7 @@ set_width_command PARAMS ((char *, int, struct cmd_list_element *));
static struct cleanup *cleanup_chain; /* cleaned up after a failed command */
static struct cleanup *final_cleanup_chain; /* cleaned up when gdb exits */
+static struct cleanup *run_cleanup_chain; /* cleaned up on each 'run' */
/* Nonzero if we have job control. */
@@ -146,6 +147,13 @@ make_final_cleanup (function, arg)
return make_my_cleanup (&final_cleanup_chain, function, arg);
}
struct cleanup *
+make_run_cleanup (function, arg)
+ void (*function) PARAMS ((PTR));
+ PTR arg;
+{
+ return make_my_cleanup (&run_cleanup_chain, function, arg);
+}
+struct cleanup *
make_my_cleanup (pmy_chain, function, arg)
struct cleanup **pmy_chain;
void (*function) PARAMS ((PTR));
@@ -181,6 +189,13 @@ do_final_cleanups (old_chain)
}
void
+do_run_cleanups (old_chain)
+ register struct cleanup *old_chain;
+{
+ do_my_cleanups (&run_cleanup_chain, old_chain);
+}
+
+void
do_my_cleanups (pmy_chain, old_chain)
register struct cleanup **pmy_chain;
register struct cleanup *old_chain;
@@ -378,7 +393,6 @@ NORETURN void
#ifdef ANSI_PROTOTYPES
error (const char *string, ...)
#else
-void
error (va_alist)
va_dcl
#endif
@@ -678,12 +692,6 @@ request_quit (signo)
about USG defines and stuff like that. */
signal (signo, request_quit);
-/* start-sanitize-gm */
-#ifdef GENERAL_MAGIC
- target_kill ();
-#endif /* GENERAL_MAGIC */
-/* end-sanitize-gm */
-
#ifdef REQUEST_QUIT
REQUEST_QUIT;
#else
@@ -1560,6 +1568,80 @@ fputc_unfiltered (c, stream)
}
+/* puts_debug is like fputs_unfiltered, except it prints special
+ characters in printable fashion. */
+
+void
+puts_debug (prefix, string, suffix)
+ char *prefix;
+ char *string;
+ char *suffix;
+{
+ int ch;
+
+ /* Print prefix and suffix after each line. */
+ static int new_line = 1;
+ static int carriage_return = 0;
+ static char *prev_prefix = "";
+ static char *prev_suffix = "";
+
+ if (*string == '\n')
+ carriage_return = 0;
+
+ /* If the prefix is changing, print the previous suffix, a new line,
+ and the new prefix. */
+ if ((carriage_return || (strcmp(prev_prefix, prefix) != 0)) && !new_line)
+ {
+ fputs_unfiltered (prev_suffix, gdb_stderr);
+ fputs_unfiltered ("\n", gdb_stderr);
+ fputs_unfiltered (prefix, gdb_stderr);
+ }
+
+ /* Print prefix if we printed a newline during the previous call. */
+ if (new_line)
+ {
+ new_line = 0;
+ fputs_unfiltered (prefix, gdb_stderr);
+ }
+
+ prev_prefix = prefix;
+ prev_suffix = suffix;
+
+ /* Output characters in a printable format. */
+ while ((ch = *string++) != '\0')
+ {
+ switch (ch)
+ {
+ default:
+ if (isprint (ch))
+ fputc_unfiltered (ch, gdb_stderr);
+
+ else
+ fprintf_unfiltered (gdb_stderr, "\\%03o", ch);
+ break;
+
+ case '\\': fputs_unfiltered ("\\\\", gdb_stderr); break;
+ case '\b': fputs_unfiltered ("\\b", gdb_stderr); break;
+ case '\f': fputs_unfiltered ("\\f", gdb_stderr); break;
+ case '\n': new_line = 1;
+ fputs_unfiltered ("\\n", gdb_stderr); break;
+ case '\r': fputs_unfiltered ("\\r", gdb_stderr); break;
+ case '\t': fputs_unfiltered ("\\t", gdb_stderr); break;
+ case '\v': fputs_unfiltered ("\\v", gdb_stderr); break;
+ }
+
+ carriage_return = ch == '\r';
+ }
+
+ /* Print suffix if we printed a newline. */
+ if (new_line)
+ {
+ fputs_unfiltered (suffix, gdb_stderr);
+ fputs_unfiltered ("\n", gdb_stderr);
+ }
+}
+
+
/* Print a variable number of ARGS using format FORMAT. If this
information is going to put the amount written (since the last call
to REINITIALIZE_MORE_FILTER or the last page break) over the page size,
@@ -1876,6 +1958,9 @@ fprintf_symbol_filtered (stream, name, lang, arg_mode)
case language_cplus:
demangled = cplus_demangle (name, arg_mode);
break;
+ case language_java:
+ demangled = cplus_demangle (name, arg_mode | DMGL_JAVA);
+ break;
case language_chill:
demangled = chill_demangle (name);
break;