public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: "Marcin Kościelnicki" <koriakin@0x04.net>
To: arnez@linux.vnet.ibm.com
Cc: gdb-patches@sourceware.org, "Marcin Kościelnicki" <koriakin@0x04.net>
Subject: [PATCH 1/8] gdb: Add supply_pseudo_pc hook to gdbarch.
Date: Sun, 07 Feb 2016 13:59:00 -0000	[thread overview]
Message-ID: <1454853588-17529-1-git-send-email-koriakin@0x04.net> (raw)
In-Reply-To: <m3zivse6ad.fsf@oc1027705133.ibm.com>

When we're looking at a tracefile trace frame where registers are not
available, and the tracepoint has only one location, we supply
the location's address as the PC register.  However, this only works
if PC is not a pseudo register.  Add a gdbarch hook that will handle
that for pseudo registers.

gdb/ChangeLog:

	* gdbarch.c: Regenerate.
	* gdbarch.h: Regenerate.
	* gdbarch.sh: Add supply_pseudo_pc hook.
	* tracefile.c (tracefile_fetch_registers): When PC is a pseudo,
	ask gdbarch to handle guessed PC via the new hook.
---
I've changed the name of the hook to supply_pseudo_pc, added missing
comments, and fixed the indent issue.

I don't think generalizing that function to arbitrary pseudo registers
is a good idea - there's already a pseudo_register_write, which covers
writing them.  The only reason I'm not using it in tracepoint.c is
that there's no "current register state" to write over, I'm making
a new one from scratch.

Perhaps a better generalization would be to instead make a hook that's
supposed to provide a whole regcache based on the tracepoint location,
not just PC?  I can imagine a few uses for that:

- on machines like ARM where you have several instruction encodings,
  you could also supply whatever registers determine the encoding
  (arm vs thumb) based on the location.
- if you can determine from the debug information that the function
  keeps GOT pointer / literal pool pointer / whatever in some register
  at the tracepoint location, you can also guess the contents of these
  (although that's probably not all that useful, and can be a lie
  if something is horribly buggy).

 gdb/ChangeLog   |  8 ++++++++
 gdb/gdbarch.c   | 32 ++++++++++++++++++++++++++++++++
 gdb/gdbarch.h   | 11 +++++++++++
 gdb/gdbarch.sh  |  5 +++++
 gdb/tracefile.c | 40 +++++++++++++++++++++++++++-------------
 5 files changed, 83 insertions(+), 13 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index a2b0d39..e0bfd21 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,11 @@
+2016-02-07  Marcin Kościelnicki  <koriakin@0x04.net>
+
+	* gdbarch.c: Regenerate.
+	* gdbarch.h: Regenerate.
+	* gdbarch.sh: Add supply_pseudo_pc hook.
+	* tracefile.c (tracefile_fetch_registers): When PC is a pseudo,
+	ask gdbarch to handle guessed PC via the new hook.
+
 2016-02-04  Yao Qi  <yao.qi@linaro.org>
 
 	* remote.c (remote_wait_as): Set rs->waiting_for_stop_reply to
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index 4143744..b323d44 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -181,6 +181,7 @@ struct gdbarch
   int char_signed;
   gdbarch_read_pc_ftype *read_pc;
   gdbarch_write_pc_ftype *write_pc;
+  gdbarch_supply_pseudo_pc_ftype *supply_pseudo_pc;
   gdbarch_virtual_frame_pointer_ftype *virtual_frame_pointer;
   gdbarch_pseudo_register_read_ftype *pseudo_register_read;
   gdbarch_pseudo_register_read_value_ftype *pseudo_register_read_value;
@@ -523,6 +524,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
     gdbarch->char_signed = 1;
   /* Skip verify of read_pc, has predicate.  */
   /* Skip verify of write_pc, has predicate.  */
+  /* Skip verify of supply_pseudo_pc, has predicate.  */
   /* Skip verify of virtual_frame_pointer, invalid_p == 0 */
   /* Skip verify of pseudo_register_read, has predicate.  */
   /* Skip verify of pseudo_register_read_value, has predicate.  */
@@ -1366,6 +1368,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
                       "gdbarch_dump: static_transform_name = <%s>\n",
                       host_address_to_string (gdbarch->static_transform_name));
   fprintf_unfiltered (file,
+                      "gdbarch_dump: gdbarch_supply_pseudo_pc_p() = %d\n",
+                      gdbarch_supply_pseudo_pc_p (gdbarch));
+  fprintf_unfiltered (file,
+                      "gdbarch_dump: supply_pseudo_pc = <%s>\n",
+                      host_address_to_string (gdbarch->supply_pseudo_pc));
+  fprintf_unfiltered (file,
                       "gdbarch_dump: syscalls_info = %s\n",
                       host_address_to_string (gdbarch->syscalls_info));
   fprintf_unfiltered (file,
@@ -1821,6 +1829,30 @@ set_gdbarch_write_pc (struct gdbarch *gdbarch,
   gdbarch->write_pc = write_pc;
 }
 
+int
+gdbarch_supply_pseudo_pc_p (struct gdbarch *gdbarch)
+{
+  gdb_assert (gdbarch != NULL);
+  return gdbarch->supply_pseudo_pc != NULL;
+}
+
+void
+gdbarch_supply_pseudo_pc (struct gdbarch *gdbarch, struct regcache *regcache, CORE_ADDR val)
+{
+  gdb_assert (gdbarch != NULL);
+  gdb_assert (gdbarch->supply_pseudo_pc != NULL);
+  if (gdbarch_debug >= 2)
+    fprintf_unfiltered (gdb_stdlog, "gdbarch_supply_pseudo_pc called\n");
+  gdbarch->supply_pseudo_pc (regcache, val);
+}
+
+void
+set_gdbarch_supply_pseudo_pc (struct gdbarch *gdbarch,
+                              gdbarch_supply_pseudo_pc_ftype supply_pseudo_pc)
+{
+  gdbarch->supply_pseudo_pc = supply_pseudo_pc;
+}
+
 void
 gdbarch_virtual_frame_pointer (struct gdbarch *gdbarch, CORE_ADDR pc, int *frame_regnum, LONGEST *frame_offset)
 {
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index 3fadcd1..bbb0ba3 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -239,6 +239,17 @@ typedef void (gdbarch_write_pc_ftype) (struct regcache *regcache, CORE_ADDR val)
 extern void gdbarch_write_pc (struct gdbarch *gdbarch, struct regcache *regcache, CORE_ADDR val);
 extern void set_gdbarch_write_pc (struct gdbarch *gdbarch, gdbarch_write_pc_ftype *write_pc);
 
+/* Supply given PC into an empty regcache.  Used for tracepoints where
+   no registers have been collected, but there's only one location,
+   allowing us to guess the PC value.  Only used on targets where PC
+   is a pseudo-register - otherwise PC is supplied directly. */
+
+extern int gdbarch_supply_pseudo_pc_p (struct gdbarch *gdbarch);
+
+typedef void (gdbarch_supply_pseudo_pc_ftype) (struct regcache *regcache, CORE_ADDR val);
+extern void gdbarch_supply_pseudo_pc (struct gdbarch *gdbarch, struct regcache *regcache, CORE_ADDR val);
+extern void set_gdbarch_supply_pseudo_pc (struct gdbarch *gdbarch, gdbarch_supply_pseudo_pc_ftype *supply_pseudo_pc);
+
 /* Function for getting target's idea of a frame pointer.  FIXME: GDB's
    whole scheme for dealing with "frames" and "frame pointers" needs a
    serious shakedown. */
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
index 4ac6b90..346dc3a 100755
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -417,6 +417,11 @@ v:int:char_signed:::1:-1:1
 #
 F:CORE_ADDR:read_pc:struct regcache *regcache:regcache
 F:void:write_pc:struct regcache *regcache, CORE_ADDR val:regcache, val
+# Supply given PC into an empty regcache.  Used for tracepoints where
+# no registers have been collected, but there's only one location,
+# allowing us to guess the PC value.  Only used on targets where PC
+# is a pseudo-register - otherwise PC is supplied directly.
+F:void:supply_pseudo_pc:struct regcache *regcache, CORE_ADDR val:regcache, val
 # Function for getting target's idea of a frame pointer.  FIXME: GDB's
 # whole scheme for dealing with "frames" and "frame pointers" needs a
 # serious shakedown.
diff --git a/gdb/tracefile.c b/gdb/tracefile.c
index fef4ed9..e3d7b0e 100644
--- a/gdb/tracefile.c
+++ b/gdb/tracefile.c
@@ -396,16 +396,18 @@ tracefile_fetch_registers (struct regcache *regcache, int regno)
      as the address of the tracepoint.  */
   pc_regno = gdbarch_pc_regnum (gdbarch);
 
-  /* XXX This guessing code below only works if the PC register isn't
-     a pseudo-register.  The value of a pseudo-register isn't stored
-     in the (non-readonly) regcache -- instead it's recomputed
-     (probably from some other cached raw register) whenever the
-     register is read.  This guesswork should probably move to some
-     higher layer.  */
-  if (pc_regno < 0 || pc_regno >= gdbarch_num_regs (gdbarch))
+  if (pc_regno < 0)
     return;
 
-  if (regno == -1 || regno == pc_regno)
+  /* We try to guess PC if:
+
+     1) We want all registers, or
+     2) PC is a real register, and we want exactly it, or
+     3) PC is a pseudo register (we don't know which real register it
+	corresponds to, so let's try to play safe).  */
+
+  if (regno == -1 || regno == pc_regno ||
+      pc_regno >= gdbarch_num_regs (gdbarch))
     {
       struct tracepoint *tp = get_tracepoint (get_tracepoint_number ());
       gdb_byte *regs;
@@ -429,11 +431,23 @@ tracefile_fetch_registers (struct regcache *regcache, int regno)
 	      return;
 	    }
 
-	  regs = (gdb_byte *) alloca (register_size (gdbarch, pc_regno));
-	  store_unsigned_integer (regs, register_size (gdbarch, pc_regno),
-				  gdbarch_byte_order (gdbarch),
-				  tp->base.loc->address);
-	  regcache_raw_supply (regcache, pc_regno, regs);
+	  if (pc_regno >= gdbarch_num_regs (gdbarch))
+	    {
+	      /* PC is a pseudo, let gdbarch deal with that.  If it doesn't
+		 know how, just bail.  */
+	      if (gdbarch_supply_pseudo_pc_p (gdbarch))
+		gdbarch_supply_pseudo_pc (gdbarch, regcache,
+						     tp->base.loc->address);
+	    }
+	  else
+	    {
+	      /* PC is a real register.  */
+	      regs = (gdb_byte *) alloca (register_size (gdbarch, pc_regno));
+	      store_unsigned_integer (regs, register_size (gdbarch, pc_regno),
+				      gdbarch_byte_order (gdbarch),
+				      tp->base.loc->address);
+	      regcache_raw_supply (regcache, pc_regno, regs);
+	    }
 	}
     }
 }
-- 
2.7.0

  reply	other threads:[~2016-02-07 13:59 UTC|newest]

Thread overview: 89+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-24 12:12 [PATCH 0/8] gdb/s390: Add regular and fast tracepoint support Marcin Kościelnicki
2016-01-24 12:12 ` [PATCH 7/8] gdb.trace: Bump tspeed.exp timeout to 600 seconds Marcin Kościelnicki
2016-01-26 18:17   ` Andreas Arnez
2016-01-29  9:53     ` [PATCH] " Marcin Kościelnicki
2016-02-12 11:20       ` Yao Qi
2016-02-18 18:54       ` Marcin Kościelnicki
2016-01-24 12:12 ` [PATCH 2/8] gdb/s390: Fill write_guessed_tracepoint_pc hook Marcin Kościelnicki
2016-01-26 18:12   ` Andreas Arnez
2016-01-26 19:26     ` Marcin Kościelnicki
2016-01-29 18:57       ` Andreas Arnez
2016-02-07 14:00         ` [PATCH 2/8] gdb/s390: Fill supply_pseudo_pc hook Marcin Kościelnicki
2016-01-24 12:12 ` [PATCH 4/8] gdb/s390: Fill gen_return_address hook Marcin Kościelnicki
2016-02-07 14:02   ` Marcin Kościelnicki
2016-02-25 19:23     ` Marcin Kościelnicki
2016-03-04 10:42       ` Marcin Kościelnicki
2016-03-11 11:20     ` Andreas Arnez
2016-03-11 11:35       ` Marcin Kościelnicki
2016-03-11 12:18         ` Andreas Arnez
2016-03-11 12:26           ` Marcin Kościelnicki
2016-03-11 15:31             ` Andreas Arnez
2016-03-11 15:44               ` Pedro Alves
2016-03-11 16:45                 ` Andreas Arnez
2016-03-11 17:02                   ` Pedro Alves
2016-03-11 18:17                     ` Eli Zaretskii
2016-03-11 18:37                       ` Pedro Alves
2016-03-11 19:34                         ` Eli Zaretskii
2016-03-15 11:11                           ` Pedro Alves
2016-03-15 11:23                             ` Andreas Arnez
2016-03-15 11:30                               ` Pedro Alves
2016-03-11 18:07                   ` Eli Zaretskii
2016-03-13  9:53               ` Marcin Kościelnicki
2016-03-14 10:07                 ` Andreas Arnez
2016-01-24 12:12 ` [PATCH 3/8] gdb/s390: Fill pseudo register agent expression hooks Marcin Kościelnicki
2016-02-07 14:01   ` Marcin Kościelnicki
2016-02-25 19:23     ` Marcin Kościelnicki
2016-03-04 10:42       ` Marcin Kościelnicki
2016-03-11  2:20         ` Marcin Kościelnicki
2016-03-11  9:58     ` Andreas Arnez
2016-03-11 10:04       ` Marcin Kościelnicki
2016-01-24 12:12 ` [PATCH 5/8] gdbserver/s390: Switch on tracepoint support Marcin Kościelnicki
2016-02-07 14:04   ` Marcin Kościelnicki
2016-02-22  7:38     ` [PATCH] " Marcin Kościelnicki
2016-03-04 10:39       ` [PATCH v3] " Marcin Kościelnicki
2016-03-15 18:41         ` [PATCH v4] " Marcin Kościelnicki
2016-03-22  9:16           ` Marcin Kościelnicki
2016-03-23 15:25           ` Andreas Arnez
2016-03-24  1:15             ` Marcin Kościelnicki
2016-03-29 18:31               ` Ulrich Weigand
2016-03-29 21:40                 ` Marcin Kościelnicki
2016-03-29 21:40             ` [PATCH obv] gdb/NEWS: Add mention of s390*-linux tracepoints Marcin Kościelnicki
2016-03-30  2:49               ` Eli Zaretskii
2016-01-24 12:12 ` [PATCH 8/8] gdbserver/s390: Add support for compiled agent expressions Marcin Kościelnicki
2016-03-04 10:41   ` [PATCH v2] " Marcin Kościelnicki
2016-03-14 16:19     ` Andreas Arnez
2016-01-24 12:12 ` [PATCH 1/8] gdb: Add write_guessed_tracepoint_pc hook to gdbarch Marcin Kościelnicki
2016-01-26 14:58   ` Andreas Arnez
2016-02-07 13:59     ` Marcin Kościelnicki [this message]
2016-02-16 18:28       ` [PATCH 1/8] gdb: Add supply_pseudo_pc " Ulrich Weigand
2016-02-16 21:32         ` Marcin Kościelnicki
2016-02-18 10:35         ` [PATCH 1/2] gdb: Add guess_tracepoint_registers " Marcin Kościelnicki
2016-02-18 10:35           ` [PATCH 2/2] gdb/s390: Fill guess_tracepoint_registers hook Marcin Kościelnicki
2016-02-18 16:03             ` Ulrich Weigand
2016-02-18 16:36               ` [PATCH] " Marcin Kościelnicki
2016-02-18 16:48                 ` Ulrich Weigand
2016-02-18 16:58                   ` Marcin Kościelnicki
2016-02-18 11:38           ` [PATCH 1/2] gdb: Add guess_tracepoint_registers hook to gdbarch Luis Machado
2016-02-18 11:39             ` Marcin Kościelnicki
2016-02-18 11:45             ` [PATCH] " Marcin Kościelnicki
2016-02-18 15:40               ` Ulrich Weigand
2016-02-18 15:41                 ` Marcin Kościelnicki
2016-02-18 15:58                   ` Ulrich Weigand
2016-02-18 16:01                     ` Marcin Kościelnicki
2016-02-18 16:06                       ` Ulrich Weigand
2016-02-18 16:11                         ` Marcin Kościelnicki
2016-02-18 16:13                           ` Ulrich Weigand
2016-02-18 16:22                             ` Marcin Kościelnicki
2016-01-24 12:13 ` [PATCH 6/8] gdbserver/s390: Add fast tracepoint support Marcin Kościelnicki
2016-01-25 14:34   ` Antoine Tremblay
2016-02-19 13:41     ` Marcin Kościelnicki
2016-02-19 14:41       ` Antoine Tremblay
2016-03-04 10:40         ` [PATCH v2] " Marcin Kościelnicki
2016-03-14 16:19           ` Andreas Arnez
2016-03-14 16:25             ` Marcin Kościelnicki
2016-01-25 13:27 ` [PATCH 0/8] gdb/s390: Add regular and " Antoine Tremblay
2016-01-25 13:56 ` Pedro Alves
2016-01-25 14:28   ` Marcin Kościelnicki
2016-01-25 15:57     ` Pedro Alves
2016-01-25 16:03       ` Marcin Kościelnicki
2016-02-12 11:04 ` Marcin Kościelnicki

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=1454853588-17529-1-git-send-email-koriakin@0x04.net \
    --to=koriakin@0x04.net \
    --cc=arnez@linux.vnet.ibm.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).