2001-04-26 Michael Snyder <msnyder@redhat.com>
[deliverable/binutils-gdb.git] / gdb / remote.c
index b79634d3260a8dceb98f80b342d35b421334d81c..18712c521a78fead7e2933fc1f67f4d0563255f2 100644 (file)
@@ -1,5 +1,6 @@
 /* Remote target communications for serial-line targets in custom GDB protocol
-   Copyright 1988, 1991-2000, 2001 Free Software Foundation, Inc.
+   Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+   1998, 1999, 2000, 2001 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -24,7 +25,6 @@
 #include "gdb_string.h"
 #include <ctype.h>
 #include <fcntl.h>
-#include "frame.h"
 #include "inferior.h"
 #include "bfd.h"
 #include "symfile.h"
@@ -35,6 +35,7 @@
 #include "gdb-stabs.h"
 #include "gdbthread.h"
 #include "remote.h"
+#include "regcache.h"
 
 #include <ctype.h>
 #include <sys/time.h>
@@ -49,6 +50,8 @@
 #include <signal.h>
 #include "serial.h"
 
+#include "gdbcore.h" /* for exec_bfd */
+
 /* Prototypes for local functions */
 static void cleanup_sigint_signal_handler (void *dummy);
 static void initialize_sigint_signal_handler (void);
@@ -615,7 +618,8 @@ packet_ok (const char *buf, struct packet_config *config)
          config->support = PACKET_ENABLE;
          break;
        case PACKET_DISABLE:
-         internal_error ("packet_ok: attempt to use a disabled packet");
+         internal_error (__FILE__, __LINE__,
+                         "packet_ok: attempt to use a disabled packet");
          break;
        case PACKET_ENABLE:
          break;
@@ -661,6 +665,40 @@ packet_ok (const char *buf, struct packet_config *config)
     }
 }
 
+/* Should we try the 'e' (step over range) request? */
+static struct packet_config remote_protocol_e;
+
+static void
+set_remote_protocol_e_packet_cmd (char *args, int from_tty,
+                                 struct cmd_list_element *c)
+{
+  update_packet_config (&remote_protocol_e);
+}
+
+static void
+show_remote_protocol_e_packet_cmd (char *args, int from_tty)
+{
+  show_packet_config_cmd (&remote_protocol_e);
+}
+  
+
+/* Should we try the 'E' (step over range / w signal #) request? */
+static struct packet_config remote_protocol_E;
+
+static void
+set_remote_protocol_E_packet_cmd (char *args, int from_tty,
+                                 struct cmd_list_element *c)
+{
+  update_packet_config (&remote_protocol_E);
+}
+
+static void
+show_remote_protocol_E_packet_cmd (char *args, int from_tty)
+{
+  show_packet_config_cmd (&remote_protocol_E);
+}
+  
+
 /* Should we try the 'P' (set register) request?  */
 
 static struct packet_config remote_protocol_P;
@@ -1681,7 +1719,8 @@ remote_threads_extra_info (struct thread_info *tp)
   int n = 0;                    /* position in display_buf */
 
   if (remote_desc == 0)                /* paranoia */
-    internal_error ("remote_threads_extra_info");
+    internal_error (__FILE__, __LINE__,
+                   "remote_threads_extra_info");
 
   if (use_threadextra_query)
     {
@@ -1873,7 +1912,6 @@ remote_cisco_section_offsets (bfd_vma text_addr,
   asection *sect;
   bfd *abfd;
   int len;
-  char *p;
 
   if (symfile_objfile == NULL)
     return -1;                 /* no can do nothin' */
@@ -1890,7 +1928,7 @@ remote_cisco_section_offsets (bfd_vma text_addr,
        sect != 0;
        sect = sect->next)
     {
-      p = (unsigned char *) bfd_get_section_name (abfd, sect);
+      const char *p = bfd_get_section_name (abfd, sect);
       len = strlen (p);
       if (strcmp (p + len - 4, "data") == 0)   /* ends in "data" */
        if (data_base == 0 ||
@@ -2029,6 +2067,8 @@ static void
 init_all_packet_configs (void)
 {
   int i;
+  update_packet_config (&remote_protocol_e);
+  update_packet_config (&remote_protocol_E);
   update_packet_config (&remote_protocol_P);
   for (i = 0; i < NR_Z_PACKET_TYPES; i++)
     update_packet_config (&remote_protocol_Z[i]);
@@ -2110,11 +2150,20 @@ serial device is attached to the remote system\n\
 
   if (extended_p)
     {
-      /* tell the remote that we're using the extended protocol.  */
+      /* Tell the remote that we are using the extended protocol.  */
       char *buf = alloca (PBUFSIZ);
       putpkt ("!");
       getpkt (buf, PBUFSIZ, 0);
     }
+  /* FIXME: need a master target_open vector from which all 
+     remote_opens can be called, so that stuff like this can 
+     go there.  Failing that, the following code must be copied
+     to the open function for any remote target that wants to 
+     support svr4 shared libraries.  */
+#ifdef SOLIB_CREATE_INFERIOR_HOOK
+  if (exec_bfd)        /* No use without an exec file. */
+    SOLIB_CREATE_INFERIOR_HOOK (inferior_pid);
+#endif
 }
 
 /* Just like remote_open but with asynchronous support. */
@@ -2204,11 +2253,20 @@ serial device is attached to the remote system\n\
 
   if (extended_p)
     {
-      /* tell the remote that we're using the extended protocol.  */
+      /* Tell the remote that we are using the extended protocol.  */
       char *buf = alloca (PBUFSIZ);
       putpkt ("!");
       getpkt (buf, PBUFSIZ, 0);
     }
+  /* FIXME: need a master target_open vector from which all 
+     remote_opens can be called, so that stuff like this can 
+     go there.  Failing that, the following code must be copied
+     to the open function for any remote target that wants to 
+     support svr4 shared libraries.  */
+#ifdef SOLIB_CREATE_INFERIOR_HOOK
+  if (exec_bfd)        /* No use without an exec file. */
+    SOLIB_CREATE_INFERIOR_HOOK (inferior_pid);
+#endif
 }
 
 /* This takes a program previously attached to and detaches it.  After
@@ -2292,6 +2350,7 @@ static void
 remote_resume (int pid, int step, enum target_signal siggnal)
 {
   char *buf = alloca (PBUFSIZ);
+  char *p;
 
   if (pid == -1)
     set_thread (0, 0);         /* run any thread */
@@ -2306,11 +2365,66 @@ remote_resume (int pid, int step, enum target_signal siggnal)
   if (target_resume_hook)
     (*target_resume_hook) ();
 
+
+  /* The s/S/c/C packets do not return status.  So if the target does
+     not support the S or C packets, the debug agent returns an empty
+     string which is detected in remote_wait().  This protocol defect
+     is fixed in the e/E packets. */
+
+  if (step && step_range_end)
+    {
+      /* If the target does not support the 'E' packet, we try the 'S'
+        packet.  Ideally we would fall back to the 'e' packet if that
+        too is not supported.  But that would require another copy of
+        the code to issue the 'e' packet (and fall back to 's' if not
+        supported) in remote_wait().  */
+      
+      if (siggnal != TARGET_SIGNAL_0)
+       {
+         if (remote_protocol_E.support != PACKET_DISABLE)
+           {
+             p = buf;
+             *p++ = 'E';
+             *p++ = tohex (((int) siggnal >> 4) & 0xf);
+             *p++ = tohex (((int) siggnal) & 0xf);
+             *p++ = ',';
+             p += hexnumstr (p, (ULONGEST) step_range_start);
+             *p++ = ',';
+             p += hexnumstr (p, (ULONGEST) step_range_end);
+             *p++ = 0;
+
+             putpkt (buf);
+             getpkt (buf, PBUFSIZ, 0);
+
+             if (packet_ok(buf, &remote_protocol_E) == PACKET_OK)
+               return;
+           }
+       }
+      else
+       {
+         if (remote_protocol_e.support != PACKET_DISABLE)
+           {
+             p = buf;
+             *p++ = 'e';
+             p += hexnumstr (p, (ULONGEST) step_range_start);
+             *p++ = ',';
+             p += hexnumstr (p, (ULONGEST) step_range_end);
+             *p++ = 0;
+
+             putpkt (buf);
+             getpkt (buf, PBUFSIZ, 0);
+
+             if (packet_ok(buf, &remote_protocol_e) == PACKET_OK)
+               return;
+           }
+       }
+    }
+
   if (siggnal != TARGET_SIGNAL_0)
     {
       buf[0] = step ? 'S' : 'C';
       buf[1] = tohex (((int) siggnal >> 4) & 0xf);
-      buf[2] = tohex ((int) siggnal & 0xf);
+      buf[2] = tohex (((int) siggnal) & 0xf);
       buf[3] = '\0';
     }
   else
@@ -2324,6 +2438,7 @@ static void
 remote_async_resume (int pid, int step, enum target_signal siggnal)
 {
   char *buf = alloca (PBUFSIZ);
+  char *p;
 
   if (pid == -1)
     set_thread (0, 0);         /* run any thread */
@@ -2338,6 +2453,60 @@ remote_async_resume (int pid, int step, enum target_signal siggnal)
   if (target_resume_hook)
     (*target_resume_hook) ();
 
+  /* The s/S/c/C packets do not return status.  So if the target does
+     not support the S or C packets, the debug agent returns an empty
+     string which is detected in remote_wait().  This protocol defect
+     is fixed in the e/E packets. */
+
+  if (step && step_range_end)
+    {
+      /* If the target does not support the 'E' packet, we try the 'S'
+        packet.  Ideally we would fall back to the 'e' packet if that
+        too is not supported.  But that would require another copy of
+        the code to issue the 'e' packet (and fall back to 's' if not
+        supported) in remote_wait().  */
+      
+      if (siggnal != TARGET_SIGNAL_0)
+       {
+         if (remote_protocol_E.support != PACKET_DISABLE)
+           {
+             p = buf;
+             *p++ = 'E';
+             *p++ = tohex (((int) siggnal >> 4) & 0xf);
+             *p++ = tohex (((int) siggnal) & 0xf);
+             *p++ = ',';
+             p += hexnumstr (p, (ULONGEST) step_range_start);
+             *p++ = ',';
+             p += hexnumstr (p, (ULONGEST) step_range_end);
+             *p++ = 0;
+
+             putpkt (buf);
+             getpkt (buf, PBUFSIZ, 0);
+
+             if (packet_ok(buf, &remote_protocol_E) == PACKET_OK)
+               goto register_event_loop;
+           }
+       }
+      else
+       {
+         if (remote_protocol_e.support != PACKET_DISABLE)
+           {
+             p = buf;
+             *p++ = 'e';
+             p += hexnumstr (p, (ULONGEST) step_range_start);
+             *p++ = ',';
+             p += hexnumstr (p, (ULONGEST) step_range_end);
+             *p++ = 0;
+
+             putpkt (buf);
+             getpkt (buf, PBUFSIZ, 0);
+
+             if (packet_ok(buf, &remote_protocol_e) == PACKET_OK)
+               goto register_event_loop;
+           }
+       }
+    }
+
   if (siggnal != TARGET_SIGNAL_0)
     {
       buf[0] = step ? 'S' : 'C';
@@ -2347,7 +2516,10 @@ remote_async_resume (int pid, int step, enum target_signal siggnal)
     }
   else
     strcpy (buf, step ? "s" : "c");
+  
+  putpkt (buf);
 
+register_event_loop:
   /* We are about to start executing the inferior, let's register it
      with the event loop. NOTE: this is the one place where all the
      execution commands end up. We could alternatively do this in each
@@ -2364,7 +2536,6 @@ remote_async_resume (int pid, int step, enum target_signal siggnal)
      this information already found in the continuation block?  */
   if (target_is_async_p ())
     target_executing = 1;
-  putpkt (buf);
 }
 \f
 
@@ -3364,10 +3535,10 @@ remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len)
       todo = min (len, max_buf_size / 2);
       break;
     case PACKET_SUPPORT_UNKNOWN:
-      internal_error ("%s:%d: remote_write_bytes: bad internal state",
-                     __FILE__, __LINE__);
+      internal_error (__FILE__, __LINE__,
+                     "remote_write_bytes: bad internal state");
     default:
-      internal_error ("%s:%d: bad switch", __FILE__, __LINE__);
+      internal_error (__FILE__, __LINE__, "bad switch");
     }
   
   /* Append <memaddr> */
@@ -3431,10 +3602,10 @@ remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len)
       *p = '\0';
       break;
     case PACKET_SUPPORT_UNKNOWN:
-      internal_error ("%s:%d: remote_write_bytes: bad internal state",
-                     __FILE__, __LINE__);
+      internal_error (__FILE__, __LINE__,
+                     "remote_write_bytes: bad internal state");
     default:
-      internal_error ("%s:%d: bad switch", __FILE__, __LINE__);
+      internal_error (__FILE__, __LINE__, "bad switch");
     }
   
   putpkt_binary (buf, (int) (p - buf));
@@ -3983,7 +4154,7 @@ getpkt (char *buf,
    executing user code to stop. If FOREVER == 0, this function is
    allowed to time out gracefully and return an indication of this to
    the caller. */
-int
+static int
 getpkt_sane (char *buf,
        long sizeof_buf,
        int forever)
@@ -4340,7 +4511,8 @@ watchpoint_to_Z_packet (int type)
       return 4;
       break;
     default:
-      internal_error ("hw_bp_to_z: bad watchpoint type %d", type);
+      internal_error (__FILE__, __LINE__,
+                     "hw_bp_to_z: bad watchpoint type %d", type);
     }
 }
 
@@ -4376,7 +4548,8 @@ remote_insert_watchpoint (CORE_ADDR addr, int len, int type)
     case PACKET_OK:
       return 0;
     }
-  internal_error ("remote_insert_watchpoint: reached end of function");
+  internal_error (__FILE__, __LINE__,
+                 "remote_insert_watchpoint: reached end of function");
 }
 
 /* FIXME: This function should be static and a member of the remote
@@ -4410,7 +4583,8 @@ remote_remove_watchpoint (CORE_ADDR addr, int len, int type)
     case PACKET_OK:
       return 0;
     }
-  internal_error ("remote_remove_watchpoint: reached end of function");
+  internal_error (__FILE__, __LINE__,
+                 "remote_remove_watchpoint: reached end of function");
 }
 
 /* FIXME: This function should be static and a member of the remote
@@ -4446,7 +4620,8 @@ remote_insert_hw_breakpoint (CORE_ADDR addr, int len)
     case PACKET_OK:
       return 0;
     }
-  internal_error ("remote_remove_watchpoint: reached end of function");
+  internal_error (__FILE__, __LINE__,
+                 "remote_remove_watchpoint: reached end of function");
 }
 
 /* FIXME: This function should be static and a member of the remote
@@ -4482,7 +4657,8 @@ remote_remove_hw_breakpoint (CORE_ADDR addr, int len)
     case PACKET_OK:
       return 0;
     }
-  internal_error ("remote_remove_watchpoint: reached end of function");
+  internal_error (__FILE__, __LINE__,
+                 "remote_remove_watchpoint: reached end of function");
 }
 
 /* Some targets are only capable of doing downloads, and afterwards
@@ -4565,7 +4741,7 @@ compare_sections_command (char *args, int from_tty)
   struct cleanup *old_chain;
   char *tmp;
   char *sectdata;
-  char *sectname;
+  const char *sectname;
   char *buf = alloca (PBUFSIZ);
   bfd_size_type size;
   bfd_vma lma;
@@ -4587,7 +4763,7 @@ compare_sections_command (char *args, int from_tty)
       if (size == 0)
        continue;               /* skip zero-length section */
 
-      sectname = (char *) bfd_get_section_name (exec_bfd, s);
+      sectname = bfd_get_section_name (exec_bfd, s);
       if (args && strcmp (args, sectname) != 0)
        continue;               /* not the section selected by user */
 
@@ -4927,6 +5103,18 @@ init_remote_threadtests (void)
 
 #endif /* 0 */
 
+/* Convert a thread ID to a string.  Returns the string in a static
+   buffer.  */
+
+static char *
+remote_pid_to_str (int pid)
+{
+  static char buf[30];
+
+  sprintf (buf, "Thread %d", pid);
+  return buf;
+}
+
 static void
 init_remote_ops (void)
 {
@@ -4954,6 +5142,7 @@ Specify the serial device it is connected to\n\
   remote_ops.to_thread_alive = remote_thread_alive;
   remote_ops.to_find_new_threads = remote_threads_info;
   remote_ops.to_extra_thread_info = remote_threads_extra_info;
+  remote_ops.to_pid_to_str = remote_pid_to_str;
   remote_ops.to_stop = remote_stop;
   remote_ops.to_query = remote_query;
   remote_ops.to_rcmd = remote_rcmd;
@@ -5405,7 +5594,8 @@ static void
 remote_async (void (*callback) (enum inferior_event_type event_type, void *context), void *context)
 {
   if (current_target.to_async_mask_value == 0)
-    internal_error ("Calling remote_async when async is masked");
+    internal_error (__FILE__, __LINE__,
+                   "Calling remote_async when async is masked");
 
   if (callback != NULL)
     {
@@ -5496,7 +5686,10 @@ set_remote_cmd (char *args, int from_tty)
 static void
 show_remote_cmd (char *args, int from_tty)
 {
+  
   show_remote_protocol_Z_packet_cmd (args, from_tty);
+  show_remote_protocol_e_packet_cmd (args, from_tty);
+  show_remote_protocol_E_packet_cmd (args, from_tty);
   show_remote_protocol_P_packet_cmd (args, from_tty);
   show_remote_protocol_binary_download_cmd (args, from_tty);
 }
@@ -5508,7 +5701,7 @@ build_remote_gdbarch_data (void)
 
   /* Cisco stuff */
   tty_input = xmalloc (PBUFSIZ);
-  remote_address_size = TARGET_PTR_BIT;
+  remote_address_size = TARGET_ADDR_BIT;
 }
 
 void
@@ -5641,6 +5834,20 @@ in a memory packet.\n",
   add_info ("remote-process", remote_info_process,
            "Query the remote system for process info.");
 
+  add_packet_config_cmd (&remote_protocol_e,
+                        "e", "step-over-range",
+                        set_remote_protocol_e_packet_cmd,
+                        show_remote_protocol_e_packet_cmd,
+                        &remote_set_cmdlist, &remote_show_cmdlist,
+                        0);
+
+  add_packet_config_cmd (&remote_protocol_E,
+                        "E", "step-over-range-w-signal",
+                        set_remote_protocol_E_packet_cmd,
+                        show_remote_protocol_E_packet_cmd,
+                        &remote_set_cmdlist, &remote_show_cmdlist,
+                        0);
+
   add_packet_config_cmd (&remote_protocol_P,
                         "P", "set-register",
                         set_remote_protocol_P_packet_cmd,
This page took 0.057797 seconds and 4 git commands to generate.