[gdb] Support DW_OP_GNU_parameter_ref for -O2 -g inferiors (BZ 827375).
Jan Kratochvil
jankratochvil at fedoraproject.org
Thu Jun 14 07:41:46 UTC 2012
commit 31e8955039c423a41aeb76056f3eb4640752d2ff
Author: Jan Kratochvil <jan.kratochvil at redhat.com>
Date: Thu Jun 14 09:41:43 2012 +0200
Support DW_OP_GNU_parameter_ref for -O2 -g inferiors (BZ 827375).
gdb-parameterref-1of2.patch | 416 +++++++++++++++++++++
gdb-parameterref-2of2.patch | 864 +++++++++++++++++++++++++++++++++++++++++++
gdb.spec | 11 +-
3 files changed, 1290 insertions(+), 1 deletions(-)
---
diff --git a/gdb-parameterref-1of2.patch b/gdb-parameterref-1of2.patch
new file mode 100644
index 0000000..029e6f9
--- /dev/null
+++ b/gdb-parameterref-1of2.patch
@@ -0,0 +1,416 @@
+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.
+
+--- a/gdb/dwarf2expr.c
++++ b/gdb/dwarf2expr.c
+@@ -1355,33 +1355,35 @@ execute_stack_op (struct dwarf_expr_context *ctx,
+ case DW_OP_GNU_entry_value:
+ {
+ uint64_t len;
+- int dwarf_reg;
+ CORE_ADDR deref_size;
++ union call_site_parameter_u kind_u;
+
+ op_ptr = safe_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;
+ }
+
+@@ -1533,7 +1535,8 @@ ctx_no_get_base_type (struct dwarf_expr_context *ctx, cu_offset 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)
+ {
+ internal_error (__FILE__, __LINE__,
+--- a/gdb/dwarf2expr.h
++++ b/gdb/dwarf2expr.h
+@@ -26,6 +26,8 @@
+ #include "leb128.h"
+
+ struct dwarf_expr_context;
++enum call_site_parameter_kind;
++union call_site_parameter_u;
+
+ /* Offset relative to the start of its containing CU (compilation unit). */
+ typedef struct
+@@ -77,14 +79,12 @@ struct dwarf_expr_context_funcs
+ struct type *(*get_base_type) (struct dwarf_expr_context *ctx, cu_offset 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);
+
+ /* Return the address indexed by DW_OP_GNU_addr_index.
+@@ -289,7 +289,8 @@ void ctx_no_dwarf_call (struct dwarf_expr_context *ctx, cu_offset die_offset);
+ struct type *ctx_no_get_base_type (struct dwarf_expr_context *ctx,
+ cu_offset 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);
+ CORE_ADDR ctx_no_get_addr_index (void *baton, unsigned int index);
+
+--- a/gdb/dwarf2loc.c
++++ b/gdb/dwarf2loc.c
+@@ -929,16 +929,34 @@ call_site_find_chain (struct gdbarch *gdbarch, CORE_ADDR caller_pc,
+ 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);
+@@ -1001,12 +1019,7 @@ dwarf_expr_reg_to_entry_parameter (struct frame_info *frame, int dwarf_reg,
+ 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)
+@@ -1063,17 +1076,17 @@ dwarf_entry_parameter_to_value (struct call_site_parameter *parameter,
+ 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;
+@@ -1090,7 +1103,7 @@ dwarf_expr_push_dwarf_reg_entry_value (struct dwarf_expr_context *ctx,
+ 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;
+@@ -1187,17 +1200,17 @@ static const struct lval_funcs entry_data_value_funcs =
+ 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);
+@@ -1207,7 +1220,7 @@ value_of_dwarf_reg_entry (struct type *type, struct frame_info *frame,
+ 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 */,
+@@ -1259,15 +1272,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;
++ union call_site_parameter_u kind_u;
+
+- 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 */);
++ 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, &fb_offset))
+- return value_of_dwarf_reg_entry (type, frame, -1, fb_offset);
++ 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
+@@ -2358,7 +2372,8 @@ needs_frame_dwarf_call (struct dwarf_expr_context *ctx, cu_offset die_offset)
+
+ 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;
+
+--- a/gdb/dwarf2read.c
++++ b/gdb/dwarf2read.c
+@@ -7816,6 +7816,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
+ child_die = sibling_die (child_die))
+ {
+ struct call_site_parameter *parameter;
++ struct attribute *loc;
+
+ if (child_die->tag != DW_TAG_GNU_call_site_parameter)
+ {
+@@ -7829,8 +7830,8 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
+ /* 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 "
+@@ -7838,19 +7839,26 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
+ child_die->offset.sect_off, 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],
+- ¶meter->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.sect_off, 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],
++ ¶meter->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.sect_off, objfile->name);
++ continue;
++ }
+ }
+
+ attr = dwarf2_attr (child_die, DW_AT_GNU_call_site_value, cu);
+--- a/gdb/gdbtypes.h
++++ b/gdb/gdbtypes.h
+@@ -23,6 +23,7 @@
+ #define GDBTYPES_H 1
+
+ #include "hashtab.h"
++#include "dwarf2expr.h"
+
+ /* Forward declarations for prototypes. */
+ struct field;
+@@ -915,6 +916,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. */
+
+@@ -948,15 +960,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..85e37af
--- /dev/null
+++ b/gdb-parameterref-2of2.patch
@@ -0,0 +1,864 @@
+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.
+
+--- a/gdb/dwarf2expr.c
++++ b/gdb/dwarf2expr.c
+@@ -1392,6 +1392,21 @@ execute_stack_op (struct dwarf_expr_context *ctx,
+ "or for DW_OP_breg*(0)+DW_OP_deref*"));
+ }
+
++ case DW_OP_GNU_parameter_ref:
++ {
++ cu_offset offset;
++ union call_site_parameter_u kind_u;
++
++ kind_u.param_offset.cu_off = 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:
+ {
+ cu_offset type_die;
+--- a/gdb/dwarf2loc.c
++++ b/gdb/dwarf2loc.c
+@@ -943,6 +943,8 @@ call_site_parameter_matches (struct call_site_parameter *parameter,
+ 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.cu_off == parameter->u.param_offset.cu_off;
+ }
+ return 0;
+ }
+@@ -2378,6 +2380,9 @@ needs_dwarf_reg_entry_value (struct dwarf_expr_context *ctx,
+ 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);
+ }
+
+ /* DW_OP_GNU_addr_index doesn't require a frame. */
+--- a/gdb/dwarf2read.c
++++ b/gdb/dwarf2read.c
+@@ -7816,7 +7816,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
+ child_die = sibling_die (child_die))
+ {
+ struct call_site_parameter *parameter;
+- struct attribute *loc;
++ struct attribute *loc, *origin;
+
+ if (child_die->tag != DW_TAG_GNU_call_site_parameter)
+ {
+@@ -7827,11 +7827,23 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
+ 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))
++ {
++ sect_offset offset;
++
++ parameter->kind = CALL_SITE_PARAMETER_PARAM_OFFSET;
++ offset = dwarf2_get_ref_die_offset (origin);
++ gdb_assert (offset.sect_off >= cu->header.offset.sect_off);
++ parameter->u.param_offset.cu_off = (offset.sect_off
++ - cu->header.offset.sect_off);
++ }
++ else if (loc == NULL || origin != NULL || !attr_form_is_block (loc))
+ {
+ complaint (&symfile_complaints,
+ _("No DW_FORM_block* DW_AT_location for "
+--- a/gdb/gdbtypes.h
++++ b/gdb/gdbtypes.h
+@@ -924,7 +924,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
+@@ -971,6 +974,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. */
++ cu_offset param_offset;
+ }
+ u;
+
+--- /dev/null
++++ b/gdb/testsuite/gdb.arch/amd64-entry-value-param.S
+@@ -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
+--- /dev/null
++++ b/gdb/testsuite/gdb.arch/amd64-entry-value-param.c
+@@ -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);
++}
+--- /dev/null
++++ b/gdb/testsuite/gdb.arch/amd64-entry-value-param.exp
+@@ -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 facb54b..d9fc09f 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: 3%{?dist}
+Release: 4%{?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
@@ -567,6 +567,10 @@ Patch694: gdb-disable-mcheck.patch
# Fix assertion on some files as glibc-2.15.90-8.fc18 (Doug Evans).
Patch695: gdb-index-assert.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
@@ -855,6 +859,8 @@ rm -f gdb/jv-exp.c gdb/m2-exp.c gdb/objc-exp.c gdb/p-exp.c
%patch693 -p1
%patch694 -p1
%patch695 -p1
+%patch696 -p1
+%patch697 -p1
%patch393 -p1
%if 0%{!?el5:1} || 0%{?scl:1}
@@ -1344,6 +1350,9 @@ fi
%endif # 0%{!?el5:1} || "%{_target_cpu}" == "noarch"
%changelog
+* Thu Jun 14 2012 Jan Kratochvil <jan.kratochvil at redhat.com> - 7.4.50.20120603-4.fc18
+- Support DW_OP_GNU_parameter_ref for -O2 -g inferiors (BZ 827375).
+
* Wed Jun 6 2012 Jan Kratochvil <jan.kratochvil at redhat.com> - 7.4.50.20120603-3.fc18
- Disable -lmcheck in the development builds.
- Fix assertion on some files as glibc-2.15.90-8.fc18 (Doug Evans).
More information about the scm-commits
mailing list