X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fframe.h;h=d8461a2e40d21b58b5a6255d029773a4b73c20e7;hb=ebd3bcc1327e6a7de6daf6536134cb20be9c2cfd;hp=d9c59d1791220f53f97bf887811be680c997e75d;hpb=12b0b6deedc672f75f59aac556e21e290e202ca2;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/frame.h b/gdb/frame.h index d9c59d1791..d8461a2e40 100644 --- a/gdb/frame.h +++ b/gdb/frame.h @@ -1,13 +1,14 @@ /* 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, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, + 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007, 2008 + 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, @@ -16,9 +17,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., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + along with this program. If not, see . */ #if !defined (FRAME_H) #define FRAME_H 1 @@ -71,10 +70,6 @@ struct block; struct gdbarch; struct ui_file; -/* 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. */ struct frame_info; @@ -124,9 +119,9 @@ struct frame_id CORE_ADDR special_addr; /* Flags to indicate the above fields have valid contents. */ - int stack_addr_p : 1; - int code_addr_p : 1; - int special_addr_p : 1; + unsigned int stack_addr_p : 1; + unsigned int code_addr_p : 1; + unsigned int special_addr_p : 1; }; /* Methods for constructing and comparing Frame IDs. @@ -149,6 +144,10 @@ struct frame_id /* For convenience. All fields are zero. */ extern const struct frame_id null_frame_id; +/* Flag to control debugging. */ + +extern int frame_debug; + /* Construct a frame ID. The first parameter is the frame's constant stack address (typically the outer-bound), and the second the frame's constant code address (typically the entry point). @@ -180,13 +179,33 @@ 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); +extern int frame_id_inner (struct gdbarch *gdbarch, struct frame_id l, + struct frame_id r); /* Write the internal representation of a frame ID on the specified stream. */ extern void fprint_frame_id (struct ui_file *file, struct frame_id id); +/* Frame types. Some are real, some are signal trampolines, and some + are completely artificial (dummy). */ + +enum frame_type +{ + /* A true stack frame, created by the target program during normal + execution. */ + NORMAL_FRAME, + /* A fake frame, created by GDB when performing an inferior function + call. */ + DUMMY_FRAME, + /* In a signal handler, various OSs handle this in various ways. + The main thing is that the frame may be far from normal. */ + SIGTRAMP_FRAME, + /* Sentinel or registers frame. This frame obtains register values + direct from the inferior's registers. */ + SENTINEL_FRAME +}; + /* 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 @@ -209,27 +228,22 @@ extern struct frame_info *get_current_frame (void); /* Invalidates the frame cache (this function should have been called invalidate_cached_frames). - FIXME: cagney/2002-11-28: The only difference between - flush_cached_frames() and reinit_frame_cache() is that the latter - explicitly sets the selected frame back to the current frame -- there - isn't any real difference (except that one delays the selection of - a new frame). Code can instead simply rely on get_selected_frame() - to reinit the selected frame as needed. As for invalidating the - cache, there should be two methods: one that reverts the thread's - selected frame back to current frame (for when the inferior - resumes) and one that does not (for when the user modifies the - target invalidating the frame cache). */ -extern void flush_cached_frames (void); + FIXME: cagney/2002-11-28: There should be two methods: one that + reverts the thread's selected frame back to current frame (for when + the inferior resumes) and one that does not (for when the user + modifies the target invalidating the frame cache). */ extern void reinit_frame_cache (void); /* On demand, create the selected frame and then return it. If the - selected frame can not be created, this function throws an error. */ + selected frame can not be created, this function prints then throws + an error. When MESSAGE is non-NULL, use it for the error message, + otherwize use a generic error message. */ /* FIXME: cagney/2002-11-28: At present, when there is no selected frame, this function always returns the current (inner most) frame. It should instead, when a thread has previously had its frame selected (but not resumed) and the frame cache invalidated, find and then return that thread's previously selected frame. */ -extern struct frame_info *get_selected_frame (void); +extern struct frame_info *get_selected_frame (const char *message); /* Select a specific frame. NULL, apparently implies re-select the inner most frame. */ @@ -266,7 +280,13 @@ extern CORE_ADDR get_frame_pc (struct frame_info *); the frame's block. */ extern CORE_ADDR get_frame_address_in_block (struct frame_info *this_frame); -extern CORE_ADDR frame_unwind_address_in_block (struct frame_info *next_frame); + +/* Similar to get_frame_address_in_block, find an address in the + block which logically called NEXT_FRAME, assuming it is a THIS_TYPE + frame. */ + +extern CORE_ADDR frame_unwind_address_in_block (struct frame_info *next_frame, + enum frame_type this_type); /* The frame's inner-most bound. AKA the stack-pointer. Confusingly known as top-of-stack. */ @@ -278,9 +298,13 @@ extern CORE_ADDR frame_sp_unwind (struct frame_info *); /* Following on from the `resume' address. Return the entry point address of the function containing that resume address, or zero if that function isn't known. */ -extern CORE_ADDR frame_func_unwind (struct frame_info *fi); extern CORE_ADDR get_frame_func (struct frame_info *fi); +/* Similar to get_frame_func, find the start of the function which + logically called NEXT_FRAME, assuming it is a THIS_TYPE frame. */ +extern CORE_ADDR frame_func_unwind (struct frame_info *next_frame, + enum frame_type this_type); + /* Closely related to the resume address, various symbol table attributes that are determined by the PC. Note that for a normal frame, the PC refers to the resume address after the return, and @@ -302,6 +326,12 @@ extern CORE_ADDR get_frame_func (struct frame_info *fi); extern void find_frame_sal (struct frame_info *frame, struct symtab_and_line *sal); +/* Set the current source and line to the location given by frame + FRAME, if possible. When CENTER is true, adjust so the relevant + line is in the center of the next 'list'. */ + +void set_current_sal_from_frame (struct frame_info *, int); + /* Return the frame base (what ever that is) (DEPRECATED). Old code was trying to use this single method for two conflicting @@ -370,31 +400,58 @@ extern CORE_ADDR get_frame_args_address (struct frame_info *); for an invalid frame). */ extern int frame_relative_level (struct frame_info *fi); -/* Return the frame's type. Some are real, some are signal - trampolines, and some are completely artificial (dummy). */ +/* Return the frame's type. */ -enum frame_type -{ - /* The frame's type hasn't yet been defined. This is a catch-all - for legacy_get_prev_frame that uses really strange techniques to - determine the frame's type. New code should not use this - value. */ - UNKNOWN_FRAME, - /* A true stack frame, created by the target program during normal - execution. */ - NORMAL_FRAME, - /* A fake frame, created by GDB when performing an inferior function - call. */ - DUMMY_FRAME, - /* In a signal handler, various OSs handle this in various ways. - The main thing is that the frame may be far from normal. */ - SIGTRAMP_FRAME, - /* Sentinel or registers frame. This frame obtains register values - direct from the inferior's registers. */ - SENTINEL_FRAME -}; extern enum frame_type get_frame_type (struct frame_info *); +/* For frames where we can not unwind further, describe why. */ + +enum unwind_stop_reason + { + /* No particular reason; either we haven't tried unwinding yet, + or we didn't fail. */ + UNWIND_NO_REASON, + + /* The previous frame's analyzer returns an invalid result + from this_id. + + FIXME drow/2006-08-16: This is how GDB used to indicate end of + stack. We should migrate to a model where frames always have a + valid ID, and this becomes not just an error but an internal + error. But that's a project for another day. */ + UNWIND_NULL_ID, + + /* All the conditions after this point are considered errors; + abnormal stack termination. If a backtrace stops for one + of these reasons, we'll let the user know. This marker + is not a valid stop reason. */ + UNWIND_FIRST_ERROR, + + /* This frame ID looks like it ought to belong to a NEXT frame, + but we got it for a PREV frame. Normally, this is a sign of + unwinder failure. It could also indicate stack corruption. */ + UNWIND_INNER_ID, + + /* This frame has the same ID as the previous one. That means + that unwinding further would almost certainly give us another + frame with exactly the same ID, so break the chain. Normally, + this is a sign of unwinder failure. It could also indicate + stack corruption. */ + UNWIND_SAME_ID, + + /* The frame unwinder didn't find any saved PC, but we needed + one to unwind further. */ + UNWIND_NO_SAVED_PC, + }; + +/* Return the reason why we can't unwind past this frame. */ + +enum unwind_stop_reason get_frame_unwind_stop_reason (struct frame_info *); + +/* Translate a reason code to an informative string. */ + +const char *frame_stop_reason_string (enum unwind_stop_reason); + /* Unwind the stack frame so that the value of REGNUM, in the previous (up, older) frame is returned. If VALUEP is NULL, don't fetch/compute the value. Instead just return the location of the @@ -402,17 +459,23 @@ extern enum frame_type get_frame_type (struct frame_info *); extern void frame_register_unwind (struct frame_info *frame, int regnum, int *optimizedp, enum lval_type *lvalp, CORE_ADDR *addrp, int *realnump, - void *valuep); + gdb_byte *valuep); /* Fetch a register from this, or unwind a register from the next frame. Note that the get_frame methods are wrappers to frame->next->unwind. They all [potentially] throw an error if the - fetch fails. */ + fetch fails. The value methods never return NULL, but usually + do return a lazy value. */ extern void frame_unwind_register (struct frame_info *frame, - int regnum, void *buf); + int regnum, gdb_byte *buf); extern void get_frame_register (struct frame_info *frame, - int regnum, void *buf); + int regnum, gdb_byte *buf); + +struct value *frame_unwind_register_value (struct frame_info *frame, + int regnum); +struct value *get_frame_register_value (struct frame_info *frame, + int regnum); extern LONGEST frame_unwind_register_signed (struct frame_info *frame, int regnum); @@ -424,25 +487,33 @@ extern ULONGEST get_frame_register_unsigned (struct frame_info *frame, int regnum); -/* Use frame_unwind_register_signed. */ -extern void frame_unwind_unsigned_register (struct frame_info *frame, - int regnum, ULONGEST *val); - /* Get the value of the register that belongs to this FRAME. This - function is a wrapper to the call sequence ``frame_unwind_register + function is a wrapper to the call sequence ``frame_register_unwind (get_next_frame (FRAME))''. As per frame_register_unwind(), if VALUEP is NULL, the registers value is not fetched/computed. */ extern void frame_register (struct frame_info *frame, int regnum, int *optimizedp, enum lval_type *lvalp, CORE_ADDR *addrp, int *realnump, - void *valuep); + gdb_byte *valuep); /* The reverse. Store a register value relative to the specified frame. Note: this call makes the frame's state undefined. The register and frame caches must be flushed. */ extern void put_frame_register (struct frame_info *frame, int regnum, - const void *buf); + const gdb_byte *buf); + +/* Read LEN bytes from one or multiple registers starting with REGNUM + in frame FRAME, starting at OFFSET, into BUF. */ +extern int get_frame_register_bytes (struct frame_info *frame, int regnum, + CORE_ADDR offset, int len, + gdb_byte *myaddr); + +/* Write LEN bytes to one or multiple registers starting with REGNUM + in frame FRAME, starting at OFFSET, into BUF. */ +extern void put_frame_register_bytes (struct frame_info *frame, int regnum, + CORE_ADDR offset, int len, + const gdb_byte *myaddr); /* Map between a frame register number and its name. A frame register space is a superset of the cooked register space --- it also @@ -478,7 +549,7 @@ extern void frame_pop (struct frame_info *frame); adaptor frames this should be ok. */ extern void get_frame_memory (struct frame_info *this_frame, CORE_ADDR addr, - void *buf, int len); + gdb_byte *buf, int len); extern LONGEST get_frame_memory_signed (struct frame_info *this_frame, CORE_ADDR memaddr, int len); extern ULONGEST get_frame_memory_unsigned (struct frame_info *this_frame, @@ -487,7 +558,7 @@ extern ULONGEST get_frame_memory_unsigned (struct frame_info *this_frame, /* Same as above, but return non-zero when the entire memory read succeeds, zero otherwize. */ extern int safe_frame_unwind_memory (struct frame_info *this_frame, - CORE_ADDR addr, void *buf, int len); + CORE_ADDR addr, gdb_byte *buf, int len); /* Return this frame's architecture. */ @@ -517,7 +588,8 @@ enum print_what #error "SIZEOF_FRAME_SAVED_REGS can not be re-defined" #endif #define SIZEOF_FRAME_SAVED_REGS \ - (sizeof (CORE_ADDR) * (NUM_REGS+NUM_PSEUDO_REGS)) + (sizeof (CORE_ADDR) * (gdbarch_num_regs (current_gdbarch)\ + + gdbarch_num_pseudo_regs (current_gdbarch))) /* Allocate zero initialized memory from the frame cache obstack. Appendices to the frame info (such as the unwind cache) should @@ -527,16 +599,8 @@ extern void *frame_obstack_zalloc (unsigned long size); #define FRAME_OBSTACK_ZALLOC(TYPE) ((TYPE *) frame_obstack_zalloc (sizeof (TYPE))) #define FRAME_OBSTACK_CALLOC(NUMBER,TYPE) ((TYPE *) frame_obstack_zalloc ((NUMBER) * sizeof (TYPE))) -/* If legacy_frame_chain_valid() returns zero it means that the given - frame is the outermost one and has no caller. - - This method has been superseded by the per-architecture - frame_unwind_pc() (returns 0 to indicate an invalid return address) - and per-frame this_id() (returns a NULL frame ID to indicate an - invalid frame). */ -extern int legacy_frame_chain_valid (CORE_ADDR, struct frame_info *); - -extern void generic_save_dummy_frame_tos (CORE_ADDR sp); +/* Create a regcache, and copy the frame's registers into it. */ +struct regcache *frame_save_as_regcache (struct frame_info *this_frame); extern struct block *get_frame_block (struct frame_info *, CORE_ADDR *addr_in_block); @@ -573,8 +637,6 @@ extern struct symbol *get_frame_function (struct frame_info *); extern CORE_ADDR get_pc_function_start (CORE_ADDR); -extern int legacy_frameless_look_for_prologue (struct frame_info *); - extern struct frame_info *find_relative_frame (struct frame_info *, int *); extern void show_and_print_stack_frame (struct frame_info *fi, int print_level, @@ -583,31 +645,13 @@ extern void show_and_print_stack_frame (struct frame_info *fi, int print_level, extern void print_stack_frame (struct frame_info *, int print_level, enum print_what print_what); -extern void show_stack_frame (struct frame_info *); - extern void print_frame_info (struct frame_info *, int print_level, enum print_what print_what, int args); extern struct frame_info *block_innermost_frame (struct block *); -/* NOTE: cagney/2002-09-13: There is no need for this function. */ -extern CORE_ADDR deprecated_read_register_dummy (CORE_ADDR pc, - CORE_ADDR fp, int); -extern void generic_push_dummy_frame (void); -extern void deprecated_pop_dummy_frame (void); - extern int deprecated_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 frame register can be - obtained by applying: frame_register_unwind to the dummy frame; or - frame_register_unwind() to the next outer frame. */ - -extern char *deprecated_generic_find_dummy_frame (CORE_ADDR pc, CORE_ADDR fp); - - -extern void generic_save_call_dummy_addr (CORE_ADDR lo, CORE_ADDR hi); - /* FIXME: cagney/2003-02-02: Should be deprecated or replaced with a function called get_frame_register_p(). This slightly weird (and older) variant of get_frame_register() returns zero (indicating the @@ -619,7 +663,7 @@ extern void generic_save_call_dummy_addr (CORE_ADDR lo, CORE_ADDR hi); isn't available (it could have been fetched from memory). */ extern int frame_register_read (struct frame_info *frame, int regnum, - void *buf); + gdb_byte *buf); /* From stack.c. */ extern void args_info (char *, int); @@ -630,11 +674,17 @@ extern void (*deprecated_selected_frame_level_changed_hook) (int); extern void return_command (char *, int); +/* Set FRAME's unwinder temporarily, so that we can call a sniffer. + Return a cleanup which should be called if unwinding fails, and + discarded if it succeeds. */ -/* NOTE: cagney/2002-11-27: +struct cleanup *frame_prepare_for_sniffer (struct frame_info *frame, + const struct frame_unwind *unwind); - You might think that the below global can simply be replaced by a - call to either get_selected_frame() or select_frame(). +/* Notes (cagney/2002-11-27, drow/2003-09-06): + + You might think that calls to this function can simply be replaced by a + call to get_selected_frame(). Unfortunately, it isn't that easy. @@ -646,25 +696,17 @@ extern void return_command (char *, int); The only real exceptions occur at the edge (in the CLI code) where user commands need to pick up the selected frame before proceeding. + There are also some functions called with a NULL frame meaning either "the + program is not running" or "use the selected frame". + This is important. GDB is trying to stamp out the hack: - saved_frame = deprecated_selected_frame; - deprecated_selected_frame = ...; + saved_frame = deprecated_safe_get_selected_frame (); + select_frame (...); hack_using_global_selected_frame (); - deprecated_selected_frame = saved_frame; + select_frame (saved_frame); - Take care! */ - -extern struct frame_info *deprecated_selected_frame; - -/* NOTE: drow/2003-09-06: - - This function is "a step sideways" for uses of deprecated_selected_frame. - They should be fixed as above, but meanwhile, we needed a solution for - cases where functions are called with a NULL frame meaning either "the - program is not running" or "use the selected frame". Lazy building of - deprecated_selected_frame confuses the situation, because now - deprecated_selected_frame can be NULL even when the inferior is running. + Take care! This function calls get_selected_frame if the inferior should have a frame, or returns NULL otherwise. */ @@ -675,24 +717,8 @@ extern struct frame_info *deprecated_safe_get_selected_frame (void); 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 *deprecated_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 + "infrun.c", Thanks to gdbarch_decr_pc_after_break, can change the PC after the initial frame create. This puts things back in sync. This replaced: frame->pc = ....; */ @@ -701,7 +727,7 @@ extern void deprecated_update_frame_pc_hack (struct frame_info *frame, /* FIXME: cagney/2002-12-18: Has the frame's base changed? Or to be more exact, was that initial guess at the frame's base as returned - by deprecated_read_fp() wrong? If it was, fix it. This shouldn't + by the deleted 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. @@ -709,17 +735,4 @@ extern void deprecated_update_frame_pc_hack (struct frame_info *frame, extern void deprecated_update_frame_base_hack (struct frame_info *frame, CORE_ADDR base); -/* 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); - -/* Return non-zero if the architecture is relying on legacy frame - code. */ -extern int legacy_frame_p (struct gdbarch *gdbarch); - #endif /* !defined (FRAME_H) */