X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fframe-unwind.h;h=c80ddc84f291e5d27f4244baa9d00307980984a8;hb=refs%2Fheads%2Fconcurrent-displaced-stepping-2020-04-01;hp=854aeb6924f370f5d2c175550fdf333d046ae231;hpb=35d5d4ee3dee63dffe7bba8ae8b00f9d2679932b;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/frame-unwind.h b/gdb/frame-unwind.h index 854aeb6924..c80ddc84f2 100644 --- a/gdb/frame-unwind.h +++ b/gdb/frame-unwind.h @@ -1,12 +1,12 @@ /* Definitions for a frame unwinder, for GDB, the GNU debugger. - Copyright (C) 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2003-2020 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,9 +15,7 @@ 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., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ + along with this program. If not, see . */ #if !defined (FRAME_UNWIND_H) #define FRAME_UNWIND_H 1 @@ -28,13 +26,14 @@ struct frame_id; struct frame_unwind; struct gdbarch; struct regcache; +struct value; #include "frame.h" /* For enum frame_type. */ /* 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. + functions are called with this frame's `struct frame_info' and + prologue cache. THIS frame's register values can be obtained by unwinding NEXT frame's registers (a recursive operation). @@ -43,17 +42,49 @@ struct regcache; as where this frame's prologue stores the previous frame's registers. */ -/* Given the NEXT frame, take a wiff of THIS frame's registers (namely +/* 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. */ + return non-zero. Possibly also initialize THIS_PROLOGUE_CACHE; but + only if returning 1. Initializing THIS_PROLOGUE_CACHE in other + cases (0 return) is invalid. In case of exception, the caller has + to set *THIS_PROLOGUE_CACHE to NULL. */ typedef int (frame_sniffer_ftype) (const struct frame_unwind *self, - struct frame_info *next_frame, + struct frame_info *this_frame, void **this_prologue_cache); +typedef enum unwind_stop_reason (frame_unwind_stop_reason_ftype) + (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); + +/* A default stop_reason callback which always claims the frame is + unwindable. */ + +enum unwind_stop_reason + default_frame_unwind_stop_reason (struct frame_info *this_frame, + void **this_cache); + +/* A default unwind_pc callback that simply unwinds the register identified + by GDBARCH_PC_REGNUM. */ + +extern CORE_ADDR default_unwind_pc (struct gdbarch *gdbarch, + struct frame_info *next_frame); + +/* A default unwind_sp callback that simply unwinds the register identified + by GDBARCH_SP_REGNUM. */ + +extern CORE_ADDR default_unwind_sp (struct gdbarch *gdbarch, + struct frame_info *next_frame); + /* 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. + 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 @@ -74,14 +105,14 @@ typedef int (frame_sniffer_ftype) (const struct frame_unwind *self, 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, +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 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). + 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 @@ -93,38 +124,34 @@ typedef void (frame_this_id_ftype) (struct frame_info *next_frame, 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. + 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). - 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. + 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 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, gdb_byte *valuep); +typedef struct value * (frame_prev_register_ftype) + (struct frame_info *this_frame, void **this_prologue_cache, + int regnum); -/* Assuming the frame chain: (outer) prev <-> this <-> next (inner); - use the NEXT frame, and its register unwind method, to return the PREV - frame's program-counter. */ +/* Deallocate extra memory associated with the frame cache if any. */ -typedef CORE_ADDR (frame_prev_pc_ftype) (struct frame_info *next_frame, - void **this_prologue_cache); +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 { @@ -133,39 +160,76 @@ struct frame_unwind enum frame_type type; /* Should an attribute indicating the frame's address-in-block go here? */ + frame_unwind_stop_reason_ftype *stop_reason; frame_this_id_ftype *this_id; frame_prev_register_ftype *prev_register; const struct frame_data *unwind_data; frame_sniffer_ftype *sniffer; - frame_prev_pc_ftype *prev_pc; + 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 + to install 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); - -/* Given the NEXT frame, take a wiff of THIS frame's registers (namely - the PC and attributes) and if it is the applicable unwinder return - the unwind methods, or NULL if it is not. */ - -typedef const struct frame_unwind *(frame_unwind_sniffer_ftype) (struct frame_info *next_frame); +extern void frame_unwind_prepend_unwinder (struct gdbarch *, + const struct frame_unwind *); /* 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_sniffer (struct gdbarch *gdbarch, - frame_unwind_sniffer_ftype *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); -/* Iterate through the next frame's sniffers until one returns with an - unwinder implementation. Possibly initialize THIS_CACHE. */ +/* 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. */ -extern const struct frame_unwind *frame_unwind_find_by_frame (struct frame_info *next_frame, - void **this_cache); +struct value *frame_unwind_got_address (struct frame_info *frame, int regnum, + CORE_ADDR addr); #endif