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