2003-04-09 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / remote.c
index 017be6c9bcd9a5f8d1537e3a2aa68199445ec7e7..5edea0102753eee58761fbc90382e809c023b4dc 100644 (file)
@@ -1,6 +1,7 @@
 /* Remote target communications for serial-line targets in custom GDB protocol
-   Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
-   1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+   Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+   1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -85,7 +86,7 @@ static void remote_resume (ptid_t ptid, int step,
                            enum target_signal siggnal);
 static void remote_async_resume (ptid_t ptid, int step,
                                 enum target_signal siggnal);
-static int remote_start_remote (PTR);
+static int remote_start_remote (struct ui_out *uiout, void *dummy);
 
 static void remote_open (char *name, int from_tty);
 static void remote_async_open (char *name, int from_tty);
@@ -93,9 +94,8 @@ static void remote_async_open (char *name, int from_tty);
 static void extended_remote_open (char *name, int from_tty);
 static void extended_remote_async_open (char *name, int from_tty);
 
-static void remote_open_1 (char *, int, struct target_ops *, int extended_p);
-static void remote_async_open_1 (char *, int, struct target_ops *,
-                                int extended_p);
+static void remote_open_1 (char *, int, struct target_ops *, int extended_p,
+                          int async_p);
 
 static void remote_close (int quitting);
 
@@ -204,21 +204,34 @@ static void show_packet_config_cmd (struct packet_config *config);
 
 static void update_packet_config (struct packet_config *config);
 
-/* Define the target subroutine names */
-
-void open_remote_target (char *, int, struct target_ops *, int);
-
 void _initialize_remote (void);
 
-/* Description of the remote protocol.  Strictly speeking, when the
+/* Description of the remote protocol.  Strictly speaking, when the
    target is open()ed, remote.c should create a per-target description
    of the remote protocol using that target's architecture.
    Unfortunatly, the target stack doesn't include local state.  For
    the moment keep the information in the target's architecture
    object.  Sigh..  */
 
+struct packet_reg
+{
+  long offset; /* Offset into G packet.  */
+  long regnum; /* GDB's internal register number.  */
+  LONGEST pnum; /* Remote protocol register number.  */
+  int in_g_packet; /* Always part of G packet.  */
+  /* long size in bytes;  == REGISTER_RAW_SIZE (regnum); at present.  */
+  /* char *name; == REGISTER_NAME (regnum); at present.  */
+};
+
 struct remote_state
 {
+  /* Description of the remote protocol registers.  */
+  long sizeof_g_packet;
+
+  /* Description of the remote protocol registers indexed by REGNUM
+     (making an array of NUM_REGS + NUM_PSEUDO_REGS in size).  */
+  struct packet_reg *regs;
+
   /* This is the size (in chars) of the first response to the ``g''
      packet.  It is used as a heuristic when determining the maximum
      size of memory-read and memory-write packets.  A target will
@@ -232,13 +245,14 @@ struct remote_state
   long remote_packet_size;
 };
 
+
 /* Handle for retreving the remote protocol data from gdbarch.  */
 static struct gdbarch_data *remote_gdbarch_data_handle;
 
 static struct remote_state *
-get_remote_state ()
+get_remote_state (void)
 {
-  return gdbarch_data (remote_gdbarch_data_handle);
+  return gdbarch_data (current_gdbarch, remote_gdbarch_data_handle);
 }
 
 static void *
@@ -247,6 +261,23 @@ init_remote_state (struct gdbarch *gdbarch)
   int regnum;
   struct remote_state *rs = xmalloc (sizeof (struct remote_state));
 
+  /* Start out by having the remote protocol mimic the existing
+     behavour - just copy in the description of the register cache.  */
+  rs->sizeof_g_packet = REGISTER_BYTES; /* OK use.   */
+
+  /* Assume a 1:1 regnum<->pnum table.  */
+  rs->regs = xcalloc (NUM_REGS + NUM_PSEUDO_REGS, sizeof (struct packet_reg));
+  for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++)
+    {
+      struct packet_reg *r = &rs->regs[regnum];
+      r->pnum = regnum;
+      r->regnum = regnum;
+      r->offset = REGISTER_BYTE (regnum);
+      r->in_g_packet = (regnum < NUM_REGS);
+      /* ...size = REGISTER_RAW_SIZE (regnum); */
+      /* ...name = REGISTER_NAME (regnum); */
+    }
+
   /* Default maximum number of characters in a packet body. Many
      remote stubs have a hardwired buffer size of 400 bytes
      (c.f. BUFMAX in m68k-stub.c and i386-stub.c).  BUFMAX-1 is used
@@ -256,14 +287,14 @@ init_remote_state (struct gdbarch *gdbarch)
      already a full buffer (As of 1999-12-04 that was most stubs. */
   rs->remote_packet_size = 400 - 1;
 
-  /* Should REGISTER_BYTES needs more space than the default, adjust
-     the size accordingly. Remember that each byte is encoded as two
-     characters. 32 is the overhead for the packet header /
-     footer. NOTE: cagney/1999-10-26: I suspect that 8
+  /* Should rs->sizeof_g_packet needs more space than the
+     default, adjust the size accordingly. Remember that each byte is
+     encoded as two characters. 32 is the overhead for the packet
+     header / footer. NOTE: cagney/1999-10-26: I suspect that 8
      (``$NN:G...#NN'') is a better guess, the below has been padded a
      little. */
-  if (REGISTER_BYTES > ((rs->remote_packet_size - 32) / 2))
-    rs->remote_packet_size = (REGISTER_BYTES * 2 + 32);
+  if (rs->sizeof_g_packet > ((rs->remote_packet_size - 32) / 2))
+    rs->remote_packet_size = (rs->sizeof_g_packet * 2 + 32);
   
   /* This one is filled in when a ``g'' packet is received. */
   rs->actual_register_packet_size = 0;
@@ -274,11 +305,48 @@ init_remote_state (struct gdbarch *gdbarch)
 static void
 free_remote_state (struct gdbarch *gdbarch, void *pointer)
 {
-  struct remote_state *state = pointer;
-  xfree (state);
+  struct remote_state *data = pointer;
+  xfree (data->regs);
+  xfree (data);
+}
+
+static struct packet_reg *
+packet_reg_from_regnum (struct remote_state *rs, long regnum)
+{
+  if (regnum < 0 && regnum >= NUM_REGS + NUM_PSEUDO_REGS)
+    return NULL;
+  else
+    {
+      struct packet_reg *r = &rs->regs[regnum];
+      gdb_assert (r->regnum == regnum);
+      return r;
+    }
+}
+
+static struct packet_reg *
+packet_reg_from_pnum (struct remote_state *rs, LONGEST pnum)
+{
+  int i;
+  for (i = 0; i < NUM_REGS + NUM_PSEUDO_REGS; i++)
+    {
+      struct packet_reg *r = &rs->regs[i];
+      if (r->pnum == pnum)
+       return r;
+    }
+  return NULL;
 }
 
-/* */
+/* FIXME: graces/2002-08-08: These variables should eventually be
+   bound to an instance of the target object (as in gdbarch-tdep()),
+   when such a thing exists.  */
+
+/* This is set to the data address of the access causing the target
+   to stop for a watchpoint.  */
+static CORE_ADDR remote_watch_data_address;
+
+/* This is non-zero if taregt stopped for a watchpoint. */
+static int remote_stopped_by_watchpoint_p;
+
 
 static struct target_ops remote_ops;
 
@@ -336,12 +404,12 @@ static int remote_async_terminal_ours_p;
 
 \f
 /* User configurable variables for the number of characters in a
-   memory read/write packet.  MIN ((rs->remote_packet_size), g-packet-size) is the
-   default.  Some targets need smaller values (fifo overruns, et.al.)
-   and some users need larger values (speed up transfers).  The
-   variables ``preferred_*'' (the user request), ``current_*'' (what
-   was actually set) and ``forced_*'' (Positive - a soft limit,
-   negative - a hard limit). */
+   memory read/write packet.  MIN ((rs->remote_packet_size),
+   rs->sizeof_g_packet) is the default.  Some targets need smaller
+   values (fifo overruns, et.al.)  and some users need larger values
+   (speed up transfers).  The variables ``preferred_*'' (the user
+   request), ``current_*'' (what was actually set) and ``forced_*''
+   (Positive - a soft limit, negative - a hard limit). */
 
 struct memory_packet_config
 {
@@ -521,7 +589,7 @@ struct packet_config
   {
     char *name;
     char *title;
-    enum cmd_auto_boolean detect;
+    enum auto_boolean detect;
     enum packet_support support;
   };
 
@@ -540,13 +608,13 @@ update_packet_config (struct packet_config *config)
 {
   switch (config->detect)
     {
-    case CMD_AUTO_BOOLEAN_TRUE:
+    case AUTO_BOOLEAN_TRUE:
       config->support = PACKET_ENABLE;
       break;
-    case CMD_AUTO_BOOLEAN_FALSE:
+    case AUTO_BOOLEAN_FALSE:
       config->support = PACKET_DISABLE;
       break;
-    case CMD_AUTO_BOOLEAN_AUTO:
+    case AUTO_BOOLEAN_AUTO:
       config->support = PACKET_SUPPORT_UNKNOWN;
       break;
     }
@@ -570,12 +638,12 @@ show_packet_config_cmd (struct packet_config *config)
     }
   switch (config->detect)
     {
-    case CMD_AUTO_BOOLEAN_AUTO:
+    case AUTO_BOOLEAN_AUTO:
       printf_filtered ("Support for remote protocol `%s' (%s) packet is auto-detected, currently %s.\n",
                       config->name, config->title, support);
       break;
-    case CMD_AUTO_BOOLEAN_TRUE:
-    case CMD_AUTO_BOOLEAN_FALSE:
+    case AUTO_BOOLEAN_TRUE:
+    case AUTO_BOOLEAN_FALSE:
       printf_filtered ("Support for remote protocol `%s' (%s) packet is currently %s.\n",
                       config->name, config->title, support);
       break;
@@ -586,11 +654,8 @@ static void
 add_packet_config_cmd (struct packet_config *config,
                       char *name,
                       char *title,
-                      void (*set_func) (char *args, int from_tty,
-                                        struct cmd_list_element *
-                                        c),
-                      void (*show_func) (char *name,
-                                         int from_tty),
+                      cmd_sfunc_ftype *set_func,
+                      cmd_sfunc_ftype *show_func,
                       struct cmd_list_element **set_remote_list,
                       struct cmd_list_element **show_remote_list,
                       int legacy)
@@ -602,7 +667,7 @@ add_packet_config_cmd (struct packet_config *config,
   char *cmd_name;
   config->name = name;
   config->title = title;
-  config->detect = CMD_AUTO_BOOLEAN_AUTO;
+  config->detect = AUTO_BOOLEAN_AUTO;
   config->support = PACKET_SUPPORT_UNKNOWN;
   xasprintf (&set_doc, "Set use of remote protocol `%s' (%s) packet",
             name, title);
@@ -610,12 +675,10 @@ add_packet_config_cmd (struct packet_config *config,
             name, title);
   /* set/show TITLE-packet {auto,on,off} */
   xasprintf (&cmd_name, "%s-packet", title);
-  set_cmd = add_set_auto_boolean_cmd (cmd_name, class_obscure,
-                               &config->detect, set_doc,
-                               set_remote_list);
-  set_cmd->function.sfunc = set_func;
-  show_cmd = add_cmd (cmd_name, class_obscure, show_func, show_doc,
-                     show_remote_list);
+  add_setshow_auto_boolean_cmd (cmd_name, class_obscure,
+                               &config->detect, set_doc, show_doc,
+                               set_func, show_func,
+                               set_remote_list, show_remote_list);
   /* set/show remote NAME-packet {auto,on,off} -- legacy */
   if (legacy)
     {
@@ -668,7 +731,7 @@ packet_ok (const char *buf, struct packet_config *config)
       switch (config->support)
        {
        case PACKET_ENABLE:
-         if (config->detect == CMD_AUTO_BOOLEAN_AUTO)
+         if (config->detect == AUTO_BOOLEAN_AUTO)
            /* If the stub previously indicated that the packet was
               supported then there is a protocol error.. */
            error ("Protocol error: %s (%s) conflicting enabled responses.",
@@ -703,7 +766,8 @@ set_remote_protocol_qSymbol_packet_cmd (char *args, int from_tty,
 }
 
 static void
-show_remote_protocol_qSymbol_packet_cmd (char *args, int from_tty)
+show_remote_protocol_qSymbol_packet_cmd (char *args, int from_tty,
+                                        struct cmd_list_element *c)
 {
   show_packet_config_cmd (&remote_protocol_qSymbol);
 }
@@ -719,7 +783,8 @@ set_remote_protocol_e_packet_cmd (char *args, int from_tty,
 }
 
 static void
-show_remote_protocol_e_packet_cmd (char *args, int from_tty)
+show_remote_protocol_e_packet_cmd (char *args, int from_tty,
+                                  struct cmd_list_element *c)
 {
   show_packet_config_cmd (&remote_protocol_e);
 }
@@ -736,7 +801,8 @@ set_remote_protocol_E_packet_cmd (char *args, int from_tty,
 }
 
 static void
-show_remote_protocol_E_packet_cmd (char *args, int from_tty)
+show_remote_protocol_E_packet_cmd (char *args, int from_tty,
+                                  struct cmd_list_element *c)
 {
   show_packet_config_cmd (&remote_protocol_E);
 }
@@ -754,7 +820,8 @@ set_remote_protocol_P_packet_cmd (char *args, int from_tty,
 }
 
 static void
-show_remote_protocol_P_packet_cmd (char *args, int from_tty)
+show_remote_protocol_P_packet_cmd (char *args, int from_tty,
+                                  struct cmd_list_element *c)
 {
   show_packet_config_cmd (&remote_protocol_P);
 }
@@ -784,7 +851,8 @@ set_remote_protocol_Z_software_bp_packet_cmd (char *args, int from_tty,
 }
 
 static void
-show_remote_protocol_Z_software_bp_packet_cmd (char *args, int from_tty)
+show_remote_protocol_Z_software_bp_packet_cmd (char *args, int from_tty,
+                                              struct cmd_list_element *c)
 {
   show_packet_config_cmd (&remote_protocol_Z[Z_PACKET_SOFTWARE_BP]);
 }
@@ -797,7 +865,8 @@ set_remote_protocol_Z_hardware_bp_packet_cmd (char *args, int from_tty,
 }
 
 static void
-show_remote_protocol_Z_hardware_bp_packet_cmd (char *args, int from_tty)
+show_remote_protocol_Z_hardware_bp_packet_cmd (char *args, int from_tty,
+                                              struct cmd_list_element *c)
 {
   show_packet_config_cmd (&remote_protocol_Z[Z_PACKET_HARDWARE_BP]);
 }
@@ -810,7 +879,8 @@ set_remote_protocol_Z_write_wp_packet_cmd (char *args, int from_tty,
 }
 
 static void
-show_remote_protocol_Z_write_wp_packet_cmd (char *args, int from_tty)
+show_remote_protocol_Z_write_wp_packet_cmd (char *args, int from_tty,
+                                           struct cmd_list_element *c)
 {
   show_packet_config_cmd (&remote_protocol_Z[Z_PACKET_WRITE_WP]);
 }
@@ -823,7 +893,8 @@ set_remote_protocol_Z_read_wp_packet_cmd (char *args, int from_tty,
 }
 
 static void
-show_remote_protocol_Z_read_wp_packet_cmd (char *args, int from_tty)
+show_remote_protocol_Z_read_wp_packet_cmd (char *args, int from_tty,
+                                          struct cmd_list_element *c)
 {
   show_packet_config_cmd (&remote_protocol_Z[Z_PACKET_READ_WP]);
 }
@@ -836,7 +907,8 @@ set_remote_protocol_Z_access_wp_packet_cmd (char *args, int from_tty,
 }
 
 static void
-show_remote_protocol_Z_access_wp_packet_cmd (char *args, int from_tty)
+show_remote_protocol_Z_access_wp_packet_cmd (char *args, int from_tty,
+                                            struct cmd_list_element *c)
 {
   show_packet_config_cmd (&remote_protocol_Z[Z_PACKET_ACCESS_WP]);
 }
@@ -844,7 +916,7 @@ show_remote_protocol_Z_access_wp_packet_cmd (char *args, int from_tty)
 /* For compatibility with older distributions.  Provide a ``set remote
    Z-packet ...'' command that updates all the Z packet types. */
 
-static enum cmd_auto_boolean remote_Z_packet_detect;
+static enum auto_boolean remote_Z_packet_detect;
 
 static void
 set_remote_protocol_Z_packet_cmd (char *args, int from_tty,
@@ -859,7 +931,8 @@ set_remote_protocol_Z_packet_cmd (char *args, int from_tty,
 }
 
 static void
-show_remote_protocol_Z_packet_cmd (char *args, int from_tty)
+show_remote_protocol_Z_packet_cmd (char *args, int from_tty,
+                                  struct cmd_list_element *c)
 {
   int i;
   for (i = 0; i < NR_Z_PACKET_TYPES; i++)
@@ -900,16 +973,16 @@ set_remote_protocol_binary_download_cmd (char *args,
 }
 
 static void
-show_remote_protocol_binary_download_cmd (char *args,
-                                         int from_tty)
+show_remote_protocol_binary_download_cmd (char *args, int from_tty,
+                                         struct cmd_list_element *c)
 {
   show_packet_config_cmd (&remote_protocol_binary_download);
 }
 
 
 /* Tokens for use by the asynchronous signal handlers for SIGINT */
-PTR sigint_remote_twice_token;
-PTR sigint_remote_token;
+static void *sigint_remote_twice_token;
+static void *sigint_remote_token;
 
 /* These are pointers to hook functions that may be set in order to
    modify resume/wait behavior for a particular architecture.  */
@@ -940,14 +1013,9 @@ record_currthread (int currthread)
   if (!in_thread_list (pid_to_ptid (currthread)))
     {
       add_thread (pid_to_ptid (currthread));
-#ifdef UI_OUT
       ui_out_text (uiout, "[New ");
       ui_out_text (uiout, target_pid_to_str (pid_to_ptid (currthread)));
       ui_out_text (uiout, "]\n");
-#else
-      printf_filtered ("[New %s]\n",
-                       target_pid_to_str (pid_to_ptid (currthread)));
-#endif
     }
 }
 
@@ -1045,7 +1113,7 @@ struct gdb_ext_thread_info
 
 #define BUF_THREAD_ID_SIZE (OPAQUETHREADBYTES*2)
 
-char *unpack_varlen_hex (char *buff, int *result);
+char *unpack_varlen_hex (char *buff, ULONGEST *result);
 
 static char *unpack_nibble (char *buf, int *val);
 
@@ -1166,7 +1234,7 @@ stub_unpack_int (char *buff, int fieldlength)
 
 char *
 unpack_varlen_hex (char *buff, /* packet to parse */
-                  int *result)
+                  ULONGEST *result)
 {
   int nibble;
   int retval = 0;
@@ -2050,14 +2118,16 @@ remote_cisco_objfile_relocate (bfd_signed_vma text_off, bfd_signed_vma data_off,
 /* Stub for catch_errors.  */
 
 static int
-remote_start_remote_dummy (void *dummy)
+remote_start_remote_dummy (struct ui_out *uiout, void *dummy)
 {
   start_remote ();             /* Initialize gdb process mechanisms */
+  /* NOTE: Return something >=0.  A -ve value is reserved for
+     catch_exceptions.  */
   return 1;
 }
 
 static int
-remote_start_remote (PTR dummy)
+remote_start_remote (struct ui_out *uiout, void *dummy)
 {
   immediate_quit++;            /* Allow user to interrupt it */
 
@@ -2074,7 +2144,9 @@ remote_start_remote (PTR dummy)
   putpkt ("?");                        /* initiate a query from remote machine */
   immediate_quit--;
 
-  return remote_start_remote_dummy (dummy);
+  /* NOTE: See comment above in remote_start_remote_dummy().  This
+     function returns something >=0.  */
+  return remote_start_remote_dummy (uiout, dummy);
 }
 
 /* Open a connection to a remote debugger.
@@ -2083,14 +2155,14 @@ remote_start_remote (PTR dummy)
 static void
 remote_open (char *name, int from_tty)
 {
-  remote_open_1 (name, from_tty, &remote_ops, 0);
+  remote_open_1 (name, from_tty, &remote_ops, 0, 0);
 }
 
 /* Just like remote_open, but with asynchronous support. */
 static void
 remote_async_open (char *name, int from_tty)
 {
-  remote_async_open_1 (name, from_tty, &remote_async_ops, 0);
+  remote_open_1 (name, from_tty, &remote_async_ops, 0, 1);
 }
 
 /* Open a connection to a remote debugger using the extended
@@ -2099,14 +2171,16 @@ remote_async_open (char *name, int from_tty)
 static void
 extended_remote_open (char *name, int from_tty)
 {
-  remote_open_1 (name, from_tty, &extended_remote_ops, 1 /*extended_p */ );
+  remote_open_1 (name, from_tty, &extended_remote_ops, 1 /*extended_p */,
+                0 /* async_p */);
 }
 
 /* Just like extended_remote_open, but with asynchronous support. */
 static void
 extended_remote_async_open (char *name, int from_tty)
 {
-  remote_async_open_1 (name, from_tty, &extended_async_remote_ops, 1 /*extended_p */ );
+  remote_open_1 (name, from_tty, &extended_async_remote_ops,
+                1 /*extended_p */, 1 /* async_p */);
 }
 
 /* Generic code for opening a connection to a remote target.  */
@@ -2165,122 +2239,46 @@ remote_check_symbols (struct objfile *objfile)
     }
 }
 
-static void
-remote_open_1 (char *name, int from_tty, struct target_ops *target,
-              int extended_p)
+static struct serial *
+remote_serial_open (char *name)
 {
-  struct remote_state *rs = get_remote_state ();
-  if (name == 0)
-    error ("To open a remote debug connection, you need to specify what\n\
-serial device is attached to the remote system\n\
-(e.g. /dev/ttyS0, /dev/ttya, COM1, etc.).");
-
-  /* See FIXME above */
-  wait_forever_enabled_p = 1;
+  static int udp_warning = 0;
 
-  target_preopen (from_tty);
-
-  unpush_target (target);
-
-  remote_desc = serial_open (name);
-  if (!remote_desc)
-    perror_with_name (name);
-
-  if (baud_rate != -1)
+  /* FIXME: Parsing NAME here is a hack.  But we want to warn here instead
+     of in ser-tcp.c, because it is the remote protocol assuming that the
+     serial connection is reliable and not the serial connection promising
+     to be.  */
+  if (!udp_warning && strncmp (name, "udp:", 4) == 0)
     {
-      if (serial_setbaudrate (remote_desc, baud_rate))
-       {
-         serial_close (remote_desc);
-         perror_with_name (name);
-       }
+      warning ("The remote protocol may be unreliable over UDP.");
+      warning ("Some events may be lost, rendering further debugging "
+              "impossible.");
+      udp_warning = 1;
     }
 
-  serial_raw (remote_desc);
-
-  /* If there is something sitting in the buffer we might take it as a
-     response to a command, which would be bad.  */
-  serial_flush_input (remote_desc);
-
-  if (from_tty)
-    {
-      puts_filtered ("Remote debugging using ");
-      puts_filtered (name);
-      puts_filtered ("\n");
-    }
-  push_target (target);                /* Switch to using remote target now */
-
-  init_all_packet_configs ();
-  
-  general_thread = -2;
-  continue_thread = -2;
-
-  /* Probe for ability to use "ThreadInfo" query, as required.  */
-  use_threadinfo_query = 1;
-  use_threadextra_query = 1;
-
-  /* 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_ptid = pid_to_ptid (MAGIC_NULL_PID);
-#ifdef SOLIB_CREATE_INFERIOR_HOOK
-  /* First delete any symbols previously loaded from shared libraries. */
-  no_shared_libraries (NULL, 0);
-#endif
-
-  /* Start the remote 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).  */
-  if (!catch_errors (remote_start_remote, NULL,
-                    "Couldn't establish connection to remote target\n",
-                    RETURN_MASK_ALL))
-    {
-      pop_target ();
-      return;
-    }
-
-  if (extended_p)
-    {
-      /* Tell the remote that we are using the extended protocol.  */
-      char *buf = alloca (rs->remote_packet_size);
-      putpkt ("!");
-      getpkt (buf, (rs->remote_packet_size), 0);
-    }
-#ifdef SOLIB_CREATE_INFERIOR_HOOK
-  /* 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.  */
-
-  /* Set up to detect and load shared libraries. */
-  if (exec_bfd)        /* No use without an exec file. */
-    {
-      SOLIB_CREATE_INFERIOR_HOOK (PIDGET (inferior_ptid));
-      remote_check_symbols (symfile_objfile);
-    }
-#endif
+  return serial_open (name);
 }
 
-/* Just like remote_open but with asynchronous support. */
 static void
-remote_async_open_1 (char *name, int from_tty, struct target_ops *target,
-                    int extended_p)
+remote_open_1 (char *name, int from_tty, struct target_ops *target,
+              int extended_p, int async_p)
 {
+  int ex;
   struct remote_state *rs = get_remote_state ();
   if (name == 0)
-    error ("To open a remote debug connection, you need to specify what\n\
-serial device is attached to the remote system\n\
-(e.g. /dev/ttyS0, /dev/ttya, COM1, etc.).");
+    error ("To open a remote debug connection, you need to specify what\n"
+          "serial device is attached to the remote system\n"
+          "(e.g. /dev/ttyS0, /dev/ttya, COM1, etc.).");
+
+  /* See FIXME above */
+  if (!async_p)
+    wait_forever_enabled_p = 1;
 
   target_preopen (from_tty);
 
   unpush_target (target);
 
-  remote_desc = serial_open (name);
+  remote_desc = remote_serial_open (name);
   if (!remote_desc)
     perror_with_name (name);
 
@@ -2305,11 +2303,10 @@ serial device is attached to the remote system\n\
       puts_filtered (name);
       puts_filtered ("\n");
     }
-
   push_target (target);                /* Switch to using remote target now */
 
   init_all_packet_configs ();
-
+  
   general_thread = -2;
   continue_thread = -2;
 
@@ -2323,38 +2320,59 @@ serial device is attached to the remote system\n\
      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_ptid = pid_to_ptid (MAGIC_NULL_PID);
 
-  /* With this target we start out by owning the terminal. */
-  remote_async_terminal_ours_p = 1;
+  inferior_ptid = pid_to_ptid (MAGIC_NULL_PID);
 
-  /* FIXME: cagney/1999-09-23: During the initial connection it is
-     assumed that the target is already ready and able to respond to
-     requests. Unfortunately remote_start_remote() eventually calls
-     wait_for_inferior() with no timeout.  wait_forever_enabled_p gets
-     around this. Eventually a mechanism that allows
-     wait_for_inferior() to expect/get timeouts will be
-     implemented. */
-  wait_forever_enabled_p = 0;
+  if (async_p)
+    {
+      /* With this target we start out by owning the terminal. */
+      remote_async_terminal_ours_p = 1;
+
+      /* FIXME: cagney/1999-09-23: During the initial connection it is
+        assumed that the target is already ready and able to respond to
+        requests. Unfortunately remote_start_remote() eventually calls
+        wait_for_inferior() with no timeout.  wait_forever_enabled_p gets
+        around this. Eventually a mechanism that allows
+        wait_for_inferior() to expect/get timeouts will be
+        implemented. */
+      wait_forever_enabled_p = 0;
+    }
 
 #ifdef SOLIB_CREATE_INFERIOR_HOOK
   /* First delete any symbols previously loaded from shared libraries. */
   no_shared_libraries (NULL, 0);
 #endif
 
-  /* Start the remote 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).  */
-  if (!catch_errors (remote_start_remote, NULL,
-                    "Couldn't establish connection to remote target\n",
-                    RETURN_MASK_ALL))
+  /* Start the remote connection.  If error() or QUIT, discard this
+     target (we'd otherwise be in an inconsistent state) and then
+     propogate the error on up the exception chain.  This ensures that
+     the caller doesn't stumble along blindly assuming that the
+     function succeeded.  The CLI doesn't have this problem but other
+     UI's, such as MI do.
+
+     FIXME: cagney/2002-05-19: Instead of re-throwing the exception,
+     this function should return an error indication letting the
+     caller restore the previous state.  Unfortunatly the command
+     ``target remote'' is directly wired to this function making that
+     impossible.  On a positive note, the CLI side of this problem has
+     been fixed - the function set_cmd_context() makes it possible for
+     all the ``target ....'' commands to share a common callback
+     function.  See cli-dump.c.  */
+  ex = catch_exceptions (uiout,
+                        remote_start_remote, NULL,
+                        "Couldn't establish connection to remote"
+                        " target\n",
+                        RETURN_MASK_ALL);
+  if (ex < 0)
     {
       pop_target ();
-      wait_forever_enabled_p = 1;
-      return;
+      if (async_p)
+       wait_forever_enabled_p = 1;
+      throw_exception (ex);
     }
 
-  wait_forever_enabled_p = 1;
+  if (async_p)
+    wait_forever_enabled_p = 1;
 
   if (extended_p)
     {
@@ -2820,7 +2838,7 @@ interrupt_query (void)
 Give up (and stop debugging it)? "))
     {
       target_mourn_inferior ();
-      return_to_top_level (RETURN_QUIT);
+      throw_exception (RETURN_QUIT);
     }
 
   target_terminal_inferior ();
@@ -2901,7 +2919,8 @@ remote_wait (ptid_t ptid, struct target_waitstatus *status)
 {
   struct remote_state *rs = get_remote_state ();
   unsigned char *buf = alloca (rs->remote_packet_size);
-  int thread_num = -1;
+  ULONGEST thread_num = -1;
+  ULONGEST addr;
 
   status->kind = TARGET_WAITKIND_EXITED;
   status->value.integer = 0;
@@ -2919,6 +2938,8 @@ remote_wait (ptid_t ptid, struct target_waitstatus *status)
       if (target_wait_loop_hook)
        (*target_wait_loop_hook) ();
 
+      remote_stopped_by_watchpoint_p = 0;
+
       switch (buf[0])
        {
        case 'E':               /* Error of some sort */
@@ -2927,7 +2948,6 @@ remote_wait (ptid_t ptid, struct target_waitstatus *status)
        case 'T':               /* Status with PC, SP, FP, ... */
          {
            int i;
-           long regno;
            char* regs = (char*) alloca (MAX_REGISTER_RAW_SIZE);
 
            /* Expedited reply, containing Signal, {regno, reg} repeat */
@@ -2943,27 +2963,56 @@ remote_wait (ptid_t ptid, struct target_waitstatus *status)
                unsigned char *p1;
                char *p_temp;
                int fieldsize;
+               LONGEST pnum = 0;
+
+               /* If the packet contains a register number save it in pnum
+                  and set p1 to point to the character following it. 
+                  Otherwise p1 points to p.  */
 
-               /* Read the register number */
-               regno = strtol ((const char *) p, &p_temp, 16);
-               p1 = (unsigned char *) p_temp;
+               /* If this packet is an awatch packet, don't parse the 'a'
+                  as a register number.  */
+
+               if (strncmp (p, "awatch", strlen("awatch")) != 0)
+                 {
+                   /* Read the ``P'' register number.  */
+                   pnum = strtol (p, &p_temp, 16);
+                   p1 = (unsigned char *) p_temp;
+                 }
+               else 
+                 p1 = p;
 
                if (p1 == p)    /* No register number present here */
                  {
-                   p1 = (unsigned char *) strchr ((const char *) p, ':');
+                   p1 = (unsigned char *) strchr (p, ':');
                    if (p1 == NULL)
                      warning ("Malformed packet(a) (missing colon): %s\n\
 Packet: '%s'\n",
                               p, buf);
-                   if (strncmp ((const char *) p, "thread", p1 - p) == 0)
+                   if (strncmp (p, "thread", p1 - p) == 0)
                      {
                        p_temp = unpack_varlen_hex (++p1, &thread_num);
                        record_currthread (thread_num);
                        p = (unsigned char *) p_temp;
                      }
+                   else if ((strncmp (p, "watch", p1 - p) == 0)
+                            || (strncmp (p, "rwatch", p1 - p) == 0)
+                            || (strncmp (p, "awatch", p1 - p) == 0))
+                     {
+                       remote_stopped_by_watchpoint_p = 1;
+                       p = unpack_varlen_hex (++p1, &addr);
+                       remote_watch_data_address = (CORE_ADDR)addr;
+                     }
+                   else
+                     {
+                       /* Silently skip unknown optional info.  */
+                       p_temp = strchr (p1 + 1, ';');
+                       if (p_temp)
+                         p = (unsigned char *) p_temp;
+                     }
                  }
                else
                  {
+                   struct packet_reg *reg = packet_reg_from_pnum (rs, pnum);
                    p = p1;
 
                    if (*p++ != ':')
@@ -2971,16 +3020,16 @@ Packet: '%s'\n",
 Packet: '%s'\n",
                               p, buf);
 
-                   if (regno >= NUM_REGS)
-                     warning ("Remote sent bad register number %ld: %s\n\
+                   if (reg == NULL)
+                     warning ("Remote sent bad register number %s: %s\n\
 Packet: '%s'\n",
-                              regno, p, buf);
+                              phex_nz (pnum, 0), p, buf);
 
-                   fieldsize = hex2bin (p, regs, REGISTER_RAW_SIZE (regno));
+                   fieldsize = hex2bin (p, regs, REGISTER_RAW_SIZE (reg->regnum));
                    p += 2 * fieldsize;
-                   if (fieldsize < REGISTER_RAW_SIZE (regno))
+                   if (fieldsize < REGISTER_RAW_SIZE (reg->regnum))
                      warning ("Remote reply is too short: %s", buf);
-                   supply_register (regno, regs);
+                   supply_register (reg->regnum, regs);
                  }
 
                if (*p++ != ';')
@@ -3115,11 +3164,14 @@ remote_async_wait (ptid_t ptid, struct target_waitstatus *status)
 {
   struct remote_state *rs = get_remote_state ();
   unsigned char *buf = alloca (rs->remote_packet_size);
-  int thread_num = -1;
+  ULONGEST thread_num = -1;
+  ULONGEST addr;
 
   status->kind = TARGET_WAITKIND_EXITED;
   status->value.integer = 0;
 
+  remote_stopped_by_watchpoint_p = 0;
+
   while (1)
     {
       unsigned char *p;
@@ -3147,7 +3199,6 @@ remote_async_wait (ptid_t ptid, struct target_waitstatus *status)
        case 'T':               /* Status with PC, SP, FP, ... */
          {
            int i;
-           long regno;
            char* regs = (char*) alloca (MAX_REGISTER_RAW_SIZE);
 
            /* Expedited reply, containing Signal, {regno, reg} repeat */
@@ -3163,44 +3214,73 @@ remote_async_wait (ptid_t ptid, struct target_waitstatus *status)
                unsigned char *p1;
                char *p_temp;
                int fieldsize;
+               long pnum = 0;
 
-               /* Read the register number */
-               regno = strtol ((const char *) p, &p_temp, 16);
-               p1 = (unsigned char *) p_temp;
+               /* If the packet contains a register number, save it in pnum
+                  and set p1 to point to the character following it. 
+                  Otherwise p1 points to p.  */
+
+               /* If this packet is an awatch packet, don't parse the 'a'
+                  as a register number.  */
+               
+               if (!strncmp (p, "awatch", strlen ("awatch")) != 0)
+                 {
+                   /* Read the register number.  */
+                   pnum = strtol (p, &p_temp, 16);
+                   p1 = (unsigned char *) p_temp;
+                 }
+               else 
+                 p1 = p;
 
                if (p1 == p)    /* No register number present here */
                  {
-                   p1 = (unsigned char *) strchr ((const char *) p, ':');
+                   p1 = (unsigned char *) strchr (p, ':');
                    if (p1 == NULL)
                      warning ("Malformed packet(a) (missing colon): %s\n\
 Packet: '%s'\n",
                               p, buf);
-                   if (strncmp ((const char *) p, "thread", p1 - p) == 0)
+                   if (strncmp (p, "thread", p1 - p) == 0)
                      {
                        p_temp = unpack_varlen_hex (++p1, &thread_num);
                        record_currthread (thread_num);
                        p = (unsigned char *) p_temp;
                      }
+                   else if ((strncmp (p, "watch", p1 - p) == 0)
+                            || (strncmp (p, "rwatch", p1 - p) == 0)
+                            || (strncmp (p, "awatch", p1 - p) == 0))
+                     {
+                       remote_stopped_by_watchpoint_p = 1;
+                       p = unpack_varlen_hex (++p1, &addr);
+                       remote_watch_data_address = (CORE_ADDR)addr;
+                     }
+                   else
+                     {
+                       /* Silently skip unknown optional info.  */
+                       p_temp = (unsigned char *) strchr (p1 + 1, ';');
+                       if (p_temp)
+                         p = p_temp;
+                     }
                  }
+               
                else
                  {
+                   struct packet_reg *reg = packet_reg_from_pnum (rs, pnum);
                    p = p1;
-
                    if (*p++ != ':')
                      warning ("Malformed packet(b) (missing colon): %s\n\
 Packet: '%s'\n",
                               p, buf);
 
-                   if (regno >= NUM_REGS)
+                   if (reg == NULL)
                      warning ("Remote sent bad register number %ld: %s\n\
 Packet: '%s'\n",
-                              regno, p, buf);
+                              pnum, p, buf);
 
-                   fieldsize = hex2bin (p, regs, REGISTER_RAW_SIZE (regno));
+                   fieldsize = hex2bin (p, regs, REGISTER_RAW_SIZE (reg->regnum));
                    p += 2 * fieldsize;
-                   if (fieldsize < REGISTER_RAW_SIZE (regno))
+                   if (fieldsize < REGISTER_RAW_SIZE (reg->regnum))
                      warning ("Remote reply is too short: %s", buf);
-                   supply_register (regno, regs);
+                   supply_register (reg->regnum, regs);
                  }
 
                if (*p++ != ';')
@@ -3337,20 +3417,30 @@ got_status:
 static int register_bytes_found;
 
 /* Read the remote registers into the block REGS.  */
-/* Currently we just read all the registers, so we don't use regno.  */
+/* Currently we just read all the registers, so we don't use regnum.  */
 
 /* ARGSUSED */
 static void
-remote_fetch_registers (int regno)
+remote_fetch_registers (int regnum)
 {
   struct remote_state *rs = get_remote_state ();
   char *buf = alloca (rs->remote_packet_size);
   int i;
   char *p;
-  char *regs = alloca (REGISTER_BYTES);
+  char *regs = alloca (rs->sizeof_g_packet);
 
   set_thread (PIDGET (inferior_ptid), 1);
 
+  if (regnum >= 0)
+    {
+      struct packet_reg *reg = packet_reg_from_regnum (rs, regnum);
+      gdb_assert (reg != NULL);
+      if (!reg->in_g_packet)
+       internal_error (__FILE__, __LINE__,
+                       "Attempt to fetch a non G-packet register when this "
+                       "remote.c does not support the p-packet.");
+    }
+
   sprintf (buf, "g");
   remote_send (buf, (rs->remote_packet_size));
 
@@ -3361,7 +3451,7 @@ remote_fetch_registers (int regno)
     (rs->actual_register_packet_size) = strlen (buf);
 
   /* Unimplemented registers read as all bits zero.  */
-  memset (regs, 0, REGISTER_BYTES);
+  memset (regs, 0, rs->sizeof_g_packet);
 
   /* We can get out of synch in various cases.  If the first character
      in the buffer is not a hex character, assume that has happened
@@ -3381,7 +3471,7 @@ remote_fetch_registers (int regno)
      register cacheing/storage mechanism.  */
 
   p = buf;
-  for (i = 0; i < REGISTER_BYTES; i++)
+  for (i = 0; i < rs->sizeof_g_packet; i++)
     {
       if (p[0] == 0)
        break;
@@ -3407,13 +3497,20 @@ remote_fetch_registers (int regno)
        warning ("Remote reply is too short: %s", buf);
     }
 
-supply_them:
-  for (i = 0; i < NUM_REGS; i++)
-    {
-      supply_register (i, &regs[REGISTER_BYTE (i)]);
-      if (buf[REGISTER_BYTE (i) * 2] == 'x')
-       set_register_cached (i, -1);
-    }
+ supply_them:
+  {
+    int i;
+    for (i = 0; i < NUM_REGS + NUM_PSEUDO_REGS; i++)
+      {
+       struct packet_reg *r = &rs->regs[i];
+       if (r->in_g_packet)
+         {
+           supply_register (r->regnum, regs + r->offset);
+           if (buf[r->offset * 2] == 'x')
+             set_register_cached (i, -1);
+         }
+      }
+  }
 }
 
 /* Prepare to store registers.  Since we may send them all (using a
@@ -3428,41 +3525,46 @@ remote_prepare_to_store (void)
     {
     case PACKET_DISABLE:
     case PACKET_SUPPORT_UNKNOWN:
-      read_register_bytes (0, (char *) NULL, REGISTER_BYTES);
+      /* NOTE: This isn't rs->sizeof_g_packet because here, we are
+         forcing the register cache to read its and not the target
+         registers.  */
+      deprecated_read_register_bytes (0, (char *) NULL,
+                                     REGISTER_BYTES); /* OK use.  */
       break;
     case PACKET_ENABLE:
       break;
     }
 }
 
-/* Helper: Attempt to store REGNO using the P packet.  Return fail IFF
+/* Helper: Attempt to store REGNUM using the P packet.  Return fail IFF
    packet was not recognized. */
 
 static int
-store_register_using_P (int regno)
+store_register_using_P (int regnum)
 {
   struct remote_state *rs = get_remote_state ();
+  struct packet_reg *reg = packet_reg_from_regnum (rs, regnum);
   /* Try storing a single register.  */
   char *buf = alloca (rs->remote_packet_size);
   char *regp = alloca (MAX_REGISTER_RAW_SIZE);
   char *p;
   int i;
 
-  sprintf (buf, "P%x=", regno);
+  sprintf (buf, "P%s=", phex_nz (reg->pnum, 0));
   p = buf + strlen (buf);
-  regcache_collect (regno, regp);
-  bin2hex (regp, p, REGISTER_RAW_SIZE (regno));
-  remote_send (buf, (rs->remote_packet_size));
+  regcache_collect (reg->regnum, regp);
+  bin2hex (regp, p, REGISTER_RAW_SIZE (reg->regnum));
+  remote_send (buf, rs->remote_packet_size);
 
   return buf[0] != '\0';
 }
 
 
-/* Store register REGNO, or all registers if REGNO == -1, from the contents
+/* Store register REGNUM, or all registers if REGNUM == -1, from the contents
    of the register cache buffer.  FIXME: ignores errors.  */
 
 static void
-remote_store_registers (int regno)
+remote_store_registers (int regnum)
 {
   struct remote_state *rs = get_remote_state ();
   char *buf;
@@ -3472,19 +3574,19 @@ remote_store_registers (int regno)
 
   set_thread (PIDGET (inferior_ptid), 1);
 
-  if (regno >= 0)
+  if (regnum >= 0)
     {
       switch (remote_protocol_P.support)
        {
        case PACKET_DISABLE:
          break;
        case PACKET_ENABLE:
-         if (store_register_using_P (regno))
+         if (store_register_using_P (regnum))
            return;
          else
            error ("Protocol error: P packet not recognized by stub");
        case PACKET_SUPPORT_UNKNOWN:
-         if (store_register_using_P (regno))
+         if (store_register_using_P (regnum))
            {
              /* The stub recognized the 'P' packet.  Remember this.  */
              remote_protocol_P.support = PACKET_ENABLE;
@@ -3505,11 +3607,13 @@ remote_store_registers (int regno)
      local buffer.  */
   {
     int i;
-    regs = alloca (REGISTER_BYTES);
-    memset (regs, REGISTER_BYTES, 0);
-    for (i = 0; i < NUM_REGS; i++)
+    regs = alloca (rs->sizeof_g_packet);
+    memset (regs, rs->sizeof_g_packet, 0);
+    for (i = 0; i < NUM_REGS + NUM_PSEUDO_REGS; i++)
       {
-       regcache_collect (i, regs + REGISTER_BYTE (i));
+       struct packet_reg *r = &rs->regs[i];
+       if (r->in_g_packet)
+         regcache_collect (r->regnum, regs + r->offset);
       }
   }
 
@@ -3825,7 +3929,9 @@ remote_read_bytes (CORE_ADDR memaddr, char *myaddr, int len)
       putpkt (buf);
       getpkt (buf, sizeof_buf, 0);
 
-      if (buf[0] == 'E')
+      if (buf[0] == 'E'
+         && isxdigit (buf[1]) && isxdigit (buf[2])
+         && buf[3] == '\0')
        {
          /* There is no correspondance between what the remote protocol uses
             for errors and errno codes.  We would like a cleaner way of
@@ -3860,8 +3966,7 @@ remote_read_bytes (CORE_ADDR memaddr, char *myaddr, int len)
 /* ARGSUSED */
 static int
 remote_xfer_memory (CORE_ADDR mem_addr, char *buffer, int mem_len,
-                   int should_write,
-                   struct mem_attrib *attrib ATTRIBUTE_UNUSED,
+                   int should_write, struct mem_attrib *attrib,
                    struct target_ops *target)
 {
   CORE_ADDR targ_addr;
@@ -4598,7 +4703,7 @@ remote_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
 
   if (val == 0)
     {
-      if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+      if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
        val = target_write_memory (addr, (char *) big_break_insn,
                                   sizeof big_break_insn);
       else
@@ -4665,10 +4770,7 @@ watchpoint_to_Z_packet (int type)
     }
 }
 
-/* FIXME: This function should be static and a member of the remote
-   target vector. */
-
-int
+static int
 remote_insert_watchpoint (CORE_ADDR addr, int len, int type)
 {
   struct remote_state *rs = get_remote_state ();
@@ -4702,10 +4804,8 @@ remote_insert_watchpoint (CORE_ADDR addr, int len, int type)
                  "remote_insert_watchpoint: reached end of function");
 }
 
-/* FIXME: This function should be static and a member of the remote
-   target vector. */
 
-int
+static int
 remote_remove_watchpoint (CORE_ADDR addr, int len, int type)
 {
   struct remote_state *rs = get_remote_state ();
@@ -4738,16 +4838,64 @@ remote_remove_watchpoint (CORE_ADDR addr, int len, int type)
                  "remote_remove_watchpoint: reached end of function");
 }
 
-/* FIXME: This function should be static and a member of the remote
-   target vector. */
+
+int remote_hw_watchpoint_limit = -1;
+int remote_hw_breakpoint_limit = -1;
+
+int
+remote_check_watch_resources (int type, int cnt, int ot)
+{
+  if (type == bp_hardware_breakpoint)
+    {
+      if (remote_hw_breakpoint_limit == 0)
+       return 0;
+      else if (remote_hw_breakpoint_limit < 0)
+       return 1;
+      else if (cnt <= remote_hw_breakpoint_limit)
+       return 1;
+    }
+  else
+    {
+      if (remote_hw_watchpoint_limit == 0)
+       return 0;
+      else if (remote_hw_watchpoint_limit < 0)
+       return 1;
+      else if (ot)
+       return -1;
+      else if (cnt <= remote_hw_watchpoint_limit)
+       return 1;
+    }
+  return -1;
+}
 
 int
-remote_insert_hw_breakpoint (CORE_ADDR addr, int len)
+remote_stopped_by_watchpoint (void)
 {
+    return remote_stopped_by_watchpoint_p;
+}
+
+CORE_ADDR
+remote_stopped_data_address (void)
+{
+  if (remote_stopped_by_watchpoint ())
+    return remote_watch_data_address;
+  return (CORE_ADDR)0;
+}
+
+
+static int
+remote_insert_hw_breakpoint (CORE_ADDR addr, char *shadow)
+{
+  int len = 0;
   struct remote_state *rs = get_remote_state ();
   char *buf = alloca (rs->remote_packet_size);
   char *p = buf;
       
+  /* The length field should be set to the size of a breakpoint
+     instruction.  */
+
+  BREAKPOINT_FROM_PC (&addr, &len);  
+
   if (remote_protocol_Z[Z_PACKET_HARDWARE_BP].support == PACKET_DISABLE)
     error ("Can't set hardware breakpoint without the '%s' (%s) packet\n",
           remote_protocol_Z[Z_PACKET_HARDWARE_BP].name,
@@ -4773,19 +4921,23 @@ remote_insert_hw_breakpoint (CORE_ADDR addr, int len)
       return 0;
     }
   internal_error (__FILE__, __LINE__,
-                 "remote_remove_watchpoint: reached end of function");
+                 "remote_insert_hw_breakpoint: reached end of function");
 }
 
-/* FIXME: This function should be static and a member of the remote
-   target vector. */
 
-int 
-remote_remove_hw_breakpoint (CORE_ADDR addr, int len)
+static int 
+remote_remove_hw_breakpoint (CORE_ADDR addr, char *shadow)
 {
+  int len;
   struct remote_state *rs = get_remote_state ();
   char *buf = alloca (rs->remote_packet_size);
   char *p = buf;
-  
+
+  /* The length field should be set to the size of a breakpoint
+     instruction.  */
+
+  BREAKPOINT_FROM_PC (&addr, &len);
+
   if (remote_protocol_Z[Z_PACKET_HARDWARE_BP].support == PACKET_DISABLE)
     error ("Can't clear hardware breakpoint without the '%s' (%s) packet\n",
           remote_protocol_Z[Z_PACKET_HARDWARE_BP].name,
@@ -4811,7 +4963,7 @@ remote_remove_hw_breakpoint (CORE_ADDR addr, int len)
       return 0;
     }
   internal_error (__FILE__, __LINE__,
-                 "remote_remove_watchpoint: reached end of function");
+                 "remote_remove_hw_breakpoint: reached end of function");
 }
 
 /* Some targets are only capable of doing downloads, and afterwards
@@ -4831,18 +4983,6 @@ push_remote_target (char *name, int from_tty)
   remote_open (name, from_tty);
 }
 
-/* Other targets want to use the entire remote serial module but with
-   certain remote_ops overridden. */
-
-void
-open_remote_target (char *name, int from_tty, struct target_ops *target,
-                   int extended_p)
-{
-  printf_filtered ("Selecting the %sremote protocol\n",
-                  (extended_p ? "extended-" : ""));
-  remote_open_1 (name, from_tty, target, extended_p);
-}
-
 /* Table used by the crc32 function to calcuate the checksum. */
 
 static unsigned long crc32_table[256] =
@@ -4935,8 +5075,8 @@ compare_sections_command (char *args, int from_tty)
 
       getpkt (buf, (rs->remote_packet_size), 0);
       if (buf[0] == 'E')
-       error ("target memory fault, section %s, range 0x%08x -- 0x%08x",
-              sectname, lma, lma + size);
+       error ("target memory fault, section %s, range 0x%s -- 0x%s",
+              sectname, paddr (lma), paddr (lma + size));
       if (buf[0] != 'C')
        error ("remote target does not support this operation");
 
@@ -5288,6 +5428,13 @@ Specify the serial device it is connected to\n\
   remote_ops.to_files_info = remote_files_info;
   remote_ops.to_insert_breakpoint = remote_insert_breakpoint;
   remote_ops.to_remove_breakpoint = remote_remove_breakpoint;
+  remote_ops.to_stopped_by_watchpoint = remote_stopped_by_watchpoint;
+  remote_ops.to_stopped_data_address = remote_stopped_data_address;
+  remote_ops.to_can_use_hw_breakpoint = remote_check_watch_resources;
+  remote_ops.to_insert_hw_breakpoint = remote_insert_hw_breakpoint;
+  remote_ops.to_remove_hw_breakpoint = remote_remove_hw_breakpoint;
+  remote_ops.to_insert_watchpoint = remote_insert_watchpoint;
+  remote_ops.to_remove_watchpoint = remote_remove_watchpoint;
   remote_ops.to_kill = remote_kill;
   remote_ops.to_load = generic_load;
   remote_ops.to_mourn_inferior = remote_mourn;
@@ -5374,10 +5521,10 @@ remote_info_process (char *args, int from_tty)
 static void
 remote_cisco_open (char *name, int from_tty)
 {
+  int ex;
   if (name == 0)
-    error (
-           "To open a remote debug connection, you need to specify what \n\
-device is attached to the remote system (e.g. host:port).");
+    error ("To open a remote debug connection, you need to specify what \n"
+          "device is attached to the remote system (e.g. host:port).");
 
   /* See FIXME above */
   wait_forever_enabled_p = 1;
@@ -5386,7 +5533,7 @@ device is attached to the remote system (e.g. host:port).");
 
   unpush_target (&remote_cisco_ops);
 
-  remote_desc = serial_open (name);
+  remote_desc = remote_serial_open (name);
   if (!remote_desc)
     perror_with_name (name);
 
@@ -5437,14 +5584,18 @@ device is attached to the remote system (e.g. host:port).");
      someday have a notion of debugging several processes.  */
   inferior_ptid = pid_to_ptid (MAGIC_NULL_PID);
 
-  /* Start the remote connection; if error (0), discard this target. */
-
-  if (!catch_errors (remote_start_remote_dummy, (char *) 0,
-                    "Couldn't establish connection to remote target\n",
-                    RETURN_MASK_ALL))
+  /* Start the remote connection; if error, discard this target.  See
+     the comments in remote_open_1() for further details such as the
+     need to re-throw the exception.  */
+  ex = catch_exceptions (uiout,
+                        remote_start_remote_dummy, NULL,
+                        "Couldn't establish connection to remote"
+                        " target\n",
+                        RETURN_MASK_ALL);
+  if (ex < 0)
     {
       pop_target ();
-      return;
+      throw_exception (ex);
     }
 }
 
@@ -5640,7 +5791,7 @@ minitelnet (void)
              if (query ("Interrupt GDB? "))
                {
                  printf_filtered ("Interrupted by user.\n");
-                 return_to_top_level (RETURN_QUIT);
+                 throw_exception (RETURN_QUIT);
                }
              quit_count = 0;
            }
@@ -5699,7 +5850,14 @@ Specify the serial device it is connected to (e.g. host:2020).";
   remote_cisco_ops.to_xfer_memory = remote_xfer_memory;
   remote_cisco_ops.to_files_info = remote_files_info;
   remote_cisco_ops.to_insert_breakpoint = remote_insert_breakpoint;
-  remote_cisco_ops.to_remove_breakpoint = remote_remove_breakpoint;
+  remote_cisco_ops.to_remove_breakpoint = remote_remove_breakpoint;  
+  remote_cisco_ops.to_remove_hw_breakpoint = remote_remove_hw_breakpoint;
+  remote_cisco_ops.to_insert_hw_breakpoint = remote_insert_hw_breakpoint;
+  remote_cisco_ops.to_insert_watchpoint = remote_insert_watchpoint;
+  remote_cisco_ops.to_remove_watchpoint = remote_remove_watchpoint;
+  remote_cisco_ops.to_stopped_by_watchpoint = remote_stopped_by_watchpoint;
+  remote_cisco_ops.to_stopped_data_address = remote_stopped_data_address;
+  remote_cisco_ops.to_can_use_hw_breakpoint = remote_check_watch_resources;
   remote_cisco_ops.to_kill = remote_kill;
   remote_cisco_ops.to_load = generic_load;
   remote_cisco_ops.to_mourn_inferior = remote_cisco_mourn;
@@ -5789,6 +5947,13 @@ Specify the serial device it is connected to (e.g. /dev/ttya).";
   remote_async_ops.to_files_info = remote_files_info;
   remote_async_ops.to_insert_breakpoint = remote_insert_breakpoint;
   remote_async_ops.to_remove_breakpoint = remote_remove_breakpoint;
+  remote_async_ops.to_can_use_hw_breakpoint = remote_check_watch_resources;
+  remote_async_ops.to_insert_hw_breakpoint = remote_insert_hw_breakpoint;
+  remote_async_ops.to_remove_hw_breakpoint = remote_remove_hw_breakpoint;
+  remote_async_ops.to_insert_watchpoint = remote_insert_watchpoint;
+  remote_async_ops.to_remove_watchpoint = remote_remove_watchpoint;
+  remote_async_ops.to_stopped_by_watchpoint = remote_stopped_by_watchpoint;
+  remote_async_ops.to_stopped_data_address = remote_stopped_data_address;
   remote_async_ops.to_terminal_inferior = remote_async_terminal_inferior;
   remote_async_ops.to_terminal_ours = remote_async_terminal_ours;
   remote_async_ops.to_kill = remote_async_kill;
@@ -5842,13 +6007,14 @@ 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_qSymbol_packet_cmd (args, from_tty);
-  show_remote_protocol_binary_download_cmd (args, from_tty);
+  /* FIXME: cagney/2002-06-15: This function should iterate over
+     remote_show_cmdlist for a list of sub commands to show.  */
+  show_remote_protocol_Z_packet_cmd (args, from_tty, NULL);
+  show_remote_protocol_e_packet_cmd (args, from_tty, NULL);
+  show_remote_protocol_E_packet_cmd (args, from_tty, NULL);
+  show_remote_protocol_P_packet_cmd (args, from_tty, NULL);
+  show_remote_protocol_qSymbol_packet_cmd (args, from_tty, NULL);
+  show_remote_protocol_binary_download_cmd (args, from_tty, NULL);
 }
 
 static void
@@ -5943,11 +6109,11 @@ response packet.  GDB supplies the initial `$' character, and the\n\
 terminating `#' character and checksum.",
           &maintenancelist);
 
-  add_show_from_set
-    (add_set_boolean_cmd ("remotebreak", no_class, &remote_break,
-                         "Set whether to send break if interrupted.\n",
-                         &setlist),
-     &showlist);
+  add_setshow_boolean_cmd ("remotebreak", no_class, &remote_break,
+                          "Set whether to send break if interrupted.\n",
+                          "Show whether to send break if interrupted.\n",
+                          NULL, NULL,
+                          &setlist, &showlist);
 
   /* Install commands for configuring memory read/write packets. */
 
@@ -5982,6 +6148,19 @@ terminating `#' character and checksum.",
           "Show the maximum number of bytes per memory-read packet.\n",
           &remote_show_cmdlist);
 
+  add_setshow_cmd ("hardware-watchpoint-limit", no_class,
+                  var_zinteger, &remote_hw_watchpoint_limit, "\
+Set the maximum number of target hardware watchpoints.\n\
+Specify a negative limit for unlimited.", "\
+Show the maximum number of target hardware watchpoints.\n",
+                  NULL, NULL, &remote_set_cmdlist, &remote_show_cmdlist);
+  add_setshow_cmd ("hardware-breakpoint-limit", no_class,
+                  var_zinteger, &remote_hw_breakpoint_limit, "\
+Set the maximum number of target hardware breakpoints.\n\
+Specify a negative limit for unlimited.", "\
+Show the maximum number of target hardware breakpoints.\n",
+                  NULL, NULL, &remote_set_cmdlist, &remote_show_cmdlist);
+
   add_show_from_set
     (add_set_cmd ("remoteaddresssize", class_obscure,
                  var_integer, (char *) &remote_address_size,
@@ -6022,6 +6201,10 @@ in a memory packet.\n",
                         show_remote_protocol_e_packet_cmd,
                         &remote_set_cmdlist, &remote_show_cmdlist,
                         0);
+  /* Disable by default.  The ``e'' packet has nasty interactions with
+     the threading code - it relies on global state.  */
+  remote_protocol_e.detect = AUTO_BOOLEAN_FALSE;
+  update_packet_config (&remote_protocol_e);
 
   add_packet_config_cmd (&remote_protocol_E,
                         "E", "step-over-range-w-signal",
@@ -6029,6 +6212,10 @@ in a memory packet.\n",
                         show_remote_protocol_E_packet_cmd,
                         &remote_set_cmdlist, &remote_show_cmdlist,
                         0);
+  /* Disable by default.  The ``e'' packet has nasty interactions with
+     the threading code - it relies on global state.  */
+  remote_protocol_E.detect = AUTO_BOOLEAN_FALSE;
+  update_packet_config (&remote_protocol_E);
 
   add_packet_config_cmd (&remote_protocol_P,
                         "P", "set-register",
@@ -6073,12 +6260,11 @@ in a memory packet.\n",
                         0);
 
   /* Keep the old ``set remote Z-packet ...'' working. */
-  tmpcmd = add_set_auto_boolean_cmd ("Z-packet", class_obscure,
-                                    &remote_Z_packet_detect,
-                                    "\
-Set use of remote protocol `Z' packets", &remote_set_cmdlist);
-  tmpcmd->function.sfunc = set_remote_protocol_Z_packet_cmd;
-  add_cmd ("Z-packet", class_obscure, show_remote_protocol_Z_packet_cmd,
-          "Show use of remote protocol `Z' packets ",
-          &remote_show_cmdlist);
+  add_setshow_auto_boolean_cmd ("Z-packet", class_obscure,
+                               &remote_Z_packet_detect, "\
+Set use of remote protocol `Z' packets",
+                               "Show use of remote protocol `Z' packets ",
+                               set_remote_protocol_Z_packet_cmd,
+                               show_remote_protocol_Z_packet_cmd,
+                               &remote_set_cmdlist, &remote_show_cmdlist);
 }
This page took 0.044282 seconds and 4 git commands to generate.