Home | History | Annotate | Line # | Download | only in guile
      1  1.1  christos /* Scheme interface to symbol tables.
      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 "symtab.h"
     24  1.1  christos #include "source.h"
     25  1.1  christos #include "objfiles.h"
     26  1.1  christos #include "block.h"
     27  1.1  christos #include "guile-internal.h"
     28  1.1  christos 
     29  1.1  christos /* A <gdb:symtab> smob.  */
     30  1.1  christos 
     31  1.8  christos struct symtab_smob
     32  1.1  christos {
     33  1.1  christos   /* This always appears first.
     34  1.1  christos      eqable_gdb_smob is used so that symtabs are eq?-able.
     35  1.1  christos      Also, a symtab object is associated with an objfile.  eqable_gdb_smob
     36  1.1  christos      lets us track the lifetime of all symtabs associated with an objfile.
     37  1.1  christos      When an objfile is deleted we need to invalidate the symtab object.  */
     38  1.1  christos   eqable_gdb_smob base;
     39  1.1  christos 
     40  1.1  christos   /* The GDB symbol table structure.
     41  1.1  christos      If this is NULL the symtab is invalid.  This can happen when the
     42  1.1  christos      underlying objfile is freed.  */
     43  1.1  christos   struct symtab *symtab;
     44  1.8  christos };
     45  1.1  christos 
     46  1.1  christos /* A <gdb:sal> smob.
     47  1.1  christos    A smob describing a gdb symtab-and-line object.
     48  1.1  christos    A sal is associated with an objfile.  All access must be gated by checking
     49  1.1  christos    the validity of symtab_scm.
     50  1.1  christos    TODO: Sals are not eq?-able at the moment, or even comparable.  */
     51  1.1  christos 
     52  1.8  christos struct sal_smob
     53  1.1  christos {
     54  1.1  christos   /* This always appears first.  */
     55  1.1  christos   gdb_smob base;
     56  1.1  christos 
     57  1.1  christos   /* The <gdb:symtab> object of the symtab.
     58  1.1  christos      We store this instead of a pointer to the symtab_smob because it's not
     59  1.1  christos      clear GC will know the symtab_smob is referenced by us otherwise, and we
     60  1.1  christos      need quick access to symtab_smob->symtab to know if this sal is valid.  */
     61  1.1  christos   SCM symtab_scm;
     62  1.1  christos 
     63  1.1  christos   /* The GDB symbol table and line structure.
     64  1.1  christos      This object is ephemeral in GDB, so keep our own copy.
     65  1.1  christos      The symtab pointer in this struct is not usable: If the symtab is deleted
     66  1.1  christos      this pointer will not be updated.  Use symtab_scm instead to determine
     67  1.1  christos      if this sal is valid.  */
     68  1.1  christos   struct symtab_and_line sal;
     69  1.8  christos };
     70  1.1  christos 
     71  1.1  christos static const char symtab_smob_name[] = "gdb:symtab";
     72  1.1  christos /* "symtab-and-line" is pretty long, and "sal" is short and unique.  */
     73  1.1  christos static const char sal_smob_name[] = "gdb:sal";
     74  1.1  christos 
     75  1.1  christos /* The tags Guile knows the symbol table smobs by.  */
     76  1.1  christos static scm_t_bits symtab_smob_tag;
     77  1.1  christos static scm_t_bits sal_smob_tag;
     78  1.1  christos 
     79  1.8  christos /* This is called when an objfile is about to be freed.
     80  1.8  christos    Invalidate the symbol table as further actions on the symbol table
     81  1.8  christos    would result in bad data.  All access to st_smob->symtab should be
     82  1.8  christos    gated by stscm_get_valid_symtab_smob_arg_unsafe which will raise an
     83  1.8  christos    exception on invalid symbol tables.  */
     84  1.8  christos struct stscm_deleter
     85  1.8  christos {
     86  1.8  christos   /* Helper function for stscm_del_objfile_symtabs to mark the symtab
     87  1.8  christos      as invalid.  */
     88  1.8  christos 
     89  1.8  christos   static int
     90  1.8  christos   stscm_mark_symtab_invalid (void **slot, void *info)
     91  1.8  christos   {
     92  1.8  christos     symtab_smob *st_smob = (symtab_smob *) *slot;
     93  1.8  christos 
     94  1.8  christos     st_smob->symtab = NULL;
     95  1.8  christos     return 1;
     96  1.8  christos   }
     97  1.8  christos 
     98  1.8  christos   void operator() (htab_t htab)
     99  1.8  christos   {
    100  1.8  christos     gdb_assert (htab != nullptr);
    101  1.8  christos     htab_traverse_noresize (htab, stscm_mark_symtab_invalid, NULL);
    102  1.8  christos     htab_delete (htab);
    103  1.8  christos   }
    104  1.8  christos };
    105  1.8  christos 
    106  1.8  christos static const registry<objfile>::key<htab, stscm_deleter>
    107  1.8  christos      stscm_objfile_data_key;
    108  1.1  christos 
    109  1.1  christos /* Administrivia for symtab smobs.  */
    111  1.1  christos 
    112  1.1  christos /* Helper function to hash a symbol_smob.  */
    113  1.1  christos 
    114  1.1  christos static hashval_t
    115  1.1  christos stscm_hash_symtab_smob (const void *p)
    116  1.4  christos {
    117  1.1  christos   const symtab_smob *st_smob = (const symtab_smob *) p;
    118  1.1  christos 
    119  1.1  christos   return htab_hash_pointer (st_smob->symtab);
    120  1.1  christos }
    121  1.1  christos 
    122  1.1  christos /* Helper function to compute equality of symtab_smobs.  */
    123  1.1  christos 
    124  1.1  christos static int
    125  1.1  christos stscm_eq_symtab_smob (const void *ap, const void *bp)
    126  1.4  christos {
    127  1.4  christos   const symtab_smob *a = (const symtab_smob *) ap;
    128  1.1  christos   const symtab_smob *b = (const symtab_smob *) bp;
    129  1.1  christos 
    130  1.1  christos   return (a->symtab == b->symtab
    131  1.1  christos 	  && a->symtab != NULL);
    132  1.1  christos }
    133  1.1  christos 
    134  1.1  christos /* Return the struct symtab pointer -> SCM mapping table.
    135  1.1  christos    It is created if necessary.  */
    136  1.1  christos 
    137  1.1  christos static htab_t
    138  1.1  christos stscm_objfile_symtab_map (struct symtab *symtab)
    139  1.8  christos {
    140  1.8  christos   struct objfile *objfile = symtab->compunit ()->objfile ();
    141  1.1  christos   htab_t htab = stscm_objfile_data_key.get (objfile);
    142  1.1  christos 
    143  1.1  christos   if (htab == NULL)
    144  1.1  christos     {
    145  1.1  christos       htab = gdbscm_create_eqable_gsmob_ptr_map (stscm_hash_symtab_smob,
    146  1.8  christos 						 stscm_eq_symtab_smob);
    147  1.1  christos       stscm_objfile_data_key.set (objfile, htab);
    148  1.1  christos     }
    149  1.1  christos 
    150  1.1  christos   return htab;
    151  1.1  christos }
    152  1.1  christos 
    153  1.1  christos /* The smob "free" function for <gdb:symtab>.  */
    154  1.1  christos 
    155  1.1  christos static size_t
    156  1.1  christos stscm_free_symtab_smob (SCM self)
    157  1.1  christos {
    158  1.1  christos   symtab_smob *st_smob = (symtab_smob *) SCM_SMOB_DATA (self);
    159  1.1  christos 
    160  1.1  christos   if (st_smob->symtab != NULL)
    161  1.1  christos     {
    162  1.1  christos       htab_t htab = stscm_objfile_symtab_map (st_smob->symtab);
    163  1.1  christos 
    164  1.1  christos       gdbscm_clear_eqable_gsmob_ptr_slot (htab, &st_smob->base);
    165  1.1  christos     }
    166  1.1  christos 
    167  1.1  christos   /* Not necessary, done to catch bugs.  */
    168  1.1  christos   st_smob->symtab = NULL;
    169  1.1  christos 
    170  1.1  christos   return 0;
    171  1.1  christos }
    172  1.1  christos 
    173  1.1  christos /* The smob "print" function for <gdb:symtab>.  */
    174  1.1  christos 
    175  1.1  christos static int
    176  1.1  christos stscm_print_symtab_smob (SCM self, SCM port, scm_print_state *pstate)
    177  1.1  christos {
    178  1.1  christos   symtab_smob *st_smob = (symtab_smob *) SCM_SMOB_DATA (self);
    179  1.1  christos 
    180  1.1  christos   gdbscm_printf (port, "#<%s ", symtab_smob_name);
    181  1.1  christos   gdbscm_printf (port, "%s",
    182  1.1  christos 		 st_smob->symtab != NULL
    183  1.1  christos 		 ? symtab_to_filename_for_display (st_smob->symtab)
    184  1.1  christos 		 : "<invalid>");
    185  1.1  christos   scm_puts (">", port);
    186  1.1  christos 
    187  1.1  christos   scm_remember_upto_here_1 (self);
    188  1.1  christos 
    189  1.1  christos   /* Non-zero means success.  */
    190  1.1  christos   return 1;
    191  1.1  christos }
    192  1.1  christos 
    193  1.1  christos /* Low level routine to create a <gdb:symtab> object.  */
    194  1.1  christos 
    195  1.1  christos static SCM
    196  1.1  christos stscm_make_symtab_smob (void)
    197  1.1  christos {
    198  1.1  christos   symtab_smob *st_smob = (symtab_smob *)
    199  1.1  christos     scm_gc_malloc (sizeof (symtab_smob), symtab_smob_name);
    200  1.1  christos   SCM st_scm;
    201  1.1  christos 
    202  1.1  christos   st_smob->symtab = NULL;
    203  1.1  christos   st_scm = scm_new_smob (symtab_smob_tag, (scm_t_bits) st_smob);
    204  1.1  christos   gdbscm_init_eqable_gsmob (&st_smob->base, st_scm);
    205  1.1  christos 
    206  1.1  christos   return st_scm;
    207  1.1  christos }
    208  1.1  christos 
    209  1.1  christos /* Return non-zero if SCM is a symbol table smob.  */
    210  1.1  christos 
    211  1.1  christos static int
    212  1.1  christos stscm_is_symtab (SCM scm)
    213  1.1  christos {
    214  1.1  christos   return SCM_SMOB_PREDICATE (symtab_smob_tag, scm);
    215  1.1  christos }
    216  1.1  christos 
    217  1.1  christos /* (symtab? object) -> boolean */
    218  1.1  christos 
    219  1.1  christos static SCM
    220  1.1  christos gdbscm_symtab_p (SCM scm)
    221  1.1  christos {
    222  1.1  christos   return scm_from_bool (stscm_is_symtab (scm));
    223  1.1  christos }
    224  1.1  christos 
    225  1.1  christos /* Create a new <gdb:symtab> object that encapsulates SYMTAB.  */
    226  1.1  christos 
    227  1.1  christos SCM
    228  1.1  christos stscm_scm_from_symtab (struct symtab *symtab)
    229  1.1  christos {
    230  1.1  christos   htab_t htab;
    231  1.1  christos   eqable_gdb_smob **slot;
    232  1.1  christos   symtab_smob *st_smob, st_smob_for_lookup;
    233  1.1  christos   SCM st_scm;
    234  1.1  christos 
    235  1.1  christos   /* If we've already created a gsmob for this symtab, return it.
    236  1.1  christos      This makes symtabs eq?-able.  */
    237  1.1  christos   htab = stscm_objfile_symtab_map (symtab);
    238  1.1  christos   st_smob_for_lookup.symtab = symtab;
    239  1.1  christos   slot = gdbscm_find_eqable_gsmob_ptr_slot (htab, &st_smob_for_lookup.base);
    240  1.1  christos   if (*slot != NULL)
    241  1.1  christos     return (*slot)->containing_scm;
    242  1.1  christos 
    243  1.1  christos   st_scm = stscm_make_symtab_smob ();
    244  1.1  christos   st_smob = (symtab_smob *) SCM_SMOB_DATA (st_scm);
    245  1.1  christos   st_smob->symtab = symtab;
    246  1.1  christos   gdbscm_fill_eqable_gsmob_ptr_slot (slot, &st_smob->base);
    247  1.1  christos 
    248  1.1  christos   return st_scm;
    249  1.1  christos }
    250  1.1  christos 
    251  1.1  christos /* Returns the <gdb:symtab> object in SELF.
    252  1.1  christos    Throws an exception if SELF is not a <gdb:symtab> object.  */
    253  1.1  christos 
    254  1.1  christos static SCM
    255  1.1  christos stscm_get_symtab_arg_unsafe (SCM self, int arg_pos, const char *func_name)
    256  1.1  christos {
    257  1.1  christos   SCM_ASSERT_TYPE (stscm_is_symtab (self), self, arg_pos, func_name,
    258  1.1  christos 		   symtab_smob_name);
    259  1.1  christos 
    260  1.1  christos   return self;
    261  1.1  christos }
    262  1.1  christos 
    263  1.1  christos /* Returns a pointer to the symtab smob of SELF.
    264  1.1  christos    Throws an exception if SELF is not a <gdb:symtab> object.  */
    265  1.1  christos 
    266  1.1  christos static symtab_smob *
    267  1.1  christos stscm_get_symtab_smob_arg_unsafe (SCM self, int arg_pos, const char *func_name)
    268  1.1  christos {
    269  1.1  christos   SCM st_scm = stscm_get_symtab_arg_unsafe (self, arg_pos, func_name);
    270  1.1  christos   symtab_smob *st_smob = (symtab_smob *) SCM_SMOB_DATA (st_scm);
    271  1.1  christos 
    272  1.1  christos   return st_smob;
    273  1.1  christos }
    274  1.1  christos 
    275  1.1  christos /* Return non-zero if symtab ST_SMOB is valid.  */
    276  1.1  christos 
    277  1.1  christos static int
    278  1.1  christos stscm_is_valid (symtab_smob *st_smob)
    279  1.1  christos {
    280  1.1  christos   return st_smob->symtab != NULL;
    281  1.1  christos }
    282  1.1  christos 
    283  1.1  christos /* Throw a Scheme error if SELF is not a valid symtab smob.
    284  1.1  christos    Otherwise return a pointer to the symtab_smob object.  */
    285  1.1  christos 
    286  1.1  christos static symtab_smob *
    287  1.1  christos stscm_get_valid_symtab_smob_arg_unsafe (SCM self, int arg_pos,
    288  1.1  christos 					const char *func_name)
    289  1.1  christos {
    290  1.1  christos   symtab_smob *st_smob
    291  1.1  christos     = stscm_get_symtab_smob_arg_unsafe (self, arg_pos, func_name);
    292  1.1  christos 
    293  1.1  christos   if (!stscm_is_valid (st_smob))
    294  1.1  christos     {
    295  1.1  christos       gdbscm_invalid_object_error (func_name, arg_pos, self,
    296  1.1  christos 				   _("<gdb:symtab>"));
    297  1.1  christos     }
    298  1.1  christos 
    299  1.1  christos   return st_smob;
    300  1.1  christos }
    301  1.1  christos 
    302  1.1  christos 
    303  1.1  christos /* Symbol table methods.  */
    305  1.1  christos 
    306  1.1  christos /* (symtab-valid? <gdb:symtab>) -> boolean
    307  1.1  christos    Returns #t if SELF still exists in GDB.  */
    308  1.1  christos 
    309  1.1  christos static SCM
    310  1.1  christos gdbscm_symtab_valid_p (SCM self)
    311  1.1  christos {
    312  1.1  christos   symtab_smob *st_smob
    313  1.1  christos     = stscm_get_symtab_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
    314  1.1  christos 
    315  1.1  christos   return scm_from_bool (stscm_is_valid (st_smob));
    316  1.1  christos }
    317  1.1  christos 
    318  1.1  christos /* (symtab-filename <gdb:symtab>) -> string */
    319  1.1  christos 
    320  1.1  christos static SCM
    321  1.1  christos gdbscm_symtab_filename (SCM self)
    322  1.1  christos {
    323  1.1  christos   symtab_smob *st_smob
    324  1.1  christos     = stscm_get_valid_symtab_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
    325  1.1  christos   struct symtab *symtab = st_smob->symtab;
    326  1.1  christos 
    327  1.1  christos   return gdbscm_scm_from_c_string (symtab_to_filename_for_display (symtab));
    328  1.1  christos }
    329  1.1  christos 
    330  1.1  christos /* (symtab-fullname <gdb:symtab>) -> string */
    331  1.1  christos 
    332  1.1  christos static SCM
    333  1.1  christos gdbscm_symtab_fullname (SCM self)
    334  1.1  christos {
    335  1.1  christos   symtab_smob *st_smob
    336  1.1  christos     = stscm_get_valid_symtab_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
    337  1.1  christos   struct symtab *symtab = st_smob->symtab;
    338  1.1  christos 
    339  1.1  christos   return gdbscm_scm_from_c_string (symtab_to_fullname (symtab));
    340  1.1  christos }
    341  1.1  christos 
    342  1.1  christos /* (symtab-objfile <gdb:symtab>) -> <gdb:objfile> */
    343  1.1  christos 
    344  1.1  christos static SCM
    345  1.1  christos gdbscm_symtab_objfile (SCM self)
    346  1.1  christos {
    347  1.1  christos   symtab_smob *st_smob
    348  1.1  christos     = stscm_get_valid_symtab_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
    349  1.8  christos   const struct symtab *symtab = st_smob->symtab;
    350  1.1  christos 
    351  1.1  christos   return ofscm_scm_from_objfile (symtab->compunit ()->objfile ());
    352  1.1  christos }
    353  1.1  christos 
    354  1.1  christos /* (symtab-global-block <gdb:symtab>) -> <gdb:block>
    355  1.1  christos    Return the GLOBAL_BLOCK of the underlying symtab.  */
    356  1.1  christos 
    357  1.1  christos static SCM
    358  1.1  christos gdbscm_symtab_global_block (SCM self)
    359  1.1  christos {
    360  1.1  christos   symtab_smob *st_smob
    361  1.1  christos     = stscm_get_valid_symtab_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
    362  1.1  christos   const struct symtab *symtab = st_smob->symtab;
    363  1.8  christos   const struct blockvector *blockvector;
    364  1.8  christos 
    365  1.1  christos   blockvector = symtab->compunit ()->blockvector ();
    366  1.8  christos   const struct block *block = blockvector->global_block ();
    367  1.1  christos 
    368  1.1  christos   return bkscm_scm_from_block (block, symtab->compunit ()->objfile ());
    369  1.1  christos }
    370  1.1  christos 
    371  1.1  christos /* (symtab-static-block <gdb:symtab>) -> <gdb:block>
    372  1.1  christos    Return the STATIC_BLOCK of the underlying symtab.  */
    373  1.1  christos 
    374  1.1  christos static SCM
    375  1.1  christos gdbscm_symtab_static_block (SCM self)
    376  1.1  christos {
    377  1.1  christos   symtab_smob *st_smob
    378  1.1  christos     = stscm_get_valid_symtab_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
    379  1.1  christos   const struct symtab *symtab = st_smob->symtab;
    380  1.8  christos   const struct blockvector *blockvector;
    381  1.8  christos 
    382  1.1  christos   blockvector = symtab->compunit ()->blockvector ();
    383  1.8  christos   const struct block *block = blockvector->static_block ();
    384  1.1  christos 
    385  1.1  christos   return bkscm_scm_from_block (block, symtab->compunit ()->objfile ());
    386  1.1  christos }
    387  1.1  christos 
    388  1.1  christos /* Administrivia for sal (symtab-and-line) smobs.  */
    390  1.1  christos 
    391  1.1  christos /* The smob "print" function for <gdb:sal>.  */
    392  1.1  christos 
    393  1.1  christos static int
    394  1.1  christos stscm_print_sal_smob (SCM self, SCM port, scm_print_state *pstate)
    395  1.1  christos {
    396  1.1  christos   sal_smob *s_smob = (sal_smob *) SCM_SMOB_DATA (self);
    397  1.1  christos 
    398  1.1  christos   gdbscm_printf (port, "#<%s ", symtab_smob_name);
    399  1.1  christos   scm_write (s_smob->symtab_scm, port);
    400  1.1  christos   if (s_smob->sal.line != 0)
    401  1.1  christos     gdbscm_printf (port, " line %d", s_smob->sal.line);
    402  1.1  christos   scm_puts (">", port);
    403  1.1  christos 
    404  1.1  christos   scm_remember_upto_here_1 (self);
    405  1.1  christos 
    406  1.1  christos   /* Non-zero means success.  */
    407  1.1  christos   return 1;
    408  1.1  christos }
    409  1.1  christos 
    410  1.1  christos /* Low level routine to create a <gdb:sal> object.  */
    411  1.1  christos 
    412  1.1  christos static SCM
    413  1.1  christos stscm_make_sal_smob (void)
    414  1.1  christos {
    415  1.1  christos   sal_smob *s_smob
    416  1.1  christos     = (sal_smob *) scm_gc_malloc (sizeof (sal_smob), sal_smob_name);
    417  1.6  christos   SCM s_scm;
    418  1.1  christos 
    419  1.1  christos   s_smob->symtab_scm = SCM_BOOL_F;
    420  1.1  christos   new (&s_smob->sal) symtab_and_line ();
    421  1.1  christos   s_scm = scm_new_smob (sal_smob_tag, (scm_t_bits) s_smob);
    422  1.1  christos   gdbscm_init_gsmob (&s_smob->base);
    423  1.1  christos 
    424  1.1  christos   return s_scm;
    425  1.1  christos }
    426  1.1  christos 
    427  1.1  christos /* Return non-zero if SCM is a <gdb:sal> object.  */
    428  1.1  christos 
    429  1.1  christos static int
    430  1.1  christos stscm_is_sal (SCM scm)
    431  1.1  christos {
    432  1.1  christos   return SCM_SMOB_PREDICATE (sal_smob_tag, scm);
    433  1.1  christos }
    434  1.1  christos 
    435  1.1  christos /* (sal? object) -> boolean */
    436  1.1  christos 
    437  1.1  christos static SCM
    438  1.1  christos gdbscm_sal_p (SCM scm)
    439  1.1  christos {
    440  1.1  christos   return scm_from_bool (stscm_is_sal (scm));
    441  1.1  christos }
    442  1.1  christos 
    443  1.1  christos /* Create a new <gdb:sal> object that encapsulates SAL.  */
    444  1.1  christos 
    445  1.1  christos SCM
    446  1.1  christos stscm_scm_from_sal (struct symtab_and_line sal)
    447  1.1  christos {
    448  1.1  christos   SCM st_scm, s_scm;
    449  1.1  christos   sal_smob *s_smob;
    450  1.1  christos 
    451  1.1  christos   st_scm = SCM_BOOL_F;
    452  1.1  christos   if (sal.symtab != NULL)
    453  1.1  christos     st_scm = stscm_scm_from_symtab (sal.symtab);
    454  1.1  christos 
    455  1.1  christos   s_scm = stscm_make_sal_smob ();
    456  1.1  christos   s_smob = (sal_smob *) SCM_SMOB_DATA (s_scm);
    457  1.1  christos   s_smob->symtab_scm = st_scm;
    458  1.1  christos   s_smob->sal = sal;
    459  1.1  christos 
    460  1.1  christos   return s_scm;
    461  1.1  christos }
    462  1.1  christos 
    463  1.1  christos /* Returns the <gdb:sal> object in SELF.
    464  1.1  christos    Throws an exception if SELF is not a <gdb:sal> object.  */
    465  1.1  christos 
    466  1.1  christos static SCM
    467  1.1  christos stscm_get_sal_arg (SCM self, int arg_pos, const char *func_name)
    468  1.1  christos {
    469  1.1  christos   SCM_ASSERT_TYPE (stscm_is_sal (self), self, arg_pos, func_name,
    470  1.1  christos 		   sal_smob_name);
    471  1.1  christos 
    472  1.1  christos   return self;
    473  1.1  christos }
    474  1.1  christos 
    475  1.1  christos /* Returns a pointer to the sal smob of SELF.
    476  1.1  christos    Throws an exception if SELF is not a <gdb:sal> object.  */
    477  1.1  christos 
    478  1.1  christos static sal_smob *
    479  1.1  christos stscm_get_sal_smob_arg (SCM self, int arg_pos, const char *func_name)
    480  1.1  christos {
    481  1.1  christos   SCM s_scm = stscm_get_sal_arg (self, arg_pos, func_name);
    482  1.1  christos   sal_smob *s_smob = (sal_smob *) SCM_SMOB_DATA (s_scm);
    483  1.1  christos 
    484  1.1  christos   return s_smob;
    485  1.1  christos }
    486  1.1  christos 
    487  1.1  christos /* Return non-zero if the symtab in S_SMOB is valid.  */
    488  1.1  christos 
    489  1.1  christos static int
    490  1.1  christos stscm_sal_is_valid (sal_smob *s_smob)
    491  1.1  christos {
    492  1.1  christos   symtab_smob *st_smob;
    493  1.1  christos 
    494  1.1  christos   /* If there's no symtab that's ok, the sal is still valid.  */
    495  1.1  christos   if (gdbscm_is_false (s_smob->symtab_scm))
    496  1.1  christos     return 1;
    497  1.1  christos 
    498  1.1  christos   st_smob = (symtab_smob *) SCM_SMOB_DATA (s_smob->symtab_scm);
    499  1.1  christos 
    500  1.1  christos   return st_smob->symtab != NULL;
    501  1.1  christos }
    502  1.1  christos 
    503  1.1  christos /* Throw a Scheme error if SELF is not a valid sal smob.
    504  1.1  christos    Otherwise return a pointer to the sal_smob object.  */
    505  1.1  christos 
    506  1.1  christos static sal_smob *
    507  1.1  christos stscm_get_valid_sal_smob_arg (SCM self, int arg_pos, const char *func_name)
    508  1.1  christos {
    509  1.1  christos   sal_smob *s_smob = stscm_get_sal_smob_arg (self, arg_pos, func_name);
    510  1.1  christos 
    511  1.1  christos   if (!stscm_sal_is_valid (s_smob))
    512  1.1  christos     {
    513  1.1  christos       gdbscm_invalid_object_error (func_name, arg_pos, self,
    514  1.1  christos 				   _("<gdb:sal>"));
    515  1.1  christos     }
    516  1.1  christos 
    517  1.1  christos   return s_smob;
    518  1.1  christos }
    519  1.1  christos 
    520  1.1  christos /* sal methods */
    522  1.1  christos 
    523  1.1  christos /* (sal-valid? <gdb:sal>) -> boolean
    524  1.1  christos    Returns #t if the symtab for SELF still exists in GDB.  */
    525  1.1  christos 
    526  1.1  christos static SCM
    527  1.1  christos gdbscm_sal_valid_p (SCM self)
    528  1.1  christos {
    529  1.1  christos   sal_smob *s_smob = stscm_get_sal_smob_arg (self, SCM_ARG1, FUNC_NAME);
    530  1.1  christos 
    531  1.1  christos   return scm_from_bool (stscm_sal_is_valid (s_smob));
    532  1.1  christos }
    533  1.1  christos 
    534  1.1  christos /* (sal-pc <gdb:sal>) -> address */
    535  1.1  christos 
    536  1.1  christos static SCM
    537  1.1  christos gdbscm_sal_pc (SCM self)
    538  1.1  christos {
    539  1.1  christos   sal_smob *s_smob = stscm_get_valid_sal_smob_arg (self, SCM_ARG1, FUNC_NAME);
    540  1.1  christos   const struct symtab_and_line *sal = &s_smob->sal;
    541  1.1  christos 
    542  1.1  christos   return gdbscm_scm_from_ulongest (sal->pc);
    543  1.1  christos }
    544  1.1  christos 
    545  1.1  christos /* (sal-last <gdb:sal>) -> address
    546  1.1  christos    Returns #f if no ending address is recorded.  */
    547  1.1  christos 
    548  1.1  christos static SCM
    549  1.1  christos gdbscm_sal_last (SCM self)
    550  1.1  christos {
    551  1.1  christos   sal_smob *s_smob = stscm_get_valid_sal_smob_arg (self, SCM_ARG1, FUNC_NAME);
    552  1.1  christos   const struct symtab_and_line *sal = &s_smob->sal;
    553  1.1  christos 
    554  1.1  christos   if (sal->end > 0)
    555  1.1  christos     return gdbscm_scm_from_ulongest (sal->end - 1);
    556  1.1  christos   return SCM_BOOL_F;
    557  1.1  christos }
    558  1.1  christos 
    559  1.1  christos /* (sal-line <gdb:sal>) -> integer
    560  1.1  christos    Returns #f if no line number is recorded.  */
    561  1.1  christos 
    562  1.1  christos static SCM
    563  1.1  christos gdbscm_sal_line (SCM self)
    564  1.1  christos {
    565  1.1  christos   sal_smob *s_smob = stscm_get_valid_sal_smob_arg (self, SCM_ARG1, FUNC_NAME);
    566  1.1  christos   const struct symtab_and_line *sal = &s_smob->sal;
    567  1.1  christos 
    568  1.1  christos   if (sal->line > 0)
    569  1.1  christos     return scm_from_int (sal->line);
    570  1.1  christos   return SCM_BOOL_F;
    571  1.1  christos }
    572  1.1  christos 
    573  1.1  christos /* (sal-symtab <gdb:sal>) -> <gdb:symtab>
    574  1.1  christos    Returns #f if no symtab is recorded.  */
    575  1.1  christos 
    576  1.1  christos static SCM
    577  1.1  christos gdbscm_sal_symtab (SCM self)
    578  1.1  christos {
    579  1.1  christos   sal_smob *s_smob = stscm_get_valid_sal_smob_arg (self, SCM_ARG1, FUNC_NAME);
    580  1.1  christos 
    581  1.1  christos   return s_smob->symtab_scm;
    582  1.1  christos }
    583  1.1  christos 
    584  1.1  christos /* (find-pc-line address) -> <gdb:sal> */
    585  1.1  christos 
    586  1.6  christos static SCM
    587  1.1  christos gdbscm_find_pc_line (SCM pc_scm)
    588  1.1  christos {
    589  1.1  christos   ULONGEST pc_ull;
    590  1.7  christos   symtab_and_line sal;
    591  1.7  christos 
    592  1.1  christos   gdbscm_parse_function_args (FUNC_NAME, SCM_ARG1, NULL, "U", pc_scm, &pc_ull);
    593  1.1  christos 
    594  1.1  christos   gdbscm_gdb_exception exc {};
    595  1.1  christos   try
    596  1.1  christos     {
    597  1.7  christos       CORE_ADDR pc = (CORE_ADDR) pc_ull;
    598  1.3  christos 
    599  1.7  christos       sal = find_pc_line (pc, 0);
    600  1.3  christos     }
    601  1.1  christos   catch (const gdb_exception &except)
    602  1.7  christos     {
    603  1.1  christos       exc = unpack (except);
    604  1.1  christos     }
    605  1.1  christos 
    606  1.1  christos   GDBSCM_HANDLE_GDB_EXCEPTION (exc);
    607  1.1  christos   return stscm_scm_from_sal (sal);
    608  1.1  christos }
    609  1.1  christos 
    610  1.4  christos /* Initialize the Scheme symbol support.  */
    612  1.1  christos 
    613  1.1  christos static const scheme_function symtab_functions[] =
    614  1.4  christos {
    615  1.1  christos   { "symtab?", 1, 0, 0, as_a_scm_t_subr (gdbscm_symtab_p),
    616  1.1  christos     "\
    617  1.1  christos Return #t if the object is a <gdb:symtab> object." },
    618  1.1  christos 
    619  1.4  christos   { "symtab-valid?", 1, 0, 0, as_a_scm_t_subr (gdbscm_symtab_valid_p),
    620  1.1  christos     "\
    621  1.1  christos Return #t if the symtab still exists in GDB.\n\
    622  1.1  christos Symtabs are deleted when the corresponding objfile is freed." },
    623  1.4  christos 
    624  1.1  christos   { "symtab-filename", 1, 0, 0, as_a_scm_t_subr (gdbscm_symtab_filename),
    625  1.1  christos     "\
    626  1.1  christos Return the symtab's source file name." },
    627  1.4  christos 
    628  1.1  christos   { "symtab-fullname", 1, 0, 0, as_a_scm_t_subr (gdbscm_symtab_fullname),
    629  1.1  christos     "\
    630  1.1  christos Return the symtab's full source file name." },
    631  1.4  christos 
    632  1.4  christos   { "symtab-objfile", 1, 0, 0, as_a_scm_t_subr (gdbscm_symtab_objfile),
    633  1.1  christos     "\
    634  1.1  christos Return the symtab's objfile." },
    635  1.1  christos 
    636  1.4  christos   { "symtab-global-block", 1, 0, 0,
    637  1.4  christos     as_a_scm_t_subr (gdbscm_symtab_global_block),
    638  1.1  christos     "\
    639  1.1  christos Return the symtab's global block." },
    640  1.1  christos 
    641  1.4  christos   { "symtab-static-block", 1, 0, 0,
    642  1.1  christos     as_a_scm_t_subr (gdbscm_symtab_static_block),
    643  1.1  christos     "\
    644  1.1  christos Return the symtab's static block." },
    645  1.4  christos 
    646  1.1  christos   { "sal?", 1, 0, 0, as_a_scm_t_subr (gdbscm_sal_p),
    647  1.1  christos     "\
    648  1.1  christos Return #t if the object is a <gdb:sal> (symtab-and-line) object." },
    649  1.1  christos 
    650  1.4  christos   { "sal-valid?", 1, 0, 0, as_a_scm_t_subr (gdbscm_sal_valid_p),
    651  1.1  christos     "\
    652  1.1  christos Return #t if the symtab for the sal still exists in GDB.\n\
    653  1.1  christos Symtabs are deleted when the corresponding objfile is freed." },
    654  1.4  christos 
    655  1.1  christos   { "sal-symtab", 1, 0, 0, as_a_scm_t_subr (gdbscm_sal_symtab),
    656  1.1  christos     "\
    657  1.1  christos Return the sal's symtab." },
    658  1.4  christos 
    659  1.1  christos   { "sal-line", 1, 0, 0, as_a_scm_t_subr (gdbscm_sal_line),
    660  1.1  christos     "\
    661  1.1  christos Return the sal's line number, or #f if there is none." },
    662  1.4  christos 
    663  1.1  christos   { "sal-pc", 1, 0, 0, as_a_scm_t_subr (gdbscm_sal_pc),
    664  1.1  christos     "\
    665  1.1  christos Return the sal's address." },
    666  1.4  christos 
    667  1.1  christos   { "sal-last", 1, 0, 0, as_a_scm_t_subr (gdbscm_sal_last),
    668  1.1  christos     "\
    669  1.1  christos Return the last address specified by the sal, or #f if there is none." },
    670  1.1  christos 
    671  1.1  christos   { "find-pc-line", 1, 0, 0, as_a_scm_t_subr (gdbscm_find_pc_line),
    672  1.1  christos     "\
    673  1.1  christos Return the sal corresponding to the address, or #f if there isn't one.\n\
    674  1.1  christos \n\
    675  1.1  christos   Arguments: address" },
    676  1.1  christos 
    677  1.1  christos   END_FUNCTIONS
    678  1.1  christos };
    679  1.1  christos 
    680  1.1  christos void
    681  1.1  christos gdbscm_initialize_symtabs (void)
    682  1.1  christos {
    683  1.1  christos   symtab_smob_tag
    684  1.1  christos     = gdbscm_make_smob_type (symtab_smob_name, sizeof (symtab_smob));
    685  1.1  christos   scm_set_smob_free (symtab_smob_tag, stscm_free_symtab_smob);
    686  1.1  christos   scm_set_smob_print (symtab_smob_tag, stscm_print_symtab_smob);
    687  1.1  christos 
    688                  sal_smob_tag = gdbscm_make_smob_type (sal_smob_name, sizeof (sal_smob));
    689                  scm_set_smob_print (sal_smob_tag, stscm_print_sal_smob);
    690                
    691                  gdbscm_define_functions (symtab_functions, 1);
    692                }
    693