public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Pedro Alves <palves@redhat.com>
To: gdb-patches@sourceware.org
Subject: [PATCH 04/10] remote: multiple remote_arch_state instances per arch
Date: Wed, 16 May 2018 14:27:00 -0000	[thread overview]
Message-ID: <20180516141830.16859-5-palves@redhat.com> (raw)
In-Reply-To: <20180516141830.16859-1-palves@redhat.com>

Currently, we associate gdbarch-related remote protocol state on a
per-gdbarch data object.  Things like the size of the g/G packet, and
the max remote packet size.  If we'll support being connected to
different remote servers at the same time, then we need to cope with
each having their own packet sizes, even if they are each debugging
programs of the same architecture.  I.e., a single instance of
remote_arch_state per arch is not sufficient.

This patch moves the remote_arch_state object to a map of
gdbarch-to-remote_arch_state saved in the remote_state structure.
Usually there will only be one entry in the map, though we may see
more with stubs that support multi-process and/or archs with multiple
ABIs (e.g, one remote_arch_state for 64-bit inferiors and another for
32-bit inferiors).

gdb/ChangeLog:
yyyy-mm-dd  Pedro Alves  <palves@redhat.com>

	* remote.c: Include <unordered_map>.
	(remote_state): Now a class.
	(remote_state) <get_remote_arch_state>: Declare method.
	<get_remote_arch_state>: New field.
	(remote_arch_state) <remote_arch_state>: Declare ctor.
	<regs>: Now a unique_ptr.
	(remote_gdbarch_data_handle): Delete.
	(get_remote_arch_state): Delete.
	(remote_state::get_remote_arch_state): New.
	(get_remote_state): Adjust to call remote_state's
	get_remote_arch_state method.
	(init_remote_state): Delete, bits factored out to ...
	(remote_arch_state::remote_arch_state): ... this new method.
	(get_remote_packet_size, get_memory_packet_size)
	(process_g_packet, remote_target::fetch_registers)
	(remote_target::prepare_to_store, store_registers_using_G)
	(remote_target::store_registers, remote_target::get_trace_status):
	Adjust to call remote_state's method.
	(_initialize_remote): Remove reference to
	remote_gdbarch_data_handle.
---
 gdb/remote.c | 108 +++++++++++++++++++++++++++++++++--------------------------
 1 file changed, 60 insertions(+), 48 deletions(-)

diff --git a/gdb/remote.c b/gdb/remote.c
index a416d9285b..7903cb6344 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -75,6 +75,7 @@
 #include "common/scoped_restore.h"
 #include "environ.h"
 #include "common/byte-vector.h"
+#include <unordered_map>
 
 /* The remote target.  */
 
@@ -606,11 +607,18 @@ struct readahead_cache
    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.
@@ -736,6 +744,14 @@ 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 *,
+		     std::unique_ptr<struct remote_arch_state>>
+    m_arch_states;
 };
 
 /* Private data that we'll store in (struct thread_info)->priv.  */
@@ -817,12 +833,14 @@ struct packet_reg
 
 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).  */
-  struct packet_reg *regs;
+  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
@@ -934,15 +952,23 @@ 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));
+  auto &rsa = this->m_arch_states[gdbarch];
+  if (rsa == nullptr)
+    {
+      rsa.reset (new remote_arch_state (gdbarch));
+
+      /* 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);
+	}
+    }
+  return rsa.get ();
 }
 
 /* Fetch the global remote target state.  */
@@ -950,14 +976,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.  */
@@ -1099,23 +1127,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
@@ -1124,10 +1145,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
@@ -1135,18 +1156,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
@@ -1156,7 +1167,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;
@@ -1324,7 +1335,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)
@@ -7246,7 +7257,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
@@ -7840,7 +7851,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;
@@ -7974,7 +7985,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 ();
@@ -8024,7 +8036,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.  */
@@ -8090,7 +8103,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;
 
@@ -8129,7 +8142,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 ();
@@ -12906,7 +12920,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");
 
@@ -14026,8 +14040,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);
 
-- 
2.14.3

  parent reply	other threads:[~2018-05-16 14:25 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-05-16 14:18 [PATCH 00/10] remote: More multi-target preparation Pedro Alves
2018-05-16 14:18 ` [PATCH 09/10] remote: Make vcont_builder a class Pedro Alves
2018-05-22  5:07   ` Simon Marchi
2018-05-22 21:33     ` Pedro Alves
2018-05-16 14:18 ` [PATCH 01/10] remote: struct remote_state, use op new Pedro Alves
2018-05-18 20:57   ` Simon Marchi
2018-05-21 15:36     ` [PATCH 1.2 01/10] remote: struct remote_state, use op new, fix leaks Pedro Alves
2018-05-16 14:18 ` [PATCH 02/10] remote: Eliminate remote_hostio_close_cleanup Pedro Alves
2018-05-16 17:43   ` Tom Tromey
2018-05-16 18:53     ` Pedro Alves
2018-05-16 19:46       ` Tom Tromey
2018-05-18 21:04   ` Simon Marchi
2018-05-16 14:18 ` [PATCH 10/10] remote: one struct remote_state per struct remote_target Pedro Alves
2018-05-22  5:07   ` Simon Marchi
2018-05-22 21:06     ` Pedro Alves
2018-05-24 17:00       ` [PATCH 11/10] remote_target::m_remote_state, pointer -> object (Re: [PATCH 10/10] remote: one struct remote_state per struct remote_target) Pedro Alves
2018-05-25  5:23         ` Simon Marchi
2018-05-16 14:25 ` [PATCH 05/10] remote: remote_arch_state pointers -> remote_arch_state objects Pedro Alves
2018-05-18 21:17   ` Simon Marchi
2018-05-18 21:18     ` Simon Marchi
2018-05-21 16:12       ` Pedro Alves
2018-05-16 14:25 ` [PATCH 03/10] remote: Make readahead_cache a C++ class Pedro Alves
2018-05-18 21:06   ` Simon Marchi
2018-05-16 14:27 ` Pedro Alves [this message]
2018-05-18 21:09   ` [PATCH 04/10] remote: multiple remote_arch_state instances per arch Simon Marchi
2018-05-16 14:28 ` [PATCH 08/10] Handle "show remote memory-write-packet-size" when not connected Pedro Alves
2018-05-18 21:42   ` Simon Marchi
2018-05-21 20:41     ` Pedro Alves
2018-05-22  3:37       ` Simon Marchi
2018-05-22 21:55       ` Sergio Durigan Junior
2018-05-22 23:26         ` [pushed] Fix gdb.base/remote.exp with native-extended-gdbserver board (Re: [PATCH 08/10] Handle "show remote memory-write-packet-size" when not connected) Pedro Alves
2018-05-16 15:46 ` [PATCH 07/10] remote: Move discard_pending_stop_replies call Pedro Alves
2018-05-18 21:29   ` Simon Marchi
2018-05-16 15:50 ` [PATCH 06/10] remote: Small cleanup in compare_section_command Pedro Alves
2018-05-18 21:26   ` Simon Marchi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180516141830.16859-5-palves@redhat.com \
    --to=palves@redhat.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).