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