[gdb/f17] Support DW_OP_GNU_parameter_ref for -O2 -g inferiors (BZ 827375).

Jan Kratochvil jankratochvil at fedoraproject.org
Thu Jun 14 07:41:58 UTC 2012


commit ac0dd8df9b7c279261001f78485cbf2e4361c27f
Author: Jan Kratochvil <jan.kratochvil at redhat.com>
Date:   Thu Jun 14 09:41:53 2012 +0200

    Support DW_OP_GNU_parameter_ref for -O2 -g inferiors (BZ 827375).

 gdb-parameterref-1of2.patch |  426 +++++++++++++++++++++
 gdb-parameterref-2of2.patch |  876 +++++++++++++++++++++++++++++++++++++++++++
 gdb.spec                    |   11 +-
 3 files changed, 1312 insertions(+), 1 deletions(-)
---
diff --git a/gdb-parameterref-1of2.patch b/gdb-parameterref-1of2.patch
new file mode 100644
index 0000000..6fa7b3d
--- /dev/null
+++ b/gdb-parameterref-1of2.patch
@@ -0,0 +1,426 @@
+http://sourceware.org/ml/gdb-patches/2012-06/msg00458.html
+Subject: [patch 1/2] Generalize call_site.parameter key ("code cleanup")
+
+Hi,
+
+previously parameter could be identified either via DW_OP_reg or via
+DW_OP_fbreg (both in DW_AT_location).  As [patch 2/2] adds new identification
+via DW_AT_abstract_origin generalize this two state deciding into more general
+enum.
+
+
+Thanks,
+Jan
+
+
+gdb/
+2012-06-14  Jan Kratochvil  <jan.kratochvil at redhat.com>
+
+	Code cleanup: Generalize call_site.parameter key.
+	* dwarf2expr.c (execute_stack_op) <DW_OP_GNU_entry_value>: Remove
+	variable dwarf_reg.  New variable kind_u.  Update parameters to
+	push_dwarf_reg_entry_value.
+	(ctx_no_push_dwarf_reg_entry_value): Update parameters.
+	* dwarf2expr.h (enum call_site_parameter_kind)
+	(union call_site_parameter_u): Forward declarations.
+	(struct dwarf_expr_context_funcs): Update parameters and their
+	description for push_dwarf_reg_entry_value.
+	(ctx_no_push_dwarf_reg_entry_value): Update parameters.
+	* dwarf2loc.c (call_site_parameter_matches): New function.
+	(dwarf_expr_reg_to_entry_parameter): Update parameters and their
+	description.  Use call_site_parameter_matches.
+	(dwarf_expr_push_dwarf_reg_entry_value, value_of_dwarf_reg_entry):
+	Update parameters and their description.
+	(value_of_dwarf_block_entry): Remove variables dwarf_reg and fb_offset.
+	New variable kind_u.  Adjust the caller for updated parameters.
+	(needs_dwarf_reg_entry_value): Update parameters.
+	* dwarf2read.c (read_call_site_scope): New variable loc.  Use it
+	instead of attr.  Update for the changed fields of struct
+	call_site_parameter.
+	* gdbtypes.h: Include dwarf2expr.h.
+	(enum call_site_parameter_kind): New.
+	(struct call_site.parameter): New field kind.  Wrap dwarf_reg and
+	fb_offset into new union u.
+
+Index: gdb-7.4.50.20120120/gdb/dwarf2expr.c
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/dwarf2expr.c	2012-06-14 08:55:44.000000000 +0200
++++ gdb-7.4.50.20120120/gdb/dwarf2expr.c	2012-06-14 08:59:51.223967311 +0200
+@@ -1349,33 +1349,35 @@ execute_stack_op (struct dwarf_expr_cont
+ 	case DW_OP_GNU_entry_value:
+ 	  {
+ 	    ULONGEST len;
+-	    int dwarf_reg;
+ 	    CORE_ADDR deref_size;
++	    union call_site_parameter_u kind_u;
+ 
+ 	    op_ptr = read_uleb128 (op_ptr, op_end, &len);
+ 	    if (op_ptr + len > op_end)
+ 	      error (_("DW_OP_GNU_entry_value: too few bytes available."));
+ 
+-	    dwarf_reg = dwarf_block_to_dwarf_reg (op_ptr, op_ptr + len);
+-	    if (dwarf_reg != -1)
++	    kind_u.dwarf_reg = dwarf_block_to_dwarf_reg (op_ptr, op_ptr + len);
++	    if (kind_u.dwarf_reg != -1)
+ 	      {
+ 		op_ptr += len;
+-		ctx->funcs->push_dwarf_reg_entry_value (ctx, dwarf_reg,
+-							0 /* unused */,
++		ctx->funcs->push_dwarf_reg_entry_value (ctx,
++						  CALL_SITE_PARAMETER_DWARF_REG,
++							kind_u,
+ 							-1 /* deref_size */);
+ 		goto no_push;
+ 	      }
+ 
+-	    dwarf_reg = dwarf_block_to_dwarf_reg_deref (op_ptr, op_ptr + len,
+-							&deref_size);
+-	    if (dwarf_reg != -1)
++	    kind_u.dwarf_reg = dwarf_block_to_dwarf_reg_deref (op_ptr,
++							       op_ptr + len,
++							       &deref_size);
++	    if (kind_u.dwarf_reg != -1)
+ 	      {
+ 		if (deref_size == -1)
+ 		  deref_size = ctx->addr_size;
+ 		op_ptr += len;
+-		ctx->funcs->push_dwarf_reg_entry_value (ctx, dwarf_reg,
+-							0 /* unused */,
+-							deref_size);
++		ctx->funcs->push_dwarf_reg_entry_value (ctx,
++						  CALL_SITE_PARAMETER_DWARF_REG,
++							kind_u, deref_size);
+ 		goto no_push;
+ 	      }
+ 
+@@ -1532,7 +1534,8 @@ ctx_no_get_base_type (struct dwarf_expr_
+ 
+ void
+ ctx_no_push_dwarf_reg_entry_value (struct dwarf_expr_context *ctx,
+-				   int dwarf_reg, CORE_ADDR fb_offset,
++				   enum call_site_parameter_kind kind,
++				   union call_site_parameter_u kind_u,
+ 				   int deref_size)
+ {
+   internal_error (__FILE__, __LINE__,
+Index: gdb-7.4.50.20120120/gdb/dwarf2expr.h
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/dwarf2expr.h	2012-06-14 08:55:44.000000000 +0200
++++ gdb-7.4.50.20120120/gdb/dwarf2expr.h	2012-06-14 08:55:59.937479777 +0200
+@@ -24,6 +24,8 @@
+ #define DWARF2EXPR_H
+ 
+ struct dwarf_expr_context;
++enum call_site_parameter_kind;
++union call_site_parameter_u;
+ 
+ /* Virtual method table for struct dwarf_expr_context below.  */
+ 
+@@ -63,14 +65,12 @@ struct dwarf_expr_context_funcs
+   struct type *(*get_base_type) (struct dwarf_expr_context *ctx, size_t die);
+ 
+   /* Push on DWARF stack an entry evaluated for DW_TAG_GNU_call_site's
+-     DWARF_REG/FB_OFFSET at the caller of specified BATON.  If DWARF register
+-     number DWARF_REG specifying the push_dwarf_reg_entry_value parameter is
+-     not -1 FB_OFFSET is ignored.  Otherwise FB_OFFSET specifies stack
+-     parameter offset against caller's stack pointer (which equals the callee's
+-     frame base).  If DEREF_SIZE is not -1 then use
+-     DW_AT_GNU_call_site_data_value instead of DW_AT_GNU_call_site_value.  */
++     parameter matching KIND and KIND_U at the caller of specified BATON.
++     If DEREF_SIZE is not -1 then use DW_AT_GNU_call_site_data_value instead of
++     DW_AT_GNU_call_site_value.  */
+   void (*push_dwarf_reg_entry_value) (struct dwarf_expr_context *ctx,
+-				      int dwarf_reg, CORE_ADDR fb_offset,
++				      enum call_site_parameter_kind kind,
++				      union call_site_parameter_u kind_u,
+ 				      int deref_size);
+ 
+   /* Not yet implemented.  */
+@@ -276,7 +276,8 @@ CORE_ADDR ctx_no_get_tls_address (void *
+ void ctx_no_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset);
+ struct type *ctx_no_get_base_type (struct dwarf_expr_context *ctx, size_t die);
+ void ctx_no_push_dwarf_reg_entry_value (struct dwarf_expr_context *ctx,
+-					int dwarf_reg, CORE_ADDR fb_offset,
++					enum call_site_parameter_kind kind,
++					union call_site_parameter_u kind_u,
+ 					int deref_size);
+ 
+ int dwarf_block_to_dwarf_reg (const gdb_byte *buf, const gdb_byte *buf_end);
+Index: gdb-7.4.50.20120120/gdb/dwarf2loc.c
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/dwarf2loc.c	2012-06-14 08:55:44.000000000 +0200
++++ gdb-7.4.50.20120120/gdb/dwarf2loc.c	2012-06-14 08:55:59.938479774 +0200
+@@ -905,16 +905,34 @@ call_site_find_chain (struct gdbarch *gd
+   return retval;
+ }
+ 
+-/* Fetch call_site_parameter from caller matching the parameters.  FRAME is for
+-   callee.  See DWARF_REG and FB_OFFSET description at struct
+-   dwarf_expr_context_funcs->push_dwarf_reg_entry_value.
++/* Return 1 if KIND and KIND_U match PARAMETER.  Return 0 otherwise.  */
++
++static int
++call_site_parameter_matches (struct call_site_parameter *parameter,
++			     enum call_site_parameter_kind kind,
++			     union call_site_parameter_u kind_u)
++{
++  if (kind == parameter->kind)
++    switch (kind)
++      {
++      case CALL_SITE_PARAMETER_DWARF_REG:
++	return kind_u.dwarf_reg == parameter->u.dwarf_reg;
++      case CALL_SITE_PARAMETER_FB_OFFSET:
++	return kind_u.fb_offset == parameter->u.fb_offset;
++      }
++  return 0;
++}
++
++/* Fetch call_site_parameter from caller matching KIND and KIND_U.
++   FRAME is for callee.
+ 
+    Function always returns non-NULL, it throws NO_ENTRY_VALUE_ERROR
+    otherwise.  */
+ 
+ static struct call_site_parameter *
+-dwarf_expr_reg_to_entry_parameter (struct frame_info *frame, int dwarf_reg,
+-				   CORE_ADDR fb_offset,
++dwarf_expr_reg_to_entry_parameter (struct frame_info *frame,
++				   enum call_site_parameter_kind kind,
++				   union call_site_parameter_u kind_u,
+ 				   struct dwarf2_per_cu_data **per_cu_return)
+ {
+   CORE_ADDR func_addr = get_frame_func (frame);
+@@ -979,12 +997,7 @@ dwarf_expr_reg_to_entry_parameter (struc
+   for (iparams = 0; iparams < call_site->parameter_count; iparams++)
+     {
+       parameter = &call_site->parameter[iparams];
+-      if (parameter->dwarf_reg == -1 && dwarf_reg == -1)
+-	{
+-	  if (parameter->fb_offset == fb_offset)
+-	    break;
+-	}
+-      else if (parameter->dwarf_reg == dwarf_reg)
++      if (call_site_parameter_matches (parameter, kind, kind_u))
+ 	break;
+     }
+   if (iparams == call_site->parameter_count)
+@@ -1041,17 +1054,17 @@ dwarf_entry_parameter_to_value (struct c
+   return dwarf2_evaluate_loc_desc (type, caller_frame, data, size + 1, per_cu);
+ }
+ 
+-/* Execute call_site_parameter's DWARF block matching DEREF_SIZE for caller of
+-   the CTX's frame.  CTX must be of dwarf_expr_ctx_funcs kind.  See DWARF_REG
+-   and FB_OFFSET description at struct
+-   dwarf_expr_context_funcs->push_dwarf_reg_entry_value.
++/* Execute DWARF block of call_site_parameter which matches KIND and KIND_U.
++   Choose DEREF_SIZE value of that parameter.  Search caller of the CTX's
++   frame.  CTX must be of dwarf_expr_ctx_funcs kind.
+ 
+    The CTX caller can be from a different CU - per_cu_dwarf_call implementation
+    can be more simple as it does not support cross-CU DWARF executions.  */
+ 
+ static void
+ dwarf_expr_push_dwarf_reg_entry_value (struct dwarf_expr_context *ctx,
+-				       int dwarf_reg, CORE_ADDR fb_offset,
++				       enum call_site_parameter_kind kind,
++				       union call_site_parameter_u kind_u,
+ 				       int deref_size)
+ {
+   struct dwarf_expr_baton *debaton;
+@@ -1068,7 +1081,7 @@ dwarf_expr_push_dwarf_reg_entry_value (s
+   frame = debaton->frame;
+   caller_frame = get_prev_frame (frame);
+ 
+-  parameter = dwarf_expr_reg_to_entry_parameter (frame, dwarf_reg, fb_offset,
++  parameter = dwarf_expr_reg_to_entry_parameter (frame, kind, kind_u,
+ 						 &caller_per_cu);
+   data_src = deref_size == -1 ? parameter->value : parameter->data_value;
+   size = deref_size == -1 ? parameter->value_size : parameter->data_value_size;
+@@ -1238,17 +1251,17 @@ static const struct lval_funcs entry_dat
+   entry_data_value_free_closure
+ };
+ 
+-/* Read parameter of TYPE at (callee) FRAME's function entry.  DWARF_REG and
+-   FB_OFFSET are used to match DW_AT_location at the caller's
+-   DW_TAG_GNU_call_site_parameter.  See DWARF_REG and FB_OFFSET description at
+-   struct dwarf_expr_context_funcs->push_dwarf_reg_entry_value.
++/* Read parameter of TYPE at (callee) FRAME's function entry.  KIND and KIND_U
++   are used to match DW_AT_location at the caller's
++   DW_TAG_GNU_call_site_parameter.
+ 
+    Function always returns non-NULL value.  It throws NO_ENTRY_VALUE_ERROR if it
+    cannot resolve the parameter for any reason.  */
+ 
+ static struct value *
+ value_of_dwarf_reg_entry (struct type *type, struct frame_info *frame,
+-			  int dwarf_reg, CORE_ADDR fb_offset)
++			  enum call_site_parameter_kind kind,
++			  union call_site_parameter_u kind_u)
+ {
+   struct type *checked_type = check_typedef (type);
+   struct type *target_type = TYPE_TARGET_TYPE (checked_type);
+@@ -1258,7 +1271,7 @@ value_of_dwarf_reg_entry (struct type *t
+   struct dwarf2_per_cu_data *caller_per_cu;
+   CORE_ADDR addr;
+ 
+-  parameter = dwarf_expr_reg_to_entry_parameter (frame, dwarf_reg, fb_offset,
++  parameter = dwarf_expr_reg_to_entry_parameter (frame, kind, kind_u,
+ 						 &caller_per_cu);
+ 
+   outer_val = dwarf_entry_parameter_to_value (parameter, -1 /* deref_size */,
+@@ -1310,15 +1323,16 @@ static struct value *
+ value_of_dwarf_block_entry (struct type *type, struct frame_info *frame,
+ 			    const gdb_byte *block, size_t block_len)
+ {
+-  int dwarf_reg;
+-  CORE_ADDR fb_offset;
+-
+-  dwarf_reg = dwarf_block_to_dwarf_reg (block, block + block_len);
+-  if (dwarf_reg != -1)
+-    return value_of_dwarf_reg_entry (type, frame, dwarf_reg, 0 /* unused */);
++  union call_site_parameter_u kind_u;
+ 
+-  if (dwarf_block_to_fb_offset (block, block + block_len, &fb_offset))
+-    return value_of_dwarf_reg_entry (type, frame, -1, fb_offset);
++  kind_u.dwarf_reg = dwarf_block_to_dwarf_reg (block, block + block_len);
++  if (kind_u.dwarf_reg != -1)
++    return value_of_dwarf_reg_entry (type, frame, CALL_SITE_PARAMETER_DWARF_REG,
++				     kind_u);
++
++  if (dwarf_block_to_fb_offset (block, block + block_len, &kind_u.fb_offset))
++    return value_of_dwarf_reg_entry (type, frame, CALL_SITE_PARAMETER_FB_OFFSET,
++                                     kind_u);
+ 
+   /* This can normally happen - throw NO_ENTRY_VALUE_ERROR to get the message
+      suppressed during normal operation.  The expression can be arbitrary if
+@@ -2391,7 +2405,8 @@ needs_frame_dwarf_call (struct dwarf_exp
+ 
+ static void
+ needs_dwarf_reg_entry_value (struct dwarf_expr_context *ctx,
+-			     int dwarf_reg, CORE_ADDR fb_offset, int deref_size)
++			     enum call_site_parameter_kind kind,
++			     union call_site_parameter_u kind_u, int deref_size)
+ {
+   struct needs_frame_baton *nf_baton = ctx->baton;
+ 
+Index: gdb-7.4.50.20120120/gdb/dwarf2read.c
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/dwarf2read.c	2012-06-14 08:55:46.000000000 +0200
++++ gdb-7.4.50.20120120/gdb/dwarf2read.c	2012-06-14 08:58:31.874143194 +0200
+@@ -6368,6 +6368,7 @@ read_call_site_scope (struct die_info *d
+     {
+       struct dwarf2_locexpr_baton *dlbaton;
+       struct call_site_parameter *parameter;
++      struct attribute *loc;
+ 
+       if (child_die->tag != DW_TAG_GNU_call_site_parameter)
+ 	{
+@@ -6381,8 +6382,8 @@ read_call_site_scope (struct die_info *d
+       /* DW_AT_location specifies the register number.  Value of the data
+ 	 assumed for the register is contained in DW_AT_GNU_call_site_value.  */
+ 
+-      attr = dwarf2_attr (child_die, DW_AT_location, cu);
+-      if (!attr || !attr_form_is_block (attr))
++      loc = dwarf2_attr (child_die, DW_AT_location, cu);
++      if (loc == NULL || !attr_form_is_block (loc))
+ 	{
+ 	  complaint (&symfile_complaints,
+ 		     _("No DW_FORM_block* DW_AT_location for "
+@@ -6390,19 +6391,26 @@ read_call_site_scope (struct die_info *d
+ 		     child_die->offset, objfile->name);
+ 	  continue;
+ 	}
+-      parameter->dwarf_reg = dwarf_block_to_dwarf_reg (DW_BLOCK (attr)->data,
+-				 &DW_BLOCK (attr)->data[DW_BLOCK (attr)->size]);
+-      if (parameter->dwarf_reg == -1
+-	  && !dwarf_block_to_sp_offset (gdbarch, DW_BLOCK (attr)->data,
+-				  &DW_BLOCK (attr)->data[DW_BLOCK (attr)->size],
+-					&parameter->fb_offset))
++      else
+ 	{
+-	  complaint (&symfile_complaints,
+-		     _("Only single DW_OP_reg or DW_OP_fbreg is supported "
+-		       "for DW_FORM_block* DW_AT_location for "
+-		       "DW_TAG_GNU_call_site child DIE 0x%x [in module %s]"),
+-		     child_die->offset, objfile->name);
+-	  continue;
++	  parameter->u.dwarf_reg = dwarf_block_to_dwarf_reg
++	    (DW_BLOCK (loc)->data, &DW_BLOCK (loc)->data[DW_BLOCK (loc)->size]);
++	  if (parameter->u.dwarf_reg != -1)
++	    parameter->kind = CALL_SITE_PARAMETER_DWARF_REG;
++	  else if (dwarf_block_to_sp_offset (gdbarch, DW_BLOCK (loc)->data,
++				    &DW_BLOCK (loc)->data[DW_BLOCK (loc)->size],
++					     &parameter->u.fb_offset))
++	    parameter->kind = CALL_SITE_PARAMETER_FB_OFFSET;
++	  else
++	    {
++	      complaint (&symfile_complaints,
++			 _("Only single DW_OP_reg or DW_OP_fbreg is supported "
++			   "for DW_FORM_block* DW_AT_location is supported for "
++			   "DW_TAG_GNU_call_site child DIE 0x%x "
++			   "[in module %s]"),
++			 child_die->offset, objfile->name);
++	      continue;
++	    }
+ 	}
+ 
+       attr = dwarf2_attr (child_die, DW_AT_GNU_call_site_value, cu);
+Index: gdb-7.4.50.20120120/gdb/gdbtypes.h
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/gdbtypes.h	2012-06-14 08:55:45.000000000 +0200
++++ gdb-7.4.50.20120120/gdb/gdbtypes.h	2012-06-14 08:55:59.943479763 +0200
+@@ -23,6 +23,7 @@
+ #define GDBTYPES_H 1
+ 
+ #include "hashtab.h"
++#include "dwarf2expr.h"
+ 
+ /* Forward declarations for prototypes.  */
+ struct field;
+@@ -1010,6 +1011,17 @@ struct func_type
+     struct call_site *tail_call_list;
+   };
+ 
++/* struct call_site_parameter can be referenced in callees by several ways.  */
++
++enum call_site_parameter_kind
++{
++  /* Use field call_site_parameter.u.dwarf_reg.  */
++  CALL_SITE_PARAMETER_DWARF_REG,
++
++  /* Use field call_site_parameter.u.fb_offset.  */
++  CALL_SITE_PARAMETER_FB_OFFSET
++};
++
+ /* A place where a function gets called from, represented by
+    DW_TAG_GNU_call_site.  It can be looked up from symtab->call_site_htab.  */
+ 
+@@ -1043,15 +1055,19 @@ struct call_site
+     /* Describe DW_TAG_GNU_call_site's DW_TAG_formal_parameter.  */
+     struct call_site_parameter
+       {
+-	/* DW_TAG_formal_parameter's DW_AT_location's DW_OP_regX as DWARF
+-	   register number, for register passed parameters.  If -1 then use
+-	   fb_offset.  */
+-	int dwarf_reg;
+-
+-	/* Offset from the callee's frame base, for stack passed parameters.
+-	   This equals offset from the caller's stack pointer.  Valid only if
+-	   DWARF_REGNUM is -1.  */
+-	CORE_ADDR fb_offset;
++	ENUM_BITFIELD (call_site_parameter_kind) kind : 2;
++
++	union call_site_parameter_u
++	  {
++	    /* DW_TAG_formal_parameter's DW_AT_location's DW_OP_regX as DWARF
++	       register number, for register passed parameters.  */
++	    int dwarf_reg;
++
++	    /* Offset from the callee's frame base, for stack passed parameters.
++	       This equals offset from the caller's stack pointer.  */
++	    CORE_ADDR fb_offset;
++	  }
++	u;
+ 
+ 	/* DW_TAG_formal_parameter's DW_AT_GNU_call_site_value.  It is never
+ 	   NULL.  */
diff --git a/gdb-parameterref-2of2.patch b/gdb-parameterref-2of2.patch
new file mode 100644
index 0000000..fe86236
--- /dev/null
+++ b/gdb-parameterref-2of2.patch
@@ -0,0 +1,876 @@
+http://sourceware.org/ml/gdb-patches/2012-06/msg00459.html
+Subject: [patch 2/2] Support gcc-4.7 DW_OP_GNU_parameter_ref
+
+Hi,
+
+this add-on to gdb.arch/amd64-entry-value.exp has been somehow forgotten:
+	[PATCH] Improve debug info for IPA-SRA optimized code - add DW_OP_GNU_parameter_ref support (PR debug/47858)
+	http://gcc.gnu.org/ml/gcc-patches/2011-06/msg00649.html
+
+And for gcc-4.7+ -O2 -g code GDB may print (instead of the calculated value):
+	(gdb) p y
+	Unhandled dwarf expression opcode 0xfa
+
+The support is pretty simple, there is just now third kind of binding between
+callers and callees parameter values.
+
+No regressions on {x86_64,x86_64-m32,i686}-fedora17-linux-gnu.
+
+
+Thanks,
+Jan
+
+
+gdb/
+2012-06-14  Jan Kratochvil  <jan.kratochvil at redhat.com>
+
+	* dwarf2expr.c (execute_stack_op): Support DW_OP_GNU_parameter_ref.
+	* dwarf2loc.c (call_site_parameter_matches): Support
+	CALL_SITE_PARAMETER_PARAM_OFFSET.
+	(needs_dwarf_reg_entry_value): Push stub value.
+	* dwarf2read.c (read_call_site_scope): New variable origin.  Support
+	CALL_SITE_PARAMETER_PARAM_OFFSET and its DW_AT_abstract_origin.
+	* gdbtypes.h (enum call_site_parameter_kind): New item
+	CALL_SITE_PARAMETER_PARAM_OFFSET.
+	(struct call_site.parameter.u): New field param_offset.
+
+gdb/testsuite/
+2012-06-14  Jan Kratochvil  <jan.kratochvil at redhat.com>
+
+	* gdb.arch/amd64-entry-value-param.S: New file.
+	* gdb.arch/amd64-entry-value-param.c: New file.
+	* gdb.arch/amd64-entry-value-param.exp: New file.
+
+Index: gdb-7.4.50.20120120/gdb/dwarf2expr.c
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/dwarf2expr.c	2012-06-14 09:23:37.499446172 +0200
++++ gdb-7.4.50.20120120/gdb/dwarf2expr.c	2012-06-14 09:24:54.042413217 +0200
+@@ -1386,6 +1386,20 @@ execute_stack_op (struct dwarf_expr_cont
+ 		     "or for DW_OP_breg*(0)+DW_OP_deref*"));
+ 	  }
+ 
++	case DW_OP_GNU_parameter_ref:
++	  {
++	    union call_site_parameter_u kind_u;
++
++	    kind_u.param_offset = extract_unsigned_integer (op_ptr, 4,
++								   byte_order);
++	    op_ptr += 4;
++	    ctx->funcs->push_dwarf_reg_entry_value (ctx,
++					       CALL_SITE_PARAMETER_PARAM_OFFSET,
++						    kind_u,
++						    -1 /* deref_size */);
++	  }
++	  goto no_push;
++
+ 	case DW_OP_GNU_const_type:
+ 	  {
+ 	    ULONGEST type_die;
+Index: gdb-7.4.50.20120120/gdb/dwarf2loc.c
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/dwarf2loc.c	2012-06-14 09:23:37.499446172 +0200
++++ gdb-7.4.50.20120120/gdb/dwarf2loc.c	2012-06-14 09:25:44.843434819 +0200
+@@ -919,6 +919,8 @@ call_site_parameter_matches (struct call
+ 	return kind_u.dwarf_reg == parameter->u.dwarf_reg;
+       case CALL_SITE_PARAMETER_FB_OFFSET:
+ 	return kind_u.fb_offset == parameter->u.fb_offset;
++      case CALL_SITE_PARAMETER_PARAM_OFFSET:
++	return kind_u.param_offset == parameter->u.param_offset;
+       }
+   return 0;
+ }
+@@ -2411,6 +2413,9 @@ needs_dwarf_reg_entry_value (struct dwar
+   struct needs_frame_baton *nf_baton = ctx->baton;
+ 
+   nf_baton->needs_frame = 1;
++
++  /* The expression may require some stub values on DWARF stack.  */
++  dwarf_expr_push_address (ctx, 0, 0);
+ }
+ 
+ /* Virtual method table for dwarf2_loc_desc_needs_frame below.  */
+Index: gdb-7.4.50.20120120/gdb/dwarf2read.c
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/dwarf2read.c	2012-06-14 09:23:37.498446171 +0200
++++ gdb-7.4.50.20120120/gdb/dwarf2read.c	2012-06-14 09:24:34.145405249 +0200
+@@ -6368,7 +6368,7 @@ read_call_site_scope (struct die_info *d
+     {
+       struct dwarf2_locexpr_baton *dlbaton;
+       struct call_site_parameter *parameter;
+-      struct attribute *loc;
++      struct attribute *loc, *origin;
+ 
+       if (child_die->tag != DW_TAG_GNU_call_site_parameter)
+ 	{
+@@ -6379,11 +6379,23 @@ read_call_site_scope (struct die_info *d
+       gdb_assert (call_site->parameter_count < nparams);
+       parameter = &call_site->parameter[call_site->parameter_count];
+ 
+-      /* DW_AT_location specifies the register number.  Value of the data
+-	 assumed for the register is contained in DW_AT_GNU_call_site_value.  */
++      /* DW_AT_location specifies the register number or DW_AT_abstract_origin
++	 specifies DW_TAG_formal_parameter.  Value of the data assumed for the
++	 register is contained in DW_AT_GNU_call_site_value.  */
+ 
+       loc = dwarf2_attr (child_die, DW_AT_location, cu);
+-      if (loc == NULL || !attr_form_is_block (loc))
++      origin = dwarf2_attr (child_die, DW_AT_abstract_origin, cu);
++      if (loc == NULL && origin != NULL && is_ref_attr (origin))
++	{
++	  unsigned offset;
++
++	  parameter->kind = CALL_SITE_PARAMETER_PARAM_OFFSET;
++	  offset = dwarf2_get_ref_die_offset (origin);
++	  gdb_assert (offset >= cu->header.offset);
++	  parameter->u.param_offset = (offset
++	                                      - cu->header.offset);
++	}
++      else if (loc == NULL || origin != NULL || !attr_form_is_block (loc))
+ 	{
+ 	  complaint (&symfile_complaints,
+ 		     _("No DW_FORM_block* DW_AT_location for "
+Index: gdb-7.4.50.20120120/gdb/gdbtypes.h
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/gdbtypes.h	2012-06-14 09:23:37.498446171 +0200
++++ gdb-7.4.50.20120120/gdb/gdbtypes.h	2012-06-14 09:24:34.189405275 +0200
+@@ -1019,7 +1019,10 @@ enum call_site_parameter_kind
+   CALL_SITE_PARAMETER_DWARF_REG,
+ 
+   /* Use field call_site_parameter.u.fb_offset.  */
+-  CALL_SITE_PARAMETER_FB_OFFSET
++  CALL_SITE_PARAMETER_FB_OFFSET,
++
++  /* Use field call_site_parameter.u.param_offset.  */
++  CALL_SITE_PARAMETER_PARAM_OFFSET
+ };
+ 
+ /* A place where a function gets called from, represented by
+@@ -1066,6 +1069,11 @@ struct call_site
+ 	    /* Offset from the callee's frame base, for stack passed parameters.
+ 	       This equals offset from the caller's stack pointer.  */
+ 	    CORE_ADDR fb_offset;
++
++	    /* Offset relative to the start of this PER_CU to
++	       DW_TAG_formal_parameter which is referenced by both caller and
++	       the callee.  */
++	    unsigned param_offset;
+ 	  }
+ 	u;
+ 
+Index: gdb-7.4.50.20120120/gdb/testsuite/gdb.arch/amd64-entry-value-param.S
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ gdb-7.4.50.20120120/gdb/testsuite/gdb.arch/amd64-entry-value-param.S	2012-06-14 09:24:34.190405269 +0200
+@@ -0,0 +1,611 @@
++/* This testcase is part of GDB, the GNU debugger.
++
++   Copyright 2012 Free Software Foundation, Inc.
++
++   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 3 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, see <http://www.gnu.org/licenses/>.  */
++
++/* This file is compiled from gdb.arch/amd64-entry-value-param.c
++   using -g -dA -S -O2.  */
++
++	.file	"amd64-entry-value-param.c"
++	.text
++.Ltext0:
++	.p2align 4,,15
++	.type	foo.isra.0.constprop.2, @function
++foo.isra.0.constprop.2:
++.LFB4:
++	.file 1 "gdb.arch/amd64-entry-value-param.c"
++	/* gdb.arch/amd64-entry-value-param.c:21 */
++	.loc 1 21 0
++	.cfi_startproc
++.LVL0:
++/* BLOCK 2 freq:10000 seq:0 */
++/* PRED: ENTRY [100.0%]  (fallthru) */
++	/* gdb.arch/amd64-entry-value-param.c:26 */
++	.loc 1 26 0
++	movl	vv(%rip), %eax
++	addl	$1, %eax
++	movl	%eax, vv(%rip)
++	/* gdb.arch/amd64-entry-value-param.c:27 */
++	.loc 1 27 0
++	leal	3(%rdi), %eax
++/* SUCC: EXIT [100.0%]  */
++	/* gdb.arch/amd64-entry-value-param.c:28 */
++	.loc 1 28 0
++	ret
++	.cfi_endproc
++.LFE4:
++	.size	foo.isra.0.constprop.2, .-foo.isra.0.constprop.2
++	.p2align 4,,15
++	.type	bar.constprop.1, @function
++bar.constprop.1:
++.LFB5:
++	/* gdb.arch/amd64-entry-value-param.c:31 */
++	.loc 1 31 0
++	.cfi_startproc
++/* BLOCK 2 freq:10000 seq:0 */
++/* PRED: ENTRY [100.0%]  (fallthru) */
++.LVL1:
++	pushq	%rbx
++.LCFI0:
++	.cfi_def_cfa_offset 16
++	.cfi_offset 3, -16
++	/* gdb.arch/amd64-entry-value-param.c:33 */
++	.loc 1 33 0
++	movl	$10, %edi
++	call	foo.isra.0.constprop.2
++.LVL2:
++	movl	$10, %edi
++	movl	%eax, %ebx
++	call	foo.isra.0.constprop.2
++.LVL3:
++	movl	$16, %edi
++	addl	%eax, %ebx
++	call	foo.isra.0.constprop.2
++.LVL4:
++	leal	10(%rbx,%rax), %eax
++	/* gdb.arch/amd64-entry-value-param.c:34 */
++	.loc 1 34 0
++	popq	%rbx
++.LCFI1:
++	.cfi_def_cfa_offset 8
++/* SUCC: EXIT [100.0%]  */
++	ret
++	.cfi_endproc
++.LFE5:
++	.size	bar.constprop.1, .-bar.constprop.1
++	.section	.text.startup,"ax", at progbits
++	.p2align 4,,15
++	.globl	main
++	.type	main, @function
++main:
++.LFB2:
++	/* gdb.arch/amd64-entry-value-param.c:38 */
++	.loc 1 38 0
++	.cfi_startproc
++/* BLOCK 2 freq:10000 seq:0 */
++/* PRED: ENTRY [100.0%]  (fallthru) */
++	/* gdb.arch/amd64-entry-value-param.c:39 */
++	.loc 1 39 0
++	jmp	bar.constprop.1
++/* SUCC: EXIT [100.0%]  (ab,sibcall) */
++.LVL5:
++	.cfi_endproc
++.LFE2:
++	.size	main, .-main
++	.comm	vv,4,4
++	.text
++.Letext0:
++	.section	.debug_info,"", at progbits
++.Ldebug_info0:
++	.4byte	0x1b7	/* Length of Compilation Unit Info */
++	.2byte	0x2	/* DWARF version number */
++	.4byte	.Ldebug_abbrev0	/* Offset Into Abbrev. Section */
++	.byte	0x8	/* Pointer Size (in bytes) */
++	.uleb128 0x1	/* (DIE (0xb) DW_TAG_compile_unit) */
++	.4byte	.LASF0	/* DW_AT_producer: "GNU C 4.7.1 20120612 (prerelease)" */
++	.byte	0x1	/* DW_AT_language */
++	.4byte	.LASF1	/* DW_AT_name: "gdb.arch/amd64-entry-value-param.c" */
++	.4byte	.LASF2	/* DW_AT_comp_dir: "" */
++	.4byte	.Ldebug_ranges0+0	/* DW_AT_ranges */
++	.quad	0	/* DW_AT_low_pc */
++	.quad	0	/* DW_AT_entry_pc */
++	.4byte	.Ldebug_line0	/* DW_AT_stmt_list */
++	.uleb128 0x2	/* (DIE (0x31) DW_TAG_subprogram) */
++	.ascii "foo\0"	/* DW_AT_name */
++	.byte	0x1	/* DW_AT_decl_file (gdb.arch/amd64-entry-value-param.c) */
++	.byte	0x15	/* DW_AT_decl_line */
++	.byte	0x1	/* DW_AT_prototyped */
++	.4byte	0x79	/* DW_AT_type */
++	.byte	0	/* DW_AT_inline */
++	.4byte	0x79	/* DW_AT_sibling */
++	.uleb128 0x3	/* (DIE (0x42) DW_TAG_formal_parameter) */
++	.ascii "x\0"	/* DW_AT_name */
++	.byte	0x1	/* DW_AT_decl_file (gdb.arch/amd64-entry-value-param.c) */
++	.byte	0x15	/* DW_AT_decl_line */
++	.4byte	0x79	/* DW_AT_type */
++	.uleb128 0x3	/* (DIE (0x4b) DW_TAG_formal_parameter) */
++	.ascii "y\0"	/* DW_AT_name */
++	.byte	0x1	/* DW_AT_decl_file (gdb.arch/amd64-entry-value-param.c) */
++	.byte	0x15	/* DW_AT_decl_line */
++	.4byte	0x79	/* DW_AT_type */
++	.uleb128 0x3	/* (DIE (0x54) DW_TAG_formal_parameter) */
++	.ascii "z\0"	/* DW_AT_name */
++	.byte	0x1	/* DW_AT_decl_file (gdb.arch/amd64-entry-value-param.c) */
++	.byte	0x15	/* DW_AT_decl_line */
++	.4byte	0x79	/* DW_AT_type */
++	.uleb128 0x4	/* (DIE (0x5d) DW_TAG_variable) */
++	.ascii "a\0"	/* DW_AT_name */
++	.byte	0x1	/* DW_AT_decl_file (gdb.arch/amd64-entry-value-param.c) */
++	.byte	0x17	/* DW_AT_decl_line */
++	.4byte	0x79	/* DW_AT_type */
++	.uleb128 0x4	/* (DIE (0x66) DW_TAG_variable) */
++	.ascii "b\0"	/* DW_AT_name */
++	.byte	0x1	/* DW_AT_decl_file (gdb.arch/amd64-entry-value-param.c) */
++	.byte	0x18	/* DW_AT_decl_line */
++	.4byte	0x79	/* DW_AT_type */
++	.uleb128 0x4	/* (DIE (0x6f) DW_TAG_variable) */
++	.ascii "c\0"	/* DW_AT_name */
++	.byte	0x1	/* DW_AT_decl_file (gdb.arch/amd64-entry-value-param.c) */
++	.byte	0x19	/* DW_AT_decl_line */
++	.4byte	0x79	/* DW_AT_type */
++	.byte	0	/* end of children of DIE 0x31 */
++	.uleb128 0x5	/* (DIE (0x79) DW_TAG_base_type) */
++	.byte	0x4	/* DW_AT_byte_size */
++	.byte	0x5	/* DW_AT_encoding */
++	.ascii "int\0"	/* DW_AT_name */
++	.uleb128 0x2	/* (DIE (0x80) DW_TAG_subprogram) */
++	.ascii "bar\0"	/* DW_AT_name */
++	.byte	0x1	/* DW_AT_decl_file (gdb.arch/amd64-entry-value-param.c) */
++	.byte	0x1f	/* DW_AT_decl_line */
++	.byte	0x1	/* DW_AT_prototyped */
++	.4byte	0x79	/* DW_AT_type */
++	.byte	0x1	/* DW_AT_inline */
++	.4byte	0x9b	/* DW_AT_sibling */
++	.uleb128 0x3	/* (DIE (0x91) DW_TAG_formal_parameter) */
++	.ascii "x\0"	/* DW_AT_name */
++	.byte	0x1	/* DW_AT_decl_file (gdb.arch/amd64-entry-value-param.c) */
++	.byte	0x1f	/* DW_AT_decl_line */
++	.4byte	0x79	/* DW_AT_type */
++	.byte	0	/* end of children of DIE 0x80 */
++	.uleb128 0x6	/* (DIE (0x9b) DW_TAG_subprogram) */
++	.4byte	0x31	/* DW_AT_abstract_origin */
++	.quad	.LFB4	/* DW_AT_low_pc */
++	.quad	.LFE4	/* DW_AT_high_pc */
++	.byte	0x2	/* DW_AT_frame_base */
++	.byte	0x77	/* DW_OP_breg7 */
++	.sleb128 8
++	.byte	0x1	/* DW_AT_GNU_all_call_sites */
++	.4byte	0xf1	/* DW_AT_sibling */
++	.uleb128 0x7	/* (DIE (0xb8) DW_TAG_formal_parameter) */
++	.4byte	0x42	/* DW_AT_abstract_origin */
++	.byte	0x1	/* DW_AT_location */
++	.byte	0x55	/* DW_OP_reg5 */
++	.uleb128 0x7	/* (DIE (0xbf) DW_TAG_formal_parameter) */
++	.4byte	0x4b	/* DW_AT_abstract_origin */
++	.byte	0x6	/* DW_AT_location */
++	.byte	0xfa	/* DW_OP_GNU_parameter_ref */
++	.4byte	0x4b
++	.byte	0x9f	/* DW_OP_stack_value */
++	.uleb128 0x8	/* (DIE (0xcb) DW_TAG_variable) */
++	.4byte	0x5d	/* DW_AT_abstract_origin */
++	.byte	0x5	/* DW_AT_location */
++	.byte	0x75	/* DW_OP_breg5 */
++	.sleb128 0
++	.byte	0x31	/* DW_OP_lit1 */
++	.byte	0x24	/* DW_OP_shl */
++	.byte	0x9f	/* DW_OP_stack_value */
++	.uleb128 0x8	/* (DIE (0xd6) DW_TAG_variable) */
++	.4byte	0x66	/* DW_AT_abstract_origin */
++	.byte	0x8	/* DW_AT_location */
++	.byte	0xfa	/* DW_OP_GNU_parameter_ref */
++	.4byte	0x4b
++	.byte	0x31	/* DW_OP_lit1 */
++	.byte	0x24	/* DW_OP_shl */
++	.byte	0x9f	/* DW_OP_stack_value */
++	.uleb128 0x9	/* (DIE (0xe4) DW_TAG_variable) */
++	.4byte	0x6f	/* DW_AT_abstract_origin */
++	.byte	0x6	/* DW_AT_const_value */
++	.uleb128 0xa	/* (DIE (0xea) DW_TAG_formal_parameter) */
++	.4byte	0x54	/* DW_AT_abstract_origin */
++	.byte	0x3	/* DW_AT_const_value */
++	.byte	0	/* end of children of DIE 0x9b */
++	.uleb128 0xb	/* (DIE (0xf1) DW_TAG_subprogram) */
++	.4byte	0x80	/* DW_AT_abstract_origin */
++	.quad	.LFB5	/* DW_AT_low_pc */
++	.quad	.LFE5	/* DW_AT_high_pc */
++	.4byte	.LLST0	/* DW_AT_frame_base */
++	.byte	0x1	/* DW_AT_GNU_all_call_sites */
++	.4byte	0x16c	/* DW_AT_sibling */
++	.uleb128 0xa	/* (DIE (0x10f) DW_TAG_formal_parameter) */
++	.4byte	0x91	/* DW_AT_abstract_origin */
++	.byte	0xa	/* DW_AT_const_value */
++	.uleb128 0xc	/* (DIE (0x115) DW_TAG_GNU_call_site) */
++	.quad	.LVL2	/* DW_AT_low_pc */
++	.4byte	0x9b	/* DW_AT_abstract_origin */
++	.4byte	0x133	/* DW_AT_sibling */
++	.uleb128 0xd	/* (DIE (0x126) DW_TAG_GNU_call_site_parameter) */
++	.byte	0x1	/* DW_AT_location */
++	.byte	0x55	/* DW_OP_reg5 */
++	.byte	0x1	/* DW_AT_GNU_call_site_value */
++	.byte	0x3a	/* DW_OP_lit10 */
++	.uleb128 0xe	/* (DIE (0x12b) DW_TAG_GNU_call_site_parameter) */
++	.4byte	0x4b	/* DW_AT_abstract_origin */
++	.byte	0x1	/* DW_AT_GNU_call_site_value */
++	.byte	0x32	/* DW_OP_lit2 */
++	.byte	0	/* end of children of DIE 0x115 */
++	.uleb128 0xc	/* (DIE (0x133) DW_TAG_GNU_call_site) */
++	.quad	.LVL3	/* DW_AT_low_pc */
++	.4byte	0x9b	/* DW_AT_abstract_origin */
++	.4byte	0x151	/* DW_AT_sibling */
++	.uleb128 0xd	/* (DIE (0x144) DW_TAG_GNU_call_site_parameter) */
++	.byte	0x1	/* DW_AT_location */
++	.byte	0x55	/* DW_OP_reg5 */
++	.byte	0x1	/* DW_AT_GNU_call_site_value */
++	.byte	0x3a	/* DW_OP_lit10 */
++	.uleb128 0xe	/* (DIE (0x149) DW_TAG_GNU_call_site_parameter) */
++	.4byte	0x4b	/* DW_AT_abstract_origin */
++	.byte	0x1	/* DW_AT_GNU_call_site_value */
++	.byte	0x34	/* DW_OP_lit4 */
++	.byte	0	/* end of children of DIE 0x133 */
++	.uleb128 0xf	/* (DIE (0x151) DW_TAG_GNU_call_site) */
++	.quad	.LVL4	/* DW_AT_low_pc */
++	.4byte	0x9b	/* DW_AT_abstract_origin */
++	.uleb128 0xd	/* (DIE (0x15e) DW_TAG_GNU_call_site_parameter) */
++	.byte	0x1	/* DW_AT_location */
++	.byte	0x55	/* DW_OP_reg5 */
++	.byte	0x1	/* DW_AT_GNU_call_site_value */
++	.byte	0x40	/* DW_OP_lit16 */
++	.uleb128 0xe	/* (DIE (0x163) DW_TAG_GNU_call_site_parameter) */
++	.4byte	0x4b	/* DW_AT_abstract_origin */
++	.byte	0x1	/* DW_AT_GNU_call_site_value */
++	.byte	0x3a	/* DW_OP_lit10 */
++	.byte	0	/* end of children of DIE 0x151 */
++	.byte	0	/* end of children of DIE 0xf1 */
++	.uleb128 0x10	/* (DIE (0x16c) DW_TAG_subprogram) */
++	.byte	0x1	/* DW_AT_external */
++	.4byte	.LASF3	/* DW_AT_name: "main" */
++	.byte	0x1	/* DW_AT_decl_file (gdb.arch/amd64-entry-value-param.c) */
++	.byte	0x25	/* DW_AT_decl_line */
++	.byte	0x1	/* DW_AT_prototyped */
++	.4byte	0x79	/* DW_AT_type */
++	.quad	.LFB2	/* DW_AT_low_pc */
++	.quad	.LFE2	/* DW_AT_high_pc */
++	.byte	0x2	/* DW_AT_frame_base */
++	.byte	0x77	/* DW_OP_breg7 */
++	.sleb128 8
++	.byte	0x1	/* DW_AT_GNU_all_call_sites */
++	.4byte	0x1a0	/* DW_AT_sibling */
++	.uleb128 0x11	/* (DIE (0x191) DW_TAG_GNU_call_site) */
++	.quad	.LVL5	/* DW_AT_low_pc */
++	.byte	0x1	/* DW_AT_GNU_tail_call */
++	.4byte	0xf1	/* DW_AT_abstract_origin */
++	.byte	0	/* end of children of DIE 0x16c */
++	.uleb128 0x12	/* (DIE (0x1a0) DW_TAG_variable) */
++	.ascii "vv\0"	/* DW_AT_name */
++	.byte	0x1	/* DW_AT_decl_file (gdb.arch/amd64-entry-value-param.c) */
++	.byte	0x12	/* DW_AT_decl_line */
++	.4byte	0x1b5	/* DW_AT_type */
++	.byte	0x1	/* DW_AT_external */
++	.byte	0x9	/* DW_AT_location */
++	.byte	0x3	/* DW_OP_addr */
++	.quad	vv
++	.uleb128 0x13	/* (DIE (0x1b5) DW_TAG_volatile_type) */
++	.4byte	0x79	/* DW_AT_type */
++	.byte	0	/* end of children of DIE 0xb */
++	.section	.debug_abbrev,"", at progbits
++.Ldebug_abbrev0:
++	.uleb128 0x1	/* (abbrev code) */
++	.uleb128 0x11	/* (TAG: DW_TAG_compile_unit) */
++	.byte	0x1	/* DW_children_yes */
++	.uleb128 0x25	/* (DW_AT_producer) */
++	.uleb128 0xe	/* (DW_FORM_strp) */
++	.uleb128 0x13	/* (DW_AT_language) */
++	.uleb128 0xb	/* (DW_FORM_data1) */
++	.uleb128 0x3	/* (DW_AT_name) */
++	.uleb128 0xe	/* (DW_FORM_strp) */
++	.uleb128 0x1b	/* (DW_AT_comp_dir) */
++	.uleb128 0xe	/* (DW_FORM_strp) */
++	.uleb128 0x55	/* (DW_AT_ranges) */
++	.uleb128 0x6	/* (DW_FORM_data4) */
++	.uleb128 0x11	/* (DW_AT_low_pc) */
++	.uleb128 0x1	/* (DW_FORM_addr) */
++	.uleb128 0x52	/* (DW_AT_entry_pc) */
++	.uleb128 0x1	/* (DW_FORM_addr) */
++	.uleb128 0x10	/* (DW_AT_stmt_list) */
++	.uleb128 0x6	/* (DW_FORM_data4) */
++	.byte	0
++	.byte	0
++	.uleb128 0x2	/* (abbrev code) */
++	.uleb128 0x2e	/* (TAG: DW_TAG_subprogram) */
++	.byte	0x1	/* DW_children_yes */
++	.uleb128 0x3	/* (DW_AT_name) */
++	.uleb128 0x8	/* (DW_FORM_string) */
++	.uleb128 0x3a	/* (DW_AT_decl_file) */
++	.uleb128 0xb	/* (DW_FORM_data1) */
++	.uleb128 0x3b	/* (DW_AT_decl_line) */
++	.uleb128 0xb	/* (DW_FORM_data1) */
++	.uleb128 0x27	/* (DW_AT_prototyped) */
++	.uleb128 0xc	/* (DW_FORM_flag) */
++	.uleb128 0x49	/* (DW_AT_type) */
++	.uleb128 0x13	/* (DW_FORM_ref4) */
++	.uleb128 0x20	/* (DW_AT_inline) */
++	.uleb128 0xb	/* (DW_FORM_data1) */
++	.uleb128 0x1	/* (DW_AT_sibling) */
++	.uleb128 0x13	/* (DW_FORM_ref4) */
++	.byte	0
++	.byte	0
++	.uleb128 0x3	/* (abbrev code) */
++	.uleb128 0x5	/* (TAG: DW_TAG_formal_parameter) */
++	.byte	0	/* DW_children_no */
++	.uleb128 0x3	/* (DW_AT_name) */
++	.uleb128 0x8	/* (DW_FORM_string) */
++	.uleb128 0x3a	/* (DW_AT_decl_file) */
++	.uleb128 0xb	/* (DW_FORM_data1) */
++	.uleb128 0x3b	/* (DW_AT_decl_line) */
++	.uleb128 0xb	/* (DW_FORM_data1) */
++	.uleb128 0x49	/* (DW_AT_type) */
++	.uleb128 0x13	/* (DW_FORM_ref4) */
++	.byte	0
++	.byte	0
++	.uleb128 0x4	/* (abbrev code) */
++	.uleb128 0x34	/* (TAG: DW_TAG_variable) */
++	.byte	0	/* DW_children_no */
++	.uleb128 0x3	/* (DW_AT_name) */
++	.uleb128 0x8	/* (DW_FORM_string) */
++	.uleb128 0x3a	/* (DW_AT_decl_file) */
++	.uleb128 0xb	/* (DW_FORM_data1) */
++	.uleb128 0x3b	/* (DW_AT_decl_line) */
++	.uleb128 0xb	/* (DW_FORM_data1) */
++	.uleb128 0x49	/* (DW_AT_type) */
++	.uleb128 0x13	/* (DW_FORM_ref4) */
++	.byte	0
++	.byte	0
++	.uleb128 0x5	/* (abbrev code) */
++	.uleb128 0x24	/* (TAG: DW_TAG_base_type) */
++	.byte	0	/* DW_children_no */
++	.uleb128 0xb	/* (DW_AT_byte_size) */
++	.uleb128 0xb	/* (DW_FORM_data1) */
++	.uleb128 0x3e	/* (DW_AT_encoding) */
++	.uleb128 0xb	/* (DW_FORM_data1) */
++	.uleb128 0x3	/* (DW_AT_name) */
++	.uleb128 0x8	/* (DW_FORM_string) */
++	.byte	0
++	.byte	0
++	.uleb128 0x6	/* (abbrev code) */
++	.uleb128 0x2e	/* (TAG: DW_TAG_subprogram) */
++	.byte	0x1	/* DW_children_yes */
++	.uleb128 0x31	/* (DW_AT_abstract_origin) */
++	.uleb128 0x13	/* (DW_FORM_ref4) */
++	.uleb128 0x11	/* (DW_AT_low_pc) */
++	.uleb128 0x1	/* (DW_FORM_addr) */
++	.uleb128 0x12	/* (DW_AT_high_pc) */
++	.uleb128 0x1	/* (DW_FORM_addr) */
++	.uleb128 0x40	/* (DW_AT_frame_base) */
++	.uleb128 0xa	/* (DW_FORM_block1) */
++	.uleb128 0x2117	/* (DW_AT_GNU_all_call_sites) */
++	.uleb128 0xc	/* (DW_FORM_flag) */
++	.uleb128 0x1	/* (DW_AT_sibling) */
++	.uleb128 0x13	/* (DW_FORM_ref4) */
++	.byte	0
++	.byte	0
++	.uleb128 0x7	/* (abbrev code) */
++	.uleb128 0x5	/* (TAG: DW_TAG_formal_parameter) */
++	.byte	0	/* DW_children_no */
++	.uleb128 0x31	/* (DW_AT_abstract_origin) */
++	.uleb128 0x13	/* (DW_FORM_ref4) */
++	.uleb128 0x2	/* (DW_AT_location) */
++	.uleb128 0xa	/* (DW_FORM_block1) */
++	.byte	0
++	.byte	0
++	.uleb128 0x8	/* (abbrev code) */
++	.uleb128 0x34	/* (TAG: DW_TAG_variable) */
++	.byte	0	/* DW_children_no */
++	.uleb128 0x31	/* (DW_AT_abstract_origin) */
++	.uleb128 0x13	/* (DW_FORM_ref4) */
++	.uleb128 0x2	/* (DW_AT_location) */
++	.uleb128 0xa	/* (DW_FORM_block1) */
++	.byte	0
++	.byte	0
++	.uleb128 0x9	/* (abbrev code) */
++	.uleb128 0x34	/* (TAG: DW_TAG_variable) */
++	.byte	0	/* DW_children_no */
++	.uleb128 0x31	/* (DW_AT_abstract_origin) */
++	.uleb128 0x13	/* (DW_FORM_ref4) */
++	.uleb128 0x1c	/* (DW_AT_const_value) */
++	.uleb128 0xb	/* (DW_FORM_data1) */
++	.byte	0
++	.byte	0
++	.uleb128 0xa	/* (abbrev code) */
++	.uleb128 0x5	/* (TAG: DW_TAG_formal_parameter) */
++	.byte	0	/* DW_children_no */
++	.uleb128 0x31	/* (DW_AT_abstract_origin) */
++	.uleb128 0x13	/* (DW_FORM_ref4) */
++	.uleb128 0x1c	/* (DW_AT_const_value) */
++	.uleb128 0xb	/* (DW_FORM_data1) */
++	.byte	0
++	.byte	0
++	.uleb128 0xb	/* (abbrev code) */
++	.uleb128 0x2e	/* (TAG: DW_TAG_subprogram) */
++	.byte	0x1	/* DW_children_yes */
++	.uleb128 0x31	/* (DW_AT_abstract_origin) */
++	.uleb128 0x13	/* (DW_FORM_ref4) */
++	.uleb128 0x11	/* (DW_AT_low_pc) */
++	.uleb128 0x1	/* (DW_FORM_addr) */
++	.uleb128 0x12	/* (DW_AT_high_pc) */
++	.uleb128 0x1	/* (DW_FORM_addr) */
++	.uleb128 0x40	/* (DW_AT_frame_base) */
++	.uleb128 0x6	/* (DW_FORM_data4) */
++	.uleb128 0x2117	/* (DW_AT_GNU_all_call_sites) */
++	.uleb128 0xc	/* (DW_FORM_flag) */
++	.uleb128 0x1	/* (DW_AT_sibling) */
++	.uleb128 0x13	/* (DW_FORM_ref4) */
++	.byte	0
++	.byte	0
++	.uleb128 0xc	/* (abbrev code) */
++	.uleb128 0x4109	/* (TAG: DW_TAG_GNU_call_site) */
++	.byte	0x1	/* DW_children_yes */
++	.uleb128 0x11	/* (DW_AT_low_pc) */
++	.uleb128 0x1	/* (DW_FORM_addr) */
++	.uleb128 0x31	/* (DW_AT_abstract_origin) */
++	.uleb128 0x13	/* (DW_FORM_ref4) */
++	.uleb128 0x1	/* (DW_AT_sibling) */
++	.uleb128 0x13	/* (DW_FORM_ref4) */
++	.byte	0
++	.byte	0
++	.uleb128 0xd	/* (abbrev code) */
++	.uleb128 0x410a	/* (TAG: DW_TAG_GNU_call_site_parameter) */
++	.byte	0	/* DW_children_no */
++	.uleb128 0x2	/* (DW_AT_location) */
++	.uleb128 0xa	/* (DW_FORM_block1) */
++	.uleb128 0x2111	/* (DW_AT_GNU_call_site_value) */
++	.uleb128 0xa	/* (DW_FORM_block1) */
++	.byte	0
++	.byte	0
++	.uleb128 0xe	/* (abbrev code) */
++	.uleb128 0x410a	/* (TAG: DW_TAG_GNU_call_site_parameter) */
++	.byte	0	/* DW_children_no */
++	.uleb128 0x31	/* (DW_AT_abstract_origin) */
++	.uleb128 0x13	/* (DW_FORM_ref4) */
++	.uleb128 0x2111	/* (DW_AT_GNU_call_site_value) */
++	.uleb128 0xa	/* (DW_FORM_block1) */
++	.byte	0
++	.byte	0
++	.uleb128 0xf	/* (abbrev code) */
++	.uleb128 0x4109	/* (TAG: DW_TAG_GNU_call_site) */
++	.byte	0x1	/* DW_children_yes */
++	.uleb128 0x11	/* (DW_AT_low_pc) */
++	.uleb128 0x1	/* (DW_FORM_addr) */
++	.uleb128 0x31	/* (DW_AT_abstract_origin) */
++	.uleb128 0x13	/* (DW_FORM_ref4) */
++	.byte	0
++	.byte	0
++	.uleb128 0x10	/* (abbrev code) */
++	.uleb128 0x2e	/* (TAG: DW_TAG_subprogram) */
++	.byte	0x1	/* DW_children_yes */
++	.uleb128 0x3f	/* (DW_AT_external) */
++	.uleb128 0xc	/* (DW_FORM_flag) */
++	.uleb128 0x3	/* (DW_AT_name) */
++	.uleb128 0xe	/* (DW_FORM_strp) */
++	.uleb128 0x3a	/* (DW_AT_decl_file) */
++	.uleb128 0xb	/* (DW_FORM_data1) */
++	.uleb128 0x3b	/* (DW_AT_decl_line) */
++	.uleb128 0xb	/* (DW_FORM_data1) */
++	.uleb128 0x27	/* (DW_AT_prototyped) */
++	.uleb128 0xc	/* (DW_FORM_flag) */
++	.uleb128 0x49	/* (DW_AT_type) */
++	.uleb128 0x13	/* (DW_FORM_ref4) */
++	.uleb128 0x11	/* (DW_AT_low_pc) */
++	.uleb128 0x1	/* (DW_FORM_addr) */
++	.uleb128 0x12	/* (DW_AT_high_pc) */
++	.uleb128 0x1	/* (DW_FORM_addr) */
++	.uleb128 0x40	/* (DW_AT_frame_base) */
++	.uleb128 0xa	/* (DW_FORM_block1) */
++	.uleb128 0x2117	/* (DW_AT_GNU_all_call_sites) */
++	.uleb128 0xc	/* (DW_FORM_flag) */
++	.uleb128 0x1	/* (DW_AT_sibling) */
++	.uleb128 0x13	/* (DW_FORM_ref4) */
++	.byte	0
++	.byte	0
++	.uleb128 0x11	/* (abbrev code) */
++	.uleb128 0x4109	/* (TAG: DW_TAG_GNU_call_site) */
++	.byte	0	/* DW_children_no */
++	.uleb128 0x11	/* (DW_AT_low_pc) */
++	.uleb128 0x1	/* (DW_FORM_addr) */
++	.uleb128 0x2115	/* (DW_AT_GNU_tail_call) */
++	.uleb128 0xc	/* (DW_FORM_flag) */
++	.uleb128 0x31	/* (DW_AT_abstract_origin) */
++	.uleb128 0x13	/* (DW_FORM_ref4) */
++	.byte	0
++	.byte	0
++	.uleb128 0x12	/* (abbrev code) */
++	.uleb128 0x34	/* (TAG: DW_TAG_variable) */
++	.byte	0	/* DW_children_no */
++	.uleb128 0x3	/* (DW_AT_name) */
++	.uleb128 0x8	/* (DW_FORM_string) */
++	.uleb128 0x3a	/* (DW_AT_decl_file) */
++	.uleb128 0xb	/* (DW_FORM_data1) */
++	.uleb128 0x3b	/* (DW_AT_decl_line) */
++	.uleb128 0xb	/* (DW_FORM_data1) */
++	.uleb128 0x49	/* (DW_AT_type) */
++	.uleb128 0x13	/* (DW_FORM_ref4) */
++	.uleb128 0x3f	/* (DW_AT_external) */
++	.uleb128 0xc	/* (DW_FORM_flag) */
++	.uleb128 0x2	/* (DW_AT_location) */
++	.uleb128 0xa	/* (DW_FORM_block1) */
++	.byte	0
++	.byte	0
++	.uleb128 0x13	/* (abbrev code) */
++	.uleb128 0x35	/* (TAG: DW_TAG_volatile_type) */
++	.byte	0	/* DW_children_no */
++	.uleb128 0x49	/* (DW_AT_type) */
++	.uleb128 0x13	/* (DW_FORM_ref4) */
++	.byte	0
++	.byte	0
++	.byte	0
++	.section	.debug_loc,"", at progbits
++.Ldebug_loc0:
++.LLST0:
++	.quad	.LFB5	/* Location list begin address (*.LLST0) */
++	.quad	.LCFI0	/* Location list end address (*.LLST0) */
++	.2byte	0x2	/* Location expression size */
++	.byte	0x77	/* DW_OP_breg7 */
++	.sleb128 8
++	.quad	.LCFI0	/* Location list begin address (*.LLST0) */
++	.quad	.LCFI1	/* Location list end address (*.LLST0) */
++	.2byte	0x2	/* Location expression size */
++	.byte	0x77	/* DW_OP_breg7 */
++	.sleb128 16
++	.quad	.LCFI1	/* Location list begin address (*.LLST0) */
++	.quad	.LFE5	/* Location list end address (*.LLST0) */
++	.2byte	0x2	/* Location expression size */
++	.byte	0x77	/* DW_OP_breg7 */
++	.sleb128 8
++	.quad	0	/* Location list terminator begin (*.LLST0) */
++	.quad	0	/* Location list terminator end (*.LLST0) */
++	.section	.debug_aranges,"", at progbits
++	.4byte	0x3c	/* Length of Address Ranges Info */
++	.2byte	0x2	/* DWARF Version */
++	.4byte	.Ldebug_info0	/* Offset of Compilation Unit Info */
++	.byte	0x8	/* Size of Address */
++	.byte	0	/* Size of Segment Descriptor */
++	.2byte	0	/* Pad to 16 byte boundary */
++	.2byte	0
++	.quad	.Ltext0	/* Address */
++	.quad	.Letext0-.Ltext0	/* Length */
++	.quad	.LFB2	/* Address */
++	.quad	.LFE2-.LFB2	/* Length */
++	.quad	0
++	.quad	0
++	.section	.debug_ranges,"", at progbits
++.Ldebug_ranges0:
++	.quad	.Ltext0	/* Offset 0 */
++	.quad	.Letext0
++	.quad	.LFB2	/* Offset 0x10 */
++	.quad	.LFE2
++	.quad	0
++	.quad	0
++	.section	.debug_line,"", at progbits
++.Ldebug_line0:
++	.section	.debug_str,"MS", at progbits,1
++.LASF1:
++	.string	"gdb.arch/amd64-entry-value-param.c"
++.LASF3:
++	.string	"main"
++.LASF2:
++	.string	""
++.LASF0:
++	.string	"GNU C 4.7.1 20120612 (prerelease)"
++	.ident	"GCC: (GNU) 4.7.1 20120612 (prerelease)"
++	.section	.note.GNU-stack,"", at progbits
+Index: gdb-7.4.50.20120120/gdb/testsuite/gdb.arch/amd64-entry-value-param.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ gdb-7.4.50.20120120/gdb/testsuite/gdb.arch/amd64-entry-value-param.c	2012-06-14 09:24:34.191405263 +0200
+@@ -0,0 +1,40 @@
++/* This testcase is part of GDB, the GNU debugger.
++
++   Copyright 2012 Free Software Foundation, Inc.
++
++   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 3 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, see <http://www.gnu.org/licenses/>.  */
++
++volatile int vv;
++
++static __attribute__((noinline)) int
++foo (int x, int y, int z)
++{
++  int a = x * 2;
++  int b = y * 2;
++  int c = z * 2;
++  vv++; /* break-here */
++  return x + z;
++}
++
++static __attribute__((noinline)) int
++bar (int x)
++{
++  return foo (x, 2, 3) + foo (x, 4, 3) + foo (x + 6, x, 3) + x;
++}
++
++int
++main (void)
++{
++  return bar (10);
++}
+Index: gdb-7.4.50.20120120/gdb/testsuite/gdb.arch/amd64-entry-value-param.exp
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ gdb-7.4.50.20120120/gdb/testsuite/gdb.arch/amd64-entry-value-param.exp	2012-06-14 09:24:34.192405264 +0200
+@@ -0,0 +1,51 @@
++# Copyright (C) 2012 Free Software Foundation, Inc.
++#
++# 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 3 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, see <http://www.gnu.org/licenses/>.
++
++set testfile amd64-entry-value-param
++set srcfile ${testfile}.S
++set csrcfile ${testfile}.c
++set opts {}
++
++if [info exists COMPILE] {
++    # make check RUNTESTFLAGS="gdb.arch/amd64-entry-value-param.exp COMPILE=1"
++    set srcfile ${csrcfile}
++    lappend opts debug optimize=-O2
++} elseif { ![istarget x86_64-*-* ] || ![is_lp64_target] } {
++    verbose "Skipping amd64-entry-value-param."
++    return
++}
++
++if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} $opts] } {
++    return -1
++}
++
++if ![runto_main] {
++    return -1
++}
++
++set srcfile $csrcfile
++gdb_breakpoint [gdb_get_line_number "break-here"]
++
++gdb_continue_to_breakpoint "break-here" ".* break-here .*"
++gdb_test "p y" " = 2"
++gdb_test "p b" " = 4"
++
++gdb_continue_to_breakpoint "break-here" ".* break-here .*"
++gdb_test "p y" " = 4"
++gdb_test "p b" " = 8"
++
++gdb_continue_to_breakpoint "break-here" ".* break-here .*"
++gdb_test "p y" " = 10"
++gdb_test "p b" " = 20"
diff --git a/gdb.spec b/gdb.spec
index 7ed50c8..9a4ef6d 100644
--- a/gdb.spec
+++ b/gdb.spec
@@ -35,7 +35,7 @@ Version: 7.4.50.%{snap}
 
 # The release always contains a leading reserved number, start it at 1.
 # `upstream' is not a part of `name' to stay fully rpm dependencies compatible for the testing.
-Release: 48%{?dist}
+Release: 49%{?dist}
 
 License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and BSD and Public Domain
 Group: Development/Debuggers
@@ -625,6 +625,10 @@ Patch690: gdb-glibc-strstr-workaround.patch
 # [ppc] Fix hardware watchpoints on PowerPC (BZ 827600, Edjunior Machado).
 Patch691: gdb-ppc-watchpoint.patch
 
+# Support DW_OP_GNU_parameter_ref for -O2 -g inferiors (BZ 827375).
+Patch696: gdb-parameterref-1of2.patch
+Patch697: gdb-parameterref-2of2.patch
+
 %if 0%{!?rhel:1} || 0%{?rhel} > 6
 # RL_STATE_FEDORA_GDB would not be found for:
 # Patch642: gdb-readline62-ask-more-rh.patch
@@ -945,6 +949,8 @@ rm -f gdb/jv-exp.c gdb/m2-exp.c gdb/objc-exp.c gdb/p-exp.c
 %patch689 -p1
 %patch690 -p1
 %patch691 -p1
+%patch696 -p1
+%patch697 -p1
 
 %patch393 -p1
 %if 0%{!?el5:1} || 0%{?scl:1}
@@ -1437,6 +1443,9 @@ fi
 %endif # 0%{!?el5:1} || "%{_target_cpu}" == "noarch"
 
 %changelog
+* Thu Jun 14 2012 Jan Kratochvil <jan.kratochvil at redhat.com> - 7.4.50.20120120-49.fc17
+- Support DW_OP_GNU_parameter_ref for -O2 -g inferiors (BZ 827375).
+
 * Sat Jun  2 2012 Jan Kratochvil <jan.kratochvil at redhat.com> - 7.4.50.20120120-48.fc17
 - [ppc] Fix hardware watchpoints on PowerPC (BZ 827600, Edjunior Machado).
 


More information about the scm-commits mailing list