public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM]  archer-jankratochvil-entryval: entryvals
@ 2011-06-12 21:36 jkratoch
  0 siblings, 0 replies; only message in thread
From: jkratoch @ 2011-06-12 21:36 UTC (permalink / raw)
  To: archer-commits

The branch, archer-jankratochvil-entryval has been updated
       via  1b8fd50a2e42d78c90a9a3403bcec8dd43e6fefb (commit)
      from  e6b412e5ab0429151655f396e1ade25d3c17efdb (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email.

- Log -----------------------------------------------------------------
commit 1b8fd50a2e42d78c90a9a3403bcec8dd43e6fefb
Author: Jan Kratochvil <jan.kratochvil@redhat.com>
Date:   Sun Jun 12 23:36:17 2011 +0200

    entryvals

-----------------------------------------------------------------------

Summary of changes:
 gdb/dwarf2expr.c |    2 +-
 gdb/dwarf2expr.h |    3 +
 gdb/dwarf2loc.c  |  116 +++++++++++++++++++++++++++++++++++++++++-------------
 gdb/f-valprint.c |    3 +-
 gdb/findvar.c    |    5 +--
 gdb/printcmd.c   |   54 ++++++++++++++++++++++---
 gdb/stack.c      |   17 ++++++--
 gdb/symtab.h     |    5 ++
 gdb/value.c      |   11 +++++
 gdb/value.h      |   12 +++++-
 10 files changed, 182 insertions(+), 46 deletions(-)

First 500 lines of diff:
diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c
index e779de9..6f8d168 100644
--- a/gdb/dwarf2expr.c
+++ b/gdb/dwarf2expr.c
@@ -512,7 +512,7 @@ dwarf_block_to_regnum (const gdb_byte *buf, const gdb_byte *buf_end)
    *DEREF_SIZE_RETURN contains -1 for DW_OP_deref or the size from
    DW_OP_deref_size.  */
 
-static int
+int
 dwarf_block_to_regnum_deref (const gdb_byte *buf, const gdb_byte *buf_end,
 			     CORE_ADDR *deref_size_return)
 {
diff --git a/gdb/dwarf2expr.h b/gdb/dwarf2expr.h
index d889d2b..80035fd 100644
--- a/gdb/dwarf2expr.h
+++ b/gdb/dwarf2expr.h
@@ -251,4 +251,7 @@ void dwarf_expr_require_composition (const gdb_byte *, const gdb_byte *,
 
 int dwarf_block_to_regnum (const gdb_byte *buf, const gdb_byte *buf_end);
 
+int dwarf_block_to_regnum_deref (const gdb_byte *buf, const gdb_byte *buf_end,
+				 CORE_ADDR *deref_size_return);
+
 #endif /* dwarf2expr.h */
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index 4addfde..f074866 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -718,17 +718,16 @@ call_site_find_chain (struct gdbarch *gdbarch, CORE_ADDR caller_pc,
   return retval;
 }
 
-/* Using the frame specified in BATON return a stack entry evaluated for
+/* Using the callee FRAME return a stack entry evaluated for
    DW_TAG_GNU_call_site's REGNUM at the caller.  If DEREF_SIZE is not -1 then
    use DW_AT_GNU_call_site_data_value instead of DW_AT_GNU_call_site_value.
-   */
 
-static void
-dwarf_expr_regnum_entry_value (struct dwarf_expr_context *ctx, int regnum,
+   Always return non-NULL, throw NOT_FOUND_ERROR otherwise.  */
+
+static struct dwarf2_locexpr_baton *
+dwarf_expr_regnum_entry_value (struct frame_info *frame, int regnum,
 			       CORE_ADDR deref_size)
 {
-  struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) ctx->baton;
-  struct frame_info *frame = debaton->frame;
   CORE_ADDR func_addr = get_frame_func (frame);
   CORE_ADDR caller_pc;
   struct gdbarch *caller_gdbarch = frame_unwind_arch (frame);
@@ -739,8 +738,6 @@ dwarf_expr_regnum_entry_value (struct dwarf_expr_context *ctx, int regnum,
   struct dwarf2_locexpr_baton *dwarf_block;
   struct call_site_parameter *parameter;
   CORE_ADDR target_addr;
-  struct dwarf_expr_baton baton_local;
-  struct dwarf_expr_context saved_ctx;
 
   if (caller_frame == NULL)
     {
@@ -821,8 +818,24 @@ dwarf_expr_regnum_entry_value (struct dwarf_expr_context *ctx, int regnum,
       /* FIXME: Check the DEREF_SIZE value.  */
     }
 
-  /* Execute DWARF_BLOCK for CALLER_FRAME but with the same DWARF stack as
-     present in CTX.  */
+  return dwarf_block;
+}
+
+/* Execute DWARF_BLOCK for CALLER_FRAME but with the same DWARF stack as
+   present in CTX.  */
+
+static void
+dwarf_expr_push_regnum_entry_value (struct dwarf_expr_context *ctx, int regnum,
+				    CORE_ADDR deref_size)
+{
+  struct dwarf_expr_baton *debaton = ctx->baton;
+  struct frame_info *frame = debaton->frame;
+  struct frame_info *caller_frame = get_prev_frame (frame);
+  struct dwarf2_locexpr_baton *dwarf_block;
+  struct dwarf_expr_baton baton_local;
+  struct dwarf_expr_context saved_ctx;
+
+  dwarf_block = dwarf_expr_regnum_entry_value (frame, regnum, deref_size);
 
   baton_local.frame = caller_frame;
   baton_local.per_cu = dwarf_block->per_cu;
@@ -844,6 +857,7 @@ dwarf_expr_regnum_entry_value (struct dwarf_expr_context *ctx, int regnum,
   ctx->baton = saved_ctx.baton;
 }
 
+
 struct piece_closure
 {
   /* Reference count.  */
@@ -1642,12 +1656,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
     invalid_synthetic_pointer ();
 
   if (size == 0)
-    {
-      retval = allocate_value (type);
-      VALUE_LVAL (retval) = not_lval;
-      set_value_optimized_out (retval, 1);
-      return retval;
-    }
+    return allocate_optimized_out_value (type);
 
   baton.frame = frame;
   baton.per_cu = per_cu;
@@ -1668,7 +1677,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
   ctx->get_tls_address = dwarf_expr_tls_address;
   ctx->dwarf_call = dwarf_expr_dwarf_call;
   ctx->get_base_type = dwarf_expr_get_base_type;
-  ctx->push_regnum_entry_value = dwarf_expr_regnum_entry_value;
+  ctx->push_regnum_entry_value = dwarf_expr_push_regnum_entry_value;
 
   TRY_CATCH (ex, RETURN_MASK_ALL)
     {
@@ -1690,9 +1699,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
 	  if (info_verbose)
 	    exception_print (gdb_stdout, ex);
 
-	  retval = allocate_value (type);
-	  set_value_optimized_out (retval, 1);
-	  return retval;
+	  return allocate_optimized_out_value (type);
 	}
       else
 	throw_exception (ex);
@@ -1807,9 +1814,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
 
 	case DWARF_VALUE_OPTIMIZED_OUT:
 	  do_cleanups (value_chain);
-	  retval = allocate_value (type);
-	  VALUE_LVAL (retval) = not_lval;
-	  set_value_optimized_out (retval, 1);
+	  retval = allocate_optimized_out_value (type);
 	  break;
 
 	  /* DWARF_VALUE_IMPLICIT_POINTER was converted to a pieced
@@ -3316,6 +3321,7 @@ locexpr_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch,
    evaluator.  */
 const struct symbol_computed_ops dwarf2_locexpr_funcs = {
   locexpr_read_variable,
+  locexpr_read_variable,	/* read_variable_at_entry */
   locexpr_read_needs_frame,
   locexpr_describe_location,
   locexpr_tracepoint_var_ref
@@ -3338,11 +3344,7 @@ loclist_read_variable (struct symbol *symbol, struct frame_info *frame)
 
   data = dwarf2_find_location_expression (dlbaton, &size, pc);
   if (data == NULL)
-    {
-      val = allocate_value (SYMBOL_TYPE (symbol));
-      VALUE_LVAL (val) = not_lval;
-      set_value_optimized_out (val, 1);
-    }
+    val = allocate_optimized_out_value (SYMBOL_TYPE (symbol));
   else
     val = dwarf2_evaluate_loc_desc (SYMBOL_TYPE (symbol), frame, data, size,
 				    dlbaton->per_cu);
@@ -3350,6 +3352,63 @@ loclist_read_variable (struct symbol *symbol, struct frame_info *frame)
   return val;
 }
 
+static struct value *
+value_of_regnum_entry_value (struct type *type, struct frame_info *frame,
+			     int regnum, CORE_ADDR deref_size)
+{
+  struct dwarf2_locexpr_baton *dwarf_block;
+  struct frame_info *caller_frame = get_prev_frame (frame);
+  gdb_byte *data;
+
+  dwarf_block = dwarf_expr_regnum_entry_value (frame, regnum, deref_size);
+
+  /* DW_AT_GNU_call_site_value is a DWARF expression, not a DWARF
+     location.  */
+  data = alloca (dwarf_block->size + 1);
+  memcpy (data, dwarf_block->data, dwarf_block->size);
+  data[dwarf_block->size] = DW_OP_stack_value;
+
+  return dwarf2_evaluate_loc_desc (type, caller_frame, data,
+				   dwarf_block->size + 1, dwarf_block->per_cu);
+}
+
+/* Read variable by like loclist_read_variable at FRAME's function entry.  */
+
+static struct value *
+loclist_read_variable_at_entry (struct symbol *symbol, struct frame_info *frame)
+{
+  struct dwarf2_loclist_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol);
+  struct value *val;
+  const gdb_byte *data;
+  size_t size;
+  int regnum;
+  CORE_ADDR deref_size;
+  CORE_ADDR pc;
+
+  if (frame == NULL || !get_frame_func_if_available (frame, &pc))
+    return allocate_optimized_out_value (SYMBOL_TYPE (symbol));
+
+  data = dwarf2_find_location_expression (dlbaton, &size, pc);
+  if (data == NULL)
+    return allocate_optimized_out_value (SYMBOL_TYPE (symbol));
+
+  regnum = dwarf_block_to_regnum (data, data + size);
+  if (regnum != -1)
+    return value_of_regnum_entry_value (SYMBOL_TYPE (symbol), frame, regnum,
+					-1);
+
+  regnum = dwarf_block_to_regnum_deref (data, data + size, &deref_size);
+  if (regnum != -1)
+    {
+      if (deref_size == -1)
+	deref_size = dwarf2_per_cu_addr_size (dlbaton->per_cu);
+      return value_of_regnum_entry_value (SYMBOL_TYPE (symbol), frame, regnum,
+					  deref_size);
+    }
+
+  return allocate_optimized_out_value (SYMBOL_TYPE (symbol));
+}
+
 /* Return non-zero iff we need a frame to evaluate SYMBOL.  */
 static int
 loclist_read_needs_frame (struct symbol *symbol)
@@ -3468,6 +3527,7 @@ loclist_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch,
    evaluator and location lists.  */
 const struct symbol_computed_ops dwarf2_loclist_funcs = {
   loclist_read_variable,
+  loclist_read_variable_at_entry,
   loclist_read_needs_frame,
   loclist_describe_location,
   loclist_tracepoint_var_ref
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c
index 3280ddc..1d1c40f 100644
--- a/gdb/f-valprint.c
+++ b/gdb/f-valprint.c
@@ -596,7 +596,8 @@ info_common_command (char *comname, int from_tty)
 
       while (entry != NULL)
 	{
-	  print_variable_and_value (NULL, entry->symbol, fi, gdb_stdout, 0);
+	  print_variable_and_value (NULL, entry->symbol, fi, gdb_stdout, 0,
+				    PVAVD_IS_NOT_ARGUMENT);
 	  entry = entry->next;
 	}
     }
diff --git a/gdb/findvar.c b/gdb/findvar.c
index 2b361ef..a700c02 100644
--- a/gdb/findvar.c
+++ b/gdb/findvar.c
@@ -577,10 +577,7 @@ read_var_value (struct symbol *var, struct frame_info *frame)
       break;
 
     case LOC_OPTIMIZED_OUT:
-      v = allocate_value_lazy (type);
-      VALUE_LVAL (v) = not_lval;
-      set_value_optimized_out (v, 1);
-      return v;
+      return allocate_optimized_out_value (type);
 
     default:
       error (_("Cannot look up value of a botched symbol."));
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index f1ebb7e..90e9bde 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -1944,27 +1944,67 @@ clear_dangling_display_expressions (struct so_list *solib)
 void
 print_variable_and_value (const char *name, struct symbol *var,
 			  struct frame_info *frame,
-			  struct ui_file *stream, int indent)
+			  struct ui_file *stream, int indent,
+			  enum print_argument print_argument)
 {
   volatile struct gdb_exception except;
 
   if (!name)
     name = SYMBOL_PRINT_NAME (var);
 
-  fprintf_filtered (stream, "%s%s = ", n_spaces (2 * indent), name);
   TRY_CATCH (except, RETURN_MASK_ERROR)
     {
-      struct value *val;
+      struct value *val, *entryval = NULL;
       struct value_print_options opts;
 
       val = read_var_value (var, frame);
       get_user_print_options (&opts);
-      common_val_print (val, stream, indent, &opts, current_language);
+
+      if (print_argument != PVAVD_IS_NOT_ARGUMENT
+	  && SYMBOL_CLASS (var) == LOC_COMPUTED
+	  && (SYMBOL_COMPUTED_OPS (var)->read_variable_at_entry
+	      != SYMBOL_COMPUTED_OPS (var)->read_variable))
+	{
+	  const struct symbol_computed_ops *ops;
+	  unsigned len = TYPE_LENGTH (value_type (val));
+	  volatile struct gdb_exception entryval_ex;
+
+	  ops = SYMBOL_COMPUTED_OPS (var);
+
+	  TRY_CATCH (entryval_ex, RETURN_MASK_ERROR)
+	    {
+	      entryval = ops->read_variable_at_entry (var, frame);
+	    }
+
+	  if (entryval_ex.reason < 0 || value_optimized_out (entryval))
+	    entryval = NULL;
+	  else
+	    {
+	      if (!value_optimized_out (val) && value_lazy (entryval))
+		value_fetch_lazy (entryval);
+	      if (!value_optimized_out (val)
+		  && value_available_contents_eq (val, 0, entryval, 0, len))
+		entryval = NULL;
+	    }
+	}
+
+      if (print_argument != PVAVD_ARGUMENT_PRINT_ENTRYVAL_ONLY)
+	{
+	  fprintf_filtered (stream, "%s%s = ", n_spaces (2 * indent), name);
+	  common_val_print (val, stream, indent, &opts, current_language);
+	  fputc_filtered ('\n', stream);
+	}
+      if (entryval)
+	{
+	  fprintf_filtered (stream, "%s%s@entry = ", n_spaces (2 * indent),
+			    name);
+	  common_val_print (entryval, stream, indent, &opts, current_language);
+	  fputc_filtered ('\n', stream);
+	}
     }
   if (except.reason < 0)
-    fprintf_filtered(stream, "<error reading variable %s (%s)>", name,
-		     except.message);
-  fprintf_filtered (stream, "\n");
+    fprintf_filtered (stream, "%s%s = <error reading variable %s (%s)>\n",
+		      n_spaces (2 * indent), name, name, except.message);
 }
 
 /* printf "printf format string" ARG to STREAM.  */
diff --git a/gdb/stack.c b/gdb/stack.c
index 7d50435..e18c9e5 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -1611,6 +1611,7 @@ struct print_variable_and_value_data
   int num_tabs;
   struct ui_file *stream;
   int values_printed;
+  enum print_argument print_argument;
 };
 
 /* The callback for the locals and args iterators.  */
@@ -1622,13 +1623,13 @@ do_print_variable_and_value (const char *print_name,
 {
   struct print_variable_and_value_data *p = cb_data;
 
-  print_variable_and_value (print_name, sym,
-			    p->frame, p->stream, p->num_tabs);
+  print_variable_and_value (print_name, sym, p->frame, p->stream, p->num_tabs,
+			    p->print_argument);
   p->values_printed = 1;
 }
 
 static void
-print_frame_local_vars (struct frame_info *frame, int num_tabs,
+print_frame_local_vars (struct frame_info *frame, int from_frame,
 			struct ui_file *stream)
 {
   struct print_variable_and_value_data cb_data;
@@ -1650,10 +1651,17 @@ print_frame_local_vars (struct frame_info *frame, int num_tabs,
     }
 
   cb_data.frame = frame;
-  cb_data.num_tabs = 4 * num_tabs;
+  cb_data.num_tabs = from_frame ? 4 : 0;
   cb_data.stream = stream;
   cb_data.values_printed = 0;
 
+  if (from_frame)
+    {
+      cb_data.print_argument = PVAVD_ARGUMENT_PRINT_ENTRYVAL_ONLY;
+      iterate_over_block_arg_vars (block, do_print_variable_and_value, &cb_data);
+    }
+
+  cb_data.print_argument = PVAVD_IS_NOT_ARGUMENT;
   iterate_over_block_local_vars (block,
 				 do_print_variable_and_value,
 				 &cb_data);
@@ -1813,6 +1821,7 @@ print_frame_arg_vars (struct frame_info *frame, struct ui_file *stream)
   cb_data.stream = gdb_stdout;
   cb_data.values_printed = 0;
 
+  cb_data.print_argument = PVAVD_ARGUMENT_PRINT_BOTH;
   iterate_over_block_arg_vars (SYMBOL_BLOCK_VALUE (func),
 			       do_print_variable_and_value, &cb_data);
 
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 12f52a2..2a3a62e 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -532,6 +532,11 @@ struct symbol_computed_ops
   struct value *(*read_variable) (struct symbol * symbol,
 				  struct frame_info * frame);
 
+  /* Like read_variable but for the first instruction of a function of FRAME.
+     Return NULL if such value is not known.  */
+  struct value *(*read_variable_at_entry) (struct symbol *symbol,
+					   struct frame_info *frame);
+
   /* Return non-zero if we need a frame to find the value of the SYMBOL.  */
   int (*read_needs_frame) (struct symbol * symbol);
 
diff --git a/gdb/value.c b/gdb/value.c
index ccd29c8..6b77522 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -728,6 +728,17 @@ allocate_computed_value (struct type *type,
   return v;
 }
 
+struct value *
+allocate_optimized_out_value (struct type *type)
+{
+  struct value *retval = allocate_value (type);
+
+  VALUE_LVAL (retval) = not_lval;
+  set_value_optimized_out (retval, 1);
+
+  return retval;
+}
+
 /* Accessor methods.  */
 
 struct value *
diff --git a/gdb/value.h b/gdb/value.h
index 65d0a02..41445da 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -207,6 +207,8 @@ extern struct value *allocate_computed_value (struct type *type,
                                               struct lval_funcs *funcs,
                                               void *closure);
 
+extern struct value *allocate_optimized_out_value (struct type *type);
+
 /* If VALUE is lval_computed, return its lval_funcs structure.  */
 
 extern struct lval_funcs *value_computed_funcs (struct value *value);
@@ -798,11 +800,19 @@ extern int val_print_string (struct type *elttype, const char *encoding,
 			     struct ui_file *stream,
 			     const struct value_print_options *options);
 
+enum print_argument
+{
+  PVAVD_IS_NOT_ARGUMENT,
+  PVAVD_ARGUMENT_PRINT_ENTRYVAL_ONLY,
+  PVAVD_ARGUMENT_PRINT_BOTH,
+};
+
 extern void print_variable_and_value (const char *name,
 				      struct symbol *var,
 				      struct frame_info *frame,
 				      struct ui_file *stream,
-				      int indent);
+				      int indent,
+				      enum print_argument print_argument);
 
 extern int check_field (struct type *, const char *);
 


hooks/post-receive
--
Repository for Project Archer.


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2011-06-12 21:36 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-06-12 21:36 [SCM] archer-jankratochvil-entryval: entryvals jkratoch

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).