Add Guile frame-read-register command
authorAndy Wingo <wingo@igalia.com>
Thu, 9 Apr 2015 12:06:41 +0000 (13:06 +0100)
committerAndy Wingo <wingo@igalia.com>
Thu, 9 Apr 2015 12:39:00 +0000 (14:39 +0200)
gdb/ChangeLog:

* 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:

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

gdb/testsuite/ChangeLog:

* gdb.guile/scm-frame.exp: Add frame-read-register tests, modelled
after the Python tests.

gdb/ChangeLog
gdb/doc/ChangeLog
gdb/doc/guile.texi
gdb/guile/lib/gdb.scm
gdb/guile/scm-frame.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.guile/scm-frame.exp

index e535767ee457ae6e763500347a8b399ece6aed62..8519fea6a75606174a931423ba22489ef0aedbcc 100644 (file)
@@ -1,3 +1,10 @@
+2015-04-09  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-04-09  Gary Benson <gbenson@redhat.com>
 
        * common/common-remote-fileio.h (remote_fileio_to_fio_error):
index b6c1ca33af98a24ba880712f8394b0c19f57955f..5ad5e3af809d239121c6f0635124be776721b0df 100644 (file)
@@ -1,3 +1,7 @@
+2015-04-09  Andy Wingo  <wingo@igalia.com>
+
+       * guile.texi (Frames In Guile): Describe frame-read-register.
+
 2015-04-02  Gary Benson <gbenson@redhat.com>
 
        * gdb.texinfo (set sysroot): Document "target:".
index 4a4365c9ba2ca200a1845373d18264c02c2b4683..04572fd9467fa3ad372deb8874ac0c36dd94b531 100644 (file)
@@ -2436,6 +2436,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
index 8f238be776ccdef447d8443f3c685c7a9227f5d0..c8a3b5c72a1bbe5f8dfbbd41979d68af10f3d009 100644 (file)
  frame-older
  frame-newer
  frame-sal
+ frame-read-register
  frame-read-var
  frame-select
  newest-frame
index ea51d1b5e4511359a66eeb8863a38f3e8105cce8..787b788d6cedc66bec9e8ca2ea6f3d4a1a553844 100644 (file)
@@ -28,6 +28,7 @@
 #include "symfile.h"
 #include "symtab.h"
 #include "stack.h"
+#include "user-regs.h"
 #include "value.h"
 #include "guile-internal.h"
 
@@ -782,6 +783,60 @@ 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)
+{
+  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
+    {
+      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);
+       }
+    }
+  CATCH (except, RETURN_MASK_ALL)
+    {
+      GDBSCM_HANDLE_GDB_EXCEPTION (except);
+    }
+  END_CATCH
+
+  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,
@@ -1076,6 +1131,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." },
index 714210998e718e55af850e9b5508e71ff8a4ee37..73785d623927a021d9b98490a70b88856b0cfadb 100644 (file)
@@ -1,3 +1,8 @@
+2015-04-09  Andy Wingo  <wingo@igalia.com>
+
+       * gdb.guile/scm-frame.exp: Add frame-read-register tests, modelled
+       after the Python tests.
+
 2015-04-08  Keith Seitz  <keiths@redhat.com>
 
        PR python/16699
index 7af9092daaae4a56ab072f220f5f92d43f570acf..9a5eb1ebb2615944288b2698e72bfb063503b73d 100644 (file)
@@ -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"
+}