scm-objfile.c revision 1.1.1.8 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