Home | History | Annotate | Line # | Download | only in guile
scm-objfile.c revision 1.1.1.5
      1 /* Scheme interface to objfiles.
      2 
      3    Copyright (C) 2008-2019 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   ofscm_current_objfile = objfile;
    343 
    344   gdb::unique_xmalloc_ptr<char> msg
    345     = gdbscm_safe_eval_string (script, 0 /* display_result */);
    346   if (msg != NULL)
    347     fprintf_filtered (gdb_stderr, "%s", msg.get ());
    348 
    349   ofscm_current_objfile = NULL;
    350 }
    351 
    352 /* (current-objfile) -> <gdb:obfjile>
    353    Return the current objfile, or #f if there isn't one.
    354    Ideally this would be named ofscm_current_objfile, but that name is
    355    taken by the variable recording the current objfile.  */
    356 
    357 static SCM
    358 gdbscm_get_current_objfile (void)
    359 {
    360   if (ofscm_current_objfile == NULL)
    361     return SCM_BOOL_F;
    362 
    363   return ofscm_scm_from_objfile (ofscm_current_objfile);
    364 }
    365 
    366 /* (objfiles) -> list
    367    Return a list of all objfiles in the current program space.  */
    368 
    369 static SCM
    370 gdbscm_objfiles (void)
    371 {
    372   SCM result;
    373 
    374   result = SCM_EOL;
    375 
    376   for (objfile *objf : current_program_space->objfiles ())
    377     {
    378       SCM item = ofscm_scm_from_objfile (objf);
    379 
    380       result = scm_cons (item, result);
    381     }
    382 
    383   return scm_reverse_x (result, SCM_EOL);
    384 }
    385 
    386 /* Initialize the Scheme objfile support.  */
    388 
    389 static const scheme_function objfile_functions[] =
    390 {
    391   { "objfile?", 1, 0, 0, as_a_scm_t_subr (gdbscm_objfile_p),
    392     "\
    393 Return #t if the object is a <gdb:objfile> object." },
    394 
    395   { "objfile-valid?", 1, 0, 0, as_a_scm_t_subr (gdbscm_objfile_valid_p),
    396     "\
    397 Return #t if the objfile is valid (hasn't been deleted from gdb)." },
    398 
    399   { "objfile-filename", 1, 0, 0, as_a_scm_t_subr (gdbscm_objfile_filename),
    400     "\
    401 Return the file name of the objfile." },
    402 
    403   { "objfile-progspace", 1, 0, 0, as_a_scm_t_subr (gdbscm_objfile_progspace),
    404     "\
    405 Return the progspace that the objfile lives in." },
    406 
    407   { "objfile-pretty-printers", 1, 0, 0,
    408     as_a_scm_t_subr (gdbscm_objfile_pretty_printers),
    409     "\
    410 Return a list of pretty-printers of the objfile." },
    411 
    412   { "set-objfile-pretty-printers!", 2, 0, 0,
    413     as_a_scm_t_subr (gdbscm_set_objfile_pretty_printers_x),
    414     "\
    415 Set the list of pretty-printers of the objfile." },
    416 
    417   { "current-objfile", 0, 0, 0, as_a_scm_t_subr (gdbscm_get_current_objfile),
    418     "\
    419 Return the current objfile if there is one or #f if there isn't one." },
    420 
    421   { "objfiles", 0, 0, 0, as_a_scm_t_subr (gdbscm_objfiles),
    422     "\
    423 Return a list of all objfiles in the current program space." },
    424 
    425   END_FUNCTIONS
    426 };
    427 
    428 void
    429 gdbscm_initialize_objfiles (void)
    430 {
    431   objfile_smob_tag
    432     = gdbscm_make_smob_type (objfile_smob_name, sizeof (objfile_smob));
    433   scm_set_smob_print (objfile_smob_tag, ofscm_print_objfile_smob);
    434 
    435   gdbscm_define_functions (objfile_functions, 1);
    436 
    437   ofscm_objfile_data_key
    438     = register_objfile_data_with_cleanup (NULL, ofscm_handle_objfile_deleted);
    439 }
    440