X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Fframe-unwind.h;h=e4cf3201c091d9bda08c38a35b01502e80e18abf;hb=809df4465f01277ab689fb82b3f16ff79f9a2606;hp=2c67c969fb1a8177de6aadebb56026bf605a3a38;hpb=dbe9fe588fc696a5d74b3a5c3208f2568b9fb7aa;p=binutils-gdb.git diff --git a/gdb/frame-unwind.h b/gdb/frame-unwind.h index 2c67c969fb1..e4cf3201c09 100644 --- a/gdb/frame-unwind.h +++ b/gdb/frame-unwind.h @@ -1,12 +1,13 @@ /* Definitions for a frame unwinder, for GDB, the GNU debugger. - Copyright 2003 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2007, 2008, 2009, 2010 + Free Software Foundation, Inc. This file is part of GDB. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,97 +16,195 @@ GNU General Public License for more details. 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. */ + along with this program. If not, see . */ #if !defined (FRAME_UNWIND_H) #define FRAME_UNWIND_H 1 +struct frame_data; struct frame_info; struct frame_id; struct frame_unwind; struct gdbarch; struct regcache; +struct value; -/* Return the frame unwind methods for the function that contains PC, - or NULL if this this unwinder can't handle this frame. */ +#include "frame.h" /* For enum frame_type. */ -typedef const struct frame_unwind *(frame_unwind_p_ftype) (CORE_ADDR pc); +/* The following unwind functions assume a chain of frames forming the + sequence: (outer) prev <-> this <-> next (inner). All the + functions are called with the next frame's `struct frame_info' + and this frame's prologue cache. -/* Add a frame unwinder to the list. The predicates are polled in the - order that they are appended. The initial list contains the dummy - frame's predicate. */ - -extern void frame_unwind_append_predicate (struct gdbarch *gdbarch, - frame_unwind_p_ftype *p); - -/* Iterate through the list of frame unwinders until one returns an - implementation. */ - -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); + 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. */ + +/* Given THIS frame, take a whiff of its registers (namely + the PC and attributes) and if SELF is the applicable unwinder, + return non-zero. Possibly also initialize THIS_PROLOGUE_CACHE. */ + +typedef int (frame_sniffer_ftype) (const struct frame_unwind *self, + struct frame_info *this_frame, + void **this_prologue_cache); + +/* A default frame sniffer which always accepts the frame. Used by + fallback prologue unwinders. */ + +int default_frame_sniffer (const struct frame_unwind *self, + struct frame_info *this_frame, + void **this_prologue_cache); + +/* Assuming the frame chain: (outer) prev <-> this <-> next (inner); + use THIS frame, and through it the NEXT frame's 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 *this_frame, + void **this_prologue_cache, + struct frame_id *this_id); + +/* Assuming the frame chain: (outer) prev <-> this <-> next (inner); + use THIS frame, and implicitly the NEXT frame's 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. + + This function takes THIS_FRAME as an argument. It can find the + values of registers in THIS frame by calling get_frame_register + (THIS_FRAME), and reinvoke itself to find other registers in the + PREVIOUS frame by calling frame_unwind_register (THIS_FRAME). + + The result is a GDB value object describing the register value. It + may be a lazy reference to memory, a lazy reference to the value of + a register in THIS frame, or a non-lvalue. + + 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 struct value * (frame_prev_register_ftype) + (struct frame_info *this_frame, void **this_prologue_cache, + int regnum); + +/* Deallocate extra memory associated with the frame cache if any. */ + +typedef void (frame_dealloc_cache_ftype) (struct frame_info *self, + void *this_cache); + +/* Assuming the frame chain: (outer) prev <-> this <-> next (inner); + use THIS frame, and implicitly the NEXT frame's register unwind + method, return PREV frame's architecture. */ + +typedef struct gdbarch *(frame_prev_arch_ftype) (struct frame_info *this_frame, + void **this_prologue_cache); 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; + const struct frame_data *unwind_data; + frame_sniffer_ftype *sniffer; + frame_dealloc_cache_ftype *dealloc_cache; + frame_prev_arch_ftype *prev_arch; }; +/* Register a frame unwinder, _prepending_ it to the front of the + search list (so it is sniffed before previously registered + unwinders). By using a prepend, later calls can install unwinders + that override earlier calls. This allows, for instance, an OSABI + to install a a more specific sigtramp unwinder that overrides the + traditional brute-force unwinder. */ +extern void frame_unwind_prepend_unwinder (struct gdbarch *gdbarch, + const struct frame_unwind *unwinder); + +/* Add a frame sniffer to the list. The predicates are polled in the + order that they are appended. The initial list contains the dummy + frame sniffer. */ + +extern void frame_unwind_append_unwinder (struct gdbarch *gdbarch, + const struct frame_unwind *unwinder); + +/* Iterate through sniffers for THIS_FRAME frame until one returns with an + unwinder implementation. THIS_FRAME->UNWIND must be NULL, it will get set + by this function. Possibly initialize THIS_CACHE. */ + +extern void frame_unwind_find_by_frame (struct frame_info *this_frame, + void **this_cache); + +/* Helper functions for value-based register unwinding. These return + a (possibly lazy) value of the appropriate type. */ + +/* Return a value which indicates that FRAME did not save REGNUM. */ + +struct value *frame_unwind_got_optimized (struct frame_info *frame, + int regnum); + +/* Return a value which indicates that FRAME copied REGNUM into + register NEW_REGNUM. */ + +struct value *frame_unwind_got_register (struct frame_info *frame, int regnum, + int new_regnum); + +/* Return a value which indicates that FRAME saved REGNUM in memory at + ADDR. */ + +struct value *frame_unwind_got_memory (struct frame_info *frame, int regnum, + CORE_ADDR addr); + +/* Return a value which indicates that FRAME's saved version of + REGNUM has a known constant (computed) value of VAL. */ + +struct value *frame_unwind_got_constant (struct frame_info *frame, int regnum, + ULONGEST val); + +/* Return a value which indicates that FRAME's saved version of + REGNUM has a known constant (computed) value which is stored + inside BUF. */ + +struct value *frame_unwind_got_bytes (struct frame_info *frame, int regnum, + gdb_byte *buf); + +/* Return a value which indicates that FRAME's saved version of REGNUM + has a known constant (computed) value of ADDR. Convert the + CORE_ADDR to a target address if necessary. */ + +struct value *frame_unwind_got_address (struct frame_info *frame, int regnum, + CORE_ADDR addr); + #endif