From f2983cc34ec64b01fabd0b5ca5af50ee690e1661 Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Thu, 9 Apr 2015 13:06:41 +0100 Subject: [PATCH] Add Guile frame-read-register command 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 | 7 +++ gdb/doc/ChangeLog | 4 ++ gdb/doc/guile.texi | 5 +++ gdb/guile/lib/gdb.scm | 1 + gdb/guile/scm-frame.c | 61 +++++++++++++++++++++++++++ gdb/testsuite/ChangeLog | 5 +++ gdb/testsuite/gdb.guile/scm-frame.exp | 20 +++++++++ 7 files changed, 103 insertions(+) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index e535767ee45..8519fea6a75 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2015-04-09 Andy Wingo + + * 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 * common/common-remote-fileio.h (remote_fileio_to_fio_error): diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index b6c1ca33af9..5ad5e3af809 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,7 @@ +2015-04-09 Andy Wingo + + * guile.texi (Frames In Guile): Describe frame-read-register. + 2015-04-02 Gary Benson * gdb.texinfo (set sysroot): Document "target:". diff --git a/gdb/doc/guile.texi b/gdb/doc/guile.texi index 4a4365c9ba2..04572fd9467 100644 --- a/gdb/doc/guile.texi +++ b/gdb/doc/guile.texi @@ -2436,6 +2436,11 @@ Return the frame's @code{} (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 8f238be776c..c8a3b5c72a1 100644 --- a/gdb/guile/lib/gdb.scm +++ b/gdb/guile/lib/gdb.scm @@ -212,6 +212,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 ea51d1b5e45..787b788d6ce 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" @@ -782,6 +783,60 @@ gdbscm_frame_sal (SCM self) return stscm_scm_from_sal (sal); } +/* (frame-read-register string) -> + 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, ®ister_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, + _("")); + } + + 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 ) -> (frame-read-var string [#:block ]) -> 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: \n\ Or: string [#:block ]" }, + { "frame-read-register", 2, 0, 0, gdbscm_frame_read_register, + "\ +Return the value of the register in the frame.\n\ +\n\ + Arguments: string" }, + { "frame-select", 1, 0, 0, gdbscm_frame_select, "\ Select this frame." }, diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 714210998e7..73785d62392 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-04-09 Andy Wingo + + * gdb.guile/scm-frame.exp: Add frame-read-register tests, modelled + after the Python tests. + 2015-04-08 Keith Seitz PR python/16699 diff --git a/gdb/testsuite/gdb.guile/scm-frame.exp b/gdb/testsuite/gdb.guile/scm-frame.exp index 7af9092daaa..9a5eb1ebb26 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.30.2