aboutsummaryrefslogtreecommitdiff
path: root/gdb/v850ice.c
diff options
context:
space:
mode:
authorStu Grossman <grossman@cygnus>1997-01-04 00:25:53 +0000
committerStu Grossman <grossman@cygnus>1997-01-04 00:25:53 +0000
commit6c310da826b31a1ce75469b0c402a75dafbf19b1 (patch)
treec166cf5f4500a649b7f8b71dbd4bd92a969ee771 /gdb/v850ice.c
parentb3ef389468d5b03b388b2c4ec3b047c7728961a3 (diff)
downloadgdb-6c310da826b31a1ce75469b0c402a75dafbf19b1.zip
gdb-6c310da826b31a1ce75469b0c402a75dafbf19b1.tar.gz
gdb-6c310da826b31a1ce75469b0c402a75dafbf19b1.tar.bz2
* Makefile.in configure configure.in: Remove ENABLE_CLIBS,
ENABLE_OBS, and THREAD_DB_OBS. These are consolidated into LIBS and CONFIG_OBS. * configure configure.in: Clean up test cases around thread support. start-sanitize-v850 * configure.tgt (v850-*-*): Include v850ice.o and v850.lib if host is Windows. end-sanitize-v850 * c-valprint.c ch-valprint.c cp-valprint.c eval.c expprint.c printcmd.c valops.c value.h values.c: Add bfd_section arg to value_at and value_at_lazy. * coffread.c dbxread.c elfread.c mdebugread.c minsyms.c symtab.h: Add bfd_section arg to prim_record_minimal_symbol_and_info. * corefile.c gdbcore.h printcmd.c valops.c: Use read_memory_section instead of read_memory. It takes a bfd_section arg. * coffread.c dbxread.c elfread.c gdb-stabs.h objfiles.h: Remove unnecessary cast for assignment of struct dbx_symfile_info. Struct objfile now uses a real pointer instead of PTR for this element. * dbxread.c (dbx_symfile_init): Stash bfd section pointers for text, data and bss into dbx_symfile_info. * exec.c (xfer_memory): Handle transfers for user-specified sections. * findvar.c (read_var_value locate_var_value): Copy bfd section from the symbol to the value. * gdb-stabs.h: Add section pointers for text, data and bss sections. * maint.c (translate address command): Add test code for overlay address translation. * printcmd.c (do_examine do_one_display): Now takes a bfd section arg. * (print_formatted x_command): Record current section along with current address for repeated commands. * sparc-nat.c (fetch_inferior_registers): Change target_xfer_memory to target_{read write}_memory to allow changes to target_xfer_memory interface for section info. * symmisc.c (dump_msymbols print_symbol): Print section assocaited with symbol. * symtab.c (fixup_symbol_section): New routine to add section info to symbols returned by lookup_symbol. * symtab.h (struct general_symbol_info): Add bfd section to symbols. * target.c target.h (target_xfer_memory): Add bfd section to args. * (target_read_memory_section): New routine to read data from a specific section. * (target_memory_bfd_section): New global variable to pass bfd section in to targets. * valarith.c (value_add value_addr value_array): Preserve bfd section when computing new value. * value.h (struct value): Add bfd section to values. * values.c (allocate_value value_copy): Initialize/preserve bfd section. * (unpack_double): Clean up _MSC_VER conditionals to remove duplicate code. start-sanitize-v850 * v850ice.c: New module to support communication with NEC's PC-based ICE. * config/v850/tm-v850.h (REGISTER_NAMES): Replace sp, gp, fp, and ep names with rxx names. sp and fp are renamed via a different mechanism. end-sanitize-v850
Diffstat (limited to 'gdb/v850ice.c')
-rwxr-xr-xgdb/v850ice.c504
1 files changed, 504 insertions, 0 deletions
diff --git a/gdb/v850ice.c b/gdb/v850ice.c
new file mode 100755
index 0000000..d3e1b19
--- /dev/null
+++ b/gdb/v850ice.c
@@ -0,0 +1,504 @@
+/* ICE interface for the NEC V850 for GDB, the GNU debugger.
+ Copyright 1996, 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 "gdb_string.h"
+#if 0
+#include "frame.h"
+#endif
+#include "inferior.h"
+#if 0
+#include "bfd.h"
+#endif
+#include "symfile.h"
+#include "target.h"
+#if 0
+#include "wait.h"
+#include "gdbcmd.h"
+#include "objfiles.h"
+#include "gdb-stabs.h"
+#include "gdbthread.h"
+#endif
+
+/* Prototypes for local functions */
+
+static void v850ice_files_info PARAMS ((struct target_ops *ignore));
+
+static int v850ice_xfer_memory PARAMS ((CORE_ADDR memaddr, char *myaddr,
+ int len, int should_write,
+ struct target_ops *target));
+
+static void v850ice_prepare_to_store PARAMS ((void));
+
+static void v850ice_fetch_registers PARAMS ((int regno));
+
+static void v850ice_resume PARAMS ((int pid, int step,
+ enum target_signal siggnal));
+
+static void v850ice_open PARAMS ((char *name, int from_tty));
+
+static void v850ice_close PARAMS ((int quitting));
+
+static void v850ice_store_registers PARAMS ((int regno));
+
+static void v850ice_mourn PARAMS ((void));
+
+static int v850ice_wait PARAMS ((int pid, struct target_waitstatus *status));
+
+static void v850ice_kill PARAMS ((void));
+
+static void v850ice_detach PARAMS ((char *args, int from_tty));
+
+static int v850ice_insert_breakpoint PARAMS ((CORE_ADDR, char *));
+
+static int v850ice_remove_breakpoint PARAMS ((CORE_ADDR, char *));
+
+static int ice_open = 0;
+
+#ifndef EXPORT
+#define EXPORT __declspec(dllexport)
+#endif
+
+EXPORT long __stdcall ExeAppReq (char *, long, char *, char *);
+
+#define MREADREG 0x0001
+#define MWRITEREG 0x0002
+#define MREADMEM 0x0003
+#define MWRITEMEM 0x0004
+#define MSINGLESTEP 0x0005
+#define MRESUME 0x0006
+#define MLOADPROGRAM 0x0007
+#define MSETBREAK 0x0008
+#define MREMOVEBREAK 0x0009
+#define MQUIT 0x000A
+#define MTERMINATE 0x000B
+#define MATTACH 0x000C
+#define MCHECKSTATUS 0x000D
+#define MHALT 0x000E
+#define MDIRECTCMD 0x000F
+#define MSYMADR 0x0010
+#define MGETTASKLIST 0x0011
+#define MREADVECREG 0x0012
+#define MWRITEVECREG 0x0013
+#define MGETCHANGEDREGS 0x0014
+#define MGETSERVERINFO 0x0015
+#define MREADBLOCK 0x0016
+#define MSETHARDBRK 0x0017
+#define MREMOVEHARDBRK 0x0018
+#define MCOPYBLOCK 0x0019
+#define MBLOCKFILL 0x001A
+#define MFINDBLOCK 0x001B
+#define MCOMPAREBLOCK 0x001C
+#define MREFRESH 0x001D
+#define MSPECIAL 0x001E
+#define MGETCMDLIST 0x001F
+#define MEXPVAL 0x0020
+#define MEXPFAILED 0x0021
+#define MSAVESTATE 0x0022
+#define MWRITEBLOCK 0x0023
+#define MDETACH 0x0024
+#define MGETMODULES 0x0025
+#define MREMOTESYMBOL 0x0026
+#define MREADCSTRING 0x0027
+#define MLOADMODULE 0x0028
+#define MDIDSYSCALL 0x0029
+#define MDBPWRITEBUFFERS 0x002A
+#define MBPID 0x002B
+#define MINITEXEC 0x002C
+#define MEXITEXEC 0x002D
+#define MRCCMD 0x002E
+#define MDOWNLOAD 0x0050
+
+extern struct target_ops v850ice_ops; /* Forward decl */
+
+/* "pir", "tkcw", "chcw", "adtre" */
+
+/* Code for opening a connection to the ICE. */
+
+static void
+v850ice_open (name, from_tty)
+ char *name;
+ int from_tty;
+{
+ long retval;
+ char retmsg[1000];
+
+ if (name)
+ error ("Too many arguments.");
+
+ target_preopen (from_tty);
+
+ unpush_target (&v850ice_ops);
+
+ if (from_tty)
+ puts_filtered ("V850ice debugging\n");
+
+ push_target (&v850ice_ops); /* Switch to using v850ice target now */
+
+ target_terminal_init ();
+
+ /* Without this, some commands which require an active target (such as kill)
+ won't work. This variable serves (at least) double duty as both the pid
+ of the target process (if it has such), and as a flag indicating that a
+ target is active. These functions should be split out into seperate
+ variables, especially since GDB will someday have a notion of debugging
+ several processes. */
+
+ inferior_pid = 42000;
+
+ /* Start the v850ice connection; if error (0), discard this target.
+ In particular, if the user quits, be sure to discard it
+ (we'd be in an inconsistent state otherwise). */
+
+ retval = ExeAppReq ("GDB", MINITEXEC, "0", retmsg);
+ ice_open = 1;
+
+ start_remote ();
+
+/* pop_target();*/
+}
+
+/* Clean up connection to a remote debugger. */
+
+/* ARGSUSED */
+static void
+v850ice_close (quitting)
+ int quitting;
+{
+ long retval;
+
+ if (ice_open)
+ {
+ retval = ExeAppReq ("GDB", MEXITEXEC, NULL, NULL);
+ if (retval)
+ error ("ExeAppReq (MEXITEXEC) returned %d", retval);
+ ice_open = 0;
+ }
+}
+
+static void
+v850ice_detach (args, from_tty)
+ char *args;
+ int from_tty;
+{
+ if (args)
+ error ("Argument given to \"detach\" when remotely debugging.");
+
+ pop_target ();
+ if (from_tty)
+ puts_filtered ("Ending v850ice debugging.\n");
+}
+
+/* Tell the remote machine to resume. */
+
+static void
+v850ice_resume (pid, step, siggnal)
+ int pid, step;
+ enum target_signal siggnal;
+{
+ long retval;
+ char cmd[100];
+ char val[100];
+
+ if (step)
+ retval = ExeAppReq ("GDB", MSINGLESTEP, "step", val);
+ else
+ retval = ExeAppReq ("GDB", MRESUME, "run", val);
+
+ if (retval)
+ error ("ExeAppReq (step = %d) returned %d: cmd = %s", step, retval, cmd);
+}
+
+/* Wait until the remote machine stops, then return,
+ storing status in STATUS just as `wait' would.
+ Returns "pid" (though it's not clear what, if anything, that
+ means in the case of this target). */
+
+static int
+v850ice_wait (pid, status)
+ int pid;
+ struct target_waitstatus *status;
+{
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = TARGET_SIGNAL_TRAP;
+
+ return inferior_pid;
+}
+
+static int
+convert_register (regno, buf)
+ int regno;
+ char *buf;
+{
+ if (regno <= 31)
+ sprintf (buf, "r%d", regno);
+ else if (reg_names[regno][0] == 's'
+ && reg_names[regno][1] == 'r')
+ return 0;
+ else
+ sprintf (buf, "%s", reg_names[regno]);
+
+ return 1;
+}
+
+/* Read the remote registers into the block REGS. */
+/* Note that the ICE returns register contents as ascii hex strings. We have
+ to convert that to an unsigned long, and then call store_unsigned_integer to
+ convert it to target byte-order if necessary. */
+
+static void
+v850ice_fetch_registers (regno)
+ int regno;
+{
+ long retval;
+ char cmd[100];
+ char val[100];
+ unsigned long regval;
+ char *p;
+
+ if (regno == -1)
+ {
+ for (regno = 0; regno < NUM_REGS; regno++)
+ v850ice_fetch_registers (regno);
+ return;
+ }
+
+ strcpy (cmd, "reg ");
+ if (!convert_register (regno, &cmd[4]))
+ return;
+
+ retval = ExeAppReq ("GDB", MREADREG, cmd, val);
+ if (retval)
+ error ("ExeAppReq returned %d: cmd = %s", retval, cmd);
+
+ regval = strtoul (val, &p, 16);
+ if (regval == 0 && p == val)
+ error ("v850ice_fetch_registers (%d): bad value from ICE: %s.",
+ regno, val);
+
+ store_unsigned_integer (val, REGISTER_RAW_SIZE (regno), regval);
+ supply_register (regno, val);
+}
+
+/* Store register REGNO, or all registers if REGNO == -1, from the contents
+ of REGISTERS. */
+
+static void
+v850ice_store_registers (regno)
+ int regno;
+{
+ long retval;
+ char cmd[100];
+ char val[100];
+ unsigned long regval;
+
+ if (regno == -1)
+ {
+ for (regno = 0; regno < NUM_REGS; regno++)
+ v850ice_store_registers (regno);
+ return;
+ }
+
+ regval = extract_unsigned_integer (&registers[REGISTER_BYTE (regno)],
+ REGISTER_RAW_SIZE (regno));
+ strcpy (cmd, "reg ");
+ if (!convert_register (regno, &cmd[4]))
+ return;
+ sprintf (cmd + strlen (cmd), "=0x%x", regval);
+
+ retval = ExeAppReq ("GDB", MWRITEREG, cmd, val);
+ if (retval)
+ error ("ExeAppReq returned %d: cmd = %s", retval, cmd);
+}
+
+/* Prepare to store registers. Nothing to do here, since the ICE can write one
+ register at a time. */
+
+static void
+v850ice_prepare_to_store ()
+{
+}
+
+/* Read or write LEN bytes from inferior memory at MEMADDR, transferring
+ to or from debugger address MYADDR. Write to inferior if SHOULD_WRITE is
+ nonzero. Returns length of data written or read; 0 for error. */
+
+/* ARGSUSED */
+static int
+v850ice_xfer_memory (memaddr, myaddr, len, should_write, target)
+ CORE_ADDR memaddr;
+ char *myaddr;
+ int len;
+ int should_write;
+ struct target_ops *target; /* ignored */
+{
+ long retval;
+ char cmd[100];
+
+ if (should_write)
+ {
+#if 1
+ sprintf (cmd, "memory b c 0x%x=0x00 l=%d", (int)memaddr, len);
+ retval = ExeAppReq ("GDB", MWRITEBLOCK, cmd, myaddr);
+#else
+ sprintf (cmd, "memory b c 0x%x=0x%x", (int)memaddr, *myaddr & 0xff);
+ retval = ExeAppReq ("GDB", MWRITEBLOCK, cmd, myaddr);
+ return 1;
+#endif
+ }
+ else
+ {
+ unsigned char *tmp;
+ int i;
+
+ tmp = alloca (len + 100);
+ memset (tmp + len, 0xff, 100);
+
+ sprintf (cmd, "memory b 0x%x l=%d", (int)memaddr, len);
+ retval = ExeAppReq ("GDB", MREADBLOCK, cmd, tmp);
+
+ for (i = 0; i < 100; i++)
+ {
+ if (tmp[len + i] != 0xff)
+ {
+ warning ("MREADBLOCK trashed bytes after transfer area.");
+ break;
+ }
+ }
+ memcpy (myaddr, tmp, len);
+ }
+
+ if (retval)
+ error ("ExeAppReq returned %d: cmd = %s", retval, cmd);
+
+ return len;
+}
+
+static void
+v850ice_files_info (ignore)
+ struct target_ops *ignore;
+{
+ puts_filtered ("Debugging a target via the NEC V850 ICE.\n");
+}
+
+static int
+v850ice_insert_breakpoint (addr, contents_cache)
+ CORE_ADDR addr;
+ char *contents_cache;
+{
+ long retval;
+ char cmd[100];
+ char val[100];
+
+ sprintf (cmd, "%d, ", addr);
+
+#if 1
+ retval = ExeAppReq ("GDB", MSETBREAK, cmd, val);
+#else
+ retval = ExeAppReq ("GDB", MSETHARDBRK, cmd, val);
+#endif
+ if (retval)
+ error ("ExeAppReq (MSETBREAK) returned %d: cmd = %s", retval, cmd);
+
+ return 0;
+}
+
+static int
+v850ice_remove_breakpoint (addr, contents_cache)
+ CORE_ADDR addr;
+ char *contents_cache;
+{
+ long retval;
+ char cmd[100];
+ char val[100];
+
+ sprintf (cmd, "%d, ", addr);
+
+#if 1
+ retval = ExeAppReq ("GDB", MREMOVEBREAK, cmd, val);
+#else
+ retval = ExeAppReq ("GDB", MREMOVEHARDBRK, cmd, val);
+#endif
+ if (retval)
+ error ("ExeAppReq (MREMOVEBREAK) returned %d: cmd = %s", retval, cmd);
+
+ return 0;
+}
+
+static void
+v850ice_kill ()
+{
+ target_mourn_inferior ();
+}
+
+static void
+v850ice_mourn ()
+{
+}
+
+/* Define the target subroutine names */
+
+struct target_ops v850ice_ops = {
+ "ice", /* to_shortname */
+ "NEC V850 ICE interface", /* to_longname */
+ "Debug a system controlled by a NEC 850 ICE.", /* to_doc */
+ v850ice_open, /* to_open */
+ v850ice_close, /* to_close */
+ NULL, /* to_attach */
+ v850ice_detach, /* to_detach */
+ v850ice_resume, /* to_resume */
+ v850ice_wait, /* to_wait */
+ v850ice_fetch_registers, /* to_fetch_registers */
+ v850ice_store_registers, /* to_store_registers */
+ v850ice_prepare_to_store, /* to_prepare_to_store */
+ v850ice_xfer_memory, /* to_xfer_memory */
+ v850ice_files_info, /* to_files_info */
+ v850ice_insert_breakpoint, /* to_insert_breakpoint */
+ v850ice_remove_breakpoint, /* to_remove_breakpoint */
+ NULL, /* to_terminal_init */
+ NULL, /* to_terminal_inferior */
+ NULL, /* to_terminal_ours_for_output */
+ NULL, /* to_terminal_ours */
+ NULL, /* to_terminal_info */
+ v850ice_kill, /* to_kill */
+ generic_load, /* to_load */
+ NULL, /* to_lookup_symbol */
+ NULL, /* to_create_inferior */
+ v850ice_mourn, /* to_mourn_inferior */
+ 0, /* to_can_run */
+ 0, /* to_notice_signals */
+ NULL, /* to_thread_alive */
+ 0, /* to_stop */
+ process_stratum, /* to_stratum */
+ NULL, /* to_next */
+ 1, /* to_has_all_memory */
+ 1, /* to_has_memory */
+ 1, /* to_has_stack */
+ 1, /* to_has_registers */
+ 1, /* to_has_execution */
+ NULL, /* sections */
+ NULL, /* sections_end */
+ OPS_MAGIC /* to_magic */
+};
+
+void
+_initialize_v850ice ()
+{
+ add_target (&v850ice_ops);
+}