From 31e8955039c423a41aeb76056f3eb4640752d2ff Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Thu, 14 Jun 2012 09:41:43 +0200 Subject: [PATCH] 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 deletion(-) create mode 100644 gdb-parameterref-1of2.patch create mode 100644 gdb-parameterref-2of2.patch 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 + + Code cleanup: Generalize call_site.parameter key. + * dwarf2expr.c (execute_stack_op) : 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 + + * 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 + + * 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 . */ ++ ++/* 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",@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,"",@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,"",@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,"",@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,"",@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,"",@progbits ++.Ldebug_ranges0: ++ .quad .Ltext0 /* Offset 0 */ ++ .quad .Letext0 ++ .quad .LFB2 /* Offset 0x10 */ ++ .quad .LFE2 ++ .quad 0 ++ .quad 0 ++ .section .debug_line,"",@progbits ++.Ldebug_line0: ++ .section .debug_str,"MS",@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,"",@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 . */ ++ ++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 . ++ ++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 - 7.4.50.20120603-4.fc18 +- Support DW_OP_GNU_parameter_ref for -O2 -g inferiors (BZ 827375). + * Wed Jun 6 2012 Jan Kratochvil - 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).