Add frame-read-register

Message ID 87r3tl0y0w.fsf@igalia.com
State New, archived
Headers

Commit Message

Andy Wingo Feb. 20, 2015, 8:47 a.m. UTC
  Hi,

The attached patch adds frame-read-register to the Guile interface, like
Frame.read_register() for python.

Andy
  

Comments

Eli Zaretskii Feb. 20, 2015, 9:58 a.m. UTC | #1
> From: Andy Wingo <wingo@igalia.com>
> Cc: Andy Wingo <wingo@igalia.com>, Doug Evans <xdje42@gmail.com>
> Date: Fri, 20 Feb 2015 09:47:59 +0100
> 
> The attached patch adds frame-read-register to the Guile interface, like
> Frame.read_register() for python.

OK for the documentation parts.

Thanks.
  
Andy Wingo March 11, 2015, 12:41 p.m. UTC | #2
Friendly ping :)  Eli already gave an LGTM on the documentation part.

On Fri 20 Feb 2015 09:47, Andy Wingo <wingo@igalia.com> writes:

> Hi,
>
> The attached patch adds frame-read-register to the Guile interface, like
> Frame.read_register() for python.
>
> Andy
>
>
> From cb83778843bbdf4f32c990ca0fc3d16841456d66 Mon Sep 17 00:00:00 2001
> From: Andy Wingo <wingo@igalia.com>
> Date: Fri, 20 Feb 2015 09:33:59 +0100
> Subject: [PATCH] Add Guile frame-read-register command
>
> gdb/ChangeLog:
> 2015-02-20  Andy Wingo  <wingo@igalia.com>
>
> 	* guile/scm-frame.c (gdbscm_frame_read_register): New function.
> 	(frame_functions): Bind gdbscm_frame_read_register to
> 	frame-read-register.
> 	* guile/lib/gdb.scm (frame-read-register): Export.
>
> gdb/doc/ChangeLog:
> 2015-02-20  Andy Wingo  <wingo@igalia.com>
>
> 	* guile.texi (Frames In Guile): Describe frame-read-register.
>
> gdb/testsuite/ChangeLog:
> 2015-02-20  Andy Wingo  <wingo@igalia.com>
>
> 	* gdb.guile/scm-frame.exp: Add frame-read-register tests, modelled
> 	after the Python tests.
> ---
>  gdb/ChangeLog                         |  7 +++++
>  gdb/doc/ChangeLog                     |  4 +++
>  gdb/doc/guile.texi                    |  5 +++
>  gdb/guile/lib/gdb.scm                 |  1 +
>  gdb/guile/scm-frame.c                 | 58 +++++++++++++++++++++++++++++++++++
>  gdb/testsuite/ChangeLog               |  5 +++
>  gdb/testsuite/gdb.guile/scm-frame.exp | 20 ++++++++++++
>  7 files changed, 100 insertions(+)
>
> diff --git a/gdb/ChangeLog b/gdb/ChangeLog
> index ee126eb..34bfba9 100644
> --- a/gdb/ChangeLog
> +++ b/gdb/ChangeLog
> @@ -1,3 +1,10 @@
> +2015-02-20  Andy Wingo  <wingo@igalia.com>
> +
> +	* guile/scm-frame.c (gdbscm_frame_read_register): New function.
> +	(frame_functions): Bind gdbscm_frame_read_register to
> +	frame-read-register.
> +	* guile/lib/gdb.scm (frame-read-register): Export.
> +
>  2015-02-15  Andy Wingo  <wingo@igalia.com>
>  
>  	* guile/scm-frame-filter.c:
> diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
> index c7f6470..cb31292 100644
> --- a/gdb/doc/ChangeLog
> +++ b/gdb/doc/ChangeLog
> @@ -1,3 +1,7 @@
> +2015-02-20  Andy Wingo  <wingo@igalia.com>
> +
> +	* guile.texi (Frames In Guile): Describe frame-read-register.
> +
>  2015-02-15  Andy Wingo  <wingo@igalia.com>
>  
>  	* guile.texi (Guile Frame Filter API)
> diff --git a/gdb/doc/guile.texi b/gdb/doc/guile.texi
> index 8ea9748..7bfdda8 100644
> --- a/gdb/doc/guile.texi
> +++ b/gdb/doc/guile.texi
> @@ -2816,6 +2816,11 @@ Return the frame's @code{<gdb:sal>} (symtab and line) object.
>  @xref{Symbol Tables In Guile}.
>  @end deffn
>  
> +@deffn {Scheme Procedure} frame-read-register frame register
> +Return the value of @var{register} in @var{frame}.  @var{register}
> +should be a string, like @samp{pc}.
> +@end deffn
> +
>  @deffn {Scheme Procedure} frame-read-var frame variable @r{[}#:block block@r{]}
>  Return the value of @var{variable} in @var{frame}.  If the optional
>  argument @var{block} is provided, search for the variable from that
> diff --git a/gdb/guile/lib/gdb.scm b/gdb/guile/lib/gdb.scm
> index cc35bc1..2eb05ea 100644
> --- a/gdb/guile/lib/gdb.scm
> +++ b/gdb/guile/lib/gdb.scm
> @@ -219,6 +219,7 @@
>   frame-older
>   frame-newer
>   frame-sal
> + frame-read-register
>   frame-read-var
>   frame-select
>   newest-frame
> diff --git a/gdb/guile/scm-frame.c b/gdb/guile/scm-frame.c
> index 3927714..8483b28 100644
> --- a/gdb/guile/scm-frame.c
> +++ b/gdb/guile/scm-frame.c
> @@ -28,6 +28,7 @@
>  #include "symfile.h"
>  #include "symtab.h"
>  #include "stack.h"
> +#include "user-regs.h"
>  #include "value.h"
>  #include "guile-internal.h"
>  
> @@ -748,6 +749,57 @@ gdbscm_frame_sal (SCM self)
>    return stscm_scm_from_sal (sal);
>  }
>  
> +/* (frame-read-register <gdb:frame> string) -> <gdb:value>
> +   The register argument must be a string.  */
> +
> +static SCM
> +gdbscm_frame_read_register (SCM self, SCM register_scm)
> +{
> +  volatile struct gdb_exception except;
> +  char *register_str;
> +  struct value *value = NULL;
> +  struct frame_info *frame = NULL;
> +  struct cleanup *cleanup;
> +  frame_smob *f_smob;
> +
> +  f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
> +  gdbscm_parse_function_args (FUNC_NAME, SCM_ARG2, NULL, "s",
> +			      register_scm, &register_str);
> +  cleanup = make_cleanup (xfree, register_str);
> +
> +  TRY_CATCH (except, RETURN_MASK_ALL)
> +    {
> +      int regnum;
> +
> +      frame = frscm_frame_smob_to_frame (f_smob);
> +      if (frame)
> +	{
> +	  regnum = user_reg_map_name_to_regnum (get_frame_arch (frame),
> +						register_str,
> +						strlen (register_str));
> +	  if (regnum >= 0)
> +	    value = value_of_register (regnum, frame);
> +	}
> +    }
> +  GDBSCM_HANDLE_GDB_EXCEPTION (except);
> +
> +  do_cleanups (cleanup);
> +
> +  if (frame == NULL)
> +    {
> +      gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
> +				   _("<gdb:frame>"));
> +    }
> +
> +  if (value == NULL)
> +    {
> +      gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG2, register_scm,
> +				 _("unknown register"));
> +    }
> +
> +  return vlscm_scm_from_value (value);
> +}
> +
>  /* (frame-read-var <gdb:frame> <gdb:symbol>) -> <gdb:value>
>     (frame-read-var <gdb:frame> string [#:block <gdb:block>]) -> <gdb:value>
>     If the optional block argument is provided start the search from that block,
> @@ -1021,6 +1073,12 @@ Return the value of the symbol in the frame.\n\
>    Arguments: <gdb:frame> <gdb:symbol>\n\
>           Or: <gdb:frame> string [#:block <gdb:block>]" },
>  
> +  { "frame-read-register", 2, 0, 0, gdbscm_frame_read_register,
> +    "\
> +Return the value of the register in the frame.\n\
> +\n\
> +  Arguments: <gdb:frame> string" },
> +
>    { "frame-select", 1, 0, 0, gdbscm_frame_select,
>      "\
>  Select this frame." },
> diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
> index 4fe771e..2d96ea8 100644
> --- a/gdb/testsuite/ChangeLog
> +++ b/gdb/testsuite/ChangeLog
> @@ -1,3 +1,8 @@
> +2015-02-20  Andy Wingo  <wingo@igalia.com>
> +
> +	* gdb.guile/scm-frame.exp: Add frame-read-register tests, modelled
> +	after the Python tests.
> +
>  2015-02-09  Mark Wielaard  <mjw@redhat.com>
>  
>  	* gdb.dwarf2/atomic.c: New file.
> diff --git a/gdb/testsuite/gdb.guile/scm-frame.exp b/gdb/testsuite/gdb.guile/scm-frame.exp
> index 7af9092..9a5eb1e 100644
> --- a/gdb/testsuite/gdb.guile/scm-frame.exp
> +++ b/gdb/testsuite/gdb.guile/scm-frame.exp
> @@ -120,3 +120,23 @@ gdb_test "guile (print (format #f \"= ~A\" (frame-read-var f0 \"a\")))" \
>  
>  gdb_test "guile (print (format #f \"= ~A\" (eq? (selected-frame) f1)))" \
>      "= #t" "test selected-frame"
> +
> +# Can read SP register.
> +gdb_test "guile (print (equal? (frame-read-register (selected-frame) \"sp\") (parse-and-eval \"\$sp\")))" \
> +  "= #t" "test frame-read-register of sp"
> +
> +# PC value obtained via read_register is as expected.
> +gdb_test "guile (print (equal? (value->integer (frame-read-register f0 \"pc\")) (frame-pc f0)))" \
> +  "= #t" "test frame-read-register of pc"
> +
> +# Test arch-specific register name.
> +set pc ""
> +if {[is_amd64_regs_target]} {
> +    set pc "rip"
> +} elseif {[is_x86_like_target]} {
> +    set pc "eip"
> +}
> +if { $pc != "" } {
> +    gdb_test "guile (print (equal? (frame-read-register f0 \"pc\") (frame-read-register f0 \"$pc\")))" \
> +	"= #t" "test frame-read-register of $pc"
> +}
  
Doug Evans March 17, 2015, 4:46 p.m. UTC | #3
Andy Wingo <wingo@igalia.com> writes:
> Hi,
>
> The attached patch adds frame-read-register to the Guile interface, like
> Frame.read_register() for python.
>
> Andy
>
>
> From cb83778843bbdf4f32c990ca0fc3d16841456d66 Mon Sep 17 00:00:00 2001
> From: Andy Wingo <wingo@igalia.com>
> Date: Fri, 20 Feb 2015 09:33:59 +0100
> Subject: [PATCH] Add Guile frame-read-register command
>
> gdb/ChangeLog:
> 2015-02-20  Andy Wingo  <wingo@igalia.com>
>
> 	* guile/scm-frame.c (gdbscm_frame_read_register): New function.
> 	(frame_functions): Bind gdbscm_frame_read_register to
> 	frame-read-register.
> 	* guile/lib/gdb.scm (frame-read-register): Export.
>
> gdb/doc/ChangeLog:
> 2015-02-20  Andy Wingo  <wingo@igalia.com>
>
> 	* guile.texi (Frames In Guile): Describe frame-read-register.
>
> gdb/testsuite/ChangeLog:
> 2015-02-20  Andy Wingo  <wingo@igalia.com>
>
> 	* gdb.guile/scm-frame.exp: Add frame-read-register tests, modelled
> 	after the Python tests.

LGTM
  

Patch

From cb83778843bbdf4f32c990ca0fc3d16841456d66 Mon Sep 17 00:00:00 2001
From: Andy Wingo <wingo@igalia.com>
Date: Fri, 20 Feb 2015 09:33:59 +0100
Subject: [PATCH] Add Guile frame-read-register command

gdb/ChangeLog:
2015-02-20  Andy Wingo  <wingo@igalia.com>

	* guile/scm-frame.c (gdbscm_frame_read_register): New function.
	(frame_functions): Bind gdbscm_frame_read_register to
	frame-read-register.
	* guile/lib/gdb.scm (frame-read-register): Export.

gdb/doc/ChangeLog:
2015-02-20  Andy Wingo  <wingo@igalia.com>

	* guile.texi (Frames In Guile): Describe frame-read-register.

gdb/testsuite/ChangeLog:
2015-02-20  Andy Wingo  <wingo@igalia.com>

	* gdb.guile/scm-frame.exp: Add frame-read-register tests, modelled
	after the Python tests.
---
 gdb/ChangeLog                         |  7 +++++
 gdb/doc/ChangeLog                     |  4 +++
 gdb/doc/guile.texi                    |  5 +++
 gdb/guile/lib/gdb.scm                 |  1 +
 gdb/guile/scm-frame.c                 | 58 +++++++++++++++++++++++++++++++++++
 gdb/testsuite/ChangeLog               |  5 +++
 gdb/testsuite/gdb.guile/scm-frame.exp | 20 ++++++++++++
 7 files changed, 100 insertions(+)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index ee126eb..34bfba9 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,10 @@ 
+2015-02-20  Andy Wingo  <wingo@igalia.com>
+
+	* guile/scm-frame.c (gdbscm_frame_read_register): New function.
+	(frame_functions): Bind gdbscm_frame_read_register to
+	frame-read-register.
+	* guile/lib/gdb.scm (frame-read-register): Export.
+
 2015-02-15  Andy Wingo  <wingo@igalia.com>
 
 	* guile/scm-frame-filter.c:
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index c7f6470..cb31292 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,7 @@ 
+2015-02-20  Andy Wingo  <wingo@igalia.com>
+
+	* guile.texi (Frames In Guile): Describe frame-read-register.
+
 2015-02-15  Andy Wingo  <wingo@igalia.com>
 
 	* guile.texi (Guile Frame Filter API)
diff --git a/gdb/doc/guile.texi b/gdb/doc/guile.texi
index 8ea9748..7bfdda8 100644
--- a/gdb/doc/guile.texi
+++ b/gdb/doc/guile.texi
@@ -2816,6 +2816,11 @@  Return the frame's @code{<gdb:sal>} (symtab and line) object.
 @xref{Symbol Tables In Guile}.
 @end deffn
 
+@deffn {Scheme Procedure} frame-read-register frame register
+Return the value of @var{register} in @var{frame}.  @var{register}
+should be a string, like @samp{pc}.
+@end deffn
+
 @deffn {Scheme Procedure} frame-read-var frame variable @r{[}#:block block@r{]}
 Return the value of @var{variable} in @var{frame}.  If the optional
 argument @var{block} is provided, search for the variable from that
diff --git a/gdb/guile/lib/gdb.scm b/gdb/guile/lib/gdb.scm
index cc35bc1..2eb05ea 100644
--- a/gdb/guile/lib/gdb.scm
+++ b/gdb/guile/lib/gdb.scm
@@ -219,6 +219,7 @@ 
  frame-older
  frame-newer
  frame-sal
+ frame-read-register
  frame-read-var
  frame-select
  newest-frame
diff --git a/gdb/guile/scm-frame.c b/gdb/guile/scm-frame.c
index 3927714..8483b28 100644
--- a/gdb/guile/scm-frame.c
+++ b/gdb/guile/scm-frame.c
@@ -28,6 +28,7 @@ 
 #include "symfile.h"
 #include "symtab.h"
 #include "stack.h"
+#include "user-regs.h"
 #include "value.h"
 #include "guile-internal.h"
 
@@ -748,6 +749,57 @@  gdbscm_frame_sal (SCM self)
   return stscm_scm_from_sal (sal);
 }
 
+/* (frame-read-register <gdb:frame> string) -> <gdb:value>
+   The register argument must be a string.  */
+
+static SCM
+gdbscm_frame_read_register (SCM self, SCM register_scm)
+{
+  volatile struct gdb_exception except;
+  char *register_str;
+  struct value *value = NULL;
+  struct frame_info *frame = NULL;
+  struct cleanup *cleanup;
+  frame_smob *f_smob;
+
+  f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
+  gdbscm_parse_function_args (FUNC_NAME, SCM_ARG2, NULL, "s",
+			      register_scm, &register_str);
+  cleanup = make_cleanup (xfree, register_str);
+
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      int regnum;
+
+      frame = frscm_frame_smob_to_frame (f_smob);
+      if (frame)
+	{
+	  regnum = user_reg_map_name_to_regnum (get_frame_arch (frame),
+						register_str,
+						strlen (register_str));
+	  if (regnum >= 0)
+	    value = value_of_register (regnum, frame);
+	}
+    }
+  GDBSCM_HANDLE_GDB_EXCEPTION (except);
+
+  do_cleanups (cleanup);
+
+  if (frame == NULL)
+    {
+      gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
+				   _("<gdb:frame>"));
+    }
+
+  if (value == NULL)
+    {
+      gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG2, register_scm,
+				 _("unknown register"));
+    }
+
+  return vlscm_scm_from_value (value);
+}
+
 /* (frame-read-var <gdb:frame> <gdb:symbol>) -> <gdb:value>
    (frame-read-var <gdb:frame> string [#:block <gdb:block>]) -> <gdb:value>
    If the optional block argument is provided start the search from that block,
@@ -1021,6 +1073,12 @@  Return the value of the symbol in the frame.\n\
   Arguments: <gdb:frame> <gdb:symbol>\n\
          Or: <gdb:frame> string [#:block <gdb:block>]" },
 
+  { "frame-read-register", 2, 0, 0, gdbscm_frame_read_register,
+    "\
+Return the value of the register in the frame.\n\
+\n\
+  Arguments: <gdb:frame> string" },
+
   { "frame-select", 1, 0, 0, gdbscm_frame_select,
     "\
 Select this frame." },
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 4fe771e..2d96ea8 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,8 @@ 
+2015-02-20  Andy Wingo  <wingo@igalia.com>
+
+	* gdb.guile/scm-frame.exp: Add frame-read-register tests, modelled
+	after the Python tests.
+
 2015-02-09  Mark Wielaard  <mjw@redhat.com>
 
 	* gdb.dwarf2/atomic.c: New file.
diff --git a/gdb/testsuite/gdb.guile/scm-frame.exp b/gdb/testsuite/gdb.guile/scm-frame.exp
index 7af9092..9a5eb1e 100644
--- a/gdb/testsuite/gdb.guile/scm-frame.exp
+++ b/gdb/testsuite/gdb.guile/scm-frame.exp
@@ -120,3 +120,23 @@  gdb_test "guile (print (format #f \"= ~A\" (frame-read-var f0 \"a\")))" \
 
 gdb_test "guile (print (format #f \"= ~A\" (eq? (selected-frame) f1)))" \
     "= #t" "test selected-frame"
+
+# Can read SP register.
+gdb_test "guile (print (equal? (frame-read-register (selected-frame) \"sp\") (parse-and-eval \"\$sp\")))" \
+  "= #t" "test frame-read-register of sp"
+
+# PC value obtained via read_register is as expected.
+gdb_test "guile (print (equal? (value->integer (frame-read-register f0 \"pc\")) (frame-pc f0)))" \
+  "= #t" "test frame-read-register of pc"
+
+# Test arch-specific register name.
+set pc ""
+if {[is_amd64_regs_target]} {
+    set pc "rip"
+} elseif {[is_x86_like_target]} {
+    set pc "eip"
+}
+if { $pc != "" } {
+    gdb_test "guile (print (equal? (frame-read-register f0 \"pc\") (frame-read-register f0 \"$pc\")))" \
+	"= #t" "test frame-read-register of $pc"
+}
-- 
2.1.4