/* Definitions for dealing with stack frames, for GDB, the GNU debugger.
- Copyright 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996,
- 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997,
+ 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007
+ Free Software Foundation, Inc.
This file is part of GDB.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
#if !defined (FRAME_H)
#define FRAME_H 1
extern void fprint_frame_id (struct ui_file *file, struct frame_id id);
+/* Frame types. Some are real, some are signal trampolines, and some
+ are completely artificial (dummy). */
+
+enum frame_type
+{
+ /* A true stack frame, created by the target program during normal
+ execution. */
+ NORMAL_FRAME,
+ /* A fake frame, created by GDB when performing an inferior function
+ call. */
+ DUMMY_FRAME,
+ /* In a signal handler, various OSs handle this in various ways.
+ The main thing is that the frame may be far from normal. */
+ SIGTRAMP_FRAME,
+ /* Sentinel or registers frame. This frame obtains register values
+ direct from the inferior's registers. */
+ SENTINEL_FRAME
+};
+
/* For every stopped thread, GDB tracks two frames: current and
selected. Current frame is the inner most frame of the selected
thread. Selected frame is the one being examined by the the GDB
/* Invalidates the frame cache (this function should have been called
invalidate_cached_frames).
- FIXME: cagney/2002-11-28: The only difference between
- flush_cached_frames() and reinit_frame_cache() is that the latter
- explicitly sets the selected frame back to the current frame -- there
- isn't any real difference (except that one delays the selection of
- a new frame). Code can instead simply rely on get_selected_frame()
- to reinit the selected frame as needed. As for invalidating the
- cache, there should be two methods: one that reverts the thread's
- selected frame back to current frame (for when the inferior
- resumes) and one that does not (for when the user modifies the
- target invalidating the frame cache). */
-extern void flush_cached_frames (void);
+ FIXME: cagney/2002-11-28: There should be two methods: one that
+ reverts the thread's selected frame back to current frame (for when
+ the inferior resumes) and one that does not (for when the user
+ modifies the target invalidating the frame cache). */
extern void reinit_frame_cache (void);
/* On demand, create the selected frame and then return it. If the
- selected frame can not be created, this function throws an error. */
+ selected frame can not be created, this function prints then throws
+ an error. When MESSAGE is non-NULL, use it for the error message,
+ otherwize use a generic error message. */
/* FIXME: cagney/2002-11-28: At present, when there is no selected
frame, this function always returns the current (inner most) frame.
It should instead, when a thread has previously had its frame
selected (but not resumed) and the frame cache invalidated, find
and then return that thread's previously selected frame. */
-extern struct frame_info *get_selected_frame (void);
+extern struct frame_info *get_selected_frame (const char *message);
/* Select a specific frame. NULL, apparently implies re-select the
inner most frame. */
the frame's block. */
extern CORE_ADDR get_frame_address_in_block (struct frame_info *this_frame);
-extern CORE_ADDR frame_unwind_address_in_block (struct frame_info *next_frame);
+
+/* Similar to get_frame_address_in_block, find an address in the
+ block which logically called NEXT_FRAME, assuming it is a THIS_TYPE
+ frame. */
+
+extern CORE_ADDR frame_unwind_address_in_block (struct frame_info *next_frame,
+ enum frame_type this_type);
/* The frame's inner-most bound. AKA the stack-pointer. Confusingly
known as top-of-stack. */
/* Following on from the `resume' address. Return the entry point
address of the function containing that resume address, or zero if
that function isn't known. */
-extern CORE_ADDR frame_func_unwind (struct frame_info *fi);
extern CORE_ADDR get_frame_func (struct frame_info *fi);
+/* Similar to get_frame_func, find the start of the function which
+ logically called NEXT_FRAME, assuming it is a THIS_TYPE frame. */
+extern CORE_ADDR frame_func_unwind (struct frame_info *next_frame,
+ enum frame_type this_type);
+
/* Closely related to the resume address, various symbol table
attributes that are determined by the PC. Note that for a normal
frame, the PC refers to the resume address after the return, and
extern void find_frame_sal (struct frame_info *frame,
struct symtab_and_line *sal);
+/* Set the current source and line to the location given by frame
+ FRAME, if possible. When CENTER is true, adjust so the relevant
+ line is in the center of the next 'list'. */
+
+void set_current_sal_from_frame (struct frame_info *, int);
+
/* Return the frame base (what ever that is) (DEPRECATED).
Old code was trying to use this single method for two conflicting
for an invalid frame). */
extern int frame_relative_level (struct frame_info *fi);
-/* Return the frame's type. Some are real, some are signal
- trampolines, and some are completely artificial (dummy). */
+/* Return the frame's type. */
-enum frame_type
-{
- /* A true stack frame, created by the target program during normal
- execution. */
- NORMAL_FRAME,
- /* A fake frame, created by GDB when performing an inferior function
- call. */
- DUMMY_FRAME,
- /* In a signal handler, various OSs handle this in various ways.
- The main thing is that the frame may be far from normal. */
- SIGTRAMP_FRAME,
- /* Sentinel or registers frame. This frame obtains register values
- direct from the inferior's registers. */
- SENTINEL_FRAME
-};
extern enum frame_type get_frame_type (struct frame_info *);
+/* For frames where we can not unwind further, describe why. */
+
+enum unwind_stop_reason
+ {
+ /* No particular reason; either we haven't tried unwinding yet,
+ or we didn't fail. */
+ UNWIND_NO_REASON,
+
+ /* The previous frame's analyzer returns an invalid result
+ from this_id.
+
+ FIXME drow/2006-08-16: This is how GDB used to indicate end of
+ stack. We should migrate to a model where frames always have a
+ valid ID, and this becomes not just an error but an internal
+ error. But that's a project for another day. */
+ UNWIND_NULL_ID,
+
+ /* All the conditions after this point are considered errors;
+ abnormal stack termination. If a backtrace stops for one
+ of these reasons, we'll let the user know. This marker
+ is not a valid stop reason. */
+ UNWIND_FIRST_ERROR,
+
+ /* This frame ID looks like it ought to belong to a NEXT frame,
+ but we got it for a PREV frame. Normally, this is a sign of
+ unwinder failure. It could also indicate stack corruption. */
+ UNWIND_INNER_ID,
+
+ /* This frame has the same ID as the previous one. That means
+ that unwinding further would almost certainly give us another
+ frame with exactly the same ID, so break the chain. Normally,
+ this is a sign of unwinder failure. It could also indicate
+ stack corruption. */
+ UNWIND_SAME_ID,
+
+ /* The frame unwinder didn't find any saved PC, but we needed
+ one to unwind further. */
+ UNWIND_NO_SAVED_PC,
+ };
+
+/* Return the reason why we can't unwind past this frame. */
+
+enum unwind_stop_reason get_frame_unwind_stop_reason (struct frame_info *);
+
+/* Translate a reason code to an informative string. */
+
+const char *frame_stop_reason_string (enum unwind_stop_reason);
+
/* Unwind the stack frame so that the value of REGNUM, in the previous
(up, older) frame is returned. If VALUEP is NULL, don't
fetch/compute the value. Instead just return the location of the
extern void frame_register_unwind (struct frame_info *frame, int regnum,
int *optimizedp, enum lval_type *lvalp,
CORE_ADDR *addrp, int *realnump,
- void *valuep);
+ gdb_byte *valuep);
/* Fetch a register from this, or unwind a register from the next
frame. Note that the get_frame methods are wrappers to
fetch fails. */
extern void frame_unwind_register (struct frame_info *frame,
- int regnum, void *buf);
+ int regnum, gdb_byte *buf);
extern void get_frame_register (struct frame_info *frame,
- int regnum, void *buf);
+ int regnum, gdb_byte *buf);
extern LONGEST frame_unwind_register_signed (struct frame_info *frame,
int regnum);
int regnum, ULONGEST *val);
/* Get the value of the register that belongs to this FRAME. This
- function is a wrapper to the call sequence ``frame_unwind_register
+ function is a wrapper to the call sequence ``frame_register_unwind
(get_next_frame (FRAME))''. As per frame_register_unwind(), if
VALUEP is NULL, the registers value is not fetched/computed. */
extern void frame_register (struct frame_info *frame, int regnum,
int *optimizedp, enum lval_type *lvalp,
CORE_ADDR *addrp, int *realnump,
- void *valuep);
+ gdb_byte *valuep);
/* The reverse. Store a register value relative to the specified
frame. Note: this call makes the frame's state undefined. The
register and frame caches must be flushed. */
extern void put_frame_register (struct frame_info *frame, int regnum,
- const void *buf);
+ const gdb_byte *buf);
+
+/* Read LEN bytes from one or multiple registers starting with REGNUM
+ in frame FRAME, starting at OFFSET, into BUF. */
+extern int get_frame_register_bytes (struct frame_info *frame, int regnum,
+ CORE_ADDR offset, int len,
+ gdb_byte *myaddr);
+
+/* Write LEN bytes to one or multiple registers starting with REGNUM
+ in frame FRAME, starting at OFFSET, into BUF. */
+extern void put_frame_register_bytes (struct frame_info *frame, int regnum,
+ CORE_ADDR offset, int len,
+ const gdb_byte *myaddr);
/* Map between a frame register number and its name. A frame register
space is a superset of the cooked register space --- it also
adaptor frames this should be ok. */
extern void get_frame_memory (struct frame_info *this_frame, CORE_ADDR addr,
- void *buf, int len);
+ gdb_byte *buf, int len);
extern LONGEST get_frame_memory_signed (struct frame_info *this_frame,
CORE_ADDR memaddr, int len);
extern ULONGEST get_frame_memory_unsigned (struct frame_info *this_frame,
/* Same as above, but return non-zero when the entire memory read
succeeds, zero otherwize. */
extern int safe_frame_unwind_memory (struct frame_info *this_frame,
- CORE_ADDR addr, void *buf, int len);
+ CORE_ADDR addr, gdb_byte *buf, int len);
/* Return this frame's architecture. */
isn't available (it could have been fetched from memory). */
extern int frame_register_read (struct frame_info *frame, int regnum,
- void *buf);
+ gdb_byte *buf);
/* From stack.c. */
extern void args_info (char *, int);
extern void return_command (char *, int);
-/* NOTE: cagney/2002-11-27:
+/* Notes (cagney/2002-11-27, drow/2003-09-06):
- You might think that the below global can simply be replaced by a
- call to either get_selected_frame() or select_frame().
+ You might think that calls to this function can simply be replaced by a
+ call to get_selected_frame().
Unfortunately, it isn't that easy.
The only real exceptions occur at the edge (in the CLI code) where
user commands need to pick up the selected frame before proceeding.
+ There are also some functions called with a NULL frame meaning either "the
+ program is not running" or "use the selected frame".
+
This is important. GDB is trying to stamp out the hack:
- saved_frame = deprecated_selected_frame;
- deprecated_selected_frame = ...;
+ saved_frame = deprecated_safe_get_selected_frame ();
+ select_frame (...);
hack_using_global_selected_frame ();
- deprecated_selected_frame = saved_frame;
-
- Take care! */
-
-extern struct frame_info *deprecated_selected_frame;
-
-/* NOTE: drow/2003-09-06:
+ select_frame (saved_frame);
- This function is "a step sideways" for uses of deprecated_selected_frame.
- They should be fixed as above, but meanwhile, we needed a solution for
- cases where functions are called with a NULL frame meaning either "the
- program is not running" or "use the selected frame". Lazy building of
- deprecated_selected_frame confuses the situation, because now
- deprecated_selected_frame can be NULL even when the inferior is running.
+ Take care!
This function calls get_selected_frame if the inferior should have a
frame, or returns NULL otherwise. */
/* FIXME: cagney/2002-12-18: Has the frame's base changed? Or to be
more exact, was that initial guess at the frame's base as returned
- by deprecated_read_fp() wrong? If it was, fix it. This shouldn't
+ by the deleted read_fp() wrong? If it was, fix it. This shouldn't
be necessary since the code should be getting the frame's base
correct from the outset.