]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/guile/scm-progspace.c
Automatic Copyright Year update after running gdb/copyright.py
[thirdparty/binutils-gdb.git] / gdb / guile / scm-progspace.c
CommitLineData
ded03782
DE
1/* Guile interface to program spaces.
2
4a94e368 3 Copyright (C) 2010-2022 Free Software Foundation, Inc.
ded03782
DE
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#include "defs.h"
21#include "charset.h"
22#include "progspace.h"
23#include "objfiles.h"
24#include "language.h"
25#include "arch-utils.h"
26#include "guile-internal.h"
27
28/* NOTE: Python exports the name "Progspace", so we export "progspace".
29 Internally we shorten that to "pspace". */
30
f99b5177 31/* The <gdb:progspace> smob. */
ded03782 32
f99b5177 33struct pspace_smob
ded03782
DE
34{
35 /* This always appears first. */
36 gdb_smob base;
37
38 /* The corresponding pspace. */
39 struct program_space *pspace;
40
41 /* The pretty-printer list of functions. */
42 SCM pretty_printers;
43
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). */
47 SCM containing_scm;
48};
49
50static const char pspace_smob_name[] = "gdb:progspace";
51
52/* The tag Guile knows the pspace smob by. */
53static scm_t_bits pspace_smob_tag;
54
55static const struct program_space_data *psscm_pspace_data_key;
56
57/* Return the list of pretty-printers registered with P_SMOB. */
58
59SCM
60psscm_pspace_smob_pretty_printers (const pspace_smob *p_smob)
61{
62 return p_smob->pretty_printers;
63}
64\f
65/* Administrivia for progspace smobs. */
66
67/* The smob "print" function for <gdb:progspace>. */
68
69static int
70psscm_print_pspace_smob (SCM self, SCM port, scm_print_state *pstate)
71{
72 pspace_smob *p_smob = (pspace_smob *) SCM_SMOB_DATA (self);
73
74 gdbscm_printf (port, "#<%s ", pspace_smob_name);
75 if (p_smob->pspace != NULL)
76 {
77 struct objfile *objfile = p_smob->pspace->symfile_object_file;
78
79 gdbscm_printf (port, "%s",
80 objfile != NULL
81 ? objfile_name (objfile)
82 : "{no symfile}");
83 }
84 else
85 scm_puts ("{invalid}", port);
86 scm_puts (">", port);
87
88 scm_remember_upto_here_1 (self);
89
90 /* Non-zero means success. */
91 return 1;
92}
93
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
96 with it. */
97
98static SCM
99psscm_make_pspace_smob (void)
100{
101 pspace_smob *p_smob = (pspace_smob *)
102 scm_gc_malloc (sizeof (pspace_smob), pspace_smob_name);
103 SCM p_scm;
104
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);
110
111 return p_scm;
112}
113
114/* Clear the progspace pointer in P_SMOB and unprotect the object from GC. */
115
116static void
117psscm_release_pspace (pspace_smob *p_smob)
118{
119 p_smob->pspace = NULL;
120 scm_gc_unprotect_object (p_smob->containing_scm);
121}
122
123/* Progspace registry cleanup handler for when a progspace is deleted. */
124
125static void
126psscm_handle_pspace_deleted (struct program_space *pspace, void *datum)
127{
9a3c8263 128 pspace_smob *p_smob = (pspace_smob *) datum;
ded03782
DE
129
130 gdb_assert (p_smob->pspace == pspace);
131
132 psscm_release_pspace (p_smob);
133}
134
135/* Return non-zero if SCM is a <gdb:progspace> object. */
136
137static int
138psscm_is_pspace (SCM scm)
139{
140 return SCM_SMOB_PREDICATE (pspace_smob_tag, scm);
141}
142
143/* (progspace? object) -> boolean */
144
145static SCM
146gdbscm_progspace_p (SCM scm)
147{
148 return scm_from_bool (psscm_is_pspace (scm));
149}
150
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. */
154
155pspace_smob *
156psscm_pspace_smob_from_pspace (struct program_space *pspace)
157{
158 pspace_smob *p_smob;
159
9a3c8263 160 p_smob = (pspace_smob *) program_space_data (pspace, psscm_pspace_data_key);
ded03782
DE
161 if (p_smob == NULL)
162 {
163 SCM p_scm = psscm_make_pspace_smob ();
164
165 p_smob = (pspace_smob *) SCM_SMOB_DATA (p_scm);
166 p_smob->pspace = pspace;
167
168 set_program_space_data (pspace, psscm_pspace_data_key, p_smob);
169 scm_gc_protect_object (p_smob->containing_scm);
170 }
171
172 return p_smob;
173}
174
175/* Return the <gdb:progspace> object that encapsulates PSPACE. */
176
177SCM
178psscm_scm_from_pspace (struct program_space *pspace)
179{
180 pspace_smob *p_smob = psscm_pspace_smob_from_pspace (pspace);
181
182 return p_smob->containing_scm;
183}
184
185/* Returns the <gdb:progspace> object in SELF.
186 Throws an exception if SELF is not a <gdb:progspace> object. */
187
188static SCM
189psscm_get_pspace_arg_unsafe (SCM self, int arg_pos, const char *func_name)
190{
191 SCM_ASSERT_TYPE (psscm_is_pspace (self), self, arg_pos, func_name,
192 pspace_smob_name);
193
194 return self;
195}
196
197/* Returns a pointer to the pspace smob of SELF.
198 Throws an exception if SELF is not a <gdb:progspace> object. */
199
200static pspace_smob *
201psscm_get_pspace_smob_arg_unsafe (SCM self, int arg_pos,
202 const char *func_name)
203{
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);
206
207 return p_smob;
208}
209
210/* Return non-zero if pspace P_SMOB is valid. */
211
212static int
213psscm_is_valid (pspace_smob *p_smob)
214{
215 return p_smob->pspace != NULL;
216}
217
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
220 invalid. */
221
222static pspace_smob *
223psscm_get_valid_pspace_smob_arg_unsafe (SCM self, int arg_pos,
224 const char *func_name)
225{
226 pspace_smob *p_smob
227 = psscm_get_pspace_smob_arg_unsafe (self, arg_pos, func_name);
228
229 if (!psscm_is_valid (p_smob))
230 {
231 gdbscm_invalid_object_error (func_name, arg_pos, self,
232 _("<gdb:progspace>"));
233 }
234
235 return p_smob;
236}
237\f
238/* Program space methods. */
239
240/* (progspace-valid? <gdb:progspace>) -> boolean
241 Returns #t if this program space still exists in GDB. */
242
243static SCM
244gdbscm_progspace_valid_p (SCM self)
245{
246 pspace_smob *p_smob
247 = psscm_get_pspace_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
248
249 return scm_from_bool (p_smob->pspace != NULL);
250}
251
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. */
256
257static SCM
258gdbscm_progspace_filename (SCM self)
259{
260 pspace_smob *p_smob
261 = psscm_get_valid_pspace_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
262 struct objfile *objfile = p_smob->pspace->symfile_object_file;
263
264 if (objfile != NULL)
265 return gdbscm_scm_from_c_string (objfile_name (objfile));
266 return SCM_BOOL_F;
267}
268
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.
275
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. */
281
282static SCM
283gdbscm_progspace_objfiles (SCM self)
284{
285 pspace_smob *p_smob
286 = psscm_get_valid_pspace_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
ded03782
DE
287 SCM result;
288
289 result = SCM_EOL;
290
2030c079 291 for (objfile *objfile : p_smob->pspace->objfiles ())
99d89cde
TT
292 {
293 if (objfile->separate_debug_objfile_backlink == NULL)
294 {
295 SCM item = ofscm_scm_from_objfile (objfile);
ded03782 296
99d89cde
TT
297 result = scm_cons (item, result);
298 }
299 }
ded03782
DE
300
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);
305}
306
307/* (progspace-pretty-printers <gdb:progspace>) -> list
308 Returns the list of pretty-printers for this program space. */
309
310static SCM
311gdbscm_progspace_pretty_printers (SCM self)
312{
313 pspace_smob *p_smob
314 = psscm_get_pspace_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
315
316 return p_smob->pretty_printers;
317}
318
319/* (set-progspace-pretty-printers! <gdb:progspace> list) -> unspecified
320 Set the pretty-printers for this program space. */
321
322static SCM
323gdbscm_set_progspace_pretty_printers_x (SCM self, SCM printers)
324{
325 pspace_smob *p_smob
326 = psscm_get_pspace_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
327
328 SCM_ASSERT_TYPE (gdbscm_is_true (scm_list_p (printers)), printers,
329 SCM_ARG2, FUNC_NAME, _("list"));
330
331 p_smob->pretty_printers = printers;
332
333 return SCM_UNSPECIFIED;
334}
335
336/* (current-progspace) -> <gdb:progspace>
337 Return the current program space. There always is one. */
338
339static SCM
340gdbscm_current_progspace (void)
341{
342 SCM result;
343
344 result = psscm_scm_from_pspace (current_program_space);
345
346 return result;
347}
348
349/* (progspaces) -> list
350 Return a list of all progspaces. */
351
352static SCM
353gdbscm_progspaces (void)
354{
ded03782
DE
355 SCM result;
356
357 result = SCM_EOL;
358
94c93c35
TT
359 for (struct program_space *ps : program_spaces)
360 {
361 SCM item = psscm_scm_from_pspace (ps);
ded03782 362
94c93c35
TT
363 result = scm_cons (item, result);
364 }
ded03782
DE
365
366 return scm_reverse_x (result, SCM_EOL);
367}
368\f
369/* Initialize the Scheme program space support. */
370
371static const scheme_function pspace_functions[] =
372{
72e02483 373 { "progspace?", 1, 0, 0, as_a_scm_t_subr (gdbscm_progspace_p),
ded03782
DE
374 "\
375Return #t if the object is a <gdb:objfile> object." },
376
72e02483 377 { "progspace-valid?", 1, 0, 0, as_a_scm_t_subr (gdbscm_progspace_valid_p),
ded03782
DE
378 "\
379Return #t if the progspace is valid (hasn't been deleted from gdb)." },
380
72e02483 381 { "progspace-filename", 1, 0, 0, as_a_scm_t_subr (gdbscm_progspace_filename),
ded03782
DE
382 "\
383Return the name of the main symbol file of the progspace." },
384
72e02483 385 { "progspace-objfiles", 1, 0, 0, as_a_scm_t_subr (gdbscm_progspace_objfiles),
ded03782
DE
386 "\
387Return the list of objfiles associated with the progspace.\n\
388Objfiles that are separate debug objfiles are not included in the result.\n\
389The order of appearance of objfiles in the result is arbitrary." },
390
72e02483
PA
391 { "progspace-pretty-printers", 1, 0, 0,
392 as_a_scm_t_subr (gdbscm_progspace_pretty_printers),
ded03782
DE
393 "\
394Return a list of pretty-printers of the progspace." },
395
396 { "set-progspace-pretty-printers!", 2, 0, 0,
72e02483 397 as_a_scm_t_subr (gdbscm_set_progspace_pretty_printers_x),
ded03782
DE
398 "\
399Set the list of pretty-printers of the progspace." },
400
72e02483 401 { "current-progspace", 0, 0, 0, as_a_scm_t_subr (gdbscm_current_progspace),
ded03782
DE
402 "\
403Return the current program space if there is one or #f if there isn't one." },
404
72e02483 405 { "progspaces", 0, 0, 0, as_a_scm_t_subr (gdbscm_progspaces),
ded03782
DE
406 "\
407Return a list of all program spaces." },
408
409 END_FUNCTIONS
410};
411
412void
413gdbscm_initialize_pspaces (void)
414{
415 pspace_smob_tag
416 = gdbscm_make_smob_type (pspace_smob_name, sizeof (pspace_smob));
417 scm_set_smob_print (pspace_smob_tag, psscm_print_pspace_smob);
418
419 gdbscm_define_functions (pspace_functions, 1);
880ae75a 420}
ded03782 421
880ae75a
AB
422void _initialize_scm_progspace ();
423void
424_initialize_scm_progspace ()
425{
ded03782
DE
426 psscm_pspace_data_key
427 = register_program_space_data_with_cleanup (NULL,
428 psscm_handle_pspace_deleted);
429}