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