Return early in target_xfer_partial when LEN is zero.
[deliverable/binutils-gdb.git] / gdb / remote.c
index a9ef2974ac34c854312b49339eeaee0c4ad2cede..da0f64a75013f852e178c0c5a347fa83ee68e00d 100644 (file)
@@ -1,6 +1,6 @@
 /* Remote target communications for serial-line targets in custom GDB protocol
 
-   Copyright (C) 1988-2013 Free Software Foundation, Inc.
+   Copyright (C) 1988-2014 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -20,7 +20,7 @@
 /* See the GDB User Guide for details of the GDB remote protocol.  */
 
 #include "defs.h"
-#include "gdb_string.h"
+#include <string.h>
 #include <ctype.h>
 #include <fcntl.h>
 #include "inferior.h"
@@ -46,7 +46,6 @@
 #include "gdb_bfd.h"
 #include "filestuff.h"
 
-#include <ctype.h>
 #include <sys/time.h>
 
 #include "event-loop.h"
@@ -60,7 +59,7 @@
 
 #include "remote-fileio.h"
 #include "gdb/fileio.h"
-#include "gdb_stat.h"
+#include <sys/stat.h>
 #include "xml-support.h"
 
 #include "memory-map.h"
@@ -98,7 +97,8 @@ static void async_handle_remote_sigint_twice (int);
 
 static void remote_files_info (struct target_ops *ignore);
 
-static void remote_prepare_to_store (struct regcache *regcache);
+static void remote_prepare_to_store (struct target_ops *self,
+                                    struct regcache *regcache);
 
 static void remote_open (char *name, int from_tty);
 
@@ -133,8 +133,6 @@ static int remote_is_async_p (void);
 static void remote_async (void (*callback) (enum inferior_event_type event_type,
                                            void *context), void *context);
 
-static void remote_detach (struct target_ops *ops, char *args, int from_tty);
-
 static void sync_remote_interrupt_twice (int signo);
 
 static void interrupt_query (void);
@@ -220,7 +218,7 @@ struct stop_reply;
 static void stop_reply_xfree (struct stop_reply *);
 static void remote_parse_stop_reply (char *, struct stop_reply *);
 static void push_stop_reply (struct stop_reply *);
-static void discard_pending_stop_replies (struct inferior *);
+static void discard_pending_stop_replies_in_queue (struct remote_state *);
 static int peek_stop_reply (ptid_t ptid);
 
 static void remote_async_inferior_event_handler (gdb_client_data);
@@ -425,6 +423,9 @@ struct remote_state
   threadref echo_nextthread;
   threadref nextthread;
   threadref resultthreadlist[MAXTHREADLISTRESULTS];
+
+  /* The state of remote notification.  */
+  struct remote_notif_state *notif_state;
 };
 
 /* Private data that we'll store in (struct thread_info)->private.  */
@@ -1561,7 +1562,18 @@ remote_add_inferior (int fake_pid_p, int pid, int attached)
 static void
 remote_add_thread (ptid_t ptid, int running)
 {
-  add_thread (ptid);
+  struct remote_state *rs = get_remote_state ();
+
+  /* GDB historically didn't pull threads in the initial connection
+     setup.  If the remote target doesn't even have a concept of
+     threads (e.g., a bare-metal target), even if internally we
+     consider that a single-threaded target, mentioning a new thread
+     might be confusing to the user.  Be silent then, preserving the
+     age old behavior.  */
+  if (rs->starting_up)
+    add_thread_silent (ptid);
+  else
+    add_thread (ptid);
 
   set_executing (ptid, running);
   set_running (ptid, running);
@@ -1639,9 +1651,15 @@ remote_notice_new_inferior (ptid_t currthread, int running)
 
       /* If we found a new inferior, let the common code do whatever
         it needs to with it (e.g., read shared libraries, insert
-        breakpoints).  */
+        breakpoints), unless we're just setting up an all-stop
+        connection.  */
       if (inf != NULL)
-       notice_new_inferior (currthread, running, 0);
+       {
+         struct remote_state *rs = get_remote_state ();
+
+         if (non_stop || !rs->starting_up)
+           notice_new_inferior (currthread, running, 0);
+       }
     }
 }
 
@@ -1714,11 +1732,9 @@ remote_pass_signals (int numsigs, unsigned char *pass_signals)
       *p = 0;
       if (!rs->last_pass_packet || strcmp (rs->last_pass_packet, pass_packet))
        {
-         char *buf = rs->buf;
-
          putpkt (pass_packet);
          getpkt (&rs->buf, &rs->buf_size, 0);
-         packet_ok (buf, &remote_protocol_packets[PACKET_QPassSignals]);
+         packet_ok (rs->buf, &remote_protocol_packets[PACKET_QPassSignals]);
          if (rs->last_pass_packet)
            xfree (rs->last_pass_packet);
          rs->last_pass_packet = pass_packet;
@@ -1767,11 +1783,9 @@ remote_program_signals (int numsigs, unsigned char *signals)
       if (!rs->last_program_signals_packet
          || strcmp (rs->last_program_signals_packet, packet) != 0)
        {
-         char *buf = rs->buf;
-
          putpkt (packet);
          getpkt (&rs->buf, &rs->buf_size, 0);
-         packet_ok (buf, &remote_protocol_packets[PACKET_QProgramSignals]);
+         packet_ok (rs->buf, &remote_protocol_packets[PACKET_QProgramSignals]);
          xfree (rs->last_program_signals_packet);
          rs->last_program_signals_packet = packet;
        }
@@ -3064,16 +3078,14 @@ remote_close (void)
   inferior_ptid = null_ptid;
   discard_all_inferiors ();
 
-  /* Stop replies may from inferiors which are still unknown to GDB.
-     We are closing the remote target, so we should discard
-     everything, including the stop replies from GDB-unknown
-     inferiors.  */
-  discard_pending_stop_replies (NULL);
+  /* We are closing the remote target, so we should discard
+     everything of this target.  */
+  discard_pending_stop_replies_in_queue (rs);
 
   if (remote_async_inferior_event_token)
     delete_async_event_handler (&remote_async_inferior_event_token);
 
-  remote_notif_unregister_async_event_handler ();
+  remote_notif_state_xfree (rs->notif_state);
 
   trace_reset_local_state ();
 }
@@ -3311,6 +3323,28 @@ stop_reply_extract_thread (char *stop_reply)
   return null_ptid;
 }
 
+/* Determine the remote side's current thread.  If we have a stop
+   reply handy (in WAIT_STATUS), maybe it's a T stop reply with a
+   "thread" register we can extract the current thread from.  If not,
+   ask the remote which is the current thread with qC.  The former
+   method avoids a roundtrip.  */
+
+static ptid_t
+get_current_thread (char *wait_status)
+{
+  ptid_t ptid;
+
+  /* Note we don't use remote_parse_stop_reply as that makes use of
+     the target architecture, which we haven't yet fully determined at
+     this point.  */
+  if (wait_status != NULL)
+    ptid = stop_reply_extract_thread (wait_status);
+  if (ptid_equal (ptid, null_ptid))
+    ptid = remote_current_thread (inferior_ptid);
+
+  return ptid;
+}
+
 /* 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
@@ -3331,18 +3365,8 @@ add_current_inferior_and_thread (char *wait_status)
 
   inferior_ptid = null_ptid;
 
-  /* Now, if we have thread information, update inferior_ptid.  First
-     if we have a stop reply handy, maybe it's a T stop reply with a
-     "thread" register we can extract the current thread from.  If
-     not, ask the remote which is the current thread, with qC.  The
-     former method avoids a roundtrip.  Note we don't use
-     remote_parse_stop_reply as that makes use of the target
-     architecture, which we haven't yet fully determined at this
-     point.  */
-  if (wait_status != NULL)
-    ptid = stop_reply_extract_thread (wait_status);
-  if (ptid_equal (ptid, null_ptid))
-    ptid = remote_current_thread (inferior_ptid);
+  /* Now, if we have thread information, update inferior_ptid.  */
+  ptid = get_current_thread (wait_status);
 
   if (!ptid_equal (ptid, null_ptid))
     {
@@ -3512,10 +3536,35 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
          strcpy (wait_status, rs->buf);
        }
 
+      /* Fetch thread list.  */
+      target_find_new_threads ();
+
       /* Let the stub know that we want it to return the thread.  */
       set_continue_thread (minus_one_ptid);
 
-      add_current_inferior_and_thread (wait_status);
+      if (thread_count () == 0)
+       {
+         /* Target has no concept of threads at all.  GDB treats
+            non-threaded target as single-threaded; add a main
+            thread.  */
+         add_current_inferior_and_thread (wait_status);
+       }
+      else
+       {
+         /* We have thread information; select the thread the target
+            says should be current.  If we're reconnecting to a
+            multi-threaded program, this will ideally be the thread
+            that last reported an event before GDB disconnected.  */
+         inferior_ptid = get_current_thread (wait_status);
+         if (ptid_equal (inferior_ptid, null_ptid))
+           {
+             /* Odd... The target was able to list threads, but not
+                tell us which thread was current (no "thread"
+                register in T stop reply?).  Just pick the first
+                thread in the thread list then.  */
+             inferior_ptid = thread_list->ptid;
+           }
+       }
 
       /* init_wait_for_inferior should be called before get_offsets in order
         to manage `inserted' flag in bp loc in a correct state.
@@ -3569,7 +3618,7 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
 
          /* remote_notif_get_pending_replies acks this one, and gets
             the rest out.  */
-         notif_client_stop.pending_event
+         rs->notif_state->pending_event[notif_client_stop.id]
            = remote_notif_parse (notif, rs->buf);
          remote_notif_get_pending_events (notif);
 
@@ -3615,7 +3664,7 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
   /* If we connected to a live target, do some additional setup.  */
   if (target_has_execution)
     {
-      if (exec_bfd)    /* No use without an exec file.  */
+      if (symfile_objfile)     /* No use without a symbol-file.  */
        remote_check_symbols ();
     }
 
@@ -4337,7 +4386,7 @@ remote_open_1 (char *name, int from_tty,
   remote_async_inferior_event_token
     = create_async_event_handler (remote_async_inferior_event_handler,
                                  NULL);
-  remote_notif_register_async_event_handler ();
+  rs->notif_state = remote_notif_state_allocate ();
 
   /* Reset the target state; these things will be queried either by
      remote_query_supported or as they are needed.  */
@@ -4424,7 +4473,7 @@ remote_open_1 (char *name, int from_tty,
    die when it hits one.  */
 
 static void
-remote_detach_1 (char *args, int from_tty, int extended)
+remote_detach_1 (const char *args, int from_tty, int extended)
 {
   int pid = ptid_get_pid (inferior_ptid);
   struct remote_state *rs = get_remote_state ();
@@ -4468,13 +4517,13 @@ remote_detach_1 (char *args, int from_tty, int extended)
 }
 
 static void
-remote_detach (struct target_ops *ops, char *args, int from_tty)
+remote_detach (struct target_ops *ops, const char *args, int from_tty)
 {
   remote_detach_1 (args, from_tty, 0);
 }
 
 static void
-extended_remote_detach (struct target_ops *ops, char *args, int from_tty)
+extended_remote_detach (struct target_ops *ops, const char *args, int from_tty)
 {
   remote_detach_1 (args, from_tty, 1);
 }
@@ -4931,7 +4980,7 @@ remote_resume (struct target_ops *ops,
      before resuming inferior, because inferior was stopped and no RSP
      traffic at that moment.  */
   if (!non_stop)
-    remote_notif_process (&notif_client_stop);
+    remote_notif_process (rs->notif_state, &notif_client_stop);
 
   rs->last_sent_signal = siggnal;
   rs->last_sent_step = step;
@@ -5273,6 +5322,11 @@ typedef struct stop_reply
   /* The identifier of the thread about this event  */
   ptid_t ptid;
 
+  /* The remote state this event is associated with.  When the remote
+     connection, represented by a remote_state object, is closed,
+     all the associated stop_reply events should be released.  */
+  struct remote_state *rs;
+
   struct target_waitstatus ws;
 
   /* Expedited registers.  This makes remote debugging a bit more
@@ -5301,11 +5355,7 @@ static QUEUE (stop_reply_p) *stop_reply_queue;
 static void
 stop_reply_xfree (struct stop_reply *r)
 {
-  if (r != NULL)
-    {
-      VEC_free (cached_reg_t, r->regcache);
-      xfree (r);
-    }
+  notif_event_xfree ((struct notif_event *) r);
 }
 
 static void
@@ -5355,7 +5405,7 @@ static struct notif_event *
 remote_notif_stop_alloc_reply (void)
 {
   struct notif_event *r
-    = (struct notif_event *) XMALLOC (struct stop_reply);
+    = (struct notif_event *) XNEW (struct stop_reply);
 
   r->dtr = stop_reply_dtr;
 
@@ -5372,7 +5422,7 @@ struct notif_client notif_client_stop =
   remote_notif_stop_ack,
   remote_notif_stop_can_get_pending_events,
   remote_notif_stop_alloc_reply,
-  NULL,
+  REMOTE_NOTIF_STOP,
 };
 
 /* A parameter to pass data in and out.  */
@@ -5383,18 +5433,19 @@ struct queue_iter_param
   struct stop_reply *output;
 };
 
-/* Remove all queue elements meet the condition it checks.  */
+/* Remove stop replies in the queue if its pid is equal to the given
+   inferior's pid.  */
 
 static int
-remote_notif_remove_all (QUEUE (stop_reply_p) *q,
-                        QUEUE_ITER (stop_reply_p) *iter,
-                        stop_reply_p event,
-                        void *data)
+remove_stop_reply_for_inferior (QUEUE (stop_reply_p) *q,
+                               QUEUE_ITER (stop_reply_p) *iter,
+                               stop_reply_p event,
+                               void *data)
 {
   struct queue_iter_param *param = data;
   struct inferior *inf = param->input;
 
-  if (inf == NULL || ptid_get_pid (event->ptid) == inf->pid)
+  if (ptid_get_pid (event->ptid) == inf->pid)
     {
       stop_reply_xfree (event);
       QUEUE_remove_elem (stop_reply_p, q, iter);
@@ -5403,24 +5454,29 @@ remote_notif_remove_all (QUEUE (stop_reply_p) *q,
   return 1;
 }
 
-/* Discard all pending stop replies of inferior INF.  If INF is NULL,
-   discard everything.  */
+/* Discard all pending stop replies of inferior INF.  */
 
 static void
 discard_pending_stop_replies (struct inferior *inf)
 {
   int i;
   struct queue_iter_param param;
-  struct stop_reply *reply
-    = (struct stop_reply *) notif_client_stop.pending_event;
+  struct stop_reply *reply;
+  struct remote_state *rs = get_remote_state ();
+  struct remote_notif_state *rns = rs->notif_state;
+
+  /* This function can be notified when an inferior exists.  When the
+     target is not remote, the notification state is NULL.  */
+  if (rs->remote_desc == NULL)
+    return;
+
+  reply = (struct stop_reply *) rns->pending_event[notif_client_stop.id];
 
   /* Discard the in-flight notification.  */
-  if (reply != NULL
-      && (inf == NULL
-         || ptid_get_pid (reply->ptid) == inf->pid))
+  if (reply != NULL && ptid_get_pid (reply->ptid) == inf->pid)
     {
       stop_reply_xfree (reply);
-      notif_client_stop.pending_event = NULL;
+      rns->pending_event[notif_client_stop.id] = NULL;
     }
 
   param.input = inf;
@@ -5428,7 +5484,43 @@ discard_pending_stop_replies (struct inferior *inf)
   /* Discard the stop replies we have already pulled with
      vStopped.  */
   QUEUE_iterate (stop_reply_p, stop_reply_queue,
-                remote_notif_remove_all, &param);
+                remove_stop_reply_for_inferior, &param);
+}
+
+/* If its remote state is equal to the given remote state,
+   remove EVENT from the stop reply queue.  */
+
+static int
+remove_stop_reply_of_remote_state (QUEUE (stop_reply_p) *q,
+                                  QUEUE_ITER (stop_reply_p) *iter,
+                                  stop_reply_p event,
+                                  void *data)
+{
+  struct queue_iter_param *param = data;
+  struct remote_state *rs = param->input;
+
+  if (event->rs == rs)
+    {
+      stop_reply_xfree (event);
+      QUEUE_remove_elem (stop_reply_p, q, iter);
+    }
+
+  return 1;
+}
+
+/* Discard the stop replies for RS in stop_reply_queue.  */
+
+static void
+discard_pending_stop_replies_in_queue (struct remote_state *rs)
+{
+  struct queue_iter_param param;
+
+  param.input = rs;
+  param.output = NULL;
+  /* Discard the stop replies we have already pulled with
+     vStopped.  */
+  QUEUE_iterate (stop_reply_p, stop_reply_queue,
+                remove_stop_reply_of_remote_state, &param);
 }
 
 /* A parameter to pass data in and out.  */
@@ -5541,6 +5633,7 @@ remote_parse_stop_reply (char *buf, struct stop_reply *event)
   char *p;
 
   event->ptid = null_ptid;
+  event->rs = get_remote_state ();
   event->ws.kind = TARGET_WAITKIND_IGNORE;
   event->ws.value.integer = 0;
   event->stopped_by_watchpoint_p = 0;
@@ -5675,9 +5768,16 @@ Packet: '%s'\n"),
 
       /* fall through */
     case 'S':          /* Old style status, just signal only.  */
-      event->ws.kind = TARGET_WAITKIND_STOPPED;
-      event->ws.value.sig = (enum gdb_signal)
-       (((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
+      {
+       int sig;
+
+       event->ws.kind = TARGET_WAITKIND_STOPPED;
+       sig = (fromhex (buf[1]) << 4) + fromhex (buf[2]);
+       if (GDB_SIGNAL_FIRST <= sig && sig < GDB_SIGNAL_LAST)
+         event->ws.value.sig = (enum gdb_signal) sig;
+       else
+         event->ws.value.sig = GDB_SIGNAL_UNKNOWN;
+      }
       break;
     case 'W':          /* Target exited.  */
     case 'X':
@@ -5701,7 +5801,10 @@ Packet: '%s'\n"),
          {
            /* The remote process exited with a signal.  */
            event->ws.kind = TARGET_WAITKIND_SIGNALLED;
-           event->ws.value.sig = (enum gdb_signal) value;
+           if (GDB_SIGNAL_FIRST <= value && value < GDB_SIGNAL_LAST)
+             event->ws.value.sig = (enum gdb_signal) value;
+           else
+             event->ws.value.sig = GDB_SIGNAL_UNKNOWN;
          }
 
        /* If no process is specified, assume inferior_ptid.  */
@@ -5784,7 +5887,7 @@ remote_notif_get_pending_events (struct notif_client *nc)
 {
   struct remote_state *rs = get_remote_state ();
 
-  if (nc->pending_event)
+  if (rs->notif_state->pending_event[nc->id] != NULL)
     {
       if (notif_debug)
        fprintf_unfiltered (gdb_stdlog,
@@ -5792,8 +5895,8 @@ remote_notif_get_pending_events (struct notif_client *nc)
                            nc->name);
 
       /* acknowledge */
-      nc->ack (nc, rs->buf, nc->pending_event);
-      nc->pending_event = NULL;
+      nc->ack (nc, rs->buf, rs->notif_state->pending_event[nc->id]);
+      rs->notif_state->pending_event[nc->id] = NULL;
 
       while (1)
        {
@@ -5898,7 +6001,7 @@ remote_wait_ns (ptid_t ptid, struct target_waitstatus *status, int options)
 
       /* Acknowledge a pending stop reply that may have arrived in the
         mean time.  */
-      if (notif_client_stop.pending_event != NULL)
+      if (rs->notif_state->pending_event[notif_client_stop.id] != NULL)
        remote_notif_get_pending_events (&notif_client_stop);
 
       /* If indeed we noticed a stop reply, we're done.  */
@@ -6360,7 +6463,7 @@ remote_fetch_registers (struct target_ops *ops,
    first.  */
 
 static void
-remote_prepare_to_store (struct regcache *regcache)
+remote_prepare_to_store (struct target_ops *self, struct regcache *regcache)
 {
   struct remote_arch_state *rsa = get_remote_arch_state ();
   int i;
@@ -6741,7 +6844,7 @@ check_binary_download (CORE_ADDR addr)
 
 static LONGEST
 remote_write_bytes_aux (const char *header, CORE_ADDR memaddr,
-                       const gdb_byte *myaddr, ssize_t len,
+                       const gdb_byte *myaddr, ULONGEST len,
                        char packet_format, int use_length)
 {
   struct remote_state *rs = get_remote_state ();
@@ -6758,7 +6861,7 @@ remote_write_bytes_aux (const char *header, CORE_ADDR memaddr,
     internal_error (__FILE__, __LINE__,
                    _("remote_write_bytes_aux: bad packet format"));
 
-  if (len <= 0)
+  if (len == 0)
     return 0;
 
   payload_size = get_memory_write_packet_size ();
@@ -6896,7 +6999,7 @@ remote_write_bytes_aux (const char *header, CORE_ADDR memaddr,
    packet.  */
 
 static LONGEST
-remote_write_bytes (CORE_ADDR memaddr, const gdb_byte *myaddr, ssize_t len)
+remote_write_bytes (CORE_ADDR memaddr, const gdb_byte *myaddr, ULONGEST len)
 {
   char *packet_format = 0;
 
@@ -6932,7 +7035,7 @@ remote_write_bytes (CORE_ADDR memaddr, const gdb_byte *myaddr, ssize_t len)
    target_xfer_error' value) for error.  */
 
 static LONGEST
-remote_read_bytes (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
+remote_read_bytes (CORE_ADDR memaddr, gdb_byte *myaddr, ULONGEST len)
 {
   struct remote_state *rs = get_remote_state ();
   int max_buf_size;            /* Max size of packet output buffer.  */
@@ -6940,7 +7043,7 @@ remote_read_bytes (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
   int todo;
   int i;
 
-  if (len <= 0)
+  if (len == 0)
     return 0;
 
   max_buf_size = get_memory_read_packet_size ();
@@ -7352,7 +7455,7 @@ putpkt_binary (char *buf, int cnt)
                                            str);
                        do_cleanups (old_chain);
                      }
-                   handle_notification (rs->buf);
+                   handle_notification (rs->notif_state, rs->buf);
                    /* We're in sync now, rewait for the ack.  */
                    tcount = 0;
                  }
@@ -7637,7 +7740,7 @@ getpkt_or_notif_sane_1 (char **buf, long *sizeof_buf, int forever,
      we get a packet.  */
   for (;;)
     {
-      /* If we get a timeout or bad checksm, retry up to MAX_TRIES
+      /* If we get a timeout or bad checksum, retry up to MAX_TRIES
         times.  */
       for (tries = 1; tries <= MAX_TRIES; tries++)
        {
@@ -7738,7 +7841,7 @@ getpkt_or_notif_sane_1 (char **buf, long *sizeof_buf, int forever,
          if (is_notif != NULL)
            *is_notif = 1;
 
-         handle_notification (*buf);
+         handle_notification (rs->notif_state, *buf);
 
          /* Notifications require no acknowledgement.  */
 
@@ -7763,23 +7866,39 @@ getpkt_or_notif_sane (char **buf, long *sizeof_buf, int forever,
 }
 
 \f
-/* A helper function that just calls putpkt; for type correctness.  */
-
-static int
-putpkt_for_catch_errors (void *arg)
-{
-  return putpkt (arg);
-}
-
 static void
 remote_kill (struct target_ops *ops)
 {
-  /* Use catch_errors so the user can quit from gdb even when we
+  volatile struct gdb_exception ex;
+
+  /* Catch errors so the user can quit from gdb even when we
      aren't on speaking terms with the remote system.  */
-  catch_errors (putpkt_for_catch_errors, "k", "", RETURN_MASK_ERROR);
+  TRY_CATCH (ex, RETURN_MASK_ERROR)
+    {
+      putpkt ("k");
+    }
+  if (ex.reason < 0)
+    {
+      if (ex.error == TARGET_CLOSE_ERROR)
+       {
+         /* If we got an (EOF) error that caused the target
+            to go away, then we're done, that's what we wanted.
+            "k" is susceptible to cause a premature EOF, given
+            that the remote server isn't actually required to
+            reply to "k", and it can happen that it doesn't
+            even get to reply ACK to the "k".  */
+         return;
+       }
+
+       /* Otherwise, something went wrong.  We didn't actually kill
+          the target.  Just propagate the exception, and let the
+          user or higher layers decide what to do.  */
+       throw_exception (ex);
+    }
 
-  /* 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.  */
+  /* We've killed the remote end, we get to mourn it.  Since this is
+     target remote, single-process, mourning the inferior also
+     unpushes remote_ops.  */
   target_mourn_inferior ();
 }
 
@@ -8008,8 +8127,9 @@ extended_remote_run (char *args)
    environment.  */
 
 static void
-extended_remote_create_inferior_1 (char *exec_file, char *args,
-                                  char **env, int from_tty)
+extended_remote_create_inferior (struct target_ops *ops,
+                                char *exec_file, char *args,
+                                char **env, int from_tty)
 {
   int run_worked;
   char *stop_reply;
@@ -8055,14 +8175,6 @@ extended_remote_create_inferior_1 (char *exec_file, char *args,
   /* Get updated offsets, if the stub uses qOffsets.  */
   get_offsets ();
 }
-
-static void
-extended_remote_create_inferior (struct target_ops *ops, 
-                                char *exec_file, char *args,
-                                char **env, int from_tty)
-{
-  extended_remote_create_inferior_1 (exec_file, args, env, from_tty);
-}
 \f
 
 /* Given a location's target info BP_TGT and the packet buffer BUF,  output
@@ -8098,8 +8210,6 @@ remote_add_target_side_condition (struct gdbarch *gdbarch,
        buf = pack_hex_byte (buf, aexpr->buf[i]);
       *buf = '\0';
     }
-
-  VEC_free (agent_expr_p, bp_tgt->conditions);
   return 0;
 }
 
@@ -8130,8 +8240,6 @@ remote_add_target_side_commands (struct gdbarch *gdbarch,
        buf = pack_hex_byte (buf, aexpr->buf[i]);
       *buf = '\0';
     }
-
-  VEC_free (agent_expr_p, bp_tgt->tcommands);
 }
 
 /* Insert a breakpoint.  On targets that have software breakpoint
@@ -8139,7 +8247,8 @@ remote_add_target_side_commands (struct gdbarch *gdbarch,
    which don't, we insert a traditional memory breakpoint.  */
 
 static int
-remote_insert_breakpoint (struct gdbarch *gdbarch,
+remote_insert_breakpoint (struct target_ops *ops,
+                         struct gdbarch *gdbarch,
                          struct bp_target_info *bp_tgt)
 {
   /* Try the "Z" s/w breakpoint packet if it is not already disabled.
@@ -8195,11 +8304,18 @@ remote_insert_breakpoint (struct gdbarch *gdbarch,
        }
     }
 
-  return memory_insert_breakpoint (gdbarch, bp_tgt);
+  /* If this breakpoint has target-side commands but this stub doesn't
+     support Z0 packets, throw error.  */
+  if (!VEC_empty (agent_expr_p, bp_tgt->tcommands))
+    throw_error (NOT_SUPPORTED_ERROR, _("\
+Target doesn't support breakpoints that have target side commands."));
+
+  return memory_insert_breakpoint (ops, gdbarch, bp_tgt);
 }
 
 static int
-remote_remove_breakpoint (struct gdbarch *gdbarch,
+remote_remove_breakpoint (struct target_ops *ops,
+                         struct gdbarch *gdbarch,
                          struct bp_target_info *bp_tgt)
 {
   CORE_ADDR addr = bp_tgt->placed_address;
@@ -8229,7 +8345,7 @@ remote_remove_breakpoint (struct gdbarch *gdbarch,
       return (rs->buf[0] == 'E');
     }
 
-  return memory_remove_breakpoint (gdbarch, bp_tgt);
+  return memory_remove_breakpoint (ops, gdbarch, bp_tgt);
 }
 
 static int
@@ -8633,7 +8749,7 @@ remote_write_qxfer (struct target_ops *ops, const char *object_name,
   int max_size = get_memory_write_packet_size (); 
 
   if (packet->support == PACKET_DISABLE)
-    return -1;
+    return TARGET_XFER_E_IO;
 
   /* Insert header.  */
   i = snprintf (rs->buf, max_size, 
@@ -8649,7 +8765,7 @@ remote_write_qxfer (struct target_ops *ops, const char *object_name,
   if (putpkt_binary (rs->buf, i + buf_len) < 0
       || getpkt_sane (&rs->buf, &rs->buf_size, 0) < 0
       || packet_ok (rs->buf, packet) != PACKET_OK)
-    return -1;
+    return TARGET_XFER_E_IO;
 
   unpack_varlen_hex (rs->buf, &n);
   return n;
@@ -8672,7 +8788,7 @@ remote_read_qxfer (struct target_ops *ops, const char *object_name,
   LONGEST i, n, packet_len;
 
   if (packet->support == PACKET_DISABLE)
-    return -1;
+    return TARGET_XFER_E_IO;
 
   /* Check whether we've cached an end-of-object packet that matches
      this request.  */
@@ -8702,12 +8818,12 @@ remote_read_qxfer (struct target_ops *ops, const char *object_name,
            phex_nz (n, sizeof n));
   i = putpkt (rs->buf);
   if (i < 0)
-    return -1;
+    return TARGET_XFER_E_IO;
 
   rs->buf[0] = '\0';
   packet_len = getpkt_sane (&rs->buf, &rs->buf_size, 0);
   if (packet_len < 0 || packet_ok (rs->buf, packet) != PACKET_OK)
-    return -1;
+    return TARGET_XFER_E_IO;
 
   if (rs->buf[0] != 'l' && rs->buf[0] != 'm')
     error (_("Unknown remote qXfer reply: %s"), rs->buf);
@@ -8738,7 +8854,7 @@ remote_read_qxfer (struct target_ops *ops, const char *object_name,
 static LONGEST
 remote_xfer_partial (struct target_ops *ops, enum target_object object,
                     const char *annex, gdb_byte *readbuf,
-                    const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
+                    const gdb_byte *writebuf, ULONGEST offset, ULONGEST len)
 {
   struct remote_state *rs;
   int i;
@@ -8804,7 +8920,7 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
                                  &remote_protocol_packets
                                  [PACKET_qXfer_statictrace_read]);
       else
-       return -1;
+       return TARGET_XFER_E_IO;
     }
 
   /* Only handle flash writes.  */
@@ -8818,7 +8934,7 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
          return remote_flash_write (ops, offset, len, writebuf);
 
        default:
-         return -1;
+         return TARGET_XFER_E_IO;
        }
     }
 
@@ -8886,7 +9002,7 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
         &remote_protocol_packets[PACKET_qXfer_btrace]);
 
     default:
-      return -1;
+      return TARGET_XFER_E_IO;
     }
 
   /* Note: a zero OFFSET and LEN can be used to query the minimum
@@ -8896,7 +9012,7 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
   /* Minimum outbuf size is get_remote_packet_size ().  If LEN is not
      large enough let the caller deal with it.  */
   if (len < get_remote_packet_size ())
-    return -1;
+    return TARGET_XFER_E_IO;
   len = get_remote_packet_size ();
 
   /* Except for querying the minimum buffer size, target must be open.  */
@@ -8928,7 +9044,7 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
 
   i = putpkt (rs->buf);
   if (i < 0)
-    return i;
+    return TARGET_XFER_E_IO;
 
   getpkt (&rs->buf, &rs->buf_size, 0);
   strcpy ((char *) readbuf, rs->buf);
@@ -11102,6 +11218,11 @@ remote_traceframe_info (void)
 {
   char *text;
 
+  /* If current traceframe is not selected, don't bother the remote
+     stub.  */
+  if (get_traceframe_number () < 0)
+    return NULL;
+
   text = target_read_stralloc (&current_target,
                               TARGET_OBJECT_TRACEFRAME_INFO, NULL);
   if (text != NULL)
@@ -11357,13 +11478,14 @@ remote_teardown_btrace (struct btrace_target_info *tinfo)
 
 /* Read the branch trace.  */
 
-static VEC (btrace_block_s) *
-remote_read_btrace (struct btrace_target_info *tinfo,
+static enum btrace_error
+remote_read_btrace (VEC (btrace_block_s) **btrace,
+                   struct btrace_target_info *tinfo,
                    enum btrace_read_type type)
 {
   struct packet_config *packet = &remote_protocol_packets[PACKET_qXfer_btrace];
   struct remote_state *rs = get_remote_state ();
-  VEC (btrace_block_s) *btrace = NULL;
+  struct cleanup *cleanup;
   const char *annex;
   char *xml;
 
@@ -11376,12 +11498,15 @@ remote_read_btrace (struct btrace_target_info *tinfo,
 
   switch (type)
     {
-    case btrace_read_all:
+    case BTRACE_READ_ALL:
       annex = "all";
       break;
-    case btrace_read_new:
+    case BTRACE_READ_NEW:
       annex = "new";
       break;
+    case BTRACE_READ_DELTA:
+      annex = "delta";
+      break;
     default:
       internal_error (__FILE__, __LINE__,
                      _("Bad branch tracing read type: %u."),
@@ -11390,15 +11515,14 @@ remote_read_btrace (struct btrace_target_info *tinfo,
 
   xml = target_read_stralloc (&current_target,
                               TARGET_OBJECT_BTRACE, annex);
-  if (xml != NULL)
-    {
-      struct cleanup *cleanup = make_cleanup (xfree, xml);
+  if (xml == NULL)
+    return BTRACE_ERR_UNKNOWN;
 
-      btrace = parse_xml_btrace (xml);
-      do_cleanups (cleanup);
-    }
+  cleanup = make_cleanup (xfree, xml);
+  *btrace = parse_xml_btrace (xml);
+  do_cleanups (cleanup);
 
-  return btrace;
+  return BTRACE_ERR_NONE;
 }
 
 static int
This page took 0.039506 seconds and 4 git commands to generate.