2003-03-26 Andrew Cagney Add frame debug info addresses: * frame-base.c: New file. * frame-base.h: New file. * frame.h (struct frame_base): Add opaque declaration. (get_frame_base): Update comment. (get_frame_base_address): Declare. (get_frame_locals_address): Declare. (get_frame_args_address): Declare. (struct frame_info): Add "base" and "base_cache". Update comments on the unwinder. * frame.c: Include "frame-base.h". (get_frame_locals_address): New function. (get_frame_base_address): New function. (get_frame_args_address): New function. * findvar.c (read_var_value): Use get_frame_locals_address. * stack.c (frame_info): Use get_frame_locals_address and get_frame_args_address. (FRAME_ARGS_ADDRESS_CORRECT): Delete conditionally defined macro, moved to "frame-base.c". * Makefile.in (frame_base_h): Define. (frame.o): Update dependencies. (d10v-tdep.o): Update dependencies. (frame-base.o): Add dependencies. (SFILES): Add frame-base.c. (COMMON_OBS): Add frame-base.o. * printcmd.c (print_frame_nameless_args): Ditto. * symtab.h (address_class): Update comments. * dwarf2loc.c (dwarf_expr_frame_base): Add note about get_frame_base_address. * dwarf2expr.c (execute_stack_op): Ditto. * d10v-tdep.c: Include "frame-base.h". (d10v_frame_unwind): Make constant. (d10v_frame_base_address): New function. (d10v_frame_base): New variable. (d10v_gdbarch_init): Set frame_base default. Index: Makefile.in =================================================================== RCS file: /cvs/src/src/gdb/Makefile.in,v retrieving revision 1.351 diff -u -r1.351 Makefile.in --- Makefile.in 26 Mar 2003 03:39:42 -0000 1.351 +++ Makefile.in 26 Mar 2003 18:21:47 -0000 @@ -517,6 +517,7 @@ dummy-frame.c dwarfread.c dwarf2expr.c dwarf2loc.c dwarf2read.c \ elfread.c environ.c eval.c event-loop.c event-top.c expprint.c \ f-exp.y f-lang.c f-typeprint.c f-valprint.c findvar.c frame.c \ + frame-base.c \ frame-unwind.c \ gdbarch.c arch-utils.c gdbtypes.c gnu-v2-abi.c gnu-v3-abi.c \ hpacc-abi.c \ @@ -641,6 +642,7 @@ f_lang_h = f-lang.h frame_h = frame.h frame_unwind_h = frame-unwind.h +frame_base_h = frame-base.h gdb_events_h = gdb-events.h gdb_stabs_h = gdb-stabs.h gdb_h = gdb.h @@ -858,6 +860,7 @@ nlmread.o serial.o mdebugread.o top.o utils.o \ ui-file.o \ frame.o frame-unwind.o doublest.o \ + frame-base.o \ gnu-v2-abi.o gnu-v3-abi.o hpacc-abi.o cp-abi.o cp-support.o \ reggroups.o @@ -1618,11 +1621,11 @@ $(gdbtypes_h) $(gdbcore_h) $(gdbcmd_h) $(target_h) $(value_h) \ $(opcode_cris_h) $(arch_utils_h) $(regcache_h) $(symfile_h) \ $(solib_h) $(solib_svr4_h) $(gdb_string_h) -d10v-tdep.o: d10v-tdep.c $(defs_h) $(frame_h) $(symtab_h) $(gdbtypes_h) \ - $(gdbcmd_h) $(gdbcore_h) $(gdb_string_h) $(value_h) $(inferior_h) \ - $(dis_asm_h) $(symfile_h) $(objfiles_h) $(language_h) $(arch_utils_h) \ - $(regcache_h) $(floatformat_h) $(gdb_sim_d10v_h) $(sim_regno_h) \ - $(gdb_assert_h) +d10v-tdep.o: d10v-tdep.c $(defs_h) $(frame_h) $(frame_unwind_h) \ + $(frame_base_h) $(symtab_h) $(gdbtypes_h) $(gdbcmd_h) $(gdbcore_h) \ + $(gdb_string_h) $(value_h) $(inferior_h) $(dis_asm_h) $(symfile_h) \ + $(objfiles_h) $(language_h) $(arch_utils_h) $(regcache_h) \ + $(floatformat_h) $(gdb_sim_d10v_h) $(sim_regno_h) $(gdb_assert_h) dbug-rom.o: dbug-rom.c $(defs_h) $(gdbcore_h) $(target_h) $(monitor_h) \ $(serial_h) $(regcache_h) $(m68k_tdep_h) dbxread.o: dbxread.c $(defs_h) $(gdb_string_h) $(gdb_obstack_h) \ @@ -1702,9 +1705,10 @@ $(terminal_h) $(gdbthread_h) $(command_h) frame.o: frame.c $(defs_h) $(frame_h) $(target_h) $(value_h) $(inferior_h) \ $(regcache_h) $(gdb_assert_h) $(gdb_string_h) $(builtin_regs_h) \ - $(gdb_obstack_h) $(dummy_frame_h) $(gdbcore_h) $(annotate_h) \ - $(language_h) $(frame_unwind_h) $(command_h) $(gdbcmd_h) \ - $(sentinel_frame_h) + $(gdb_obstack_h) $(dummy_frame_h) $(sentinel_frame_h) $(gdbcore_h) \ + $(annotate_h) $(language_h) $(frame_unwind_h) $(frame_base_h) \ + $(command_h) $(gdbcmd_h) +frame-base.o: frame-base.c $(defs_h) $(frame_base_h) frame-unwind.o: frame-unwind.c $(defs_h) $(frame_h) $(frame_unwind_h) \ $(gdb_assert_h) $(dummy_frame_h) $(legacy_frame_h) frv-tdep.o: frv-tdep.c $(defs_h) $(inferior_h) $(symfile_h) $(gdbcore_h) \ Index: d10v-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/d10v-tdep.c,v retrieving revision 1.90 diff -u -r1.90 d10v-tdep.c --- d10v-tdep.c 25 Mar 2003 22:56:39 -0000 1.90 +++ d10v-tdep.c 26 Mar 2003 18:21:49 -0000 @@ -25,6 +25,7 @@ #include "defs.h" #include "frame.h" #include "frame-unwind.h" +#include "frame-base.h" #include "symtab.h" #include "gdbtypes.h" #include "gdbcmd.h" @@ -1558,8 +1559,7 @@ } } - -static struct frame_unwind d10v_frame_unwind = { +static const struct frame_unwind d10v_frame_unwind = { d10v_frame_this_id, d10v_frame_prev_register }; @@ -1570,6 +1570,21 @@ return &d10v_frame_unwind; } +static CORE_ADDR +d10v_frame_base_address (struct frame_info *next_frame, void **this_cache) +{ + struct d10v_unwind_cache *info + = d10v_frame_unwind_cache (next_frame, this_cache); + return info->base; +} + +static const struct frame_base d10v_frame_base = { + &d10v_frame_unwind, + d10v_frame_base_address, + d10v_frame_base_address, + d10v_frame_base_address +}; + /* Assuming NEXT_FRAME->prev is a dummy, return the frame ID of that dummy frame. The frame ID's base needs to match the TOS value saved by save_dummy_frame_tos(), and the PC match the dummy frame's @@ -1719,6 +1734,7 @@ set_gdbarch_print_registers_info (gdbarch, d10v_print_registers_info); frame_unwind_append_predicate (gdbarch, d10v_frame_p); + frame_base_set_default (gdbarch, &d10v_frame_base); /* Methods for saving / extracting a dummy frame's ID. */ set_gdbarch_unwind_dummy_id (gdbarch, d10v_unwind_dummy_id); Index: dwarf2expr.c =================================================================== RCS file: /cvs/src/src/gdb/dwarf2expr.c,v retrieving revision 1.3 diff -u -r1.3 dwarf2expr.c --- dwarf2expr.c 5 Mar 2003 18:00:02 -0000 1.3 +++ dwarf2expr.c 26 Mar 2003 18:21:49 -0000 @@ -454,6 +454,9 @@ afterwards, effectively erasing whatever the recursive call put there. */ before_stack_len = ctx->stack_len; + /* FIXME: cagney/2003-03-26: This code should be using + get_frame_base_address(), and then implement a dwarf2 + specific this_base method. */ (ctx->get_frame_base) (ctx->baton, &datastart, &datalen); dwarf_expr_eval (ctx, datastart, datalen); result = dwarf_expr_fetch (ctx, 0); Index: dwarf2loc.c =================================================================== RCS file: /cvs/src/src/gdb/dwarf2loc.c,v retrieving revision 1.3 diff -u -r1.3 dwarf2loc.c --- dwarf2loc.c 5 Mar 2003 18:00:02 -0000 1.3 +++ dwarf2loc.c 26 Mar 2003 18:21:49 -0000 @@ -87,6 +87,9 @@ static void dwarf_expr_frame_base (void *baton, unsigned char **start, size_t * length) { + /* FIXME: cagney/2003-03-26: This code should be using + get_frame_base_address(), and then implement a dwarf2 specific + this_base method. */ struct symbol *framefunc; struct dwarf2_locexpr_baton *symbaton; struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton; Index: findvar.c =================================================================== RCS file: /cvs/src/src/gdb/findvar.c,v retrieving revision 1.52 diff -u -r1.52 findvar.c --- findvar.c 14 Mar 2003 17:07:00 -0000 1.52 +++ findvar.c 26 Mar 2003 18:21:49 -0000 @@ -533,7 +533,7 @@ case LOC_LOCAL_ARG: if (frame == NULL) return 0; - addr = FRAME_LOCALS_ADDRESS (frame); + addr = get_frame_locals_address (frame); addr += SYMBOL_VALUE (var); break; Index: frame-base.c =================================================================== RCS file: frame-base.c diff -N frame-base.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ frame-base.c 26 Mar 2003 18:21:49 -0000 @@ -0,0 +1,154 @@ +/* Definitions for frame address handler, for GDB, the GNU debugger. + + Copyright 2003 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 + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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. */ + +#include "defs.h" +#include "frame-base.h" +#include "frame.h" + +/* A default frame base implementations. If it wasn't for the old + FRAME_LOCALS_ADDRESS and FRAME_ARGS_ADDRESS, these could be + combined into a single function. All architectures really need to + override this. */ + +static CORE_ADDR +default_frame_base_address (struct frame_info *next_frame, void **this_cache) +{ + struct frame_info *this_frame = get_prev_frame (next_frame); + return get_frame_base (this_frame); /* sigh! */ +} + +static CORE_ADDR +default_frame_locals_address (struct frame_info *next_frame, void **this_cache) +{ + struct frame_info *this_frame = get_prev_frame (next_frame); + return FRAME_LOCALS_ADDRESS (this_frame); +} + +static CORE_ADDR +default_frame_args_address (struct frame_info *next_frame, void **this_cache) +{ + struct frame_info *this_frame = get_prev_frame (next_frame); + /* FRAME_ARGS_ADDRESS_CORRECT is just like FRAME_ARGS_ADDRESS except + that if it is unsure about the answer, it returns 0 instead of + guessing (this happens on the VAX and i960, for example). + + On most machines, we never have to guess about the args address, + so FRAME_ARGS_ADDRESS{,_CORRECT} are the same. */ +#ifdef FRAME_ARGS_ADDRESS_CORRECT + return FRAME_ARGS_ADDRESS_CORRECT (this_frame); +#else + return FRAME_ARGS_ADDRESS (this_frame); +#endif +} + +const struct frame_base default_frame_base = { + NULL, /* No parent. */ + default_frame_base_address, + default_frame_locals_address, + default_frame_args_address +}; + +static struct gdbarch_data *frame_base_data; + +struct frame_base_table +{ + frame_base_p_ftype **p; + const struct frame_base *default_base; + int nr; +}; + +static void * +frame_base_init (struct gdbarch *gdbarch) +{ + struct frame_base_table *table = XCALLOC (1, struct frame_base_table); + table->default_base = &default_frame_base; + return table; +} + +static void +frame_base_free (struct gdbarch *gdbarch, void *data) +{ + struct frame_base_table *table = + gdbarch_data (gdbarch, frame_base_data); + xfree (table->p); + xfree (table); +} + +static struct frame_base_table * +frame_base_table (struct gdbarch *gdbarch) +{ + struct frame_base_table *table = gdbarch_data (gdbarch, frame_base_data); + if (table == NULL) + { + /* ULGH, called during architecture initialization. Patch + things up. */ + table = frame_base_init (gdbarch); + set_gdbarch_data (gdbarch, frame_base_data, table); + } + return table; +} + +/* Append a predicate to the end of the table. */ +static void +append_predicate (struct frame_base_table *table, frame_base_p_ftype *p) +{ + table->p = xrealloc (table->p, ((table->nr + 1) + * sizeof (frame_base_p_ftype *))); + table->p[table->nr] = p; + table->nr++; +} + +void +frame_base_append_predicate (struct gdbarch *gdbarch, + frame_base_p_ftype *p) +{ + struct frame_base_table *table = frame_base_table (gdbarch); + append_predicate (table, p); +} + +void +frame_base_set_default (struct gdbarch *gdbarch, + const struct frame_base *default_base) +{ + struct frame_base_table *table = frame_base_table (gdbarch); + table->default_base = default_base; +} + +const struct frame_base * +frame_base_find_by_pc (struct gdbarch *gdbarch, CORE_ADDR pc) +{ + int i; + struct frame_base_table *table = frame_base_table (gdbarch); + for (i = 0; i < table->nr; i++) + { + const struct frame_base *desc = table->p[i] (pc); + if (desc != NULL) + return desc; + } + return table->default_base; +} + +void +_initialize_frame_base (void) +{ + frame_base_data = register_gdbarch_data (frame_base_init, + frame_base_free); +} Index: frame-base.h =================================================================== RCS file: frame-base.h diff -N frame-base.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ frame-base.h 26 Mar 2003 18:21:49 -0000 @@ -0,0 +1,94 @@ +/* Definitions for a frame base, for GDB, the GNU debugger. + + Copyright 2003 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 + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + 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. */ + +#if !defined (FRAME_BASE_H) +#define FRAME_BASE_H 1 + +struct frame_info; +struct frame_id; +struct frame_unwind; +struct frame_base; +struct gdbarch; +struct regcache; + +/* Return the frame base methods for the function that contains PC, or + NULL if it can't handle this frame. */ + +typedef const struct frame_base *(frame_base_p_ftype) (CORE_ADDR pc); + +/* Add a frame base handler to the list. The predicates are polled in + the order that they are appended. */ + +extern void frame_base_append_predicate (struct gdbarch *gdbarch, + frame_base_p_ftype *p); + +/* Set the default frame base. If all else fails, this one is + returned. If this isn't set, the default is to use legacy code + that uses things like the frame ID's base (ulgh!). */ + +extern void frame_base_set_default (struct gdbarch *gdbarch, + const struct frame_base *def); + +/* Iterate through the list of frame base handlers until one returns + an implementation. */ + +extern const struct frame_base *frame_base_find_by_pc (struct gdbarch *gdbarch, + CORE_ADDR pc); + +/* Assuming the frame chain: (outer) prev <-> this <-> next (inner); + and that this is a `normal frame'; use the NEXT frame, and its + register unwind method, to determine the address of THIS frame's + `base'. + + The exact meaning of `base' is highly dependant on the type of the + debug info. It is assumed that dwarf2, stabs, ... will each + provide their own methods. + + A typical implmentation will return the same value for base, + locals-base and args-base. That value, however, will likely be + different to the frame ID's stack address. */ + +/* A generic base address. */ + +typedef CORE_ADDR (frame_this_base_ftype) (struct frame_info *next_frame, + void **this_base_cache); + +/* The base address of the frame's local variables. */ + +typedef CORE_ADDR (frame_this_locals_ftype) (struct frame_info *next_frame, + void **this_base_cache); + +/* The base address of the frame's arguments / parameters. */ + +typedef CORE_ADDR (frame_this_args_ftype) (struct frame_info *next_frame, + void **this_base_cache); + +struct frame_base +{ + /* If non-NULL, a low-level unwinder that shares its implementation + with this high-level frame-base method. */ + const struct frame_unwind *unwind; + frame_this_base_ftype *this_base; + frame_this_locals_ftype *this_locals; + frame_this_args_ftype *this_args; +}; + +#endif Index: frame.c =================================================================== RCS file: /cvs/src/src/gdb/frame.c,v retrieving revision 1.89 diff -u -r1.89 frame.c --- frame.c 26 Mar 2003 00:00:07 -0000 1.89 +++ frame.c 26 Mar 2003 18:21:50 -0000 @@ -36,6 +36,7 @@ #include "annotate.h" #include "language.h" #include "frame-unwind.h" +#include "frame-base.h" #include "command.h" #include "gdbcmd.h" @@ -1625,6 +1626,58 @@ get_frame_base (struct frame_info *fi) { return fi->frame; +} + +/* High-level offsets into the frame. Used by the debug info. */ + +CORE_ADDR +get_frame_base_address (struct frame_info *fi) +{ + if (fi->type != NORMAL_FRAME) + return 0; + if (fi->base == NULL) + fi->base = frame_base_find_by_pc (current_gdbarch, get_frame_pc (fi)); + /* Sneaky: If the low-level unwind and high-level base code share a + common unwinder, let them share the prologue cache. */ + if (fi->base->unwind == fi->unwind) + return fi->base->this_base (fi->next, &fi->prologue_cache); + return fi->base->this_base (fi->next, &fi->base_cache); +} + +CORE_ADDR +get_frame_locals_address (struct frame_info *fi) +{ + void **cache; + if (fi->type != NORMAL_FRAME) + return 0; + /* If there isn't a frame address method, find it. */ + if (fi->base == NULL) + fi->base = frame_base_find_by_pc (current_gdbarch, get_frame_pc (fi)); + /* Sneaky: If the low-level unwind and high-level base code share a + common unwinder, let them share the prologue cache. */ + if (fi->base->unwind == fi->unwind) + cache = &fi->prologue_cache; + else + cache = &fi->base_cache; + return fi->base->this_locals (fi->next, cache); +} + +CORE_ADDR +get_frame_args_address (struct frame_info *fi) +{ + void **cache; + if (fi->type != NORMAL_FRAME) + return 0; + /* If there isn't a frame address method, find it. */ + if (fi->base == NULL) + fi->base = frame_base_find_by_pc (current_gdbarch, get_frame_pc (fi)); + /* Sneaky: If the low-level unwind and high-level base code share a + common unwinder, let them share the prologue cache. */ + if (fi->base->unwind == fi->unwind) + cache = &fi->prologue_cache; + else + cache = &fi->base_cache; + return fi->base->this_args (fi->next, cache); } /* Level of the selected frame: 0 for innermost, 1 for its caller, ... Index: frame.h =================================================================== RCS file: /cvs/src/src/gdb/frame.h,v retrieving revision 1.76 diff -u -r1.76 frame.h --- frame.h 24 Mar 2003 03:54:47 -0000 1.76 +++ frame.h 26 Mar 2003 18:21:50 -0000 @@ -25,6 +25,7 @@ struct symtab_and_line; struct frame_unwind; +struct frame_base; struct block; /* A legacy unwinder to prop up architectures using the old style @@ -169,47 +170,25 @@ extern void find_frame_sal (struct frame_info *frame, struct symtab_and_line *sal); -/* Return the frame address from FI. Except in the machine-dependent - *FRAME* macros, a frame address has no defined meaning other than - as a magic cookie which identifies a frame over calls to the - inferior (um, SEE NOTE BELOW). The only known exception is - inferior.h (DEPRECATED_PC_IN_CALL_DUMMY) [ON_STACK]; see comments - there. You cannot assume that a frame address contains enough - information to reconstruct the frame; if you want more than just to - identify the frame (e.g. be able to fetch variables relative to - that frame), then save the whole struct frame_info (and the next - struct frame_info, since the latter is used for fetching variables - on some machines) (um, again SEE NOTE BELOW). - - NOTE: cagney/2002-11-18: Actually, the frame address isn't - sufficient for identifying a frame, and the counter examples are - wrong! - - Code that needs to (re)identify a frame must use get_frame_id() and - frame_find_by_id() (and in the future, a frame_compare() function - instead of INNER_THAN()). Two reasons: an architecture (e.g., - ia64) can have more than one frame address (due to multiple stack - pointers) (frame ID is going to be expanded to accomodate this); - successive frameless function calls can only be differientated by - comparing both the frame's base and the frame's enclosing function - (frame_find_by_id() is going to be modified to perform this test). - - The generic dummy frame version of DEPRECATED_PC_IN_CALL_DUMMY() is - able to identify a dummy frame using only the PC value. So the - frame address is not needed. In fact, most - DEPRECATED_PC_IN_CALL_DUMMY() calls now pass zero as the frame/sp - values as the caller knows that those values won't be used. Once - all architectures are using generic dummy frames, - DEPRECATED_PC_IN_CALL_DUMMY() can drop the sp/frame parameters. - When it comes to finding a dummy frame, the next frame's frame ID - (with out duing an unwind) can be used (ok, could if it wasn't for - the need to change the way the PPC defined frame base in a strange - way). - - Modern architectures should be using something like dwarf2's - location expression to describe where a variable lives. Such - expressions specify their own debug info centric frame address. - Consequently, a generic frame address is pretty meaningless. */ +/* Return the frame base (what ever that is) (DEPRECATED). + + Old code was trying to use this single method for two conflicting + purposes. Such code needs to be updated to use either of: + + get_frame_id: A low level frame unique identifier, that consists of + both a stack and a function address, that can be used to uniquely + identify a frame. This value is determined by the frame's + 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, + the old get_frame_base method was not sufficient. + + get_frame_base_address: get_frame_locals_address: + get_frame_args_address: A set of high-level debug-info dependant + addresses that fall within the frame. These addresses almost + certainly will not match the stack address part of a frame ID (as + returned by get_frame_base). */ extern CORE_ADDR get_frame_base (struct frame_info *); @@ -218,6 +197,25 @@ FI is NULL, return the null_frame_id. */ extern struct frame_id get_frame_id (struct frame_info *fi); +/* Assuming that a frame is `normal', return its base-address, or 0 if + the information isn't available. NOTE: This address is really only + meaningful to the frame's high-level debug info. */ +extern CORE_ADDR get_frame_base_address (struct frame_info *); + +/* Assuming that a frame is `normal', return the address of the first + local variable, or 0 if the information isn't available. NOTE: + This address is really only meaningful to the frame's high-level + debug info. Typically, the argument and locals share a single + base-address. */ +extern CORE_ADDR get_frame_locals_address (struct frame_info *); + +/* Assuming that a frame is `normal', return the address of the first + parameter, or 0 if that information isn't available. NOTE: This + address is really only meaningful to the frame's high-level debug + info. Typically, the argument and locals share a single + base-address. */ +extern CORE_ADDR get_frame_args_address (struct frame_info *); + /* The frame's level: 0 for innermost, 1 for its caller, ...; or -1 for an invalid frame). */ extern int frame_relative_level (struct frame_info *fi); @@ -398,11 +396,12 @@ related unwind data. */ struct context *context; - /* Prologue cache shared between the unwind functions. See - "frame-unwind.h" for more information. */ + /* The frame's low-level unwinder and corresponding cache. The + low-level unwinder is responsible for unwinding register values + for the previous frame. The low-level unwind methods are + selected based on the presence, or otherwize, of register + unwind information such as CFI. */ void *prologue_cache; - - /* The frame's unwinder. */ const struct frame_unwind *unwind; /* Cached copy of the previous frame's resume address. */ @@ -412,6 +411,12 @@ /* This frame's ID. Note that the frame's ID, base and PC contain redundant information. */ struct frame_id id; + + /* The frame's high-level base methods, and corresponding cache. + The high level base methods are selected based on the frame's + debug info. */ + const struct frame_base *base; + void *base_cache; /* Pointers to the next (down, inner, younger) and previous (up, outer, older) frame_info's in the frame cache. */ Index: printcmd.c =================================================================== RCS file: /cvs/src/src/gdb/printcmd.c,v retrieving revision 1.57 diff -u -r1.57 printcmd.c --- printcmd.c 18 Mar 2003 22:03:29 -0000 1.57 +++ printcmd.c 26 Mar 2003 18:21:51 -0000 @@ -1959,7 +1959,7 @@ #ifdef NAMELESS_ARG_VALUE NAMELESS_ARG_VALUE (fi, start, &arg_value); #else - argsaddr = FRAME_ARGS_ADDRESS (fi); + argsaddr = get_frame_args_address (fi); if (!argsaddr) return; Index: stack.c =================================================================== RCS file: /cvs/src/src/gdb/stack.c,v retrieving revision 1.71 diff -u -r1.71 stack.c --- stack.c 13 Mar 2003 21:45:41 -0000 1.71 +++ stack.c 26 Mar 2003 18:21:51 -0000 @@ -600,16 +600,6 @@ /* NOTREACHED */ } -/* FRAME_ARGS_ADDRESS_CORRECT is just like FRAME_ARGS_ADDRESS except - that if it is unsure about the answer, it returns 0 - instead of guessing (this happens on the VAX and i960, for example). - - On most machines, we never have to guess about the args address, - so FRAME_ARGS_ADDRESS{,_CORRECT} are the same. */ -#if !defined (FRAME_ARGS_ADDRESS_CORRECT) -#define FRAME_ARGS_ADDRESS_CORRECT FRAME_ARGS_ADDRESS -#endif - /* Print verbosely the selected frame or the frame at address ADDR. This means absolutely all information in the frame is printed. */ @@ -743,7 +733,7 @@ { /* Address of the argument list for this frame, or 0. */ - CORE_ADDR arg_list = FRAME_ARGS_ADDRESS_CORRECT (fi); + CORE_ADDR arg_list = get_frame_args_address (fi); /* Number of args for this frame, or -1 if unknown. */ int numargs; @@ -770,7 +760,7 @@ } { /* Address of the local variables for this frame, or 0. */ - CORE_ADDR arg_list = FRAME_LOCALS_ADDRESS (fi); + CORE_ADDR arg_list = get_frame_locals_address (fi); if (arg_list == 0) printf_filtered (" Locals at unknown address,"); Index: symtab.h =================================================================== RCS file: /cvs/src/src/gdb/symtab.h,v retrieving revision 1.65 diff -u -r1.65 symtab.h --- symtab.h 3 Mar 2003 18:34:12 -0000 1.65 +++ symtab.h 26 Mar 2003 18:21:51 -0000 @@ -402,8 +402,8 @@ /* Value is in register number SYMBOL_VALUE. Just like LOC_REGISTER except this is an argument. Probably the cleaner way to handle this would be to separate address_class (which would include - separate ARG and LOCAL to deal with FRAME_ARGS_ADDRESS versus - FRAME_LOCALS_ADDRESS), and an is_argument flag. + separate ARG and LOCAL to deal with get_frame_args_address() + versus get_frame_locals_address()), and an is_argument flag. For some symbol formats (stabs, for some compilers at least), the compiler generates two symbols, an argument and a register. @@ -447,9 +447,9 @@ /* Value is arg at SYMBOL_VALUE offset in stack frame. Differs from LOC_LOCAL in that symbol is an argument; differs from LOC_ARG in - that we find it in the frame (FRAME_LOCALS_ADDRESS), not in the - arglist (FRAME_ARGS_ADDRESS). Added for i960, which passes args - in regs then copies to frame. */ + that we find it in the frame (get_frame_locals_address()), not in + the arglist (get_frame_args_address()). Added for i960, which + passes args in regs then copies to frame. */ LOC_LOCAL_ARG,