1 /* Guile interface to program spaces.
3 Copyright (C) 2010-2021 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
22 #include "progspace.h"
25 #include "arch-utils.h"
26 #include "guile-internal.h"
28 /* NOTE: Python exports the name "Progspace", so we export "progspace".
29 Internally we shorten that to "pspace". */
31 /* The <gdb:progspace> smob. */
35 /* This always appears first. */
38 /* The corresponding pspace. */
39 struct program_space *pspace;
41 /* The pretty-printer list of functions. */
44 /* The <gdb:progspace> object we are contained in, needed to
45 protect/unprotect the object since a reference to it comes from
46 non-gc-managed space (the progspace). */
50 static const char pspace_smob_name[] = "gdb:progspace";
52 /* The tag Guile knows the pspace smob by. */
53 static scm_t_bits pspace_smob_tag;
55 static const struct program_space_data *psscm_pspace_data_key;
57 /* Return the list of pretty-printers registered with P_SMOB. */
60 psscm_pspace_smob_pretty_printers (const pspace_smob *p_smob)
62 return p_smob->pretty_printers;
65 /* Administrivia for progspace smobs. */
67 /* The smob "print" function for <gdb:progspace>. */
70 psscm_print_pspace_smob (SCM self, SCM port, scm_print_state *pstate)
72 pspace_smob *p_smob = (pspace_smob *) SCM_SMOB_DATA (self);
74 gdbscm_printf (port, "#<%s ", pspace_smob_name);
75 if (p_smob->pspace != NULL)
77 struct objfile *objfile = p_smob->pspace->symfile_object_file;
79 gdbscm_printf (port, "%s",
81 ? objfile_name (objfile)
85 scm_puts ("{invalid}", port);
88 scm_remember_upto_here_1 (self);
90 /* Non-zero means success. */
94 /* Low level routine to create a <gdb:progspace> object.
95 It's empty in the sense that a progspace still needs to be associated
99 psscm_make_pspace_smob (void)
101 pspace_smob *p_smob = (pspace_smob *)
102 scm_gc_malloc (sizeof (pspace_smob), pspace_smob_name);
105 p_smob->pspace = NULL;
106 p_smob->pretty_printers = SCM_EOL;
107 p_scm = scm_new_smob (pspace_smob_tag, (scm_t_bits) p_smob);
108 p_smob->containing_scm = p_scm;
109 gdbscm_init_gsmob (&p_smob->base);
114 /* Clear the progspace pointer in P_SMOB and unprotect the object from GC. */
117 psscm_release_pspace (pspace_smob *p_smob)
119 p_smob->pspace = NULL;
120 scm_gc_unprotect_object (p_smob->containing_scm);
123 /* Progspace registry cleanup handler for when a progspace is deleted. */
126 psscm_handle_pspace_deleted (struct program_space *pspace, void *datum)
128 pspace_smob *p_smob = (pspace_smob *) datum;
130 gdb_assert (p_smob->pspace == pspace);
132 psscm_release_pspace (p_smob);
135 /* Return non-zero if SCM is a <gdb:progspace> object. */
138 psscm_is_pspace (SCM scm)
140 return SCM_SMOB_PREDICATE (pspace_smob_tag, scm);
143 /* (progspace? object) -> boolean */
146 gdbscm_progspace_p (SCM scm)
148 return scm_from_bool (psscm_is_pspace (scm));
151 /* Return a pointer to the progspace_smob that encapsulates PSPACE,
152 creating one if necessary.
153 The result is cached so that we have only one copy per objfile. */
156 psscm_pspace_smob_from_pspace (struct program_space *pspace)
160 p_smob = (pspace_smob *) program_space_data (pspace, psscm_pspace_data_key);
163 SCM p_scm = psscm_make_pspace_smob ();
165 p_smob = (pspace_smob *) SCM_SMOB_DATA (p_scm);
166 p_smob->pspace = pspace;
168 set_program_space_data (pspace, psscm_pspace_data_key, p_smob);
169 scm_gc_protect_object (p_smob->containing_scm);
175 /* Return the <gdb:progspace> object that encapsulates PSPACE. */
178 psscm_scm_from_pspace (struct program_space *pspace)
180 pspace_smob *p_smob = psscm_pspace_smob_from_pspace (pspace);
182 return p_smob->containing_scm;
185 /* Returns the <gdb:progspace> object in SELF.
186 Throws an exception if SELF is not a <gdb:progspace> object. */
189 psscm_get_pspace_arg_unsafe (SCM self, int arg_pos, const char *func_name)
191 SCM_ASSERT_TYPE (psscm_is_pspace (self), self, arg_pos, func_name,
197 /* Returns a pointer to the pspace smob of SELF.
198 Throws an exception if SELF is not a <gdb:progspace> object. */
201 psscm_get_pspace_smob_arg_unsafe (SCM self, int arg_pos,
202 const char *func_name)
204 SCM p_scm = psscm_get_pspace_arg_unsafe (self, arg_pos, func_name);
205 pspace_smob *p_smob = (pspace_smob *) SCM_SMOB_DATA (p_scm);
210 /* Return non-zero if pspace P_SMOB is valid. */
213 psscm_is_valid (pspace_smob *p_smob)
215 return p_smob->pspace != NULL;
218 /* Return the pspace smob in SELF, verifying it's valid.
219 Throws an exception if SELF is not a <gdb:progspace> object or is
223 psscm_get_valid_pspace_smob_arg_unsafe (SCM self, int arg_pos,
224 const char *func_name)
227 = psscm_get_pspace_smob_arg_unsafe (self, arg_pos, func_name);
229 if (!psscm_is_valid (p_smob))
231 gdbscm_invalid_object_error (func_name, arg_pos, self,
232 _("<gdb:progspace>"));
238 /* Program space methods. */
240 /* (progspace-valid? <gdb:progspace>) -> boolean
241 Returns #t if this program space still exists in GDB. */
244 gdbscm_progspace_valid_p (SCM self)
247 = psscm_get_pspace_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
249 return scm_from_bool (p_smob->pspace != NULL);
252 /* (progspace-filename <gdb:progspace>) -> string
253 Returns the name of the main symfile associated with the progspace,
254 or #f if there isn't one.
255 Throw's an exception if the underlying pspace is invalid. */
258 gdbscm_progspace_filename (SCM self)
261 = psscm_get_valid_pspace_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
262 struct objfile *objfile = p_smob->pspace->symfile_object_file;
265 return gdbscm_scm_from_c_string (objfile_name (objfile));
269 /* (progspace-objfiles <gdb:progspace>) -> list
270 Return the list of objfiles in the progspace.
271 Objfiles that are separate debug objfiles are *not* included in the result,
272 only the "original/real" one appears in the result.
273 The order of appearance of objfiles in the result is arbitrary.
274 Throw's an exception if the underlying pspace is invalid.
276 Some apps can have 1000s of shared libraries. Seriously.
277 A future extension here could be to provide, e.g., a regexp to select
278 just the ones the caller is interested in (rather than building the list
279 and then selecting the desired ones). Another alternative is passing a
280 predicate, then the filter criteria can be more general. */
283 gdbscm_progspace_objfiles (SCM self)
286 = psscm_get_valid_pspace_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
291 for (objfile *objfile : p_smob->pspace->objfiles ())
293 if (objfile->separate_debug_objfile_backlink == NULL)
295 SCM item = ofscm_scm_from_objfile (objfile);
297 result = scm_cons (item, result);
301 /* We don't really have to return the list in the same order as recorded
302 internally, but for consistency we do. We still advertise that one
303 cannot assume anything about the order. */
304 return scm_reverse_x (result, SCM_EOL);
307 /* (progspace-pretty-printers <gdb:progspace>) -> list
308 Returns the list of pretty-printers for this program space. */
311 gdbscm_progspace_pretty_printers (SCM self)
314 = psscm_get_pspace_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
316 return p_smob->pretty_printers;
319 /* (set-progspace-pretty-printers! <gdb:progspace> list) -> unspecified
320 Set the pretty-printers for this program space. */
323 gdbscm_set_progspace_pretty_printers_x (SCM self, SCM printers)
326 = psscm_get_pspace_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
328 SCM_ASSERT_TYPE (gdbscm_is_true (scm_list_p (printers)), printers,
329 SCM_ARG2, FUNC_NAME, _("list"));
331 p_smob->pretty_printers = printers;
333 return SCM_UNSPECIFIED;
336 /* (current-progspace) -> <gdb:progspace>
337 Return the current program space. There always is one. */
340 gdbscm_current_progspace (void)
344 result = psscm_scm_from_pspace (current_program_space);
349 /* (progspaces) -> list
350 Return a list of all progspaces. */
353 gdbscm_progspaces (void)
359 for (struct program_space *ps : program_spaces)
361 SCM item = psscm_scm_from_pspace (ps);
363 result = scm_cons (item, result);
366 return scm_reverse_x (result, SCM_EOL);
369 /* Initialize the Scheme program space support. */
371 static const scheme_function pspace_functions[] =
373 { "progspace?", 1, 0, 0, as_a_scm_t_subr (gdbscm_progspace_p),
375 Return #t if the object is a <gdb:objfile> object." },
377 { "progspace-valid?", 1, 0, 0, as_a_scm_t_subr (gdbscm_progspace_valid_p),
379 Return #t if the progspace is valid (hasn't been deleted from gdb)." },
381 { "progspace-filename", 1, 0, 0, as_a_scm_t_subr (gdbscm_progspace_filename),
383 Return the name of the main symbol file of the progspace." },
385 { "progspace-objfiles", 1, 0, 0, as_a_scm_t_subr (gdbscm_progspace_objfiles),
387 Return the list of objfiles associated with the progspace.\n\
388 Objfiles that are separate debug objfiles are not included in the result.\n\
389 The order of appearance of objfiles in the result is arbitrary." },
391 { "progspace-pretty-printers", 1, 0, 0,
392 as_a_scm_t_subr (gdbscm_progspace_pretty_printers),
394 Return a list of pretty-printers of the progspace." },
396 { "set-progspace-pretty-printers!", 2, 0, 0,
397 as_a_scm_t_subr (gdbscm_set_progspace_pretty_printers_x),
399 Set the list of pretty-printers of the progspace." },
401 { "current-progspace", 0, 0, 0, as_a_scm_t_subr (gdbscm_current_progspace),
403 Return the current program space if there is one or #f if there isn't one." },
405 { "progspaces", 0, 0, 0, as_a_scm_t_subr (gdbscm_progspaces),
407 Return a list of all program spaces." },
413 gdbscm_initialize_pspaces (void)
416 = gdbscm_make_smob_type (pspace_smob_name, sizeof (pspace_smob));
417 scm_set_smob_print (pspace_smob_tag, psscm_print_pspace_smob);
419 gdbscm_define_functions (pspace_functions, 1);
422 void _initialize_scm_progspace ();
424 _initialize_scm_progspace ()
426 psscm_pspace_data_key
427 = register_program_space_data_with_cleanup (NULL,
428 psscm_handle_pspace_deleted);