Revert 'Remove unused struct serial::name field'
[deliverable/binutils-gdb.git] / gdb / guile / scm-frame.c
index c335385e830d7d6bcdd3629f1745aad2e8365ac3..3617eb77ded2d4ebe17a9b844584bb47a8fb5e05 100644 (file)
@@ -1,6 +1,6 @@
 /* Scheme interface to stack frames.
 
-   Copyright (C) 2008-2014 Free Software Foundation, Inc.
+   Copyright (C) 2008-2020 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -28,6 +28,7 @@
 #include "symfile.h"
 #include "symtab.h"
 #include "stack.h"
+#include "user-regs.h"
 #include "value.h"
 #include "guile-internal.h"
 
@@ -83,7 +84,7 @@ static const struct inferior_data *frscm_inferior_data_key;
 static hashval_t
 frscm_hash_frame_smob (const void *p)
 {
-  const frame_smob *f_smob = p;
+  const frame_smob *f_smob = (const frame_smob *) p;
   const struct frame_id *fid = &f_smob->frame_id;
   hashval_t hash = htab_hash_pointer (f_smob->inferior);
 
@@ -103,8 +104,8 @@ frscm_hash_frame_smob (const void *p)
 static int
 frscm_eq_frame_smob (const void *ap, const void *bp)
 {
-  const frame_smob *a = ap;
-  const frame_smob *b = bp;
+  const frame_smob *a = (const frame_smob *) ap;
+  const frame_smob *b = (const frame_smob *) bp;
 
   return (frame_id_eq (a->frame_id, b->frame_id)
          && a->inferior == b->inferior
@@ -117,7 +118,7 @@ frscm_eq_frame_smob (const void *ap, const void *bp)
 static htab_t
 frscm_inferior_frame_map (struct inferior *inferior)
 {
-  htab_t htab = inferior_data (inferior, frscm_inferior_data_key);
+  htab_t htab = (htab_t) inferior_data (inferior, frscm_inferior_data_key);
 
   if (htab == NULL)
     {
@@ -155,17 +156,12 @@ static int
 frscm_print_frame_smob (SCM self, SCM port, scm_print_state *pstate)
 {
   frame_smob *f_smob = (frame_smob *) SCM_SMOB_DATA (self);
-  struct ui_file *strfile;
-  char *s;
 
   gdbscm_printf (port, "#<%s ", frame_smob_name);
 
-  strfile = mem_fileopen ();
-  fprint_frame_id (strfile, f_smob->frame_id);
-  s = ui_file_xstrdup (strfile, NULL);
-  gdbscm_printf (port, "%s", s);
-  ui_file_delete (strfile);
-  xfree (s);
+  string_file strfile;
+  fprint_frame_id (&strfile, f_smob->frame_id);
+  gdbscm_printf (port, "%s", strfile.c_str ());
 
   scm_puts (">", port);
 
@@ -220,7 +216,6 @@ frscm_scm_from_frame (struct frame_info *frame, struct inferior *inferior)
   SCM f_scm;
   htab_t htab;
   eqable_gdb_smob **slot;
-  volatile struct gdb_exception except;
   struct frame_id frame_id = null_frame_id;
   struct gdbarch *gdbarch = NULL;
   int frame_id_is_next = 0;
@@ -234,7 +229,7 @@ frscm_scm_from_frame (struct frame_info *frame, struct inferior *inferior)
   if (*slot != NULL)
     return (*slot)->containing_scm;
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  try
     {
       /* Try to get the previous frame, to determine if this is the last frame
         in a corrupt stack.  If so, we need to store the frame_id of the next
@@ -253,8 +248,10 @@ frscm_scm_from_frame (struct frame_info *frame, struct inferior *inferior)
        }
       gdbarch = get_frame_arch (frame);
     }
-  if (except.reason < 0)
-    return gdbscm_scm_from_gdb_exception (except);
+  catch (const gdb_exception &except)
+    {
+      return gdbscm_scm_from_gdb_exception (unpack (except));
+    }
 
   f_scm = frscm_make_frame_smob ();
   f_smob = (frame_smob *) SCM_SMOB_DATA (f_scm);
@@ -300,13 +297,14 @@ frscm_get_frame_arg_unsafe (SCM self, int arg_pos, const char *func_name)
    Thus code working with frames has to handle both Scheme errors (e.g., the
    object is not a frame) and GDB errors (e.g., the frame lookup failed).
 
-   To help keep things clear we split gdbscm_scm_to_frame into two:
+   To help keep things clear we split what would be gdbscm_scm_to_frame
+   into two:
 
-   gdbscm_get_frame_smob_arg_unsafe
+   frscm_get_frame_smob_arg_unsafe
      - throws a Scheme error if object is not a frame,
        or if the inferior is gone or is no longer current
 
-   gdbscm_frame_smob_to_frame
+   frscm_frame_smob_to_frame
      - may throw a gdb error if the conversion fails
      - it's not clear when it will and won't throw a GDB error,
        but for robustness' sake we assume that whenever we call out to GDB
@@ -375,7 +373,7 @@ frscm_mark_frame_invalid (void **slot, void *info)
 static void
 frscm_del_inferior_frames (struct inferior *inferior, void *datum)
 {
-  htab_t htab = datum;
+  htab_t htab = (htab_t) datum;
 
   if (htab != NULL)
     {
@@ -395,16 +393,20 @@ gdbscm_frame_valid_p (SCM self)
 {
   frame_smob *f_smob;
   struct frame_info *frame = NULL;
-  volatile struct gdb_exception except;
 
   f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  gdbscm_gdb_exception exc {};
+  try
     {
       frame = frscm_frame_smob_to_frame (f_smob);
     }
-  GDBSCM_HANDLE_GDB_EXCEPTION (except);
+  catch (const gdb_exception &except)
+    {
+      exc = unpack (except);
+    }
 
+  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
   return scm_from_bool (frame != NULL);
 }
 
@@ -416,24 +418,26 @@ static SCM
 gdbscm_frame_name (SCM self)
 {
   frame_smob *f_smob;
-  char *name = NULL;
+  gdb::unique_xmalloc_ptr<char> name;
   enum language lang = language_minimal;
   struct frame_info *frame = NULL;
   SCM result;
-  volatile struct gdb_exception except;
 
   f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  gdbscm_gdb_exception exc {};
+  try
     {
       frame = frscm_frame_smob_to_frame (f_smob);
       if (frame != NULL)
-       find_frame_funname (frame, &name, &lang, NULL);
+       name = find_frame_funname (frame, &lang, NULL);
+    }
+  catch (const gdb_exception &except)
+    {
+      exc = unpack (except);
     }
-  if (except.reason < 0)
-    xfree (name);
-  GDBSCM_HANDLE_GDB_EXCEPTION (except);
 
+  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
   if (frame == NULL)
     {
       gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
@@ -441,10 +445,7 @@ gdbscm_frame_name (SCM self)
     }
 
   if (name != NULL)
-    {
-      result = gdbscm_scm_from_c_string (name);
-      xfree (name);
-    }
+    result = gdbscm_scm_from_c_string (name.get ());
   else
     result = SCM_BOOL_F;
 
@@ -460,18 +461,22 @@ gdbscm_frame_type (SCM self)
   frame_smob *f_smob;
   enum frame_type type = NORMAL_FRAME;
   struct frame_info *frame = NULL;
-  volatile struct gdb_exception except;
 
   f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  gdbscm_gdb_exception exc {};
+  try
     {
       frame = frscm_frame_smob_to_frame (f_smob);
       if (frame != NULL)
        type = get_frame_type (frame);
     }
-  GDBSCM_HANDLE_GDB_EXCEPTION (except);
+  catch (const gdb_exception &except)
+    {
+      exc = unpack (except);
+    }
 
+  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
   if (frame == NULL)
     {
       gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
@@ -489,16 +494,20 @@ gdbscm_frame_arch (SCM self)
 {
   frame_smob *f_smob;
   struct frame_info *frame = NULL;
-  volatile struct gdb_exception except;
 
   f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  gdbscm_gdb_exception exc {};
+  try
     {
       frame = frscm_frame_smob_to_frame (f_smob);
     }
-  GDBSCM_HANDLE_GDB_EXCEPTION (except);
+  catch (const gdb_exception &except)
+    {
+      exc = unpack (except);
+    }
 
+  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
   if (frame == NULL)
     {
       gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
@@ -516,17 +525,21 @@ gdbscm_frame_unwind_stop_reason (SCM self)
 {
   frame_smob *f_smob;
   struct frame_info *frame = NULL;
-  volatile struct gdb_exception except;
   enum unwind_stop_reason stop_reason;
 
   f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  gdbscm_gdb_exception exc {};
+  try
     {
       frame = frscm_frame_smob_to_frame (f_smob);
     }
-  GDBSCM_HANDLE_GDB_EXCEPTION (except);
+  catch (const gdb_exception &except)
+    {
+      exc = unpack (except);
+    }
 
+  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
   if (frame == NULL)
     {
       gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
@@ -547,18 +560,22 @@ gdbscm_frame_pc (SCM self)
   frame_smob *f_smob;
   CORE_ADDR pc = 0;
   struct frame_info *frame = NULL;
-  volatile struct gdb_exception except;
 
   f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  gdbscm_gdb_exception exc {};
+  try
     {
       frame = frscm_frame_smob_to_frame (f_smob);
       if (frame != NULL)
        pc = get_frame_pc (frame);
     }
-  GDBSCM_HANDLE_GDB_EXCEPTION (except);
+  catch (const gdb_exception &except)
+    {
+      exc = unpack (except);
+    }
 
+  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
   if (frame == NULL)
     {
       gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
@@ -577,18 +594,22 @@ gdbscm_frame_block (SCM self)
   frame_smob *f_smob;
   const struct block *block = NULL, *fn_block;
   struct frame_info *frame = NULL;
-  volatile struct gdb_exception except;
 
   f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  gdbscm_gdb_exception exc {};
+  try
     {
       frame = frscm_frame_smob_to_frame (f_smob);
       if (frame != NULL)
        block = get_frame_block (frame, NULL);
     }
-  GDBSCM_HANDLE_GDB_EXCEPTION (except);
+  catch (const gdb_exception &except)
+    {
+      exc = unpack (except);
+    }
 
+  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
   if (frame == NULL)
     {
       gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
@@ -608,11 +629,8 @@ gdbscm_frame_block (SCM self)
 
   if (block != NULL)
     {
-      struct symtab *st;
-      SCM block_scm;
-
-      st = SYMBOL_SYMTAB (BLOCK_FUNCTION (fn_block));
-      return bkscm_scm_from_block (block, st->objfile);
+      return bkscm_scm_from_block
+       (block, symbol_objfile (BLOCK_FUNCTION (fn_block)));
     }
 
   return SCM_BOOL_F;
@@ -628,18 +646,22 @@ gdbscm_frame_function (SCM self)
   frame_smob *f_smob;
   struct symbol *sym = NULL;
   struct frame_info *frame = NULL;
-  volatile struct gdb_exception except;
 
   f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  gdbscm_gdb_exception exc {};
+  try
     {
       frame = frscm_frame_smob_to_frame (f_smob);
       if (frame != NULL)
        sym = find_pc_function (get_frame_address_in_block (frame));
     }
-  GDBSCM_HANDLE_GDB_EXCEPTION (except);
+  catch (const gdb_exception &except)
+    {
+      exc = unpack (except);
+    }
 
+  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
   if (frame == NULL)
     {
       gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
@@ -662,18 +684,22 @@ gdbscm_frame_older (SCM self)
   frame_smob *f_smob;
   struct frame_info *prev = NULL;
   struct frame_info *frame = NULL;
-  volatile struct gdb_exception except;
 
   f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  gdbscm_gdb_exception exc {};
+  try
     {
       frame = frscm_frame_smob_to_frame (f_smob);
       if (frame != NULL)
        prev = get_prev_frame (frame);
     }
-  GDBSCM_HANDLE_GDB_EXCEPTION (except);
+  catch (const gdb_exception &except)
+    {
+      exc = unpack (except);
+    }
 
+  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
   if (frame == NULL)
     {
       gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
@@ -696,18 +722,22 @@ gdbscm_frame_newer (SCM self)
   frame_smob *f_smob;
   struct frame_info *next = NULL;
   struct frame_info *frame = NULL;
-  volatile struct gdb_exception except;
 
   f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  gdbscm_gdb_exception exc {};
+  try
     {
       frame = frscm_frame_smob_to_frame (f_smob);
       if (frame != NULL)
        next = get_next_frame (frame);
     }
-  GDBSCM_HANDLE_GDB_EXCEPTION (except);
+  catch (const gdb_exception &except)
+    {
+      exc = unpack (except);
+    }
 
+  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
   if (frame == NULL)
     {
       gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
@@ -729,18 +759,22 @@ gdbscm_frame_sal (SCM self)
   frame_smob *f_smob;
   struct symtab_and_line sal;
   struct frame_info *frame = NULL;
-  volatile struct gdb_exception except;
 
   f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  gdbscm_gdb_exception exc {};
+  try
     {
       frame = frscm_frame_smob_to_frame (f_smob);
       if (frame != NULL)
-       find_frame_sal (frame, &sal);
+       sal = find_frame_sal (frame);
+    }
+  catch (const gdb_exception &except)
+    {
+      exc = unpack (except);
     }
-  GDBSCM_HANDLE_GDB_EXCEPTION (except);
 
+  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
   if (frame == NULL)
     {
       gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
@@ -750,6 +784,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;
+  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);
+
+  gdbscm_gdb_exception except {};
+
+  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 (const gdb_exception &ex)
+    {
+      except = unpack (ex);
+    }
+
+  xfree (register_str);
+  GDBSCM_HANDLE_GDB_EXCEPTION (except);
+
+  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,
@@ -762,23 +850,27 @@ static SCM
 gdbscm_frame_read_var (SCM self, SCM symbol_scm, SCM rest)
 {
   SCM keywords[] = { block_keyword, SCM_BOOL_F };
-  int rc;
   frame_smob *f_smob;
   int block_arg_pos = -1;
   SCM block_scm = SCM_UNDEFINED;
   struct frame_info *frame = NULL;
   struct symbol *var = NULL;
+  const struct block *block = NULL;
   struct value *value = NULL;
-  volatile struct gdb_exception except;
 
   f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  gdbscm_gdb_exception exc {};
+  try
     {
       frame = frscm_frame_smob_to_frame (f_smob);
     }
-  GDBSCM_HANDLE_GDB_EXCEPTION (except);
+  catch (const gdb_exception &except)
+    {
+      exc = unpack (except);
+    }
 
+  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
   if (frame == NULL)
     {
       gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
@@ -796,10 +888,7 @@ gdbscm_frame_read_var (SCM self, SCM symbol_scm, SCM rest)
     }
   else if (scm_is_string (symbol_scm))
     {
-      char *var_name;
-      const struct block *block = NULL;
-      struct cleanup *cleanup;
-      volatile struct gdb_exception except;
+      gdbscm_gdb_exception except {};
 
       if (! SCM_UNBNDP (block_scm))
        {
@@ -812,29 +901,34 @@ gdbscm_frame_read_var (SCM self, SCM symbol_scm, SCM rest)
            gdbscm_throw (except_scm);
        }
 
-      var_name = gdbscm_scm_to_c_string (symbol_scm);
-      cleanup = make_cleanup (xfree, var_name);
-      /* N.B. Between here and the call to do_cleanups, don't do anything
-        to cause a Scheme exception without performing the cleanup.  */
+      {
+       gdb::unique_xmalloc_ptr<char> var_name
+         (gdbscm_scm_to_c_string (symbol_scm));
+       /* N.B. Between here and the end of the scope, don't do anything
+          to cause a Scheme exception.  */
+
+       try
+         {
+           struct block_symbol lookup_sym;
+
+           if (block == NULL)
+             block = get_frame_block (frame, NULL);
+           lookup_sym = lookup_symbol (var_name.get (), block, VAR_DOMAIN,
+                                       NULL);
+           var = lookup_sym.symbol;
+           block = lookup_sym.block;
+         }
+       catch (const gdb_exception &ex)
+         {
+           except = unpack (ex);
+         }
+      }
 
-      TRY_CATCH (except, RETURN_MASK_ALL)
-       {
-         if (block == NULL)
-           block = get_frame_block (frame, NULL);
-         var = lookup_symbol (var_name, block, VAR_DOMAIN, NULL);
-       }
-      if (except.reason < 0)
-       do_cleanups (cleanup);
       GDBSCM_HANDLE_GDB_EXCEPTION (except);
 
       if (var == NULL)
-       {
-         do_cleanups (cleanup);
-         gdbscm_out_of_range_error (FUNC_NAME, 0, symbol_scm,
-                                    _("variable not found"));
-       }
-
-      do_cleanups (cleanup);
+       gdbscm_out_of_range_error (FUNC_NAME, 0, symbol_scm,
+                                  _("variable not found"));
     }
   else
     {
@@ -843,12 +937,16 @@ gdbscm_frame_read_var (SCM self, SCM symbol_scm, SCM rest)
                       _("gdb:symbol or string"));
     }
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  try
     {
-      value = read_var_value (var, frame);
+      value = read_var_value (var, block, frame);
+    }
+  catch (const gdb_exception &except)
+    {
+      exc = unpack (except);
     }
-  GDBSCM_HANDLE_GDB_EXCEPTION (except);
 
+  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
   return vlscm_scm_from_value (value);
 }
 
@@ -860,18 +958,22 @@ gdbscm_frame_select (SCM self)
 {
   frame_smob *f_smob;
   struct frame_info *frame = NULL;
-  volatile struct gdb_exception except;
 
   f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  gdbscm_gdb_exception exc {};
+  try
     {
       frame = frscm_frame_smob_to_frame (f_smob);
       if (frame != NULL)
        select_frame (frame);
     }
-  GDBSCM_HANDLE_GDB_EXCEPTION (except);
+  catch (const gdb_exception &except)
+    {
+      exc = unpack (except);
+    }
 
+  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
   if (frame == NULL)
     {
       gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
@@ -888,14 +990,18 @@ static SCM
 gdbscm_newest_frame (void)
 {
   struct frame_info *frame = NULL;
-  volatile struct gdb_exception except;
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  gdbscm_gdb_exception exc {};
+  try
     {
       frame = get_current_frame ();
     }
-  GDBSCM_HANDLE_GDB_EXCEPTION (except);
+  catch (const gdb_exception &except)
+    {
+      exc = unpack (except);
+    }
 
+  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
   return frscm_scm_from_frame_unsafe (frame, current_inferior ());
 }
 
@@ -906,14 +1012,18 @@ static SCM
 gdbscm_selected_frame (void)
 {
   struct frame_info *frame = NULL;
-  volatile struct gdb_exception except;
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  gdbscm_gdb_exception exc {};
+  try
     {
       frame = get_selected_frame (_("No frame is currently selected"));
     }
-  GDBSCM_HANDLE_GDB_EXCEPTION (except);
+  catch (const gdb_exception &except)
+    {
+      exc = unpack (except);
+    }
 
+  GDBSCM_HANDLE_GDB_EXCEPTION (exc);
   return frscm_scm_from_frame_unsafe (frame, current_inferior ());
 }
 
@@ -932,7 +1042,7 @@ gdbscm_unwind_stop_reason_string (SCM reason_scm)
   if (reason < UNWIND_FIRST || reason > UNWIND_LAST)
     scm_out_of_range (FUNC_NAME, reason_scm);
 
-  str = unwind_stop_reason_to_string (reason);
+  str = unwind_stop_reason_to_string ((enum unwind_stop_reason) reason);
   return gdbscm_scm_from_c_string (str);
 }
 \f
@@ -962,80 +1072,89 @@ static const scheme_integer_constant frame_integer_constants[] =
 
 static const scheme_function frame_functions[] =
 {
-  { "frame?", 1, 0, 0, gdbscm_frame_p,
+  { "frame?", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_p),
     "\
 Return #t if the object is a <gdb:frame> object." },
 
-  { "frame-valid?", 1, 0, 0, gdbscm_frame_valid_p,
+  { "frame-valid?", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_valid_p),
     "\
 Return #t if the object is a valid <gdb:frame> object.\n\
 Frames become invalid when the inferior returns to its caller." },
 
-  { "frame-name", 1, 0, 0, gdbscm_frame_name,
+  { "frame-name", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_name),
     "\
 Return the name of the function corresponding to this frame,\n\
 or #f if there is no function." },
 
-  { "frame-arch", 1, 0, 0, gdbscm_frame_arch,
+  { "frame-arch", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_arch),
     "\
 Return the frame's architecture as a <gdb:arch> object." },
 
-  { "frame-type", 1, 0, 0, gdbscm_frame_type,
+  { "frame-type", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_type),
     "\
 Return the frame type, namely one of the gdb:*_FRAME constants." },
 
-  { "frame-unwind-stop-reason", 1, 0, 0, gdbscm_frame_unwind_stop_reason,
+  { "frame-unwind-stop-reason", 1, 0, 0,
+    as_a_scm_t_subr (gdbscm_frame_unwind_stop_reason),
     "\
 Return one of the gdb:FRAME_UNWIND_* constants explaining why\n\
 it's not possible to find frames older than this." },
 
-  { "frame-pc", 1, 0, 0, gdbscm_frame_pc,
+  { "frame-pc", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_pc),
     "\
 Return the frame's resume address." },
 
-  { "frame-block", 1, 0, 0, gdbscm_frame_block,
+  { "frame-block", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_block),
     "\
 Return the frame's code block, or #f if one cannot be found." },
 
-  { "frame-function", 1, 0, 0, gdbscm_frame_function,
+  { "frame-function", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_function),
     "\
 Return the <gdb:symbol> for the function corresponding to this frame,\n\
 or #f if there isn't one." },
 
-  { "frame-older", 1, 0, 0, gdbscm_frame_older,
+  { "frame-older", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_older),
     "\
 Return the frame immediately older (outer) to this frame,\n\
 or #f if there isn't one." },
 
-  { "frame-newer", 1, 0, 0, gdbscm_frame_newer,
+  { "frame-newer", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_newer),
     "\
 Return the frame immediately newer (inner) to this frame,\n\
 or #f if there isn't one." },
 
-  { "frame-sal", 1, 0, 0, gdbscm_frame_sal,
+  { "frame-sal", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_sal),
     "\
 Return the frame's symtab-and-line <gdb:sal> object." },
 
-  { "frame-read-var", 2, 0, 1, gdbscm_frame_read_var,
+  { "frame-read-var", 2, 0, 1, as_a_scm_t_subr (gdbscm_frame_read_var),
     "\
 Return the value of the symbol in the frame.\n\
 \n\
   Arguments: <gdb:frame> <gdb:symbol>\n\
          Or: <gdb:frame> string [#:block <gdb:block>]" },
 
-  { "frame-select", 1, 0, 0, gdbscm_frame_select,
+  { "frame-read-register", 2, 0, 0,
+    as_a_scm_t_subr (gdbscm_frame_read_register),
+    "\
+Return the value of the register in the frame.\n\
+\n\
+  Arguments: <gdb:frame> string" },
+
+  { "frame-select", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_select),
     "\
 Select this frame." },
 
-  { "newest-frame", 0, 0, 0, gdbscm_newest_frame,
+  { "newest-frame", 0, 0, 0, as_a_scm_t_subr (gdbscm_newest_frame),
     "\
 Return the newest frame." },
 
-  { "selected-frame", 0, 0, 0, gdbscm_selected_frame,
+  { "selected-frame", 0, 0, 0, as_a_scm_t_subr (gdbscm_selected_frame),
     "\
 Return the selected frame." },
 
-  { "unwind-stop-reason-string", 1, 0, 0, gdbscm_unwind_stop_reason_string,
+  { "unwind-stop-reason-string", 1, 0, 0,
+    as_a_scm_t_subr (gdbscm_unwind_stop_reason_string),
     "\
 Return a string explaining the unwind stop reason.\n\
 \n\
This page took 0.040006 seconds and 4 git commands to generate.