]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/guile/scm-frame.c
Remove redundant typedefs
[thirdparty/binutils-gdb.git] / gdb / guile / scm-frame.c
1 /* Scheme interface to stack frames.
2
3 Copyright (C) 2008-2020 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 "block.h"
25 #include "frame.h"
26 #include "inferior.h"
27 #include "objfiles.h"
28 #include "symfile.h"
29 #include "symtab.h"
30 #include "stack.h"
31 #include "user-regs.h"
32 #include "value.h"
33 #include "guile-internal.h"
34
35 /* The <gdb:frame> smob. */
36
37 struct frame_smob
38 {
39 /* This always appears first. */
40 eqable_gdb_smob base;
41
42 struct frame_id frame_id;
43 struct gdbarch *gdbarch;
44
45 /* Frames are tracked by inferior.
46 We need some place to put the eq?-able hash table, and this feels as
47 good a place as any. Frames in one inferior shouldn't be considered
48 equal to frames in a different inferior. The frame becomes invalid if
49 this becomes NULL (the inferior has been deleted from gdb).
50 It's easier to relax restrictions than impose them after the fact.
51 N.B. It is an outstanding question whether a frame survives reruns of
52 the inferior. Intuitively the answer is "No", but currently a frame
53 also survives, e.g., multiple invocations of the same function from
54 the same point. Even different threads can have the same frame, e.g.,
55 if a thread dies and a new thread gets the same stack. */
56 struct inferior *inferior;
57
58 /* Marks that the FRAME_ID member actually holds the ID of the frame next
59 to this, and not this frame's ID itself. This is a hack to permit Scheme
60 frame objects which represent invalid frames (i.e., the last frame_info
61 in a corrupt stack). The problem arises from the fact that this code
62 relies on FRAME_ID to uniquely identify a frame, which is not always true
63 for the last "frame" in a corrupt stack (it can have a null ID, or the
64 same ID as the previous frame). Whenever get_prev_frame returns NULL, we
65 record the frame_id of the next frame and set FRAME_ID_IS_NEXT to 1. */
66 int frame_id_is_next;
67 };
68
69 static const char frame_smob_name[] = "gdb:frame";
70
71 /* The tag Guile knows the frame smob by. */
72 static scm_t_bits frame_smob_tag;
73
74 /* Keywords used in argument passing. */
75 static SCM block_keyword;
76
77 static const struct inferior_data *frscm_inferior_data_key;
78 \f
79 /* Administrivia for frame smobs. */
80
81 /* Helper function to hash a frame_smob. */
82
83 static hashval_t
84 frscm_hash_frame_smob (const void *p)
85 {
86 const frame_smob *f_smob = (const frame_smob *) p;
87 const struct frame_id *fid = &f_smob->frame_id;
88 hashval_t hash = htab_hash_pointer (f_smob->inferior);
89
90 if (fid->stack_status == FID_STACK_VALID)
91 hash = iterative_hash (&fid->stack_addr, sizeof (fid->stack_addr), hash);
92 if (fid->code_addr_p)
93 hash = iterative_hash (&fid->code_addr, sizeof (fid->code_addr), hash);
94 if (fid->special_addr_p)
95 hash = iterative_hash (&fid->special_addr, sizeof (fid->special_addr),
96 hash);
97
98 return hash;
99 }
100
101 /* Helper function to compute equality of frame_smobs. */
102
103 static int
104 frscm_eq_frame_smob (const void *ap, const void *bp)
105 {
106 const frame_smob *a = (const frame_smob *) ap;
107 const frame_smob *b = (const frame_smob *) bp;
108
109 return (frame_id_eq (a->frame_id, b->frame_id)
110 && a->inferior == b->inferior
111 && a->inferior != NULL);
112 }
113
114 /* Return the frame -> SCM mapping table.
115 It is created if necessary. */
116
117 static htab_t
118 frscm_inferior_frame_map (struct inferior *inferior)
119 {
120 htab_t htab = (htab_t) inferior_data (inferior, frscm_inferior_data_key);
121
122 if (htab == NULL)
123 {
124 htab = gdbscm_create_eqable_gsmob_ptr_map (frscm_hash_frame_smob,
125 frscm_eq_frame_smob);
126 set_inferior_data (inferior, frscm_inferior_data_key, htab);
127 }
128
129 return htab;
130 }
131
132 /* The smob "free" function for <gdb:frame>. */
133
134 static size_t
135 frscm_free_frame_smob (SCM self)
136 {
137 frame_smob *f_smob = (frame_smob *) SCM_SMOB_DATA (self);
138
139 if (f_smob->inferior != NULL)
140 {
141 htab_t htab = frscm_inferior_frame_map (f_smob->inferior);
142
143 gdbscm_clear_eqable_gsmob_ptr_slot (htab, &f_smob->base);
144 }
145
146 /* Not necessary, done to catch bugs. */
147 f_smob->inferior = NULL;
148
149 return 0;
150 }
151
152 /* The smob "print" function for <gdb:frame>. */
153
154 static int
155 frscm_print_frame_smob (SCM self, SCM port, scm_print_state *pstate)
156 {
157 frame_smob *f_smob = (frame_smob *) SCM_SMOB_DATA (self);
158
159 gdbscm_printf (port, "#<%s ", frame_smob_name);
160
161 string_file strfile;
162 fprint_frame_id (&strfile, f_smob->frame_id);
163 gdbscm_printf (port, "%s", strfile.c_str ());
164
165 scm_puts (">", port);
166
167 scm_remember_upto_here_1 (self);
168
169 /* Non-zero means success. */
170 return 1;
171 }
172
173 /* Low level routine to create a <gdb:frame> object. */
174
175 static SCM
176 frscm_make_frame_smob (void)
177 {
178 frame_smob *f_smob = (frame_smob *)
179 scm_gc_malloc (sizeof (frame_smob), frame_smob_name);
180 SCM f_scm;
181
182 f_smob->frame_id = null_frame_id;
183 f_smob->gdbarch = NULL;
184 f_smob->inferior = NULL;
185 f_smob->frame_id_is_next = 0;
186 f_scm = scm_new_smob (frame_smob_tag, (scm_t_bits) f_smob);
187 gdbscm_init_eqable_gsmob (&f_smob->base, f_scm);
188
189 return f_scm;
190 }
191
192 /* Return non-zero if SCM is a <gdb:frame> object. */
193
194 int
195 frscm_is_frame (SCM scm)
196 {
197 return SCM_SMOB_PREDICATE (frame_smob_tag, scm);
198 }
199
200 /* (frame? object) -> boolean */
201
202 static SCM
203 gdbscm_frame_p (SCM scm)
204 {
205 return scm_from_bool (frscm_is_frame (scm));
206 }
207
208 /* Create a new <gdb:frame> object that encapsulates FRAME.
209 Returns a <gdb:exception> object if there is an error. */
210
211 static SCM
212 frscm_scm_from_frame (struct frame_info *frame, struct inferior *inferior)
213 {
214 frame_smob *f_smob, f_smob_for_lookup;
215 SCM f_scm;
216 htab_t htab;
217 eqable_gdb_smob **slot;
218 struct frame_id frame_id = null_frame_id;
219 struct gdbarch *gdbarch = NULL;
220 int frame_id_is_next = 0;
221
222 /* If we've already created a gsmob for this frame, return it.
223 This makes frames eq?-able. */
224 htab = frscm_inferior_frame_map (inferior);
225 f_smob_for_lookup.frame_id = get_frame_id (frame);
226 f_smob_for_lookup.inferior = inferior;
227 slot = gdbscm_find_eqable_gsmob_ptr_slot (htab, &f_smob_for_lookup.base);
228 if (*slot != NULL)
229 return (*slot)->containing_scm;
230
231 try
232 {
233 /* Try to get the previous frame, to determine if this is the last frame
234 in a corrupt stack. If so, we need to store the frame_id of the next
235 frame and not of this one (which is possibly invalid). */
236 if (get_prev_frame (frame) == NULL
237 && get_frame_unwind_stop_reason (frame) != UNWIND_NO_REASON
238 && get_next_frame (frame) != NULL)
239 {
240 frame_id = get_frame_id (get_next_frame (frame));
241 frame_id_is_next = 1;
242 }
243 else
244 {
245 frame_id = get_frame_id (frame);
246 frame_id_is_next = 0;
247 }
248 gdbarch = get_frame_arch (frame);
249 }
250 catch (const gdb_exception &except)
251 {
252 return gdbscm_scm_from_gdb_exception (unpack (except));
253 }
254
255 f_scm = frscm_make_frame_smob ();
256 f_smob = (frame_smob *) SCM_SMOB_DATA (f_scm);
257 f_smob->frame_id = frame_id;
258 f_smob->gdbarch = gdbarch;
259 f_smob->inferior = inferior;
260 f_smob->frame_id_is_next = frame_id_is_next;
261
262 gdbscm_fill_eqable_gsmob_ptr_slot (slot, &f_smob->base);
263
264 return f_scm;
265 }
266
267 /* Create a new <gdb:frame> object that encapsulates FRAME.
268 A Scheme exception is thrown if there is an error. */
269
270 static SCM
271 frscm_scm_from_frame_unsafe (struct frame_info *frame,
272 struct inferior *inferior)
273 {
274 SCM f_scm = frscm_scm_from_frame (frame, inferior);
275
276 if (gdbscm_is_exception (f_scm))
277 gdbscm_throw (f_scm);
278
279 return f_scm;
280 }
281
282 /* Returns the <gdb:frame> object in SELF.
283 Throws an exception if SELF is not a <gdb:frame> object. */
284
285 static SCM
286 frscm_get_frame_arg_unsafe (SCM self, int arg_pos, const char *func_name)
287 {
288 SCM_ASSERT_TYPE (frscm_is_frame (self), self, arg_pos, func_name,
289 frame_smob_name);
290
291 return self;
292 }
293
294 /* There is no gdbscm_scm_to_frame function because translating
295 a frame SCM object to a struct frame_info * can throw a GDB error.
296 Thus code working with frames has to handle both Scheme errors (e.g., the
297 object is not a frame) and GDB errors (e.g., the frame lookup failed).
298
299 To help keep things clear we split what would be gdbscm_scm_to_frame
300 into two:
301
302 frscm_get_frame_smob_arg_unsafe
303 - throws a Scheme error if object is not a frame,
304 or if the inferior is gone or is no longer current
305
306 frscm_frame_smob_to_frame
307 - may throw a gdb error if the conversion fails
308 - it's not clear when it will and won't throw a GDB error,
309 but for robustness' sake we assume that whenever we call out to GDB
310 a GDB error may get thrown (and thus the call must be wrapped in a
311 TRY_CATCH) */
312
313 /* Returns the frame_smob for the object wrapped by FRAME_SCM.
314 A Scheme error is thrown if FRAME_SCM is not a frame. */
315
316 frame_smob *
317 frscm_get_frame_smob_arg_unsafe (SCM self, int arg_pos, const char *func_name)
318 {
319 SCM f_scm = frscm_get_frame_arg_unsafe (self, arg_pos, func_name);
320 frame_smob *f_smob = (frame_smob *) SCM_SMOB_DATA (f_scm);
321
322 if (f_smob->inferior == NULL)
323 {
324 gdbscm_invalid_object_error (func_name, arg_pos, self,
325 _("inferior"));
326 }
327 if (f_smob->inferior != current_inferior ())
328 scm_misc_error (func_name, _("inferior has changed"), SCM_EOL);
329
330 return f_smob;
331 }
332
333 /* Returns the frame_info object wrapped by F_SMOB.
334 If the frame doesn't exist anymore (the frame id doesn't
335 correspond to any frame in the inferior), returns NULL.
336 This function calls GDB routines, so don't assume a GDB error will
337 not be thrown. */
338
339 struct frame_info *
340 frscm_frame_smob_to_frame (frame_smob *f_smob)
341 {
342 struct frame_info *frame;
343
344 frame = frame_find_by_id (f_smob->frame_id);
345 if (frame == NULL)
346 return NULL;
347
348 if (f_smob->frame_id_is_next)
349 frame = get_prev_frame (frame);
350
351 return frame;
352 }
353
354 /* Helper function for frscm_del_inferior_frames to mark the frame
355 as invalid. */
356
357 static int
358 frscm_mark_frame_invalid (void **slot, void *info)
359 {
360 frame_smob *f_smob = (frame_smob *) *slot;
361
362 f_smob->inferior = NULL;
363 return 1;
364 }
365
366 /* This function is called when an inferior is about to be freed.
367 Invalidate the frame as further actions on the frame could result
368 in bad data. All access to the frame should be gated by
369 frscm_get_frame_smob_arg_unsafe which will raise an exception on
370 invalid frames. */
371
372 static void
373 frscm_del_inferior_frames (struct inferior *inferior, void *datum)
374 {
375 htab_t htab = (htab_t) datum;
376
377 if (htab != NULL)
378 {
379 htab_traverse_noresize (htab, frscm_mark_frame_invalid, NULL);
380 htab_delete (htab);
381 }
382 }
383 \f
384 /* Frame methods. */
385
386 /* (frame-valid? <gdb:frame>) -> bool
387 Returns #t if the frame corresponding to the frame_id of this
388 object still exists in the inferior. */
389
390 static SCM
391 gdbscm_frame_valid_p (SCM self)
392 {
393 frame_smob *f_smob;
394 struct frame_info *frame = NULL;
395
396 f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
397
398 gdbscm_gdb_exception exc {};
399 try
400 {
401 frame = frscm_frame_smob_to_frame (f_smob);
402 }
403 catch (const gdb_exception &except)
404 {
405 exc = unpack (except);
406 }
407
408 GDBSCM_HANDLE_GDB_EXCEPTION (exc);
409 return scm_from_bool (frame != NULL);
410 }
411
412 /* (frame-name <gdb:frame>) -> string
413 Returns the name of the function corresponding to this frame,
414 or #f if there is no function. */
415
416 static SCM
417 gdbscm_frame_name (SCM self)
418 {
419 frame_smob *f_smob;
420 gdb::unique_xmalloc_ptr<char> name;
421 enum language lang = language_minimal;
422 struct frame_info *frame = NULL;
423 SCM result;
424
425 f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
426
427 gdbscm_gdb_exception exc {};
428 try
429 {
430 frame = frscm_frame_smob_to_frame (f_smob);
431 if (frame != NULL)
432 name = find_frame_funname (frame, &lang, NULL);
433 }
434 catch (const gdb_exception &except)
435 {
436 exc = unpack (except);
437 }
438
439 GDBSCM_HANDLE_GDB_EXCEPTION (exc);
440 if (frame == NULL)
441 {
442 gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
443 _("<gdb:frame>"));
444 }
445
446 if (name != NULL)
447 result = gdbscm_scm_from_c_string (name.get ());
448 else
449 result = SCM_BOOL_F;
450
451 return result;
452 }
453
454 /* (frame-type <gdb:frame>) -> integer
455 Returns the frame type, namely one of the gdb:*_FRAME constants. */
456
457 static SCM
458 gdbscm_frame_type (SCM self)
459 {
460 frame_smob *f_smob;
461 enum frame_type type = NORMAL_FRAME;
462 struct frame_info *frame = NULL;
463
464 f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
465
466 gdbscm_gdb_exception exc {};
467 try
468 {
469 frame = frscm_frame_smob_to_frame (f_smob);
470 if (frame != NULL)
471 type = get_frame_type (frame);
472 }
473 catch (const gdb_exception &except)
474 {
475 exc = unpack (except);
476 }
477
478 GDBSCM_HANDLE_GDB_EXCEPTION (exc);
479 if (frame == NULL)
480 {
481 gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
482 _("<gdb:frame>"));
483 }
484
485 return scm_from_int (type);
486 }
487
488 /* (frame-arch <gdb:frame>) -> <gdb:architecture>
489 Returns the frame's architecture as a gdb:architecture object. */
490
491 static SCM
492 gdbscm_frame_arch (SCM self)
493 {
494 frame_smob *f_smob;
495 struct frame_info *frame = NULL;
496
497 f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
498
499 gdbscm_gdb_exception exc {};
500 try
501 {
502 frame = frscm_frame_smob_to_frame (f_smob);
503 }
504 catch (const gdb_exception &except)
505 {
506 exc = unpack (except);
507 }
508
509 GDBSCM_HANDLE_GDB_EXCEPTION (exc);
510 if (frame == NULL)
511 {
512 gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
513 _("<gdb:frame>"));
514 }
515
516 return arscm_scm_from_arch (f_smob->gdbarch);
517 }
518
519 /* (frame-unwind-stop-reason <gdb:frame>) -> integer
520 Returns one of the gdb:FRAME_UNWIND_* constants. */
521
522 static SCM
523 gdbscm_frame_unwind_stop_reason (SCM self)
524 {
525 frame_smob *f_smob;
526 struct frame_info *frame = NULL;
527 enum unwind_stop_reason stop_reason;
528
529 f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
530
531 gdbscm_gdb_exception exc {};
532 try
533 {
534 frame = frscm_frame_smob_to_frame (f_smob);
535 }
536 catch (const gdb_exception &except)
537 {
538 exc = unpack (except);
539 }
540
541 GDBSCM_HANDLE_GDB_EXCEPTION (exc);
542 if (frame == NULL)
543 {
544 gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
545 _("<gdb:frame>"));
546 }
547
548 stop_reason = get_frame_unwind_stop_reason (frame);
549
550 return scm_from_int (stop_reason);
551 }
552
553 /* (frame-pc <gdb:frame>) -> integer
554 Returns the frame's resume address. */
555
556 static SCM
557 gdbscm_frame_pc (SCM self)
558 {
559 frame_smob *f_smob;
560 CORE_ADDR pc = 0;
561 struct frame_info *frame = NULL;
562
563 f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
564
565 gdbscm_gdb_exception exc {};
566 try
567 {
568 frame = frscm_frame_smob_to_frame (f_smob);
569 if (frame != NULL)
570 pc = get_frame_pc (frame);
571 }
572 catch (const gdb_exception &except)
573 {
574 exc = unpack (except);
575 }
576
577 GDBSCM_HANDLE_GDB_EXCEPTION (exc);
578 if (frame == NULL)
579 {
580 gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
581 _("<gdb:frame>"));
582 }
583
584 return gdbscm_scm_from_ulongest (pc);
585 }
586
587 /* (frame-block <gdb:frame>) -> <gdb:block>
588 Returns the frame's code block, or #f if one cannot be found. */
589
590 static SCM
591 gdbscm_frame_block (SCM self)
592 {
593 frame_smob *f_smob;
594 const struct block *block = NULL, *fn_block;
595 struct frame_info *frame = NULL;
596
597 f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
598
599 gdbscm_gdb_exception exc {};
600 try
601 {
602 frame = frscm_frame_smob_to_frame (f_smob);
603 if (frame != NULL)
604 block = get_frame_block (frame, NULL);
605 }
606 catch (const gdb_exception &except)
607 {
608 exc = unpack (except);
609 }
610
611 GDBSCM_HANDLE_GDB_EXCEPTION (exc);
612 if (frame == NULL)
613 {
614 gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
615 _("<gdb:frame>"));
616 }
617
618 for (fn_block = block;
619 fn_block != NULL && BLOCK_FUNCTION (fn_block) == NULL;
620 fn_block = BLOCK_SUPERBLOCK (fn_block))
621 continue;
622
623 if (block == NULL || fn_block == NULL || BLOCK_FUNCTION (fn_block) == NULL)
624 {
625 scm_misc_error (FUNC_NAME, _("cannot find block for frame"),
626 scm_list_1 (self));
627 }
628
629 if (block != NULL)
630 {
631 return bkscm_scm_from_block
632 (block, symbol_objfile (BLOCK_FUNCTION (fn_block)));
633 }
634
635 return SCM_BOOL_F;
636 }
637
638 /* (frame-function <gdb:frame>) -> <gdb:symbol>
639 Returns the symbol for the function corresponding to this frame,
640 or #f if there isn't one. */
641
642 static SCM
643 gdbscm_frame_function (SCM self)
644 {
645 frame_smob *f_smob;
646 struct symbol *sym = NULL;
647 struct frame_info *frame = NULL;
648
649 f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
650
651 gdbscm_gdb_exception exc {};
652 try
653 {
654 frame = frscm_frame_smob_to_frame (f_smob);
655 if (frame != NULL)
656 sym = find_pc_function (get_frame_address_in_block (frame));
657 }
658 catch (const gdb_exception &except)
659 {
660 exc = unpack (except);
661 }
662
663 GDBSCM_HANDLE_GDB_EXCEPTION (exc);
664 if (frame == NULL)
665 {
666 gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
667 _("<gdb:frame>"));
668 }
669
670 if (sym != NULL)
671 return syscm_scm_from_symbol (sym);
672
673 return SCM_BOOL_F;
674 }
675
676 /* (frame-older <gdb:frame>) -> <gdb:frame>
677 Returns the frame immediately older (outer) to this frame,
678 or #f if there isn't one. */
679
680 static SCM
681 gdbscm_frame_older (SCM self)
682 {
683 frame_smob *f_smob;
684 struct frame_info *prev = NULL;
685 struct frame_info *frame = NULL;
686
687 f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
688
689 gdbscm_gdb_exception exc {};
690 try
691 {
692 frame = frscm_frame_smob_to_frame (f_smob);
693 if (frame != NULL)
694 prev = get_prev_frame (frame);
695 }
696 catch (const gdb_exception &except)
697 {
698 exc = unpack (except);
699 }
700
701 GDBSCM_HANDLE_GDB_EXCEPTION (exc);
702 if (frame == NULL)
703 {
704 gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
705 _("<gdb:frame>"));
706 }
707
708 if (prev != NULL)
709 return frscm_scm_from_frame_unsafe (prev, f_smob->inferior);
710
711 return SCM_BOOL_F;
712 }
713
714 /* (frame-newer <gdb:frame>) -> <gdb:frame>
715 Returns the frame immediately newer (inner) to this frame,
716 or #f if there isn't one. */
717
718 static SCM
719 gdbscm_frame_newer (SCM self)
720 {
721 frame_smob *f_smob;
722 struct frame_info *next = NULL;
723 struct frame_info *frame = NULL;
724
725 f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
726
727 gdbscm_gdb_exception exc {};
728 try
729 {
730 frame = frscm_frame_smob_to_frame (f_smob);
731 if (frame != NULL)
732 next = get_next_frame (frame);
733 }
734 catch (const gdb_exception &except)
735 {
736 exc = unpack (except);
737 }
738
739 GDBSCM_HANDLE_GDB_EXCEPTION (exc);
740 if (frame == NULL)
741 {
742 gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
743 _("<gdb:frame>"));
744 }
745
746 if (next != NULL)
747 return frscm_scm_from_frame_unsafe (next, f_smob->inferior);
748
749 return SCM_BOOL_F;
750 }
751
752 /* (frame-sal <gdb:frame>) -> <gdb:sal>
753 Returns the frame's symtab and line. */
754
755 static SCM
756 gdbscm_frame_sal (SCM self)
757 {
758 frame_smob *f_smob;
759 struct symtab_and_line sal;
760 struct frame_info *frame = NULL;
761
762 f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
763
764 gdbscm_gdb_exception exc {};
765 try
766 {
767 frame = frscm_frame_smob_to_frame (f_smob);
768 if (frame != NULL)
769 sal = find_frame_sal (frame);
770 }
771 catch (const gdb_exception &except)
772 {
773 exc = unpack (except);
774 }
775
776 GDBSCM_HANDLE_GDB_EXCEPTION (exc);
777 if (frame == NULL)
778 {
779 gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
780 _("<gdb:frame>"));
781 }
782
783 return stscm_scm_from_sal (sal);
784 }
785
786 /* (frame-read-register <gdb:frame> string) -> <gdb:value>
787 The register argument must be a string. */
788
789 static SCM
790 gdbscm_frame_read_register (SCM self, SCM register_scm)
791 {
792 char *register_str;
793 struct value *value = NULL;
794 struct frame_info *frame = NULL;
795 frame_smob *f_smob;
796
797 f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
798 gdbscm_parse_function_args (FUNC_NAME, SCM_ARG2, NULL, "s",
799 register_scm, &register_str);
800
801 gdbscm_gdb_exception except {};
802
803 try
804 {
805 int regnum;
806
807 frame = frscm_frame_smob_to_frame (f_smob);
808 if (frame)
809 {
810 regnum = user_reg_map_name_to_regnum (get_frame_arch (frame),
811 register_str,
812 strlen (register_str));
813 if (regnum >= 0)
814 value = value_of_register (regnum, frame);
815 }
816 }
817 catch (const gdb_exception &ex)
818 {
819 except = unpack (ex);
820 }
821
822 xfree (register_str);
823 GDBSCM_HANDLE_GDB_EXCEPTION (except);
824
825 if (frame == NULL)
826 {
827 gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
828 _("<gdb:frame>"));
829 }
830
831 if (value == NULL)
832 {
833 gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG2, register_scm,
834 _("unknown register"));
835 }
836
837 return vlscm_scm_from_value (value);
838 }
839
840 /* (frame-read-var <gdb:frame> <gdb:symbol>) -> <gdb:value>
841 (frame-read-var <gdb:frame> string [#:block <gdb:block>]) -> <gdb:value>
842 If the optional block argument is provided start the search from that block,
843 otherwise search from the frame's current block (determined by examining
844 the resume address of the frame). The variable argument must be a string
845 or an instance of a <gdb:symbol>. The block argument must be an instance of
846 <gdb:block>. */
847
848 static SCM
849 gdbscm_frame_read_var (SCM self, SCM symbol_scm, SCM rest)
850 {
851 SCM keywords[] = { block_keyword, SCM_BOOL_F };
852 frame_smob *f_smob;
853 int block_arg_pos = -1;
854 SCM block_scm = SCM_UNDEFINED;
855 struct frame_info *frame = NULL;
856 struct symbol *var = NULL;
857 const struct block *block = NULL;
858 struct value *value = NULL;
859
860 f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
861
862 gdbscm_gdb_exception exc {};
863 try
864 {
865 frame = frscm_frame_smob_to_frame (f_smob);
866 }
867 catch (const gdb_exception &except)
868 {
869 exc = unpack (except);
870 }
871
872 GDBSCM_HANDLE_GDB_EXCEPTION (exc);
873 if (frame == NULL)
874 {
875 gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
876 _("<gdb:frame>"));
877 }
878
879 gdbscm_parse_function_args (FUNC_NAME, SCM_ARG3, keywords, "#O",
880 rest, &block_arg_pos, &block_scm);
881
882 if (syscm_is_symbol (symbol_scm))
883 {
884 var = syscm_get_valid_symbol_arg_unsafe (symbol_scm, SCM_ARG2,
885 FUNC_NAME);
886 SCM_ASSERT (SCM_UNBNDP (block_scm), block_scm, SCM_ARG3, FUNC_NAME);
887 }
888 else if (scm_is_string (symbol_scm))
889 {
890 gdbscm_gdb_exception except {};
891
892 if (! SCM_UNBNDP (block_scm))
893 {
894 SCM except_scm;
895
896 gdb_assert (block_arg_pos > 0);
897 block = bkscm_scm_to_block (block_scm, block_arg_pos, FUNC_NAME,
898 &except_scm);
899 if (block == NULL)
900 gdbscm_throw (except_scm);
901 }
902
903 {
904 gdb::unique_xmalloc_ptr<char> var_name
905 (gdbscm_scm_to_c_string (symbol_scm));
906 /* N.B. Between here and the end of the scope, don't do anything
907 to cause a Scheme exception. */
908
909 try
910 {
911 struct block_symbol lookup_sym;
912
913 if (block == NULL)
914 block = get_frame_block (frame, NULL);
915 lookup_sym = lookup_symbol (var_name.get (), block, VAR_DOMAIN,
916 NULL);
917 var = lookup_sym.symbol;
918 block = lookup_sym.block;
919 }
920 catch (const gdb_exception &ex)
921 {
922 except = unpack (ex);
923 }
924 }
925
926 GDBSCM_HANDLE_GDB_EXCEPTION (except);
927
928 if (var == NULL)
929 gdbscm_out_of_range_error (FUNC_NAME, 0, symbol_scm,
930 _("variable not found"));
931 }
932 else
933 {
934 /* Use SCM_ASSERT_TYPE for more consistent error messages. */
935 SCM_ASSERT_TYPE (0, symbol_scm, SCM_ARG1, FUNC_NAME,
936 _("gdb:symbol or string"));
937 }
938
939 try
940 {
941 value = read_var_value (var, block, frame);
942 }
943 catch (const gdb_exception &except)
944 {
945 exc = unpack (except);
946 }
947
948 GDBSCM_HANDLE_GDB_EXCEPTION (exc);
949 return vlscm_scm_from_value (value);
950 }
951
952 /* (frame-select <gdb:frame>) -> unspecified
953 Select this frame. */
954
955 static SCM
956 gdbscm_frame_select (SCM self)
957 {
958 frame_smob *f_smob;
959 struct frame_info *frame = NULL;
960
961 f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
962
963 gdbscm_gdb_exception exc {};
964 try
965 {
966 frame = frscm_frame_smob_to_frame (f_smob);
967 if (frame != NULL)
968 select_frame (frame);
969 }
970 catch (const gdb_exception &except)
971 {
972 exc = unpack (except);
973 }
974
975 GDBSCM_HANDLE_GDB_EXCEPTION (exc);
976 if (frame == NULL)
977 {
978 gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
979 _("<gdb:frame>"));
980 }
981
982 return SCM_UNSPECIFIED;
983 }
984
985 /* (newest-frame) -> <gdb:frame>
986 Returns the newest frame. */
987
988 static SCM
989 gdbscm_newest_frame (void)
990 {
991 struct frame_info *frame = NULL;
992
993 gdbscm_gdb_exception exc {};
994 try
995 {
996 frame = get_current_frame ();
997 }
998 catch (const gdb_exception &except)
999 {
1000 exc = unpack (except);
1001 }
1002
1003 GDBSCM_HANDLE_GDB_EXCEPTION (exc);
1004 return frscm_scm_from_frame_unsafe (frame, current_inferior ());
1005 }
1006
1007 /* (selected-frame) -> <gdb:frame>
1008 Returns the selected frame. */
1009
1010 static SCM
1011 gdbscm_selected_frame (void)
1012 {
1013 struct frame_info *frame = NULL;
1014
1015 gdbscm_gdb_exception exc {};
1016 try
1017 {
1018 frame = get_selected_frame (_("No frame is currently selected"));
1019 }
1020 catch (const gdb_exception &except)
1021 {
1022 exc = unpack (except);
1023 }
1024
1025 GDBSCM_HANDLE_GDB_EXCEPTION (exc);
1026 return frscm_scm_from_frame_unsafe (frame, current_inferior ());
1027 }
1028
1029 /* (unwind-stop-reason-string integer) -> string
1030 Return a string explaining the unwind stop reason. */
1031
1032 static SCM
1033 gdbscm_unwind_stop_reason_string (SCM reason_scm)
1034 {
1035 int reason;
1036 const char *str;
1037
1038 gdbscm_parse_function_args (FUNC_NAME, SCM_ARG1, NULL, "i",
1039 reason_scm, &reason);
1040
1041 if (reason < UNWIND_FIRST || reason > UNWIND_LAST)
1042 scm_out_of_range (FUNC_NAME, reason_scm);
1043
1044 str = unwind_stop_reason_to_string ((enum unwind_stop_reason) reason);
1045 return gdbscm_scm_from_c_string (str);
1046 }
1047 \f
1048 /* Initialize the Scheme frame support. */
1049
1050 static const scheme_integer_constant frame_integer_constants[] =
1051 {
1052 #define ENTRY(X) { #X, X }
1053
1054 ENTRY (NORMAL_FRAME),
1055 ENTRY (DUMMY_FRAME),
1056 ENTRY (INLINE_FRAME),
1057 ENTRY (TAILCALL_FRAME),
1058 ENTRY (SIGTRAMP_FRAME),
1059 ENTRY (ARCH_FRAME),
1060 ENTRY (SENTINEL_FRAME),
1061
1062 #undef ENTRY
1063
1064 #define SET(name, description) \
1065 { "FRAME_" #name, name },
1066 #include "unwind_stop_reasons.def"
1067 #undef SET
1068
1069 END_INTEGER_CONSTANTS
1070 };
1071
1072 static const scheme_function frame_functions[] =
1073 {
1074 { "frame?", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_p),
1075 "\
1076 Return #t if the object is a <gdb:frame> object." },
1077
1078 { "frame-valid?", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_valid_p),
1079 "\
1080 Return #t if the object is a valid <gdb:frame> object.\n\
1081 Frames become invalid when the inferior returns to its caller." },
1082
1083 { "frame-name", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_name),
1084 "\
1085 Return the name of the function corresponding to this frame,\n\
1086 or #f if there is no function." },
1087
1088 { "frame-arch", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_arch),
1089 "\
1090 Return the frame's architecture as a <gdb:arch> object." },
1091
1092 { "frame-type", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_type),
1093 "\
1094 Return the frame type, namely one of the gdb:*_FRAME constants." },
1095
1096 { "frame-unwind-stop-reason", 1, 0, 0,
1097 as_a_scm_t_subr (gdbscm_frame_unwind_stop_reason),
1098 "\
1099 Return one of the gdb:FRAME_UNWIND_* constants explaining why\n\
1100 it's not possible to find frames older than this." },
1101
1102 { "frame-pc", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_pc),
1103 "\
1104 Return the frame's resume address." },
1105
1106 { "frame-block", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_block),
1107 "\
1108 Return the frame's code block, or #f if one cannot be found." },
1109
1110 { "frame-function", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_function),
1111 "\
1112 Return the <gdb:symbol> for the function corresponding to this frame,\n\
1113 or #f if there isn't one." },
1114
1115 { "frame-older", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_older),
1116 "\
1117 Return the frame immediately older (outer) to this frame,\n\
1118 or #f if there isn't one." },
1119
1120 { "frame-newer", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_newer),
1121 "\
1122 Return the frame immediately newer (inner) to this frame,\n\
1123 or #f if there isn't one." },
1124
1125 { "frame-sal", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_sal),
1126 "\
1127 Return the frame's symtab-and-line <gdb:sal> object." },
1128
1129 { "frame-read-var", 2, 0, 1, as_a_scm_t_subr (gdbscm_frame_read_var),
1130 "\
1131 Return the value of the symbol in the frame.\n\
1132 \n\
1133 Arguments: <gdb:frame> <gdb:symbol>\n\
1134 Or: <gdb:frame> string [#:block <gdb:block>]" },
1135
1136 { "frame-read-register", 2, 0, 0,
1137 as_a_scm_t_subr (gdbscm_frame_read_register),
1138 "\
1139 Return the value of the register in the frame.\n\
1140 \n\
1141 Arguments: <gdb:frame> string" },
1142
1143 { "frame-select", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_select),
1144 "\
1145 Select this frame." },
1146
1147 { "newest-frame", 0, 0, 0, as_a_scm_t_subr (gdbscm_newest_frame),
1148 "\
1149 Return the newest frame." },
1150
1151 { "selected-frame", 0, 0, 0, as_a_scm_t_subr (gdbscm_selected_frame),
1152 "\
1153 Return the selected frame." },
1154
1155 { "unwind-stop-reason-string", 1, 0, 0,
1156 as_a_scm_t_subr (gdbscm_unwind_stop_reason_string),
1157 "\
1158 Return a string explaining the unwind stop reason.\n\
1159 \n\
1160 Arguments: integer (the result of frame-unwind-stop-reason)" },
1161
1162 END_FUNCTIONS
1163 };
1164
1165 void
1166 gdbscm_initialize_frames (void)
1167 {
1168 frame_smob_tag
1169 = gdbscm_make_smob_type (frame_smob_name, sizeof (frame_smob));
1170 scm_set_smob_free (frame_smob_tag, frscm_free_frame_smob);
1171 scm_set_smob_print (frame_smob_tag, frscm_print_frame_smob);
1172
1173 gdbscm_define_integer_constants (frame_integer_constants, 1);
1174 gdbscm_define_functions (frame_functions, 1);
1175
1176 block_keyword = scm_from_latin1_keyword ("block");
1177
1178 /* Register an inferior "free" callback so we can properly
1179 invalidate frames when an inferior file is about to be deleted. */
1180 frscm_inferior_data_key
1181 = register_inferior_data_with_cleanup (NULL, frscm_del_inferior_frames);
1182 }