RFC: implement DW_OP_call_frame_cfa

Tom Tromey tromey@redhat.com
Mon Jun 8 22:23:00 GMT 2009


GCC developers would like to change GCC to emit DW_OP_call_frame_cfa,
as this would reduce the size of the generated debuginfo.

A prerequisite to this is that GDB understand this.  So, this patch
implements this feature.  This is PR 10224.

I'm interested in feedback on this.  I am not sure whether the
implementation of dwarf2_frame_cfa is ok.

No test case since at some point GCC will start generating this
(perhaps optionally -- but I feel certain we'll do it by default in
Fedora), and since it therefore seemed like a lot of work for little
payoff.

Tom

2009-06-08  Tom Tromey  <tromey@redhat.com>

	PR gdb/10224:
	* dwarf2loc.c: Include dwarf2-frame.h.
	(dwarf_expr_frame_cfa): New function.
	(dwarf2_evaluate_loc_desc): Initialize new field.
	(needs_frame_frame_cfa): New function.
	(dwarf2_loc_desc_needs_frame): Initialize new field.
	* dwarf2expr.h (struct dwarf_expr_context) <get_frame_cfa>: New
	field.
	* dwarf2expr.c (execute_stack_op) <DW_OP_call_frame_cfa>: New
	case.
	* dwarf2-frame.h (dwarf2_frame_cfa): Declare.
	* dwarf2-frame.c (no_get_frame_cfa): New function.
	(execute_stack_op): Initialize new field.
	(dwarf2_frame_cfa): New function.

diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c
index c1b3e60..cdcd462 100644
--- a/gdb/dwarf2-frame.c
+++ b/gdb/dwarf2-frame.c
@@ -1,6 +1,6 @@
 /* Frame unwinder for frames with DWARF Call Frame Information.
 
-   Copyright (C) 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
 
    Contributed by Mark Kettenis.
 
@@ -304,6 +304,13 @@ no_get_frame_base (void *baton, gdb_byte **start, size_t *length)
 }
 
 static CORE_ADDR
+no_get_frame_cfa (void *baton)
+{
+  internal_error (__FILE__, __LINE__,
+		  _("Support for DW_OP_call_frame_cfa is unimplemented"));
+}
+
+static CORE_ADDR
 no_get_tls_address (void *baton, CORE_ADDR offset)
 {
   internal_error (__FILE__, __LINE__,
@@ -354,6 +361,7 @@ execute_stack_op (gdb_byte *exp, ULONGEST len, int addr_size,
   ctx->read_reg = read_reg;
   ctx->read_mem = read_mem;
   ctx->get_frame_base = no_get_frame_base;
+  ctx->get_frame_cfa = no_get_frame_cfa;
   ctx->get_tls_address = no_get_tls_address;
 
   dwarf_expr_push (ctx, initial);
@@ -1219,6 +1227,13 @@ dwarf2_frame_base_address (struct frame_info *this_frame, void **this_cache)
   return cache->cfa;
 }
 
+CORE_ADDR
+dwarf2_frame_cfa (struct frame_info *this_frame)
+{
+  void *cache = NULL;
+  return dwarf2_frame_base_address (this_frame, &cache);
+}
+
 static const struct frame_base dwarf2_frame_base =
 {
   &dwarf2_frame_unwind,
diff --git a/gdb/dwarf2-frame.h b/gdb/dwarf2-frame.h
index aeff54a..e08452c 100644
--- a/gdb/dwarf2-frame.h
+++ b/gdb/dwarf2-frame.h
@@ -1,6 +1,6 @@
 /* Frame unwinder for frames with DWARF Call Frame Information.
 
-   Copyright (C) 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
 
    Contributed by Mark Kettenis.
 
@@ -117,4 +117,8 @@ extern const struct frame_base *
 
 void dwarf2_frame_build_info (struct objfile *objfile);
 
+/* Compute the DWARF CFA for a frame.  */
+
+CORE_ADDR dwarf2_frame_cfa (struct frame_info *this_frame);
+
 #endif /* dwarf2-frame.h */
diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c
index 707c0de..e556038 100644
--- a/gdb/dwarf2expr.c
+++ b/gdb/dwarf2expr.c
@@ -1,6 +1,6 @@
 /* DWARF 2 Expression Evaluator.
 
-   Copyright (C) 2001, 2002, 2003, 2005, 2007, 2008
+   Copyright (C) 2001, 2002, 2003, 2005, 2007, 2008, 2009
    Free Software Foundation, Inc.
 
    Contributed by Daniel Berlin (dan@dberlin.org)
@@ -683,6 +683,10 @@ execute_stack_op (struct dwarf_expr_context *ctx,
 	  }
 	  break;
 
+	case DW_OP_call_frame_cfa:
+	  result = (ctx->get_frame_cfa) (ctx->baton);
+	  break;
+
 	case DW_OP_GNU_push_tls_address:
 	  /* Variable is at a constant offset in the thread-local
 	  storage block into the objfile for the current thread and
diff --git a/gdb/dwarf2expr.h b/gdb/dwarf2expr.h
index 5d9581c..97edf6c 100644
--- a/gdb/dwarf2expr.h
+++ b/gdb/dwarf2expr.h
@@ -1,6 +1,6 @@
 /* DWARF 2 Expression Evaluator.
 
-   Copyright (C) 2001, 2002, 2003, 2005, 2007, 2008
+   Copyright (C) 2001, 2002, 2003, 2005, 2007, 2008, 2009
    Free Software Foundation, Inc.
 
    Contributed by Daniel Berlin <dan@dberlin.org>.
@@ -55,6 +55,9 @@ struct dwarf_expr_context
      expression evaluation is complete.  */
   void (*get_frame_base) (void *baton, gdb_byte **start, size_t *length);
 
+  /* Return the CFA for the frame.  */
+  CORE_ADDR (*get_frame_cfa) (void *baton);
+
   /* Return the thread-local storage address for
      DW_OP_GNU_push_tls_address.  */
   CORE_ADDR (*get_tls_address) (void *baton, CORE_ADDR offset);
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index 080cd06..c7dc48e 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -1,6 +1,6 @@
 /* DWARF 2 location expression support for GDB.
 
-   Copyright (C) 2003, 2005, 2007, 2008 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
 
    Contributed by Daniel Jacobowitz, MontaVista Software, Inc.
 
@@ -35,6 +35,7 @@
 #include "elf/dwarf2.h"
 #include "dwarf2expr.h"
 #include "dwarf2loc.h"
+#include "dwarf2-frame.h"
 
 #include "gdb_string.h"
 #include "gdb_assert.h"
@@ -181,6 +182,13 @@ dwarf_expr_frame_base (void *baton, gdb_byte **start, size_t * length)
 	   SYMBOL_NATURAL_NAME (framefunc));
 }
 
+static CORE_ADDR
+dwarf_expr_frame_cfa (void *baton)
+{
+  struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
+  return dwarf2_frame_cfa (debaton->frame);
+}
+
 /* Using the objfile specified in BATON, find the address for the
    current thread's thread-local storage with offset OFFSET.  */
 static CORE_ADDR
@@ -222,6 +230,7 @@ dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame,
   ctx->read_reg = dwarf_expr_read_reg;
   ctx->read_mem = dwarf_expr_read_mem;
   ctx->get_frame_base = dwarf_expr_frame_base;
+  ctx->get_frame_cfa = dwarf_expr_frame_cfa;
   ctx->get_tls_address = dwarf_expr_tls_address;
 
   dwarf_expr_eval (ctx, data, size);
@@ -315,6 +324,15 @@ needs_frame_frame_base (void *baton, gdb_byte **start, size_t * length)
   nf_baton->needs_frame = 1;
 }
 
+/* CFA accesses require a frame.  */
+static CORE_ADDR
+needs_frame_frame_cfa (void *baton)
+{
+  struct needs_frame_baton *nf_baton = baton;
+  nf_baton->needs_frame = 1;
+  return 1;
+}
+
 /* Thread-local accesses do require a frame.  */
 static CORE_ADDR
 needs_frame_tls_address (void *baton, CORE_ADDR offset)
@@ -344,6 +362,7 @@ dwarf2_loc_desc_needs_frame (gdb_byte *data, unsigned short size,
   ctx->read_reg = needs_frame_read_reg;
   ctx->read_mem = needs_frame_read_mem;
   ctx->get_frame_base = needs_frame_frame_base;
+  ctx->get_frame_cfa = needs_frame_frame_cfa;
   ctx->get_tls_address = needs_frame_tls_address;
 
   dwarf_expr_eval (ctx, data, size);



More information about the Gdb-patches mailing list