keiths / rpms / gdb

Forked from rpms/gdb 2 days ago
Clone
638b7b7
http://sourceware.org/ml/gdb-patches/2009-06/msg00191.html
638b7b7
638b7b7
GCC developers would like to change GCC to emit DW_OP_call_frame_cfa,
638b7b7
as this would reduce the size of the generated debuginfo.
638b7b7
638b7b7
A prerequisite to this is that GDB understand this.  So, this patch
638b7b7
implements this feature.  This is PR 10224.
638b7b7
638b7b7
I'm interested in feedback on this.  I am not sure whether the
638b7b7
implementation of dwarf2_frame_cfa is ok.
638b7b7
638b7b7
No test case since at some point GCC will start generating this
638b7b7
(perhaps optionally -- but I feel certain we'll do it by default in
638b7b7
Fedora), and since it therefore seemed like a lot of work for little
638b7b7
payoff.
638b7b7
638b7b7
Tom
638b7b7
638b7b7
2009-06-08  Tom Tromey  <tromey@redhat.com>
638b7b7
638b7b7
	PR gdb/10224:
638b7b7
	* dwarf2loc.c: Include dwarf2-frame.h.
638b7b7
	(dwarf_expr_frame_cfa): New function.
638b7b7
	(dwarf2_evaluate_loc_desc): Initialize new field.
638b7b7
	(needs_frame_frame_cfa): New function.
638b7b7
	(dwarf2_loc_desc_needs_frame): Initialize new field.
638b7b7
	* dwarf2expr.h (struct dwarf_expr_context) <get_frame_cfa>: New
638b7b7
	field.
638b7b7
	* dwarf2expr.c (execute_stack_op) <DW_OP_call_frame_cfa>: New
638b7b7
	case.
638b7b7
	* dwarf2-frame.h (dwarf2_frame_cfa): Declare.
638b7b7
	* dwarf2-frame.c (no_get_frame_cfa): New function.
638b7b7
	(execute_stack_op): Initialize new field.
638b7b7
	(dwarf2_frame_cfa): New function.
638b7b7
638b7b7
[ Backported for Fedora Rawhide.  ]
638b7b7
638b7b7
--- ./gdb/dwarf2-frame.c	2009-06-12 11:12:51.000000000 +0200
638b7b7
+++ ./gdb/dwarf2-frame.c	2009-06-12 11:13:30.000000000 +0200
638b7b7
@@ -306,6 +306,13 @@ no_get_frame_base (void *baton, gdb_byte
638b7b7
 }
638b7b7
 
638b7b7
 static CORE_ADDR
638b7b7
+no_get_frame_cfa (void *baton)
638b7b7
+{
638b7b7
+  internal_error (__FILE__, __LINE__,
638b7b7
+		  _("Support for DW_OP_call_frame_cfa is unimplemented"));
638b7b7
+}
638b7b7
+
638b7b7
+static CORE_ADDR
638b7b7
 no_get_tls_address (void *baton, CORE_ADDR offset)
638b7b7
 {
638b7b7
   internal_error (__FILE__, __LINE__,
638b7b7
@@ -356,6 +363,7 @@ execute_stack_op (gdb_byte *exp, ULONGES
638b7b7
   ctx->read_reg = read_reg;
638b7b7
   ctx->read_mem = read_mem;
638b7b7
   ctx->get_frame_base = no_get_frame_base;
638b7b7
+  ctx->get_frame_cfa = no_get_frame_cfa;
638b7b7
   ctx->get_tls_address = no_get_tls_address;
638b7b7
 
638b7b7
   dwarf_expr_push (ctx, initial);
638b7b7
@@ -1221,6 +1229,13 @@ dwarf2_frame_base_address (struct frame_
638b7b7
   return cache->cfa;
638b7b7
 }
638b7b7
 
638b7b7
+CORE_ADDR
638b7b7
+dwarf2_frame_cfa (struct frame_info *this_frame)
638b7b7
+{
638b7b7
+  void *cache = NULL;
638b7b7
+  return dwarf2_frame_base_address (this_frame, &cache);
638b7b7
+}
638b7b7
+
638b7b7
 static const struct frame_base dwarf2_frame_base =
638b7b7
 {
638b7b7
   &dwarf2_frame_unwind,
638b7b7
--- ./gdb/dwarf2-frame.h	2009-01-03 06:57:51.000000000 +0100
638b7b7
+++ ./gdb/dwarf2-frame.h	2009-06-12 11:13:30.000000000 +0200
638b7b7
@@ -118,4 +118,8 @@ extern const struct frame_base *
638b7b7
 
638b7b7
 void dwarf2_frame_build_info (struct objfile *objfile);
638b7b7
 
638b7b7
+/* Compute the DWARF CFA for a frame.  */
638b7b7
+
638b7b7
+CORE_ADDR dwarf2_frame_cfa (struct frame_info *this_frame);
638b7b7
+
638b7b7
 #endif /* dwarf2-frame.h */
638b7b7
--- ./gdb/dwarf2expr.c	2009-06-12 11:12:51.000000000 +0200
638b7b7
+++ ./gdb/dwarf2expr.c	2009-06-12 11:13:44.000000000 +0200
638b7b7
@@ -697,6 +697,10 @@ execute_stack_op (struct dwarf_expr_cont
638b7b7
 	  }
638b7b7
 	  break;
638b7b7
 
638b7b7
+	case DW_OP_call_frame_cfa:
638b7b7
+	  result = (ctx->get_frame_cfa) (ctx->baton);
638b7b7
+	  break;
638b7b7
+
638b7b7
 	case DW_OP_GNU_push_tls_address:
638b7b7
 	  /* Variable is at a constant offset in the thread-local
638b7b7
 	  storage block into the objfile for the current thread and
638b7b7
--- ./gdb/dwarf2expr.h	2009-06-12 11:12:51.000000000 +0200
638b7b7
+++ ./gdb/dwarf2expr.h	2009-06-12 11:15:36.000000000 +0200
638b7b7
@@ -55,6 +55,9 @@ struct dwarf_expr_context
638b7b7
      expression evaluation is complete.  */
638b7b7
   void (*get_frame_base) (void *baton, gdb_byte **start, size_t *length);
638b7b7
 
638b7b7
+  /* Return the CFA for the frame.  */
638b7b7
+  CORE_ADDR (*get_frame_cfa) (void *baton);
638b7b7
+
638b7b7
   /* Return the thread-local storage address for
638b7b7
      DW_OP_GNU_push_tls_address.  */
638b7b7
   CORE_ADDR (*get_tls_address) (void *baton, CORE_ADDR offset);
638b7b7
--- ./gdb/dwarf2loc.c	2009-06-12 11:12:55.000000000 +0200
638b7b7
+++ ./gdb/dwarf2loc.c	2009-06-12 11:15:07.000000000 +0200
638b7b7
@@ -32,6 +32,7 @@
638b7b7
 #include "objfiles.h"
638b7b7
 #include "exceptions.h"
638b7b7
 #include "block.h"
638b7b7
+#include "dwarf2-frame.h"
638b7b7
 
638b7b7
 #include "elf/dwarf2.h"
638b7b7
 #include "dwarf2expr.h"
638b7b7
@@ -200,6 +201,13 @@ dwarf_expr_frame_base (void *baton, gdb_
638b7b7
 	   SYMBOL_PRINT_NAME (framefunc));
638b7b7
 }
638b7b7
 
638b7b7
+static CORE_ADDR
638b7b7
+dwarf_expr_frame_cfa (void *baton)
638b7b7
+{
638b7b7
+  struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
638b7b7
+  return dwarf2_frame_cfa (debaton->frame);
638b7b7
+}
638b7b7
+
638b7b7
 /* Using the objfile specified in BATON, find the address for the
638b7b7
    current thread's thread-local storage with offset OFFSET.  */
638b7b7
 static CORE_ADDR
638b7b7
@@ -286,6 +294,7 @@ dwarf_expr_prep_ctx (struct frame_info *
638b7b7
   ctx->read_reg = dwarf_expr_read_reg;
638b7b7
   ctx->read_mem = dwarf_expr_read_mem;
638b7b7
   ctx->get_frame_base = dwarf_expr_frame_base;
638b7b7
+  ctx->get_frame_cfa = dwarf_expr_frame_cfa;
638b7b7
   ctx->get_tls_address = dwarf_expr_tls_address;
638b7b7
   ctx->get_object_address = dwarf_expr_object_address;
638b7b7
 
638b7b7
@@ -439,6 +448,15 @@ needs_frame_frame_base (void *baton, gdb
638b7b7
   nf_baton->needs_frame = 1;
638b7b7
 }
638b7b7
 
638b7b7
+/* CFA accesses require a frame.  */
638b7b7
+static CORE_ADDR
638b7b7
+needs_frame_frame_cfa (void *baton)
638b7b7
+{
638b7b7
+  struct needs_frame_baton *nf_baton = baton;
638b7b7
+  nf_baton->needs_frame = 1;
638b7b7
+  return 1;
638b7b7
+}
638b7b7
+
638b7b7
 /* Thread-local accesses do require a frame.  */
638b7b7
 static CORE_ADDR
638b7b7
 needs_frame_tls_address (void *baton, CORE_ADDR offset)
638b7b7
@@ -468,6 +486,7 @@ dwarf2_loc_desc_needs_frame (gdb_byte *d
638b7b7
   ctx->read_reg = needs_frame_read_reg;
638b7b7
   ctx->read_mem = needs_frame_read_mem;
638b7b7
   ctx->get_frame_base = needs_frame_frame_base;
638b7b7
+  ctx->get_frame_cfa = needs_frame_frame_cfa;
638b7b7
   ctx->get_tls_address = needs_frame_tls_address;
638b7b7
 
638b7b7
   dwarf_expr_eval (ctx, data, size);