Home | History | Annotate | Line # | Download | only in guile
      1  1.1  christos /* Scheme interface to stack frames.
      2  1.1  christos 
      3  1.9  christos    Copyright (C) 2008-2024 Free Software Foundation, Inc.
      4  1.1  christos 
      5  1.1  christos    This file is part of GDB.
      6  1.1  christos 
      7  1.1  christos    This program is free software; you can redistribute it and/or modify
      8  1.1  christos    it under the terms of the GNU General Public License as published by
      9  1.1  christos    the Free Software Foundation; either version 3 of the License, or
     10  1.1  christos    (at your option) any later version.
     11  1.1  christos 
     12  1.1  christos    This program is distributed in the hope that it will be useful,
     13  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15  1.1  christos    GNU General Public License for more details.
     16  1.1  christos 
     17  1.1  christos    You should have received a copy of the GNU General Public License
     18  1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     19  1.1  christos 
     20  1.1  christos /* See README file in this directory for implementation notes, coding
     21  1.1  christos    conventions, et.al.  */
     22  1.1  christos 
     23  1.1  christos #include "block.h"
     24  1.1  christos #include "frame.h"
     25  1.1  christos #include "inferior.h"
     26  1.1  christos #include "objfiles.h"
     27  1.1  christos #include "symfile.h"
     28  1.1  christos #include "symtab.h"
     29  1.1  christos #include "stack.h"
     30  1.3  christos #include "user-regs.h"
     31  1.1  christos #include "value.h"
     32  1.1  christos #include "guile-internal.h"
     33  1.1  christos 
     34  1.8  christos /* The <gdb:frame> smob.  */
     35  1.1  christos 
     36  1.8  christos struct frame_smob
     37  1.1  christos {
     38  1.1  christos   /* This always appears first.  */
     39  1.1  christos   eqable_gdb_smob base;
     40  1.1  christos 
     41  1.1  christos   struct frame_id frame_id;
     42  1.1  christos   struct gdbarch *gdbarch;
     43  1.1  christos 
     44  1.1  christos   /* Frames are tracked by inferior.
     45  1.1  christos      We need some place to put the eq?-able hash table, and this feels as
     46  1.1  christos      good a place as any.  Frames in one inferior shouldn't be considered
     47  1.1  christos      equal to frames in a different inferior.  The frame becomes invalid if
     48  1.1  christos      this becomes NULL (the inferior has been deleted from gdb).
     49  1.1  christos      It's easier to relax restrictions than impose them after the fact.
     50  1.1  christos      N.B. It is an outstanding question whether a frame survives reruns of
     51  1.1  christos      the inferior.  Intuitively the answer is "No", but currently a frame
     52  1.1  christos      also survives, e.g., multiple invocations of the same function from
     53  1.1  christos      the same point.  Even different threads can have the same frame, e.g.,
     54  1.1  christos      if a thread dies and a new thread gets the same stack.  */
     55  1.1  christos   struct inferior *inferior;
     56  1.1  christos 
     57  1.1  christos   /* Marks that the FRAME_ID member actually holds the ID of the frame next
     58  1.1  christos      to this, and not this frame's ID itself.  This is a hack to permit Scheme
     59  1.1  christos      frame objects which represent invalid frames (i.e., the last frame_info
     60  1.1  christos      in a corrupt stack).  The problem arises from the fact that this code
     61  1.1  christos      relies on FRAME_ID to uniquely identify a frame, which is not always true
     62  1.1  christos      for the last "frame" in a corrupt stack (it can have a null ID, or the
     63  1.1  christos      same ID as the  previous frame).  Whenever get_prev_frame returns NULL, we
     64  1.1  christos      record the frame_id of the next frame and set FRAME_ID_IS_NEXT to 1.  */
     65  1.1  christos   int frame_id_is_next;
     66  1.1  christos };
     67  1.1  christos 
     68  1.1  christos static const char frame_smob_name[] = "gdb:frame";
     69  1.1  christos 
     70  1.1  christos /* The tag Guile knows the frame smob by.  */
     71  1.1  christos static scm_t_bits frame_smob_tag;
     72  1.1  christos 
     73  1.1  christos /* Keywords used in argument passing.  */
     74  1.1  christos static SCM block_keyword;
     75  1.1  christos 
     76  1.8  christos /* This is called when an inferior is about to be freed.
     77  1.8  christos    Invalidate the frame as further actions on the frame could result
     78  1.8  christos    in bad data.  All access to the frame should be gated by
     79  1.8  christos    frscm_get_frame_smob_arg_unsafe which will raise an exception on
     80  1.8  christos    invalid frames.  */
     81  1.8  christos struct frscm_deleter
     82  1.8  christos {
     83  1.8  christos   /* Helper function for frscm_del_inferior_frames to mark the frame
     84  1.8  christos      as invalid.  */
     85  1.8  christos 
     86  1.8  christos   static int
     87  1.8  christos   frscm_mark_frame_invalid (void **slot, void *info)
     88  1.8  christos   {
     89  1.8  christos     frame_smob *f_smob = (frame_smob *) *slot;
     90  1.8  christos 
     91  1.8  christos     f_smob->inferior = NULL;
     92  1.8  christos     return 1;
     93  1.8  christos   }
     94  1.8  christos 
     95  1.8  christos   void operator() (htab_t htab)
     96  1.8  christos   {
     97  1.8  christos     gdb_assert (htab != nullptr);
     98  1.8  christos     htab_traverse_noresize (htab, frscm_mark_frame_invalid, NULL);
     99  1.8  christos     htab_delete (htab);
    100  1.8  christos   }
    101  1.8  christos };
    102  1.8  christos 
    103  1.8  christos static const registry<inferior>::key<htab, frscm_deleter>
    104  1.8  christos     frscm_inferior_data_key;
    105  1.1  christos 
    106  1.1  christos /* Administrivia for frame smobs.  */
    108  1.1  christos 
    109  1.1  christos /* Helper function to hash a frame_smob.  */
    110  1.1  christos 
    111  1.1  christos static hashval_t
    112  1.1  christos frscm_hash_frame_smob (const void *p)
    113  1.4  christos {
    114  1.1  christos   const frame_smob *f_smob = (const frame_smob *) p;
    115  1.1  christos   const struct frame_id *fid = &f_smob->frame_id;
    116  1.1  christos   hashval_t hash = htab_hash_pointer (f_smob->inferior);
    117  1.1  christos 
    118  1.1  christos   if (fid->stack_status == FID_STACK_VALID)
    119  1.1  christos     hash = iterative_hash (&fid->stack_addr, sizeof (fid->stack_addr), hash);
    120  1.1  christos   if (fid->code_addr_p)
    121  1.1  christos     hash = iterative_hash (&fid->code_addr, sizeof (fid->code_addr), hash);
    122  1.1  christos   if (fid->special_addr_p)
    123  1.1  christos     hash = iterative_hash (&fid->special_addr, sizeof (fid->special_addr),
    124  1.1  christos 			   hash);
    125  1.1  christos 
    126  1.1  christos   return hash;
    127  1.1  christos }
    128  1.1  christos 
    129  1.1  christos /* Helper function to compute equality of frame_smobs.  */
    130  1.1  christos 
    131  1.1  christos static int
    132  1.1  christos frscm_eq_frame_smob (const void *ap, const void *bp)
    133  1.4  christos {
    134  1.4  christos   const frame_smob *a = (const frame_smob *) ap;
    135  1.1  christos   const frame_smob *b = (const frame_smob *) bp;
    136  1.8  christos 
    137  1.1  christos   return (a->frame_id == b->frame_id
    138  1.1  christos 	  && a->inferior == b->inferior
    139  1.1  christos 	  && a->inferior != NULL);
    140  1.1  christos }
    141  1.1  christos 
    142  1.1  christos /* Return the frame -> SCM mapping table.
    143  1.1  christos    It is created if necessary.  */
    144  1.1  christos 
    145  1.1  christos static htab_t
    146  1.1  christos frscm_inferior_frame_map (struct inferior *inferior)
    147  1.8  christos {
    148  1.1  christos   htab_t htab = frscm_inferior_data_key.get (inferior);
    149  1.1  christos 
    150  1.1  christos   if (htab == NULL)
    151  1.1  christos     {
    152  1.1  christos       htab = gdbscm_create_eqable_gsmob_ptr_map (frscm_hash_frame_smob,
    153  1.8  christos 						 frscm_eq_frame_smob);
    154  1.1  christos       frscm_inferior_data_key.set (inferior, htab);
    155  1.1  christos     }
    156  1.1  christos 
    157  1.1  christos   return htab;
    158  1.1  christos }
    159  1.1  christos 
    160  1.1  christos /* The smob "free" function for <gdb:frame>.  */
    161  1.1  christos 
    162  1.1  christos static size_t
    163  1.1  christos frscm_free_frame_smob (SCM self)
    164  1.1  christos {
    165  1.1  christos   frame_smob *f_smob = (frame_smob *) SCM_SMOB_DATA (self);
    166  1.1  christos 
    167  1.1  christos   if (f_smob->inferior != NULL)
    168  1.1  christos     {
    169  1.1  christos       htab_t htab = frscm_inferior_frame_map (f_smob->inferior);
    170  1.1  christos 
    171  1.1  christos       gdbscm_clear_eqable_gsmob_ptr_slot (htab, &f_smob->base);
    172  1.1  christos     }
    173  1.1  christos 
    174  1.1  christos   /* Not necessary, done to catch bugs.  */
    175  1.1  christos   f_smob->inferior = NULL;
    176  1.1  christos 
    177  1.1  christos   return 0;
    178  1.1  christos }
    179  1.1  christos 
    180  1.1  christos /* The smob "print" function for <gdb:frame>.  */
    181  1.1  christos 
    182  1.1  christos static int
    183  1.1  christos frscm_print_frame_smob (SCM self, SCM port, scm_print_state *pstate)
    184  1.1  christos {
    185  1.1  christos   frame_smob *f_smob = (frame_smob *) SCM_SMOB_DATA (self);
    186  1.8  christos 
    187  1.8  christos   gdbscm_printf (port, "#<%s %s>",
    188  1.8  christos 		 frame_smob_name,
    189  1.1  christos 		 f_smob->frame_id.to_string ().c_str ());
    190  1.1  christos   scm_remember_upto_here_1 (self);
    191  1.1  christos 
    192  1.1  christos   /* Non-zero means success.  */
    193  1.1  christos   return 1;
    194  1.1  christos }
    195  1.1  christos 
    196  1.1  christos /* Low level routine to create a <gdb:frame> object.  */
    197  1.1  christos 
    198  1.1  christos static SCM
    199  1.1  christos frscm_make_frame_smob (void)
    200  1.1  christos {
    201  1.1  christos   frame_smob *f_smob = (frame_smob *)
    202  1.1  christos     scm_gc_malloc (sizeof (frame_smob), frame_smob_name);
    203  1.1  christos   SCM f_scm;
    204  1.1  christos 
    205  1.1  christos   f_smob->frame_id = null_frame_id;
    206  1.1  christos   f_smob->gdbarch = NULL;
    207  1.1  christos   f_smob->inferior = NULL;
    208  1.1  christos   f_smob->frame_id_is_next = 0;
    209  1.1  christos   f_scm = scm_new_smob (frame_smob_tag, (scm_t_bits) f_smob);
    210  1.1  christos   gdbscm_init_eqable_gsmob (&f_smob->base, f_scm);
    211  1.1  christos 
    212  1.1  christos   return f_scm;
    213  1.1  christos }
    214  1.1  christos 
    215  1.1  christos /* Return non-zero if SCM is a <gdb:frame> object.  */
    216  1.1  christos 
    217  1.1  christos int
    218  1.1  christos frscm_is_frame (SCM scm)
    219  1.1  christos {
    220  1.1  christos   return SCM_SMOB_PREDICATE (frame_smob_tag, scm);
    221  1.1  christos }
    222  1.1  christos 
    223  1.1  christos /* (frame? object) -> boolean */
    224  1.1  christos 
    225  1.1  christos static SCM
    226  1.1  christos gdbscm_frame_p (SCM scm)
    227  1.1  christos {
    228  1.1  christos   return scm_from_bool (frscm_is_frame (scm));
    229  1.1  christos }
    230  1.1  christos 
    231  1.1  christos /* Create a new <gdb:frame> object that encapsulates FRAME.
    232  1.1  christos    Returns a <gdb:exception> object if there is an error.  */
    233  1.1  christos 
    234  1.1  christos static SCM
    235  1.1  christos frscm_scm_from_frame (struct frame_info *frame, struct inferior *inferior)
    236  1.1  christos {
    237  1.1  christos   frame_smob *f_smob, f_smob_for_lookup;
    238  1.1  christos   SCM f_scm;
    239  1.1  christos   htab_t htab;
    240  1.1  christos   eqable_gdb_smob **slot;
    241  1.1  christos   struct frame_id frame_id = null_frame_id;
    242  1.1  christos   struct gdbarch *gdbarch = NULL;
    243  1.1  christos   int frame_id_is_next = 0;
    244  1.1  christos 
    245  1.1  christos   /* If we've already created a gsmob for this frame, return it.
    246  1.1  christos      This makes frames eq?-able.  */
    247  1.8  christos   htab = frscm_inferior_frame_map (inferior);
    248  1.1  christos   f_smob_for_lookup.frame_id = get_frame_id (frame_info_ptr (frame));
    249  1.1  christos   f_smob_for_lookup.inferior = inferior;
    250  1.1  christos   slot = gdbscm_find_eqable_gsmob_ptr_slot (htab, &f_smob_for_lookup.base);
    251  1.1  christos   if (*slot != NULL)
    252  1.1  christos     return (*slot)->containing_scm;
    253  1.7  christos 
    254  1.1  christos   try
    255  1.8  christos     {
    256  1.8  christos       frame_info_ptr frame_ptr (frame);
    257  1.1  christos 
    258  1.1  christos       /* Try to get the previous frame, to determine if this is the last frame
    259  1.1  christos 	 in a corrupt stack.  If so, we need to store the frame_id of the next
    260  1.8  christos 	 frame and not of this one (which is possibly invalid).  */
    261  1.8  christos       if (get_prev_frame (frame_ptr) == NULL
    262  1.8  christos 	  && get_frame_unwind_stop_reason (frame_ptr) != UNWIND_NO_REASON
    263  1.1  christos 	  && get_next_frame (frame_ptr) != NULL)
    264  1.8  christos 	{
    265  1.1  christos 	  frame_id = get_frame_id (get_next_frame (frame_ptr));
    266  1.1  christos 	  frame_id_is_next = 1;
    267  1.1  christos 	}
    268  1.1  christos       else
    269  1.8  christos 	{
    270  1.1  christos 	  frame_id = get_frame_id (frame_ptr);
    271  1.1  christos 	  frame_id_is_next = 0;
    272  1.8  christos 	}
    273  1.1  christos       gdbarch = get_frame_arch (frame_ptr);
    274  1.7  christos     }
    275  1.3  christos   catch (const gdb_exception &except)
    276  1.7  christos     {
    277  1.3  christos       return gdbscm_scm_from_gdb_exception (unpack (except));
    278  1.1  christos     }
    279  1.1  christos 
    280  1.1  christos   f_scm = frscm_make_frame_smob ();
    281  1.1  christos   f_smob = (frame_smob *) SCM_SMOB_DATA (f_scm);
    282  1.1  christos   f_smob->frame_id = frame_id;
    283  1.1  christos   f_smob->gdbarch = gdbarch;
    284  1.1  christos   f_smob->inferior = inferior;
    285  1.1  christos   f_smob->frame_id_is_next = frame_id_is_next;
    286  1.1  christos 
    287  1.1  christos   gdbscm_fill_eqable_gsmob_ptr_slot (slot, &f_smob->base);
    288  1.1  christos 
    289  1.1  christos   return f_scm;
    290  1.1  christos }
    291  1.1  christos 
    292  1.1  christos /* Create a new <gdb:frame> object that encapsulates FRAME.
    293  1.1  christos    A Scheme exception is thrown if there is an error.  */
    294  1.1  christos 
    295  1.1  christos static SCM
    296  1.1  christos frscm_scm_from_frame_unsafe (struct frame_info *frame,
    297  1.1  christos 			     struct inferior *inferior)
    298  1.1  christos {
    299  1.1  christos   SCM f_scm = frscm_scm_from_frame (frame, inferior);
    300  1.1  christos 
    301  1.1  christos   if (gdbscm_is_exception (f_scm))
    302  1.1  christos     gdbscm_throw (f_scm);
    303  1.1  christos 
    304  1.1  christos   return f_scm;
    305  1.1  christos }
    306  1.1  christos 
    307  1.1  christos /* Returns the <gdb:frame> object in SELF.
    308  1.1  christos    Throws an exception if SELF is not a <gdb:frame> object.  */
    309  1.1  christos 
    310  1.1  christos static SCM
    311  1.1  christos frscm_get_frame_arg_unsafe (SCM self, int arg_pos, const char *func_name)
    312  1.1  christos {
    313  1.1  christos   SCM_ASSERT_TYPE (frscm_is_frame (self), self, arg_pos, func_name,
    314  1.1  christos 		   frame_smob_name);
    315  1.1  christos 
    316  1.1  christos   return self;
    317  1.1  christos }
    318  1.1  christos 
    319  1.1  christos /* There is no gdbscm_scm_to_frame function because translating
    320  1.1  christos    a frame SCM object to a struct frame_info * can throw a GDB error.
    321  1.1  christos    Thus code working with frames has to handle both Scheme errors (e.g., the
    322  1.1  christos    object is not a frame) and GDB errors (e.g., the frame lookup failed).
    323  1.3  christos 
    324  1.3  christos    To help keep things clear we split what would be gdbscm_scm_to_frame
    325  1.1  christos    into two:
    326  1.3  christos 
    327  1.1  christos    frscm_get_frame_smob_arg_unsafe
    328  1.1  christos      - throws a Scheme error if object is not a frame,
    329  1.1  christos        or if the inferior is gone or is no longer current
    330  1.3  christos 
    331  1.1  christos    frscm_frame_smob_to_frame
    332  1.1  christos      - may throw a gdb error if the conversion fails
    333  1.1  christos      - it's not clear when it will and won't throw a GDB error,
    334  1.1  christos        but for robustness' sake we assume that whenever we call out to GDB
    335  1.1  christos        a GDB error may get thrown (and thus the call must be wrapped in a
    336  1.1  christos        TRY_CATCH)  */
    337  1.1  christos 
    338  1.1  christos /* Returns the frame_smob for the object wrapped by FRAME_SCM.
    339  1.1  christos    A Scheme error is thrown if FRAME_SCM is not a frame.  */
    340  1.1  christos 
    341  1.1  christos frame_smob *
    342  1.1  christos frscm_get_frame_smob_arg_unsafe (SCM self, int arg_pos, const char *func_name)
    343  1.1  christos {
    344  1.1  christos   SCM f_scm = frscm_get_frame_arg_unsafe (self, arg_pos, func_name);
    345  1.1  christos   frame_smob *f_smob = (frame_smob *) SCM_SMOB_DATA (f_scm);
    346  1.1  christos 
    347  1.1  christos   if (f_smob->inferior == NULL)
    348  1.1  christos     {
    349  1.1  christos       gdbscm_invalid_object_error (func_name, arg_pos, self,
    350  1.1  christos 				   _("inferior"));
    351  1.1  christos     }
    352  1.1  christos   if (f_smob->inferior != current_inferior ())
    353  1.1  christos     scm_misc_error (func_name, _("inferior has changed"), SCM_EOL);
    354  1.1  christos 
    355  1.1  christos   return f_smob;
    356  1.1  christos }
    357  1.1  christos 
    358  1.1  christos /* Returns the frame_info object wrapped by F_SMOB.
    359  1.1  christos    If the frame doesn't exist anymore (the frame id doesn't
    360  1.1  christos    correspond to any frame in the inferior), returns NULL.
    361  1.1  christos    This function calls GDB routines, so don't assume a GDB error will
    362  1.1  christos    not be thrown.  */
    363  1.8  christos 
    364  1.1  christos struct frame_info_ptr
    365  1.1  christos frscm_frame_smob_to_frame (frame_smob *f_smob)
    366  1.8  christos {
    367  1.1  christos   frame_info_ptr frame = frame_find_by_id (f_smob->frame_id);
    368  1.1  christos   if (frame == NULL)
    369  1.1  christos     return NULL;
    370  1.1  christos 
    371  1.1  christos   if (f_smob->frame_id_is_next)
    372  1.1  christos     frame = get_prev_frame (frame);
    373  1.1  christos 
    374  1.1  christos   return frame;
    375  1.1  christos }
    376  1.1  christos 
    377  1.1  christos 
    378  1.1  christos /* Frame methods.  */
    380  1.1  christos 
    381  1.1  christos /* (frame-valid? <gdb:frame>) -> bool
    382  1.1  christos    Returns #t if the frame corresponding to the frame_id of this
    383  1.1  christos    object still exists in the inferior.  */
    384  1.1  christos 
    385  1.1  christos static SCM
    386  1.1  christos gdbscm_frame_valid_p (SCM self)
    387  1.8  christos {
    388  1.1  christos   frame_smob *f_smob;
    389  1.1  christos   bool result = false;
    390  1.1  christos 
    391  1.7  christos   f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
    392  1.7  christos 
    393  1.1  christos   gdbscm_gdb_exception exc {};
    394  1.8  christos   try
    395  1.8  christos     {
    396  1.1  christos       frame_info_ptr frame = frscm_frame_smob_to_frame (f_smob);
    397  1.7  christos       result = frame != nullptr;
    398  1.3  christos     }
    399  1.7  christos   catch (const gdb_exception &except)
    400  1.3  christos     {
    401  1.1  christos       exc = unpack (except);
    402  1.7  christos     }
    403  1.8  christos 
    404  1.1  christos   GDBSCM_HANDLE_GDB_EXCEPTION (exc);
    405  1.1  christos   return scm_from_bool (result);
    406  1.1  christos }
    407  1.1  christos 
    408  1.1  christos /* (frame-name <gdb:frame>) -> string
    409  1.1  christos    Returns the name of the function corresponding to this frame,
    410  1.1  christos    or #f if there is no function.  */
    411  1.1  christos 
    412  1.1  christos static SCM
    413  1.1  christos gdbscm_frame_name (SCM self)
    414  1.6  christos {
    415  1.1  christos   frame_smob *f_smob;
    416  1.8  christos   gdb::unique_xmalloc_ptr<char> name;
    417  1.1  christos   enum language lang = language_minimal;
    418  1.1  christos   bool found = false;
    419  1.1  christos   SCM result;
    420  1.1  christos 
    421  1.7  christos   f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
    422  1.7  christos 
    423  1.1  christos   gdbscm_gdb_exception exc {};
    424  1.8  christos   try
    425  1.1  christos     {
    426  1.8  christos       frame_info_ptr frame = frscm_frame_smob_to_frame (f_smob);
    427  1.8  christos       if (frame != NULL)
    428  1.8  christos 	{
    429  1.8  christos 	  found = true;
    430  1.1  christos 	  name = find_frame_funname (frame, &lang, NULL);
    431  1.7  christos 	}
    432  1.3  christos     }
    433  1.7  christos   catch (const gdb_exception &except)
    434  1.3  christos     {
    435  1.1  christos       exc = unpack (except);
    436  1.7  christos     }
    437  1.8  christos 
    438  1.1  christos   GDBSCM_HANDLE_GDB_EXCEPTION (exc);
    439  1.1  christos   if (!found)
    440  1.1  christos     {
    441  1.1  christos       gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
    442  1.1  christos 				   _("<gdb:frame>"));
    443  1.1  christos     }
    444  1.6  christos 
    445  1.1  christos   if (name != NULL)
    446  1.1  christos     result = gdbscm_scm_from_c_string (name.get ());
    447  1.1  christos   else
    448  1.1  christos     result = SCM_BOOL_F;
    449  1.1  christos 
    450  1.1  christos   return result;
    451  1.1  christos }
    452  1.1  christos 
    453  1.1  christos /* (frame-type <gdb:frame>) -> integer
    454  1.1  christos    Returns the frame type, namely one of the gdb:*_FRAME constants.  */
    455  1.1  christos 
    456  1.1  christos static SCM
    457  1.1  christos gdbscm_frame_type (SCM self)
    458  1.1  christos {
    459  1.8  christos   frame_smob *f_smob;
    460  1.1  christos   enum frame_type type = NORMAL_FRAME;
    461  1.1  christos   bool found = false;
    462  1.1  christos 
    463  1.7  christos   f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
    464  1.7  christos 
    465  1.1  christos   gdbscm_gdb_exception exc {};
    466  1.8  christos   try
    467  1.1  christos     {
    468  1.8  christos       frame_info_ptr frame = frscm_frame_smob_to_frame (f_smob);
    469  1.8  christos       if (frame != NULL)
    470  1.8  christos 	{
    471  1.8  christos 	  found = true;
    472  1.1  christos 	  type = get_frame_type (frame);
    473  1.7  christos 	}
    474  1.3  christos     }
    475  1.7  christos   catch (const gdb_exception &except)
    476  1.3  christos     {
    477  1.1  christos       exc = unpack (except);
    478  1.7  christos     }
    479  1.8  christos 
    480  1.1  christos   GDBSCM_HANDLE_GDB_EXCEPTION (exc);
    481  1.1  christos   if (!found)
    482  1.1  christos     {
    483  1.1  christos       gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
    484  1.1  christos 				   _("<gdb:frame>"));
    485  1.1  christos     }
    486  1.1  christos 
    487  1.1  christos   return scm_from_int (type);
    488  1.1  christos }
    489  1.1  christos 
    490  1.1  christos /* (frame-arch <gdb:frame>) -> <gdb:architecture>
    491  1.1  christos    Returns the frame's architecture as a gdb:architecture object.  */
    492  1.1  christos 
    493  1.1  christos static SCM
    494  1.1  christos gdbscm_frame_arch (SCM self)
    495  1.8  christos {
    496  1.1  christos   frame_smob *f_smob;
    497  1.1  christos   bool found = false;
    498  1.1  christos 
    499  1.7  christos   f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
    500  1.7  christos 
    501  1.1  christos   gdbscm_gdb_exception exc {};
    502  1.8  christos   try
    503  1.8  christos     {
    504  1.1  christos       frame_info_ptr frame = frscm_frame_smob_to_frame (f_smob);
    505  1.7  christos       found = frame != nullptr;
    506  1.3  christos     }
    507  1.7  christos   catch (const gdb_exception &except)
    508  1.3  christos     {
    509  1.1  christos       exc = unpack (except);
    510  1.7  christos     }
    511  1.8  christos 
    512  1.1  christos   GDBSCM_HANDLE_GDB_EXCEPTION (exc);
    513  1.1  christos   if (!found)
    514  1.1  christos     {
    515  1.1  christos       gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
    516  1.1  christos 				   _("<gdb:frame>"));
    517  1.1  christos     }
    518  1.1  christos 
    519  1.1  christos   return arscm_scm_from_arch (f_smob->gdbarch);
    520  1.1  christos }
    521  1.1  christos 
    522  1.1  christos /* (frame-unwind-stop-reason <gdb:frame>) -> integer
    523  1.1  christos    Returns one of the gdb:FRAME_UNWIND_* constants.  */
    524  1.1  christos 
    525  1.1  christos static SCM
    526  1.1  christos gdbscm_frame_unwind_stop_reason (SCM self)
    527  1.8  christos {
    528  1.8  christos   frame_smob *f_smob;
    529  1.1  christos   bool found = false;
    530  1.1  christos   enum unwind_stop_reason stop_reason = UNWIND_NO_REASON;
    531  1.1  christos 
    532  1.7  christos   f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
    533  1.7  christos 
    534  1.1  christos   gdbscm_gdb_exception exc {};
    535  1.8  christos   try
    536  1.8  christos     {
    537  1.8  christos       frame_info_ptr frame = frscm_frame_smob_to_frame (f_smob);
    538  1.8  christos       if (frame != nullptr)
    539  1.8  christos 	{
    540  1.8  christos 	  found = true;
    541  1.1  christos 	  stop_reason = get_frame_unwind_stop_reason (frame);
    542  1.7  christos 	}
    543  1.3  christos     }
    544  1.7  christos   catch (const gdb_exception &except)
    545  1.3  christos     {
    546  1.1  christos       exc = unpack (except);
    547  1.7  christos     }
    548  1.8  christos 
    549  1.1  christos   GDBSCM_HANDLE_GDB_EXCEPTION (exc);
    550  1.1  christos   if (!found)
    551  1.1  christos     {
    552  1.1  christos       gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
    553  1.1  christos 				   _("<gdb:frame>"));
    554  1.1  christos     }
    555  1.1  christos 
    556  1.1  christos   return scm_from_int (stop_reason);
    557  1.1  christos }
    558  1.1  christos 
    559  1.1  christos /* (frame-pc <gdb:frame>) -> integer
    560  1.1  christos    Returns the frame's resume address.  */
    561  1.1  christos 
    562  1.1  christos static SCM
    563  1.1  christos gdbscm_frame_pc (SCM self)
    564  1.1  christos {
    565  1.8  christos   frame_smob *f_smob;
    566  1.1  christos   CORE_ADDR pc = 0;
    567  1.1  christos   bool found = false;
    568  1.1  christos 
    569  1.7  christos   f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
    570  1.7  christos 
    571  1.1  christos   gdbscm_gdb_exception exc {};
    572  1.8  christos   try
    573  1.1  christos     {
    574  1.8  christos       frame_info_ptr frame = frscm_frame_smob_to_frame (f_smob);
    575  1.8  christos       if (frame != NULL)
    576  1.8  christos 	{
    577  1.8  christos 	  pc = get_frame_pc (frame);
    578  1.1  christos 	  found = true;
    579  1.7  christos 	}
    580  1.3  christos     }
    581  1.7  christos   catch (const gdb_exception &except)
    582  1.3  christos     {
    583  1.1  christos       exc = unpack (except);
    584  1.7  christos     }
    585  1.8  christos 
    586  1.1  christos   GDBSCM_HANDLE_GDB_EXCEPTION (exc);
    587  1.1  christos   if (!found)
    588  1.1  christos     {
    589  1.1  christos       gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
    590  1.1  christos 				   _("<gdb:frame>"));
    591  1.1  christos     }
    592  1.1  christos 
    593  1.1  christos   return gdbscm_scm_from_ulongest (pc);
    594  1.1  christos }
    595  1.1  christos 
    596  1.1  christos /* (frame-block <gdb:frame>) -> <gdb:block>
    597  1.1  christos    Returns the frame's code block, or #f if one cannot be found.  */
    598  1.1  christos 
    599  1.1  christos static SCM
    600  1.1  christos gdbscm_frame_block (SCM self)
    601  1.1  christos {
    602  1.8  christos   frame_smob *f_smob;
    603  1.1  christos   const struct block *block = NULL, *fn_block;
    604  1.1  christos   bool found = false;
    605  1.1  christos 
    606  1.7  christos   f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
    607  1.7  christos 
    608  1.1  christos   gdbscm_gdb_exception exc {};
    609  1.8  christos   try
    610  1.1  christos     {
    611  1.8  christos       frame_info_ptr frame = frscm_frame_smob_to_frame (f_smob);
    612  1.8  christos       if (frame != NULL)
    613  1.8  christos 	{
    614  1.8  christos 	  found = true;
    615  1.1  christos 	  block = get_frame_block (frame, NULL);
    616  1.7  christos 	}
    617  1.3  christos     }
    618  1.7  christos   catch (const gdb_exception &except)
    619  1.3  christos     {
    620  1.1  christos       exc = unpack (except);
    621  1.7  christos     }
    622  1.8  christos 
    623  1.1  christos   GDBSCM_HANDLE_GDB_EXCEPTION (exc);
    624  1.1  christos   if (!found)
    625  1.1  christos     {
    626  1.1  christos       gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
    627  1.1  christos 				   _("<gdb:frame>"));
    628  1.1  christos     }
    629  1.8  christos 
    630  1.8  christos   for (fn_block = block;
    631  1.1  christos        fn_block != NULL && fn_block->function () == NULL;
    632  1.1  christos        fn_block = fn_block->superblock ())
    633  1.8  christos     continue;
    634  1.1  christos 
    635  1.1  christos   if (block == NULL || fn_block == NULL || fn_block->function () == NULL)
    636  1.1  christos     {
    637  1.1  christos       scm_misc_error (FUNC_NAME, _("cannot find block for frame"),
    638  1.1  christos 		      scm_list_1 (self));
    639  1.1  christos     }
    640  1.1  christos 
    641  1.1  christos   if (block != NULL)
    642  1.8  christos     {
    643  1.1  christos       return bkscm_scm_from_block
    644  1.1  christos 	(block, fn_block->function ()->objfile ());
    645  1.1  christos     }
    646  1.1  christos 
    647  1.1  christos   return SCM_BOOL_F;
    648  1.1  christos }
    649  1.1  christos 
    650  1.1  christos /* (frame-function <gdb:frame>) -> <gdb:symbol>
    651  1.1  christos    Returns the symbol for the function corresponding to this frame,
    652  1.1  christos    or #f if there isn't one.  */
    653  1.1  christos 
    654  1.1  christos static SCM
    655  1.1  christos gdbscm_frame_function (SCM self)
    656  1.1  christos {
    657  1.8  christos   frame_smob *f_smob;
    658  1.1  christos   struct symbol *sym = NULL;
    659  1.1  christos   bool found = false;
    660  1.1  christos 
    661  1.7  christos   f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
    662  1.7  christos 
    663  1.1  christos   gdbscm_gdb_exception exc {};
    664  1.8  christos   try
    665  1.1  christos     {
    666  1.8  christos       frame_info_ptr frame = frscm_frame_smob_to_frame (f_smob);
    667  1.8  christos       if (frame != NULL)
    668  1.8  christos 	{
    669  1.8  christos 	  found = true;
    670  1.1  christos 	  sym = find_pc_function (get_frame_address_in_block (frame));
    671  1.7  christos 	}
    672  1.3  christos     }
    673  1.7  christos   catch (const gdb_exception &except)
    674  1.3  christos     {
    675  1.1  christos       exc = unpack (except);
    676  1.7  christos     }
    677  1.8  christos 
    678  1.1  christos   GDBSCM_HANDLE_GDB_EXCEPTION (exc);
    679  1.1  christos   if (!found)
    680  1.1  christos     {
    681  1.1  christos       gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
    682  1.1  christos 				   _("<gdb:frame>"));
    683  1.1  christos     }
    684  1.1  christos 
    685  1.1  christos   if (sym != NULL)
    686  1.1  christos     return syscm_scm_from_symbol (sym);
    687  1.1  christos 
    688  1.1  christos   return SCM_BOOL_F;
    689  1.1  christos }
    690  1.1  christos 
    691  1.1  christos /* (frame-older <gdb:frame>) -> <gdb:frame>
    692  1.1  christos    Returns the frame immediately older (outer) to this frame,
    693  1.1  christos    or #f if there isn't one.  */
    694  1.1  christos 
    695  1.1  christos static SCM
    696  1.1  christos gdbscm_frame_older (SCM self)
    697  1.1  christos {
    698  1.8  christos   frame_smob *f_smob;
    699  1.1  christos   struct frame_info *prev = NULL;
    700  1.1  christos   bool found = false;
    701  1.1  christos 
    702  1.7  christos   f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
    703  1.7  christos 
    704  1.1  christos   gdbscm_gdb_exception exc {};
    705  1.8  christos   try
    706  1.1  christos     {
    707  1.8  christos       frame_info_ptr frame = frscm_frame_smob_to_frame (f_smob);
    708  1.8  christos       if (frame != NULL)
    709  1.8  christos 	{
    710  1.8  christos 	  found = true;
    711  1.1  christos 	  prev = get_prev_frame (frame).get ();
    712  1.7  christos 	}
    713  1.3  christos     }
    714  1.7  christos   catch (const gdb_exception &except)
    715  1.3  christos     {
    716  1.1  christos       exc = unpack (except);
    717  1.7  christos     }
    718  1.8  christos 
    719  1.1  christos   GDBSCM_HANDLE_GDB_EXCEPTION (exc);
    720  1.1  christos   if (!found)
    721  1.1  christos     {
    722  1.1  christos       gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
    723  1.1  christos 				   _("<gdb:frame>"));
    724  1.1  christos     }
    725  1.1  christos 
    726  1.1  christos   if (prev != NULL)
    727  1.1  christos     return frscm_scm_from_frame_unsafe (prev, f_smob->inferior);
    728  1.1  christos 
    729  1.1  christos   return SCM_BOOL_F;
    730  1.1  christos }
    731  1.1  christos 
    732  1.1  christos /* (frame-newer <gdb:frame>) -> <gdb:frame>
    733  1.1  christos    Returns the frame immediately newer (inner) to this frame,
    734  1.1  christos    or #f if there isn't one.  */
    735  1.1  christos 
    736  1.1  christos static SCM
    737  1.1  christos gdbscm_frame_newer (SCM self)
    738  1.1  christos {
    739  1.8  christos   frame_smob *f_smob;
    740  1.1  christos   struct frame_info *next = NULL;
    741  1.1  christos   bool found = false;
    742  1.1  christos 
    743  1.7  christos   f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
    744  1.7  christos 
    745  1.1  christos   gdbscm_gdb_exception exc {};
    746  1.8  christos   try
    747  1.1  christos     {
    748  1.8  christos       frame_info_ptr frame = frscm_frame_smob_to_frame (f_smob);
    749  1.8  christos       if (frame != NULL)
    750  1.8  christos 	{
    751  1.8  christos 	  found = true;
    752  1.1  christos 	  next = get_next_frame (frame).get ();
    753  1.7  christos 	}
    754  1.3  christos     }
    755  1.7  christos   catch (const gdb_exception &except)
    756  1.3  christos     {
    757  1.1  christos       exc = unpack (except);
    758  1.7  christos     }
    759  1.8  christos 
    760  1.1  christos   GDBSCM_HANDLE_GDB_EXCEPTION (exc);
    761  1.1  christos   if (!found)
    762  1.1  christos     {
    763  1.1  christos       gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
    764  1.1  christos 				   _("<gdb:frame>"));
    765  1.1  christos     }
    766  1.1  christos 
    767  1.1  christos   if (next != NULL)
    768  1.1  christos     return frscm_scm_from_frame_unsafe (next, f_smob->inferior);
    769  1.1  christos 
    770  1.1  christos   return SCM_BOOL_F;
    771  1.1  christos }
    772  1.1  christos 
    773  1.1  christos /* (frame-sal <gdb:frame>) -> <gdb:sal>
    774  1.1  christos    Returns the frame's symtab and line.  */
    775  1.1  christos 
    776  1.1  christos static SCM
    777  1.1  christos gdbscm_frame_sal (SCM self)
    778  1.1  christos {
    779  1.8  christos   frame_smob *f_smob;
    780  1.1  christos   struct symtab_and_line sal;
    781  1.1  christos   bool found = false;
    782  1.1  christos 
    783  1.7  christos   f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
    784  1.7  christos 
    785  1.1  christos   gdbscm_gdb_exception exc {};
    786  1.8  christos   try
    787  1.1  christos     {
    788  1.8  christos       frame_info_ptr frame = frscm_frame_smob_to_frame (f_smob);
    789  1.8  christos       if (frame != NULL)
    790  1.8  christos 	{
    791  1.8  christos 	  found = true;
    792  1.1  christos 	  sal = find_frame_sal (frame);
    793  1.7  christos 	}
    794  1.3  christos     }
    795  1.7  christos   catch (const gdb_exception &except)
    796  1.3  christos     {
    797  1.1  christos       exc = unpack (except);
    798  1.7  christos     }
    799  1.8  christos 
    800  1.1  christos   GDBSCM_HANDLE_GDB_EXCEPTION (exc);
    801  1.1  christos   if (!found)
    802  1.1  christos     {
    803  1.1  christos       gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
    804  1.1  christos 				   _("<gdb:frame>"));
    805  1.1  christos     }
    806  1.1  christos 
    807  1.1  christos   return stscm_scm_from_sal (sal);
    808  1.3  christos }
    809  1.3  christos 
    810  1.3  christos /* (frame-read-register <gdb:frame> string) -> <gdb:value>
    811  1.3  christos    The register argument must be a string.  */
    812  1.3  christos 
    813  1.3  christos static SCM
    814  1.3  christos gdbscm_frame_read_register (SCM self, SCM register_scm)
    815  1.3  christos {
    816  1.8  christos   char *register_str;
    817  1.3  christos   struct value *value = NULL;
    818  1.3  christos   bool found = false;
    819  1.3  christos   frame_smob *f_smob;
    820  1.3  christos 
    821  1.3  christos   f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
    822  1.6  christos   gdbscm_parse_function_args (FUNC_NAME, SCM_ARG2, NULL, "s",
    823  1.7  christos 			      register_scm, &register_str);
    824  1.3  christos 
    825  1.7  christos   gdbscm_gdb_exception except {};
    826  1.3  christos 
    827  1.3  christos   try
    828  1.3  christos     {
    829  1.8  christos       int regnum;
    830  1.3  christos 
    831  1.3  christos       frame_info_ptr frame = frscm_frame_smob_to_frame (f_smob);
    832  1.8  christos       if (frame)
    833  1.3  christos 	{
    834  1.3  christos 	  found = true;
    835  1.3  christos 	  regnum = user_reg_map_name_to_regnum (get_frame_arch (frame),
    836  1.3  christos 						register_str,
    837  1.9  christos 						strlen (register_str));
    838  1.9  christos 	  if (regnum >= 0)
    839  1.3  christos 	    value = value_of_register (regnum,
    840  1.3  christos 				       get_next_frame_sentinel_okay (frame));
    841  1.7  christos 	}
    842  1.3  christos     }
    843  1.7  christos   catch (const gdb_exception &ex)
    844  1.3  christos     {
    845  1.3  christos       except = unpack (ex);
    846  1.6  christos     }
    847  1.6  christos 
    848  1.3  christos   xfree (register_str);
    849  1.8  christos   GDBSCM_HANDLE_GDB_EXCEPTION (except);
    850  1.3  christos 
    851  1.3  christos   if (!found)
    852  1.3  christos     {
    853  1.3  christos       gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
    854  1.3  christos 				   _("<gdb:frame>"));
    855  1.3  christos     }
    856  1.3  christos 
    857  1.3  christos   if (value == NULL)
    858  1.3  christos     {
    859  1.3  christos       gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG2, register_scm,
    860  1.3  christos 				 _("unknown register"));
    861  1.3  christos     }
    862  1.3  christos 
    863  1.3  christos   return vlscm_scm_from_value (value);
    864  1.1  christos }
    865  1.1  christos 
    866  1.1  christos /* (frame-read-var <gdb:frame> <gdb:symbol>) -> <gdb:value>
    867  1.1  christos    (frame-read-var <gdb:frame> string [#:block <gdb:block>]) -> <gdb:value>
    868  1.1  christos    If the optional block argument is provided start the search from that block,
    869  1.1  christos    otherwise search from the frame's current block (determined by examining
    870  1.1  christos    the resume address of the frame).  The variable argument must be a string
    871  1.1  christos    or an instance of a <gdb:symbol>.  The block argument must be an instance of
    872  1.1  christos    <gdb:block>.  */
    873  1.1  christos 
    874  1.1  christos static SCM
    875  1.1  christos gdbscm_frame_read_var (SCM self, SCM symbol_scm, SCM rest)
    876  1.1  christos {
    877  1.1  christos   SCM keywords[] = { block_keyword, SCM_BOOL_F };
    878  1.1  christos   frame_smob *f_smob;
    879  1.1  christos   int block_arg_pos = -1;
    880  1.1  christos   SCM block_scm = SCM_UNDEFINED;
    881  1.4  christos   struct frame_info *frame = NULL;
    882  1.1  christos   struct symbol *var = NULL;
    883  1.1  christos   const struct block *block = NULL;
    884  1.1  christos   struct value *value = NULL;
    885  1.1  christos 
    886  1.7  christos   f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
    887  1.7  christos 
    888  1.1  christos   gdbscm_gdb_exception exc {};
    889  1.8  christos   try
    890  1.1  christos     {
    891  1.7  christos       frame = frscm_frame_smob_to_frame (f_smob).get ();
    892  1.3  christos     }
    893  1.7  christos   catch (const gdb_exception &except)
    894  1.3  christos     {
    895  1.1  christos       exc = unpack (except);
    896  1.7  christos     }
    897  1.1  christos 
    898  1.1  christos   GDBSCM_HANDLE_GDB_EXCEPTION (exc);
    899  1.1  christos   if (frame == NULL)
    900  1.1  christos     {
    901  1.1  christos       gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
    902  1.1  christos 				   _("<gdb:frame>"));
    903  1.1  christos     }
    904  1.1  christos 
    905  1.1  christos   gdbscm_parse_function_args (FUNC_NAME, SCM_ARG3, keywords, "#O",
    906  1.1  christos 			      rest, &block_arg_pos, &block_scm);
    907  1.1  christos 
    908  1.1  christos   if (syscm_is_symbol (symbol_scm))
    909  1.1  christos     {
    910  1.1  christos       var = syscm_get_valid_symbol_arg_unsafe (symbol_scm, SCM_ARG2,
    911  1.1  christos 					       FUNC_NAME);
    912  1.1  christos       SCM_ASSERT (SCM_UNBNDP (block_scm), block_scm, SCM_ARG3, FUNC_NAME);
    913  1.1  christos     }
    914  1.7  christos   else if (scm_is_string (symbol_scm))
    915  1.1  christos     {
    916  1.1  christos       gdbscm_gdb_exception except {};
    917  1.1  christos 
    918  1.1  christos       if (! SCM_UNBNDP (block_scm))
    919  1.1  christos 	{
    920  1.1  christos 	  SCM except_scm;
    921  1.1  christos 
    922  1.1  christos 	  gdb_assert (block_arg_pos > 0);
    923  1.1  christos 	  block = bkscm_scm_to_block (block_scm, block_arg_pos, FUNC_NAME,
    924  1.1  christos 				      &except_scm);
    925  1.1  christos 	  if (block == NULL)
    926  1.1  christos 	    gdbscm_throw (except_scm);
    927  1.6  christos 	}
    928  1.6  christos 
    929  1.6  christos       {
    930  1.6  christos 	gdb::unique_xmalloc_ptr<char> var_name
    931  1.6  christos 	  (gdbscm_scm_to_c_string (symbol_scm));
    932  1.6  christos 	/* N.B. Between here and the end of the scope, don't do anything
    933  1.7  christos 	   to cause a Scheme exception.  */
    934  1.6  christos 
    935  1.6  christos 	try
    936  1.6  christos 	  {
    937  1.6  christos 	    struct block_symbol lookup_sym;
    938  1.8  christos 
    939  1.9  christos 	    if (block == NULL)
    940  1.6  christos 	      block = get_frame_block (frame_info_ptr (frame), NULL);
    941  1.6  christos 	    lookup_sym = lookup_symbol (var_name.get (), block, SEARCH_VFT,
    942  1.6  christos 					NULL);
    943  1.6  christos 	    var = lookup_sym.symbol;
    944  1.7  christos 	    block = lookup_sym.block;
    945  1.6  christos 	  }
    946  1.7  christos 	catch (const gdb_exception &ex)
    947  1.6  christos 	  {
    948  1.6  christos 	    except = unpack (ex);
    949  1.4  christos 	  }
    950  1.1  christos       }
    951  1.1  christos 
    952  1.1  christos       GDBSCM_HANDLE_GDB_EXCEPTION (except);
    953  1.6  christos 
    954  1.6  christos       if (var == NULL)
    955  1.1  christos 	gdbscm_out_of_range_error (FUNC_NAME, 0, symbol_scm,
    956  1.1  christos 				   _("variable not found"));
    957  1.1  christos     }
    958  1.1  christos   else
    959  1.1  christos     {
    960  1.1  christos       /* Use SCM_ASSERT_TYPE for more consistent error messages.  */
    961  1.1  christos       SCM_ASSERT_TYPE (0, symbol_scm, SCM_ARG1, FUNC_NAME,
    962  1.1  christos 		       _("gdb:symbol or string"));
    963  1.7  christos     }
    964  1.1  christos 
    965  1.8  christos   try
    966  1.1  christos     {
    967  1.7  christos       value = read_var_value (var, block, frame_info_ptr (frame));
    968  1.3  christos     }
    969  1.7  christos   catch (const gdb_exception &except)
    970  1.3  christos     {
    971  1.1  christos       exc = unpack (except);
    972  1.7  christos     }
    973  1.1  christos 
    974  1.1  christos   GDBSCM_HANDLE_GDB_EXCEPTION (exc);
    975  1.1  christos   return vlscm_scm_from_value (value);
    976  1.1  christos }
    977  1.1  christos 
    978  1.1  christos /* (frame-select <gdb:frame>) -> unspecified
    979  1.1  christos    Select this frame.  */
    980  1.1  christos 
    981  1.1  christos static SCM
    982  1.1  christos gdbscm_frame_select (SCM self)
    983  1.8  christos {
    984  1.1  christos   frame_smob *f_smob;
    985  1.1  christos   bool found = false;
    986  1.1  christos 
    987  1.7  christos   f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
    988  1.7  christos 
    989  1.1  christos   gdbscm_gdb_exception exc {};
    990  1.8  christos   try
    991  1.1  christos     {
    992  1.8  christos       frame_info_ptr frame = frscm_frame_smob_to_frame (f_smob);
    993  1.8  christos       if (frame != NULL)
    994  1.8  christos 	{
    995  1.8  christos 	  found = true;
    996  1.1  christos 	  select_frame (frame);
    997  1.7  christos 	}
    998  1.3  christos     }
    999  1.7  christos   catch (const gdb_exception &except)
   1000  1.3  christos     {
   1001  1.1  christos       exc = unpack (except);
   1002  1.7  christos     }
   1003  1.8  christos 
   1004  1.1  christos   GDBSCM_HANDLE_GDB_EXCEPTION (exc);
   1005  1.1  christos   if (!found)
   1006  1.1  christos     {
   1007  1.1  christos       gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
   1008  1.1  christos 				   _("<gdb:frame>"));
   1009  1.1  christos     }
   1010  1.1  christos 
   1011  1.1  christos   return SCM_UNSPECIFIED;
   1012  1.1  christos }
   1013  1.1  christos 
   1014  1.1  christos /* (newest-frame) -> <gdb:frame>
   1015  1.1  christos    Returns the newest frame.  */
   1016  1.1  christos 
   1017  1.1  christos static SCM
   1018  1.1  christos gdbscm_newest_frame (void)
   1019  1.1  christos {
   1020  1.7  christos   struct frame_info *frame = NULL;
   1021  1.7  christos 
   1022  1.1  christos   gdbscm_gdb_exception exc {};
   1023  1.8  christos   try
   1024  1.1  christos     {
   1025  1.7  christos       frame = get_current_frame ().get ();
   1026  1.3  christos     }
   1027  1.7  christos   catch (const gdb_exception &except)
   1028  1.3  christos     {
   1029  1.1  christos       exc = unpack (except);
   1030  1.7  christos     }
   1031  1.1  christos 
   1032  1.1  christos   GDBSCM_HANDLE_GDB_EXCEPTION (exc);
   1033  1.1  christos   return frscm_scm_from_frame_unsafe (frame, current_inferior ());
   1034  1.1  christos }
   1035  1.1  christos 
   1036  1.1  christos /* (selected-frame) -> <gdb:frame>
   1037  1.1  christos    Returns the selected frame.  */
   1038  1.1  christos 
   1039  1.1  christos static SCM
   1040  1.1  christos gdbscm_selected_frame (void)
   1041  1.1  christos {
   1042  1.7  christos   struct frame_info *frame = NULL;
   1043  1.7  christos 
   1044  1.1  christos   gdbscm_gdb_exception exc {};
   1045  1.8  christos   try
   1046  1.1  christos     {
   1047  1.7  christos       frame = get_selected_frame (_("No frame is currently selected")).get ();
   1048  1.3  christos     }
   1049  1.7  christos   catch (const gdb_exception &except)
   1050  1.3  christos     {
   1051  1.1  christos       exc = unpack (except);
   1052  1.7  christos     }
   1053  1.1  christos 
   1054  1.1  christos   GDBSCM_HANDLE_GDB_EXCEPTION (exc);
   1055  1.1  christos   return frscm_scm_from_frame_unsafe (frame, current_inferior ());
   1056  1.1  christos }
   1057  1.1  christos 
   1058  1.1  christos /* (unwind-stop-reason-string integer) -> string
   1059  1.1  christos    Return a string explaining the unwind stop reason.  */
   1060  1.1  christos 
   1061  1.1  christos static SCM
   1062  1.1  christos gdbscm_unwind_stop_reason_string (SCM reason_scm)
   1063  1.1  christos {
   1064  1.1  christos   int reason;
   1065  1.1  christos   const char *str;
   1066  1.1  christos 
   1067  1.1  christos   gdbscm_parse_function_args (FUNC_NAME, SCM_ARG1, NULL, "i",
   1068  1.1  christos 			      reason_scm, &reason);
   1069  1.1  christos 
   1070  1.1  christos   if (reason < UNWIND_FIRST || reason > UNWIND_LAST)
   1071  1.4  christos     scm_out_of_range (FUNC_NAME, reason_scm);
   1072  1.1  christos 
   1073  1.1  christos   str = unwind_stop_reason_to_string ((enum unwind_stop_reason) reason);
   1074  1.1  christos   return gdbscm_scm_from_c_string (str);
   1075  1.1  christos }
   1076  1.1  christos 
   1077  1.1  christos /* Initialize the Scheme frame support.  */
   1079  1.1  christos 
   1080  1.1  christos static const scheme_integer_constant frame_integer_constants[] =
   1081  1.1  christos {
   1082  1.1  christos #define ENTRY(X) { #X, X }
   1083  1.1  christos 
   1084  1.1  christos   ENTRY (NORMAL_FRAME),
   1085  1.1  christos   ENTRY (DUMMY_FRAME),
   1086  1.1  christos   ENTRY (INLINE_FRAME),
   1087  1.1  christos   ENTRY (TAILCALL_FRAME),
   1088  1.1  christos   ENTRY (SIGTRAMP_FRAME),
   1089  1.1  christos   ENTRY (ARCH_FRAME),
   1090  1.1  christos   ENTRY (SENTINEL_FRAME),
   1091  1.1  christos 
   1092  1.1  christos #undef ENTRY
   1093  1.1  christos 
   1094  1.1  christos #define SET(name, description) \
   1095  1.1  christos   { "FRAME_" #name, name },
   1096  1.1  christos #include "unwind_stop_reasons.def"
   1097  1.1  christos #undef SET
   1098  1.1  christos 
   1099  1.1  christos   END_INTEGER_CONSTANTS
   1100  1.1  christos };
   1101  1.4  christos 
   1102  1.1  christos static const scheme_function frame_functions[] =
   1103  1.1  christos {
   1104  1.1  christos   { "frame?", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_p),
   1105  1.4  christos     "\
   1106  1.1  christos Return #t if the object is a <gdb:frame> object." },
   1107  1.1  christos 
   1108  1.1  christos   { "frame-valid?", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_valid_p),
   1109  1.1  christos     "\
   1110  1.4  christos Return #t if the object is a valid <gdb:frame> object.\n\
   1111  1.1  christos Frames become invalid when the inferior returns to its caller." },
   1112  1.1  christos 
   1113  1.1  christos   { "frame-name", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_name),
   1114  1.1  christos     "\
   1115  1.4  christos Return the name of the function corresponding to this frame,\n\
   1116  1.1  christos or #f if there is no function." },
   1117  1.1  christos 
   1118  1.1  christos   { "frame-arch", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_arch),
   1119  1.4  christos     "\
   1120  1.1  christos Return the frame's architecture as a <gdb:arch> object." },
   1121  1.1  christos 
   1122  1.1  christos   { "frame-type", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_type),
   1123  1.4  christos     "\
   1124  1.4  christos Return the frame type, namely one of the gdb:*_FRAME constants." },
   1125  1.1  christos 
   1126  1.1  christos   { "frame-unwind-stop-reason", 1, 0, 0,
   1127  1.1  christos     as_a_scm_t_subr (gdbscm_frame_unwind_stop_reason),
   1128  1.1  christos     "\
   1129  1.4  christos Return one of the gdb:FRAME_UNWIND_* constants explaining why\n\
   1130  1.1  christos it's not possible to find frames older than this." },
   1131  1.1  christos 
   1132  1.1  christos   { "frame-pc", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_pc),
   1133  1.4  christos     "\
   1134  1.1  christos Return the frame's resume address." },
   1135  1.1  christos 
   1136  1.1  christos   { "frame-block", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_block),
   1137  1.4  christos     "\
   1138  1.1  christos Return the frame's code block, or #f if one cannot be found." },
   1139  1.1  christos 
   1140  1.1  christos   { "frame-function", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_function),
   1141  1.1  christos     "\
   1142  1.4  christos Return the <gdb:symbol> for the function corresponding to this frame,\n\
   1143  1.1  christos or #f if there isn't one." },
   1144  1.1  christos 
   1145  1.1  christos   { "frame-older", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_older),
   1146  1.1  christos     "\
   1147  1.4  christos Return the frame immediately older (outer) to this frame,\n\
   1148  1.1  christos or #f if there isn't one." },
   1149  1.1  christos 
   1150  1.1  christos   { "frame-newer", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_newer),
   1151  1.1  christos     "\
   1152  1.4  christos Return the frame immediately newer (inner) to this frame,\n\
   1153  1.1  christos or #f if there isn't one." },
   1154  1.1  christos 
   1155  1.1  christos   { "frame-sal", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_sal),
   1156  1.4  christos     "\
   1157  1.1  christos Return the frame's symtab-and-line <gdb:sal> object." },
   1158  1.1  christos 
   1159  1.1  christos   { "frame-read-var", 2, 0, 1, as_a_scm_t_subr (gdbscm_frame_read_var),
   1160  1.1  christos     "\
   1161  1.8  christos Return the value of the symbol in the frame.\n\
   1162  1.1  christos \n\
   1163  1.4  christos   Arguments: <gdb:frame> <gdb:symbol>\n\
   1164  1.4  christos 	 Or: <gdb:frame> string [#:block <gdb:block>]" },
   1165  1.3  christos 
   1166  1.3  christos   { "frame-read-register", 2, 0, 0,
   1167  1.3  christos     as_a_scm_t_subr (gdbscm_frame_read_register),
   1168  1.3  christos     "\
   1169  1.3  christos Return the value of the register in the frame.\n\
   1170  1.4  christos \n\
   1171  1.1  christos   Arguments: <gdb:frame> string" },
   1172  1.1  christos 
   1173  1.1  christos   { "frame-select", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_select),
   1174  1.4  christos     "\
   1175  1.1  christos Select this frame." },
   1176  1.1  christos 
   1177  1.1  christos   { "newest-frame", 0, 0, 0, as_a_scm_t_subr (gdbscm_newest_frame),
   1178  1.4  christos     "\
   1179  1.1  christos Return the newest frame." },
   1180  1.1  christos 
   1181  1.1  christos   { "selected-frame", 0, 0, 0, as_a_scm_t_subr (gdbscm_selected_frame),
   1182  1.4  christos     "\
   1183  1.4  christos Return the selected frame." },
   1184  1.1  christos 
   1185  1.1  christos   { "unwind-stop-reason-string", 1, 0, 0,
   1186  1.1  christos     as_a_scm_t_subr (gdbscm_unwind_stop_reason_string),
   1187  1.1  christos     "\
   1188  1.1  christos Return a string explaining the unwind stop reason.\n\
   1189  1.1  christos \n\
   1190  1.1  christos   Arguments: integer (the result of frame-unwind-stop-reason)" },
   1191  1.1  christos 
   1192  1.1  christos   END_FUNCTIONS
   1193  1.1  christos };
   1194  1.1  christos 
   1195  1.1  christos void
   1196  1.1  christos gdbscm_initialize_frames (void)
   1197  1.1  christos {
   1198  1.1  christos   frame_smob_tag
   1199  1.1  christos     = gdbscm_make_smob_type (frame_smob_name, sizeof (frame_smob));
   1200  1.1  christos   scm_set_smob_free (frame_smob_tag, frscm_free_frame_smob);
   1201  1.1  christos   scm_set_smob_print (frame_smob_tag, frscm_print_frame_smob);
   1202  1.1  christos 
   1203  1.1  christos   gdbscm_define_integer_constants (frame_integer_constants, 1);
   1204  1.1  christos   gdbscm_define_functions (frame_functions, 1);
   1205                
   1206                  block_keyword = scm_from_latin1_keyword ("block");
   1207                }
   1208