diff options
Diffstat (limited to 'gdb/frame-unwind.h')
-rw-r--r-- | gdb/frame-unwind.h | 139 |
1 files changed, 85 insertions, 54 deletions
diff --git a/gdb/frame-unwind.h b/gdb/frame-unwind.h index 2c67c96..ad1efdf 100644 --- a/gdb/frame-unwind.h +++ b/gdb/frame-unwind.h @@ -28,6 +28,8 @@ struct frame_unwind; struct gdbarch; struct regcache; +#include "frame.h" /* For enum frame_type. */ + /* Return the frame unwind methods for the function that contains PC, or NULL if this this unwinder can't handle this frame. */ @@ -47,65 +49,94 @@ extern const struct frame_unwind *frame_unwind_find_by_pc (struct gdbarch *gdbarch, CORE_ADDR pc); -/* 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_zalloc(). - - 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_unwind_reg_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_unwind_pc_ftype) (struct frame_info * frame, - void **unwind_cache); - -/* Same as for registers above, but return the ID of the frame that - called this one. */ - -typedef void (frame_unwind_id_ftype) (struct frame_info * frame, - void **unwind_cache, - struct frame_id * id); - -/* Discard the frame by restoring the registers (in regcache) back to - that of the caller. */ -/* NOTE: cagney/2003-01-19: While at present the callers all pop each - frame in turn, the implementor should try to code things so that - any frame can be popped directly. */ -/* FIXME: cagney/2003-01-19: Since both FRAME and REGCACHE refer to a - common register cache, care must be taken when restoring the - registers. The `correct fix' is to first first save the registers - in a scratch cache, and second write that scratch cache back to to - the real register cache. */ - -typedef void (frame_unwind_pop_ftype) (struct frame_info *frame, - void **unwind_cache, - struct regcache *regcache); +/* The following unwind functions assume a chain of frames forming the + sequence: (outer) prev <-> this <-> next (inner). All the + functions are called with called with the next frame's `struct + frame_info' and and this frame's prologue cache. + + THIS frame's register values can be obtained by unwinding NEXT + frame's registers (a recursive operation). + + THIS frame's prologue cache can be used to cache information such + as where this frame's prologue stores the previous frame's + registers. */ + +/* Assuming the frame chain: (outer) prev <-> this <-> next (inner); + use the NEXT frame, and its register unwind method, to determine + the frame ID of THIS frame. + + A frame ID provides an invariant that can be used to re-identify an + instance of a frame. It is a combination of the frame's `base' and + the frame's function's code address. + + Traditionally, THIS frame's ID was determined by examining THIS + frame's function's prologue, and identifying the register/offset + used as THIS frame's base. + + Example: An examination of THIS frame's prologue reveals that, on + entry, it saves the PC(+12), SP(+8), and R1(+4) registers + (decrementing the SP by 12). Consequently, the frame ID's base can + be determined by adding 12 to the THIS frame's stack-pointer, and + the value of THIS frame's SP can be obtained by unwinding the NEXT + frame's SP. + + THIS_PROLOGUE_CACHE can be used to share any prolog analysis data + with the other unwind methods. Memory for that cache should be + allocated using frame_obstack_zalloc(). */ + +typedef void (frame_this_id_ftype) (struct frame_info *next_frame, + void **this_prologue_cache, + struct frame_id *this_id); + +/* Assuming the frame chain: (outer) prev <-> this <-> next (inner); + use the NEXT frame, and its register unwind method, to unwind THIS + frame's registers (returning the value of the specified register + REGNUM in the previous frame). + + Traditionally, THIS frame's registers were unwound by examining + THIS frame's function's prologue and identifying which registers + that prolog code saved on the stack. + + Example: An examination of THIS frame's prologue reveals that, on + entry, it saves the PC(+12), SP(+8), and R1(+4) registers + (decrementing the SP by 12). Consequently, the value of the PC + register in the previous frame is found in memory at SP+12, and + THIS frame's SP can be obtained by unwinding the NEXT frame's SP. + + Why not pass in THIS_FRAME? By passing in NEXT frame and THIS + cache, the supplied parameters are consistent with the sibling + function THIS_ID. + + Can the code call ``frame_register (get_prev_frame (NEXT_FRAME))''? + Won't the call frame_register (THIS_FRAME) be faster? Well, + ignoring the possability that the previous frame does not yet + exist, the ``frame_register (FRAME)'' function is expanded to + ``frame_register_unwind (get_next_frame (FRAME)'' and hence that + call will expand to ``frame_register_unwind (get_next_frame + (get_prev_frame (NEXT_FRAME)))''. Might as well call + ``frame_register_unwind (NEXT_FRAME)'' directly. + + THIS_PROLOGUE_CACHE can be used to share any prolog analysis data + with the other unwind methods. Memory for that cache should be + allocated using frame_obstack_zalloc(). */ + +typedef void (frame_prev_register_ftype) (struct frame_info *next_frame, + void **this_prologue_cache, + int prev_regnum, + int *optimized, + enum lval_type * lvalp, + CORE_ADDR *addrp, + int *realnump, void *valuep); struct frame_unwind { - /* Should the frame's type go here? */ + /* The frame's type. Should this instead be a collection of + predicates that test the frame for various attributes? */ + enum frame_type type; /* Should an attribute indicating the frame's address-in-block go here? */ - frame_unwind_pop_ftype *pop; - frame_unwind_pc_ftype *pc; - frame_unwind_id_ftype *id; - frame_unwind_reg_ftype *reg; + frame_this_id_ftype *this_id; + frame_prev_register_ftype *prev_register; }; #endif |