]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/guile/scm-frame.c
Remove redundant typedefs
[thirdparty/binutils-gdb.git] / gdb / guile / scm-frame.c
CommitLineData
ed3ef339
DE
1/* Scheme interface to stack frames.
2
b811d2c2 3 Copyright (C) 2008-2020 Free Software Foundation, Inc.
ed3ef339
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/* 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"
ed3ef339
DE
26#include "inferior.h"
27#include "objfiles.h"
28#include "symfile.h"
29#include "symtab.h"
30#include "stack.h"
f2983cc3 31#include "user-regs.h"
ed3ef339
DE
32#include "value.h"
33#include "guile-internal.h"
34
f99b5177 35/* The <gdb:frame> smob. */
ed3ef339 36
f99b5177 37struct frame_smob
ed3ef339
DE
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
69static const char frame_smob_name[] = "gdb:frame";
70
71/* The tag Guile knows the frame smob by. */
72static scm_t_bits frame_smob_tag;
73
74/* Keywords used in argument passing. */
75static SCM block_keyword;
76
77static 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
83static hashval_t
84frscm_hash_frame_smob (const void *p)
85{
9a3c8263 86 const frame_smob *f_smob = (const frame_smob *) p;
ed3ef339
DE
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
103static int
104frscm_eq_frame_smob (const void *ap, const void *bp)
105{
9a3c8263
SM
106 const frame_smob *a = (const frame_smob *) ap;
107 const frame_smob *b = (const frame_smob *) bp;
ed3ef339
DE
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
117static htab_t
118frscm_inferior_frame_map (struct inferior *inferior)
119{
9a3c8263 120 htab_t htab = (htab_t) inferior_data (inferior, frscm_inferior_data_key);
ed3ef339
DE
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
ed3ef339
DE
132/* The smob "free" function for <gdb:frame>. */
133
134static size_t
135frscm_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
154static int
155frscm_print_frame_smob (SCM self, SCM port, scm_print_state *pstate)
156{
157 frame_smob *f_smob = (frame_smob *) SCM_SMOB_DATA (self);
ed3ef339
DE
158
159 gdbscm_printf (port, "#<%s ", frame_smob_name);
160
d7e74731
PA
161 string_file strfile;
162 fprint_frame_id (&strfile, f_smob->frame_id);
163 gdbscm_printf (port, "%s", strfile.c_str ());
ed3ef339
DE
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
175static SCM
176frscm_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);
1254eefc 187 gdbscm_init_eqable_gsmob (&f_smob->base, f_scm);
ed3ef339
DE
188
189 return f_scm;
190}
191
192/* Return non-zero if SCM is a <gdb:frame> object. */
193
194int
195frscm_is_frame (SCM scm)
196{
197 return SCM_SMOB_PREDICATE (frame_smob_tag, scm);
198}
199
200/* (frame? object) -> boolean */
201
202static SCM
203gdbscm_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
211static SCM
212frscm_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;
ed3ef339
DE
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
a70b8144 231 try
ed3ef339
DE
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 }
230d2906 250 catch (const gdb_exception &except)
492d29ea 251 {
680d7fd5 252 return gdbscm_scm_from_gdb_exception (unpack (except));
492d29ea 253 }
ed3ef339
DE
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
1254eefc 262 gdbscm_fill_eqable_gsmob_ptr_slot (slot, &f_smob->base);
ed3ef339
DE
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
270static SCM
271frscm_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
285static SCM
286frscm_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
e9fbd043
DE
299 To help keep things clear we split what would be gdbscm_scm_to_frame
300 into two:
ed3ef339 301
e9fbd043 302 frscm_get_frame_smob_arg_unsafe
ed3ef339
DE
303 - throws a Scheme error if object is not a frame,
304 or if the inferior is gone or is no longer current
305
e9fbd043 306 frscm_frame_smob_to_frame
ed3ef339
DE
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
316frame_smob *
317frscm_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
339struct frame_info *
340frscm_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
357static int
358frscm_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
372static void
373frscm_del_inferior_frames (struct inferior *inferior, void *datum)
374{
9a3c8263 375 htab_t htab = (htab_t) datum;
ed3ef339
DE
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
390static SCM
391gdbscm_frame_valid_p (SCM self)
392{
393 frame_smob *f_smob;
394 struct frame_info *frame = NULL;
ed3ef339
DE
395
396 f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
397
680d7fd5 398 gdbscm_gdb_exception exc {};
a70b8144 399 try
ed3ef339
DE
400 {
401 frame = frscm_frame_smob_to_frame (f_smob);
402 }
230d2906 403 catch (const gdb_exception &except)
492d29ea 404 {
680d7fd5 405 exc = unpack (except);
492d29ea 406 }
ed3ef339 407
680d7fd5 408 GDBSCM_HANDLE_GDB_EXCEPTION (exc);
ed3ef339
DE
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
416static SCM
417gdbscm_frame_name (SCM self)
418{
419 frame_smob *f_smob;
c6dc63a1 420 gdb::unique_xmalloc_ptr<char> name;
ed3ef339
DE
421 enum language lang = language_minimal;
422 struct frame_info *frame = NULL;
423 SCM result;
ed3ef339
DE
424
425 f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
426
680d7fd5 427 gdbscm_gdb_exception exc {};
a70b8144 428 try
ed3ef339
DE
429 {
430 frame = frscm_frame_smob_to_frame (f_smob);
431 if (frame != NULL)
c6dc63a1 432 name = find_frame_funname (frame, &lang, NULL);
ed3ef339 433 }
230d2906 434 catch (const gdb_exception &except)
492d29ea 435 {
680d7fd5 436 exc = unpack (except);
492d29ea 437 }
492d29ea 438
680d7fd5 439 GDBSCM_HANDLE_GDB_EXCEPTION (exc);
ed3ef339
DE
440 if (frame == NULL)
441 {
442 gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self,
443 _("<gdb:frame>"));
444 }
445
446 if (name != NULL)
c6dc63a1 447 result = gdbscm_scm_from_c_string (name.get ());
ed3ef339
DE
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
457static SCM
458gdbscm_frame_type (SCM self)
459{
460 frame_smob *f_smob;
461 enum frame_type type = NORMAL_FRAME;
462 struct frame_info *frame = NULL;
ed3ef339
DE
463
464 f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
465
680d7fd5 466 gdbscm_gdb_exception exc {};
a70b8144 467 try
ed3ef339
DE
468 {
469 frame = frscm_frame_smob_to_frame (f_smob);
470 if (frame != NULL)
471 type = get_frame_type (frame);
472 }
230d2906 473 catch (const gdb_exception &except)
492d29ea 474 {
680d7fd5 475 exc = unpack (except);
492d29ea 476 }
ed3ef339 477
680d7fd5 478 GDBSCM_HANDLE_GDB_EXCEPTION (exc);
ed3ef339
DE
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
491static SCM
492gdbscm_frame_arch (SCM self)
493{
494 frame_smob *f_smob;
495 struct frame_info *frame = NULL;
ed3ef339
DE
496
497 f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
498
680d7fd5 499 gdbscm_gdb_exception exc {};
a70b8144 500 try
ed3ef339
DE
501 {
502 frame = frscm_frame_smob_to_frame (f_smob);
503 }
230d2906 504 catch (const gdb_exception &except)
492d29ea 505 {
680d7fd5 506 exc = unpack (except);
492d29ea 507 }
ed3ef339 508
680d7fd5 509 GDBSCM_HANDLE_GDB_EXCEPTION (exc);
ed3ef339
DE
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
522static SCM
523gdbscm_frame_unwind_stop_reason (SCM self)
524{
525 frame_smob *f_smob;
526 struct frame_info *frame = NULL;
ed3ef339
DE
527 enum unwind_stop_reason stop_reason;
528
529 f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
530
680d7fd5 531 gdbscm_gdb_exception exc {};
a70b8144 532 try
ed3ef339
DE
533 {
534 frame = frscm_frame_smob_to_frame (f_smob);
535 }
230d2906 536 catch (const gdb_exception &except)
492d29ea 537 {
680d7fd5 538 exc = unpack (except);
492d29ea 539 }
ed3ef339 540
680d7fd5 541 GDBSCM_HANDLE_GDB_EXCEPTION (exc);
ed3ef339
DE
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
556static SCM
557gdbscm_frame_pc (SCM self)
558{
559 frame_smob *f_smob;
560 CORE_ADDR pc = 0;
561 struct frame_info *frame = NULL;
ed3ef339
DE
562
563 f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
564
680d7fd5 565 gdbscm_gdb_exception exc {};
a70b8144 566 try
ed3ef339
DE
567 {
568 frame = frscm_frame_smob_to_frame (f_smob);
569 if (frame != NULL)
570 pc = get_frame_pc (frame);
571 }
230d2906 572 catch (const gdb_exception &except)
492d29ea 573 {
680d7fd5 574 exc = unpack (except);
492d29ea 575 }
ed3ef339 576
680d7fd5 577 GDBSCM_HANDLE_GDB_EXCEPTION (exc);
ed3ef339
DE
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
590static SCM
591gdbscm_frame_block (SCM self)
592{
593 frame_smob *f_smob;
3977b71f 594 const struct block *block = NULL, *fn_block;
ed3ef339 595 struct frame_info *frame = NULL;
ed3ef339
DE
596
597 f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
598
680d7fd5 599 gdbscm_gdb_exception exc {};
a70b8144 600 try
ed3ef339
DE
601 {
602 frame = frscm_frame_smob_to_frame (f_smob);
603 if (frame != NULL)
604 block = get_frame_block (frame, NULL);
605 }
230d2906 606 catch (const gdb_exception &except)
492d29ea 607 {
680d7fd5 608 exc = unpack (except);
492d29ea 609 }
ed3ef339 610
680d7fd5 611 GDBSCM_HANDLE_GDB_EXCEPTION (exc);
ed3ef339
DE
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 {
08be3fe3
DE
631 return bkscm_scm_from_block
632 (block, symbol_objfile (BLOCK_FUNCTION (fn_block)));
ed3ef339
DE
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
642static SCM
643gdbscm_frame_function (SCM self)
644{
645 frame_smob *f_smob;
646 struct symbol *sym = NULL;
647 struct frame_info *frame = NULL;
ed3ef339
DE
648
649 f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
650
680d7fd5 651 gdbscm_gdb_exception exc {};
a70b8144 652 try
ed3ef339
DE
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 }
230d2906 658 catch (const gdb_exception &except)
492d29ea 659 {
680d7fd5 660 exc = unpack (except);
492d29ea 661 }
ed3ef339 662
680d7fd5 663 GDBSCM_HANDLE_GDB_EXCEPTION (exc);
ed3ef339
DE
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
680static SCM
681gdbscm_frame_older (SCM self)
682{
683 frame_smob *f_smob;
684 struct frame_info *prev = NULL;
685 struct frame_info *frame = NULL;
ed3ef339
DE
686
687 f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
688
680d7fd5 689 gdbscm_gdb_exception exc {};
a70b8144 690 try
ed3ef339
DE
691 {
692 frame = frscm_frame_smob_to_frame (f_smob);
693 if (frame != NULL)
694 prev = get_prev_frame (frame);
695 }
230d2906 696 catch (const gdb_exception &except)
492d29ea 697 {
680d7fd5 698 exc = unpack (except);
492d29ea 699 }
ed3ef339 700
680d7fd5 701 GDBSCM_HANDLE_GDB_EXCEPTION (exc);
ed3ef339
DE
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
718static SCM
719gdbscm_frame_newer (SCM self)
720{
721 frame_smob *f_smob;
722 struct frame_info *next = NULL;
723 struct frame_info *frame = NULL;
ed3ef339
DE
724
725 f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
726
680d7fd5 727 gdbscm_gdb_exception exc {};
a70b8144 728 try
ed3ef339
DE
729 {
730 frame = frscm_frame_smob_to_frame (f_smob);
731 if (frame != NULL)
732 next = get_next_frame (frame);
733 }
230d2906 734 catch (const gdb_exception &except)
492d29ea 735 {
680d7fd5 736 exc = unpack (except);
492d29ea 737 }
ed3ef339 738
680d7fd5 739 GDBSCM_HANDLE_GDB_EXCEPTION (exc);
ed3ef339
DE
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
755static SCM
756gdbscm_frame_sal (SCM self)
757{
758 frame_smob *f_smob;
759 struct symtab_and_line sal;
760 struct frame_info *frame = NULL;
ed3ef339
DE
761
762 f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
763
680d7fd5 764 gdbscm_gdb_exception exc {};
a70b8144 765 try
ed3ef339
DE
766 {
767 frame = frscm_frame_smob_to_frame (f_smob);
768 if (frame != NULL)
51abb421 769 sal = find_frame_sal (frame);
ed3ef339 770 }
230d2906 771 catch (const gdb_exception &except)
492d29ea 772 {
680d7fd5 773 exc = unpack (except);
492d29ea 774 }
ed3ef339 775
680d7fd5 776 GDBSCM_HANDLE_GDB_EXCEPTION (exc);
ed3ef339
DE
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
f2983cc3
AW
786/* (frame-read-register <gdb:frame> string) -> <gdb:value>
787 The register argument must be a string. */
788
789static SCM
790gdbscm_frame_read_register (SCM self, SCM register_scm)
791{
792 char *register_str;
793 struct value *value = NULL;
794 struct frame_info *frame = NULL;
f2983cc3
AW
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);
557e56be 800
680d7fd5 801 gdbscm_gdb_exception except {};
f2983cc3 802
a70b8144 803 try
f2983cc3
AW
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 }
230d2906 817 catch (const gdb_exception &ex)
f2983cc3 818 {
680d7fd5 819 except = unpack (ex);
f2983cc3 820 }
f2983cc3 821
557e56be
PA
822 xfree (register_str);
823 GDBSCM_HANDLE_GDB_EXCEPTION (except);
f2983cc3
AW
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
ed3ef339
DE
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
848static SCM
849gdbscm_frame_read_var (SCM self, SCM symbol_scm, SCM rest)
850{
851 SCM keywords[] = { block_keyword, SCM_BOOL_F };
ed3ef339
DE
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;
63e43d3a 857 const struct block *block = NULL;
ed3ef339 858 struct value *value = NULL;
ed3ef339
DE
859
860 f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
861
680d7fd5 862 gdbscm_gdb_exception exc {};
a70b8144 863 try
ed3ef339
DE
864 {
865 frame = frscm_frame_smob_to_frame (f_smob);
866 }
230d2906 867 catch (const gdb_exception &except)
492d29ea 868 {
680d7fd5 869 exc = unpack (except);
492d29ea 870 }
ed3ef339 871
680d7fd5 872 GDBSCM_HANDLE_GDB_EXCEPTION (exc);
ed3ef339
DE
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 {
680d7fd5 890 gdbscm_gdb_exception except {};
ed3ef339
DE
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
a95c7dab
TT
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
a70b8144 909 try
a95c7dab
TT
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 }
230d2906 920 catch (const gdb_exception &ex)
a95c7dab 921 {
680d7fd5 922 except = unpack (ex);
a95c7dab 923 }
a95c7dab 924 }
ed3ef339 925
ed3ef339
DE
926 GDBSCM_HANDLE_GDB_EXCEPTION (except);
927
928 if (var == NULL)
a95c7dab
TT
929 gdbscm_out_of_range_error (FUNC_NAME, 0, symbol_scm,
930 _("variable not found"));
ed3ef339
DE
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
a70b8144 939 try
ed3ef339 940 {
63e43d3a 941 value = read_var_value (var, block, frame);
ed3ef339 942 }
230d2906 943 catch (const gdb_exception &except)
492d29ea 944 {
680d7fd5 945 exc = unpack (except);
492d29ea 946 }
ed3ef339 947
680d7fd5 948 GDBSCM_HANDLE_GDB_EXCEPTION (exc);
ed3ef339
DE
949 return vlscm_scm_from_value (value);
950}
951
952/* (frame-select <gdb:frame>) -> unspecified
953 Select this frame. */
954
955static SCM
956gdbscm_frame_select (SCM self)
957{
958 frame_smob *f_smob;
959 struct frame_info *frame = NULL;
ed3ef339
DE
960
961 f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
962
680d7fd5 963 gdbscm_gdb_exception exc {};
a70b8144 964 try
ed3ef339
DE
965 {
966 frame = frscm_frame_smob_to_frame (f_smob);
967 if (frame != NULL)
968 select_frame (frame);
969 }
230d2906 970 catch (const gdb_exception &except)
492d29ea 971 {
680d7fd5 972 exc = unpack (except);
492d29ea 973 }
ed3ef339 974
680d7fd5 975 GDBSCM_HANDLE_GDB_EXCEPTION (exc);
ed3ef339
DE
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
988static SCM
989gdbscm_newest_frame (void)
990{
991 struct frame_info *frame = NULL;
ed3ef339 992
680d7fd5 993 gdbscm_gdb_exception exc {};
a70b8144 994 try
ed3ef339
DE
995 {
996 frame = get_current_frame ();
997 }
230d2906 998 catch (const gdb_exception &except)
492d29ea 999 {
680d7fd5 1000 exc = unpack (except);
492d29ea 1001 }
ed3ef339 1002
680d7fd5 1003 GDBSCM_HANDLE_GDB_EXCEPTION (exc);
ed3ef339
DE
1004 return frscm_scm_from_frame_unsafe (frame, current_inferior ());
1005}
1006
1007/* (selected-frame) -> <gdb:frame>
1008 Returns the selected frame. */
1009
1010static SCM
1011gdbscm_selected_frame (void)
1012{
1013 struct frame_info *frame = NULL;
ed3ef339 1014
680d7fd5 1015 gdbscm_gdb_exception exc {};
a70b8144 1016 try
ed3ef339
DE
1017 {
1018 frame = get_selected_frame (_("No frame is currently selected"));
1019 }
230d2906 1020 catch (const gdb_exception &except)
492d29ea 1021 {
680d7fd5 1022 exc = unpack (except);
492d29ea 1023 }
ed3ef339 1024
680d7fd5 1025 GDBSCM_HANDLE_GDB_EXCEPTION (exc);
ed3ef339
DE
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
1032static SCM
1033gdbscm_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
fa4c39cb 1044 str = unwind_stop_reason_to_string ((enum unwind_stop_reason) reason);
ed3ef339
DE
1045 return gdbscm_scm_from_c_string (str);
1046}
1047\f
1048/* Initialize the Scheme frame support. */
1049
1050static 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
1072static const scheme_function frame_functions[] =
1073{
72e02483 1074 { "frame?", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_p),
ed3ef339
DE
1075 "\
1076Return #t if the object is a <gdb:frame> object." },
1077
72e02483 1078 { "frame-valid?", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_valid_p),
ed3ef339
DE
1079 "\
1080Return #t if the object is a valid <gdb:frame> object.\n\
1081Frames become invalid when the inferior returns to its caller." },
1082
72e02483 1083 { "frame-name", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_name),
ed3ef339
DE
1084 "\
1085Return the name of the function corresponding to this frame,\n\
1086or #f if there is no function." },
1087
72e02483 1088 { "frame-arch", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_arch),
ed3ef339
DE
1089 "\
1090Return the frame's architecture as a <gdb:arch> object." },
1091
72e02483 1092 { "frame-type", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_type),
ed3ef339
DE
1093 "\
1094Return the frame type, namely one of the gdb:*_FRAME constants." },
1095
72e02483
PA
1096 { "frame-unwind-stop-reason", 1, 0, 0,
1097 as_a_scm_t_subr (gdbscm_frame_unwind_stop_reason),
ed3ef339
DE
1098 "\
1099Return one of the gdb:FRAME_UNWIND_* constants explaining why\n\
1100it's not possible to find frames older than this." },
1101
72e02483 1102 { "frame-pc", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_pc),
ed3ef339
DE
1103 "\
1104Return the frame's resume address." },
1105
72e02483 1106 { "frame-block", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_block),
ed3ef339
DE
1107 "\
1108Return the frame's code block, or #f if one cannot be found." },
1109
72e02483 1110 { "frame-function", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_function),
ed3ef339
DE
1111 "\
1112Return the <gdb:symbol> for the function corresponding to this frame,\n\
1113or #f if there isn't one." },
1114
72e02483 1115 { "frame-older", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_older),
ed3ef339
DE
1116 "\
1117Return the frame immediately older (outer) to this frame,\n\
1118or #f if there isn't one." },
1119
72e02483 1120 { "frame-newer", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_newer),
ed3ef339
DE
1121 "\
1122Return the frame immediately newer (inner) to this frame,\n\
1123or #f if there isn't one." },
1124
72e02483 1125 { "frame-sal", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_sal),
ed3ef339
DE
1126 "\
1127Return the frame's symtab-and-line <gdb:sal> object." },
1128
72e02483 1129 { "frame-read-var", 2, 0, 1, as_a_scm_t_subr (gdbscm_frame_read_var),
ed3ef339
DE
1130 "\
1131Return the value of the symbol in the frame.\n\
1132\n\
1133 Arguments: <gdb:frame> <gdb:symbol>\n\
dda83cd7 1134 Or: <gdb:frame> string [#:block <gdb:block>]" },
ed3ef339 1135
72e02483
PA
1136 { "frame-read-register", 2, 0, 0,
1137 as_a_scm_t_subr (gdbscm_frame_read_register),
f2983cc3
AW
1138 "\
1139Return the value of the register in the frame.\n\
1140\n\
1141 Arguments: <gdb:frame> string" },
1142
72e02483 1143 { "frame-select", 1, 0, 0, as_a_scm_t_subr (gdbscm_frame_select),
ed3ef339
DE
1144 "\
1145Select this frame." },
1146
72e02483 1147 { "newest-frame", 0, 0, 0, as_a_scm_t_subr (gdbscm_newest_frame),
ed3ef339
DE
1148 "\
1149Return the newest frame." },
1150
72e02483 1151 { "selected-frame", 0, 0, 0, as_a_scm_t_subr (gdbscm_selected_frame),
ed3ef339
DE
1152 "\
1153Return the selected frame." },
1154
72e02483
PA
1155 { "unwind-stop-reason-string", 1, 0, 0,
1156 as_a_scm_t_subr (gdbscm_unwind_stop_reason_string),
ed3ef339
DE
1157 "\
1158Return 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
1165void
1166gdbscm_initialize_frames (void)
1167{
1168 frame_smob_tag
1169 = gdbscm_make_smob_type (frame_smob_name, sizeof (frame_smob));
ed3ef339
DE
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}