/* Remote debugging interface for M32R/SDI.
- Copyright 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
+ Free Software Foundation, Inc.
Contributed by Renesas Technology Co.
Written by Kei Sakamoto <sakamoto.kei@renesas.com>.
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
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
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. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
#include "gdbcmd.h"
#include "target.h"
#include "regcache.h"
#include "gdb_string.h"
+#include "gdbthread.h"
#include <ctype.h>
#include <signal.h>
+#ifdef __MINGW32__
+#include <winsock.h>
+#else
#include <netinet/in.h>
+#endif
#include <sys/types.h>
#include <sys/time.h>
#include <signal.h>
/* Forward data declarations */
extern struct target_ops m32r_ops;
+/* This is the ptid we use while we're connected to the remote. Its
+ value is arbitrary, as the target doesn't have a notion of
+ processes or threads, but we need something non-null to place in
+ inferior_ptid. */
+static ptid_t remote_m32r_ptid;
/* Commands */
#define SDI_OPEN 1
/* Install inferior's terminal modes. */
target_terminal_inferior ();
- proceed (entry_pt, TARGET_SIGNAL_DEFAULT, 0);
+ write_pc (entry_pt);
}
/* Open a connection to a remote debugger.
}
inferior_ptid = null_ptid;
+ delete_thread_silent (remote_m32r_ptid);
return;
}
else
{
buf[0] = SDI_WRITE_MEMORY;
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ if (gdbarch_byte_order (target_gdbarch) == BFD_ENDIAN_BIG)
store_long_parameter (buf + 1, pc_addr);
else
store_long_parameter (buf + 1, pc_addr - 1);
continue;
/* Set PBP. */
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ if (gdbarch_byte_order (target_gdbarch) == BFD_ENDIAN_BIG)
send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8000 + 4 * i, 4,
0x00000006);
else
/* Write DBT instruction. */
buf[0] = SDI_WRITE_MEMORY;
- store_long_parameter (buf + 1, bp_addr);
+ store_long_parameter (buf + 1, (bp_addr & 0xfffffffc));
store_long_parameter (buf + 5, 4);
if ((bp_addr & 2) == 0 && bp_addr != (pc_addr & 0xfffffffc))
{
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ if (gdbarch_byte_order (target_gdbarch) == BFD_ENDIAN_BIG)
{
buf[9] = dbt_bp_entry[0];
buf[10] = dbt_bp_entry[1];
}
else
{
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ if (gdbarch_byte_order (target_gdbarch) == BFD_ENDIAN_BIG)
{
if ((bp_addr & 2) == 0)
{
continue;
/* DBC register */
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ if (gdbarch_byte_order (target_gdbarch) == BFD_ENDIAN_BIG)
{
switch (ab_type[i])
{
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_ptid = pid_to_ptid (32);
+ inferior_ptid = remote_m32r_ptid;
+ add_thread_silent (remote_m32r_ptid);
return;
}
if (last_pc_addr != 0xffffffff)
{
buf[0] = SDI_WRITE_MEMORY;
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ if (gdbarch_byte_order (target_gdbarch) == BFD_ENDIAN_BIG)
store_long_parameter (buf + 1, last_pc_addr);
else
store_long_parameter (buf + 1, last_pc_addr - 1);
address, we have to take care of it later. */
if ((pc_addr & 0x2) != 0)
{
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ if (gdbarch_byte_order (target_gdbarch) == BFD_ENDIAN_BIG)
{
if ((bp_data[i][2] & 0x80) != 0)
{
{
if (!mmu_on)
bp_addr &= 0x7fffffff;
- buf[0] = SDI_READ_MEMORY;
+ buf[0] = SDI_WRITE_MEMORY;
store_long_parameter (buf + 1, bp_addr & 0xfffffffc);
store_long_parameter (buf + 5, 4);
buf[9] = bp_data[i][0];
c = serial_readchar (sdi_desc, SDI_TIMEOUT);
if (c != '-' && recv_data (buf, 4) != -1)
{
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ if (gdbarch_byte_order (target_gdbarch) == BFD_ENDIAN_BIG)
{
if ((buf[3] & 0x1) == 0x1)
hit_watchpoint_addr = ab_address[i];
/* Read the remote registers into the block REGS. */
-static void m32r_fetch_register (int);
+static void m32r_fetch_register (struct regcache *, int);
static void
-m32r_fetch_registers (void)
+m32r_fetch_registers (struct regcache *regcache)
{
int regno;
- for (regno = 0; regno < NUM_REGS; regno++)
- m32r_fetch_register (regno);
+ for (regno = 0;
+ regno < gdbarch_num_regs (get_regcache_arch (regcache));
+ regno++)
+ m32r_fetch_register (regcache, regno);
}
/* Fetch register REGNO, or all registers if REGNO is -1.
Returns errno value. */
static void
-m32r_fetch_register (int regno)
+m32r_fetch_register (struct regcache *regcache, int regno)
{
unsigned long val, val2, regid;
if (regno == -1)
- m32r_fetch_registers ();
+ m32r_fetch_registers (regcache);
else
{
char buffer[MAX_REGISTER_SIZE];
{
send_one_arg_cmd (SDI_READ_CPU_REG, SDI_REG_BBPSW);
val2 = recv_long_data ();
- val = ((0x00c1 & val2) << 8) | ((0xc100 & val) >> 8);
+ val = ((0x00cf & val2) << 8) | ((0xcf00 & val) >> 8);
}
if (remote_debug)
/* We got the number the register holds, but gdb expects to see a
value in the target byte ordering. */
store_unsigned_integer (buffer, 4, val);
- regcache_raw_supply (current_regcache, regno, buffer);
+ regcache_raw_supply (regcache, regno, buffer);
}
return;
}
/* Store the remote registers from the contents of the block REGS. */
-static void m32r_store_register (int);
+static void m32r_store_register (struct regcache *, int);
static void
-m32r_store_registers (void)
+m32r_store_registers (struct regcache *regcache)
{
int regno;
- for (regno = 0; regno < NUM_REGS; regno++)
- m32r_store_register (regno);
+ for (regno = 0;
+ regno < gdbarch_num_regs (get_regcache_arch (regcache));
+ regno++)
+ m32r_store_register (regcache, regno);
registers_changed ();
}
/* Store register REGNO, or all if REGNO == 0.
Return errno value. */
static void
-m32r_store_register (int regno)
+m32r_store_register (struct regcache *regcache, int regno)
{
int regid;
ULONGEST regval, tmp;
if (regno == -1)
- m32r_store_registers ();
+ m32r_store_registers (regcache);
else
{
- regcache_cooked_read_unsigned (current_regcache, regno, ®val);
+ regcache_cooked_read_unsigned (regcache, regno, ®val);
regid = get_reg_id (regno);
if (regid == SDI_REG_PSW)
send_one_arg_cmd (SDI_READ_CPU_REG, SDI_REG_BBPSW);
bbpsw = recv_long_data ();
- tmp = (0x00c1 & psw) | ((0x00c1 & regval) << 8);
+ tmp = (0x00cf & psw) | ((0x00cf & regval) << 8);
send_two_arg_cmd (SDI_WRITE_CPU_REG, SDI_REG_PSW, tmp);
- tmp = (0x0030 & bbpsw) | ((0xc100 & regval) >> 8);
+ tmp = (0x0030 & bbpsw) | ((0xcf00 & regval) >> 8);
send_two_arg_cmd (SDI_WRITE_CPU_REG, SDI_REG_BBPSW, tmp);
}
else
debugged. */
static void
-m32r_prepare_to_store (void)
+m32r_prepare_to_store (struct regcache *regcache)
{
/* Do nothing, since we can store individual regs */
if (remote_debug)
/* Read/Write memory. */
static int
-m32r_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
+m32r_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len,
int write,
struct mem_attrib *attrib, struct target_ops *target)
{
if (remote_debug)
{
if (write)
- fprintf_unfiltered (gdb_stdlog, "m32r_xfer_memory(%08lx,%d,write)\n",
- memaddr, len);
+ fprintf_unfiltered (gdb_stdlog, "m32r_xfer_memory(%s,%d,write)\n",
+ paddr (memaddr), len);
else
- fprintf_unfiltered (gdb_stdlog, "m32r_xfer_memory(%08lx,%d,read)\n",
- memaddr, len);
+ fprintf_unfiltered (gdb_stdlog, "m32r_xfer_memory(%s,%d,read)\n",
+ paddr (memaddr), len);
}
if (write)
fprintf_unfiltered (gdb_stdlog, "m32r_kill()\n");
inferior_ptid = null_ptid;
+ delete_thread_silent (remote_m32r_ptid);
return;
}
}
static int
-m32r_insert_breakpoint (CORE_ADDR addr, bfd_byte *shadow)
+m32r_insert_breakpoint (struct bp_target_info *bp_tgt)
{
+ CORE_ADDR addr = bp_tgt->placed_address;
int ib_breakpoints;
unsigned char buf[13];
int i, c;
if (remote_debug)
- fprintf_unfiltered (gdb_stdlog, "m32r_insert_breakpoint(%08lx,\"%s\")\n",
- addr, shadow);
+ fprintf_unfiltered (gdb_stdlog, "m32r_insert_breakpoint(%s,...)\n",
+ paddr (addr));
if (use_ib_breakpoints)
ib_breakpoints = max_ib_breakpoints;
}
static int
-m32r_remove_breakpoint (CORE_ADDR addr, bfd_byte *shadow)
+m32r_remove_breakpoint (struct bp_target_info *bp_tgt)
{
+ CORE_ADDR addr = bp_tgt->placed_address;
int i;
if (remote_debug)
- fprintf_unfiltered (gdb_stdlog, "m32r_remove_breakpoint(%08lx,\"%s\")\n",
- addr, shadow);
+ fprintf_unfiltered (gdb_stdlog, "m32r_remove_breakpoint(%s)\n",
+ paddr (addr));
for (i = 0; i < MAX_BREAKPOINTS; i++)
{
char *filename;
int quiet;
int nostart;
- time_t start_time, end_time; /* Start and end times of download */
+ struct timeval start_time, end_time;
unsigned long data_count; /* Number of bytes transferred to memory */
int ret;
static RETSIGTYPE (*prev_sigint) ();
error (_("\"%s\" is not an object file: %s"), filename,
bfd_errmsg (bfd_get_error ()));
- start_time = time (NULL);
+ gettimeofday (&start_time, NULL);
data_count = 0;
interrupted = 0;
if (!quiet)
printf_filtered ("[Loading section %s at 0x%lx (%d bytes)]\n",
bfd_get_section_name (pbfd, section),
- section_address, (int) section_size);
+ (unsigned long) section_address,
+ (int) section_size);
fptr = 0;
interrupted = 0;
signal (SIGINT, prev_sigint);
- end_time = time (NULL);
+ gettimeofday (&end_time, NULL);
/* Make the PC point at the start address */
if (exec_bfd)
write_pc (bfd_get_start_address (exec_bfd));
inferior_ptid = null_ptid; /* No process now */
+ delete_thread_silent (remote_m32r_ptid);
/* This is necessary because many things were based on the PC at the time
that we attached to the monitor, which is no longer valid now that we
entry = bfd_get_start_address (pbfd);
if (!quiet)
- printf_unfiltered ("[Starting %s at 0x%lx]\n", filename, entry);
+ printf_unfiltered ("[Starting %s at 0x%lx]\n", filename,
+ (unsigned long) entry);
}
- print_transfer_performance (gdb_stdout, data_count, 0,
- end_time - start_time);
+ print_transfer_performance (gdb_stdout, data_count, 0, &start_time,
+ &end_time);
do_cleanups (old_chain);
}
static void
-m32r_stop (void)
+m32r_stop (ptid_t ptid)
{
if (remote_debug)
fprintf_unfiltered (gdb_stdlog, "m32r_stop()\n");
int i;
if (remote_debug)
- fprintf_unfiltered (gdb_stdlog, "m32r_insert_watchpoint(%08lx,%d,%d)\n",
- addr, len, type);
+ fprintf_unfiltered (gdb_stdlog, "m32r_insert_watchpoint(%s,%d,%d)\n",
+ paddr (addr), len, type);
for (i = 0; i < MAX_ACCESS_BREAKS; i++)
{
int i;
if (remote_debug)
- fprintf_unfiltered (gdb_stdlog, "m32r_remove_watchpoint(%08lx,%d,%d)\n",
- addr, len, type);
+ fprintf_unfiltered (gdb_stdlog, "m32r_remove_watchpoint(%s,%d,%d)\n",
+ paddr (addr), len, type);
for (i = 0; i < MAX_ACCESS_BREAKS; i++)
{
return m32r_stopped_data_address (¤t_target, &addr);
}
+/* Check to see if a thread is still alive. */
+
+static int
+m32r_thread_alive (ptid_t ptid)
+{
+ if (ptid_equal (ptid, remote_m32r_ptid))
+ /* The main task is always alive. */
+ return 1;
+
+ return 0;
+}
+
+/* Convert a thread ID to a string. Returns the string in a static
+ buffer. */
+
+static char *
+m32r_pid_to_str (ptid_t ptid)
+{
+ static char buf[64];
+
+ if (ptid_equal (remote_m32r_ptid, ptid))
+ {
+ xsnprintf (buf, sizeof buf, "Thread <main>");
+ return buf;
+ }
+
+ return normal_pid_to_str (ptid);
+}
static void
sdireset_command (char *args, int from_tty)
send_cmd (SDI_OPEN);
inferior_ptid = null_ptid;
+ delete_thread_silent (remote_m32r_ptid);
}
m32r_ops.to_create_inferior = m32r_create_inferior;
m32r_ops.to_mourn_inferior = m32r_mourn_inferior;
m32r_ops.to_stop = m32r_stop;
+ m32r_ops.to_log_command = serial_log_command;
+ m32r_ops.to_thread_alive = m32r_thread_alive;
+ m32r_ops.to_pid_to_str = m32r_pid_to_str;
m32r_ops.to_stratum = process_stratum;
m32r_ops.to_has_all_memory = 1;
m32r_ops.to_has_memory = 1;
_("Set breakpoints by IB break."));
add_com ("use_dbt_break", class_obscure, use_dbt_breakpoints_command,
_("Set breakpoints by dbt."));
+
+ /* Yes, 42000 is arbitrary. The only sense out of it, is that it
+ isn't 0. */
+ remote_m32r_ptid = ptid_build (42000, 0, 42000);
}