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