2003-03-17 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / frame.h
index ab123b322622142c77ed45ba8d0ecbd8ed6440f9..ee0fc7e49b10163233ee94ea31fe628d595349bc 100644 (file)
@@ -1,7 +1,7 @@
 /* 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 Free Software Foundation, Inc.
+   1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #define FRAME_H 1
 
 struct symtab_and_line;
+struct frame_unwind;
+struct block;
+
+/* A legacy unwinder to prop up architectures using the old style
+   saved regs array.  */
+extern const struct frame_unwind *legacy_saved_regs_unwind;
 
 /* The frame object.  */
 
@@ -31,8 +37,8 @@ struct frame_info;
 
 /* The frame object's ID.  This provides a per-frame unique identifier
    that can be used to relocate a `struct frame_info' after a target
-   resume or a frame cache destruct (assuming the target hasn't
-   unwound the stack past that frame - a problem handled elsewhere).  */
+   resume or a frame cache destruct.  It of course assumes that the
+   inferior hasn't unwound the stack past that frame.  */
 
 struct frame_id
 {
@@ -47,6 +53,38 @@ struct frame_id
   CORE_ADDR pc;
 };
 
+/* Methods for constructing and comparing Frame IDs.
+
+   NOTE: Given frameless functions A and B, where A calls B (and hence
+   B is inner-to A).  The relationships: !eq(A,B); !eq(B,A);
+   !inner(A,B); !inner(B,A); all hold.  This is because, while B is
+   inner to A, B is not strictly inner to A (being frameless, they
+   have the same .base value).  */
+
+/* For convenience.  All fields are zero.  */
+extern const struct frame_id null_frame_id;
+
+/* Construct a frame ID.  The second parameter isn't yet well defined.
+   It might be the containing function, or the resume PC (see comment
+   above in `struct frame_id')?  A func/pc of zero indicates a
+   wildcard (i.e., do not use func in frame ID comparisons).  */
+extern struct frame_id frame_id_build (CORE_ADDR base,
+                                      CORE_ADDR func_or_pc);
+
+/* Returns non-zero when L is a valid frame (a valid frame has a
+   non-zero .base).  */
+extern int frame_id_p (struct frame_id l);
+
+/* Returns non-zero when L and R identify the same frame, or, if
+   either L or R have a zero .func, then the same frame base.  */
+extern int frame_id_eq (struct frame_id l, struct frame_id r);
+
+/* Returns non-zero when L is strictly inner-than R (they have
+   different frame .bases).  Neither L, nor R can be `null'.  See note
+   above about frameless functions.  */
+extern int frame_id_inner (struct frame_id l, struct frame_id r);
+
+
 /* 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
@@ -176,8 +214,9 @@ extern void find_frame_sal (struct frame_info *frame,
 extern CORE_ADDR get_frame_base (struct frame_info *);
 
 /* Return the per-frame unique identifer.  Can be used to relocate a
-   frame after a frame cache flush (and other similar operations).  */
-extern void get_frame_id (struct frame_info *fi, struct frame_id *id);
+   frame after a frame cache flush (and other similar operations).  If
+   FI is NULL, return the null_frame_id.  */
+extern struct frame_id get_frame_id (struct frame_info *fi);
 
 /* The frame's level: 0 for innermost, 1 for its caller, ...; or -1
    for an invalid frame).  */
@@ -205,7 +244,7 @@ extern enum frame_type get_frame_type (struct frame_info *);
    PC_IN_SIGTRAMP() indicates a SIGTRAMP_FRAME and
    DEPRECATED_PC_IN_CALL_DUMMY() indicates a DUMMY_FRAME.  I suspect
    the real problem here is that get_prev_frame() only sets
-   initialized after INIT_EXTRA_FRAME_INFO as been called.
+   initialized after DEPRECATED_INIT_EXTRA_FRAME_INFO as been called.
    Consequently, some targets found that the frame's type was wrong
    and tried to fix it.  The correct fix is to modify get_prev_frame()
    so that it initializes the frame's type before calling any other
@@ -226,6 +265,9 @@ extern void frame_register_unwind (struct frame_info *frame, int regnum,
 /* NOTE: cagney/2002-09-13: Return void as one day these functions may
    be changed to return an indication that the read succeeded.  */
 
+extern void frame_unwind_register (struct frame_info *frame,
+                                  int regnum, void *buf);
+
 extern void frame_unwind_signed_register (struct frame_info *frame,
                                          int regnum, LONGEST *val);
 
@@ -246,6 +288,9 @@ extern void frame_register (struct frame_info *frame, int regnum,
 /* NOTE: cagney/2002-09-13: Return void as one day these functions may
    be changed to return an indication that the read succeeded.  */
 
+extern void frame_read_register (struct frame_info *frame, int regnum,
+                                void *buf);
+
 extern void frame_read_signed_register (struct frame_info *frame,
                                        int regnum, LONGEST *val);
 
@@ -254,9 +299,10 @@ extern void frame_read_unsigned_register (struct frame_info *frame,
 
 /* Map between a frame register number and its name.  A frame register
    space is a superset of the cooked register space --- it also
-   includes builtin registers.  */
+   includes builtin registers.  If NAMELEN is negative, use the NAME's
+   length when doing the comparison.  */
 
-extern int frame_map_name_to_regnum (const char *name, int strlen);
+extern int frame_map_name_to_regnum (const char *name, int namelen);
 extern const char *frame_map_regnum_to_name (int regnum);
 
 /* Unwind the PC.  Strictly speaking return the resume address of the
@@ -265,35 +311,9 @@ extern const char *frame_map_regnum_to_name (int regnum);
 
 extern CORE_ADDR frame_pc_unwind (struct frame_info *frame);
 
-\f
-/* 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);
-
-/* Same as for registers above, but return the address at which the
-   calling frame would resume.  */
-
-typedef CORE_ADDR (frame_pc_unwind_ftype) (struct frame_info *frame,
-                                          void **unwind_cache);
+/* Discard the specified frame.  Restoring the registers to the state
+   of the caller.  */
+extern void frame_pop (struct frame_info *frame);
 
 /* Describe the saved registers of a frame.  */
 
@@ -358,7 +378,7 @@ struct frame_info
        special, the address here is the sp for the previous frame, not
        the address where the sp was saved.  */
     /* Allocated by frame_saved_regs_zalloc () which is called /
-       initialized by FRAME_INIT_SAVED_REGS(). */
+       initialized by DEPRECATED_FRAME_INIT_SAVED_REGS(). */
     CORE_ADDR *saved_regs;     /*NUM_REGS + NUM_PSEUDO_REGS*/
 
 #ifdef EXTRA_FRAME_INFO
@@ -370,27 +390,29 @@ struct frame_info
 
     /* Anything extra for this structure that may have been defined
        in the machine dependent files. */
-    /* Allocated by frame_obstack_alloc () which is called /
-       initialized by INIT_EXTRA_FRAME_INFO */
+    /* Allocated by frame_extra_info_zalloc () which is called /
+       initialized by DEPRECATED_INIT_EXTRA_FRAME_INFO */
     struct frame_extra_info *extra_info;
 
     /* If dwarf2 unwind frame informations is used, this structure holds all
        related unwind data.  */
     struct context *context;
 
-    /* Unwind cache shared between the unwind functions - they had
-       better all agree as to the contents.  */
-    void *unwind_cache;
+    /* Prologue cache shared between the unwind functions.  See
+       "frame-unwind.h" for more information.  */
+    void *prologue_cache;
 
-    /* See description above.  The previous frame's registers.  */
-    frame_register_unwind_ftype *register_unwind;
+    /* The frame's unwinder.  */
+    const struct frame_unwind *unwind;
 
-    /* See description above.  The previous frame's resume address.
-       Save the previous PC in a local cache.  */
-    frame_pc_unwind_ftype *pc_unwind;
+    /* Cached copy of the previous frame's resume address.  */
     int pc_unwind_cache_p;
     CORE_ADDR pc_unwind_cache;
 
+    /* This frame's ID.  Note that the frame's ID, base and PC contain
+       redundant information.  */
+    struct frame_id id;
+
     /* Pointers to the next (down, inner, younger) and previous (up,
        outer, older) frame_info's in the frame cache.  */
     struct frame_info *next; /* down, inner, younger */
@@ -423,31 +445,26 @@ enum print_what
 #define SIZEOF_FRAME_SAVED_REGS \
         (sizeof (CORE_ADDR) * (NUM_REGS+NUM_PSEUDO_REGS))
 
-extern void *frame_obstack_alloc (unsigned long size);
-extern void frame_saved_regs_zalloc (struct frame_info *);
+/* Allocate zero initialized memory from the frame cache obstack.
+   Appendices to the frame info (such as the unwind cache) should
+   allocate memory using this method.  */
 
-/* Define a default FRAME_CHAIN_VALID, in the form that is suitable for most
-   targets.  If FRAME_CHAIN_VALID returns zero it means that the given frame
-   is the outermost one and has no caller.
+extern void *frame_obstack_zalloc (unsigned long size);
+#define FRAME_OBSTACK_ZALLOC(TYPE) ((TYPE *) frame_obstack_zalloc (sizeof (TYPE)))
 
-   XXXX - both default and alternate frame_chain_valid functions are
-   deprecated.  New code should use dummy frames and one of the
-   generic functions. */
+/* If FRAME_CHAIN_VALID returns zero it means that the given frame
+   is the outermost one and has no caller.  */
 
-extern int file_frame_chain_valid (CORE_ADDR, struct frame_info *);
-extern int func_frame_chain_valid (CORE_ADDR, struct frame_info *);
-extern int nonnull_frame_chain_valid (CORE_ADDR, struct frame_info *);
-extern int generic_file_frame_chain_valid (CORE_ADDR, struct frame_info *);
-extern int generic_func_frame_chain_valid (CORE_ADDR, struct frame_info *);
-extern void generic_save_dummy_frame_tos (CORE_ADDR sp);
+extern int frame_chain_valid (CORE_ADDR, struct frame_info *);
 
+extern void generic_save_dummy_frame_tos (CORE_ADDR sp);
 
 
 #ifdef FRAME_FIND_SAVED_REGS
 /* XXX - deprecated */
-#define FRAME_INIT_SAVED_REGS(FI) get_frame_saved_regs (FI, NULL)
-extern void get_frame_saved_regs (struct frame_info *,
-                                 struct frame_saved_regs *);
+#define DEPRECATED_FRAME_INIT_SAVED_REGS(FI) deprecated_get_frame_saved_regs (FI, NULL)
+extern void deprecated_get_frame_saved_regs (struct frame_info *,
+                                            struct frame_saved_regs *);
 #endif
 
 extern struct block *get_frame_block (struct frame_info *,
@@ -487,10 +504,6 @@ 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 struct block *block_for_pc_sect (CORE_ADDR, asection *);
-
 extern int frameless_look_for_prologue (struct frame_info *);
 
 extern void print_frame_args (struct symbol *, struct frame_info *,
@@ -503,8 +516,6 @@ extern void show_and_print_stack_frame (struct frame_info *fi, int level,
 
 extern void print_stack_frame (struct frame_info *, int, int);
 
-extern void print_only_stack_frame (struct frame_info *, int, int);
-
 extern void show_stack_frame (struct frame_info *);
 
 extern void print_frame_info (struct frame_info *, int, int, int);
@@ -528,7 +539,7 @@ extern int generic_pc_in_call_dummy (CORE_ADDR pc,
 /* 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.  */
+   frame_register_unwind() to the next outer frame.  */
 
 extern char *deprecated_generic_find_dummy_frame (CORE_ADDR pc, CORE_ADDR fp);
 
@@ -536,21 +547,34 @@ extern void generic_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun,
                                    int nargs, struct value **args,
                                    struct type *type, int gcc_p);
 
+void generic_unwind_get_saved_register (char *raw_buffer,
+                                       int *optimizedp,
+                                       CORE_ADDR *addrp,
+                                       struct frame_info *frame,
+                                       int regnum,
+                                       enum lval_type *lvalp);
+
 /* The function generic_get_saved_register() has been made obsolete.
-   GET_SAVED_REGISTER now defaults to the recursive equivalent -
-   generic_unwind_get_saved_register() - so there is no need to even
-   set GET_SAVED_REGISTER.  Architectures that need to override the
-   register unwind mechanism should modify frame->unwind().  */
+   DEPRECATED_GET_SAVED_REGISTER now defaults to the recursive
+   equivalent - generic_unwind_get_saved_register() - so there is no
+   need to even set DEPRECATED_GET_SAVED_REGISTER.  Architectures that
+   need to override the register unwind mechanism should modify
+   frame->unwind().  */
 extern void deprecated_generic_get_saved_register (char *, int *, CORE_ADDR *,
                                                   struct frame_info *, int,
                                                   enum lval_type *);
 
 extern void generic_save_call_dummy_addr (CORE_ADDR lo, CORE_ADDR hi);
 
-extern void get_saved_register (char *raw_buffer, int *optimized,
-                               CORE_ADDR * addrp,
-                               struct frame_info *frame,
-                               int regnum, enum lval_type *lval);
+/* FIXME: cagney/2003-02-02: Should be deprecated or replaced with a
+   function called frame_read_register_p().  This slightly weird (and
+   older) variant of frame_read_register() returns zero (indicating
+   the register is unavailable) if either: the register isn't cached;
+   or the register has been optimized out.  Problem is, neither check
+   is exactly correct.  A register can't be optimized out (it may not
+   have been saved as part of a function call); The fact that a
+   register isn't in the register cache doesn't mean that the register
+   isn't available (it could have been fetched from memory).  */
 
 extern int frame_register_read (struct frame_info *frame, int regnum,
                                void *buf);
@@ -592,22 +616,90 @@ extern void return_command (char *, int);
 extern struct frame_info *deprecated_selected_frame;
 
 
-/* NOTE: cagney/2002-11-28:
-
-   These functions are used to explicitly create and set the inner
-   most (current) frame vis:
-
-   set_current_frame (create_new_frame (read_fp(), stop_pc)));
-
-   Such code should be removed.  Instead that task can be left to
-   get_current_frame() which will update things on-demand.
-
-   The only vague exception is found in "infcmd.c" (and a few
-   architectures specific files) as part of the code implementing the
-   command ``(gdb) frame FRAME PC''.  There, the frame should be
-   created/selected in a single shot.  */
-
-extern void set_current_frame (struct frame_info *);
-extern struct frame_info *create_new_frame (CORE_ADDR, CORE_ADDR);
+/* Create a frame using the specified BASE and PC.  */
+
+extern struct frame_info *create_new_frame (CORE_ADDR base, CORE_ADDR pc);
+
+
+/* Create/access the frame's `extra info'.  The extra info is used by
+   older code to store information such as the analyzed prologue.  The
+   zalloc() should only be called by the INIT_EXTRA_INFO method.  */
+
+extern struct frame_extra_info *frame_extra_info_zalloc (struct frame_info *fi,
+                                                        long size);
+extern struct frame_extra_info *get_frame_extra_info (struct frame_info *fi);
+
+/* Create/access the frame's `saved_regs'.  The saved regs are used by
+   older code to store the address of each register (except for
+   SP_REGNUM where the value of the register in the previous frame is
+   stored).  */
+extern CORE_ADDR *frame_saved_regs_zalloc (struct frame_info *);
+extern CORE_ADDR *get_frame_saved_regs (struct frame_info *);
+
+/* FIXME: cagney/2002-12-06: Has the PC in the current frame changed?
+   "infrun.c", Thanks to DECR_PC_AFTER_BREAK, can change the PC after
+   the initial frame create.  This puts things back in sync.  */
+extern void deprecated_update_frame_pc_hack (struct frame_info *frame,
+                                            CORE_ADDR pc);
+
+/* FIXME: cagney/2002-12-18: Has the frame's base changed?  Or to be
+   more exact, whas that initial guess at the frame's base as returned
+   by 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.  */
+extern void deprecated_update_frame_base_hack (struct frame_info *frame,
+                                              CORE_ADDR base);
+
+/* FIXME: cagney/2003-01-04: Explicitly set the frame's saved_regs
+   and/or extra_info.  Target code is allocating a fake frame and than
+   initializing that to get around the problem of, when creating the
+   inner most frame, there is no where to cache information such as
+   the prologue analysis.  This is fixed by the new unwind mechanism -
+   even the inner most frame has somewhere to store things like the
+   prolog analysis (or at least will once the frame overhaul is
+   finished).  */
+extern void deprecated_set_frame_saved_regs_hack (struct frame_info *frame,
+                                                 CORE_ADDR *saved_regs);
+extern void deprecated_set_frame_extra_info_hack (struct frame_info *frame,
+                                                 struct frame_extra_info *extra_info);
+
+/* FIXME: cagney/2003-01-04: Allocate a frame from the heap (rather
+   than the frame obstack).  Targets do this as a way of saving the
+   prologue analysis from the inner most frame before that frame has
+   been created.  By always creating a frame, this problem goes away.  */
+extern struct frame_info *deprecated_frame_xmalloc (void);
+
+/* FIXME: cagney/2003-01-05: Allocate a frame, along with the
+   saved_regs and extra_info.  Set up cleanups for all three.  Same as
+   for deprecated_frame_xmalloc, targets are calling this when
+   creating a scratch `struct frame_info'.  The frame overhaul makes
+   this unnecessary since all frame queries are parameterized with a
+   common cache parameter and a frame.  */
+extern struct frame_info *deprecated_frame_xmalloc_with_cleanup (long sizeof_saved_regs,
+                                                                long sizeof_extra_info);
+
+/* FIXME: cagney/2003-01-07: These are just nasty.  Code shouldn't be
+   doing this.  I suspect it dates back to the days when every field
+   of an allocated structure was explicitly initialized.  */
+extern void deprecated_set_frame_next_hack (struct frame_info *fi,
+                                           struct frame_info *next);
+extern void deprecated_set_frame_prev_hack (struct frame_info *fi,
+                                           struct frame_info *prev);
+
+/* FIXME: cagney/2003-01-07: Instead of the dwarf2cfi having its own
+   dedicated `struct frame_info . context' field, the code should use
+   the per frame `unwind_cache' that is passed to the
+   frame_pc_unwind(), frame_register_unwind() and frame_id_unwind()
+   methods.
+
+   See "dummy-frame.c" for an example of how a cfi-frame object can be
+   implemented using this.  */
+extern struct context *deprecated_get_frame_context (struct frame_info *fi);
+extern void deprecated_set_frame_context (struct frame_info *fi,
+                                         struct context *context);
+
+/* Return non-zero if the architecture is relying on legacy frame
+   code.  */
+extern int legacy_frame_p (struct gdbarch *gdbarch);
 
 #endif /* !defined (FRAME_H)  */
This page took 0.028343 seconds and 4 git commands to generate.