]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/python/py-frame.c
PR python/18565 - make Frame.function work for inline frames
[thirdparty/binutils-gdb.git] / gdb / python / py-frame.c
CommitLineData
f8f6f20b
TJB
1/* Python interface to stack frames
2
618f726f 3 Copyright (C) 2008-2016 Free Software Foundation, Inc.
f8f6f20b
TJB
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20#include "defs.h"
21#include "charset.h"
22#include "block.h"
23#include "frame.h"
f8f6f20b
TJB
24#include "symtab.h"
25#include "stack.h"
26#include "value.h"
27#include "python-internal.h"
f3e9a817
PM
28#include "symfile.h"
29#include "objfiles.h"
5f3b99cf 30#include "user-regs.h"
f8f6f20b
TJB
31
32typedef struct {
33 PyObject_HEAD
34 struct frame_id frame_id;
35 struct gdbarch *gdbarch;
36
37 /* Marks that the FRAME_ID member actually holds the ID of the frame next
38 to this, and not this frames' ID itself. This is a hack to permit Python
39 frame objects which represent invalid frames (i.e., the last frame_info
40 in a corrupt stack). The problem arises from the fact that this code
41 relies on FRAME_ID to uniquely identify a frame, which is not always true
42 for the last "frame" in a corrupt stack (it can have a null ID, or the same
43 ID as the previous frame). Whenever get_prev_frame returns NULL, we
44 record the frame_id of the next frame and set FRAME_ID_IS_NEXT to 1. */
45 int frame_id_is_next;
46} frame_object;
47
48/* Require a valid frame. This must be called inside a TRY_CATCH, or
49 another context in which a gdb exception is allowed. */
50#define FRAPY_REQUIRE_VALID(frame_obj, frame) \
51 do { \
52 frame = frame_object_to_frame_info (frame_obj); \
53 if (frame == NULL) \
044c0f87 54 error (_("Frame is invalid.")); \
f8f6f20b
TJB
55 } while (0)
56
f8f6f20b
TJB
57/* Returns the frame_info object corresponding to the given Python Frame
58 object. If the frame doesn't exist anymore (the frame id doesn't
59 correspond to any frame in the inferior), returns NULL. */
60
cc72b2a2
KP
61struct frame_info *
62frame_object_to_frame_info (PyObject *obj)
f8f6f20b 63{
256458bc 64 frame_object *frame_obj = (frame_object *) obj;
f8f6f20b
TJB
65 struct frame_info *frame;
66
67 frame = frame_find_by_id (frame_obj->frame_id);
68 if (frame == NULL)
69 return NULL;
70
71 if (frame_obj->frame_id_is_next)
72 frame = get_prev_frame (frame);
73
74 return frame;
75}
76
77/* Called by the Python interpreter to obtain string representation
78 of the object. */
79
80static PyObject *
81frapy_str (PyObject *self)
82{
83 char *s;
f8f6f20b
TJB
84 PyObject *result;
85 struct ui_file *strfile;
86
87 strfile = mem_fileopen ();
88 fprint_frame_id (strfile, ((frame_object *) self)->frame_id);
759ef836 89 s = ui_file_xstrdup (strfile, NULL);
f8f6f20b
TJB
90 result = PyString_FromString (s);
91 xfree (s);
92
93 return result;
94}
95
96/* Implementation of gdb.Frame.is_valid (self) -> Boolean.
97 Returns True if the frame corresponding to the frame_id of this
98 object still exists in the inferior. */
99
100static PyObject *
101frapy_is_valid (PyObject *self, PyObject *args)
102{
76dce0be 103 struct frame_info *frame = NULL;
76dce0be 104
492d29ea 105 TRY
76dce0be 106 {
cc72b2a2 107 frame = frame_object_to_frame_info (self);
76dce0be 108 }
492d29ea
PA
109 CATCH (except, RETURN_MASK_ALL)
110 {
111 GDB_PY_HANDLE_EXCEPTION (except);
112 }
113 END_CATCH
f8f6f20b 114
f8f6f20b
TJB
115 if (frame == NULL)
116 Py_RETURN_FALSE;
117
118 Py_RETURN_TRUE;
119}
120
121/* Implementation of gdb.Frame.name (self) -> String.
122 Returns the name of the function corresponding to this frame. */
123
124static PyObject *
125frapy_name (PyObject *self, PyObject *args)
126{
127 struct frame_info *frame;
55b87a52 128 char *name = NULL;
f8f6f20b
TJB
129 enum language lang;
130 PyObject *result;
f8f6f20b 131
492d29ea 132 TRY
f8f6f20b 133 {
cc72b2a2 134 FRAPY_REQUIRE_VALID (self, frame);
f8f6f20b 135
e9e07ba6 136 find_frame_funname (frame, &name, &lang, NULL);
f8f6f20b 137 }
492d29ea
PA
138 CATCH (except, RETURN_MASK_ALL)
139 {
140 xfree (name);
141 GDB_PY_HANDLE_EXCEPTION (except);
142 }
143 END_CATCH
f8f6f20b
TJB
144
145 if (name)
55b87a52
KS
146 {
147 result = PyUnicode_Decode (name, strlen (name), host_charset (), NULL);
148 xfree (name);
149 }
f8f6f20b
TJB
150 else
151 {
152 result = Py_None;
153 Py_INCREF (Py_None);
154 }
155
156 return result;
157}
158
159/* Implementation of gdb.Frame.type (self) -> Integer.
160 Returns the frame type, namely one of the gdb.*_FRAME constants. */
161
162static PyObject *
163frapy_type (PyObject *self, PyObject *args)
164{
165 struct frame_info *frame;
166 enum frame_type type = NORMAL_FRAME;/* Initialize to appease gcc warning. */
f8f6f20b 167
492d29ea 168 TRY
f8f6f20b 169 {
cc72b2a2 170 FRAPY_REQUIRE_VALID (self, frame);
f8f6f20b
TJB
171
172 type = get_frame_type (frame);
173 }
492d29ea
PA
174 CATCH (except, RETURN_MASK_ALL)
175 {
176 GDB_PY_HANDLE_EXCEPTION (except);
177 }
178 END_CATCH
f8f6f20b
TJB
179
180 return PyInt_FromLong (type);
181}
182
bea883fd
SCR
183/* Implementation of gdb.Frame.architecture (self) -> gdb.Architecture.
184 Returns the frame's architecture as a gdb.Architecture object. */
185
186static PyObject *
187frapy_arch (PyObject *self, PyObject *args)
188{
189 struct frame_info *frame = NULL; /* Initialize to appease gcc warning. */
190 frame_object *obj = (frame_object *) self;
bea883fd 191
492d29ea 192 TRY
bea883fd
SCR
193 {
194 FRAPY_REQUIRE_VALID (self, frame);
195 }
492d29ea
PA
196 CATCH (except, RETURN_MASK_ALL)
197 {
198 GDB_PY_HANDLE_EXCEPTION (except);
199 }
200 END_CATCH
bea883fd
SCR
201
202 return gdbarch_to_arch_object (obj->gdbarch);
203}
204
f8f6f20b
TJB
205/* Implementation of gdb.Frame.unwind_stop_reason (self) -> Integer.
206 Returns one of the gdb.FRAME_UNWIND_* constants. */
207
208static PyObject *
209frapy_unwind_stop_reason (PyObject *self, PyObject *args)
210{
211 struct frame_info *frame = NULL; /* Initialize to appease gcc warning. */
f8f6f20b
TJB
212 enum unwind_stop_reason stop_reason;
213
492d29ea 214 TRY
f8f6f20b 215 {
cc72b2a2 216 FRAPY_REQUIRE_VALID (self, frame);
f8f6f20b 217 }
492d29ea
PA
218 CATCH (except, RETURN_MASK_ALL)
219 {
220 GDB_PY_HANDLE_EXCEPTION (except);
221 }
222 END_CATCH
f8f6f20b
TJB
223
224 stop_reason = get_frame_unwind_stop_reason (frame);
225
226 return PyInt_FromLong (stop_reason);
227}
228
229/* Implementation of gdb.Frame.pc (self) -> Long.
230 Returns the frame's resume address. */
231
232static PyObject *
233frapy_pc (PyObject *self, PyObject *args)
234{
235 CORE_ADDR pc = 0; /* Initialize to appease gcc warning. */
236 struct frame_info *frame;
f8f6f20b 237
492d29ea 238 TRY
f8f6f20b 239 {
cc72b2a2 240 FRAPY_REQUIRE_VALID (self, frame);
f8f6f20b
TJB
241
242 pc = get_frame_pc (frame);
243 }
492d29ea
PA
244 CATCH (except, RETURN_MASK_ALL)
245 {
246 GDB_PY_HANDLE_EXCEPTION (except);
247 }
248 END_CATCH
f8f6f20b 249
74aedc46 250 return gdb_py_long_from_ulongest (pc);
f8f6f20b
TJB
251}
252
5f3b99cf
SS
253/* Implementation of gdb.Frame.read_register (self, register) -> gdb.Value.
254 Returns the value of a register in this frame. */
255
256static PyObject *
257frapy_read_register (PyObject *self, PyObject *args)
258{
5f3b99cf
SS
259 const char *regnum_str;
260 struct value *val = NULL;
261
262 if (!PyArg_ParseTuple (args, "s", &regnum_str))
263 return NULL;
264
492d29ea 265 TRY
5f3b99cf
SS
266 {
267 struct frame_info *frame;
268 int regnum;
269
270 FRAPY_REQUIRE_VALID (self, frame);
271
272 regnum = user_reg_map_name_to_regnum (get_frame_arch (frame),
273 regnum_str,
274 strlen (regnum_str));
275 if (regnum >= 0)
276 val = value_of_register (regnum, frame);
277
278 if (val == NULL)
279 PyErr_SetString (PyExc_ValueError, _("Unknown register."));
280 }
492d29ea
PA
281 CATCH (except, RETURN_MASK_ALL)
282 {
283 GDB_PY_HANDLE_EXCEPTION (except);
284 }
285 END_CATCH
5f3b99cf
SS
286
287 return val == NULL ? NULL : value_to_value_object (val);
288}
289
f3e9a817
PM
290/* Implementation of gdb.Frame.block (self) -> gdb.Block.
291 Returns the frame's code block. */
292
293static PyObject *
294frapy_block (PyObject *self, PyObject *args)
295{
296 struct frame_info *frame;
3977b71f 297 const struct block *block = NULL, *fn_block;
f3e9a817 298
492d29ea 299 TRY
f3e9a817 300 {
cc72b2a2 301 FRAPY_REQUIRE_VALID (self, frame);
57126e4a 302 block = get_frame_block (frame, NULL);
f3e9a817 303 }
492d29ea
PA
304 CATCH (except, RETURN_MASK_ALL)
305 {
306 GDB_PY_HANDLE_EXCEPTION (except);
307 }
308 END_CATCH
f3e9a817 309
57126e4a
TT
310 for (fn_block = block;
311 fn_block != NULL && BLOCK_FUNCTION (fn_block) == NULL;
312 fn_block = BLOCK_SUPERBLOCK (fn_block))
313 ;
314
315 if (block == NULL || fn_block == NULL || BLOCK_FUNCTION (fn_block) == NULL)
f3e9a817
PM
316 {
317 PyErr_SetString (PyExc_RuntimeError,
1e1d6920 318 _("Cannot locate block for frame."));
f3e9a817
PM
319 return NULL;
320 }
321
322 if (block)
57126e4a 323 {
08be3fe3
DE
324 return block_to_block_object
325 (block, symbol_objfile (BLOCK_FUNCTION (fn_block)));
57126e4a 326 }
f3e9a817
PM
327
328 Py_RETURN_NONE;
329}
330
331
332/* Implementation of gdb.Frame.function (self) -> gdb.Symbol.
333 Returns the symbol for the function corresponding to this frame. */
334
335static PyObject *
336frapy_function (PyObject *self, PyObject *args)
337{
338 struct symbol *sym = NULL;
339 struct frame_info *frame;
f3e9a817 340
492d29ea 341 TRY
f3e9a817 342 {
282a0691
TT
343 char *funname;
344 enum language funlang;
345
cc72b2a2 346 FRAPY_REQUIRE_VALID (self, frame);
f3e9a817 347
282a0691
TT
348 find_frame_funname (frame, &funname, &funlang, &sym);
349 xfree (funname);
f3e9a817 350 }
492d29ea
PA
351 CATCH (except, RETURN_MASK_ALL)
352 {
353 GDB_PY_HANDLE_EXCEPTION (except);
354 }
355 END_CATCH
f3e9a817
PM
356
357 if (sym)
358 return symbol_to_symbol_object (sym);
359
360 Py_RETURN_NONE;
361}
362
f8f6f20b
TJB
363/* Convert a frame_info struct to a Python Frame object.
364 Sets a Python exception and returns NULL on error. */
365
595939de 366PyObject *
f8f6f20b
TJB
367frame_info_to_frame_object (struct frame_info *frame)
368{
369 frame_object *frame_obj;
370
371 frame_obj = PyObject_New (frame_object, &frame_object_type);
372 if (frame_obj == NULL)
6cbc7c3d 373 return NULL;
f8f6f20b 374
492d29ea 375 TRY
f8f6f20b 376 {
f8f6f20b 377
76dce0be
PM
378 /* Try to get the previous frame, to determine if this is the last frame
379 in a corrupt stack. If so, we need to store the frame_id of the next
380 frame and not of this one (which is possibly invalid). */
381 if (get_prev_frame (frame) == NULL
382 && get_frame_unwind_stop_reason (frame) != UNWIND_NO_REASON
383 && get_next_frame (frame) != NULL)
384 {
385 frame_obj->frame_id = get_frame_id (get_next_frame (frame));
386 frame_obj->frame_id_is_next = 1;
387 }
388 else
389 {
390 frame_obj->frame_id = get_frame_id (frame);
391 frame_obj->frame_id_is_next = 0;
392 }
393 frame_obj->gdbarch = get_frame_arch (frame);
394 }
492d29ea 395 CATCH (except, RETURN_MASK_ALL)
1efd7661
PM
396 {
397 Py_DECREF (frame_obj);
398 gdbpy_convert_exception (except);
399 return NULL;
400 }
492d29ea
PA
401 END_CATCH
402
595939de 403 return (PyObject *) frame_obj;
f8f6f20b
TJB
404}
405
406/* Implementation of gdb.Frame.older (self) -> gdb.Frame.
407 Returns the frame immediately older (outer) to this frame, or None if
408 there isn't one. */
409
410static PyObject *
411frapy_older (PyObject *self, PyObject *args)
412{
dcf87832 413 struct frame_info *frame, *prev = NULL;
f8f6f20b
TJB
414 PyObject *prev_obj = NULL; /* Initialize to appease gcc warning. */
415
492d29ea 416 TRY
f8f6f20b 417 {
cc72b2a2 418 FRAPY_REQUIRE_VALID (self, frame);
f8f6f20b
TJB
419
420 prev = get_prev_frame (frame);
f8f6f20b 421 }
492d29ea
PA
422 CATCH (except, RETURN_MASK_ALL)
423 {
424 GDB_PY_HANDLE_EXCEPTION (except);
425 }
426 END_CATCH
f8f6f20b 427
dcf87832
TT
428 if (prev)
429 prev_obj = (PyObject *) frame_info_to_frame_object (prev);
430 else
431 {
432 Py_INCREF (Py_None);
433 prev_obj = Py_None;
434 }
435
f8f6f20b
TJB
436 return prev_obj;
437}
438
439/* Implementation of gdb.Frame.newer (self) -> gdb.Frame.
440 Returns the frame immediately newer (inner) to this frame, or None if
441 there isn't one. */
442
443static PyObject *
444frapy_newer (PyObject *self, PyObject *args)
445{
dcf87832 446 struct frame_info *frame, *next = NULL;
f8f6f20b
TJB
447 PyObject *next_obj = NULL; /* Initialize to appease gcc warning. */
448
492d29ea 449 TRY
f8f6f20b 450 {
cc72b2a2 451 FRAPY_REQUIRE_VALID (self, frame);
f8f6f20b
TJB
452
453 next = get_next_frame (frame);
f8f6f20b 454 }
492d29ea
PA
455 CATCH (except, RETURN_MASK_ALL)
456 {
457 GDB_PY_HANDLE_EXCEPTION (except);
458 }
459 END_CATCH
f8f6f20b 460
dcf87832
TT
461 if (next)
462 next_obj = (PyObject *) frame_info_to_frame_object (next);
463 else
464 {
465 Py_INCREF (Py_None);
466 next_obj = Py_None;
467 }
468
f8f6f20b
TJB
469 return next_obj;
470}
471
f3e9a817
PM
472/* Implementation of gdb.Frame.find_sal (self) -> gdb.Symtab_and_line.
473 Returns the frame's symtab and line. */
474
475static PyObject *
476frapy_find_sal (PyObject *self, PyObject *args)
477{
478 struct frame_info *frame;
479 struct symtab_and_line sal;
f3e9a817
PM
480 PyObject *sal_obj = NULL; /* Initialize to appease gcc warning. */
481
492d29ea 482 TRY
f3e9a817 483 {
cc72b2a2 484 FRAPY_REQUIRE_VALID (self, frame);
f3e9a817
PM
485
486 find_frame_sal (frame, &sal);
487 sal_obj = symtab_and_line_to_sal_object (sal);
488 }
492d29ea
PA
489 CATCH (except, RETURN_MASK_ALL)
490 {
491 GDB_PY_HANDLE_EXCEPTION (except);
492 }
493 END_CATCH
f3e9a817
PM
494
495 return sal_obj;
496}
497
dc00d89f
PM
498/* Implementation of gdb.Frame.read_var_value (self, variable,
499 [block]) -> gdb.Value. If the optional block argument is provided
500 start the search from that block, otherwise search from the frame's
501 current block (determined by examining the resume address of the
502 frame). The variable argument must be a string or an instance of a
8dc78533
JK
503 gdb.Symbol. The block argument must be an instance of gdb.Block. Returns
504 NULL on error, with a python exception set. */
f8f6f20b
TJB
505static PyObject *
506frapy_read_var (PyObject *self, PyObject *args)
507{
508 struct frame_info *frame;
dc00d89f 509 PyObject *sym_obj, *block_obj = NULL;
f8f6f20b 510 struct symbol *var = NULL; /* gcc-4.3.2 false warning. */
63e43d3a 511 const struct block *block = NULL;
f8f6f20b 512 struct value *val = NULL;
f8f6f20b 513
dc00d89f 514 if (!PyArg_ParseTuple (args, "O|O", &sym_obj, &block_obj))
f8f6f20b
TJB
515 return NULL;
516
f3e9a817
PM
517 if (PyObject_TypeCheck (sym_obj, &symbol_object_type))
518 var = symbol_object_to_symbol (sym_obj);
519 else if (gdbpy_is_string (sym_obj))
f8f6f20b
TJB
520 {
521 char *var_name;
f8f6f20b 522 struct cleanup *cleanup;
f8f6f20b
TJB
523
524 var_name = python_string_to_target_string (sym_obj);
525 if (!var_name)
526 return NULL;
527 cleanup = make_cleanup (xfree, var_name);
528
dc00d89f
PM
529 if (block_obj)
530 {
531 block = block_object_to_block (block_obj);
532 if (!block)
533 {
534 PyErr_SetString (PyExc_RuntimeError,
535 _("Second argument must be block."));
af1c6971 536 do_cleanups (cleanup);
dc00d89f
PM
537 return NULL;
538 }
539 }
540
492d29ea 541 TRY
f8f6f20b 542 {
63e43d3a 543 struct block_symbol lookup_sym;
cc72b2a2 544 FRAPY_REQUIRE_VALID (self, frame);
f8f6f20b 545
dc00d89f 546 if (!block)
626e7282 547 block = get_frame_block (frame, NULL);
63e43d3a
PMR
548 lookup_sym = lookup_symbol (var_name, block, VAR_DOMAIN, NULL);
549 var = lookup_sym.symbol;
550 block = lookup_sym.block;
f8f6f20b 551 }
492d29ea 552 CATCH (except, RETURN_MASK_ALL)
af1c6971
TT
553 {
554 do_cleanups (cleanup);
f3300387
TT
555 gdbpy_convert_exception (except);
556 return NULL;
af1c6971 557 }
492d29ea 558 END_CATCH
f8f6f20b
TJB
559
560 if (!var)
561 {
562 PyErr_Format (PyExc_ValueError,
044c0f87 563 _("Variable '%s' not found."), var_name);
f8f6f20b
TJB
564 do_cleanups (cleanup);
565
566 return NULL;
567 }
568
569 do_cleanups (cleanup);
570 }
571 else
572 {
573 PyErr_SetString (PyExc_TypeError,
044c0f87 574 _("Argument must be a symbol or string."));
f8f6f20b
TJB
575 return NULL;
576 }
577
492d29ea 578 TRY
f8f6f20b 579 {
cc72b2a2 580 FRAPY_REQUIRE_VALID (self, frame);
f8f6f20b 581
63e43d3a 582 val = read_var_value (var, block, frame);
f8f6f20b 583 }
492d29ea
PA
584 CATCH (except, RETURN_MASK_ALL)
585 {
586 GDB_PY_HANDLE_EXCEPTION (except);
587 }
588 END_CATCH
f8f6f20b 589
dc00d89f 590 return value_to_value_object (val);
f8f6f20b
TJB
591}
592
f3e9a817
PM
593/* Select this frame. */
594
595static PyObject *
596frapy_select (PyObject *self, PyObject *args)
597{
598 struct frame_info *fi;
f3e9a817 599
492d29ea 600 TRY
f3e9a817 601 {
cc72b2a2 602 FRAPY_REQUIRE_VALID (self, fi);
f3e9a817
PM
603
604 select_frame (fi);
605 }
492d29ea
PA
606 CATCH (except, RETURN_MASK_ALL)
607 {
608 GDB_PY_HANDLE_EXCEPTION (except);
609 }
610 END_CATCH
f3e9a817
PM
611
612 Py_RETURN_NONE;
613}
614
d8e22779
TT
615/* Implementation of gdb.newest_frame () -> gdb.Frame.
616 Returns the newest frame object. */
617
618PyObject *
619gdbpy_newest_frame (PyObject *self, PyObject *args)
620{
dcf87832 621 struct frame_info *frame = NULL;
d8e22779 622
492d29ea 623 TRY
d8e22779
TT
624 {
625 frame = get_current_frame ();
d8e22779 626 }
492d29ea
PA
627 CATCH (except, RETURN_MASK_ALL)
628 {
629 GDB_PY_HANDLE_EXCEPTION (except);
630 }
631 END_CATCH
d8e22779 632
dcf87832 633 return frame_info_to_frame_object (frame);
d8e22779
TT
634}
635
f8f6f20b
TJB
636/* Implementation of gdb.selected_frame () -> gdb.Frame.
637 Returns the selected frame object. */
638
639PyObject *
640gdbpy_selected_frame (PyObject *self, PyObject *args)
641{
dcf87832 642 struct frame_info *frame = NULL;
f8f6f20b 643
492d29ea 644 TRY
f8f6f20b
TJB
645 {
646 frame = get_selected_frame ("No frame is currently selected.");
f8f6f20b 647 }
492d29ea
PA
648 CATCH (except, RETURN_MASK_ALL)
649 {
650 GDB_PY_HANDLE_EXCEPTION (except);
651 }
652 END_CATCH
f8f6f20b 653
dcf87832 654 return frame_info_to_frame_object (frame);
f8f6f20b
TJB
655}
656
657/* Implementation of gdb.stop_reason_string (Integer) -> String.
658 Return a string explaining the unwind stop reason. */
659
660PyObject *
661gdbpy_frame_stop_reason_string (PyObject *self, PyObject *args)
662{
663 int reason;
664 const char *str;
665
666 if (!PyArg_ParseTuple (args, "i", &reason))
667 return NULL;
668
2231f1fb 669 if (reason < UNWIND_FIRST || reason > UNWIND_LAST)
f8f6f20b 670 {
256458bc 671 PyErr_SetString (PyExc_ValueError,
044c0f87 672 _("Invalid frame stop reason."));
f8f6f20b
TJB
673 return NULL;
674 }
675
aead7601 676 str = unwind_stop_reason_to_string ((enum unwind_stop_reason) reason);
f8f6f20b
TJB
677 return PyUnicode_Decode (str, strlen (str), host_charset (), NULL);
678}
679
680/* Implements the equality comparison for Frame objects.
681 All other comparison operators will throw a TypeError Python exception,
682 as they aren't valid for frames. */
683
684static PyObject *
685frapy_richcompare (PyObject *self, PyObject *other, int op)
686{
18e8c3bc
TT
687 int result;
688
689 if (!PyObject_TypeCheck (other, &frame_object_type)
690 || (op != Py_EQ && op != Py_NE))
f8f6f20b 691 {
18e8c3bc
TT
692 Py_INCREF (Py_NotImplemented);
693 return Py_NotImplemented;
f8f6f20b
TJB
694 }
695
696 if (frame_id_eq (((frame_object *) self)->frame_id,
697 ((frame_object *) other)->frame_id))
18e8c3bc
TT
698 result = Py_EQ;
699 else
700 result = Py_NE;
f8f6f20b 701
18e8c3bc
TT
702 if (op == result)
703 Py_RETURN_TRUE;
f8f6f20b
TJB
704 Py_RETURN_FALSE;
705}
706
707/* Sets up the Frame API in the gdb module. */
708
999633ed 709int
f8f6f20b
TJB
710gdbpy_initialize_frames (void)
711{
6a1b1664 712 frame_object_type.tp_new = PyType_GenericNew;
f8f6f20b 713 if (PyType_Ready (&frame_object_type) < 0)
999633ed 714 return -1;
f8f6f20b 715
9a2b4c1b
MS
716 /* Note: These would probably be best exposed as class attributes of
717 Frame, but I don't know how to do it except by messing with the
718 type's dictionary. That seems too messy. */
999633ed
TT
719 if (PyModule_AddIntConstant (gdb_module, "NORMAL_FRAME", NORMAL_FRAME) < 0
720 || PyModule_AddIntConstant (gdb_module, "DUMMY_FRAME", DUMMY_FRAME) < 0
721 || PyModule_AddIntConstant (gdb_module, "INLINE_FRAME", INLINE_FRAME) < 0
722 || PyModule_AddIntConstant (gdb_module, "TAILCALL_FRAME",
723 TAILCALL_FRAME) < 0
724 || PyModule_AddIntConstant (gdb_module, "SIGTRAMP_FRAME",
725 SIGTRAMP_FRAME) < 0
726 || PyModule_AddIntConstant (gdb_module, "ARCH_FRAME", ARCH_FRAME) < 0
727 || PyModule_AddIntConstant (gdb_module, "SENTINEL_FRAME",
728 SENTINEL_FRAME) < 0)
729 return -1;
2231f1fb
KP
730
731#define SET(name, description) \
999633ed
TT
732 if (PyModule_AddIntConstant (gdb_module, "FRAME_"#name, name) < 0) \
733 return -1;
2231f1fb
KP
734#include "unwind_stop_reasons.def"
735#undef SET
f8f6f20b 736
aa36459a
TT
737 return gdb_pymodule_addobject (gdb_module, "Frame",
738 (PyObject *) &frame_object_type);
f8f6f20b
TJB
739}
740
741\f
742
743static PyMethodDef frame_object_methods[] = {
744 { "is_valid", frapy_is_valid, METH_NOARGS,
745 "is_valid () -> Boolean.\n\
746Return true if this frame is valid, false if not." },
747 { "name", frapy_name, METH_NOARGS,
748 "name () -> String.\n\
749Return the function name of the frame, or None if it can't be determined." },
750 { "type", frapy_type, METH_NOARGS,
751 "type () -> Integer.\n\
752Return the type of the frame." },
bea883fd
SCR
753 { "architecture", frapy_arch, METH_NOARGS,
754 "architecture () -> gdb.Architecture.\n\
755Return the architecture of the frame." },
f8f6f20b
TJB
756 { "unwind_stop_reason", frapy_unwind_stop_reason, METH_NOARGS,
757 "unwind_stop_reason () -> Integer.\n\
758Return the reason why it's not possible to find frames older than this." },
759 { "pc", frapy_pc, METH_NOARGS,
760 "pc () -> Long.\n\
761Return the frame's resume address." },
5f3b99cf
SS
762 { "read_register", frapy_read_register, METH_VARARGS,
763 "read_register (register_name) -> gdb.Value\n\
764Return the value of the register in the frame." },
f3e9a817
PM
765 { "block", frapy_block, METH_NOARGS,
766 "block () -> gdb.Block.\n\
767Return the frame's code block." },
768 { "function", frapy_function, METH_NOARGS,
769 "function () -> gdb.Symbol.\n\
770Returns the symbol for the function corresponding to this frame." },
f8f6f20b
TJB
771 { "older", frapy_older, METH_NOARGS,
772 "older () -> gdb.Frame.\n\
773Return the frame that called this frame." },
774 { "newer", frapy_newer, METH_NOARGS,
775 "newer () -> gdb.Frame.\n\
776Return the frame called by this frame." },
f3e9a817
PM
777 { "find_sal", frapy_find_sal, METH_NOARGS,
778 "find_sal () -> gdb.Symtab_and_line.\n\
779Return the frame's symtab and line." },
f8f6f20b
TJB
780 { "read_var", frapy_read_var, METH_VARARGS,
781 "read_var (variable) -> gdb.Value.\n\
782Return the value of the variable in this frame." },
f3e9a817
PM
783 { "select", frapy_select, METH_NOARGS,
784 "Select this frame as the user's current frame." },
f8f6f20b
TJB
785 {NULL} /* Sentinel */
786};
787
f0823d2c 788PyTypeObject frame_object_type = {
9a27f2c6 789 PyVarObject_HEAD_INIT (NULL, 0)
f8f6f20b
TJB
790 "gdb.Frame", /* tp_name */
791 sizeof (frame_object), /* tp_basicsize */
792 0, /* tp_itemsize */
793 0, /* tp_dealloc */
794 0, /* tp_print */
795 0, /* tp_getattr */
796 0, /* tp_setattr */
797 0, /* tp_compare */
798 0, /* tp_repr */
799 0, /* tp_as_number */
800 0, /* tp_as_sequence */
801 0, /* tp_as_mapping */
802 0, /* tp_hash */
803 0, /* tp_call */
804 frapy_str, /* tp_str */
805 0, /* tp_getattro */
806 0, /* tp_setattro */
807 0, /* tp_as_buffer */
808 Py_TPFLAGS_DEFAULT, /* tp_flags */
809 "GDB frame object", /* tp_doc */
810 0, /* tp_traverse */
811 0, /* tp_clear */
812 frapy_richcompare, /* tp_richcompare */
813 0, /* tp_weaklistoffset */
814 0, /* tp_iter */
815 0, /* tp_iternext */
816 frame_object_methods, /* tp_methods */
817 0, /* tp_members */
818 0, /* tp_getset */
819 0, /* tp_base */
820 0, /* tp_dict */
821 0, /* tp_descr_get */
822 0, /* tp_descr_set */
823 0, /* tp_dictoffset */
824 0, /* tp_init */
825 0, /* tp_alloc */
f8f6f20b 826};