Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [patch rfc] Per-frame frame-base
@ 2003-03-26 20:37 Andrew Cagney
  2003-03-26 21:00 ` Daniel Jacobowitz
  2003-04-01 19:25 ` Andrew Cagney
  0 siblings, 2 replies; 7+ messages in thread
From: Andrew Cagney @ 2003-03-26 20:37 UTC (permalink / raw)
  To: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 2882 bytes --]

Hello,

Ref: frame->unwind->this_base()
http://sources.redhat.com/ml/gdb/2003-03/msg00238.html
Ref: cagney_framebase-20030326-branch

The attached patch introduces new per-frame methods:

	get_frame_base_address()
	get_frame_locals_address()
	get_frame_args_address()

as successors to the old FRAME_LOCALS_ADDRESS(), FRAME_ARGS_ADDRESS(), 
and get_frame_base()

These debug-info specific methods are expected to return various 
addresses, within a frame, which that same debug-info can use.  For 
instance, a frame with dwarf2 debug info would provide dwarf2 version of 
the above that return DW_AT_frame_base in all cases.

These methods are:

- per frame
Each frame, can have a different implementation.  The implementation 
being selected on the basis of the high-level debug info that needs 
those corresponding values.  One frame stabs, the next dwarf2, the next 
nothing.

- unwind netural
These methods are not tied to the frame's register unwind code.  A frame 
might mix'n'match a dwarf2 frame-base with a libunwind frame-unwind.

Going through the old methods:

FRAME_LOCALS_ADDRESS(), FRAME_ARGS_ADDRESS(): These were hard-wired to 
return a value that assumed a specific ABI and debug info.  Both those 
restrictions have been removed.

get_frame_base(): This was hardwired to return the frame->frame (what 
ever that ended up being).  Code then tried to use that value both as a 
frame identifier, and as a higher-level frame base.  It didn't work. 
New code should instead use get_frame_id() XOR get_frame_*_address().

Other stuff:

The implementation is very much modeled on the frame-unwind code.  Debug 
readers are expected to register their own high level frame-base handler.

In the case of a frame using both a prologue based frame-unwind and 
frame-base, there is an oportunity to share a common cache.  The code 
handles this with:
+  /* 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;
so I guess that is cheap inheritance.

It adds a note to dwarf2loc and dwarf2expr pointing out that they can, 
and should, implement a dwarf2 specific frame-base.  If nothing else, 
this makes the dwarf2 frame addresses visible to the user (via `info 
frame'), which is much less confusing then the current situtation where 
`info frame' prints irellevant prologue based values :-( (there is also 
an oportunity for some value caching using the frame).

A follow on d10v change is to modify its frame ID / frame base methods 
so that they return different values.  At present they return the same 
value and that is very wrong :-(  I believe that the i386 is hitting the 
same problem.

Baring comment, I'll commit it in a week, I'll, for the moment, toss it 
on a branch.

Andrew

[-- Attachment #2: diffs --]
[-- Type: text/plain, Size: 28428 bytes --]

2003-03-26  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.
	* 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,
 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [patch rfc] Per-frame frame-base
  2003-03-26 20:37 [patch rfc] Per-frame frame-base Andrew Cagney
@ 2003-03-26 21:00 ` Daniel Jacobowitz
  2003-03-26 21:51   ` Andrew Cagney
  2003-04-01 19:25 ` Andrew Cagney
  1 sibling, 1 reply; 7+ messages in thread
From: Daniel Jacobowitz @ 2003-03-26 21:00 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb-patches

On Wed, Mar 26, 2003 at 03:37:22PM -0500, Andrew Cagney wrote:
> The implementation is very much modeled on the frame-unwind code.  Debug 
> readers are expected to register their own high level frame-base handler.

So what will the process for getting a dwarf2-debug-info frame
registered look like?  How will we figure out that this function has
dwarf2 debug info?  It's not trivial... we don't have that information
around any more on a per-PC basis.

I'll have to think.

> +/* 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 *);
> +

Address of the first parameter / address of the first argument isn't
correct I think.  It's the base address for parameters and the base
address from locals.  They're likely to be the same but with different
offsets.

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [patch rfc] Per-frame frame-base
  2003-03-26 21:00 ` Daniel Jacobowitz
@ 2003-03-26 21:51   ` Andrew Cagney
  2003-03-26 21:58     ` Daniel Jacobowitz
  0 siblings, 1 reply; 7+ messages in thread
From: Andrew Cagney @ 2003-03-26 21:51 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: gdb-patches

> On Wed, Mar 26, 2003 at 03:37:22PM -0500, Andrew Cagney wrote:
> 
>> The implementation is very much modeled on the frame-unwind code.  Debug 
>> readers are expected to register their own high level frame-base handler.
> 
> 
> So what will the process for getting a dwarf2-debug-info frame
> registered look like?

The current interface is identical to frame-unwind.

> How will we figure out that this function has
> dwarf2 debug info?  It's not trivial... we don't have that information
> around any more on a per-PC basis.

Ask the frame's function's symbol or block.

> I'll have to think.
> 
> 
>> +/* 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 *);
>> +
> 
> 
> Address of the first parameter / address of the first argument isn't
> correct I think.  It's the base address for parameters and the base
> address from locals.  They're likely to be the same but with different
> offsets.

You mean:

``Assuming that .., return the base address of the parameters''

Which may be different to the address of the first parameter since, even 
the first parameter's location may be specified as an offset from that 
base?  Ok.

Andrew



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [patch rfc] Per-frame frame-base
  2003-03-26 21:51   ` Andrew Cagney
@ 2003-03-26 21:58     ` Daniel Jacobowitz
  2003-03-26 22:18       ` Andrew Cagney
  0 siblings, 1 reply; 7+ messages in thread
From: Daniel Jacobowitz @ 2003-03-26 21:58 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb-patches

On Wed, Mar 26, 2003 at 04:51:13PM -0500, Andrew Cagney wrote:
> >On Wed, Mar 26, 2003 at 03:37:22PM -0500, Andrew Cagney wrote:
> >
> >>The implementation is very much modeled on the frame-unwind code.  Debug 
> >>readers are expected to register their own high level frame-base handler.
> >
> >
> >So what will the process for getting a dwarf2-debug-info frame
> >registered look like?
> 
> The current interface is identical to frame-unwind.
> 
> >How will we figure out that this function has
> >dwarf2 debug info?  It's not trivial... we don't have that information
> >around any more on a per-PC basis.
> 
> Ask the frame's function's symbol or block.

Symbols don't currently have this information, nor do blocks.

> You mean:
> 
> ``Assuming that .., return the base address of the parameters''
> 
> Which may be different to the address of the first parameter since, even 
> the first parameter's location may be specified as an offset from that 
> base?  Ok.

Right.  DW_OP_fbreg is used for both parameters and locals without
distinction; generally at 0 offset is something like the return
address or frame chain.

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [patch rfc] Per-frame frame-base
  2003-03-26 21:58     ` Daniel Jacobowitz
@ 2003-03-26 22:18       ` Andrew Cagney
  2003-03-26 22:22         ` Daniel Jacobowitz
  0 siblings, 1 reply; 7+ messages in thread
From: Andrew Cagney @ 2003-03-26 22:18 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: gdb-patches

> On Wed, Mar 26, 2003 at 04:51:13PM -0500, Andrew Cagney wrote:
> 
>> >On Wed, Mar 26, 2003 at 03:37:22PM -0500, Andrew Cagney wrote:
>> >
> 
>> >>The implementation is very much modeled on the frame-unwind code.  Debug 
>> >>readers are expected to register their own high level frame-base handler.
> 
>> >
>> >
>> >So what will the process for getting a dwarf2-debug-info frame
>> >registered look like?
> 
>> 
>> The current interface is identical to frame-unwind.
>> 
> 
>> >How will we figure out that this function has
>> >dwarf2 debug info?  It's not trivial... we don't have that information
>> >around any more on a per-PC basis.
> 
>> 
>> Ask the frame's function's symbol or block.
> 
> 
> Symbols don't currently have this information, nor do blocks.

Well, at least the partial symtab does, sort of implicit via 
read_symtab.  Shame that location_funcs stuff wasn't a symbol wide 
virtual function table.

Andrew



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [patch rfc] Per-frame frame-base
  2003-03-26 22:18       ` Andrew Cagney
@ 2003-03-26 22:22         ` Daniel Jacobowitz
  0 siblings, 0 replies; 7+ messages in thread
From: Daniel Jacobowitz @ 2003-03-26 22:22 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb-patches

On Wed, Mar 26, 2003 at 05:18:32PM -0500, Andrew Cagney wrote:
> >On Wed, Mar 26, 2003 at 04:51:13PM -0500, Andrew Cagney wrote:
> >
> >>>On Wed, Mar 26, 2003 at 03:37:22PM -0500, Andrew Cagney wrote:
> >>>
> >
> >>>>The implementation is very much modeled on the frame-unwind code.  
> >>Debug >>readers are expected to register their own high level frame-base 
> >>handler.
> >
> >>>
> >>>
> >>>So what will the process for getting a dwarf2-debug-info frame
> >>>registered look like?
> >
> >>
> >>The current interface is identical to frame-unwind.
> >>
> >
> >>>How will we figure out that this function has
> >>>dwarf2 debug info?  It's not trivial... we don't have that information
> >>>around any more on a per-PC basis.
> >
> >>
> >>Ask the frame's function's symbol or block.
> >
> >
> >Symbols don't currently have this information, nor do blocks.
> 
> Well, at least the partial symtab does, sort of implicit via 
> read_symtab.  Shame that location_funcs stuff wasn't a symbol wide 
> virtual function table.

I heard a volunteer running away into the woods, where did he go?
It took over a year to get location_funcs in at all.

Obviously using any of these frame cleanups is going to require
cleanups in the symtab.  I don't know who will be interested in doing
them however.

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [patch rfc] Per-frame frame-base
  2003-03-26 20:37 [patch rfc] Per-frame frame-base Andrew Cagney
  2003-03-26 21:00 ` Daniel Jacobowitz
@ 2003-04-01 19:25 ` Andrew Cagney
  1 sibling, 0 replies; 7+ messages in thread
From: Andrew Cagney @ 2003-04-01 19:25 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 1593 bytes --]

I've checked this in, and then quickly followed it by the attached.  I 
forgot to update that comment :-(

Andrew


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.


[-- Attachment #2: diffs --]
[-- Type: text/plain, Size: 1730 bytes --]

2003-04-01  Andrew Cagney  <cagney@redhat.com>

	* frame.h (get_frame_locals_address, get_frame_args_address):
	Refer to the base address, instead of the address of the first
	local or parameter.
	
Index: frame.h
===================================================================
RCS file: /cvs/src/src/gdb/frame.h,v
retrieving revision 1.79
diff -u -r1.79 frame.h
--- frame.h	1 Apr 2003 19:11:01 -0000	1.79
+++ frame.h	1 Apr 2003 19:15:22 -0000
@@ -202,17 +202,17 @@
    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:
+/* Assuming that a frame is `normal', return the base-address of the
+   local variables, 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
+/* Assuming that a frame is `normal', return the base-address of the
+   parameter list, 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 *);
 

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2003-04-01 19:25 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-03-26 20:37 [patch rfc] Per-frame frame-base Andrew Cagney
2003-03-26 21:00 ` Daniel Jacobowitz
2003-03-26 21:51   ` Andrew Cagney
2003-03-26 21:58     ` Daniel Jacobowitz
2003-03-26 22:18       ` Andrew Cagney
2003-03-26 22:22         ` Daniel Jacobowitz
2003-04-01 19:25 ` Andrew Cagney

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox