1999-02-10 Jason Molenda (jsm@bugshack.cygnus.com)
[deliverable/binutils-gdb.git] / gdb / remote.c
index ab0f4707df5f243f513c1ed41c39c3f0b1267151..bcdc48f0288eba2a6f986deb6cfcc0d9b261eef1 100644 (file)
@@ -99,8 +99,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
                                        resume at same address.
 
        continue with   Csig;AA..AA     Continue with signal sig (hex signal
-       signal                          number).  If ;AA..AA is omitted, resume
-                                       at same address.
+       signal                          number).  If ;AA..AA is omitted, 
+                                       resume at same address.
 
        step with       Ssig;AA..AA     Like 'C' but step not continue.
        signal
@@ -135,9 +135,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
        or...           XAA             The process terminated with signal
                                        AA.
         or...           OXX..XX        XX..XX  is hex encoding of ASCII data. This
-                                       can happen at any time while the program is
-                                       running and the debugger should
-                                       continue to wait for 'W', 'T', etc.
+                                       can happen at any time while the 
+                                       program is running and the debugger 
+                                       should continue to wait for 
+                                       'W', 'T', etc.
 
        thread alive    TXX             Find out if the thread XX is alive.
        reply           OK              thread is still alive
@@ -209,7 +210,7 @@ static int remote_write_bytes PARAMS ((CORE_ADDR memaddr,
 static int remote_read_bytes PARAMS ((CORE_ADDR memaddr,
                                      char *myaddr, int len));
 
-static void remote_files_info PARAMS ((struct target_ops * ignore));
+static void remote_files_info PARAMS ((struct target_ops *ignore));
 
 static int remote_xfer_memory PARAMS ((CORE_ADDR memaddr, char * myaddr,
                                       int len, int should_write,
@@ -222,13 +223,14 @@ static void remote_fetch_registers PARAMS ((int regno));
 static void remote_resume PARAMS ((int pid, int step,
                                   enum target_signal siggnal));
 
-static int remote_start_remote PARAMS ((char *dummy));
+static int remote_start_remote PARAMS ((PTR));
 
 static void remote_open PARAMS ((char *name, int from_tty));
 
 static void extended_remote_open PARAMS ((char *name, int from_tty));
 
-static void remote_open_1 PARAMS ((char *, int, struct target_ops *, int extended_p));
+static void remote_open_1 PARAMS ((char *, int, struct target_ops *,
+                                  int extended_p));
 
 static void remote_close PARAMS ((int quitting));
 
@@ -280,6 +282,12 @@ static void init_extended_remote_ops PARAMS ((void));
 
 static void remote_stop PARAMS ((void));
 
+static int ishex PARAMS ((int ch, int *val));
+
+static int stubhex PARAMS ((int ch));
+
+static int remote_query PARAMS ((char, char *, char *, int *));
+
 static int hexnumstr PARAMS ((char *, ULONGEST));
 
 static CORE_ADDR remote_address_masked PARAMS ((CORE_ADDR));
@@ -292,6 +300,84 @@ static void compare_sections_command PARAMS ((char *, int));
 
 static void packet_command PARAMS ((char *, int));
 
+static int stub_unpack_int PARAMS ((char *buff, int fieldlength));
+
+char *unpack_varlen_hex PARAMS ((char *buff, int *result));
+
+static char *unpack_nibble PARAMS ((char *buf, int *val));
+
+static char *pack_nibble PARAMS ((char *buf, int nibble));
+
+static char *pack_hex_byte PARAMS ((char *pkt, unsigned char byte));
+
+static char *unpack_byte PARAMS ((char *buf, int *value));
+
+static char *pack_int PARAMS ((char *buf, int value));
+
+static char *unpack_int PARAMS ((char *buf, int *value));
+
+static char *unpack_string PARAMS ((char *src, char *dest, int length));
+
+static char *pack_threadid PARAMS ((char *pkt, threadref *id));
+
+static char *unpack_threadid PARAMS ((char *inbuf, threadref *id));
+
+void int_to_threadref PARAMS ((threadref *id, int value));
+
+static int threadref_to_int PARAMS ((threadref *ref));
+
+static void copy_threadref PARAMS ((threadref *dest, threadref *src));
+
+static int threadmatch PARAMS ((threadref *dest, threadref *src));
+
+static char *pack_threadinfo_request PARAMS ((char *pkt, int mode,
+                                             threadref *id));
+
+static int remote_unpack_thread_info_response PARAMS ((char *pkt,
+                                                      threadref *expectedref,
+                                                      struct gdb_ext_thread_info *info));
+
+
+static int remote_get_threadinfo PARAMS ((threadref *threadid,
+                                         int fieldset, /*TAG mask */
+                                         struct gdb_ext_thread_info *info));
+
+static int adapt_remote_get_threadinfo PARAMS ((gdb_threadref *ref,
+                                               int selection,
+                                               struct gdb_ext_thread_info *info));
+
+static char *pack_threadlist_request PARAMS ((char *pkt, int startflag,
+                                             int threadcount,
+                                             threadref *nextthread));
+
+static int parse_threadlist_response PARAMS ((char *pkt,
+                                             int result_limit,
+                                             threadref *original_echo,
+                                             threadref *resultlist,
+                                             int *doneflag));
+
+static int remote_get_threadlist PARAMS ((int startflag,
+                                         threadref *nextthread,
+                                         int result_limit,
+                                         int *done,
+                                         int *result_count,
+                                         threadref *threadlist));
+
+typedef int (*rmt_thread_action) (threadref *ref, void *context);
+
+static int remote_threadlist_iterator PARAMS ((rmt_thread_action stepfunction,
+                                              void *context, int looplimit));
+
+static int remote_newthread_step PARAMS ((threadref *ref, void *context));
+
+static int remote_current_thread PARAMS ((int oldpid));
+
+int remote_find_new_threads PARAMS ((void));
+
+static void record_currthread PARAMS ((int currthread));
+
+static void init_remote_threads PARAMS ((void));
+
 /* exported functions */
 
 extern int fromhex PARAMS ((int a));
@@ -314,6 +400,8 @@ static struct target_ops remote_ops;
 
 static struct target_ops extended_remote_ops;
 
+static struct target_thread_vector remote_thread_vec;
+
 /* This was 5 seconds, which is a long time to sit and wait.
    Unless this is going though some terminal server or multiplexer or
    other form of hairy serial connection, I would think 2 seconds would
@@ -399,158 +487,11 @@ void (*target_resume_hook) PARAMS ((void));
 void (*target_wait_loop_hook) PARAMS ((void));
 
 \f
-/* ------- REMOTE Thread (or) Process support ----------------------- */
-
-
-
-static int
-stub_unpack_int PARAMS ((char *buff, int fieldlength));
-
-char *
-  unpack_varlen_hex PARAMS ((char *buff, int *result));
-
-
-static char *
-  unpack_nibble PARAMS ((char *buf, int *val));
-
-static char *
-  unpack_nibble PARAMS ((char *buf, int *val));
-
-static char *
-  pack_hex_byte PARAMS ((char *pkt, unsigned char byte));
-
-static char *
-  unpack_byte PARAMS ((char *buf, int *value));
-
-static char *
-  pack_int PARAMS ((char *buf, int value));
-
-static char *
-  unpack_int PARAMS ((char *buf, int *value));
-
-static char *
-  pack_string PARAMS ((char *pkt, char *string));
-
-static char *
-  unpack_string PARAMS ((char *src, char *dest, int length));
-
-static char *
-  pack_threadid PARAMS ((char *pkt, threadref * id));
-
-static char *
-  unpack_threadid PARAMS ((char *inbuf, threadref * id));
-
-void
-int_to_threadref PARAMS ((threadref * id, int value));
-
-
-int
-threadref_to_int PARAMS ((threadref * ref));
-
-static void
-copy_threadref PARAMS ((threadref * dest, threadref * src));
-
-static int
-threadmatch PARAMS ((threadref * dest, threadref * src));
-
-
-static char *
-  pack_threadinfo_request PARAMS ((char *pkt,
-                                  int mode,
-                                  threadref * id));
-
-static int
-remote_unpack_thread_info_response PARAMS ((
-                                         char *pkt,
-                                         threadref * expectedref,
-                                       struct gdb_ext_thread_info * info));
-
-
-int
-remote_get_threadinfo PARAMS ((
-                               threadref * threadid,
-                               int fieldset,   /* TAG mask */
-                               struct gdb_ext_thread_info * info));
-
-int
-adapt_remote_get_threadinfo PARAMS ((
-                                     gdb_threadref * ref,
-                                     int selection,
-                                     struct gdb_ext_thread_info * info));
-static char *
-  pack_threadlist_request PARAMS ((
-                                   char *pkt,
-                                   int startflag,
-                                   int threadcount,
-                                   threadref * nextthread));
-
-static int
-parse_threadlist_response PARAMS ((
-                                   char *pkt,
-                                   int result_limit,
-                                   threadref * original_echo,
-                                   threadref * resultlist,
-                                   int *doneflag));
-static int
-remote_get_threadlist PARAMS ((
-                               int startflag,
-                               threadref * nextthread,
-                               int result_limit,
-                               int *done,
-                               int *result_count,
-                               threadref * threadlist));
-
-
-
-static int
-remote_newthread_step PARAMS ((
-                               threadref * ref,
-                               void *context));
-
-int
-remote_find_new_threads PARAMS ((void)) ;
-
-static void
-threadalive_test PARAMS ((char *cmd, int tty));
-
-
-static void
-threadset_test_cmd PARAMS ((char *cmd, int tty));
-
-static void
-threadlist_test_cmd PARAMS ((char *cmd,
-                            int tty));
-
-void
-display_thread_info PARAMS ((struct gdb_ext_thread_info * info));
-
-
-int
-get_and_display_threadinfo PARAMS ((threadref * ref));
-
-
-static void
-threadinfo_test_cmd PARAMS ((char *cmd,
-                            int tty));
-
-static int
-thread_display_step PARAMS ((
-                             threadref * ref,
-                             void *context));
-
-
-static void
-threadlist_update_test_cmd PARAMS ((char *cmd,
-                                   int tty));
-
-
-static void
-init_remote_threadtests PARAMS ((void));
 
-/* These are the threads which we last sent to the remote system.  -1 for all
-   or -2 for not sent yet.  */
-int general_thread;
-int cont_thread;
+/* These are the threads which we last sent to the remote system.
+   -1 for all or -2 for not sent yet.  */
+static int general_thread;
+static int cont_thread;
 
 /* Call this function as a result of
    1) A halt indication (T packet) containing a thread id
@@ -562,11 +503,22 @@ static void
 record_currthread (currthread)
      int currthread;
 {
+#if 0  /* target_wait must not modify inferior_pid! */
   inferior_pid = currthread;
+#endif
   general_thread = currthread;
+#if 0  /* setting cont_thread has a different meaning 
+          from having the target report its thread id.  */
   cont_thread = currthread;
+#endif
+  /* If this is a new thread, add it to GDB's thread list.
+     If we leave it up to WFI to do this, bad things will happen.  */
+  if (!in_thread_list (currthread))
+    add_thread (currthread);
 }
 
+#define MAGIC_NULL_PID 42000
+
 static void
 set_thread (th, gen)
      int th;
@@ -574,11 +526,13 @@ set_thread (th, gen)
 {
   char buf[PBUFSIZ];
   int state = gen ? general_thread : cont_thread;
+
   if (state == th)
     return;
+
   buf[0] = 'H';
   buf[1] = gen ? 'g' : 'c';
-  if (th == 42000)
+  if (th == MAGIC_NULL_PID)
     {
       buf[2] = '0';
       buf[3] = '\0';
@@ -613,25 +567,21 @@ remote_thread_alive (th)
   return (buf[0] == 'O' && buf[1] == 'K');
 }
 
-/*
-  About these extended threadlist and threadinfo packets.
-  They are variable length packets but, the fields within them
-    are often fixed length.
-  They are redundent enough to send over UDP as is the remote protocol
-   in general.
-  There is a matching unit test module in libstub.
- */
-
+/* About these extended threadlist and threadinfo packets.  They are
+   variable length packets but, the fields within them are often fixed
+   length.  They are redundent enough to send over UDP as is the
+   remote protocol in general.  There is a matching unit test module
+   in libstub.  */
 
 #define BUF_THREAD_ID_SIZE (OPAQUETHREADBYTES*2)
-/* encode 64 bits in 16 chars of hex */
 
+/* encode 64 bits in 16 chars of hex */
 
 static const char hexchars[] = "0123456789abcdef";
 
 static int
 ishex (ch, val)
-     char ch;
+     int ch;
      int *val;
 {
   if ((ch >= 'a') && (ch <= 'f'))
@@ -654,7 +604,7 @@ ishex (ch, val)
 
 static int
 stubhex (ch)
-     unsigned char ch;
+     int ch;
 {
   if (ch >= 'a' && ch <= 'f')
     return ch - 'a' + 10;
@@ -670,8 +620,9 @@ stub_unpack_int (buff, fieldlength)
      char *buff;
      int fieldlength;
 {
-  int retval = 0;
   int nibble;
+  int retval = 0;
+
   while (fieldlength)
     {
       nibble = stubhex (*buff++);
@@ -689,8 +640,7 @@ unpack_varlen_hex (buff, result)
      int *result;
 {
   int nibble;
-  int retval;
-  retval = 0;
+  int retval = 0;
 
   while (ishex (*buff, &nibble))
     {
@@ -706,7 +656,6 @@ static char *
 unpack_nibble (buf, val)
      char *buf;
      int *val;
-
 {
   ishex (*buf++, val);
   return buf;
@@ -716,7 +665,6 @@ static char *
 pack_nibble (buf, nibble)
      char *buf;
      int nibble;
-
 {
   *buf++ = hexchars[(nibble & 0x0f)];
   return buf;
@@ -741,7 +689,6 @@ unpack_byte (buf, value)
   return buf + 2;
 }
 
-
 static char *
 pack_int (buf, value)
      char *buf;
@@ -754,7 +701,6 @@ pack_int (buf, value)
   return buf;
 }
 
-
 static char *
 unpack_int (buf, value)
      char *buf;
@@ -764,6 +710,8 @@ unpack_int (buf, value)
   return buf + 8;
 }
 
+#if 0 /* currently unused, uncomment when needed */
+static char *pack_string PARAMS ((char *pkt, char *string));
 
 static char *
 pack_string (pkt, string)
@@ -772,6 +720,7 @@ pack_string (pkt, string)
 {
   char ch;
   int len;
+
   len = strlen (string);
   if (len > 200)
     len = 200;                 /* Bigger than most GDB packets, junk??? */
@@ -785,6 +734,7 @@ pack_string (pkt, string)
     }
   return pkt;
 }
+#endif /* 0 (unused) */
 
 static char *
 unpack_string (src, dest, length)
@@ -805,6 +755,7 @@ pack_threadid (pkt, id)
 {
   char *limit;
   unsigned char *altid;
+
   altid = (unsigned char *) id;
   limit = pkt + BUF_THREAD_ID_SIZE;
   while (pkt < limit)
@@ -821,6 +772,7 @@ unpack_threadid (inbuf, id)
   char *altref;
   char *limit = inbuf + BUF_THREAD_ID_SIZE;
   int x, y;
+
   altref = (char *) id;
 
   while (inbuf < limit)
@@ -833,10 +785,9 @@ unpack_threadid (inbuf, id)
 }
 
 /* Externally, threadrefs are 64 bits but internally, they are still
-   ints. This is due to a mismatch of specifications.
-   We would like to use 64bit thread references internally.
-   This is an adapter function.
- */
+   ints. This is due to a mismatch of specifications.  We would like
+   to use 64bit thread references internally.  This is an adapter
+   function.  */
 
 void
 int_to_threadref (id, value)
@@ -844,6 +795,7 @@ int_to_threadref (id, value)
      int value;
 {
   unsigned char *scan;
+
   scan = (unsigned char *) id;
   {
     int i = 4;
@@ -856,13 +808,12 @@ int_to_threadref (id, value)
   *scan++ = (value & 0xff);
 }
 
-int
+static int
 threadref_to_int (ref)
      threadref *ref;
 {
-  int value = 0;
+  int i, value = 0;
   unsigned char *scan;
-  int i;
 
   scan = (char *) ref;
   scan += 4;
@@ -879,6 +830,7 @@ copy_threadref (dest, src)
 {
   int i;
   unsigned char *csrc, *cdest;
+
   csrc = (unsigned char *) src;
   cdest = (unsigned char *) dest;
   i = 8;
@@ -886,8 +838,6 @@ copy_threadref (dest, src)
     *cdest++ = *csrc++;
 }
 
-
-
 static int
 threadmatch (dest, src)
      threadref *dest;
@@ -908,15 +858,6 @@ threadmatch (dest, src)
   return 1;
 }
 
-#if THREAD_PKT_TRACE
-#define PKT_TRACE(title,packet)  { printf_filtered("%s %s\n", title, packet);}
-#else
-#define PKT_TRACE(a,b) {}
-#endif
-
-
-/* ----- PACK_THREAD_INFO_REQUEST -------------------------------- */
-
 /*
   threadid:1,        # always request threadid
   context_exists:2,
@@ -927,38 +868,31 @@ threadmatch (dest, src)
 
 /* Encoding:  'Q':8,'P':8,mask:32,threadid:64 */
 
-static char *
-  pack_threadinfo_request PARAMS ((char *pkt,
-                                  int mode,
-                                  threadref * id));
-
 static char *
 pack_threadinfo_request (pkt, mode, id)
      char *pkt;
      int mode;
      threadref *id;
 {
-  char *base = pkt;
   *pkt++ = 'q';                        /* Info Query */
   *pkt++ = 'P';                        /* process or thread info */
   pkt = pack_int (pkt, mode);  /* mode */
   pkt = pack_threadid (pkt, id);       /* threadid */
   *pkt = '\0';                 /* terminate */
-  PKT_TRACE ("threadinfo-req ", base);
   return pkt;
 }
 
-
 /* These values tag the fields in a thread info response packet */
 /* Tagging the fields allows us to request specific fields and to
    add more fields as time goes by */
+
 #define TAG_THREADID 1      /* Echo the thread identifier */
-#define TAG_EXISTS 2        /* It this process defined enough to
+#define TAG_EXISTS 2        /* Is this process defined enough to
                               fetch registers and its stack */
 #define TAG_DISPLAY 4       /* A short thing maybe to put on a window */
 #define TAG_THREADNAME 8    /* string, maps 1-to-1 with a thread is */
-#define TAG_MOREDISPLAY 16  /* Whatever the kernel wants to say about the process*/
-
+#define TAG_MOREDISPLAY 16  /* Whatever the kernel wants to say about 
+                              the process*/
 
 static int
 remote_unpack_thread_info_response (pkt, expectedref, info)
@@ -972,8 +906,6 @@ remote_unpack_thread_info_response (pkt, expectedref, info)
   char *limit = pkt + PBUFSIZ;  /* plausable parsing limit */
   int retval = 1;
 
-  PKT_TRACE ("unpack-threadinfo ", pkt);
-
   /* info->threadid = 0; FIXME: implement zero_threadref */
   info->active = 0;
   info->display[0] = '\0';
@@ -985,17 +917,17 @@ remote_unpack_thread_info_response (pkt, expectedref, info)
   pkt = unpack_threadid (pkt, &ref);
 
   if (mask == 0)
-    warning("Incomplete response to threadinfo request\n");
+    warning ("Incomplete response to threadinfo request\n");
   if (!threadmatch (&ref, expectedref))
     {                          /* This is an answer to a different request */
-      warning("ERROR RMT Thread info mismatch\n");
+      warning ("ERROR RMT Thread info mismatch\n");
       return 0;
     }
   copy_threadref (&info->threadid, &ref);
 
   /* Loop on tagged fields , try to bail if somthing goes wrong */
 
-  while ((pkt < limit) && mask && *pkt)                /* packets are terminated with nulls */
+  while ((pkt < limit) && mask && *pkt)        /* packets are terminated with nulls */
     {
       pkt = unpack_int (pkt, &tag);    /* tag */
       pkt = unpack_byte (pkt, &length);                /* length */
@@ -1054,10 +986,7 @@ remote_unpack_thread_info_response (pkt, expectedref, info)
   return retval;
 }
 
-
-/* ------ REMOTE_GET_THREADINFO -------------------------------------- */
-
-int
+static int
 remote_get_threadinfo (threadid, fieldset, info)
      threadref *threadid;
      int fieldset;             /* TAG mask */
@@ -1065,31 +994,30 @@ remote_get_threadinfo (threadid, fieldset, info)
 {
   int result;
   char threadinfo_pkt[PBUFSIZ];
+
   pack_threadinfo_request (threadinfo_pkt, fieldset, threadid);
   putpkt (threadinfo_pkt);
   getpkt (threadinfo_pkt, 0);
-  result = remote_unpack_thread_info_response (threadinfo_pkt + 2, threadid, info);
+  result = remote_unpack_thread_info_response (threadinfo_pkt + 2, threadid,
+                                              info);
   return result;
 }
 
-/* ------- ADAPT_remote_GET_THREADINFO  - */
-/* Unfortunatly, 61 but thread-ids are bugger than the internal
+/* Unfortunately, 61 bit thread-ids are bigger than the internal
    representation of a threadid.  */
 
-
-int
+static int
 adapt_remote_get_threadinfo (ref, selection, info)
      gdb_threadref *ref;
      int selection;
      struct gdb_ext_thread_info *info;
 {
   threadref lclref;
+
   int_to_threadref (&lclref, *ref);
   return remote_get_threadinfo (&lclref, selection, info);
 }
 
-
-/* -------- PACK_THREADLIST-REQUEST --------------------------------- */
 /*    Format: i'Q':8,i"L":8,initflag:8,batchsize:16,lastthreadid:32   */
 
 static char *
@@ -1108,14 +1036,11 @@ pack_threadlist_request (pkt, startflag, threadcount, nextthread)
   return pkt;
 }
 
-
-/* ---------- PARSE_THREADLIST_RESPONSE ------------------------------------ */
 /* Encoding:   'q':8,'M':8,count:16,done:8,argthreadid:64,(threadid:64)* */
 
-
 static int
-parse_threadlist_response (pkt, result_limit, original_echo,
-                          resultlist, doneflag)
+parse_threadlist_response (pkt, result_limit, original_echo, resultlist,
+                          doneflag)
      char *pkt;
      int result_limit;
      threadref *original_echo;
@@ -1124,14 +1049,13 @@ parse_threadlist_response (pkt, result_limit, original_echo,
 {
   char *limit;
   int count, resultcount, done;
-  resultcount = 0;
 
-  /* assume the 'q' and 'M chars have been stripped */
-  PKT_TRACE ("parse-threadlist-response ", pkt);
+  resultcount = 0;
+  /* Assume the 'q' and 'M chars have been stripped.  */
   limit = pkt + (PBUFSIZ - BUF_THREAD_ID_SIZE);        /* done parse past here */
   pkt = unpack_byte (pkt, &count);     /* count field */
   pkt = unpack_nibble (pkt, &done);
-  /* The first threadid is the argument threadid */
+  /* The first threadid is the argument threadid */
   pkt = unpack_threadid (pkt, original_echo);  /* should match query packet */
   while ((count-- > 0) && (pkt < limit))
     {
@@ -1141,11 +1065,9 @@ parse_threadlist_response (pkt, result_limit, original_echo,
     }
   if (doneflag)
     *doneflag = done;
-  return resultcount;          /* successvalue */
+  return resultcount;
 }
 
-
-
 static int
 remote_get_threadlist (startflag, nextthread, result_limit,
                       done, result_count, threadlist)
@@ -1170,12 +1092,11 @@ remote_get_threadlist (startflag, nextthread, result_limit,
                           startflag, result_limit, nextthread);
   putpkt (threadlist_packet);
   getpkt (t_response, 0);
-  *result_count = parse_threadlist_response (
-                                             t_response + 2,   /* strip header */
-                                             result_limit,
-                                             &echo_nextthread,
-                                             threadlist,
-                                             done);
+
+  *result_count =
+    parse_threadlist_response (t_response + 2, result_limit, &echo_nextthread,
+                              threadlist, done);
+
   if (!threadmatch (&echo_nextthread, nextthread))
     {
       /* FIXME: This is a good reason to drop the packet */
@@ -1207,28 +1128,18 @@ remote_get_threadlist (startflag, nextthread, result_limit,
   return result;
 }
 
-
-
 /* This is the interface between remote and threads, remotes upper interface */
-/* remote_find_new_threads retreives the thread list and for each
+
+/* remote_find_new_threads retrieves the thread list and for each
    thread in the list, looks up the thread in GDB's internal list,
-   ading the thread if it does not already exist.
-   This involves getting partial thread lists from the remote target so,
-   polling the quit_flag is required.
-*/
+   ading the thread if it does not already exist.  This involves
+   getting partial thread lists from the remote target so, polling the
+   quit_flag is required.  */
 
-typedef int (*rmt_thread_action) (
-                                  threadref * ref,
-                                  void *context
-);
 
-#define MAXTHREADLISTRESULTS 32 /* About this many threadisds fit in a packet */
+/* About this many threadisds fit in a packet. */
 
-static int
-remote_threadlist_iterator PARAMS ((
-                                    rmt_thread_action stepfunction,
-                                    void *context,
-                                    int looplimit));
+#define MAXTHREADLISTRESULTS 32
 
 static int
 remote_threadlist_iterator (stepfunction, context, looplimit)
@@ -1241,7 +1152,6 @@ remote_threadlist_iterator (stepfunction, context, looplimit)
   int result = 1;
   int loopcount = 0;
   static threadref nextthread;
-  static threadref echo_nextthread;
   static threadref resultthreadlist[MAXTHREADLISTRESULTS];
 
   done = 0;
@@ -1253,222 +1163,77 @@ remote_threadlist_iterator (stepfunction, context, looplimit)
          warning ("Remote fetch threadlist -infinite loop-\n");
          break;
        }
-      if (!remote_get_threadlist (startflag,
-                                 &nextthread,
-                                 MAXTHREADLISTRESULTS,
-                                 &done,
-                                 &result_count,
-                                 resultthreadlist))
+      if (!remote_get_threadlist (startflag, &nextthread, MAXTHREADLISTRESULTS,
+                                 &done, &result_count, resultthreadlist))
        {
          result = 0;
          break;
        }
-      startflag = 0;           /* clear for later iterations */
-      /* Setup to resume next batch of thread references , set nestthread */
+      /* clear for later iterations */
+      startflag = 0;
+      /* Setup to resume next batch of thread references, set nextthread.  */
       if (result_count >= 1)
        copy_threadref (&nextthread, &resultthreadlist[result_count - 1]);
-      /* output_threadid("last-of-batch",&nextthread); */
       i = 0;
       while (result_count--)
        if (!(result = (*stepfunction) (&resultthreadlist[i++], context)))
-         break;
-    }
-  return result;
-}
-
-
-static int
-remote_newthread_step (ref, context)
-     threadref *ref;
-     void *context
-      ;
-
-{
-  int pid;
-  pid = threadref_to_int (ref);
-  if (!in_thread_list (pid))
-    add_thread (pid);
-  return 1;                    /* continue iterator */
-}
-
-#define CRAZY_MAX_THREADS 1000
-
-
-int
-remote_find_new_threads  (void)
-{
-  return remote_threadlist_iterator (remote_newthread_step, 0, CRAZY_MAX_THREADS);
-} /* remote_find_new_threads */
-
-int
-remote_update_threads ()
-{
-  /* Right now, this is empty. But it is one of the functions
-     defined for the thread target vector so it gets called.
-     If we were to allow the modification of the registers of
-     a suspended process, this would be implemented. */
-  return 0;
-}
-
-static struct target_thread_vector remote_thread_vec;
-
-/* Initialize the thread vector which is used by threads.c */
-/* The thread stubb is a package, it has an initializer */
-void init_remote_threads ()
-{
-  remote_thread_vec.find_new_threads = remote_find_new_threads;
-  remote_thread_vec.get_thread_info = adapt_remote_get_threadinfo;
-}
-
-/* --------- UNIT_TEST for THREAD oriented PACKETS -------------------------- */
-
-#define SAMPLE_THREAD  0x05060708  /* Truncated 64 bit threadid */
-
-
-static void
-threadset_test_cmd (cmd, tty)
-     char *cmd;
-     int tty;
-{
-  int sample_thread = SAMPLE_THREAD;
-  printf_filtered ("Remote threadset test\n");
-  set_thread (sample_thread, 1);
-}
-
-
-static void
-threadalive_test (cmd, tty)
-     char *cmd;
-     int tty;
-{
-  int sample_thread = SAMPLE_THREAD;
-  if (remote_thread_alive (sample_thread))
-    printf_filtered ("PASS: Thread alive test\n");
-  else
-    printf_filtered ("FAIL: Thread alive test\n");
-}
-
-void
-output_threadid PARAMS ((char *title, threadref * ref));
-
-void
-output_threadid (title, ref)
-     char *title;
-     threadref *ref;
-{
-  char hexid[20];
-  pack_threadid (&hexid[0], ref);      /* Convert threead id into hex */
-  hexid[16] = 0;
-  printf_filtered ("%s  %s\n", title, (&hexid[0]));
-}
-
-
-static void
-threadlist_test_cmd (cmd, tty)
-     char *cmd;
-     int tty;
-{
-  int startflag = 1;
-  threadref nextthread;
-  int done, result_count;
-  threadref threadlist[3];
-
-  printf_filtered ("Remote Threadlist test\n");
-  if (!remote_get_threadlist (startflag, &nextthread, 3, &done,
-                             &result_count, &threadlist[0]))
-    printf_filtered ("FAIL: threadlist test\n");
-  else
-    {
-      threadref *scan = threadlist;
-      threadref *limit = scan + result_count;
-      while (scan < limit)
-       output_threadid (" thread ", scan++);
-    }
-}
-
-void
-display_thread_info (info)
-     struct gdb_ext_thread_info *info;
-{
-
-  output_threadid ("Threadid: ", &info->threadid);
-  /* short name */
-  printf_filtered ("Name: %s\n ", info->shortname);
-  /* format display state */
-  printf_filtered ("State: %s\n", info->display);
-  /* additional data */
-  printf_filtered ("other: %s\n\n", info->more_display);
-}
-
-int
-get_and_display_threadinfo (ref)
-     threadref *ref;
-{
-  int result;
-  int set;
-  struct gdb_ext_thread_info threadinfo;
-
-  set = TAG_THREADID | TAG_EXISTS | TAG_THREADNAME
-    | TAG_MOREDISPLAY | TAG_DISPLAY;
-  if (0 != (result = remote_get_threadinfo (ref, set, &threadinfo)))
-    display_thread_info (&threadinfo);
+         break;
+    }
   return result;
 }
 
-static void
-threadinfo_test_cmd (cmd, tty)
-     char *cmd;
-     int tty;
+static int
+remote_newthread_step (ref, context)
+     threadref *ref;
+     void *context;
 {
-  int athread = SAMPLE_THREAD;
-  threadref thread;
-  int set;
+  int pid;
 
-  int_to_threadref (&thread, athread);
-  printf_filtered ("Remote Threadinfo test\n");
-  if (!get_and_display_threadinfo (&thread))
-    printf_filtered ("FAIL cannot get thread info\n");
+  pid = threadref_to_int (ref);
+  if (!in_thread_list (pid))
+    add_thread (pid);
+  return 1;                    /* continue iterator */
 }
 
+#define CRAZY_MAX_THREADS 1000
 
 static int
-thread_display_step (ref, context)
-     threadref *ref;
-     void *context;
+remote_current_thread (oldpid)
+     int oldpid;
 {
-  /* output_threadid(" threadstep ",ref); *//* simple test */
-  return get_and_display_threadinfo (ref);
-}
+  char buf[PBUFSIZ];
 
+  putpkt ("qC");
+  getpkt (buf, 0);
+  if (buf[0] == 'Q' && buf[1] == 'C')
+    return strtol (&buf[2], NULL, 16);
+  else
+    return oldpid;
+}
 
-static void
-threadlist_update_test_cmd (cmd, tty)
-     char *cmd;
-     int tty;
+int
+remote_find_new_threads ()
 {
-  printf_filtered ("Remote Threadlist update test\n");
-  remote_threadlist_iterator (thread_display_step, 0, CRAZY_MAX_THREADS);
+  int ret;
+
+  ret = remote_threadlist_iterator (remote_newthread_step, 0, 
+                                   CRAZY_MAX_THREADS);
+  if (inferior_pid == MAGIC_NULL_PID)  /* ack ack ack */
+    inferior_pid = remote_current_thread (inferior_pid);
+  return ret;
 }
 
+/* Initialize the thread vector which is used by threads.c */
+/* The thread stub is a package, it has an initializer */
+
 static void
-init_remote_threadtests (void)
+init_remote_threads ()
 {
-  add_com ("tlist", class_obscure, threadlist_test_cmd,
-     "Fetch and print the remote list of thread identifiers, one pkt only");
-  add_com ("tinfo", class_obscure, threadinfo_test_cmd,
-          "Fetch and display info about one thread");
-  add_com ("tset", class_obscure, threadset_test_cmd,
-          "Test setting to a different thread");
-  add_com ("tupd", class_obscure, threadlist_update_test_cmd,
-          "Iterate through updating all remote thread info");
-  add_com ("talive", class_obscure, threadalive_test,
-          " Remote thread alive test ");
+  remote_thread_vec.find_new_threads = remote_find_new_threads;
+  remote_thread_vec.get_thread_info = adapt_remote_get_threadinfo;
 }
 
-#define INIT_REMOTE_THREADTESTS { init_remote_threadtests();}
-/* END OF REMOTE THREAD UNIT TESTS */
 \f
-
 /*  Restart the remote side; this is an extended protocol operation.  */
 
 static void
@@ -1515,8 +1280,8 @@ get_offsets ()
   getpkt (buf, 0);
 
   if (buf[0] == '\000')
-    return;                    /* Return silently.  Stub doesn't support this
-                                  command. */
+    return;                    /* Return silently.  Stub doesn't support
+                                  this command. */
   if (buf[0] == 'E')
     {
       warning ("Remote failure reply: %s", buf);
@@ -1589,7 +1354,7 @@ get_offsets ()
 
 static int
 remote_start_remote (dummy)
-     char *dummy;
+     PTR dummy;
 {
   immediate_quit = 1;          /* Allow user to interrupt it */
 
@@ -1599,6 +1364,8 @@ remote_start_remote (dummy)
   /* Let the stub know that we want it to return the thread.  */
   set_thread (-1, 0);
 
+  inferior_pid = remote_current_thread (inferior_pid);
+
   get_offsets ();              /* Get text, data & bss offsets */
 
   putpkt ("?");                        /* initiate a query from remote machine */
@@ -1631,6 +1398,7 @@ extended_remote_open (name, from_tty)
 }
 
 /* Generic code for opening a connection to a remote target.  */
+
 static DCACHE *remote_dcache;
 
 static void
@@ -1641,8 +1409,8 @@ remote_open_1 (name, from_tty, target, extended_p)
      int extended_p;
 {
   if (name == 0)
-    error ("To open a remote debug connection, you need to specify what serial\n\
-device is attached to the remote system (e.g. /dev/ttya).");
+    error ("To open a remote debug connection, you need to specify what\n\
+serial device is attached to the remote system (e.g. /dev/ttya).");
 
   target_preopen (from_tty);
 
@@ -1677,33 +1445,37 @@ device is attached to the remote system (e.g. /dev/ttya).");
       puts_filtered ("\n");
     }
   push_target (target);        /* Switch to using remote target now */
+
   /* The target vector does not have the thread functions in it yet,
      so we use this function to call back into the thread module and
      register the thread vector and its contained functions. */
-  bind_target_thread_vector(&remote_thread_vec);
-  /* Start out by trying the 'P' request to set registers.  We set this each
-     time that we open a new target so that if the user switches from one
-     stub to another, we can (if the target is closed and reopened) cope.  */
+  bind_target_thread_vector (&remote_thread_vec);
+
+  /* Start out by trying the 'P' request to set registers.  We set
+     this each time that we open a new target so that if the user
+     switches from one stub to another, we can (if the target is
+     closed and reopened) cope.  */
   stub_supports_P = 1;
 
   general_thread = -2;
   cont_thread = -2;
 
-  /* 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.  */
+  /* Without this, some commands which require an active target (such
+     as kill) won't work.  This variable serves (at least) double duty
+     as both the pid of the target process (if it has such), and as a
+     flag indicating that a target is active.  These functions should
+     be split out into seperate variables, especially since GDB will
+     someday have a notion of debugging several processes.  */
 
-  inferior_pid = 42000;
+  inferior_pid = MAGIC_NULL_PID;
   /* 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, (char *)0, 
-                    "Couldn't establish connection to remote target\n", RETURN_MASK_ALL))
+  if (!catch_errors (remote_start_remote, NULL, 
+                    "Couldn't establish connection to remote target\n", 
+                    RETURN_MASK_ALL))
     {
-      pop_target();
+      pop_target ();
       return;
     }
 
@@ -1771,7 +1543,8 @@ tohex (nib)
 /* Tell the remote machine to resume.  */
 
 static enum target_signal last_sent_signal = TARGET_SIGNAL_0;
-int last_sent_step;
+
+static int last_sent_step;
 
 static void
 remote_resume (pid, step, siggnal)
@@ -1781,9 +1554,9 @@ remote_resume (pid, step, siggnal)
   char buf[PBUFSIZ];
 
   if (pid == -1)
-    set_thread (inferior_pid, 0);
+    set_thread (0, 0);         /* run any thread */
   else
-    set_thread (pid, 0);
+    set_thread (pid, 0);       /* run this thread */
 
   dcache_flush (remote_dcache);
 
@@ -1810,6 +1583,7 @@ remote_resume (pid, step, siggnal)
 \f
 /* Send ^C to target to halt it.  Target will respond, and send us a
    packet.  */
+
 static void (*ofunc) PARAMS ((int));
 
 static void
@@ -1863,6 +1637,7 @@ Give up (and stop debugging it)? "))
 }
 
 /* If nonzero, ignore the next kill.  */
+
 int kill_kludge;
 
 void
@@ -1884,10 +1659,9 @@ remote_console_output (msg)
     }
 }
 
-/* Wait until the remote machine stops, then return,
-   storing status in STATUS just as `wait' would.
-   Returns "pid" (though it's not clear what, if anything, that
-   means in the case of this target).  */
+/* Wait until the remote machine stops, then return, storing status in
+   STATUS just as `wait' would.  Returns "pid" (though it's not clear
+   what, if anything, that means in the case of this target).  */
 
 static int
 remote_wait (pid, status)
@@ -1938,7 +1712,8 @@ remote_wait (pid, status)
                unsigned char *p1;
                char *p_temp;
 
-               regno = strtol ((const char *) p, &p_temp, 16); /* Read the register number */
+               /* Read the register number */
+               regno = strtol ((const char *) p, &p_temp, 16);
                p1 = (unsigned char *)p_temp;
 
                if (p1 == p) /* No register number present here */
@@ -1950,9 +1725,9 @@ Packet: '%s'\n",
                               p, buf);
                    if (strncmp ((const char *) p, "thread", p1 - p) == 0)
                      {
-                       p_temp = unpack_varlen_hex(++p1,&thread_num);
-                       record_currthread(thread_num);
-                       p = (unsigned char *)p_temp;
+                       p_temp = unpack_varlen_hex (++p1, &thread_num);
+                       record_currthread (thread_num);
+                       p = (unsigned char *) p_temp;
                      }
                  }
                else
@@ -2038,10 +1813,11 @@ Packet: '%s'\n",
       /* Initial thread value can only be acquired via wait, so deal with
         this marker which is used before the first thread value is
         acquired.  */
-      if (inferior_pid == 42000)
+      if (inferior_pid == MAGIC_NULL_PID)
        {
          inferior_pid = thread_num;
-         add_thread (inferior_pid);
+         if (!in_thread_list (inferior_pid))
+           add_thread (inferior_pid);
        }
       return thread_num;
     }
@@ -2049,10 +1825,12 @@ Packet: '%s'\n",
 }
 
 /* Number of bytes of registers this stub implements.  */
+
 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.  */
+
 /* ARGSUSED */
 static void
 remote_fetch_registers (regno)
@@ -2195,9 +1973,8 @@ remote_store_registers (regno)
   remote_send (buf);
 }
 
-/* 
-   Use of the data cache *used* to be disabled because it loses for looking at
-   and changing hardware I/O ports and the like.  Accepting `volatile'
+/* Use of the data cache *used* to be disabled because it loses for looking
+   at and changing hardware I/O ports and the like.  Accepting `volatile'
    would perhaps be one way to fix it.  Another idea would be to use the
    executable file for the text segment (for all SEC_CODE sections?
    For all SEC_READONLY sections?).  This has problems if you want to
@@ -2205,8 +1982,7 @@ remote_store_registers (regno)
    clobbered memory, user downloaded the wrong thing).  
 
    Because it speeds so much up, it's now enabled, if you're playing
-   with registers you turn it of (set remotecache 0)
-*/
+   with registers you turn it of (set remotecache 0).  */
 
 /* Read a word from remote address ADDR and return it.
    This goes through the data cache.  */
@@ -2247,7 +2023,7 @@ hexnumlen (num)
   return max (i, 1);
 }
 
-/* Set BUF to the hex digits representing NUM */
+/* Set BUF to the hex digits representing NUM */
 
 static int
 hexnumstr (buf, num)
@@ -2268,7 +2044,7 @@ hexnumstr (buf, num)
   return len;
 }
 
-/* Mask all but the least significant REMOTE_ADDRESS_SIZE bits */
+/* Mask all but the least significant REMOTE_ADDRESS_SIZE bits. */
 
 static CORE_ADDR
 remote_address_masked (addr)
@@ -2333,8 +2109,8 @@ remote_write_bytes (memaddr, myaddr, len)
       *p++ = ':';
       *p = '\0';
 
-      /* We send target system values byte by byte, in increasing byte addresses,
-        each byte encoded as two hex characters.  */
+      /* We send target system values byte by byte, in increasing byte
+        addresses, each byte encoded as two hex characters.  */
 
       for (i = 0; i < todo; i++)
        {
@@ -2425,8 +2201,8 @@ remote_read_bytes (memaddr, myaddr, len)
       for (i = 0; i < todo; i++)
        {
          if (p[0] == 0 || p[1] == 0)
-           /* Reply is short.  This means that we were able to read only part
-              of what we wanted to.  */
+           /* Reply is short.  This means that we were able to read
+              only part of what we wanted to.  */
            return i + (origlen - len);
          myaddr[i] = fromhex (p[0]) * 16 + fromhex (p[1]);
          p += 2;
@@ -2438,13 +2214,14 @@ remote_read_bytes (memaddr, myaddr, len)
   return origlen;
 }
 \f
-/* Read or write LEN bytes from inferior memory at MEMADDR, transferring
-   to or from debugger address MYADDR.  Write to inferior if SHOULD_WRITE is
-   nonzero.  Returns length of data written or read; 0 for error.  */
+/* Read or write LEN bytes from inferior memory at MEMADDR,
+   transferring to or from debugger address MYADDR.  Write to inferior
+   if SHOULD_WRITE is nonzero.  Returns length of data written or
+   read; 0 for error.  */
 
 /* ARGSUSED */
 static int
-remote_xfer_memory(memaddr, myaddr, len, should_write, target)
+remote_xfer_memory (memaddr, myaddr, len, should_write, target)
      CORE_ADDR memaddr;
      char *myaddr;
      int len;
@@ -2461,7 +2238,8 @@ remote_xfer_memory(memaddr, myaddr, len, should_write, target)
   len = targlen;
 #endif
 
-  return dcache_xfer_memory (remote_dcache, memaddr, myaddr, len, should_write);
+  return dcache_xfer_memory (remote_dcache, memaddr, myaddr,
+                            len, should_write);
 }
 
    
@@ -2572,9 +2350,8 @@ readchar (timeout)
     }
 }
 
-/* Send the command in BUF to the remote machine,
-   and read the reply into BUF.
-   Report an error if we get an error reply.  */
+/* Send the command in BUF to the remote machine, and read the reply
+   into BUF.  Report an error if we get an error reply.  */
 
 static void
 remote_send (buf)
@@ -2601,8 +2378,10 @@ print_packet (buf)
 }
 
 
-/* Send a packet to the remote machine, with error checking.
-   The data of the packet is in BUF.  */
+/* Send a packet to the remote machine, with error checking.  The data
+   of the packet is in BUF.  The string in BUF can be at most  PBUFSIZ - 5
+   to account for the $, # and checksum, and for a possible /0 if we are
+   debugging (remote_debug) and want to print the sent packet as a string */
 
 int
 putpkt (buf)
@@ -2620,7 +2399,7 @@ putpkt (buf)
      and giving it a checksum.  */
 
   if (cnt > (int) sizeof (buf2) - 5)           /* Prosanity check */
-    abort();
+    abort ();
 
   p = buf2;
   *p++ = '$';
@@ -2644,7 +2423,7 @@ putpkt (buf)
        {
          *p = '\0';
          printf_unfiltered ("Sending packet: %s...", buf2);
-         gdb_flush(gdb_stdout);
+         gdb_flush (gdb_stdout);
        }
       if (SERIAL_WRITE (remote_desc, buf2, p - buf2))
        perror_with_name ("putpkt: write failed");
@@ -2673,7 +2452,7 @@ putpkt (buf)
            {
            case '+':
              if (remote_debug)
-               printf_unfiltered("Ack\n");
+               printf_unfiltered ("Ack\n");
              return 1;
            case SERIAL_TIMEOUT:
              tcount ++;
@@ -2684,8 +2463,8 @@ putpkt (buf)
              {
                char junkbuf[PBUFSIZ];
 
-             /* It's probably an old response, and we're out of sync.  Just
-                gobble up the packet and ignore it.  */
+             /* It's probably an old response, and we're out of sync.
+                Just gobble up the packet and ignore it.  */
                getpkt (junkbuf, 0);
                continue;               /* Now, go look for + */
              }
@@ -2706,10 +2485,10 @@ putpkt (buf)
 
 #if 0
       /* This is wrong.  If doing a long backtrace, the user should be
-        able to get out next time we call QUIT, without anything as violent
-        as interrupt_query.  If we want to provide a way out of here
-        without getting to the next QUIT, it should be based on hitting
-        ^C twice as in remote_wait.  */
+        able to get out next time we call QUIT, without anything as
+        violent as interrupt_query.  If we want to provide a way out of
+        here without getting to the next QUIT, it should be based on
+        hitting ^C twice as in remote_wait.  */
       if (quit_flag)
        {
          quit_flag = 0;
@@ -2719,9 +2498,9 @@ putpkt (buf)
     }
 }
 
-/* Come here after finding the start of the frame.  Collect the rest into BUF,
-   verifying the checksum, length, and handling run-length compression.
-   Returns 0 on any error, 1 on success.  */
+/* Come here after finding the start of the frame.  Collect the rest
+   into BUF, verifying the checksum, length, and handling run-length
+   compression.  Returns 0 on any error, 1 on success.  */
 
 static int
 read_frame (buf)
@@ -2807,12 +2586,10 @@ read_frame (buf)
     }
 }
 
-
-
-/* Read a packet from the remote machine, with error checking,
-   and store it in BUF.  BUF is expected to be of size PBUFSIZ.
-   If FOREVER, wait forever rather than timing out; this is used
-   while the target is executing user code.  */
+/* Read a packet from the remote machine, with error checking, and
+   store it in BUF.  BUF is expected to be of size PBUFSIZ.  If
+   FOREVER, wait forever rather than timing out; this is used while
+   the target is executing user code.  */
 
 void
 getpkt (buf, forever)
@@ -2907,7 +2684,7 @@ remote_kill ()
 
   /* Use catch_errors so the user can quit from gdb even when we aren't on
      speaking terms with the remote system.  */
-  catch_errors (putpkt, "k", "", RETURN_MASK_ERROR);
+  catch_errors ((catch_errors_ftype*) putpkt, "k", "", RETURN_MASK_ERROR);
 
   /* Don't wait for it to die.  I'm not really sure it matters whether
      we do or not.  For the existing stubs, kill is a noop.  */
@@ -3048,16 +2825,15 @@ remote_remove_breakpoint (addr, contents_cache)
 #endif /* REMOTE_BREAKPOINT */
 }
 
-/* Some targets are only capable of doing downloads, and afterwards they switch
-   to the remote serial protocol.  This function provides a clean way to get
-   from the download target to the remote target.  It's basically just a
-   wrapper so that we don't have to expose any of the internal workings of
-   remote.c.
+/* Some targets are only capable of doing downloads, and afterwards
+   they switch to the remote serial protocol.  This function provides
+   a clean way to get from the download target to the remote target.
+   It's basically just a wrapper so that we don't have to expose any
+   of the internal workings of remote.c.
 
-   Prior to calling this routine, you should shutdown the current target code,
-   else you will get the "A program is being debugged already..." message.
-   Usually a call to pop_target() suffices.
-*/
+   Prior to calling this routine, you should shutdown the current
+   target code, else you will get the "A program is being debugged
+   already..." message.  Usually a call to pop_target() suffices.  */
 
 void
 push_remote_target (name, from_tty)
@@ -3084,6 +2860,7 @@ open_remote_target (name, from_tty, target, extended_p)
 }
 
 /* Table used by the crc32 function to calcuate the checksum. */
+
 static unsigned long crc32_table[256] = {0, 0};
 
 static unsigned long
@@ -3190,11 +2967,82 @@ compare_sections_command (args, from_tty)
       do_cleanups (old_chain);
     }
   if (mismatched > 0)
-    warning ("One or more sections of the remote executable does not match\nthe loaded file\n");
+    warning ("One or more sections of the remote executable does not match\n\
+the loaded file\n");
   if (args && !matched)
     printf_filtered ("No loaded section named '%s'.\n", args);
 }
 
+static int
+remote_query (query_type, buf, outbuf, bufsiz)
+     char query_type;
+     char *buf;
+     char *outbuf;
+     int *bufsiz;
+{
+  int i;
+  char buf2[PBUFSIZ];
+  char *p2 = &buf2[0];
+  char *p = buf;
+
+  if (! bufsiz)
+    error ("null pointer to remote bufer size specified");
+
+  /* minimum outbuf size is PBUFSIZE - if bufsiz is not large enough let 
+     the caller know and return what the minimum size is   */
+  /* Note: a zero bufsiz can be used to query the minimum buffer size */
+  if ( *bufsiz < PBUFSIZ )
+    {
+      *bufsiz = PBUFSIZ;
+      return -1;
+    }
+
+  /* except for querying the minimum buffer size, target must be open */
+  if (! remote_desc)
+    error ("remote query is only available after target open");
+
+  /* we only take uppercase letters as query types, at least for now */
+  if ( (query_type < 'A') || (query_type > 'Z') )
+    error ("invalid remote query type");
+
+  if (! buf)
+    error ("null remote query specified");
+
+  if (! outbuf)
+    error ("remote query requires a buffer to receive data");
+
+  outbuf[0] = '\0';
+
+  *p2++ = 'q';
+  *p2++ = query_type;
+
+  /* we used one buffer char for the remote protocol q command and another
+     for the query type.  As the remote protocol encapsulation uses 4 chars
+     plus one extra in case we are debugging (remote_debug),
+     we have PBUFZIZ - 7 left to pack the query string */
+  i = 0;
+  while ( buf[i] && (i < (PBUFSIZ - 8)) )
+    {
+      /* bad caller may have sent forbidden characters */
+      if ( (!isprint(buf[i])) || (buf[i] == '$') || (buf[i] == '#') )
+        error ("illegal characters in query string");
+
+      *p2++ = buf[i];
+      i++;
+    }
+  *p2 = buf[i];
+
+  if ( buf[i] )
+    error ("query larger than available buffer");
+
+  i = putpkt (buf2);
+  if ( i < 0 ) return i;
+
+  getpkt (outbuf, 0);
+
+  return 0;
+}
+
 static void
 packet_command (args, from_tty)
      char *args;
@@ -3219,12 +3067,174 @@ packet_command (args, from_tty)
   puts_filtered ("\n");
 }
 
+#if 0
+/* --------- UNIT_TEST for THREAD oriented PACKETS ------------------------- */
+
+static void display_thread_info PARAMS ((struct gdb_ext_thread_info *info));
+
+static void threadset_test_cmd PARAMS ((char *cmd, int tty));
+
+static void threadalive_test PARAMS ((char *cmd, int tty));
+
+static void threadlist_test_cmd PARAMS ((char *cmd, int tty));
+
+int get_and_display_threadinfo PARAMS ((threadref *ref));
+
+static void threadinfo_test_cmd PARAMS ((char *cmd, int tty));
+
+static int thread_display_step PARAMS ((threadref *ref, void *context));
+
+static void threadlist_update_test_cmd PARAMS ((char *cmd, int tty));
+
+static void init_remote_threadtests PARAMS ((void));
+
+#define SAMPLE_THREAD  0x05060708  /* Truncated 64 bit threadid */
+
+static void
+threadset_test_cmd (cmd, tty)
+     char *cmd;
+     int tty;
+{
+  int sample_thread = SAMPLE_THREAD;
+
+  printf_filtered ("Remote threadset test\n");
+  set_thread (sample_thread, 1);
+}
+
+
+static void
+threadalive_test (cmd, tty)
+     char *cmd;
+     int tty;
+{
+  int sample_thread = SAMPLE_THREAD;
+
+  if (remote_thread_alive (sample_thread))
+    printf_filtered ("PASS: Thread alive test\n");
+  else
+    printf_filtered ("FAIL: Thread alive test\n");
+}
+
+void output_threadid PARAMS ((char *title, threadref * ref));
+
+void
+output_threadid (title, ref)
+     char *title;
+     threadref *ref;
+{
+  char hexid[20];
+
+  pack_threadid (&hexid[0], ref);      /* Convert threead id into hex */
+  hexid[16] = 0;
+  printf_filtered ("%s  %s\n", title, (&hexid[0]));
+}
+
+static void
+threadlist_test_cmd (cmd, tty)
+     char *cmd;
+     int tty;
+{
+  int startflag = 1;
+  threadref nextthread;
+  int done, result_count;
+  threadref threadlist[3];
+
+  printf_filtered ("Remote Threadlist test\n");
+  if (!remote_get_threadlist (startflag, &nextthread, 3, &done,
+                             &result_count, &threadlist[0]))
+    printf_filtered ("FAIL: threadlist test\n");
+  else
+    {
+      threadref *scan = threadlist;
+      threadref *limit = scan + result_count;
+
+      while (scan < limit)
+       output_threadid (" thread ", scan++);
+    }
+}
+
+void
+display_thread_info (info)
+     struct gdb_ext_thread_info *info;
+{
+  output_threadid ("Threadid: ", &info->threadid);
+  printf_filtered ("Name: %s\n ", info->shortname);
+  printf_filtered ("State: %s\n", info->display);
+  printf_filtered ("other: %s\n\n", info->more_display);
+}
+
+int
+get_and_display_threadinfo (ref)
+     threadref *ref;
+{
+  int result;
+  int set;
+  struct gdb_ext_thread_info threadinfo;
+
+  set = TAG_THREADID | TAG_EXISTS | TAG_THREADNAME
+    | TAG_MOREDISPLAY | TAG_DISPLAY;
+  if (0 != (result = remote_get_threadinfo (ref, set, &threadinfo)))
+    display_thread_info (&threadinfo);
+  return result;
+}
+
+static void
+threadinfo_test_cmd (cmd, tty)
+     char *cmd;
+     int tty;
+{
+  int athread = SAMPLE_THREAD;
+  threadref thread;
+  int set;
+
+  int_to_threadref (&thread, athread);
+  printf_filtered ("Remote Threadinfo test\n");
+  if (!get_and_display_threadinfo (&thread))
+    printf_filtered ("FAIL cannot get thread info\n");
+}
+
+static int
+thread_display_step (ref, context)
+     threadref *ref;
+     void *context;
+{
+  /* output_threadid(" threadstep ",ref); *//* simple test */
+  return get_and_display_threadinfo (ref);
+}
+
+static void
+threadlist_update_test_cmd (cmd, tty)
+     char *cmd;
+     int tty;
+{
+  printf_filtered ("Remote Threadlist update test\n");
+  remote_threadlist_iterator (thread_display_step, 0, CRAZY_MAX_THREADS);
+}
+
+static void
+init_remote_threadtests (void)
+{
+  add_com ("tlist", class_obscure, threadlist_test_cmd,
+     "Fetch and print the remote list of thread identifiers, one pkt only");
+  add_com ("tinfo", class_obscure, threadinfo_test_cmd,
+          "Fetch and display info about one thread");
+  add_com ("tset", class_obscure, threadset_test_cmd,
+          "Test setting to a different thread");
+  add_com ("tupd", class_obscure, threadlist_update_test_cmd,
+          "Iterate through updating all remote thread info");
+  add_com ("talive", class_obscure, threadalive_test,
+          " Remote thread alive test ");
+}
+
+#endif /* 0 */
+
 static void
 init_remote_ops ()
 {
   remote_ops.to_shortname = "remote";          
   remote_ops.to_longname = "Remote serial target in gdb-specific protocol";
-  remote_ops.to_doc = "Use a remote computer via a serial line, using a gdb-specific protocol.\n\
+  remote_ops.to_doc = 
+    "Use a remote computer via a serial line, using a gdb-specific protocol.\n\
 Specify the serial device it is connected to (e.g. /dev/ttya).";  
   remote_ops.to_open = remote_open;            
   remote_ops.to_close = remote_close;          
@@ -3243,23 +3253,30 @@ Specify the serial device it is connected to (e.g. /dev/ttya).";
   remote_ops.to_mourn_inferior = remote_mourn;
   remote_ops.to_thread_alive = remote_thread_alive;
   remote_ops.to_stop = remote_stop;
+  remote_ops.to_query = remote_query;
   remote_ops.to_stratum = process_stratum;
   remote_ops.to_has_all_memory = 1;    
   remote_ops.to_has_memory = 1;        
   remote_ops.to_has_stack = 1; 
   remote_ops.to_has_registers = 1;     
   remote_ops.to_has_execution = 1;     
+  remote_ops.to_has_thread_control = tc_schedlock; /* can lock scheduler */
   remote_ops.to_magic = OPS_MAGIC;     
 }
 
+/* Set up the extended remote vector by making a copy of the standard
+   remote vector and adding to it.  */
+
 static void
 init_extended_remote_ops ()
 {
   extended_remote_ops = remote_ops;
 
   extended_remote_ops.to_shortname = "extended-remote";        
-  extended_remote_ops.to_longname = "Extended remote serial target in gdb-specific protocol";
-  extended_remote_ops.to_doc = "Use a remote computer via a serial line, using a gdb-specific protocol.\n\
+  extended_remote_ops.to_longname = 
+    "Extended remote serial target in gdb-specific protocol";
+  extended_remote_ops.to_doc = 
+    "Use a remote computer via a serial line, using a gdb-specific protocol.\n\
 Specify the serial device it is connected to (e.g. /dev/ttya).",
   extended_remote_ops.to_open = extended_remote_open;  
   extended_remote_ops.to_create_inferior = extended_remote_create_inferior;
@@ -3274,8 +3291,10 @@ _initialize_remote ()
 
   init_extended_remote_ops ();
   add_target (&extended_remote_ops);
-  init_remote_threads();
-  INIT_REMOTE_THREADTESTS   /* conditional thread packet unit test */
+  init_remote_threads ();
+#if 0
+  init_remote_threadtests ();
+#endif
 
   add_cmd ("compare-sections", class_obscure, compare_sections_command, 
           "Compare section data on target to the exec file.\n\
@@ -3291,31 +3310,33 @@ response packet.  GDB supplies the initial `$' character, and the\n\
 terminating `#' character and checksum.",
           &maintenancelist);
 
-  add_show_from_set (add_set_cmd ("remotetimeout", no_class,
-                                 var_integer, (char *)&remote_timeout,
-                                 "Set timeout value for remote read.\n",
-                                 &setlist),
-                    &showlist);
-
-  add_show_from_set (add_set_cmd ("remotebreak", no_class,
-                                 var_integer, (char *)&remote_break,
-                                 "Set whether to send break if interrupted.\n",
-                                 &setlist),
-                    &showlist);
-
-  add_show_from_set (add_set_cmd ("remotewritesize", no_class,
-                                 var_integer, (char *)&remote_write_size,
-                                 "Set the maximum number of bytes in each memory write packet.\n",
-                                 &setlist),
-                    &showlist);
-
-   
+  add_show_from_set 
+    (add_set_cmd ("remotetimeout", no_class,
+                 var_integer, (char *)&remote_timeout,
+                 "Set timeout value for remote read.\n",
+                 &setlist),
+     &showlist);
+
+  add_show_from_set 
+    (add_set_cmd ("remotebreak", no_class,
+                 var_integer, (char *)&remote_break,
+                 "Set whether to send break if interrupted.\n",
+                 &setlist),
+     &showlist);
+
+  add_show_from_set 
+    (add_set_cmd ("remotewritesize", no_class,
+                 var_integer, (char *)&remote_write_size,
+                 "Set the maximum number of bytes per memory write packet.\n",
+                 &setlist),
+     &showlist);
 
   remote_address_size = TARGET_PTR_BIT;
-  add_show_from_set (add_set_cmd ("remoteaddresssize", class_obscure,
-                                 var_integer, (char *)&remote_address_size,
-                                 "Set the maximum size of the address (in bits) in a memory packet.\n",
-                                 &setlist),
-                    &showlist);  
+  add_show_from_set 
+    (add_set_cmd ("remoteaddresssize", class_obscure,
+                 var_integer, (char *)&remote_address_size,
+                 "Set the maximum size of the address (in bits) \
+in a memory packet.\n",
+                 &setlist),
+     &showlist);  
 }
-
This page took 0.04562 seconds and 4 git commands to generate.