Home | History | Annotate | Line # | Download | only in guile
scm-objfile.c revision 1.1.1.1
      1 /* Scheme interface to objfiles.
      2 
      3    Copyright (C) 2008-2015 Free Software Foundation, Inc.
      4 
      5    This file is part of GDB.
      6 
      7    This program is free software; you can redistribute it and/or modify
      8    it under the terms of the GNU General Public License as published by
      9    the Free Software Foundation; either version 3 of the License, or
     10    (at your option) any later version.
     11 
     12    This program is distributed in the hope that it will be useful,
     13    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15    GNU General Public License for more details.
     16 
     17    You should have received a copy of the GNU General Public License
     18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     19 
     20 /* See README file in this directory for implementation notes, coding
     21    conventions, et.al.  */
     22 
     23 #include "defs.h"
     24 #include "objfiles.h"
     25 #include "language.h"
     26 #include "guile-internal.h"
     27 
     28 /* The <gdb:objfile> smob.
     29    The typedef for this struct is in guile-internal.h.  */
     30 
     31 struct _objfile_smob
     32 {
     33   /* This always appears first.  */
     34   gdb_smob base;
     35 
     36   /* The corresponding objfile.  */
     37   struct objfile *objfile;
     38 
     39   /* The pretty-printer list of functions.  */
     40   SCM pretty_printers;
     41 
     42   /* The <gdb:objfile> object we are contained in, needed to protect/unprotect
     43      the object since a reference to it comes from non-gc-managed space
     44      (the objfile).  */
     45   SCM containing_scm;
     46 };
     47 
     48 static const char objfile_smob_name[] = "gdb:objfile";
     49 
     50 /* The tag Guile knows the objfile smob by.  */
     51 static scm_t_bits objfile_smob_tag;
     52 
     53 static const struct objfile_data *ofscm_objfile_data_key;
     54 
     55 /* Return the list of pretty-printers registered with O_SMOB.  */
     56 
     57 SCM
     58 ofscm_objfile_smob_pretty_printers (objfile_smob *o_smob)
     59 {
     60   return o_smob->pretty_printers;
     61 }
     62 
     63 /* Administrivia for objfile smobs.  */
     65 
     66 /* The smob "print" function for <gdb:objfile>.  */
     67 
     68 static int
     69 ofscm_print_objfile_smob (SCM self, SCM port, scm_print_state *pstate)
     70 {
     71   objfile_smob *o_smob = (objfile_smob *) SCM_SMOB_DATA (self);
     72 
     73   gdbscm_printf (port, "#<%s ", objfile_smob_name);
     74   gdbscm_printf (port, "%s",
     75 		 o_smob->objfile != NULL
     76 		 ? objfile_name (o_smob->objfile)
     77 		 : "{invalid}");
     78   scm_puts (">", port);
     79 
     80   scm_remember_upto_here_1 (self);
     81 
     82   /* Non-zero means success.  */
     83   return 1;
     84 }
     85 
     86 /* Low level routine to create a <gdb:objfile> object.
     87    It's empty in the sense that an OBJFILE still needs to be associated
     88    with it.  */
     89 
     90 static SCM
     91 ofscm_make_objfile_smob (void)
     92 {
     93   objfile_smob *o_smob = (objfile_smob *)
     94     scm_gc_malloc (sizeof (objfile_smob), objfile_smob_name);
     95   SCM o_scm;
     96 
     97   o_smob->objfile = NULL;
     98   o_smob->pretty_printers = SCM_EOL;
     99   o_scm = scm_new_smob (objfile_smob_tag, (scm_t_bits) o_smob);
    100   o_smob->containing_scm = o_scm;
    101   gdbscm_init_gsmob (&o_smob->base);
    102 
    103   return o_scm;
    104 }
    105 
    106 /* Clear the OBJFILE pointer in O_SMOB and unprotect the object from GC.  */
    107 
    108 static void
    109 ofscm_release_objfile (objfile_smob *o_smob)
    110 {
    111   o_smob->objfile = NULL;
    112   scm_gc_unprotect_object (o_smob->containing_scm);
    113 }
    114 
    115 /* Objfile registry cleanup handler for when an objfile is deleted.  */
    116 
    117 static void
    118 ofscm_handle_objfile_deleted (struct objfile *objfile, void *datum)
    119 {
    120   objfile_smob *o_smob = datum;
    121 
    122   gdb_assert (o_smob->objfile == objfile);
    123 
    124   ofscm_release_objfile (o_smob);
    125 }
    126 
    127 /* Return non-zero if SCM is a <gdb:objfile> object.  */
    128 
    129 static int
    130 ofscm_is_objfile (SCM scm)
    131 {
    132   return SCM_SMOB_PREDICATE (objfile_smob_tag, scm);
    133 }
    134 
    135 /* (objfile? object) -> boolean */
    136 
    137 static SCM
    138 gdbscm_objfile_p (SCM scm)
    139 {
    140   return scm_from_bool (ofscm_is_objfile (scm));
    141 }
    142 
    143 /* Return a pointer to the objfile_smob that encapsulates OBJFILE,
    144    creating one if necessary.
    145    The result is cached so that we have only one copy per objfile.  */
    146 
    147 objfile_smob *
    148 ofscm_objfile_smob_from_objfile (struct objfile *objfile)
    149 {
    150   objfile_smob *o_smob;
    151 
    152   o_smob = objfile_data (objfile, ofscm_objfile_data_key);
    153   if (o_smob == NULL)
    154     {
    155       SCM o_scm = ofscm_make_objfile_smob ();
    156 
    157       o_smob = (objfile_smob *) SCM_SMOB_DATA (o_scm);
    158       o_smob->objfile = objfile;
    159 
    160       set_objfile_data (objfile, ofscm_objfile_data_key, o_smob);
    161       scm_gc_protect_object (o_smob->containing_scm);
    162     }
    163 
    164   return o_smob;
    165 }
    166 
    167 /* Return the <gdb:objfile> object that encapsulates OBJFILE.  */
    168 
    169 SCM
    170 ofscm_scm_from_objfile (struct objfile *objfile)
    171 {
    172   objfile_smob *o_smob = ofscm_objfile_smob_from_objfile (objfile);
    173 
    174   return o_smob->containing_scm;
    175 }
    176 
    177 /* Returns the <gdb:objfile> object in SELF.
    178    Throws an exception if SELF is not a <gdb:objfile> object.  */
    179 
    180 static SCM
    181 ofscm_get_objfile_arg_unsafe (SCM self, int arg_pos, const char *func_name)
    182 {
    183   SCM_ASSERT_TYPE (ofscm_is_objfile (self), self, arg_pos, func_name,
    184 		   objfile_smob_name);
    185 
    186   return self;
    187 }
    188 
    189 /* Returns a pointer to the objfile smob of SELF.
    190    Throws an exception if SELF is not a <gdb:objfile> object.  */
    191 
    192 static objfile_smob *
    193 ofscm_get_objfile_smob_arg_unsafe (SCM self, int arg_pos,
    194 				   const char *func_name)
    195 {
    196   SCM o_scm = ofscm_get_objfile_arg_unsafe (self, arg_pos, func_name);
    197   objfile_smob *o_smob = (objfile_smob *) SCM_SMOB_DATA (o_scm);
    198 
    199   return o_smob;
    200 }
    201 
    202 /* Return non-zero if objfile O_SMOB is valid.  */
    203 
    204 static int
    205 ofscm_is_valid (objfile_smob *o_smob)
    206 {
    207   return o_smob->objfile != NULL;
    208 }
    209 
    210 /* Return the objfile smob in SELF, verifying it's valid.
    211    Throws an exception if SELF is not a <gdb:objfile> object or is invalid.  */
    212 
    213 static objfile_smob *
    214 ofscm_get_valid_objfile_smob_arg_unsafe (SCM self, int arg_pos,
    215 					 const char *func_name)
    216 {
    217   objfile_smob *o_smob
    218     = ofscm_get_objfile_smob_arg_unsafe (self, arg_pos, func_name);
    219 
    220   if (!ofscm_is_valid (o_smob))
    221     {
    222       gdbscm_invalid_object_error (func_name, arg_pos, self,
    223 				   _("<gdb:objfile>"));
    224     }
    225 
    226   return o_smob;
    227 }
    228 
    229 /* Objfile methods.  */
    231 
    232 /* (objfile-valid? <gdb:objfile>) -> boolean
    233    Returns #t if this object file still exists in GDB.  */
    234 
    235 static SCM
    236 gdbscm_objfile_valid_p (SCM self)
    237 {
    238   objfile_smob *o_smob
    239     = ofscm_get_objfile_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
    240 
    241   return scm_from_bool (o_smob->objfile != NULL);
    242 }
    243 
    244 /* (objfile-filename <gdb:objfile>) -> string
    245    Returns the objfile's file name.
    246    Throw's an exception if the underlying objfile is invalid.  */
    247 
    248 static SCM
    249 gdbscm_objfile_filename (SCM self)
    250 {
    251   objfile_smob *o_smob
    252     = ofscm_get_valid_objfile_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
    253 
    254   return gdbscm_scm_from_c_string (objfile_name (o_smob->objfile));
    255 }
    256 
    257 /* (objfile-pretty-printers <gdb:objfile>) -> list
    258    Returns the list of pretty-printers for this objfile.  */
    259 
    260 static SCM
    261 gdbscm_objfile_pretty_printers (SCM self)
    262 {
    263   objfile_smob *o_smob
    264     = ofscm_get_objfile_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
    265 
    266   return o_smob->pretty_printers;
    267 }
    268 
    269 /* (set-objfile-pretty-printers! <gdb:objfile> list) -> unspecified
    270    Set the pretty-printers for this objfile.  */
    271 
    272 static SCM
    273 gdbscm_set_objfile_pretty_printers_x (SCM self, SCM printers)
    274 {
    275   objfile_smob *o_smob
    276     = ofscm_get_objfile_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
    277 
    278   SCM_ASSERT_TYPE (gdbscm_is_true (scm_list_p (printers)), printers,
    279 		   SCM_ARG2, FUNC_NAME, _("list"));
    280 
    281   o_smob->pretty_printers = printers;
    282 
    283   return SCM_UNSPECIFIED;
    284 }
    285 
    286 /* The "current" objfile.  This is set when gdb detects that a new
    288    objfile has been loaded.  It is only set for the duration of a call to
    289    gdbscm_source_objfile_script; it is NULL at other times.  */
    290 static struct objfile *ofscm_current_objfile;
    291 
    292 /* Set the current objfile to OBJFILE and then read FILE named FILENAME
    293    as Guile code.  This does not throw any errors.  If an exception
    294    occurs Guile will print the backtrace.
    295    This is the extension_language_script_ops.objfile_script_sourcer
    296    "method".  */
    297 
    298 void
    299 gdbscm_source_objfile_script (const struct extension_language_defn *extlang,
    300 			      struct objfile *objfile, FILE *file,
    301 			      const char *filename)
    302 {
    303   char *msg;
    304 
    305   ofscm_current_objfile = objfile;
    306 
    307   msg = gdbscm_safe_source_script (filename);
    308   if (msg != NULL)
    309     {
    310       fprintf_filtered (gdb_stderr, "%s", msg);
    311       xfree (msg);
    312     }
    313 
    314   ofscm_current_objfile = NULL;
    315 }
    316 
    317 /* (current-objfile) -> <gdb:obfjile>
    318    Return the current objfile, or #f if there isn't one.
    319    Ideally this would be named ofscm_current_objfile, but that name is
    320    taken by the variable recording the current objfile.  */
    321 
    322 static SCM
    323 gdbscm_get_current_objfile (void)
    324 {
    325   if (ofscm_current_objfile == NULL)
    326     return SCM_BOOL_F;
    327 
    328   return ofscm_scm_from_objfile (ofscm_current_objfile);
    329 }
    330 
    331 /* (objfiles) -> list
    332    Return a list of all objfiles in the current program space.  */
    333 
    334 static SCM
    335 gdbscm_objfiles (void)
    336 {
    337   struct objfile *objf;
    338   SCM result;
    339 
    340   result = SCM_EOL;
    341 
    342   ALL_OBJFILES (objf)
    343   {
    344     SCM item = ofscm_scm_from_objfile (objf);
    345 
    346     result = scm_cons (item, result);
    347   }
    348 
    349   return scm_reverse_x (result, SCM_EOL);
    350 }
    351 
    352 /* Initialize the Scheme objfile support.  */
    354 
    355 static const scheme_function objfile_functions[] =
    356 {
    357   { "objfile?", 1, 0, 0, gdbscm_objfile_p,
    358     "\
    359 Return #t if the object is a <gdb:objfile> object." },
    360 
    361   { "objfile-valid?", 1, 0, 0, gdbscm_objfile_valid_p,
    362     "\
    363 Return #t if the objfile is valid (hasn't been deleted from gdb)." },
    364 
    365   { "objfile-filename", 1, 0, 0, gdbscm_objfile_filename,
    366     "\
    367 Return the file name of the objfile." },
    368 
    369   { "objfile-pretty-printers", 1, 0, 0, gdbscm_objfile_pretty_printers,
    370     "\
    371 Return a list of pretty-printers of the objfile." },
    372 
    373   { "set-objfile-pretty-printers!", 2, 0, 0,
    374     gdbscm_set_objfile_pretty_printers_x,
    375     "\
    376 Set the list of pretty-printers of the objfile." },
    377 
    378   { "current-objfile", 0, 0, 0, gdbscm_get_current_objfile,
    379     "\
    380 Return the current objfile if there is one or #f if there isn't one." },
    381 
    382   { "objfiles", 0, 0, 0, gdbscm_objfiles,
    383     "\
    384 Return a list of all objfiles in the current program space." },
    385 
    386   END_FUNCTIONS
    387 };
    388 
    389 void
    390 gdbscm_initialize_objfiles (void)
    391 {
    392   objfile_smob_tag
    393     = gdbscm_make_smob_type (objfile_smob_name, sizeof (objfile_smob));
    394   scm_set_smob_print (objfile_smob_tag, ofscm_print_objfile_smob);
    395 
    396   gdbscm_define_functions (objfile_functions, 1);
    397 
    398   ofscm_objfile_data_key
    399     = register_objfile_data_with_cleanup (NULL, ofscm_handle_objfile_deleted);
    400 }
    401