* amd64-sol2-tdep.c (amd64_sol2_gregset_reg_offset): Correct
[deliverable/binutils-gdb.git] / gdb / remote.c
index 3a9e2f6ff0a865e1459891529ecb27594cbc5367..3187ac00328b6f4e9fc5a36daa047fe45d5fe141 100644 (file)
@@ -359,7 +359,7 @@ free_private_thread_info (struct private_thread_info *info)
 static int
 remote_multi_process_p (struct remote_state *rs)
 {
-  return rs->extended && rs->multi_process_aware;
+  return rs->multi_process_aware;
 }
 
 /* This data could be associated with a target, but we do not always
@@ -742,7 +742,7 @@ static int wait_forever_enabled_p = 1;
 const char interrupt_sequence_control_c[] = "Ctrl-C";
 const char interrupt_sequence_break[] = "BREAK";
 const char interrupt_sequence_break_g[] = "BREAK-g";
-static const char *interrupt_sequence_modes[] =
+static const char *const interrupt_sequence_modes[] =
   {
     interrupt_sequence_control_c,
     interrupt_sequence_break,
@@ -1238,6 +1238,7 @@ enum {
   PACKET_vFile_pwrite,
   PACKET_vFile_close,
   PACKET_vFile_unlink,
+  PACKET_vFile_readlink,
   PACKET_qXfer_auxv,
   PACKET_qXfer_features,
   PACKET_qXfer_libraries,
@@ -1439,16 +1440,17 @@ remote_query_attached (int pid)
   return 0;
 }
 
-/* Add PID to GDB's inferior table.  Since we can be connected to a
-   remote system before before knowing about any inferior, mark the
-   target with execution when we find the first inferior.  If ATTACHED
-   is 1, then we had just attached to this inferior.  If it is 0, then
-   we just created this inferior.  If it is -1, then try querying the
-   remote stub to find out if it had attached to the inferior or
-   not.  */
+/* Add PID to GDB's inferior table.  If FAKE_PID_P is true, then PID
+   has been invented by GDB, instead of reported by the target.  Since
+   we can be connected to a remote system before before knowing about
+   any inferior, mark the target with execution when we find the first
+   inferior.  If ATTACHED is 1, then we had just attached to this
+   inferior.  If it is 0, then we just created this inferior.  If it
+   is -1, then try querying the remote stub to find out if it had
+   attached to the inferior or not.  */
 
 static struct inferior *
-remote_add_inferior (int pid, int attached)
+remote_add_inferior (int fake_pid_p, int pid, int attached)
 {
   struct inferior *inf;
 
@@ -1480,6 +1482,7 @@ remote_add_inferior (int pid, int attached)
     }
 
   inf->attach_flag = attached;
+  inf->fake_pid_p = fake_pid_p;
 
   return inf;
 }
@@ -1555,7 +1558,13 @@ remote_notice_new_inferior (ptid_t currthread, int running)
         may not know about it yet.  Add it before adding its child
         thread, so notifications are emitted in a sensible order.  */
       if (!in_inferior_list (ptid_get_pid (currthread)))
-       inf = remote_add_inferior (ptid_get_pid (currthread), -1);
+       {
+         struct remote_state *rs = get_remote_state ();
+         int fake_pid_p = !remote_multi_process_p (rs);
+
+         inf = remote_add_inferior (fake_pid_p,
+                                    ptid_get_pid (currthread), -1);
+       }
 
       /* This is really a new thread.  Add it.  */
       remote_add_thread (currthread, running);
@@ -1713,7 +1722,7 @@ set_general_process (void)
   struct remote_state *rs = get_remote_state ();
 
   /* If the remote can't handle multiple processes, don't bother.  */
-  if (!remote_multi_process_p (rs))
+  if (!rs->extended || !remote_multi_process_p (rs))
     return;
 
   /* We only need to change the remote current thread if it's pointing
@@ -3149,6 +3158,45 @@ send_interrupt_sequence (void)
                    interrupt_sequence_mode);
 }
 
+/* Query the remote target for which is the current thread/process,
+   add it to our tables, and update INFERIOR_PTID.  The caller is
+   responsible for setting the state such that the remote end is ready
+   to return the current thread.  */
+
+static void
+add_current_inferior_and_thread (void)
+{
+  struct remote_state *rs = get_remote_state ();
+  int fake_pid_p = 0;
+  ptid_t ptid;
+
+  inferior_ptid = null_ptid;
+
+  /* Now, if we have thread information, update inferior_ptid.  */
+  ptid = remote_current_thread (inferior_ptid);
+  if (!ptid_equal (ptid, null_ptid))
+    {
+      if (!remote_multi_process_p (rs))
+       fake_pid_p = 1;
+
+      inferior_ptid = ptid;
+    }
+  else
+    {
+      /* 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.  */
+      inferior_ptid = magic_null_ptid;
+      fake_pid_p = 1;
+    }
+
+  remote_add_inferior (fake_pid_p, ptid_get_pid (inferior_ptid), -1);
+
+  /* Add the main thread.  */
+  add_thread_silent (inferior_ptid);
+}
+
 static void
 remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
 {
@@ -3276,40 +3324,7 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
       /* Let the stub know that we want it to return the thread.  */
       set_continue_thread (minus_one_ptid);
 
-      inferior_ptid = minus_one_ptid;
-
-      /* Now, if we have thread information, update inferior_ptid.  */
-      ptid = remote_current_thread (inferior_ptid);
-      if (!ptid_equal (ptid, minus_one_ptid))
-       {
-         if (ptid_get_pid (ptid) == -1)
-           {
-             ptid = ptid_build (ptid_get_pid (magic_null_ptid),
-                                ptid_get_lwp (ptid),
-                                ptid_get_tid (ptid));
-             fake_pid_p = 1;
-           }
-
-         inferior_ptid = ptid;
-       }
-      else
-       {
-         /* 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 = magic_null_ptid;
-         fake_pid_p = 1;
-       }
-
-      inf = remote_add_inferior (ptid_get_pid (inferior_ptid), -1);
-      inf->fake_pid_p = fake_pid_p;
-
-      /* Always add the main thread.  */
-      add_thread_silent (inferior_ptid);
+      add_current_inferior_and_thread ();
 
       /* init_wait_for_inferior should be called before get_offsets in order
         to manage `inserted' flag in bp loc in a correct state.
@@ -3885,8 +3900,7 @@ remote_query_supported (void)
       char *q = NULL;
       struct cleanup *old_chain = make_cleanup (free_current_contents, &q);
 
-      if (rs->extended)
-       q = remote_query_supported_append (q, "multiprocess+");
+      q = remote_query_supported_append (q, "multiprocess+");
 
       if (remote_support_xml)
        q = remote_query_supported_append (q, remote_support_xml);
@@ -4300,7 +4314,7 @@ extended_remote_attach_1 (struct target_ops *target, char *args, int from_tty)
     error (_("Attaching to %s failed"),
           target_pid_to_str (pid_to_ptid (pid)));
 
-  set_current_inferior (remote_add_inferior (pid, 1));
+  set_current_inferior (remote_add_inferior (0, pid, 1));
 
   inferior_ptid = pid_to_ptid (pid);
 
@@ -7440,7 +7454,7 @@ extended_remote_kill (struct target_ops *ops)
   struct remote_state *rs = get_remote_state ();
 
   res = remote_vkill (pid, rs);
-  if (res == -1 && !remote_multi_process_p (rs))
+  if (res == -1 && !(rs->extended && remote_multi_process_p (rs)))
     {
       /* Don't try 'k' on a multi-process aware stub -- it has no way
         to specify the pid.  */
@@ -7674,14 +7688,7 @@ extended_remote_create_inferior_1 (char *exec_file, char *args,
       init_wait_for_inferior ();
     }
 
-  /* Now mark the inferior as running before we do anything else.  */
-  inferior_ptid = magic_null_ptid;
-
-  /* Now, if we have thread information, update inferior_ptid.  */
-  inferior_ptid = remote_current_thread (inferior_ptid);
-
-  remote_add_inferior (ptid_get_pid (inferior_ptid), 0);
-  add_thread_silent (inferior_ptid);
+  add_current_inferior_and_thread ();
 
   /* Get updated offsets, if the stub uses qOffsets.  */
   get_offsets ();
@@ -8583,8 +8590,17 @@ remote_rcmd (char *command,
       char *buf;
 
       /* XXX - see also remote_get_noisy_reply().  */
+      QUIT;                    /* Allow user to bail out with ^C.  */
       rs->buf[0] = '\0';
-      getpkt (&rs->buf, &rs->buf_size, 0);
+      if (getpkt_sane (&rs->buf, &rs->buf_size, 0) == -1)
+        { 
+          /* Timeout.  Continue to (try to) read responses.
+             This is better than stopping with an error, assuming the stub
+             is still executing the (long) monitor command.
+             If needed, the user can interrupt gdb using C-c, obtaining
+             an effect similar to stop on timeout.  */
+          continue;
+        }
       buf = rs->buf;
       if (buf[0] == '\0')
        error (_("Target does not support this command."));
@@ -8832,7 +8848,7 @@ remote_pid_to_str (struct target_ops *ops, ptid_t ptid)
     {
       if (ptid_equal (magic_null_ptid, ptid))
        xsnprintf (buf, sizeof buf, "Thread <main>");
-      else if (remote_multi_process_p (rs))
+      else if (rs->extended && remote_multi_process_p (rs))
        xsnprintf (buf, sizeof buf, "Thread %d.%ld",
                   ptid_get_pid (ptid), ptid_get_tid (ptid));
       else
@@ -9359,6 +9375,44 @@ remote_hostio_unlink (const char *filename, int *remote_errno)
                                     remote_errno, NULL, NULL);
 }
 
+/* Read value of symbolic link FILENAME on the remote target.  Return
+   a null-terminated string allocated via xmalloc, or NULL if an error
+   occurs (and set *REMOTE_ERRNO).  */
+
+static char *
+remote_hostio_readlink (const char *filename, int *remote_errno)
+{
+  struct remote_state *rs = get_remote_state ();
+  char *p = rs->buf;
+  char *attachment;
+  int left = get_remote_packet_size ();
+  int len, attachment_len;
+  int read_len;
+  char *ret;
+
+  remote_buffer_add_string (&p, &left, "vFile:readlink:");
+
+  remote_buffer_add_bytes (&p, &left, (const gdb_byte *) filename,
+                          strlen (filename));
+
+  len = remote_hostio_send_command (p - rs->buf, PACKET_vFile_readlink,
+                                   remote_errno, &attachment,
+                                   &attachment_len);
+
+  if (len < 0)
+    return NULL;
+
+  ret = xmalloc (len + 1);
+
+  read_len = remote_unescape_input (attachment, attachment_len,
+                                   ret, len);
+  if (read_len != len)
+    error (_("Readlink returned %d, but %d bytes."), len, read_len);
+
+  ret[len] = '\0';
+  return ret;
+}
+
 static int
 remote_fileio_errno_to_host (int errnum)
 {
@@ -9773,7 +9827,11 @@ remote_supports_multi_process (void)
 {
   struct remote_state *rs = get_remote_state ();
 
-  return remote_multi_process_p (rs);
+  /* Only extended-remote handles being attached to multiple
+     processes, even though plain remote can use the multi-process
+     thread id extensions, so that GDB knows the target process's
+     PID.  */
+  return rs->extended && remote_multi_process_p (rs);
 }
 
 int
@@ -10543,6 +10601,14 @@ remote_get_min_fast_tracepoint_insn_len (void)
   struct remote_state *rs = get_remote_state ();
   char *reply;
 
+  /* If we're not debugging a process yet, the IPA can't be
+     loaded.  */
+  if (!target_has_execution)
+    return 0;
+
+  /* Make sure the remote is pointing at the right process.  */
+  set_general_process ();
+
   sprintf (rs->buf, "qTMinFTPILen");
   putpkt (rs->buf);
   reply = remote_get_noisy_reply (&target_buf, &target_buf_size);
@@ -10671,6 +10737,12 @@ Specify the serial device it is connected to\n\
   remote_ops.to_supports_multi_process = remote_supports_multi_process;
   remote_ops.to_supports_disable_randomization
     = remote_supports_disable_randomization;
+  remote_ops.to_fileio_open = remote_hostio_open;
+  remote_ops.to_fileio_pwrite = remote_hostio_pwrite;
+  remote_ops.to_fileio_pread = remote_hostio_pread;
+  remote_ops.to_fileio_close = remote_hostio_close;
+  remote_ops.to_fileio_unlink = remote_hostio_unlink;
+  remote_ops.to_fileio_readlink = remote_hostio_readlink;
   remote_ops.to_supports_enable_disable_tracepoint = remote_supports_enable_disable_tracepoint;
   remote_ops.to_supports_string_tracing = remote_supports_string_tracing;
   remote_ops.to_trace_init = remote_trace_init;
@@ -11169,6 +11241,9 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
   add_packet_config_cmd (&remote_protocol_packets[PACKET_vFile_unlink],
                         "vFile:unlink", "hostio-unlink", 0);
 
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_vFile_readlink],
+                        "vFile:readlink", "hostio-readlink", 0);
+
   add_packet_config_cmd (&remote_protocol_packets[PACKET_vAttach],
                         "vAttach", "attach", 0);
 
This page took 0.028997 seconds and 4 git commands to generate.