2003-04-01 Andrew Cagney <cagney@redhat.com>
authorAndrew Cagney <cagney@redhat.com>
Tue, 1 Apr 2003 19:11:01 +0000 (19:11 +0000)
committerAndrew Cagney <cagney@redhat.com>
Tue, 1 Apr 2003 19:11:01 +0000 (19:11 +0000)
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 and
get_frame_args_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".
* 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.
* Makefile.in (frame_base_h): Define.
(frame.o): Update dependencies.
(frame-base.o): Add dependencies.
(SFILES): Add frame-base.c.
(COMMON_OBS): Add frame-base.o.

gdb/ChangeLog
gdb/Makefile.in
gdb/dwarf2expr.c
gdb/dwarf2loc.c
gdb/findvar.c
gdb/frame-base.c [new file with mode: 0644]
gdb/frame-base.h [new file with mode: 0644]
gdb/frame.c
gdb/frame.h
gdb/printcmd.c
gdb/stack.c

index e2415161e36491640ef9fb92660d970b164cf9c5..46955bbdc0fd91594f06dfcb3723f871336bd771 100644 (file)
@@ -1,3 +1,36 @@
+2003-04-01  Andrew Cagney  <cagney@redhat.com>
+
+       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 and
+       get_frame_args_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".
+       * 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.
+       * Makefile.in (frame_base_h): Define.
+       (frame.o): Update dependencies.
+       (frame-base.o): Add dependencies.
+       (SFILES): Add frame-base.c.
+       (COMMON_OBS): Add frame-base.o.
+
 2003-04-01  Andrew Cagney  <cagney@redhat.com>
 
        * gdbarch.sh (CALL_DUMMY_START_OFFSET): Default to zero.
index 3f1e91f91c44b0a31a2469ec7db15f47cc41290d..b07b7b9a5199ef0b0dd0cd066c03c0ab2fd985eb 100644 (file)
@@ -517,6 +517,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \
        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 @@ expression_h = expression.h $(symtab_h) $(doublest_h)
 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
@@ -859,6 +861,7 @@ COMMON_OBS = version.o blockframe.o breakpoint.o findvar.o regcache.o \
        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
 
@@ -1702,9 +1705,10 @@ fork-child.o: fork-child.c $(defs_h) $(gdb_string_h) $(frame_h) \
        $(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_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 7456979b91f31450650b4f79e16792920eeb1eac..be965abd528127e524b8792a461d743aed59de5d 100644 (file)
@@ -454,6 +454,9 @@ execute_stack_op (struct dwarf_expr_context *ctx, unsigned char *op_ptr,
               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 9ea9941f249c995ad0ff781359f995bc7ea73c1e..7073549bf02daa5bed36c12d74a9273a4e113ea8 100644 (file)
@@ -87,6 +87,9 @@ dwarf_expr_read_mem (void *baton, char *buf, CORE_ADDR addr, size_t len)
 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 93c4d8a6e8305a36436b0af037d632cb9c005cf7..beab9fb8fe5fb7977956abc7dfc36c3c9e8ec7d2 100644 (file)
@@ -508,7 +508,7 @@ addresses have not been bound by the dynamic loader. Try again when executable i
     case LOC_ARG:
       if (frame == NULL)
        return 0;
-      addr = FRAME_ARGS_ADDRESS (frame);
+      addr = get_frame_args_address (frame);
       if (!addr)
        return 0;
       addr += SYMBOL_VALUE (var);
@@ -520,7 +520,7 @@ addresses have not been bound by the dynamic loader. Try again when executable i
        CORE_ADDR argref;
        if (frame == NULL)
          return 0;
-       argref = FRAME_ARGS_ADDRESS (frame);
+       argref = get_frame_args_address (frame);
        if (!argref)
          return 0;
        argref += SYMBOL_VALUE (var);
@@ -533,7 +533,7 @@ addresses have not been bound by the dynamic loader. Try again when executable i
     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;
 
diff --git a/gdb/frame-base.c b/gdb/frame-base.c
new file mode 100644 (file)
index 0000000..f7ba4be
--- /dev/null
@@ -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);
+}
diff --git a/gdb/frame-base.h b/gdb/frame-base.h
new file mode 100644 (file)
index 0000000..5e0d5db
--- /dev/null
@@ -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 99b3108ce237254719e74985b7185c9b10773d14..09dea5e4c0224c5f0822c1b67800344356a2bb20 100644 (file)
@@ -36,6 +36,7 @@
 #include "annotate.h"
 #include "language.h"
 #include "frame-unwind.h"
+#include "frame-base.h"
 #include "command.h"
 #include "gdbcmd.h"
 
@@ -1630,6 +1631,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, ...
    or -1 for a NULL frame.  */
 
index dfbebda06ebef59f666c400c9193c8c0b0a28dc7..d13e25b91c1bc6fb26db1a80012ccfa88320b496 100644 (file)
@@ -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 CORE_ADDR get_frame_pc (struct frame_info *);
 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 @@ extern CORE_ADDR get_frame_base (struct frame_info *);
    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 @@ struct frame_info
        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.  */
@@ -414,6 +413,12 @@ struct frame_info
     int id_p;
     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.  */
     struct frame_info *next; /* down, inner, younger */
index 5196ef049b68516b4404164113ec414389b9a3fa..b38968d7751174f076ea8b3dc859c7b1132d8704 100644 (file)
@@ -1959,7 +1959,7 @@ print_frame_nameless_args (struct frame_info *fi, long start, int num,
 #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 98b8a0f88ce66fd607e8b0aaa2a75d8fe2be0f56..27fcaf6f6dba782489e7385d8dfa7be921552b20 100644 (file)
@@ -600,16 +600,6 @@ parse_frame_specification (char *frame_exp)
   /* 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 @@ frame_info (char *addr_exp, int from_tty)
 
   {
     /* 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 @@ frame_info (char *addr_exp, int from_tty)
   }
   {
     /* 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,");