remote: Move discard_pending_stop_replies call
[deliverable/binutils-gdb.git] / gdb / remote.c
index 34ae7c6921c214c04d3dc05059563c7e94d6cec9..59880a93a87a5f23a9cfb2713fcbb404744e6b45 100644 (file)
@@ -75,6 +75,7 @@
 #include "common/scoped_restore.h"
 #include "environ.h"
 #include "common/byte-vector.h"
+#include <unordered_map>
 
 /* The remote target.  */
 
@@ -518,8 +519,6 @@ static void remote_btrace_maybe_reopen (void);
 
 static int stop_reply_queue_length (void);
 
-static void readahead_cache_invalidate (void);
-
 static void remote_unpush_and_throw (void);
 
 static struct remote_state *get_remote_state (void);
@@ -541,16 +540,16 @@ static struct cmd_list_element *remote_show_cmdlist;
 struct vCont_action_support
 {
   /* vCont;t */
-  int t;
+  bool t = false;
 
   /* vCont;r */
-  int r;
+  bool r = false;
 
   /* vCont;s */
-  int s;
+  bool s = false;
 
   /* vCont;S */
-  int S;
+  bool S = false;
 };
 
 /* Controls whether GDB is willing to use range stepping.  */
@@ -575,31 +574,89 @@ typedef unsigned char threadref[OPAQUETHREADBYTES];
 
 struct readahead_cache
 {
+  /* Invalidate the readahead cache.  */
+  void invalidate ();
+
+  /* Invalidate the readahead cache if it is holding data for FD.  */
+  void invalidate_fd (int fd);
+
+  /* Serve pread from the readahead cache.  Returns number of bytes
+     read, or 0 if the request can't be served from the cache.  */
+  int pread (int fd, gdb_byte *read_buf, size_t len, ULONGEST offset);
+
   /* The file descriptor for the file that is being cached.  -1 if the
      cache is invalid.  */
-  int fd;
+  int fd = -1;
 
   /* The offset into the file that the cache buffer corresponds
      to.  */
-  ULONGEST offset;
+  ULONGEST offset = 0;
 
   /* The buffer holding the cache contents.  */
-  gdb_byte *buf;
+  gdb_byte *buf = nullptr;
   /* The buffer's size.  We try to read as much as fits into a packet
      at a time.  */
-  size_t bufsize;
+  size_t bufsize = 0;
 
   /* Cache hit and miss counters.  */
-  ULONGEST hit_count;
-  ULONGEST miss_count;
+  ULONGEST hit_count = 0;
+  ULONGEST miss_count = 0;
+};
+
+/* Description of the remote protocol for a given architecture.  */
+
+struct packet_reg
+{
+  long offset; /* Offset into G packet.  */
+  long regnum; /* GDB's internal register number.  */
+  LONGEST pnum; /* Remote protocol register number.  */
+  int in_g_packet; /* Always part of G packet.  */
+  /* long size in bytes;  == register_size (target_gdbarch (), regnum);
+     at present.  */
+  /* char *name; == gdbarch_register_name (target_gdbarch (), regnum);
+     at present.  */
+};
+
+struct remote_arch_state
+{
+  explicit remote_arch_state (struct gdbarch *gdbarch);
+
+  /* Description of the remote protocol registers.  */
+  long sizeof_g_packet;
+
+  /* Description of the remote protocol registers indexed by REGNUM
+     (making an array gdbarch_num_regs in size).  */
+  std::unique_ptr<packet_reg[]> regs;
+
+  /* This is the size (in chars) of the first response to the ``g''
+     packet.  It is used as a heuristic when determining the maximum
+     size of memory-read and memory-write packets.  A target will
+     typically only reserve a buffer large enough to hold the ``g''
+     packet.  The size does not include packet overhead (headers and
+     trailers).  */
+  long actual_register_packet_size;
+
+  /* This is the maximum size (in chars) of a non read/write packet.
+     It is also used as a cap on the size of read/write packets.  */
+  long remote_packet_size;
 };
 
 /* Description of the remote protocol state for the currently
    connected target.  This is per-target state, and independent of the
    selected architecture.  */
 
-struct remote_state
+class remote_state
 {
+public:
+
+  remote_state ();
+  ~remote_state ();
+
+  /* Get the remote arch state for GDBARCH.  */
+  struct remote_arch_state *get_remote_arch_state (struct gdbarch *gdbarch);
+
+public: /* data */
+
   /* A buffer to use for incoming packets, and its current size.  The
      buffer is grown dynamically for larger incoming packets.
      Outgoing packets may also be constructed in this buffer.
@@ -611,13 +668,13 @@ struct remote_state
 
   /* True if we're going through initial connection setup (finding out
      about the remote side's threads, relocating symbols, etc.).  */
-  int starting_up;
+  bool starting_up = false;
 
   /* If we negotiated packet size explicitly (and thus can bypass
      heuristics for the largest packet size that will not overflow
      a buffer in the stub), this will be set to that packet size.
      Otherwise zero, meaning to use the guessed size.  */
-  long explicit_packet_size;
+  long explicit_packet_size = 0;
 
   /* remote_wait is normally called when the target is running and
      waits for a stop reply packet.  But sometimes we need to call it
@@ -626,15 +683,15 @@ struct remote_state
      the response, we can stash it in BUF and tell remote_wait to
      skip calling getpkt.  This flag is set when BUF contains a
      stop reply packet and the target is not waiting.  */
-  int cached_wait_status;
+  int cached_wait_status = 0;
 
   /* True, if in no ack mode.  That is, neither GDB nor the stub will
      expect acks from each other.  The connection is assumed to be
      reliable.  */
-  int noack_mode;
+  bool noack_mode = false;
 
   /* True if we're connected in extended remote mode.  */
-  int extended;
+  bool extended = false;
 
   /* True if we resumed the target and we're waiting for the target to
      stop.  In the mean time, we can't start another command/query.
@@ -642,14 +699,14 @@ struct remote_state
      timeout waiting for a reply that would never come and eventually
      we'd close the connection.  This can happen in asynchronous mode
      because we allow GDB commands while the target is running.  */
-  int waiting_for_stop_reply;
+  bool waiting_for_stop_reply = false;
 
   /* The status of the stub support for the various vCont actions.  */
-  struct vCont_action_support supports_vCont;
+  vCont_action_support supports_vCont;
 
-  /* Nonzero if the user has pressed Ctrl-C, but the target hasn't
+  /* True if the user has pressed Ctrl-C, but the target hasn't
      responded to that.  */
-  int ctrlc_pending_p;
+  bool ctrlc_pending_p = false;
 
   /* True if we saw a Ctrl-C while reading or writing from/to the
      remote descriptor.  At that point it is not safe to send a remote
@@ -657,40 +714,40 @@ struct remote_state
      process it once we're done with sending/receiving the current
      packet, which should be shortly.  If however that takes too long,
      and the user presses Ctrl-C again, we offer to disconnect.  */
-  int got_ctrlc_during_io;
+  bool got_ctrlc_during_io = false;
 
   /* Descriptor for I/O to remote machine.  Initialize it to NULL so that
      remote_open knows that we don't have a file open when the program
      starts.  */
-  struct serial *remote_desc;
+  struct serial *remote_desc = nullptr;
 
   /* These are the threads which we last sent to the remote system.  The
      TID member will be -1 for all or -2 for not sent yet.  */
-  ptid_t general_thread;
-  ptid_t continue_thread;
+  ptid_t general_thread = null_ptid;
+  ptid_t continue_thread = null_ptid;
 
   /* This is the traceframe which we last selected on the remote system.
      It will be -1 if no traceframe is selected.  */
-  int remote_traceframe_number;
+  int remote_traceframe_number = -1;
 
-  char *last_pass_packet;
+  char *last_pass_packet = nullptr;
 
   /* The last QProgramSignals packet sent to the target.  We bypass
      sending a new program signals list down to the target if the new
      packet is exactly the same as the last we sent.  IOW, we only let
      the target know about program signals list changes.  */
-  char *last_program_signals_packet;
+  char *last_program_signals_packet = nullptr;
 
-  enum gdb_signal last_sent_signal;
+  gdb_signal last_sent_signal = GDB_SIGNAL_0;
 
-  int last_sent_step;
+  bool last_sent_step = false;
 
   /* The execution direction of the last resume we got.  */
-  enum exec_direction_kind last_resume_exec_dir;
+  exec_direction_kind last_resume_exec_dir = EXEC_FORWARD;
 
-  char *finished_object;
-  char *finished_annex;
-  ULONGEST finished_offset;
+  char *finished_object = nullptr;
+  char *finished_annex = nullptr;
+  ULONGEST finished_offset = 0;
 
   /* Should we try the 'ThreadInfo' query packet?
 
@@ -699,24 +756,24 @@ struct remote_state
      query or the older, more complex syntax for thread queries.
      This is an auto-detect variable (set to true at each connect,
      and set to false when the target fails to recognize it).  */
-  int use_threadinfo_query;
-  int use_threadextra_query;
+  bool use_threadinfo_query = false;
+  bool use_threadextra_query = false;
 
-  threadref echo_nextthread;
-  threadref nextthread;
-  threadref resultthreadlist[MAXTHREADLISTRESULTS];
+  threadref echo_nextthread {};
+  threadref nextthread {};
+  threadref resultthreadlist[MAXTHREADLISTRESULTS] {};
 
   /* The state of remote notification.  */
-  struct remote_notif_state *notif_state;
+  struct remote_notif_state *notif_state = nullptr;
 
   /* The branch trace configuration.  */
-  struct btrace_config btrace_config;
+  struct btrace_config btrace_config {};
 
   /* The argument to the last "vFile:setfs:" packet we sent, used
      to avoid sending repeated unnecessary "vFile:setfs:" packets.
      Initialized to -1 to indicate that no "vFile:setfs:" packet
      has yet been sent.  */
-  int fs_pid;
+  int fs_pid = -1;
 
   /* A readahead cache for vFile:pread.  Often, reading a binary
      involves a sequence of small reads.  E.g., when parsing an ELF
@@ -725,6 +782,13 @@ struct remote_state
      request/reply nature of the RSP.  We only cache data for a single
      file descriptor at a time.  */
   struct readahead_cache readahead_cache;
+
+private:
+  /* Mapping of remote protocol data for each gdbarch.  Usually there
+     is only one entry here, though we may see more with stubs that
+     support multi-process.  */
+  std::unordered_map<struct gdbarch *, remote_arch_state>
+    m_arch_states;
 };
 
 /* Private data that we'll store in (struct thread_info)->priv.  */
@@ -764,6 +828,23 @@ struct remote_thread_info : public private_thread_info
   int vcont_resumed = 0;
 };
 
+remote_state::remote_state ()
+{
+  /* The default buffer size is unimportant; it will be expanded
+     whenever a larger buffer is needed. */
+  this->buf_size = 400;
+  this->buf = (char *) xmalloc (this->buf_size);
+}
+
+remote_state::~remote_state ()
+{
+  xfree (this->last_pass_packet);
+  xfree (this->last_program_signals_packet);
+  xfree (this->buf);
+  xfree (this->finished_object);
+  xfree (this->finished_annex);
+}
+
 /* This data could be associated with a target, but we do not always
    have access to the current target when we need it, so for now it is
    static.  This will be fine for as long as only one target is in use
@@ -776,62 +857,6 @@ get_remote_state_raw (void)
   return remote_state;
 }
 
-/* Allocate a new struct remote_state with xmalloc, initialize it, and
-   return it.  */
-
-static struct remote_state *
-new_remote_state (void)
-{
-  struct remote_state *result = XCNEW (struct remote_state);
-
-  /* The default buffer size is unimportant; it will be expanded
-     whenever a larger buffer is needed. */
-  result->buf_size = 400;
-  result->buf = (char *) xmalloc (result->buf_size);
-  result->remote_traceframe_number = -1;
-  result->last_sent_signal = GDB_SIGNAL_0;
-  result->last_resume_exec_dir = EXEC_FORWARD;
-  result->fs_pid = -1;
-
-  return result;
-}
-
-/* Description of the remote protocol for a given architecture.  */
-
-struct packet_reg
-{
-  long offset; /* Offset into G packet.  */
-  long regnum; /* GDB's internal register number.  */
-  LONGEST pnum; /* Remote protocol register number.  */
-  int in_g_packet; /* Always part of G packet.  */
-  /* long size in bytes;  == register_size (target_gdbarch (), regnum);
-     at present.  */
-  /* char *name; == gdbarch_register_name (target_gdbarch (), regnum);
-     at present.  */
-};
-
-struct remote_arch_state
-{
-  /* Description of the remote protocol registers.  */
-  long sizeof_g_packet;
-
-  /* Description of the remote protocol registers indexed by REGNUM
-     (making an array gdbarch_num_regs in size).  */
-  struct packet_reg *regs;
-
-  /* This is the size (in chars) of the first response to the ``g''
-     packet.  It is used as a heuristic when determining the maximum
-     size of memory-read and memory-write packets.  A target will
-     typically only reserve a buffer large enough to hold the ``g''
-     packet.  The size does not include packet overhead (headers and
-     trailers).  */
-  long actual_register_packet_size;
-
-  /* This is the maximum size (in chars) of a non read/write packet.
-     It is also used as a cap on the size of read/write packets.  */
-  long remote_packet_size;
-};
-
 /* Utility: generate error from an incoming stub packet.  */
 static void
 trace_error (char *buf)
@@ -929,15 +954,31 @@ remote_get_noisy_reply ()
   while (1);
 }
 
-/* Handle for retreving the remote protocol data from gdbarch.  */
-static struct gdbarch_data *remote_gdbarch_data_handle;
-
-static struct remote_arch_state *
-get_remote_arch_state (struct gdbarch *gdbarch)
+struct remote_arch_state *
+remote_state::get_remote_arch_state (struct gdbarch *gdbarch)
 {
-  gdb_assert (gdbarch != NULL);
-  return ((struct remote_arch_state *)
-         gdbarch_data (gdbarch, remote_gdbarch_data_handle));
+  remote_arch_state *rsa;
+
+  auto it = this->m_arch_states.find (gdbarch);
+  if (it == this->m_arch_states.end ())
+    {
+      auto p = this->m_arch_states.emplace (std::piecewise_construct,
+                                           std::forward_as_tuple (gdbarch),
+                                           std::forward_as_tuple (gdbarch));
+      rsa = &p.first->second;
+
+      /* Make sure that the packet buffer is plenty big enough for
+        this architecture.  */
+      if (this->buf_size < rsa->remote_packet_size)
+       {
+         this->buf_size = 2 * rsa->remote_packet_size;
+         this->buf = (char *) xrealloc (this->buf, this->buf_size);
+       }
+    }
+  else
+    rsa = &it->second;
+
+  return rsa;
 }
 
 /* Fetch the global remote target state.  */
@@ -945,14 +986,16 @@ get_remote_arch_state (struct gdbarch *gdbarch)
 static struct remote_state *
 get_remote_state (void)
 {
+  struct remote_state *rs = get_remote_state_raw ();
+
   /* Make sure that the remote architecture state has been
      initialized, because doing so might reallocate rs->buf.  Any
      function which calls getpkt also needs to be mindful of changes
      to rs->buf, but this call limits the number of places which run
      into trouble.  */
-  get_remote_arch_state (target_gdbarch ());
+  rs->get_remote_arch_state (target_gdbarch ());
 
-  return get_remote_state_raw ();
+  return rs;
 }
 
 /* Cleanup routine for the remote module's pspace data.  */
@@ -1094,23 +1137,16 @@ remote_register_number_and_offset (struct gdbarch *gdbarch, int regnum,
   return *pnum != -1;
 }
 
-static void *
-init_remote_state (struct gdbarch *gdbarch)
+remote_arch_state::remote_arch_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);
+  this->regs.reset (new packet_reg [gdbarch_num_regs (gdbarch)] ());
 
   /* Record the maximum possible size of the g packet - it may turn out
      to be smaller.  */
-  rsa->sizeof_g_packet = map_regcache_remote_table (gdbarch, rsa->regs);
+  this->sizeof_g_packet
+    = map_regcache_remote_table (gdbarch, this->regs.get ());
 
   /* Default maximum number of characters in a packet body.  Many
      remote stubs have a hardwired buffer size of 400 bytes
@@ -1119,10 +1155,10 @@ init_remote_state (struct gdbarch *gdbarch)
      NUL character can always fit in the buffer.  This stops GDB
      trashing stubs that try to squeeze an extra NUL into what is
      already a full buffer (As of 1999-12-04 that was most stubs).  */
-  rsa->remote_packet_size = 400 - 1;
+  this->remote_packet_size = 400 - 1;
 
   /* This one is filled in when a ``g'' packet is received.  */
-  rsa->actual_register_packet_size = 0;
+  this->actual_register_packet_size = 0;
 
   /* Should rsa->sizeof_g_packet needs more space than the
      default, adjust the size accordingly.  Remember that each byte is
@@ -1130,18 +1166,8 @@ init_remote_state (struct gdbarch *gdbarch)
      header / footer.  NOTE: cagney/1999-10-26: I suspect that 8
      (``$NN:G...#NN'') is a better guess, the below has been padded a
      little.  */
-  if (rsa->sizeof_g_packet > ((rsa->remote_packet_size - 32) / 2))
-    rsa->remote_packet_size = (rsa->sizeof_g_packet * 2 + 32);
-
-  /* Make sure that the packet buffer is plenty big enough for
-     this architecture.  */
-  if (rs->buf_size < rsa->remote_packet_size)
-    {
-      rs->buf_size = 2 * rsa->remote_packet_size;
-      rs->buf = (char *) xrealloc (rs->buf, rs->buf_size);
-    }
-
-  return rsa;
+  if (this->sizeof_g_packet > ((this->remote_packet_size - 32) / 2))
+    this->remote_packet_size = (this->sizeof_g_packet * 2 + 32);
 }
 
 /* Return the current allowed size of a remote packet.  This is
@@ -1151,7 +1177,7 @@ static long
 get_remote_packet_size (void)
 {
   struct remote_state *rs = get_remote_state ();
-  remote_arch_state *rsa = get_remote_arch_state (target_gdbarch ());
+  remote_arch_state *rsa = rs->get_remote_arch_state (target_gdbarch ());
 
   if (rs->explicit_packet_size)
     return rs->explicit_packet_size;
@@ -1319,7 +1345,7 @@ static long
 get_memory_packet_size (struct memory_packet_config *config)
 {
   struct remote_state *rs = get_remote_state ();
-  remote_arch_state *rsa = get_remote_arch_state (target_gdbarch ());
+  remote_arch_state *rsa = rs->get_remote_arch_state (target_gdbarch ());
 
   long what_they_get;
   if (config->fixed_p)
@@ -5302,7 +5328,7 @@ remote_target::open_1 (const char *name, int from_tty, int extended_p)
   rs->use_threadinfo_query = 1;
   rs->use_threadextra_query = 1;
 
-  readahead_cache_invalidate ();
+  rs->readahead_cache.invalidate ();
 
   if (target_async_permitted)
     {
@@ -7241,7 +7267,7 @@ Packet: '%s'\n"),
                        }
 
                      event->arch = inf->gdbarch;
-                     rsa = get_remote_arch_state (event->arch);
+                     rsa = event->rs->get_remote_arch_state (event->arch);
                    }
 
                  packet_reg *reg
@@ -7675,7 +7701,7 @@ remote_wait_as (ptid_t ptid, struct target_waitstatus *status, int options)
          putpkt (buf);
          break;
        }
-      /* else fallthrough */
+      /* fallthrough */
     default:
       warning (_("Invalid remote reply: %s"), buf);
       break;
@@ -7835,7 +7861,7 @@ process_g_packet (struct regcache *regcache)
 {
   struct gdbarch *gdbarch = regcache->arch ();
   struct remote_state *rs = get_remote_state ();
-  remote_arch_state *rsa = get_remote_arch_state (gdbarch);
+  remote_arch_state *rsa = rs->get_remote_arch_state (gdbarch);
   int i, buf_len;
   char *p;
   char *regs;
@@ -7969,7 +7995,8 @@ void
 remote_target::fetch_registers (struct regcache *regcache, int regnum)
 {
   struct gdbarch *gdbarch = regcache->arch ();
-  remote_arch_state *rsa = get_remote_arch_state (gdbarch);
+  struct remote_state *rs = get_remote_state ();
+  remote_arch_state *rsa = rs->get_remote_arch_state (gdbarch);
   int i;
 
   set_remote_traceframe ();
@@ -8019,7 +8046,8 @@ remote_target::fetch_registers (struct regcache *regcache, int regnum)
 void
 remote_target::prepare_to_store (struct regcache *regcache)
 {
-  remote_arch_state *rsa = get_remote_arch_state (regcache->arch ());
+  struct remote_state *rs = get_remote_state ();
+  remote_arch_state *rsa = rs->get_remote_arch_state (regcache->arch ());
   int i;
 
   /* Make sure the entire registers array is valid.  */
@@ -8085,7 +8113,7 @@ static void
 store_registers_using_G (const struct regcache *regcache)
 {
   struct remote_state *rs = get_remote_state ();
-  remote_arch_state *rsa = get_remote_arch_state (regcache->arch ());
+  remote_arch_state *rsa = rs->get_remote_arch_state (regcache->arch ());
   gdb_byte *regs;
   char *p;
 
@@ -8124,7 +8152,8 @@ void
 remote_target::store_registers (struct regcache *regcache, int regnum)
 {
   struct gdbarch *gdbarch = regcache->arch ();
-  remote_arch_state *rsa = get_remote_arch_state (gdbarch);
+  struct remote_state *rs = get_remote_state ();
+  remote_arch_state *rsa = rs->get_remote_arch_state (gdbarch);
   int i;
 
   set_remote_traceframe ();
@@ -9642,6 +9671,10 @@ remote_target::mourn_inferior ()
 {
   struct remote_state *rs = get_remote_state ();
 
+  /* We're no longer interested in notification events of an inferior
+     that exited or was killed/detached.  */
+  discard_pending_stop_replies (current_inferior ());
+
   /* In 'target remote' mode with one inferior, we close the connection.  */
   if (!rs->extended && number_of_live_inferiors () <= 1)
     {
@@ -10487,9 +10520,6 @@ compare_sections_command (const char *args, int from_tty)
   if (!exec_bfd)
     error (_("command cannot be used without an exec file"));
 
-  /* Make sure the remote is pointing at the right process.  */
-  set_general_process ();
-
   if (args != NULL && strcmp (args, "-r") == 0)
     {
       read_only = 1;
@@ -11671,25 +11701,21 @@ remote_hostio_send_command (int command_bytes, int which_packet,
   return ret;
 }
 
-/* Invalidate the readahead cache.  */
+/* See declaration.h.  */
 
-static void
-readahead_cache_invalidate (void)
+void
+readahead_cache::invalidate ()
 {
-  struct remote_state *rs = get_remote_state ();
-
-  rs->readahead_cache.fd = -1;
+  this->fd = -1;
 }
 
-/* Invalidate the readahead cache if it is holding data for FD.  */
+/* See declaration.h.  */
 
-static void
-readahead_cache_invalidate_fd (int fd)
+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;
+  if (this->fd == fd)
+    this->fd = -1;
 }
 
 /* Set the filesystem remote_hostio functions that take FILENAME
@@ -11796,7 +11822,7 @@ remote_hostio_pwrite (struct target_ops *self,
   int left = get_remote_packet_size ();
   int out_len;
 
-  readahead_cache_invalidate_fd (fd);
+  rs->readahead_cache.invalidate_fd (fd);
 
   remote_buffer_add_string (&p, &left, "vFile:pwrite:");
 
@@ -11860,26 +11886,22 @@ remote_hostio_pread_vFile (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.  */
+/* See declaration.h.  */
 
-static int
-remote_hostio_pread_from_cache (struct remote_state *rs,
-                               int fd, gdb_byte *read_buf, size_t len,
-                               ULONGEST offset)
+int
+readahead_cache::pread (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)
+  if (this->fd == fd
+      && this->offset <= offset
+      && offset < this->offset + this->bufsize)
     {
-      ULONGEST max = cache->offset + cache->bufsize;
+      ULONGEST max = this->offset + this->bufsize;
 
       if (offset + len > max)
        len = max - offset;
 
-      memcpy (read_buf, cache->buf + offset - cache->offset, len);
+      memcpy (read_buf, this->buf + offset - this->offset, len);
       return len;
     }
 
@@ -11895,9 +11917,9 @@ remote_hostio_pread (struct target_ops *self,
 {
   int ret;
   struct remote_state *rs = get_remote_state ();
-  struct readahead_cache *cache = &rs->readahead_cache;
+  readahead_cache *cache = &rs->readahead_cache;
 
-  ret = remote_hostio_pread_from_cache (rs, fd, read_buf, len, offset);
+  ret = cache->pread (fd, read_buf, len, offset);
   if (ret > 0)
     {
       cache->hit_count++;
@@ -11922,12 +11944,12 @@ remote_hostio_pread (struct target_ops *self,
                                   cache->offset, remote_errno);
   if (ret <= 0)
     {
-      readahead_cache_invalidate_fd (fd);
+      cache->invalidate_fd (fd);
       return ret;
     }
 
   cache->bufsize = ret;
-  return remote_hostio_pread_from_cache (rs, fd, read_buf, len, offset);
+  return cache->pread (fd, read_buf, len, offset);
 }
 
 int
@@ -11946,7 +11968,7 @@ 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);
+  rs->readahead_cache.invalidate_fd (fd);
 
   remote_buffer_add_string (&p, &left, "vFile:close:");
 
@@ -12201,20 +12223,61 @@ remote_hostio_error (int errnum)
     error (_("Remote I/O error: %s"), safe_strerror (host_error));
 }
 
-static void
-remote_hostio_close_cleanup (void *opaque)
+/* A RAII wrapper around a remote file descriptor.  */
+
+class scoped_remote_fd
 {
-  int fd = *(int *) opaque;
-  int remote_errno;
+public:
+  explicit scoped_remote_fd (int fd)
+    : m_fd (fd)
+  {
+  }
 
-  remote_hostio_close (find_target_at (process_stratum), fd, &remote_errno);
-}
+  ~scoped_remote_fd ()
+  {
+    if (m_fd != -1)
+      {
+       try
+         {
+           int remote_errno;
+           remote_hostio_close (find_target_at (process_stratum),
+                                m_fd, &remote_errno);
+         }
+       catch (...)
+         {
+           /* Swallow exception before it escapes the dtor.  If
+              something goes wrong, likely the connection is gone,
+              and there's nothing else that can be done.  */
+         }
+      }
+  }
+
+  DISABLE_COPY_AND_ASSIGN (scoped_remote_fd);
+
+  /* Release ownership of the file descriptor, and return it.  */
+  int release () noexcept
+  {
+    int fd = m_fd;
+    m_fd = -1;
+    return fd;
+  }
+
+  /* Return the owned file descriptor.  */
+  int get () const noexcept
+  {
+    return m_fd;
+  }
+
+private:
+  /* The owned remote I/O file descriptor.  */
+  int m_fd;
+};
 
 void
 remote_file_put (const char *local_file, const char *remote_file, int from_tty)
 {
-  struct cleanup *back_to, *close_cleanup;
-  int retcode, fd, remote_errno, bytes, io_size;
+  struct cleanup *back_to;
+  int retcode, remote_errno, bytes, io_size;
   gdb_byte *buffer;
   int bytes_in_buffer;
   int saw_eof;
@@ -12228,11 +12291,12 @@ remote_file_put (const char *local_file, const char *remote_file, int from_tty)
   if (file == NULL)
     perror_with_name (local_file);
 
-  fd = remote_hostio_open (find_target_at (process_stratum), NULL,
-                          remote_file, (FILEIO_O_WRONLY | FILEIO_O_CREAT
-                                        | FILEIO_O_TRUNC),
-                          0700, 0, &remote_errno);
-  if (fd == -1)
+  scoped_remote_fd fd
+    (remote_hostio_open (find_target_at (process_stratum), NULL,
+                        remote_file, (FILEIO_O_WRONLY | FILEIO_O_CREAT
+                                      | FILEIO_O_TRUNC),
+                        0700, 0, &remote_errno));
+  if (fd.get () == -1)
     remote_hostio_error (remote_errno);
 
   /* Send up to this many bytes at once.  They won't all fit in the
@@ -12241,8 +12305,6 @@ remote_file_put (const char *local_file, const char *remote_file, int from_tty)
   buffer = (gdb_byte *) xmalloc (io_size);
   back_to = make_cleanup (xfree, buffer);
 
-  close_cleanup = make_cleanup (remote_hostio_close_cleanup, &fd);
-
   bytes_in_buffer = 0;
   saw_eof = 0;
   offset = 0;
@@ -12274,7 +12336,7 @@ remote_file_put (const char *local_file, const char *remote_file, int from_tty)
       bytes_in_buffer = 0;
 
       retcode = remote_hostio_pwrite (find_target_at (process_stratum),
-                                     fd, buffer, bytes,
+                                     fd.get (), buffer, bytes,
                                      offset, &remote_errno);
 
       if (retcode < 0)
@@ -12292,8 +12354,8 @@ remote_file_put (const char *local_file, const char *remote_file, int from_tty)
       offset += retcode;
     }
 
-  discard_cleanups (close_cleanup);
-  if (remote_hostio_close (find_target_at (process_stratum), fd, &remote_errno))
+  if (remote_hostio_close (find_target_at (process_stratum),
+                          fd.release (), &remote_errno))
     remote_hostio_error (remote_errno);
 
   if (from_tty)
@@ -12304,8 +12366,8 @@ remote_file_put (const char *local_file, const char *remote_file, int from_tty)
 void
 remote_file_get (const char *remote_file, const char *local_file, int from_tty)
 {
-  struct cleanup *back_to, *close_cleanup;
-  int fd, remote_errno, bytes, io_size;
+  struct cleanup *back_to;
+  int remote_errno, bytes, io_size;
   gdb_byte *buffer;
   ULONGEST offset;
   struct remote_state *rs = get_remote_state ();
@@ -12313,10 +12375,11 @@ remote_file_get (const char *remote_file, const char *local_file, int from_tty)
   if (!rs->remote_desc)
     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, 0,
-                          &remote_errno);
-  if (fd == -1)
+  scoped_remote_fd fd
+    (remote_hostio_open (find_target_at (process_stratum), NULL,
+                        remote_file, FILEIO_O_RDONLY, 0, 0,
+                        &remote_errno));
+  if (fd.get () == -1)
     remote_hostio_error (remote_errno);
 
   gdb_file_up file = gdb_fopen_cloexec (local_file, "wb");
@@ -12329,13 +12392,12 @@ remote_file_get (const char *remote_file, const char *local_file, int from_tty)
   buffer = (gdb_byte *) xmalloc (io_size);
   back_to = make_cleanup (xfree, buffer);
 
-  close_cleanup = make_cleanup (remote_hostio_close_cleanup, &fd);
-
   offset = 0;
   while (1)
     {
       bytes = remote_hostio_pread (find_target_at (process_stratum),
-                                  fd, buffer, io_size, offset, &remote_errno);
+                                  fd.get (), buffer, io_size, offset,
+                                  &remote_errno);
       if (bytes == 0)
        /* Success, but no bytes, means end-of-file.  */
        break;
@@ -12349,8 +12411,8 @@ remote_file_get (const char *remote_file, const char *local_file, int from_tty)
        perror_with_name (local_file);
     }
 
-  discard_cleanups (close_cleanup);
-  if (remote_hostio_close (find_target_at (process_stratum), fd, &remote_errno))
+  if (remote_hostio_close (find_target_at (process_stratum),
+                          fd.release (), &remote_errno))
     remote_hostio_error (remote_errno);
 
   if (from_tty)
@@ -12878,7 +12940,7 @@ remote_target::get_trace_status (struct trace_status *ts)
     return -1;
 
   trace_regblock_size
-    = get_remote_arch_state (target_gdbarch ())->sizeof_g_packet;
+    = rs->get_remote_arch_state (target_gdbarch ())->sizeof_g_packet;
 
   putpkt ("qTStatus");
 
@@ -13998,8 +14060,6 @@ _initialize_remote (void)
   const char *cmd_name;
 
   /* architecture specific data */
-  remote_gdbarch_data_handle =
-    gdbarch_data_register_post_init (init_remote_state);
   remote_g_packet_data_handle =
     gdbarch_data_register_pre_init (remote_g_packet_data_init);
 
@@ -14010,16 +14070,13 @@ _initialize_remote (void)
   /* Initialize the per-target state.  At the moment there is only one
      of these, not one per target.  Only one target is active at a
      time.  */
-  remote_state = new_remote_state ();
+  remote_state = new struct remote_state ();
 
   add_target (remote_target_info, remote_target::open);
   add_target (extended_remote_target_info, extended_remote_target::open);
 
   /* Hook into new objfile notification.  */
   gdb::observers::new_objfile.attach (remote_new_objfile);
-  /* We're no longer interested in notification events of an inferior
-     when it exits.  */
-  gdb::observers::inferior_exit.attach (discard_pending_stop_replies);
 
 #if 0
   init_remote_threadtests ();
This page took 0.073251 seconds and 4 git commands to generate.