public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Joel Brobecker <brobecker@adacore.com>
To: Pedro Alves <palves@redhat.com>
Cc: gdb-patches@sourceware.org
Subject: Re: [PATCH 1/2] Minor reorganization of fetch_registers/store_registers in windows-nat.c
Date: Tue, 26 Jun 2018 21:41:00 -0000	[thread overview]
Message-ID: <20180626214115.GB8075@adacore.com> (raw)
In-Reply-To: <ac019b00-982b-1f42-3f4a-10e32703008c@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 859 bytes --]

> I agree this looks clearer without the recursion.
> 
> LGTM.  A couple nits on comments below.

Thanks, Pedro. Attached is the version I ended up pushing.

gdb/ChangeLog:

        * windows-nat.c (do_windows_fetch_inferior_registers): Rename
        to windows_fetch_one_register, and only handle the case of
        fetching one register.  Move the code that reloads the context
        and iterates over all registers if R is negative to...
        (windows_nat_target::fetch_registers): ... here.
        (do_windows_store_inferior_registers): Rename to
        windows_store_one_register, and only handle the case of storing
        one register.  Move the code that handles the case where r is
        negative to...
        (windows_nat_target::store_registers) ... here.

Tested on x86-windows and x86_64-windows using AdaCore's testsuite.

-- 
Joel

[-- Attachment #2: 0001-Minor-reorganization-of-fetch_registers-store_regist.patch --]
[-- Type: text/x-diff, Size: 6906 bytes --]

From 59b78c81d3bdd7cd5ad8e8eae8f940a6115f1209 Mon Sep 17 00:00:00 2001
From: Joel Brobecker <brobecker@adacore.com>
Date: Tue, 26 Jun 2018 16:46:09 -0400
Subject: [PATCH] Minor reorganization of fetch_registers/store_registers in
 windows-nat.c

This patch is a small reorganizational patch that splits
do_windows_fetch_inferior_registers into two parts:

  (a) One part that first reloads the thread's context when needed,
      and then decides based on the given register number whether
      one register needs to be fetched or all of them.

      This part is moved to windows_nat_target::fetch_registers.

  (b) The rest of the code, which actually fetches the register value
      and supplies it to the regcache.

A similar treatment is applied to do_windows_store_inferior_registers.

This change is preparation work for changing the way we calculate
the location of a given register in the thread context structure,
and should be a no op.

gdb/ChangeLog:

        * windows-nat.c (do_windows_fetch_inferior_registers): Rename
        to windows_fetch_one_register, and only handle the case of
        fetching one register.  Move the code that reloads the context
        and iterates over all registers if R is negative to...
        (windows_nat_target::fetch_registers): ... here.
        (do_windows_store_inferior_registers): Rename to
        windows_store_one_register, and only handle the case of storing
        one register.  Move the code that handles the case where r is
        negative to...
        (windows_nat_target::store_registers) ... here.

Tested on x86-windows and x86_64-windows using AdaCore's testsuite.
---
 gdb/windows-nat.c | 117 ++++++++++++++++++++++++++++++++----------------------
 1 file changed, 69 insertions(+), 48 deletions(-)

diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index 98d94a3..35ad865 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -509,14 +509,59 @@ windows_delete_thread (ptid_t ptid, DWORD exit_code)
     }
 }
 
+/* Fetches register number R from the given windows_thread_info,
+   and supplies its value to the given regcache.
+
+   This function assumes that R is non-negative.  A failed assertion
+   is raised if that is not true.
+
+   This function assumes that TH->RELOAD_CONTEXT is not set, meaning
+   that the windows_thread_info has an up-to-date context.  A failed
+   assertion is raised if that assumption is violated.  */
+
 static void
-do_windows_fetch_inferior_registers (struct regcache *regcache,
-				     windows_thread_info *th, int r)
+windows_fetch_one_register (struct regcache *regcache,
+			    windows_thread_info *th, int r)
 {
+  gdb_assert (r >= 0);
+  gdb_assert (!th->reload_context);
+
   char *context_offset = ((char *) &th->context) + mappings[r];
   struct gdbarch *gdbarch = regcache->arch ();
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-  long l;
+
+  if (r == I387_FISEG_REGNUM (tdep))
+    {
+      long l = *((long *) context_offset) & 0xffff;
+      regcache->raw_supply (r, (char *) &l);
+    }
+  else if (r == I387_FOP_REGNUM (tdep))
+    {
+      long l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
+      regcache->raw_supply (r, (char *) &l);
+    }
+  else if (segment_register_p (r))
+    {
+      /* GDB treats segment registers as 32bit registers, but they are
+	 in fact only 16 bits long.  Make sure we do not read extra
+	 bits from our source buffer.  */
+      long l = *((long *) context_offset) & 0xffff;
+      regcache->raw_supply (r, (char *) &l);
+    }
+  else
+    regcache->raw_supply (r, context_offset);
+}
+
+void
+windows_nat_target::fetch_registers (struct regcache *regcache, int r)
+{
+  DWORD pid = ptid_get_tid (regcache->ptid ());
+  windows_thread_info *th = thread_rec (pid, TRUE);
+
+  /* Check if TH exists.  Windows sometimes uses a non-existent
+     thread id in its events.  */
+  if (th == NULL)
+    return;
 
   if (th->reload_context)
     {
@@ -552,56 +597,26 @@ do_windows_fetch_inferior_registers (struct regcache *regcache,
       th->reload_context = 0;
     }
 
-  if (r == I387_FISEG_REGNUM (tdep))
-    {
-      l = *((long *) context_offset) & 0xffff;
-      regcache->raw_supply (r, (char *) &l);
-    }
-  else if (r == I387_FOP_REGNUM (tdep))
-    {
-      l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
-      regcache->raw_supply (r, (char *) &l);
-    }
-  else if (segment_register_p (r))
-    {
-      /* GDB treats segment registers as 32bit registers, but they are
-	 in fact only 16 bits long.  Make sure we do not read extra
-	 bits from our source buffer.  */
-      l = *((long *) context_offset) & 0xffff;
-      regcache->raw_supply (r, (char *) &l);
-    }
-  else if (r >= 0)
-    regcache->raw_supply (r, context_offset);
+  if (r < 0)
+    for (r = 0; r < gdbarch_num_regs (regcache->arch()); r++)
+      windows_fetch_one_register (regcache, th, r);
   else
-    {
-      for (r = 0; r < gdbarch_num_regs (gdbarch); r++)
-	do_windows_fetch_inferior_registers (regcache, th, r);
-    }
+    windows_fetch_one_register (regcache, th, r);
 }
 
-void
-windows_nat_target::fetch_registers (struct regcache *regcache, int r)
-{
-  DWORD pid = ptid_get_tid (regcache->ptid ());
-  windows_thread_info *th = thread_rec (pid, TRUE);
+/* Collect the register number R from the given regcache, and store
+   its value into the corresponding area of the given thread's context.
 
-  /* Check if TH exists.  Windows sometimes uses a non-existent
-     thread id in its events.  */
-  if (th != NULL)
-    do_windows_fetch_inferior_registers (regcache, th, r);
-}
+   This function assumes that R is non-negative.  A failed assertion
+   assertion is raised if that is not true.  */
 
 static void
-do_windows_store_inferior_registers (const struct regcache *regcache,
-				     windows_thread_info *th, int r)
+windows_store_one_register (const struct regcache *regcache,
+			    windows_thread_info *th, int r)
 {
-  if (r >= 0)
-    regcache->raw_collect (r, ((char *) &th->context) + mappings[r]);
-  else
-    {
-      for (r = 0; r < gdbarch_num_regs (regcache->arch ()); r++)
-	do_windows_store_inferior_registers (regcache, th, r);
-    }
+  gdb_assert (r >= 0);
+
+  regcache->raw_collect (r, ((char *) &th->context) + mappings[r]);
 }
 
 /* Store a new register value into the context of the thread tied to
@@ -615,8 +630,14 @@ windows_nat_target::store_registers (struct regcache *regcache, int r)
 
   /* Check if TH exists.  Windows sometimes uses a non-existent
      thread id in its events.  */
-  if (th != NULL)
-    do_windows_store_inferior_registers (regcache, th, r);
+  if (th == NULL)
+    return;
+
+  if (r < 0)
+    for (r = 0; r < gdbarch_num_regs (regcache->arch ()); r++)
+      windows_store_one_register (regcache, th, r);
+  else
+    windows_store_one_register (regcache, th, r);
 }
 
 /* Encapsulate the information required in a call to
-- 
2.8.3


      reply	other threads:[~2018-06-26 21:41 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-25 18:55 x86_64-windows GDB crash due to fs_base/gs_base registers Joel Brobecker
2018-06-25 18:55 ` [PATCH 2/2] " Joel Brobecker
2018-06-26 16:00   ` Pedro Alves
2018-06-26 21:53     ` Joel Brobecker
2018-06-29 12:32       ` Pedro Alves
2018-06-29 22:08         ` Joel Brobecker
2018-06-29 12:32       ` Pedro Alves
2018-06-25 18:55 ` [PATCH 1/2] Minor reorganization of fetch_registers/store_registers in windows-nat.c Joel Brobecker
2018-06-26 16:03   ` Pedro Alves
2018-06-26 21:41     ` Joel Brobecker [this message]

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=20180626214115.GB8075@adacore.com \
    --to=brobecker@adacore.com \
    --cc=gdb-patches@sourceware.org \
    --cc=palves@redhat.com \
    /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).