2011-04-21 Tristan Gingold <gingold@adacore.com>
[deliverable/binutils-gdb.git] / gdb / remote.c
index da04932c9e3a80a33b885a9c0282dc3d581753f8..fdb45734369aa7f3fd7dbe31a9e569e9a08bcc22 100644 (file)
@@ -455,7 +455,7 @@ remote_get_noisy_reply (char **buf_p,
          from = ul;
 
          p = pp + 1;
-         pp = unpack_varlen_hex (p, &ul);
+         unpack_varlen_hex (p, &ul);
          to = ul;
 
          org_to = to;
@@ -535,24 +535,15 @@ compare_pnums (const void *lhs_, const void *rhs_)
     return 1;
 }
 
-static void *
-init_remote_state (struct gdbarch *gdbarch)
+static int
+map_regcache_remote_table (struct gdbarch *gdbarch, struct packet_reg *regs)
 {
   int regnum, num_remote_regs, offset;
-  struct remote_state *rs = get_remote_state_raw ();
-  struct remote_arch_state *rsa;
   struct packet_reg **remote_regs;
 
-  rsa = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct remote_arch_state);
-
-  /* Use the architecture to build a regnum<->pnum table, which will be
-     1:1 unless a feature set specifies otherwise.  */
-  rsa->regs = GDBARCH_OBSTACK_CALLOC (gdbarch,
-                                     gdbarch_num_regs (gdbarch),
-                                     struct packet_reg);
   for (regnum = 0; regnum < gdbarch_num_regs (gdbarch); regnum++)
     {
-      struct packet_reg *r = &rsa->regs[regnum];
+      struct packet_reg *r = &regs[regnum];
 
       if (register_size (gdbarch, regnum) == 0)
        /* Do not try to fetch zero-sized (placeholder) registers.  */
@@ -568,12 +559,12 @@ init_remote_state (struct gdbarch *gdbarch)
      number.  */
 
   remote_regs = alloca (gdbarch_num_regs (gdbarch)
-                         * sizeof (struct packet_reg *));
+                       * sizeof (struct packet_reg *));
   for (num_remote_regs = 0, regnum = 0;
        regnum < gdbarch_num_regs (gdbarch);
        regnum++)
-    if (rsa->regs[regnum].pnum != -1)
-      remote_regs[num_remote_regs++] = &rsa->regs[regnum];
+    if (regs[regnum].pnum != -1)
+      remote_regs[num_remote_regs++] = &regs[regnum];
 
   qsort (remote_regs, num_remote_regs, sizeof (struct packet_reg *),
         compare_pnums);
@@ -585,9 +576,55 @@ init_remote_state (struct gdbarch *gdbarch)
       offset += register_size (gdbarch, remote_regs[regnum]->regnum);
     }
 
+  return offset;
+}
+
+/* Given the architecture described by GDBARCH, return the remote
+   protocol register's number and the register's offset in the g/G
+   packets of GDB register REGNUM, in PNUM and POFFSET respectively.
+   If the target does not have a mapping for REGNUM, return false,
+   otherwise, return true.  */
+
+int
+remote_register_number_and_offset (struct gdbarch *gdbarch, int regnum,
+                                  int *pnum, int *poffset)
+{
+  int sizeof_g_packet;
+  struct packet_reg *regs;
+  struct cleanup *old_chain;
+
+  gdb_assert (regnum < gdbarch_num_regs (gdbarch));
+
+  regs = xcalloc (gdbarch_num_regs (gdbarch), sizeof (struct packet_reg));
+  old_chain = make_cleanup (xfree, regs);
+
+  sizeof_g_packet = map_regcache_remote_table (gdbarch, regs);
+
+  *pnum = regs[regnum].pnum;
+  *poffset = regs[regnum].offset;
+
+  do_cleanups (old_chain);
+
+  return *pnum != -1;
+}
+
+static void *
+init_remote_state (struct gdbarch *gdbarch)
+{
+  struct remote_state *rs = get_remote_state_raw ();
+  struct remote_arch_state *rsa;
+
+  rsa = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct remote_arch_state);
+
+  /* Use the architecture to build a regnum<->pnum table, which will be
+     1:1 unless a feature set specifies otherwise.  */
+  rsa->regs = GDBARCH_OBSTACK_CALLOC (gdbarch,
+                                     gdbarch_num_regs (gdbarch),
+                                     struct packet_reg);
+
   /* Record the maximum possible size of the g packet - it may turn out
      to be smaller.  */
-  rsa->sizeof_g_packet = offset;
+  rsa->sizeof_g_packet = map_regcache_remote_table (gdbarch, rsa->regs);
 
   /* Default maximum number of characters in a packet body.  Many
      remote stubs have a hardwired buffer size of 400 bytes
@@ -1353,6 +1390,10 @@ static ptid_t any_thread_ptid;
 static ptid_t general_thread;
 static ptid_t continue_thread;
 
+/* This the traceframe which we last selected on the remote system.
+   It will be -1 if no traceframe is selected.  */
+static int remote_traceframe_number = -1;
+
 /* Find out if the stub attached to PID (and hence GDB should offer to
    detach instead of killing it when bailing out).  */
 
@@ -1872,7 +1913,7 @@ read_ptid (char *buf, char **obuf)
       /* Multi-process ptid.  */
       pp = unpack_varlen_hex (p + 1, &pid);
       if (*pp != '.')
-       error (_("invalid remote ptid: %s\n"), p);
+       error (_("invalid remote ptid: %s"), p);
 
       p = pp;
       pp = unpack_varlen_hex (p + 1, &tid);
@@ -2904,9 +2945,11 @@ remote_close (int quitting)
   remote_desc = NULL;
 
   /* We don't have a connection to the remote stub anymore.  Get rid
-     of all the inferiors and their threads we were controlling.  */
-  discard_all_inferiors ();
+     of all the inferiors and their threads we were controlling.
+     Reset inferior_ptid to null_ptid first, as otherwise has_stack_frame
+     will be unable to find the thread corresponding to (pid, 0, 0).  */
   inferior_ptid = null_ptid;
+  discard_all_inferiors ();
 
   /* We're no longer interested in any of these events.  */
   discard_pending_stop_replies (-1);
@@ -3091,22 +3134,9 @@ set_stop_requested_callback (struct thread_info *thread, void *data)
   return 0;
 }
 
-/* Stub for catch_exception.  */
-
-struct start_remote_args
-{
-  int from_tty;
-
-  /* The current target.  */
-  struct target_ops *target;
-
-  /* Non-zero if this is an extended-remote target.  */
-  int extended_p;
-};
-
 /* Send interrupt_sequence to remote target.  */
 static void
-send_interrupt_sequence ()
+send_interrupt_sequence (void)
 {
   if (interrupt_sequence_mode == interrupt_sequence_control_c)
     serial_write (remote_desc, "\x03", 1);
@@ -3124,9 +3154,8 @@ send_interrupt_sequence ()
 }
 
 static void
-remote_start_remote (struct ui_out *uiout, void *opaque)
+remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
 {
-  struct start_remote_args *args = opaque;
   struct remote_state *rs = get_remote_state ();
   struct packet_config *noack_config;
   char *wait_status = NULL;
@@ -3173,7 +3202,7 @@ remote_start_remote (struct ui_out *uiout, void *opaque)
        rs->noack_mode = 1;
     }
 
-  if (args->extended_p)
+  if (extended_p)
     {
       /* Tell the remote that we are using the extended protocol.  */
       putpkt ("!");
@@ -3191,7 +3220,7 @@ remote_start_remote (struct ui_out *uiout, void *opaque)
   /* On OSs where the list of libraries is global to all
      processes, we fetch them early.  */
   if (gdbarch_has_global_solist (target_gdbarch))
-    solib_add (NULL, args->from_tty, args->target, auto_solib_add);
+    solib_add (NULL, from_tty, target, auto_solib_add);
 
   if (non_stop)
     {
@@ -3209,7 +3238,7 @@ remote_start_remote (struct ui_out *uiout, void *opaque)
         controlling.  We default to adding them in the running state.
         The '?' query below will then tell us about which threads are
         stopped.  */
-      remote_threads_info (args->target);
+      remote_threads_info (target);
     }
   else if (rs->non_stop_aware)
     {
@@ -3230,7 +3259,7 @@ remote_start_remote (struct ui_out *uiout, void *opaque)
     {
       if (rs->buf[0] == 'W' || rs->buf[0] == 'X')
        {
-         if (!args->extended_p)
+         if (!extended_p)
            error (_("The target is not running (try extended-remote?)"));
 
          /* We're connected, but not running.  Drop out before we
@@ -3270,7 +3299,7 @@ remote_start_remote (struct ui_out *uiout, void *opaque)
         how to do it some other way, try again.  This is not
         supported for non-stop; it could be, but it is tricky if
         there are no stopped threads when we connect.  */
-      if (remote_read_description_p (args->target)
+      if (remote_read_description_p (target)
          && gdbarch_target_desc (target_gdbarch) == NULL)
        {
          target_clear_description ();
@@ -3283,7 +3312,7 @@ remote_start_remote (struct ui_out *uiout, void *opaque)
       rs->cached_wait_status = 1;
 
       immediate_quit--;
-      start_remote (args->from_tty); /* Initialize gdb process mechanisms.  */
+      start_remote (from_tty); /* Initialize gdb process mechanisms.  */
     }
   else
     {
@@ -3325,7 +3354,7 @@ remote_start_remote (struct ui_out *uiout, void *opaque)
 
       if (thread_count () == 0)
        {
-         if (!args->extended_p)
+         if (!extended_p)
            error (_("The target is not running (try extended-remote?)"));
 
          /* We're connected, but not running.  Drop out before we
@@ -3429,10 +3458,19 @@ remote_check_symbols (struct objfile *objfile)
   struct minimal_symbol *sym;
   int end;
 
+  /* The remote side has no concept of inferiors that aren't running
+     yet, it only knows about running processes.  If we're connected
+     but our current inferior is not running, we should not invite the
+     remote target to request symbol lookups related to its
+     (unrelated) current process.  */
+  if (!target_has_execution)
+    return;
+
   if (remote_protocol_packets[PACKET_qSymbol].support == PACKET_DISABLE)
     return;
 
-  /* Make sure the remote is pointing at the right process.  */
+  /* Make sure the remote is pointing at the right process.  Note
+     there's no way to select "no process".  */
   set_general_process ();
 
   /* Allocate a message buffer.  We can't reuse the input buffer in RS,
@@ -3522,7 +3560,7 @@ remote_set_permissions (void)
   /* If the target didn't like the packet, warn the user.  Do not try
      to undo the user's settings, that would just be maddening.  */
   if (strcmp (rs->buf, "OK") != 0)
-    warning ("Remote refused setting permissions with: %s", rs->buf);
+    warning (_("Remote refused setting permissions with: %s"), rs->buf);
 }
 
 /* This type describes each known response to the qSupported
@@ -4002,6 +4040,7 @@ remote_open_1 (char *name, int from_tty,
 
   general_thread = not_sent_ptid;
   continue_thread = not_sent_ptid;
+  remote_traceframe_number = -1;
 
   /* Probe for ability to use "ThreadInfo" query, as required.  */
   use_threadinfo_query = 1;
@@ -4044,14 +4083,12 @@ remote_open_1 (char *name, int from_tty,
      all the ``target ....'' commands to share a common callback
      function.  See cli-dump.c.  */
   {
-    struct gdb_exception ex;
-    struct start_remote_args args;
-
-    args.from_tty = from_tty;
-    args.target = target;
-    args.extended_p = extended_p;
+    volatile struct gdb_exception ex;
 
-    ex = catch_exception (uiout, remote_start_remote, &args, RETURN_MASK_ALL);
+    TRY_CATCH (ex, RETURN_MASK_ALL)
+      {
+       remote_start_remote (from_tty, target, extended_p);
+      }
     if (ex.reason < 0)
       {
        /* Pop the partially set up target - unless something else did
@@ -4457,7 +4494,7 @@ remote_vcont_resume (ptid_t ptid, int step, enum target_signal siggnal)
         so we don't have any TID numbers the inferior will
         understand.  Make sure to only send forms that do not specify
         a TID.  */
-      p = append_resumption (p, endp, minus_one_ptid, step, siggnal);
+      append_resumption (p, endp, minus_one_ptid, step, siggnal);
     }
   else if (ptid_equal (ptid, minus_one_ptid) || ptid_is_pid (ptid))
     {
@@ -4472,12 +4509,12 @@ remote_vcont_resume (ptid_t ptid, int step, enum target_signal siggnal)
        }
 
       /* And continue others without a signal.  */
-      p = append_resumption (p, endp, ptid, /*step=*/ 0, TARGET_SIGNAL_0);
+      append_resumption (p, endp, ptid, /*step=*/ 0, TARGET_SIGNAL_0);
     }
   else
     {
       /* Scheduler locking; resume only PTID.  */
-      p = append_resumption (p, endp, ptid, step, siggnal);
+      append_resumption (p, endp, ptid, step, siggnal);
     }
 
   gdb_assert (strlen (rs->buf) < get_remote_packet_size ());
@@ -4533,7 +4570,7 @@ remote_resume (struct target_ops *ops,
     {
       /* We don't pass signals to the target in reverse exec mode.  */
       if (info_verbose && siggnal != TARGET_SIGNAL_0)
-       warning (" - Can't pass signal %d to target in reverse: ignored.\n",
+       warning (_(" - Can't pass signal %d to target in reverse: ignored."),
                 siggnal);
 
       if (step 
@@ -4704,7 +4741,7 @@ remote_stop_ns (ptid_t ptid)
          nptid = ptid;
        }
 
-      p = write_ptid (p, endp, nptid);
+      write_ptid (p, endp, nptid);
     }
 
   /* In non-stop, we get an immediate OK reply.  The stop reply will
@@ -5770,6 +5807,28 @@ fetch_registers_using_g (struct regcache *regcache)
   process_g_packet (regcache);
 }
 
+/* Make the remote selected traceframe match GDB's selected
+   traceframe.  */
+
+static void
+set_remote_traceframe (void)
+{
+  int newnum;
+
+  if (remote_traceframe_number == get_traceframe_number ())
+    return;
+
+  /* Avoid recursion, remote_trace_find calls us again.  */
+  remote_traceframe_number = get_traceframe_number ();
+
+  newnum = target_trace_find (tfind_number,
+                             get_traceframe_number (), 0, 0, NULL);
+
+  /* Should not happen.  If it does, all bets are off.  */
+  if (newnum != get_traceframe_number ())
+    warning (_("could not set remote traceframe"));
+}
+
 static void
 remote_fetch_registers (struct target_ops *ops,
                        struct regcache *regcache, int regnum)
@@ -5777,6 +5836,7 @@ remote_fetch_registers (struct target_ops *ops,
   struct remote_arch_state *rsa = get_remote_arch_state ();
   int i;
 
+  set_remote_traceframe ();
   set_general_thread (inferior_ptid);
 
   if (regnum >= 0)
@@ -5934,6 +5994,7 @@ remote_store_registers (struct target_ops *ops,
   struct remote_arch_state *rsa = get_remote_arch_state ();
   int i;
 
+  set_remote_traceframe ();
   set_general_thread (inferior_ptid);
 
   if (regnum >= 0)
@@ -6502,6 +6563,7 @@ remote_xfer_memory (CORE_ADDR mem_addr, gdb_byte *buffer, int mem_len,
 {
   int res;
 
+  set_remote_traceframe ();
   set_general_thread (inferior_ptid);
 
   if (should_write)
@@ -6816,6 +6878,7 @@ putpkt_binary (char *buf, int cnt)
            case '-':
              if (remote_debug)
                fprintf_unfiltered (gdb_stdlog, "Nak\n");
+             /* FALLTHROUGH */
            case SERIAL_TIMEOUT:
              tcount++;
              if (tcount > 3)
@@ -8084,6 +8147,7 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
   char *p2;
   char query_type;
 
+  set_remote_traceframe ();
   set_general_thread (inferior_ptid);
 
   rs = get_remote_state ();
@@ -9972,6 +10036,12 @@ remote_trace_find (enum trace_find_type type, int num,
   char *p, *reply;
   int target_frameno = -1, target_tracept = -1;
 
+  /* Lookups other than by absolute frame number depend on the current
+     trace selected, so make sure it is correct on the remote end
+     first.  */
+  if (type != tfind_number)
+    set_remote_traceframe ();
+
   p = rs->buf;
   strcpy (p, "QTFrame:");
   p = strchr (p, '\0');
@@ -10009,6 +10079,8 @@ remote_trace_find (enum trace_find_type type, int num,
        target_frameno = (int) strtol (p, &reply, 16);
        if (reply == p)
          error (_("Unable to parse trace frame number"));
+       /* Don't update our remote traceframe number cache on failure
+          to select a remote traceframe.  */
        if (target_frameno == -1)
          return -1;
        break;
@@ -10029,6 +10101,8 @@ remote_trace_find (enum trace_find_type type, int num,
       }
   if (tpp)
     *tpp = target_tracept;
+
+  remote_traceframe_number = target_frameno;
   return target_frameno;
 }
 
@@ -10039,6 +10113,8 @@ remote_get_trace_state_variable_value (int tsvnum, LONGEST *val)
   char *reply;
   ULONGEST uval;
 
+  set_remote_traceframe ();
+
   sprintf (rs->buf, "qTV:%x", tsvnum);
   putpkt (rs->buf);
   reply = remote_get_noisy_reply (&target_buf, &target_buf_size);
This page took 0.032795 seconds and 4 git commands to generate.