X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fframe.h;h=79881521d7a9472d59e3cd4c1ef4228ae5421fc4;hb=70e38b8e988c7db764a7344f0d27273706543a54;hp=1463064248cf3021cd3114e8743e0cd80b825ea5;hpb=6c95b8df7fef5273da71c34775918c554aae0ea8;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/frame.h b/gdb/frame.h index 1463064248..79881521d7 100644 --- a/gdb/frame.h +++ b/gdb/frame.h @@ -1,8 +1,6 @@ /* Definitions for dealing with stack frames, for GDB, the GNU debugger. - Copyright (C) 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, - 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007, 2008, 2009 - Free Software Foundation, Inc. + Copyright (C) 1986-2014 Free Software Foundation, Inc. This file is part of GDB. @@ -78,6 +76,23 @@ struct block; struct gdbarch; struct ui_file; +/* Status of a given frame's stack. */ + +enum frame_id_stack_status +{ + /* Stack address is invalid. E.g., this frame is the outermost + (i.e., _start), and the stack hasn't been setup yet. */ + FID_STACK_INVALID = 0, + + /* Stack address is valid, and is found in the stack_addr field. */ + FID_STACK_VALID = 1, + + /* Stack address is unavailable. I.e., there's a valid stack, but + we don't know where it is (because memory or registers we'd + compute it from were not collected). */ + FID_STACK_UNAVAILABLE = -1 +}; + /* The frame object. */ struct frame_info; @@ -99,8 +114,9 @@ struct frame_id function pointer register or stack pointer register. They are wrong. - This field is valid only if stack_addr_p is true. Otherwise, this - frame represents the null frame. */ + This field is valid only if frame_id.stack_status is + FID_STACK_VALID. It will be 0 for other + FID_STACK_... statuses. */ CORE_ADDR stack_addr; /* The frame's code address. This shall be constant through out the @@ -131,13 +147,15 @@ struct frame_id CORE_ADDR special_addr; /* Flags to indicate the above fields have valid contents. */ - unsigned int stack_addr_p : 1; + ENUM_BITFIELD(frame_id_stack_status) stack_status : 2; unsigned int code_addr_p : 1; unsigned int special_addr_p : 1; - /* The inline depth of this frame. A frame representing a "called" - inlined function will have this set to a nonzero value. */ - int inline_depth; + /* It is non-zero for a frame made up by GDB without stack data + representation in inferior, such as INLINE_FRAME or TAILCALL_FRAME. + Caller of inlined function will have it zero, each more inner called frame + will have it increasingly one, two etc. Similarly for TAILCALL_FRAME. */ + int artificial_depth; }; /* Methods for constructing and comparing Frame IDs. */ @@ -152,7 +170,7 @@ extern const struct frame_id outer_frame_id; /* Flag to control debugging. */ -extern int frame_debug; +extern unsigned 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 @@ -164,11 +182,25 @@ extern struct frame_id frame_id_build (CORE_ADDR stack_addr, /* Construct a special frame ID. The first parameter is the frame's constant stack address (typically the outer-bound), the second is the frame's constant code address (typically the entry point), - and the third parameter is the frame's special identifier address. */ + and the third parameter is the frame's special identifier address. */ extern struct frame_id frame_id_build_special (CORE_ADDR stack_addr, CORE_ADDR code_addr, CORE_ADDR special_addr); +/* Construct a frame ID representing a frame where the stack address + exists, but is unavailable. CODE_ADDR is the frame's constant code + address (typically the entry point). The special identifier + address is set to indicate a wild card. */ +extern struct frame_id frame_id_build_unavailable_stack (CORE_ADDR code_addr); + +/* Construct a frame ID representing a frame where the stack address + exists, but is unavailable. CODE_ADDR is the frame's constant code + address (typically the entry point). SPECIAL_ADDR is the special + identifier address. */ +extern struct frame_id + frame_id_build_unavailable_stack_special (CORE_ADDR code_addr, + CORE_ADDR special_addr); + /* Construct a wild card frame ID. The parameter is the frame's constant stack address (typically the outer-bound). The code address as well as the special identifier address are set to indicate wild cards. */ @@ -179,9 +211,10 @@ extern struct frame_id frame_id_build_wild (CORE_ADDR stack_addr); ID. */ extern int frame_id_p (struct frame_id l); -/* Returns non-zero when L is a valid frame representing an inlined - function. */ -extern int frame_id_inlined_p (struct frame_id l); +/* Returns non-zero when L is a valid frame representing a frame made up by GDB + without stack data representation in inferior, such as INLINE_FRAME or + TAILCALL_FRAME. */ +extern int frame_id_artificial_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. */ @@ -204,8 +237,10 @@ enum frame_type call. */ DUMMY_FRAME, /* A frame representing an inlined function, associated with an - upcoming (next, inner, younger) NORMAL_FRAME. */ + upcoming (prev, outer, older) NORMAL_FRAME. */ INLINE_FRAME, + /* A virtual frame of a tail call - see dwarf2_tailcall_frame_unwind. */ + TAILCALL_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, @@ -218,7 +253,7 @@ enum frame_type /* 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 + thread. Selected frame is the one being examined by the GDB CLI (selected using `up', `down', ...). The frames are created on-demand (via get_prev_frame()) and then held in a frame cache. */ /* FIXME: cagney/2002-11-28: Er, there is a lie here. If you do the @@ -260,6 +295,9 @@ extern void reinit_frame_cache (void); and then return that thread's previously selected frame. */ extern struct frame_info *get_selected_frame (const char *message); +/* If there is a selected frame, return it. Otherwise, return NULL. */ +extern struct frame_info *get_selected_frame_if_set (void); + /* Select a specific frame. NULL, apparently implies re-select the inner most frame. */ extern void select_frame (struct frame_info *); @@ -269,6 +307,13 @@ extern void select_frame (struct frame_info *); extern struct frame_info *get_prev_frame (struct frame_info *); extern struct frame_info *get_next_frame (struct frame_info *); +/* Return a "struct frame_info" corresponding to the frame that called + THIS_FRAME. Returns NULL if there is no such frame. + + Unlike get_prev_frame, this function always tries to unwind the + frame. */ +extern struct frame_info *get_prev_frame_always (struct frame_info *); + /* Given a frame's ID, relocate the frame. Returns NULL if the frame is not found. */ extern struct frame_info *frame_find_by_id (struct frame_id id); @@ -281,6 +326,12 @@ extern struct frame_info *frame_find_by_id (struct frame_id id); This replaced: frame->pc; */ extern CORE_ADDR get_frame_pc (struct frame_info *); +/* Same as get_frame_pc, but return a boolean indication of whether + the PC is actually available, instead of throwing an error. */ + +extern int get_frame_pc_if_available (struct frame_info *frame, + CORE_ADDR *pc); + /* An address (not necessarily aligned to an instruction boundary) that falls within THIS frame's code block. @@ -296,6 +347,15 @@ extern CORE_ADDR get_frame_pc (struct frame_info *); extern CORE_ADDR get_frame_address_in_block (struct frame_info *this_frame); +/* Same as get_frame_address_in_block, but returns a boolean + indication of whether the frame address is determinable (when the + PC is unavailable, it will not be), instead of possibly throwing an + error trying to read an unavailable PC. */ + +extern int + get_frame_address_in_block_if_available (struct frame_info *this_frame, + CORE_ADDR *pc); + /* The frame's inner-most bound. AKA the stack-pointer. Confusingly known as top-of-stack. */ @@ -306,6 +366,13 @@ extern CORE_ADDR get_frame_sp (struct frame_info *); that function isn't known. */ extern CORE_ADDR get_frame_func (struct frame_info *fi); +/* Same as get_frame_func, but returns a boolean indication of whether + the frame function is determinable (when the PC is unavailable, it + will not be), instead of possibly throwing an error trying to read + an unavailable PC. */ + +extern int get_frame_func_if_available (struct frame_info *fi, CORE_ADDR *); + /* 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 @@ -328,10 +395,9 @@ 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'. */ + FRAME, if possible. */ -void set_current_sal_from_frame (struct frame_info *, int); +void set_current_sal_from_frame (struct frame_info *); /* Return the frame base (what ever that is) (DEPRECATED). @@ -344,7 +410,7 @@ void set_current_sal_from_frame (struct frame_info *, int); low-level unwinder, the stack part [typically] being the top-of-stack of the previous frame, and the function part being the function's start address. Since the correct identification of a - frameless function requires both the a stack and function address, + frameless function requires both a stack and function address, the old get_frame_base method was not sufficient. get_frame_base_address: get_frame_locals_address: @@ -419,40 +485,16 @@ extern struct address_space *get_frame_address_space (struct frame_info *); 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, +#define SET(name, description) name, +#define FIRST_ENTRY(name) UNWIND_FIRST = name, +#define LAST_ENTRY(name) UNWIND_LAST = name, +#define FIRST_ERROR(name) UNWIND_FIRST_ERROR = name, + +#include "unwind_stop_reasons.def" +#undef SET +#undef FIRST_ENTRY +#undef LAST_ENTRY +#undef FIRST_ERROR }; /* Return the reason why we can't unwind past this frame. */ @@ -461,14 +503,15 @@ 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); +const char *unwind_stop_reason_to_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 value. */ extern void frame_register_unwind (struct frame_info *frame, int regnum, - int *optimizedp, enum lval_type *lvalp, + int *optimizedp, int *unavailablep, + enum lval_type *lvalp, CORE_ADDR *addrp, int *realnump, gdb_byte *valuep); @@ -497,6 +540,13 @@ extern ULONGEST frame_unwind_register_unsigned (struct frame_info *frame, extern ULONGEST get_frame_register_unsigned (struct frame_info *frame, int regnum); +/* Read a register from this, or unwind a register from the next + frame. Note that the read_frame methods are wrappers to + get_frame_register_value, that do not throw if the result is + optimized out or unavailable. */ + +extern int read_frame_register_unsigned (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_register_unwind @@ -504,7 +554,8 @@ extern ULONGEST get_frame_register_unsigned (struct frame_info *frame, 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, + int *optimizedp, int *unavailablep, + enum lval_type *lvalp, CORE_ADDR *addrp, int *realnump, gdb_byte *valuep); @@ -515,10 +566,13 @@ extern void put_frame_register (struct frame_info *frame, int regnum, const gdb_byte *buf); /* Read LEN bytes from one or multiple registers starting with REGNUM - in frame FRAME, starting at OFFSET, into BUF. */ + in frame FRAME, starting at OFFSET, into BUF. If the register + contents are optimized out or unavailable, set *OPTIMIZEDP, + *UNAVAILABLEP accordingly. */ extern int get_frame_register_bytes (struct frame_info *frame, int regnum, CORE_ADDR offset, int len, - gdb_byte *myaddr); + gdb_byte *myaddr, + int *optimizedp, int *unavailablep); /* Write LEN bytes to one or multiple registers starting with REGNUM in frame FRAME, starting at OFFSET, into BUF. */ @@ -574,14 +628,14 @@ extern struct gdbarch *frame_unwind_caller_arch (struct frame_info *frame); /* Values for the source flag to be used in print_frame_info_base(). */ enum print_what { - /* Print only the source line, like in stepi. */ + /* Print only the source line, like in stepi. */ SRC_LINE = -1, /* Print only the location, i.e. level, address (sometimes) - function, args, file, line, line num. */ + function, args, file, line, line num. */ LOCATION, - /* Print both of the above. */ + /* Print both of the above. */ SRC_AND_LOC, - /* Print location only, but always include the address. */ + /* Print location only, but always include the address. */ LOC_AND_ADDRESS }; @@ -590,8 +644,10 @@ enum print_what allocate memory using this method. */ 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))) +#define FRAME_OBSTACK_ZALLOC(TYPE) \ + ((TYPE *) frame_obstack_zalloc (sizeof (TYPE))) +#define FRAME_OBSTACK_CALLOC(NUMBER,TYPE) \ + ((TYPE *) frame_obstack_zalloc ((NUMBER) * sizeof (TYPE))) /* Create a regcache, and copy the frame's registers into it. */ struct regcache *frame_save_as_regcache (struct frame_info *this_frame); @@ -633,33 +689,63 @@ extern CORE_ADDR get_pc_function_start (CORE_ADDR); 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, - enum print_what print_what); - extern void print_stack_frame (struct frame_info *, int print_level, - enum print_what print_what); + enum print_what print_what, + int set_current_sal); 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 *); - -extern int deprecated_pc_in_call_dummy (struct gdbarch *gdbarch, CORE_ADDR pc); + enum print_what print_what, int args, + int set_current_sal); -/* 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 - 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 struct frame_info *block_innermost_frame (const struct block *); -extern int frame_register_read (struct frame_info *frame, int regnum, +extern int deprecated_frame_register_read (struct frame_info *frame, int regnum, gdb_byte *buf); /* From stack.c. */ + +extern const char print_entry_values_no[]; +extern const char print_entry_values_only[]; +extern const char print_entry_values_preferred[]; +extern const char print_entry_values_if_needed[]; +extern const char print_entry_values_both[]; +extern const char print_entry_values_compact[]; +extern const char print_entry_values_default[]; +extern const char *print_entry_values; + +/* Inferior function parameter value read in from a frame. */ + +struct frame_arg +{ + /* Symbol for this parameter used for example for its name. */ + struct symbol *sym; + + /* Value of the parameter. It is NULL if ERROR is not NULL; if both VAL and + ERROR are NULL this parameter's value should not be printed. */ + struct value *val; + + /* String containing the error message, it is more usually NULL indicating no + error occured reading this parameter. */ + char *error; + + /* One of the print_entry_values_* entries as appropriate specifically for + this frame_arg. It will be different from print_entry_values. With + print_entry_values_no this frame_arg should be printed as a normal + parameter. print_entry_values_only says it should be printed as entry + value parameter. print_entry_values_compact says it should be printed as + both as a normal parameter and entry values parameter having the same + value - print_entry_values_compact is not permitted fi ui_out_is_mi_like_p + (in such case print_entry_values_no and print_entry_values_only is used + for each parameter kind specifically. */ + const char *entry_kind; +}; + +extern void read_frame_arg (struct symbol *sym, struct frame_info *frame, + struct frame_arg *argp, + struct frame_arg *entryargp); +extern void read_frame_local (struct symbol *sym, struct frame_info *frame, + struct frame_arg *argp); + extern void args_info (char *, int); extern void locals_info (char *, int);