Home | History | Annotate | Line # | Download | only in guile
scm-objfile.c revision 1.1.1.4
      1 /* Scheme interface to objfiles.
      2 
      3    Copyright (C) 2008-2017 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 = (objfile_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_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-progspace <gdb:objfile>) -> <gdb:progspace>
    258    Returns the objfile's progspace.
    259    Throw's an exception if the underlying objfile is invalid.  */
    260 
    261 static SCM
    262 gdbscm_objfile_progspace (SCM self)
    263 {
    264   objfile_smob *o_smob
    265     = ofscm_get_valid_objfile_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
    266 
    267   return psscm_scm_from_pspace (o_smob->objfile->pspace);
    268 }
    269 
    270 /* (objfile-pretty-printers <gdb:objfile>) -> list
    271    Returns the list of pretty-printers for this objfile.  */
    272 
    273 static SCM
    274 gdbscm_objfile_pretty_printers (SCM self)
    275 {
    276   objfile_smob *o_smob
    277     = ofscm_get_objfile_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
    278 
    279   return o_smob->pretty_printers;
    280 }
    281 
    282 /* (set-objfile-pretty-printers! <gdb:objfile> list) -> unspecified
    283    Set the pretty-printers for this objfile.  */
    284 
    285 static SCM
    286 gdbscm_set_objfile_pretty_printers_x (SCM self, SCM printers)
    287 {
    288   objfile_smob *o_smob
    289     = ofscm_get_objfile_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
    290 
    291   SCM_ASSERT_TYPE (gdbscm_is_true (scm_list_p (printers)), printers,
    292 		   SCM_ARG2, FUNC_NAME, _("list"));
    293 
    294   o_smob->pretty_printers = printers;
    295 
    296   return SCM_UNSPECIFIED;
    297 }
    298 
    299 /* The "current" objfile.  This is set when gdb detects that a new
    301    objfile has been loaded.  It is only set for the duration of a call to
    302    gdbscm_source_objfile_script and gdbscm_execute_objfile_script; it is NULL
    303    at other times.  */
    304 static struct objfile *ofscm_current_objfile;
    305 
    306 /* Set the current objfile to OBJFILE and then read FILE named FILENAME
    307    as Guile code.  This does not throw any errors.  If an exception
    308    occurs Guile will print the backtrace.
    309    This is the extension_language_script_ops.objfile_script_sourcer
    310    "method".  */
    311 
    312 void
    313 gdbscm_source_objfile_script (const struct extension_language_defn *extlang,
    314 			      struct objfile *objfile, FILE *file,
    315 			      const char *filename)
    316 {
    317   char *msg;
    318 
    319   ofscm_current_objfile = objfile;
    320 
    321   msg = gdbscm_safe_source_script (filename);
    322   if (msg != NULL)
    323     {
    324       fprintf_filtered (gdb_stderr, "%s", msg);
    325       xfree (msg);
    326     }
    327 
    328   ofscm_current_objfile = NULL;
    329 }
    330 
    331 /* Set the current objfile to OBJFILE and then read FILE named FILENAME
    332    as Guile code.  This does not throw any errors.  If an exception
    333    occurs Guile will print the backtrace.
    334    This is the extension_language_script_ops.objfile_script_sourcer
    335    "method".  */
    336 
    337 void
    338 gdbscm_execute_objfile_script (const struct extension_language_defn *extlang,
    339 			       struct objfile *objfile, const char *name,
    340 			       const char *script)
    341 {
    342   char *msg;
    343 
    344   ofscm_current_objfile = objfile;
    345 
    346   msg = gdbscm_safe_eval_string (script, 0 /* display_result */);
    347   if (msg != NULL)
    348     {
    349       fprintf_filtered (gdb_stderr, "%s", msg);
    350       xfree (msg);
    351     }
    352 
    353   ofscm_current_objfile = NULL;
    354 }
    355 
    356 /* (current-objfile) -> <gdb:obfjile>
    357    Return the current objfile, or #f if there isn't one.
    358    Ideally this would be named ofscm_current_objfile, but that name is
    359    taken by the variable recording the current objfile.  */
    360 
    361 static SCM
    362 gdbscm_get_current_objfile (void)
    363 {
    364   if (ofscm_current_objfile == NULL)
    365     return SCM_BOOL_F;
    366 
    367   return ofscm_scm_from_objfile (ofscm_current_objfile);
    368 }
    369 
    370 /* (objfiles) -> list
    371    Return a list of all objfiles in the current program space.  */
    372 
    373 static SCM
    374 gdbscm_objfiles (void)
    375 {
    376   struct objfile *objf;
    377   SCM result;
    378 
    379   result = SCM_EOL;
    380 
    381   ALL_OBJFILES (objf)
    382   {
    383     SCM item = ofscm_scm_from_objfile (objf);
    384 
    385     result = scm_cons (item, result);
    386   }
    387 
    388   return scm_reverse_x (result, SCM_EOL);
    389 }
    390 
    391 /* Initialize the Scheme objfile support.  */
    393 
    394 static const scheme_function objfile_functions[] =
    395 {
    396   { "objfile?", 1, 0, 0, as_a_scm_t_subr (gdbscm_objfile_p),
    397     "\
    398 Return #t if the object is a <gdb:objfile> object." },
    399 
    400   { "objfile-valid?", 1, 0, 0, as_a_scm_t_subr (gdbscm_objfile_valid_p),
    401     "\
    402 Return #t if the objfile is valid (hasn't been deleted from gdb)." },
    403 
    404   { "objfile-filename", 1, 0, 0, as_a_scm_t_subr (gdbscm_objfile_filename),
    405     "\
    406 Return the file name of the objfile." },
    407 
    408   { "objfile-progspace", 1, 0, 0, as_a_scm_t_subr (gdbscm_objfile_progspace),
    409     "\
    410 Return the progspace that the objfile lives in." },
    411 
    412   { "objfile-pretty-printers", 1, 0, 0,
    413     as_a_scm_t_subr (gdbscm_objfile_pretty_printers),
    414     "\
    415 Return a list of pretty-printers of the objfile." },
    416 
    417   { "set-objfile-pretty-printers!", 2, 0, 0,
    418     as_a_scm_t_subr (gdbscm_set_objfile_pretty_printers_x),
    419     "\
    420 Set the list of pretty-printers of the objfile." },
    421 
    422   { "current-objfile", 0, 0, 0, as_a_scm_t_subr (gdbscm_get_current_objfile),
    423     "\
    424 Return the current objfile if there is one or #f if there isn't one." },
    425 
    426   { "objfiles", 0, 0, 0, as_a_scm_t_subr (gdbscm_objfiles),
    427     "\
    428 Return a list of all objfiles in the current program space." },
    429 
    430   END_FUNCTIONS
    431 };
    432 
    433 void
    434 gdbscm_initialize_objfiles (void)
    435 {
    436   objfile_smob_tag
    437     = gdbscm_make_smob_type (objfile_smob_name, sizeof (objfile_smob));
    438   scm_set_smob_print (objfile_smob_tag, ofscm_print_objfile_smob);
    439 
    440   gdbscm_define_functions (objfile_functions, 1);
    441 
    442   ofscm_objfile_data_key
    443     = register_objfile_data_with_cleanup (NULL, ofscm_handle_objfile_deleted);
    444 }
    445