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