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