From 6c310da826b31a1ce75469b0c402a75dafbf19b1 Mon Sep 17 00:00:00 2001 From: Stu Grossman Date: Sat, 4 Jan 1997 00:25:53 +0000 Subject: * 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 --- gdb/v850ice.c | 504 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 504 insertions(+) create mode 100755 gdb/v850ice.c (limited to 'gdb/v850ice.c') 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 (®isters[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); +} -- cgit v1.1