* write.c (relax_segment <rs_space>): Calculate growth using
[deliverable/binutils-gdb.git] / gdb / remote.c
index c7ff58f03f34c1229be4aeeebb726d7ee3dc13ba..e2e9f7395388e05c2c2671974263ca20c32a0c87 100644 (file)
@@ -50,6 +50,8 @@
 #include <signal.h>
 #include "serial.h"
 
+#include "gdbcore.h" /* for exec_bfd */
+
 /* Prototypes for local functions */
 static void cleanup_sigint_signal_handler (void *dummy);
 static void initialize_sigint_signal_handler (void);
@@ -77,8 +79,9 @@ static void remote_prepare_to_store (void);
 
 static void remote_fetch_registers (int regno);
 
-static void remote_resume (int pid, int step, enum target_signal siggnal);
-static void remote_async_resume (int pid, int step,
+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);
 
@@ -112,8 +115,10 @@ static void remote_send (char *buf, long sizeof_buf);
 
 static int readchar (int timeout);
 
-static int remote_wait (int pid, struct target_waitstatus *status);
-static int remote_async_wait (int pid, struct target_waitstatus *status);
+static ptid_t remote_wait (ptid_t ptid,
+                                 struct target_waitstatus *status);
+static ptid_t remote_async_wait (ptid_t ptid,
+                                       struct target_waitstatus *status);
 
 static void remote_kill (void);
 static void remote_async_kill (void);
@@ -131,7 +136,7 @@ static void interrupt_query (void);
 
 static void set_thread (int, int);
 
-static int remote_thread_alive (int);
+static int remote_thread_alive (ptid_t);
 
 static void get_offsets (void);
 
@@ -175,15 +180,17 @@ static void packet_command (char *, int);
 
 static int stub_unpack_int (char *buff, int fieldlength);
 
-static int remote_current_thread (int oldpid);
+static ptid_t remote_current_thread (ptid_t oldptid);
 
 static void remote_find_new_threads (void);
 
 static void record_currthread (int currthread);
 
-/* exported functions */
+static int fromhex (int a);
+
+static int hex2bin (const char *hex, char *bin, int);
 
-extern int fromhex (int a);
+static int bin2hex (const char *bin, char *hex, int);
 
 static int putpkt_binary (char *buf, int cnt);
 
@@ -892,15 +899,16 @@ record_currthread (int currthread)
 
   /* 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))
+  if (!in_thread_list (pid_to_ptid (currthread)))
     {
-      add_thread (currthread);
+      add_thread (pid_to_ptid (currthread));
 #ifdef UI_OUT
       ui_out_text (uiout, "[New ");
-      ui_out_text (uiout, target_pid_to_str (currthread));
+      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 (currthread));
+      printf_filtered ("[New %s]\n",
+                       target_pid_to_str (pid_to_ptid (currthread)));
 #endif
     }
 }
@@ -938,8 +946,9 @@ set_thread (int th, int gen)
 /*  Return nonzero if the thread TH is still alive on the remote system.  */
 
 static int
-remote_thread_alive (int tid)
+remote_thread_alive (ptid_t ptid)
 {
+  int tid = PIDGET (ptid);
   char buf[16];
 
   if (tid < 0)
@@ -1613,25 +1622,26 @@ remote_threadlist_iterator (rmt_thread_action stepfunction, void *context,
 static int
 remote_newthread_step (threadref *ref, void *context)
 {
-  int pid;
+  ptid_t ptid;
 
-  pid = threadref_to_int (ref);
-  if (!in_thread_list (pid))
-    add_thread (pid);
+  ptid = pid_to_ptid (threadref_to_int (ref));
+
+  if (!in_thread_list (ptid))
+    add_thread (ptid);
   return 1;                    /* continue iterator */
 }
 
 #define CRAZY_MAX_THREADS 1000
 
-static int
-remote_current_thread (int oldpid)
+static ptid_t
+remote_current_thread (ptid_t oldpid)
 {
   char *buf = alloca (PBUFSIZ);
 
   putpkt ("qC");
   getpkt (buf, PBUFSIZ, 0);
   if (buf[0] == 'Q' && buf[1] == 'C')
-    return strtol (&buf[2], NULL, 16);
+    return pid_to_ptid (strtol (&buf[2], NULL, 16));
   else
     return oldpid;
 }
@@ -1645,8 +1655,8 @@ remote_find_new_threads (void)
 {
   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);
+  if (PIDGET (inferior_ptid) == MAGIC_NULL_PID)        /* ack ack ack */
+    inferior_ptid = remote_current_thread (inferior_ptid);
 }
 
 /*
@@ -1678,8 +1688,8 @@ remote_threads_info (void)
              do
                {
                  tid = strtol (bufp, &bufp, 16);
-                 if (tid != 0 && !in_thread_list (tid))
-                   add_thread (tid);
+                 if (tid != 0 && !in_thread_list (pid_to_ptid (tid)))
+                   add_thread (pid_to_ptid (tid));
                }
              while (*bufp++ == ',');   /* comma-separated list */
              putpkt ("qsThreadInfo");
@@ -1722,22 +1732,14 @@ remote_threads_extra_info (struct thread_info *tp)
 
   if (use_threadextra_query)
     {
-      sprintf (bufp, "qThreadExtraInfo,%x", tp->pid);
+      sprintf (bufp, "qThreadExtraInfo,%x", PIDGET (tp->ptid));
       putpkt (bufp);
       getpkt (bufp, PBUFSIZ, 0);
       if (bufp[0] != 0)
        {
-         char *p;
-
-         for (p = display_buf; 
-              p < display_buf + sizeof(display_buf) - 1 &&
-                bufp[0] != 0 &&
-                bufp[1] != 0;
-              p++, bufp+=2)
-           {
-             *p = fromhex (bufp[0]) * 16 + fromhex (bufp[1]);
-           }
-         *p = 0;
+         n = min (strlen (bufp) / 2, sizeof (display_buf));
+         result = hex2bin (bufp, display_buf, n);
+         display_buf [result] = '\0';
          return display_buf;
        }
     }
@@ -1746,7 +1748,7 @@ remote_threads_extra_info (struct thread_info *tp)
   use_threadextra_query = 0;
   set = TAG_THREADID | TAG_EXISTS | TAG_THREADNAME
     | TAG_MOREDISPLAY | TAG_DISPLAY;
-  int_to_threadref (&id, tp->pid);
+  int_to_threadref (&id, PIDGET (tp->ptid));
   if (remote_get_threadinfo (&id, set, &threadinfo))
     if (threadinfo.active)
       {
@@ -2017,7 +2019,7 @@ remote_start_remote (PTR dummy)
   /* Let the stub know that we want it to return the thread.  */
   set_thread (-1, 0);
 
-  inferior_pid = remote_current_thread (inferior_pid);
+  inferior_ptid = remote_current_thread (inferior_ptid);
 
   get_offsets ();              /* Get text, data & bss offsets */
 
@@ -2134,7 +2136,12 @@ serial device is attached to the remote system\n\
      be split out into seperate variables, especially since GDB will
      someday have a notion of debugging several processes.  */
 
-  inferior_pid = MAGIC_NULL_PID;
+  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).  */
@@ -2148,11 +2155,22 @@ serial device is attached to the remote system\n\
 
   if (extended_p)
     {
-      /* tell the remote that we're using the extended protocol.  */
+      /* Tell the remote that we are using the extended protocol.  */
       char *buf = alloca (PBUFSIZ);
       putpkt ("!");
       getpkt (buf, PBUFSIZ, 0);
     }
+#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));
+#endif
 }
 
 /* Just like remote_open but with asynchronous support. */
@@ -2212,7 +2230,7 @@ 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_pid = MAGIC_NULL_PID;
+  inferior_ptid = pid_to_ptid (MAGIC_NULL_PID);
 
   /* With this target we start out by owning the terminal. */
   remote_async_terminal_ours_p = 1;
@@ -2226,6 +2244,11 @@ serial device is attached to the remote system\n\
      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).  */
@@ -2242,11 +2265,22 @@ serial device is attached to the remote system\n\
 
   if (extended_p)
     {
-      /* tell the remote that we're using the extended protocol.  */
+      /* Tell the remote that we are using the extended protocol.  */
       char *buf = alloca (PBUFSIZ);
       putpkt ("!");
       getpkt (buf, PBUFSIZ, 0);
     }
+#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));
+#endif
 }
 
 /* This takes a program previously attached to and detaches it.  After
@@ -2296,7 +2330,7 @@ remote_async_detach (char *args, int from_tty)
 
 /* Convert hex digit A to a number.  */
 
-int
+static int
 fromhex (int a)
 {
   if (a >= '0' && a <= '9')
@@ -2309,6 +2343,25 @@ fromhex (int a)
     error ("Reply contains invalid hex digit %d", a);
 }
 
+static int
+hex2bin (const char *hex, char *bin, int count)
+{
+  int i;
+
+  for (i = 0; i < count; i++)
+    {
+      if (hex[0] == 0 || hex[1] == 0)
+       {
+         /* Hex string is short, or of uneven length.
+            Return the count that has been converted so far. */
+         return i;
+       }
+      *bin++ = fromhex (hex[0]) * 16 + fromhex (hex[1]);
+      hex += 2;
+    }
+  return i;
+}
+
 /* Convert number NIB to a hex digit.  */
 
 static int
@@ -2319,6 +2372,23 @@ tohex (int nib)
   else
     return 'a' + nib - 10;
 }
+
+static int
+bin2hex (const char *bin, char *hex, int count)
+{
+  int i;
+  /* May use a length, or a nul-terminated string as input. */
+  if (count == 0)
+    count = strlen (bin);
+
+  for (i = 0; i < count; i++)
+    {
+      *hex++ = tohex ((*bin >> 4) & 0xf);
+      *hex++ = tohex (*bin++ & 0xf);
+    }
+  *hex = 0;
+  return i;
+}
 \f
 /* Tell the remote machine to resume.  */
 
@@ -2327,9 +2397,10 @@ static enum target_signal last_sent_signal = TARGET_SIGNAL_0;
 static int last_sent_step;
 
 static void
-remote_resume (int pid, int step, enum target_signal siggnal)
+remote_resume (ptid_t ptid, int step, enum target_signal siggnal)
 {
   char *buf = alloca (PBUFSIZ);
+  int pid = PIDGET (ptid);
   char *p;
 
   if (pid == -1)
@@ -2376,7 +2447,7 @@ remote_resume (int pid, int step, enum target_signal siggnal)
              putpkt (buf);
              getpkt (buf, PBUFSIZ, 0);
 
-             if (packet_ok(buf, &remote_protocol_E) == PACKET_OK)
+             if (packet_ok (buf, &remote_protocol_E) == PACKET_OK)
                return;
            }
        }
@@ -2394,7 +2465,7 @@ remote_resume (int pid, int step, enum target_signal siggnal)
              putpkt (buf);
              getpkt (buf, PBUFSIZ, 0);
 
-             if (packet_ok(buf, &remote_protocol_e) == PACKET_OK)
+             if (packet_ok (buf, &remote_protocol_e) == PACKET_OK)
                return;
            }
        }
@@ -2415,9 +2486,10 @@ remote_resume (int pid, int step, enum target_signal siggnal)
 
 /* Same as remote_resume, but with async support. */
 static void
-remote_async_resume (int pid, int step, enum target_signal siggnal)
+remote_async_resume (ptid_t ptid, int step, enum target_signal siggnal)
 {
   char *buf = alloca (PBUFSIZ);
+  int pid = PIDGET (ptid);
   char *p;
 
   if (pid == -1)
@@ -2463,7 +2535,7 @@ remote_async_resume (int pid, int step, enum target_signal siggnal)
              putpkt (buf);
              getpkt (buf, PBUFSIZ, 0);
 
-             if (packet_ok(buf, &remote_protocol_E) == PACKET_OK)
+             if (packet_ok (buf, &remote_protocol_E) == PACKET_OK)
                goto register_event_loop;
            }
        }
@@ -2481,7 +2553,7 @@ remote_async_resume (int pid, int step, enum target_signal siggnal)
              putpkt (buf);
              getpkt (buf, PBUFSIZ, 0);
 
-             if (packet_ok(buf, &remote_protocol_e) == PACKET_OK)
+             if (packet_ok (buf, &remote_protocol_e) == PACKET_OK)
                goto register_event_loop;
            }
        }
@@ -2724,8 +2796,8 @@ remote_console_output (char *msg)
    Returns "pid", which in the case of a multi-threaded 
    remote OS, is the thread-id.  */
 
-static int
-remote_wait (int pid, struct target_waitstatus *status)
+static ptid_t
+remote_wait (ptid_t ptid, struct target_waitstatus *status)
 {
   unsigned char *buf = alloca (PBUFSIZ);
   int thread_num = -1;
@@ -2769,6 +2841,7 @@ remote_wait (int pid, struct target_waitstatus *status)
              {
                unsigned char *p1;
                char *p_temp;
+               int fieldsize;
 
                /* Read the register number */
                regno = strtol ((const char *) p, &p_temp, 16);
@@ -2802,13 +2875,10 @@ Packet: '%s'\n",
 Packet: '%s'\n",
                               regno, p, buf);
 
-                   for (i = 0; i < REGISTER_RAW_SIZE (regno); i++)
-                     {
-                       if (p[0] == 0 || p[1] == 0)
-                         warning ("Remote reply is too short: %s", buf);
-                       regs[i] = fromhex (p[0]) * 16 + fromhex (p[1]);
-                       p += 2;
-                     }
+                   fieldsize = hex2bin (p, regs, REGISTER_RAW_SIZE (regno));
+                   p += 2 * fieldsize;
+                   if (fieldsize < REGISTER_RAW_SIZE (regno))
+                     warning ("Remote reply is too short: %s", buf);
                    supply_register (regno, regs);
                  }
 
@@ -2933,14 +3003,14 @@ Packet Dropped");
 got_status:
   if (thread_num != -1)
     {
-      return thread_num;
+      return pid_to_ptid (thread_num);
     }
-  return inferior_pid;
+  return inferior_ptid;
 }
 
 /* Async version of remote_wait. */
-static int
-remote_async_wait (int pid, struct target_waitstatus *status)
+static ptid_t
+remote_async_wait (ptid_t ptid, struct target_waitstatus *status)
 {
   unsigned char *buf = alloca (PBUFSIZ);
   int thread_num = -1;
@@ -2990,6 +3060,7 @@ remote_async_wait (int pid, struct target_waitstatus *status)
              {
                unsigned char *p1;
                char *p_temp;
+               int fieldsize;
 
                /* Read the register number */
                regno = strtol ((const char *) p, &p_temp, 16);
@@ -3023,13 +3094,10 @@ Packet: '%s'\n",
 Packet: '%s'\n",
                               regno, p, buf);
 
-                   for (i = 0; i < REGISTER_RAW_SIZE (regno); i++)
-                     {
-                       if (p[0] == 0 || p[1] == 0)
-                         warning ("Remote reply is too short: %s", buf);
-                       regs[i] = fromhex (p[0]) * 16 + fromhex (p[1]);
-                       p += 2;
-                     }
+                   fieldsize = hex2bin (p, regs, REGISTER_RAW_SIZE (regno));
+                   p += 2 * fieldsize;
+                   if (fieldsize < REGISTER_RAW_SIZE (regno))
+                     warning ("Remote reply is too short: %s", buf);
                    supply_register (regno, regs);
                  }
 
@@ -3157,9 +3225,9 @@ Packet Dropped");
 got_status:
   if (thread_num != -1)
     {
-      return thread_num;
+      return pid_to_ptid (thread_num);
     }
-  return inferior_pid;
+  return inferior_ptid;
 }
 
 /* Number of bytes of registers this stub implements.  */
@@ -3178,7 +3246,7 @@ remote_fetch_registers (int regno)
   char *p;
   char *regs = alloca (REGISTER_BYTES);
 
-  set_thread (inferior_pid, 1);
+  set_thread (PIDGET (inferior_ptid), 1);
 
   sprintf (buf, "g");
   remote_send (buf, PBUFSIZ);
@@ -3279,12 +3347,7 @@ store_register_using_P (int regno)
   sprintf (buf, "P%x=", regno);
   p = buf + strlen (buf);
   regp = register_buffer (regno);
-  for (i = 0; i < REGISTER_RAW_SIZE (regno); ++i)
-    {
-      *p++ = tohex ((regp[i] >> 4) & 0xf);
-      *p++ = tohex (regp[i] & 0xf);
-    }
-  *p = '\0';
+  bin2hex (regp, p, REGISTER_RAW_SIZE (regno));
   remote_send (buf, PBUFSIZ);
 
   return buf[0] != '\0';
@@ -3302,7 +3365,7 @@ remote_store_registers (int regno)
   char *p;
   char *regs;
 
-  set_thread (inferior_pid, 1);
+  set_thread (PIDGET (inferior_ptid), 1);
 
   if (regno >= 0)
     {
@@ -3341,13 +3404,7 @@ remote_store_registers (int regno)
   regs = register_buffer (-1);
   p = buf + 1;
   /* remote_prepare_to_store insures that register_bytes_found gets set.  */
-  for (i = 0; i < register_bytes_found; i++)
-    {
-      *p++ = tohex ((regs[i] >> 4) & 0xf);
-      *p++ = tohex (regs[i] & 0xf);
-    }
-  *p = '\0';
-
+  bin2hex (regs, p, register_bytes_found);
   remote_send (buf, PBUFSIZ);
 }
 \f
@@ -3574,12 +3631,8 @@ remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len)
       /* Normal mode: Send target system values byte by byte, in
         increasing byte addresses.  Each byte is encoded as a two hex
         value.  */
-      for (nr_bytes = 0; nr_bytes < todo; nr_bytes++)
-       {
-         *p++ = tohex ((myaddr[nr_bytes] >> 4) & 0xf);
-         *p++ = tohex (myaddr[nr_bytes] & 0xf);
-       }
-      *p = '\0';
+      nr_bytes = bin2hex (myaddr, p, todo);
+      p += 2 * nr_bytes;
       break;
     case PACKET_SUPPORT_UNKNOWN:
       internal_error (__FILE__, __LINE__,
@@ -3670,14 +3723,11 @@ remote_read_bytes (CORE_ADDR memaddr, char *myaddr, int len)
          each byte encoded as two hex characters.  */
 
       p = buf;
-      for (i = 0; i < todo; i++)
+      if ((i = hex2bin (p, myaddr, todo)) < todo)
        {
-         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.  */
-           return i + (origlen - len);
-         myaddr[i] = fromhex (p[0]) * 16 + fromhex (p[1]);
-         p += 2;
+         /* Reply is short.  This means that we were able to read
+            only part of what we wanted to. */
+         return i + (origlen - len);
        }
       myaddr += todo;
       memaddr += todo;
@@ -4877,12 +4927,7 @@ remote_rcmd (char *command,
     error ("\"monitor\" command ``%s'' is too long\n", command);
 
   /* Encode the actual command */
-  for (i = 0; command[i]; i++)
-    {
-      *p++ = tohex ((command[i] >> 4) & 0xf);
-      *p++ = tohex (command[i] & 0xf);
-    }
-  *p = '\0';
+  bin2hex (command, p, 0);
 
   if (putpkt (buf) < 0)
     error ("Communication problem with target\n");
@@ -4976,7 +5021,7 @@ threadalive_test (char *cmd, int tty)
 {
   int sample_thread = SAMPLE_THREAD;
 
-  if (remote_thread_alive (sample_thread))
+  if (remote_thread_alive (pid_to_ptid (sample_thread)))
     printf_filtered ("PASS: Thread alive test\n");
   else
     printf_filtered ("FAIL: Thread alive test\n");
@@ -5083,6 +5128,18 @@ init_remote_threadtests (void)
 
 #endif /* 0 */
 
+/* Convert a thread ID to a string.  Returns the string in a static
+   buffer.  */
+
+static char *
+remote_pid_to_str (ptid_t ptid)
+{
+  static char buf[30];
+
+  sprintf (buf, "Thread %d", PIDGET (ptid));
+  return buf;
+}
+
 static void
 init_remote_ops (void)
 {
@@ -5110,6 +5167,7 @@ Specify the serial device it is connected to\n\
   remote_ops.to_thread_alive = remote_thread_alive;
   remote_ops.to_find_new_threads = remote_threads_info;
   remote_ops.to_extra_thread_info = remote_threads_extra_info;
+  remote_ops.to_pid_to_str = remote_pid_to_str;
   remote_ops.to_stop = remote_stop;
   remote_ops.to_query = remote_query;
   remote_ops.to_rcmd = remote_rcmd;
@@ -5249,7 +5307,7 @@ device is attached to the remote system (e.g. host:port).");
      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 = MAGIC_NULL_PID;
+  inferior_ptid = pid_to_ptid (MAGIC_NULL_PID);
 
   /* Start the remote connection; if error (0), discard this target. */
 
@@ -5481,15 +5539,15 @@ minitelnet (void)
     }
 }
 
-static int
-remote_cisco_wait (int pid, struct target_waitstatus *status)
+static ptid_t
+remote_cisco_wait (ptid_t ptid, struct target_waitstatus *status)
 {
   if (minitelnet () != ENTER_DEBUG)
     {
       error ("Debugging session terminated by protocol error");
     }
   putpkt ("?");
-  return remote_wait (pid, status);
+  return remote_wait (ptid, status);
 }
 
 static void
This page took 0.031878 seconds and 4 git commands to generate.