Use gdbarch obstack to allocate the TYPE_NAME string in arch_type
[deliverable/binutils-gdb.git] / gdb / remote.c
index 4b5eb8ed8c9f1ee0e64b36cce6081b3f1f1cab26..3afcaf41c93b3bdfc1e67a9e3e6a784f5addb62b 100644 (file)
@@ -45,8 +45,9 @@
 #include "filestuff.h"
 #include "rsp-low.h"
 #include "disasm.h"
+#include "location.h"
 
-#include <sys/time.h>
+#include "gdb_sys_time.h"
 
 #include "event-loop.h"
 #include "event-top.h"
@@ -225,6 +226,10 @@ static int remote_can_run_breakpoint_commands (struct target_ops *self);
 
 static void remote_btrace_reset (void);
 
+static int stop_reply_queue_length (void);
+
+static void readahead_cache_invalidate (void);
+
 /* For "remote".  */
 
 static struct cmd_list_element *remote_cmdlist;
@@ -261,6 +266,29 @@ typedef unsigned char threadref[OPAQUETHREADBYTES];
 
 #define MAXTHREADLISTRESULTS 32
 
+/* Data for the vFile:pread readahead cache.  */
+
+struct readahead_cache
+{
+  /* The file descriptor for the file that is being cached.  -1 if the
+     cache is invalid.  */
+  int fd;
+
+  /* The offset into the file that the cache buffer corresponds
+     to.  */
+  ULONGEST offset;
+
+  /* The buffer holding the cache contents.  */
+  gdb_byte *buf;
+  /* The buffer's size.  We try to read as much as fits into a packet
+     at a time.  */
+  size_t bufsize;
+
+  /* Cache hit and miss counters.  */
+  ULONGEST hit_count;
+  ULONGEST miss_count;
+};
+
 /* Description of the remote protocol state for the currently
    connected target.  This is per-target state, and independent of the
    selected architecture.  */
@@ -380,6 +408,14 @@ struct remote_state
      Initialized to -1 to indicate that no "vFile:setfs:" packet
      has yet been sent.  */
   int fs_pid;
+
+  /* A readahead cache for vFile:pread.  Often, reading a binary
+     involves a sequence of small reads.  E.g., when parsing an ELF
+     file.  A readahead cache helps mostly the case of remote
+     debugging on a connection with higher latency, due to the
+     request/reply nature of the RSP.  We only cache data for a single
+     file descriptor at a time.  */
+  struct readahead_cache readahead_cache;
 };
 
 /* Private data that we'll store in (struct thread_info)->private.  */
@@ -564,6 +600,7 @@ static struct gdbarch_data *remote_gdbarch_data_handle;
 static struct remote_arch_state *
 get_remote_arch_state (void)
 {
+  gdb_assert (target_gdbarch () != NULL);
   return gdbarch_data (target_gdbarch (), remote_gdbarch_data_handle);
 }
 
@@ -884,6 +921,16 @@ struct memory_packet_config
   int fixed_p;
 };
 
+/* The default max memory-write-packet-size.  The 16k is historical.
+   (It came from older GDB's using alloca for buffers and the
+   knowledge (folklore?) that some hosts don't cope very well with
+   large alloca calls.)  */
+#define DEFAULT_MAX_MEMORY_PACKET_SIZE 16384
+
+/* The minimum remote packet size for memory transfers.  Ensures we
+   can write at least one byte.  */
+#define MIN_MEMORY_PACKET_SIZE 20
+
 /* Compute the current size of a read/write packet.  Since this makes
    use of ``actual_register_packet_size'' the computation is dynamic.  */
 
@@ -893,23 +940,11 @@ get_memory_packet_size (struct memory_packet_config *config)
   struct remote_state *rs = get_remote_state ();
   struct remote_arch_state *rsa = get_remote_arch_state ();
 
-  /* NOTE: The somewhat arbitrary 16k comes from the knowledge (folk
-     law?) that some hosts don't cope very well with large alloca()
-     calls.  Eventually the alloca() code will be replaced by calls to
-     xmalloc() and make_cleanups() allowing this restriction to either
-     be lifted or removed.  */
-#ifndef MAX_REMOTE_PACKET_SIZE
-#define MAX_REMOTE_PACKET_SIZE 16384
-#endif
-  /* NOTE: 20 ensures we can write at least one byte.  */
-#ifndef MIN_REMOTE_PACKET_SIZE
-#define MIN_REMOTE_PACKET_SIZE 20
-#endif
   long what_they_get;
   if (config->fixed_p)
     {
       if (config->size <= 0)
-       what_they_get = MAX_REMOTE_PACKET_SIZE;
+       what_they_get = DEFAULT_MAX_MEMORY_PACKET_SIZE;
       else
        what_they_get = config->size;
     }
@@ -928,10 +963,8 @@ get_memory_packet_size (struct memory_packet_config *config)
          && what_they_get > rsa->actual_register_packet_size)
        what_they_get = rsa->actual_register_packet_size;
     }
-  if (what_they_get > MAX_REMOTE_PACKET_SIZE)
-    what_they_get = MAX_REMOTE_PACKET_SIZE;
-  if (what_they_get < MIN_REMOTE_PACKET_SIZE)
-    what_they_get = MIN_REMOTE_PACKET_SIZE;
+  if (what_they_get < MIN_MEMORY_PACKET_SIZE)
+    what_they_get = MIN_MEMORY_PACKET_SIZE;
 
   /* Make sure there is room in the global buffer for this packet
      (including its trailing NUL byte).  */
@@ -968,15 +1001,16 @@ set_memory_packet_size (char *args, struct memory_packet_config *config)
       size = strtoul (args, &end, 0);
       if (args == end)
        error (_("Invalid %s (bad syntax)."), config->name);
-#if 0
-      /* Instead of explicitly capping the size of a packet to
-         MAX_REMOTE_PACKET_SIZE or dissallowing it, the user is
-         instead allowed to set the size to something arbitrarily
-         large.  */
-      if (size > MAX_REMOTE_PACKET_SIZE)
-       error (_("Invalid %s (too large)."), config->name);
-#endif
+
+      /* Instead of explicitly capping the size of a packet to or
+        disallowing it, the user is allowed to set the size to
+        something arbitrarily large.  */
     }
+
+  /* So that the query shows the correct value.  */
+  if (size <= 0)
+    size = DEFAULT_MAX_MEMORY_PACKET_SIZE;
+
   /* Extra checks?  */
   if (fixed_p && !config->fixed_p)
     {
@@ -1763,7 +1797,7 @@ demand_private_info (ptid_t ptid)
 
   if (!info->priv)
     {
-      info->priv = xmalloc (sizeof (*(info->priv)));
+      info->priv = XNEW (struct private_thread_info);
       info->private_dtor = free_private_thread_info;
       info->priv->core = -1;
       info->priv->extra = 0;
@@ -3410,21 +3444,6 @@ get_offsets (void)
   objfile_relocate (symfile_objfile, offs);
 }
 
-/* Callback for iterate_over_threads.  Set the STOP_REQUESTED flags in
-   threads we know are stopped already.  This is used during the
-   initial remote connection in non-stop mode --- threads that are
-   reported as already being stopped are left stopped.  */
-
-static int
-set_stop_requested_callback (struct thread_info *thread, void *data)
-{
-  /* If we have a stop reply for this thread, it must be stopped.  */
-  if (peek_stop_reply (thread->ptid))
-    set_stop_requested (thread->ptid, 1);
-
-  return 0;
-}
-
 /* Send interrupt_sequence to remote target.  */
 static void
 send_interrupt_sequence (void)
@@ -3552,6 +3571,77 @@ add_current_inferior_and_thread (char *wait_status)
   add_thread_silent (inferior_ptid);
 }
 
+/* Process all initial stop replies the remote side sent in response
+   to the ? packet.  These indicate threads that were already stopped
+   on initial connection.  We mark these threads as stopped and print
+   their current frame before giving the user the prompt.  */
+
+static void
+process_initial_stop_replies (void)
+{
+  int pending_stop_replies = stop_reply_queue_length ();
+
+  /* Consume the initial pending events.  */
+  while (pending_stop_replies-- > 0)
+    {
+      ptid_t waiton_ptid = minus_one_ptid;
+      ptid_t event_ptid;
+      struct target_waitstatus ws;
+      int ignore_event = 0;
+
+      memset (&ws, 0, sizeof (ws));
+      event_ptid = target_wait (waiton_ptid, &ws, TARGET_WNOHANG);
+      if (remote_debug)
+       print_target_wait_results (waiton_ptid, event_ptid, &ws);
+
+      switch (ws.kind)
+       {
+       case TARGET_WAITKIND_IGNORE:
+       case TARGET_WAITKIND_NO_RESUMED:
+       case TARGET_WAITKIND_SIGNALLED:
+       case TARGET_WAITKIND_EXITED:
+         /* We shouldn't see these, but if we do, just ignore.  */
+         if (remote_debug)
+           fprintf_unfiltered (gdb_stdlog, "remote: event ignored\n");
+         ignore_event = 1;
+         break;
+
+       case TARGET_WAITKIND_EXECD:
+         xfree (ws.value.execd_pathname);
+         break;
+       default:
+         break;
+       }
+
+      if (ignore_event)
+       continue;
+
+      switch_to_thread (event_ptid);
+      set_executing (event_ptid, 0);
+      set_running (event_ptid, 0);
+
+      stop_pc = get_frame_pc (get_current_frame ());
+      set_current_sal_from_frame (get_current_frame ());
+
+      if (ws.kind == TARGET_WAITKIND_STOPPED)
+       {
+         enum gdb_signal sig = ws.value.sig;
+
+         /* Stubs traditionally report SIGTRAP as initial signal,
+            instead of signal 0.  Suppress it.  */
+         if (sig == GDB_SIGNAL_TRAP)
+           sig = GDB_SIGNAL_0;
+         inferior_thread ()->suspend.stop_signal = sig;
+
+         if (signal_print_state (sig))
+           observer_notify_signal_received (sig);
+        }
+
+      print_stop_event (&ws);
+      observer_notify_normal_stop (NULL, 1);
+    }
+}
+
 static void
 remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
 {
@@ -3764,6 +3854,8 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
     }
   else
     {
+      ptid_t current_ptid;
+
       /* Clear WFI global state.  Do this before finding about new
         threads and inferiors, and setting the current inferior.
         Otherwise we would clear the proceed status of the current
@@ -3785,15 +3877,8 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
          rs->notif_state->pending_event[notif_client_stop.id]
            = remote_notif_parse (notif, rs->buf);
          remote_notif_get_pending_events (notif);
-
-         /* Make sure that threads that were stopped remain
-            stopped.  */
-         iterate_over_threads (set_stop_requested_callback, NULL);
        }
 
-      if (target_can_async_p ())
-       target_async (1);
-
       if (thread_count () == 0)
        {
          if (!extended_p)
@@ -3811,10 +3896,11 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
       set_general_thread (null_ptid);
 
       /* Query it.  */
-      inferior_ptid = remote_current_thread (minus_one_ptid);
+      current_ptid = remote_current_thread (minus_one_ptid);
       if (ptid_equal (inferior_ptid, minus_one_ptid))
        error (_("remote didn't report the current thread in non-stop mode"));
 
+      inferior_ptid = current_ptid;
       get_offsets ();          /* Get text, data & bss offsets.  */
 
       /* In non-stop mode, any cached wait status will be stored in
@@ -3823,6 +3909,15 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
 
       /* Report all signals during attach/startup.  */
       remote_pass_signals (target, 0, NULL);
+
+      /* If there are already stopped threads, mark them stopped and
+        report their stops before giving the prompt to the user.  */
+      process_initial_stop_replies ();
+
+      switch_to_thread (current_ptid);
+
+      if (target_can_async_p ())
+       target_async (1);
     }
 
   /* If we connected to a live target, do some additional setup.  */
@@ -3910,6 +4005,7 @@ remote_check_symbols (void)
   char *msg, *reply, *tmp;
   struct bound_minimal_symbol sym;
   int end;
+  struct cleanup *old_chain;
 
   /* The remote side has no concept of inferiors that aren't running
      yet, it only knows about running processes.  If we're connected
@@ -3928,7 +4024,8 @@ remote_check_symbols (void)
 
   /* Allocate a message buffer.  We can't reuse the input buffer in RS,
      because we need both at the same time.  */
-  msg = alloca (get_remote_packet_size ());
+  msg = xmalloc (get_remote_packet_size ());
+  old_chain = make_cleanup (xfree, msg);
 
   /* Invite target to request symbol lookups.  */
 
@@ -3966,6 +4063,8 @@ remote_check_symbols (void)
       getpkt (&rs->buf, &rs->buf_size, 0);
       reply = rs->buf;
     }
+
+  do_cleanups (old_chain);
 }
 
 static struct serial *
@@ -4088,13 +4187,6 @@ remote_packet_size (const struct protocol_feature *feature,
       return;
     }
 
-  if (packet_size > MAX_REMOTE_PACKET_SIZE)
-    {
-      warning (_("limiting remote suggested packet size (%d bytes) to %d"),
-              packet_size, MAX_REMOTE_PACKET_SIZE);
-      packet_size = MAX_REMOTE_PACKET_SIZE;
-    }
-
   /* Record the new maximum packet size.  */
   rs->explicit_packet_size = packet_size;
 }
@@ -4255,7 +4347,8 @@ remote_query_supported (void)
       char *q = NULL;
       struct cleanup *old_chain = make_cleanup (free_current_contents, &q);
 
-      q = remote_query_supported_append (q, "multiprocess+");
+      if (packet_set_cmd_state (PACKET_multiprocess_feature) != AUTO_BOOLEAN_FALSE)
+       q = remote_query_supported_append (q, "multiprocess+");
 
       if (packet_set_cmd_state (PACKET_swbreak_feature) != AUTO_BOOLEAN_FALSE)
        q = remote_query_supported_append (q, "swbreak+");
@@ -4497,6 +4590,8 @@ remote_open_1 (const char *name, int from_tty,
   rs->use_threadinfo_query = 1;
   rs->use_threadextra_query = 1;
 
+  readahead_cache_invalidate ();
+
   if (target_async_permitted)
     {
       /* With this target we start out by owning the terminal.  */
@@ -5181,6 +5276,20 @@ async_handle_remote_sigint_twice (int sig)
   gdb_call_async_signal_handler (async_sigint_remote_twice_token, 0);
 }
 
+/* Implementation of to_check_pending_interrupt.  */
+
+static void
+remote_check_pending_interrupt (struct target_ops *self)
+{
+  struct async_signal_handler *token = async_sigint_remote_twice_token;
+
+  if (async_signal_handler_is_marked (token))
+    {
+      clear_async_signal_handler (token);
+      call_async_signal_handler (token);
+    }
+}
+
 /* Perform the real interruption of the target execution, in response
    to a ^C.  */
 static void
@@ -5215,11 +5324,12 @@ async_cleanup_sigint_signal_handler (void *dummy)
    packet.  */
 static void (*ofunc) (int);
 
-/* The command line interface's stop routine.  This function is installed
-   as a signal handler for SIGINT.  The first time a user requests a
-   stop, we call remote_stop to send a break or ^C.  If there is no
+/* The command line interface's interrupt routine.  This function is installed
+   as a signal handler for SIGINT.  The first time a user requests an
+   interrupt, we call remote_interrupt to send a break or ^C.  If there is no
    response from the target (it didn't stop when the user requested it),
    we ask the user if he'd like to detach from the target.  */
+
 static void
 sync_remote_interrupt (int signo)
 {
@@ -5290,12 +5400,12 @@ remote_stop_ns (ptid_t ptid)
     error (_("Stopping %s failed: %s"), target_pid_to_str (ptid), rs->buf);
 }
 
-/* All-stop version of target_stop.  Sends a break or a ^C to stop the
-   remote target.  It is undefined which thread of which process
-   reports the stop.  */
+/* All-stop version of target_interrupt.  Sends a break or a ^C to
+   interrupt the remote target.  It is undefined which thread of which
+   process reports the interrupt.  */
 
 static void
-remote_stop_as (ptid_t ptid)
+remote_interrupt_as (ptid_t ptid)
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -5311,9 +5421,7 @@ remote_stop_as (ptid_t ptid)
   send_interrupt_sequence ();
 }
 
-/* This is the generic stop called via the target vector.  When a target
-   interrupt is requested, either by the command line or the GUI, we
-   will eventually end up here.  */
+/* Implement the to_stop function for the remote targets.  */
 
 static void
 remote_stop (struct target_ops *self, ptid_t ptid)
@@ -5324,32 +5432,59 @@ remote_stop (struct target_ops *self, ptid_t ptid)
   if (non_stop)
     remote_stop_ns (ptid);
   else
-    remote_stop_as (ptid);
+    {
+      /* We don't currently have a way to transparently pause the
+        remote target in all-stop mode.  Interrupt it instead.  */
+      remote_interrupt_as (ptid);
+    }
 }
 
-/* Ask the user what to do when an interrupt is received.  */
+/* Implement the to_interrupt function for the remote targets.  */
 
 static void
-interrupt_query (void)
+remote_interrupt (struct target_ops *self, ptid_t ptid)
 {
-  target_terminal_ours ();
+  if (remote_debug)
+    fprintf_unfiltered (gdb_stdlog, "remote_interrupt called\n");
 
-  if (target_is_async_p ())
+  if (non_stop)
     {
-      signal (SIGINT, handle_sigint);
-      quit ();
+      /* We don't currently have a way to ^C the remote target in
+        non-stop mode.  Stop it (with no signal) instead.  */
+      remote_stop_ns (ptid);
     }
   else
+    remote_interrupt_as (ptid);
+}
+
+/* Ask the user what to do when an interrupt is received.  */
+
+static void
+interrupt_query (void)
+{
+  struct remote_state *rs = get_remote_state ();
+  struct cleanup *old_chain;
+
+  old_chain = make_cleanup_restore_target_terminal ();
+  target_terminal_ours ();
+
+  if (rs->waiting_for_stop_reply && rs->ctrlc_pending_p)
     {
-      if (query (_("Interrupted while waiting for the program.\n\
-Give up (and stop debugging it)? ")))
+      if (query (_("The target is not responding to interrupt requests.\n"
+                  "Stop debugging it? ")))
        {
          remote_unpush_target ();
-         quit ();
+         throw_error (TARGET_CLOSE_ERROR, _("Disconnected from target."));
        }
     }
+  else
+    {
+      if (query (_("Interrupted while waiting for the program.\n"
+                  "Give up waiting? ")))
+       quit ();
+    }
 
-  target_terminal_inferior ();
+  do_cleanups (old_chain);
 }
 
 /* Enable/disable target terminal ownership.  Most targets can use
@@ -5464,6 +5599,14 @@ stop_reply_xfree (struct stop_reply *r)
   notif_event_xfree ((struct notif_event *) r);
 }
 
+/* Return the length of the stop reply queue.  */
+
+static int
+stop_reply_queue_length (void)
+{
+  return QUEUE_length (stop_reply_p, stop_reply_queue);
+}
+
 static void
 remote_notif_stop_parse (struct notif_client *self, char *buf,
                         struct notif_event *event)
@@ -5510,8 +5653,8 @@ stop_reply_dtr (struct notif_event *event)
 static struct notif_event *
 remote_notif_stop_alloc_reply (void)
 {
-  struct notif_event *r
-    = (struct notif_event *) XNEW (struct stop_reply);
+  /* We cast to a pointer to the "base class".  */
+  struct notif_event *r = (struct notif_event *) XNEW (struct stop_reply);
 
   r->dtr = stop_reply_dtr;
 
@@ -5813,6 +5956,18 @@ skip_to_semicolon (char *p)
   return p;
 }
 
+/* Helper for remote_parse_stop_reply.  Return nonzero if the substring
+   starting with P and ending with PEND matches PREFIX.  */
+
+static int
+strprefix (const char *p, const char *pend, const char *prefix)
+{
+  for ( ; p < pend; p++, prefix++)
+    if (*p != *prefix)
+      return 0;
+  return *prefix == '\0';
+}
+
 /* Parse the stop reply in BUF.  Either the function succeeds, and the
    result is stored in EVENT, or throws an error.  */
 
@@ -5864,17 +6019,17 @@ Packet: '%s'\n"),
             the server only sends such a packet if it knows the
             client understands it.  */
 
-         if (strncmp (p, "thread", p1 - p) == 0)
+         if (strprefix (p, p1, "thread"))
            event->ptid = read_ptid (++p1, &p);
-         else if ((strncmp (p, "watch", p1 - p) == 0)
-                  || (strncmp (p, "rwatch", p1 - p) == 0)
-                  || (strncmp (p, "awatch", p1 - p) == 0))
+         else if (strprefix (p, p1, "watch")
+                  || strprefix (p, p1, "rwatch")
+                  || strprefix (p, p1, "awatch"))
            {
              event->stop_reason = TARGET_STOPPED_BY_WATCHPOINT;
              p = unpack_varlen_hex (++p1, &addr);
              event->watch_data_address = (CORE_ADDR) addr;
            }
-         else if (strncmp (p, "swbreak", p1 - p) == 0)
+         else if (strprefix (p, p1, "swbreak"))
            {
              event->stop_reason = TARGET_STOPPED_BY_SW_BREAKPOINT;
 
@@ -5888,7 +6043,7 @@ Packet: '%s'\n"),
                 use of it in a backward compatible way.  */
              p = skip_to_semicolon (p1 + 1);
            }
-         else if (strncmp (p, "hwbreak", p1 - p) == 0)
+         else if (strprefix (p, p1, "hwbreak"))
            {
              event->stop_reason = TARGET_STOPPED_BY_HW_BREAKPOINT;
 
@@ -5900,36 +6055,36 @@ Packet: '%s'\n"),
              /* See above.  */
              p = skip_to_semicolon (p1 + 1);
            }
-         else if (strncmp (p, "library", p1 - p) == 0)
+         else if (strprefix (p, p1, "library"))
            {
              event->ws.kind = TARGET_WAITKIND_LOADED;
              p = skip_to_semicolon (p1 + 1);
            }
-         else if (strncmp (p, "replaylog", p1 - p) == 0)
+         else if (strprefix (p, p1, "replaylog"))
            {
              event->ws.kind = TARGET_WAITKIND_NO_HISTORY;
              /* p1 will indicate "begin" or "end", but it makes
                 no difference for now, so ignore it.  */
              p = skip_to_semicolon (p1 + 1);
            }
-         else if (strncmp (p, "core", p1 - p) == 0)
+         else if (strprefix (p, p1, "core"))
            {
              ULONGEST c;
 
              p = unpack_varlen_hex (++p1, &c);
              event->core = c;
            }
-         else if (strncmp (p, "fork", p1 - p) == 0)
+         else if (strprefix (p, p1, "fork"))
            {
              event->ws.value.related_pid = read_ptid (++p1, &p);
              event->ws.kind = TARGET_WAITKIND_FORKED;
            }
-         else if (strncmp (p, "vfork", p1 - p) == 0)
+         else if (strprefix (p, p1, "vfork"))
            {
              event->ws.value.related_pid = read_ptid (++p1, &p);
              event->ws.kind = TARGET_WAITKIND_VFORKED;
            }
-         else if (strncmp (p, "vforkdone", p1 - p) == 0)
+         else if (strprefix (p, p1, "vforkdone"))
            {
              event->ws.kind = TARGET_WAITKIND_VFORK_DONE;
              p = skip_to_semicolon (p1 + 1);
@@ -7623,7 +7778,8 @@ putpkt_binary (const char *buf, int cnt)
   struct remote_state *rs = get_remote_state ();
   int i;
   unsigned char csum = 0;
-  char *buf2 = alloca (cnt + 6);
+  char *buf2 = xmalloc (cnt + 6);
+  struct cleanup *old_chain = make_cleanup (xfree, buf2);
 
   int ch;
   int tcount = 0;
@@ -7716,6 +7872,7 @@ putpkt_binary (const char *buf, int cnt)
            case '+':
              if (remote_debug)
                fprintf_unfiltered (gdb_stdlog, "Ack\n");
+             do_cleanups (old_chain);
              return 1;
            case '-':
              if (remote_debug)
@@ -7724,7 +7881,10 @@ putpkt_binary (const char *buf, int cnt)
            case SERIAL_TIMEOUT:
              tcount++;
              if (tcount > 3)
-               return 0;
+               {
+                 do_cleanups (old_chain);
+                 return 0;
+               }
              break;            /* Retransmit buffer.  */
            case '$':
              {
@@ -7811,6 +7971,8 @@ putpkt_binary (const char *buf, int cnt)
        }
 #endif
     }
+
+  do_cleanups (old_chain);
   return 0;
 }
 
@@ -10295,6 +10457,27 @@ remote_hostio_send_command (int command_bytes, int which_packet,
   return ret;
 }
 
+/* Invalidate the readahead cache.  */
+
+static void
+readahead_cache_invalidate (void)
+{
+  struct remote_state *rs = get_remote_state ();
+
+  rs->readahead_cache.fd = -1;
+}
+
+/* Invalidate the readahead cache if it is holding data for FD.  */
+
+static void
+readahead_cache_invalidate_fd (int fd)
+{
+  struct remote_state *rs = get_remote_state ();
+
+  if (rs->readahead_cache.fd == fd)
+    rs->readahead_cache.fd = -1;
+}
+
 /* Set the filesystem remote_hostio functions that take FILENAME
    arguments will use.  Return 0 on success, or -1 if an error
    occurs (and set *REMOTE_ERRNO).  */
@@ -10337,12 +10520,29 @@ remote_hostio_set_filesystem (struct inferior *inf, int *remote_errno)
 static int
 remote_hostio_open (struct target_ops *self,
                    struct inferior *inf, const char *filename,
-                   int flags, int mode, int *remote_errno)
+                   int flags, int mode, int warn_if_slow,
+                   int *remote_errno)
 {
   struct remote_state *rs = get_remote_state ();
   char *p = rs->buf;
   int left = get_remote_packet_size () - 1;
 
+  if (warn_if_slow)
+    {
+      static int warning_issued = 0;
+
+      printf_unfiltered (_("Reading %s from remote target...\n"),
+                        filename);
+
+      if (!warning_issued)
+       {
+         warning (_("File transfers from remote targets can be slow."
+                    " Use \"set sysroot\" to access files locally"
+                    " instead."));
+         warning_issued = 1;
+       }
+    }
+
   if (remote_hostio_set_filesystem (inf, remote_errno) != 0)
     return -1;
 
@@ -10373,6 +10573,8 @@ remote_hostio_pwrite (struct target_ops *self,
   int left = get_remote_packet_size ();
   int out_len;
 
+  readahead_cache_invalidate_fd (fd);
+
   remote_buffer_add_string (&p, &left, "vFile:pwrite:");
 
   remote_buffer_add_int (&p, &left, fd);
@@ -10388,12 +10590,13 @@ remote_hostio_pwrite (struct target_ops *self,
                                     remote_errno, NULL, NULL);
 }
 
-/* Implementation of to_fileio_pread.  */
+/* Helper for the implementation of to_fileio_pread.  Read the file
+   from the remote side with vFile:pread.  */
 
 static int
-remote_hostio_pread (struct target_ops *self,
-                    int fd, gdb_byte *read_buf, int len,
-                    ULONGEST offset, int *remote_errno)
+remote_hostio_pread_vFile (struct target_ops *self,
+                          int fd, gdb_byte *read_buf, int len,
+                          ULONGEST offset, int *remote_errno)
 {
   struct remote_state *rs = get_remote_state ();
   char *p = rs->buf;
@@ -10427,6 +10630,76 @@ remote_hostio_pread (struct target_ops *self,
   return ret;
 }
 
+/* Serve pread from the readahead cache.  Returns number of bytes
+   read, or 0 if the request can't be served from the cache.  */
+
+static int
+remote_hostio_pread_from_cache (struct remote_state *rs,
+                               int fd, gdb_byte *read_buf, size_t len,
+                               ULONGEST offset)
+{
+  struct readahead_cache *cache = &rs->readahead_cache;
+
+  if (cache->fd == fd
+      && cache->offset <= offset
+      && offset < cache->offset + cache->bufsize)
+    {
+      ULONGEST max = cache->offset + cache->bufsize;
+
+      if (offset + len > max)
+       len = max - offset;
+
+      memcpy (read_buf, cache->buf + offset - cache->offset, len);
+      return len;
+    }
+
+  return 0;
+}
+
+/* Implementation of to_fileio_pread.  */
+
+static int
+remote_hostio_pread (struct target_ops *self,
+                    int fd, gdb_byte *read_buf, int len,
+                    ULONGEST offset, int *remote_errno)
+{
+  int ret;
+  struct remote_state *rs = get_remote_state ();
+  struct readahead_cache *cache = &rs->readahead_cache;
+
+  ret = remote_hostio_pread_from_cache (rs, fd, read_buf, len, offset);
+  if (ret > 0)
+    {
+      cache->hit_count++;
+
+      if (remote_debug)
+       fprintf_unfiltered (gdb_stdlog, "readahead cache hit %s\n",
+                           pulongest (cache->hit_count));
+      return ret;
+    }
+
+  cache->miss_count++;
+  if (remote_debug)
+    fprintf_unfiltered (gdb_stdlog, "readahead cache miss %s\n",
+                       pulongest (cache->miss_count));
+
+  cache->fd = fd;
+  cache->offset = offset;
+  cache->bufsize = get_remote_packet_size ();
+  cache->buf = xrealloc (cache->buf, cache->bufsize);
+
+  ret = remote_hostio_pread_vFile (self, cache->fd, cache->buf, cache->bufsize,
+                                  cache->offset, remote_errno);
+  if (ret <= 0)
+    {
+      readahead_cache_invalidate_fd (fd);
+      return ret;
+    }
+
+  cache->bufsize = ret;
+  return remote_hostio_pread_from_cache (rs, fd, read_buf, len, offset);
+}
+
 /* Implementation of to_fileio_close.  */
 
 static int
@@ -10436,6 +10709,8 @@ remote_hostio_close (struct target_ops *self, int fd, int *remote_errno)
   char *p = rs->buf;
   int left = get_remote_packet_size () - 1;
 
+  readahead_cache_invalidate_fd (fd);
+
   remote_buffer_add_string (&p, &left, "vFile:close:");
 
   remote_buffer_add_int (&p, &left, fd);
@@ -10591,7 +10866,7 @@ remote_filesystem_is_local (struct target_ops *self)
             filename is irrelevant, we only care about whether
             the stub recognizes the packet or not.  */
          fd = remote_hostio_open (self, NULL, "just probing",
-                                  FILEIO_O_RDONLY, 0700,
+                                  FILEIO_O_RDONLY, 0700, 0,
                                   &remote_errno);
 
          if (fd >= 0)
@@ -10713,7 +10988,7 @@ remote_file_put (const char *local_file, const char *remote_file, int from_tty)
   fd = remote_hostio_open (find_target_at (process_stratum), NULL,
                           remote_file, (FILEIO_O_WRONLY | FILEIO_O_CREAT
                                         | FILEIO_O_TRUNC),
-                          0700, &remote_errno);
+                          0700, 0, &remote_errno);
   if (fd == -1)
     remote_hostio_error (remote_errno);
 
@@ -10797,7 +11072,8 @@ remote_file_get (const char *remote_file, const char *local_file, int from_tty)
     error (_("command can only be used with remote target"));
 
   fd = remote_hostio_open (find_target_at (process_stratum), NULL,
-                          remote_file, FILEIO_O_RDONLY, 0, &remote_errno);
+                          remote_file, FILEIO_O_RDONLY, 0, 0,
+                          &remote_errno);
   if (fd == -1)
     remote_hostio_error (remote_errno);
 
@@ -11221,13 +11497,12 @@ remote_download_tracepoint (struct target_ops *self, struct bp_location *loc)
 
   if (packet_support (PACKET_TracepointSource) == PACKET_ENABLE)
     {
-      if (b->addr_string)
+      if (b->location != NULL)
        {
          strcpy (buf, "QTDPsrc:");
-         encode_source_string (b->number, loc->address,
-                               "at", b->addr_string, buf + strlen (buf),
-                               2048 - strlen (buf));
-
+         encode_source_string (b->number, loc->address, "at",
+                               event_location_to_string (b->location),
+                               buf + strlen (buf), 2048 - strlen (buf));
          putpkt (buf);
          remote_get_noisy_reply (&target_buf, &target_buf_size);
          if (strcmp (target_buf, "OK"))
@@ -12058,7 +12333,7 @@ remote_enable_btrace (struct target_ops *self, ptid_t ptid,
               target_pid_to_str (ptid));
     }
 
-  tinfo = xzalloc (sizeof (*tinfo));
+  tinfo = XCNEW (struct btrace_target_info);
   tinfo->ptid = ptid;
 
   /* If we fail to read the configuration, we lose some information, but the
@@ -12275,6 +12550,8 @@ Specify the serial device it is connected to\n\
   remote_ops.to_extra_thread_info = remote_threads_extra_info;
   remote_ops.to_get_ada_task_ptid = remote_get_ada_task_ptid;
   remote_ops.to_stop = remote_stop;
+  remote_ops.to_interrupt = remote_interrupt;
+  remote_ops.to_check_pending_interrupt = remote_check_pending_interrupt;
   remote_ops.to_xfer_partial = remote_xfer_partial;
   remote_ops.to_rcmd = remote_rcmd;
   remote_ops.to_pid_to_exec_file = remote_pid_to_exec_file;
@@ -12977,6 +13254,9 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
   add_packet_config_cmd (&remote_protocol_packets[PACKET_Qbtrace_conf_bts_size],
        "Qbtrace-conf:bts:size", "btrace-conf-bts-size", 0);
 
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_multiprocess_feature],
+       "multiprocess-feature", "multiprocess-feature", 0);
+
   add_packet_config_cmd (&remote_protocol_packets[PACKET_swbreak_feature],
                          "swbreak-feature", "swbreak-feature", 0);
 
@@ -13006,7 +13286,6 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
        switch (i)
          {
          case PACKET_QNonStop:
-         case PACKET_multiprocess_feature:
          case PACKET_EnableDisableTracepoints_feature:
          case PACKET_tracenz_feature:
          case PACKET_DisconnectedTracing_feature:
This page took 0.047902 seconds and 4 git commands to generate.