#if !defined (FRAME_H)
#define FRAME_H 1
+/* Return the location (and possibly value) of REGNUM for the previous
+ (older, up) frame. All parameters except VALUEP can be assumed to
+ be non NULL. When VALUEP is NULL, just the location of the
+ register should be returned.
+
+ UNWIND_CACHE is provided as mechanism for implementing a per-frame
+ local cache. It's initial value being NULL. Memory for that cache
+ should be allocated using frame_obstack_alloc().
+
+ Register window architectures (eg SPARC) should note that REGNUM
+ identifies the register for the previous frame. For instance, a
+ request for the value of "o1" for the previous frame would be found
+ in the register "i1" in this FRAME. */
+
+typedef void (frame_register_unwind_ftype) (struct frame_info *frame,
+ void **unwind_cache,
+ int regnum,
+ int *optimized,
+ enum lval_type *lvalp,
+ CORE_ADDR *addrp,
+ int *realnump,
+ void *valuep);
+
/* Describe the saved registers of a frame. */
#if defined (EXTRA_FRAME_INFO) || defined (FRAME_FIND_SAVED_REGS)
/* If dwarf2 unwind frame informations is used, this structure holds all
related unwind data. */
- struct unwind_contect *context;
+ struct context *context;
+
+ /* See description above. Return the register value for the
+ previous frame. */
+ frame_register_unwind_ftype *register_unwind;
+ void *register_unwind_cache;
/* Pointers to the next (down, inner) and previous (up, outer)
frame_info's in the frame cache. */
extern CORE_ADDR get_frame_pc (struct frame_info *);
+extern CORE_ADDR frame_address_in_block (struct frame_info *);
+
extern CORE_ADDR get_pc_function_start (CORE_ADDR);
extern struct block *block_for_pc (CORE_ADDR);
extern void show_stack_frame (struct frame_info *);
-extern void select_frame (struct frame_info *, int);
+extern void select_frame (struct frame_info *);
+
+/* Return an ID that can be used to re-find a frame. */
-extern void record_selected_frame (CORE_ADDR *, int *);
+struct frame_id
+{
+ /* The frame's address. This should be constant through out the
+ lifetime of a frame. */
+ CORE_ADDR base;
+ /* The frame's current PC. While this changes, the function that
+ the PC falls into, does not. */
+ CORE_ADDR pc;
+};
-extern void select_and_print_frame (struct frame_info *, int);
+extern void get_frame_id (struct frame_info *fi, struct frame_id *id);
+
+extern struct frame_info *frame_find_by_id (struct frame_id id);
extern void print_frame_info (struct frame_info *, int, int, int);
extern int generic_pc_in_call_dummy (CORE_ADDR pc,
CORE_ADDR sp, CORE_ADDR fp);
-extern char *generic_find_dummy_frame (CORE_ADDR pc, CORE_ADDR fp);
+
+/* NOTE: cagney/2002-06-26: Targets should no longer use this
+ function. Instead, the contents of a dummy frames registers can be
+ obtained by applying: frame_register_unwind to the dummy frame; or
+ get_saved_register to the next outer frame. */
+
+extern char *deprecated_generic_find_dummy_frame (CORE_ADDR pc, CORE_ADDR fp);
extern void generic_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun,
int nargs, struct value **args,
struct frame_info *, int,
enum lval_type *);
+extern void generic_unwind_get_saved_register (char *raw_buffer,
+ int *optimized,
+ CORE_ADDR * addrp,
+ struct frame_info *frame,
+ int regnum,
+ enum lval_type *lval);
+
+/* Unwind the stack frame so that the value of REGNUM, in the previous
+ frame is returned. If VALUEP is NULL, don't fetch/compute the
+ value. Instead just return the location of the value. */
+
+extern void frame_register_unwind (struct frame_info *frame, int regnum,
+ int *optimizedp, enum lval_type *lvalp,
+ CORE_ADDR *addrp, int *realnump,
+ void *valuep);
+
extern void generic_save_call_dummy_addr (CORE_ADDR lo, CORE_ADDR hi);
extern void get_saved_register (char *raw_buffer, int *optimized,