* breakpoint.h (struct breakpoint): New member GDBARCH.
[deliverable/binutils-gdb.git] / gdb / monitor.c
index 30493f4270b324381a526c0df3333e6ec1c55a67..b51848e48847ecbdb1bac0f9c28a4686251f773d 100644 (file)
@@ -1,7 +1,7 @@
 /* Remote debugging interface for boot monitors, for GDB.
 
    Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2006, 2007 Free Software Foundation, Inc.
+   2000, 2001, 2002, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
 
    Contributed by Cygnus Support.  Written by Rob Savoye for Cygnus.
    Resurrected from the ashes by Stu Grossman.
@@ -10,7 +10,7 @@
 
    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,
@@ -19,9 +19,7 @@
    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., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 /* This file was derived from various remote-* modules. It is a collection
    of generic support functions so GDB can talk directly to a ROM based
 #include "gdb_regex.h"
 #include "srec.h"
 #include "regcache.h"
+#include "gdbthread.h"
 
 static char *dev_name;
 static struct target_ops *targ_ops;
 
 static void monitor_interrupt_query (void);
 static void monitor_interrupt_twice (int);
-static void monitor_stop (void);
+static void monitor_stop (ptid_t);
 static void monitor_dump_regs (struct regcache *regcache);
 
 #if 0
@@ -107,6 +106,13 @@ static int dump_reg_flag;  /* Non-zero means do a dump_registers cmd when
 static int first_time = 0;     /* is this the first time we're executing after 
                                   gaving created the child proccess? */
 
+
+/* This is the ptid we use while we're connected to a monitor.  Its
+   value is arbitrary, as monitor targets don't have a notion of
+   processes or threads, but we need something non-null to place in
+   inferior_ptid.  */
+static ptid_t monitor_ptid;
+
 #define TARGET_BUF_SIZE 2048
 
 /* Monitor specific debugging information.  Typically only useful to
@@ -760,7 +766,7 @@ monitor_open (char *args, struct monitor_ops *mon_ops, int from_tty)
 
   if (current_monitor->stop)
     {
-      monitor_stop ();
+      monitor_stop (inferior_ptid);
       if ((current_monitor->flags & MO_NO_ECHO_ON_OPEN) == 0)
        {
          monitor_debug ("EXP Open echo\n");
@@ -806,7 +812,13 @@ monitor_open (char *args, struct monitor_ops *mon_ops, int from_tty)
 
   push_target (targ_ops);
 
-  inferior_ptid = pid_to_ptid (42000); /* Make run command think we are busy... */
+  /* Start afresh.  */
+  init_thread_list ();
+
+  /* Make run command think we are busy...  */
+  inferior_ptid = monitor_ptid;
+  add_inferior_silent (ptid_get_pid (inferior_ptid));
+  add_thread_silent (inferior_ptid);
 
   /* Give monitor_wait something to read */
 
@@ -832,13 +844,16 @@ monitor_close (int quitting)
     }
 
   monitor_desc = NULL;
+
+  delete_thread_silent (monitor_ptid);
+  delete_inferior_silent (ptid_get_pid (monitor_ptid));
 }
 
 /* Terminate the open connection to the remote debugger.  Use this
    when you want to detach and do something else with your gdb.  */
 
 static void
-monitor_detach (char *args, int from_tty)
+monitor_detach (struct target_ops *ops, char *args, int from_tty)
 {
   pop_target ();               /* calls monitor_close to do the real work */
   if (from_tty)
@@ -885,7 +900,9 @@ monitor_supply_register (struct regcache *regcache, int regno, char *valstr)
 
   /* supply register stores in target byte order, so swap here */
 
-  store_unsigned_integer (regbuf, register_size (current_gdbarch, regno), val);
+  store_unsigned_integer (regbuf,
+                         register_size (get_regcache_arch (regcache), regno),
+                         val);
 
   regcache_raw_supply (regcache, regno, regbuf);
 
@@ -895,7 +912,8 @@ monitor_supply_register (struct regcache *regcache, int regno, char *valstr)
 /* Tell the remote machine to resume.  */
 
 static void
-monitor_resume (ptid_t ptid, int step, enum target_signal sig)
+monitor_resume (struct target_ops *ops,
+               ptid_t ptid, int step, enum target_signal sig)
 {
   /* Some monitors require a different command when starting a program */
   monitor_debug ("MON resume\n");
@@ -968,7 +986,7 @@ monitor_interrupt (int signo)
   if (monitor_debug_p || remote_debug)
     fprintf_unfiltered (gdb_stdlog, "monitor_interrupt called\n");
 
-  target_stop ();
+  target_stop (inferior_ptid);
 }
 
 /* The user typed ^C twice.  */
@@ -990,8 +1008,8 @@ monitor_interrupt_query (void)
 {
   target_terminal_ours ();
 
-  if (query ("Interrupted while waiting for the program.\n\
-Give up (and stop debugging it)? "))
+  if (query (_("Interrupted while waiting for the program.\n\
+Give up (and stop debugging it)? ")))
     {
       target_mourn_inferior ();
       deprecated_throw_reason (RETURN_QUIT);
@@ -1046,7 +1064,8 @@ monitor_wait_filter (char *buf,
    status just as `wait' would.  */
 
 static ptid_t
-monitor_wait (ptid_t ptid, struct target_waitstatus *status)
+monitor_wait (struct target_ops *ops,
+             ptid_t ptid, struct target_waitstatus *status, int options)
 {
   int old_timeout = timeout;
   char buf[TARGET_BUF_SIZE];
@@ -1109,10 +1128,10 @@ monitor_wait (ptid_t ptid, struct target_waitstatus *status)
     }
 
   if (current_monitor->register_pattern)
-    parse_register_dump (current_regcache, buf, resp_len);
+    parse_register_dump (get_current_regcache (), buf, resp_len);
 #else
   monitor_debug ("Wait fetching registers after stop\n");
-  monitor_dump_regs (current_regcache);
+  monitor_dump_regs (get_current_regcache ());
 #endif
 
   status->kind = TARGET_WAITKIND_STOPPED;
@@ -1192,7 +1211,7 @@ monitor_fetch_register (struct regcache *regcache, int regno)
      spaces, but stop reading if something else is seen.  Some monitors
      like to drop leading zeros.  */
 
-  for (i = 0; i < register_size (current_gdbarch, regno) * 2; i++)
+  for (i = 0; i < register_size (get_regcache_arch (regcache), regno) * 2; i++)
     {
       int c;
       c = readchar (timeout);
@@ -1268,7 +1287,8 @@ monitor_dump_regs (struct regcache *regcache)
 }
 
 static void
-monitor_fetch_registers (struct regcache *regcache, int regno)
+monitor_fetch_registers (struct target_ops *ops,
+                        struct regcache *regcache, int regno)
 {
   monitor_debug ("MON fetchregs\n");
   if (current_monitor->getreg.cmd)
@@ -1279,7 +1299,8 @@ monitor_fetch_registers (struct regcache *regcache, int regno)
          return;
        }
 
-      for (regno = 0; regno < gdbarch_num_regs (current_gdbarch); regno++)
+      for (regno = 0; regno < gdbarch_num_regs (get_regcache_arch (regcache));
+          regno++)
        monitor_fetch_register (regcache, regno);
     }
   else
@@ -1309,7 +1330,8 @@ monitor_store_register (struct regcache *regcache, int regno)
 
   regcache_cooked_read_unsigned (regcache, regno, &val);
   monitor_debug ("MON storeg %d %s\n", regno,
-                phex (val, register_size (current_gdbarch, regno)));
+                phex (val,
+                      register_size (get_regcache_arch (regcache), regno)));
 
   /* send the register deposit command */
 
@@ -1348,7 +1370,8 @@ monitor_store_register (struct regcache *regcache, int regno)
 /* Store the remote registers.  */
 
 static void
-monitor_store_registers (struct regcache *regcache, int regno)
+monitor_store_registers (struct target_ops *ops,
+                        struct regcache *regcache, int regno)
 {
   if (regno >= 0)
     {
@@ -1356,7 +1379,8 @@ monitor_store_registers (struct regcache *regcache, int regno)
       return;
     }
 
-  for (regno = 0; regno < gdbarch_num_regs (current_gdbarch); regno++)
+  for (regno = 0; regno < gdbarch_num_regs (get_regcache_arch (regcache));
+       regno++)
     monitor_store_register (regcache, regno);
 }
 
@@ -1388,7 +1412,7 @@ monitor_write_memory (CORE_ADDR memaddr, char *myaddr, int len)
   monitor_debug ("MON write %d %s\n", len, paddr (memaddr));
 
   if (current_monitor->flags & MO_ADDR_BITS_REMOVE)
-    memaddr = gdbarch_addr_bits_remove (current_gdbarch, memaddr);
+    memaddr = gdbarch_addr_bits_remove (target_gdbarch, memaddr);
 
   /* Use memory fill command for leading 0 bytes.  */
 
@@ -1787,7 +1811,7 @@ monitor_read_memory (CORE_ADDR memaddr, char *myaddr, int len)
                 paddr_nz (memaddr), (long) myaddr, len);
 
   if (current_monitor->flags & MO_ADDR_BITS_REMOVE)
-    memaddr = gdbarch_addr_bits_remove (current_gdbarch, memaddr);
+    memaddr = gdbarch_addr_bits_remove (target_gdbarch, memaddr);
 
   if (current_monitor->flags & MO_GETMEM_READ_SINGLE)
     return monitor_read_memory_single (memaddr, myaddr, len);
@@ -1967,7 +1991,7 @@ monitor_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, int write,
 }
 
 static void
-monitor_kill (void)
+monitor_kill (struct target_ops *ops)
 {
   return;                      /* ignore attempts to kill target system */
 }
@@ -1975,15 +1999,16 @@ monitor_kill (void)
 /* All we actually do is set the PC to the start address of exec_bfd.  */
 
 static void
-monitor_create_inferior (char *exec_file, char *args, char **env,
-                        int from_tty)
+monitor_create_inferior (struct target_ops *ops, char *exec_file,
+                        char *args, char **env, int from_tty)
 {
   if (args && (*args != '\000'))
     error (_("Args are not supported by the monitor."));
 
   first_time = 1;
   clear_proceed_status ();
-  write_pc (bfd_get_start_address (exec_bfd));
+  regcache_write_pc (get_current_regcache (),
+                    bfd_get_start_address (exec_bfd));
 }
 
 /* Clean up when a program exits.
@@ -1992,20 +2017,21 @@ monitor_create_inferior (char *exec_file, char *args, char **env,
    instructions.  */
 
 static void
-monitor_mourn_inferior (void)
+monitor_mourn_inferior (struct target_ops *ops)
 {
   unpush_target (targ_ops);
   generic_mourn_inferior ();   /* Do all the proper things now */
+  delete_thread_silent (monitor_ptid);
 }
 
 /* Tell the monitor to add a breakpoint.  */
 
 static int
-monitor_insert_breakpoint (struct bp_target_info *bp_tgt)
+monitor_insert_breakpoint (struct gdbarch *gdbarch,
+                          struct bp_target_info *bp_tgt)
 {
   CORE_ADDR addr = bp_tgt->placed_address;
   int i;
-  const unsigned char *bp;
   int bplen;
 
   monitor_debug ("MON inst bkpt %s\n", paddr (addr));
@@ -2013,10 +2039,10 @@ monitor_insert_breakpoint (struct bp_target_info *bp_tgt)
     error (_("No set_break defined for this monitor"));
 
   if (current_monitor->flags & MO_ADDR_BITS_REMOVE)
-    addr = gdbarch_addr_bits_remove (current_gdbarch, addr);
+    addr = gdbarch_addr_bits_remove (gdbarch, addr);
 
   /* Determine appropriate breakpoint size for this address.  */
-  bp = gdbarch_breakpoint_from_pc (current_gdbarch, &addr, &bplen);
+  gdbarch_breakpoint_from_pc (gdbarch, &addr, &bplen);
   bp_tgt->placed_address = addr;
   bp_tgt->placed_size = bplen;
 
@@ -2037,7 +2063,8 @@ monitor_insert_breakpoint (struct bp_target_info *bp_tgt)
 /* Tell the monitor to remove a breakpoint.  */
 
 static int
-monitor_remove_breakpoint (struct bp_target_info *bp_tgt)
+monitor_remove_breakpoint (struct gdbarch *gdbarch,
+                          struct bp_target_info *bp_tgt)
 {
   CORE_ADDR addr = bp_tgt->placed_address;
   int i;
@@ -2131,7 +2158,8 @@ monitor_load (char *file, int from_tty)
 
   /* Finally, make the PC point at the start address */
   if (exec_bfd)
-    write_pc (bfd_get_start_address (exec_bfd));
+    regcache_write_pc (get_current_regcache (),
+                      bfd_get_start_address (exec_bfd));
 
   /* There used to be code here which would clear inferior_ptid and
      call clear_symtab_users.  None of that should be necessary:
@@ -2149,7 +2177,7 @@ monitor_load (char *file, int from_tty)
 }
 
 static void
-monitor_stop (void)
+monitor_stop (ptid_t ptid)
 {
   monitor_debug ("MON stop\n");
   if ((current_monitor->flags & MO_SEND_BREAK_ON_STOP) != 0)
@@ -2208,6 +2236,35 @@ monitor_get_dev_name (void)
   return dev_name;
 }
 
+/* Check to see if a thread is still alive.  */
+
+static int
+monitor_thread_alive (struct target_ops *ops, ptid_t ptid)
+{
+  if (ptid_equal (ptid, monitor_ptid))
+    /* The monitor's task is always alive.  */
+    return 1;
+
+  return 0;
+}
+
+/* Convert a thread ID to a string.  Returns the string in a static
+   buffer.  */
+
+static char *
+monitor_pid_to_str (struct target_ops *ops, ptid_t ptid)
+{
+  static char buf[64];
+
+  if (ptid_equal (monitor_ptid, ptid))
+    {
+      xsnprintf (buf, sizeof buf, "Thread <main>");
+      return buf;
+    }
+
+  return normal_pid_to_str (ptid);
+}
+
 static struct target_ops monitor_ops;
 
 static void
@@ -2230,12 +2287,15 @@ init_base_monitor_ops (void)
   monitor_ops.to_mourn_inferior = monitor_mourn_inferior;
   monitor_ops.to_stop = monitor_stop;
   monitor_ops.to_rcmd = monitor_rcmd;
+  monitor_ops.to_log_command = serial_log_command;
+  monitor_ops.to_thread_alive = monitor_thread_alive;
+  monitor_ops.to_pid_to_str = monitor_pid_to_str;
   monitor_ops.to_stratum = process_stratum;
-  monitor_ops.to_has_all_memory = 1;
-  monitor_ops.to_has_memory = 1;
-  monitor_ops.to_has_stack = 1;
-  monitor_ops.to_has_registers = 1;
-  monitor_ops.to_has_execution = 1;
+  monitor_ops.to_has_all_memory = default_child_has_all_memory;
+  monitor_ops.to_has_memory = default_child_has_memory;
+  monitor_ops.to_has_stack = default_child_has_stack;
+  monitor_ops.to_has_registers = default_child_has_registers;
+  monitor_ops.to_has_execution = default_child_has_execution;
   monitor_ops.to_magic = OPS_MAGIC;
 }                              /* init_base_monitor_ops */
 
@@ -2274,4 +2334,8 @@ is displayed."),
                            NULL,
                            NULL, /* FIXME: i18n: */
                            &setdebuglist, &showdebuglist);
+
+  /* Yes, 42000 is arbitrary.  The only sense out of it, is that it
+     isn't 0.  */
+  monitor_ptid = ptid_build (42000, 0, 42000);
 }
This page took 0.029564 seconds and 4 git commands to generate.