From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27791 invoked by alias); 12 Jun 2011 21:36:38 -0000 Mailing-List: contact archer-commits-help@sourceware.org; run by ezmlm Sender: Precedence: bulk List-Post: List-Help: List-Subscribe: Received: (qmail 27763 invoked by uid 9674); 12 Jun 2011 21:36:38 -0000 Date: Sun, 12 Jun 2011 21:36:00 -0000 Message-ID: <20110612213638.27747.qmail@sourceware.org> From: jkratoch@sourceware.org To: archer-commits@sourceware.org Subject: [SCM] archer-jankratochvil-entryval: entryvals X-Git-Refname: refs/heads/archer-jankratochvil-entryval X-Git-Reftype: branch X-Git-Oldrev: e6b412e5ab0429151655f396e1ade25d3c17efdb X-Git-Newrev: 1b8fd50a2e42d78c90a9a3403bcec8dd43e6fefb X-SW-Source: 2011-q2/txt/msg00061.txt.bz2 List-Id: The branch, archer-jankratochvil-entryval has been updated via 1b8fd50a2e42d78c90a9a3403bcec8dd43e6fefb (commit) from e6b412e5ab0429151655f396e1ade25d3c17efdb (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit 1b8fd50a2e42d78c90a9a3403bcec8dd43e6fefb Author: Jan Kratochvil Date: Sun Jun 12 23:36:17 2011 +0200 entryvals ----------------------------------------------------------------------- Summary of changes: gdb/dwarf2expr.c | 2 +- gdb/dwarf2expr.h | 3 + gdb/dwarf2loc.c | 116 +++++++++++++++++++++++++++++++++++++++++------------- gdb/f-valprint.c | 3 +- gdb/findvar.c | 5 +-- gdb/printcmd.c | 54 ++++++++++++++++++++++--- gdb/stack.c | 17 ++++++-- gdb/symtab.h | 5 ++ gdb/value.c | 11 +++++ gdb/value.h | 12 +++++- 10 files changed, 182 insertions(+), 46 deletions(-) First 500 lines of diff: diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c index e779de9..6f8d168 100644 --- a/gdb/dwarf2expr.c +++ b/gdb/dwarf2expr.c @@ -512,7 +512,7 @@ dwarf_block_to_regnum (const gdb_byte *buf, const gdb_byte *buf_end) *DEREF_SIZE_RETURN contains -1 for DW_OP_deref or the size from DW_OP_deref_size. */ -static int +int dwarf_block_to_regnum_deref (const gdb_byte *buf, const gdb_byte *buf_end, CORE_ADDR *deref_size_return) { diff --git a/gdb/dwarf2expr.h b/gdb/dwarf2expr.h index d889d2b..80035fd 100644 --- a/gdb/dwarf2expr.h +++ b/gdb/dwarf2expr.h @@ -251,4 +251,7 @@ void dwarf_expr_require_composition (const gdb_byte *, const gdb_byte *, int dwarf_block_to_regnum (const gdb_byte *buf, const gdb_byte *buf_end); +int dwarf_block_to_regnum_deref (const gdb_byte *buf, const gdb_byte *buf_end, + CORE_ADDR *deref_size_return); + #endif /* dwarf2expr.h */ diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c index 4addfde..f074866 100644 --- a/gdb/dwarf2loc.c +++ b/gdb/dwarf2loc.c @@ -718,17 +718,16 @@ call_site_find_chain (struct gdbarch *gdbarch, CORE_ADDR caller_pc, return retval; } -/* Using the frame specified in BATON return a stack entry evaluated for +/* Using the callee FRAME return a stack entry evaluated for DW_TAG_GNU_call_site's REGNUM at the caller. If DEREF_SIZE is not -1 then use DW_AT_GNU_call_site_data_value instead of DW_AT_GNU_call_site_value. - */ -static void -dwarf_expr_regnum_entry_value (struct dwarf_expr_context *ctx, int regnum, + Always return non-NULL, throw NOT_FOUND_ERROR otherwise. */ + +static struct dwarf2_locexpr_baton * +dwarf_expr_regnum_entry_value (struct frame_info *frame, int regnum, CORE_ADDR deref_size) { - struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) ctx->baton; - struct frame_info *frame = debaton->frame; CORE_ADDR func_addr = get_frame_func (frame); CORE_ADDR caller_pc; struct gdbarch *caller_gdbarch = frame_unwind_arch (frame); @@ -739,8 +738,6 @@ dwarf_expr_regnum_entry_value (struct dwarf_expr_context *ctx, int regnum, struct dwarf2_locexpr_baton *dwarf_block; struct call_site_parameter *parameter; CORE_ADDR target_addr; - struct dwarf_expr_baton baton_local; - struct dwarf_expr_context saved_ctx; if (caller_frame == NULL) { @@ -821,8 +818,24 @@ dwarf_expr_regnum_entry_value (struct dwarf_expr_context *ctx, int regnum, /* FIXME: Check the DEREF_SIZE value. */ } - /* Execute DWARF_BLOCK for CALLER_FRAME but with the same DWARF stack as - present in CTX. */ + return dwarf_block; +} + +/* Execute DWARF_BLOCK for CALLER_FRAME but with the same DWARF stack as + present in CTX. */ + +static void +dwarf_expr_push_regnum_entry_value (struct dwarf_expr_context *ctx, int regnum, + CORE_ADDR deref_size) +{ + struct dwarf_expr_baton *debaton = ctx->baton; + struct frame_info *frame = debaton->frame; + struct frame_info *caller_frame = get_prev_frame (frame); + struct dwarf2_locexpr_baton *dwarf_block; + struct dwarf_expr_baton baton_local; + struct dwarf_expr_context saved_ctx; + + dwarf_block = dwarf_expr_regnum_entry_value (frame, regnum, deref_size); baton_local.frame = caller_frame; baton_local.per_cu = dwarf_block->per_cu; @@ -844,6 +857,7 @@ dwarf_expr_regnum_entry_value (struct dwarf_expr_context *ctx, int regnum, ctx->baton = saved_ctx.baton; } + struct piece_closure { /* Reference count. */ @@ -1642,12 +1656,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, invalid_synthetic_pointer (); if (size == 0) - { - retval = allocate_value (type); - VALUE_LVAL (retval) = not_lval; - set_value_optimized_out (retval, 1); - return retval; - } + return allocate_optimized_out_value (type); baton.frame = frame; baton.per_cu = per_cu; @@ -1668,7 +1677,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, ctx->get_tls_address = dwarf_expr_tls_address; ctx->dwarf_call = dwarf_expr_dwarf_call; ctx->get_base_type = dwarf_expr_get_base_type; - ctx->push_regnum_entry_value = dwarf_expr_regnum_entry_value; + ctx->push_regnum_entry_value = dwarf_expr_push_regnum_entry_value; TRY_CATCH (ex, RETURN_MASK_ALL) { @@ -1690,9 +1699,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, if (info_verbose) exception_print (gdb_stdout, ex); - retval = allocate_value (type); - set_value_optimized_out (retval, 1); - return retval; + return allocate_optimized_out_value (type); } else throw_exception (ex); @@ -1807,9 +1814,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, case DWARF_VALUE_OPTIMIZED_OUT: do_cleanups (value_chain); - retval = allocate_value (type); - VALUE_LVAL (retval) = not_lval; - set_value_optimized_out (retval, 1); + retval = allocate_optimized_out_value (type); break; /* DWARF_VALUE_IMPLICIT_POINTER was converted to a pieced @@ -3316,6 +3321,7 @@ locexpr_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch, evaluator. */ const struct symbol_computed_ops dwarf2_locexpr_funcs = { locexpr_read_variable, + locexpr_read_variable, /* read_variable_at_entry */ locexpr_read_needs_frame, locexpr_describe_location, locexpr_tracepoint_var_ref @@ -3338,11 +3344,7 @@ loclist_read_variable (struct symbol *symbol, struct frame_info *frame) data = dwarf2_find_location_expression (dlbaton, &size, pc); if (data == NULL) - { - val = allocate_value (SYMBOL_TYPE (symbol)); - VALUE_LVAL (val) = not_lval; - set_value_optimized_out (val, 1); - } + val = allocate_optimized_out_value (SYMBOL_TYPE (symbol)); else val = dwarf2_evaluate_loc_desc (SYMBOL_TYPE (symbol), frame, data, size, dlbaton->per_cu); @@ -3350,6 +3352,63 @@ loclist_read_variable (struct symbol *symbol, struct frame_info *frame) return val; } +static struct value * +value_of_regnum_entry_value (struct type *type, struct frame_info *frame, + int regnum, CORE_ADDR deref_size) +{ + struct dwarf2_locexpr_baton *dwarf_block; + struct frame_info *caller_frame = get_prev_frame (frame); + gdb_byte *data; + + dwarf_block = dwarf_expr_regnum_entry_value (frame, regnum, deref_size); + + /* DW_AT_GNU_call_site_value is a DWARF expression, not a DWARF + location. */ + data = alloca (dwarf_block->size + 1); + memcpy (data, dwarf_block->data, dwarf_block->size); + data[dwarf_block->size] = DW_OP_stack_value; + + return dwarf2_evaluate_loc_desc (type, caller_frame, data, + dwarf_block->size + 1, dwarf_block->per_cu); +} + +/* Read variable by like loclist_read_variable at FRAME's function entry. */ + +static struct value * +loclist_read_variable_at_entry (struct symbol *symbol, struct frame_info *frame) +{ + struct dwarf2_loclist_baton *dlbaton = SYMBOL_LOCATION_BATON (symbol); + struct value *val; + const gdb_byte *data; + size_t size; + int regnum; + CORE_ADDR deref_size; + CORE_ADDR pc; + + if (frame == NULL || !get_frame_func_if_available (frame, &pc)) + return allocate_optimized_out_value (SYMBOL_TYPE (symbol)); + + data = dwarf2_find_location_expression (dlbaton, &size, pc); + if (data == NULL) + return allocate_optimized_out_value (SYMBOL_TYPE (symbol)); + + regnum = dwarf_block_to_regnum (data, data + size); + if (regnum != -1) + return value_of_regnum_entry_value (SYMBOL_TYPE (symbol), frame, regnum, + -1); + + regnum = dwarf_block_to_regnum_deref (data, data + size, &deref_size); + if (regnum != -1) + { + if (deref_size == -1) + deref_size = dwarf2_per_cu_addr_size (dlbaton->per_cu); + return value_of_regnum_entry_value (SYMBOL_TYPE (symbol), frame, regnum, + deref_size); + } + + return allocate_optimized_out_value (SYMBOL_TYPE (symbol)); +} + /* Return non-zero iff we need a frame to evaluate SYMBOL. */ static int loclist_read_needs_frame (struct symbol *symbol) @@ -3468,6 +3527,7 @@ loclist_tracepoint_var_ref (struct symbol *symbol, struct gdbarch *gdbarch, evaluator and location lists. */ const struct symbol_computed_ops dwarf2_loclist_funcs = { loclist_read_variable, + loclist_read_variable_at_entry, loclist_read_needs_frame, loclist_describe_location, loclist_tracepoint_var_ref diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 3280ddc..1d1c40f 100644 --- a/gdb/f-valprint.c +++ b/gdb/f-valprint.c @@ -596,7 +596,8 @@ info_common_command (char *comname, int from_tty) while (entry != NULL) { - print_variable_and_value (NULL, entry->symbol, fi, gdb_stdout, 0); + print_variable_and_value (NULL, entry->symbol, fi, gdb_stdout, 0, + PVAVD_IS_NOT_ARGUMENT); entry = entry->next; } } diff --git a/gdb/findvar.c b/gdb/findvar.c index 2b361ef..a700c02 100644 --- a/gdb/findvar.c +++ b/gdb/findvar.c @@ -577,10 +577,7 @@ read_var_value (struct symbol *var, struct frame_info *frame) break; case LOC_OPTIMIZED_OUT: - v = allocate_value_lazy (type); - VALUE_LVAL (v) = not_lval; - set_value_optimized_out (v, 1); - return v; + return allocate_optimized_out_value (type); default: error (_("Cannot look up value of a botched symbol.")); diff --git a/gdb/printcmd.c b/gdb/printcmd.c index f1ebb7e..90e9bde 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -1944,27 +1944,67 @@ clear_dangling_display_expressions (struct so_list *solib) void print_variable_and_value (const char *name, struct symbol *var, struct frame_info *frame, - struct ui_file *stream, int indent) + struct ui_file *stream, int indent, + enum print_argument print_argument) { volatile struct gdb_exception except; if (!name) name = SYMBOL_PRINT_NAME (var); - fprintf_filtered (stream, "%s%s = ", n_spaces (2 * indent), name); TRY_CATCH (except, RETURN_MASK_ERROR) { - struct value *val; + struct value *val, *entryval = NULL; struct value_print_options opts; val = read_var_value (var, frame); get_user_print_options (&opts); - common_val_print (val, stream, indent, &opts, current_language); + + if (print_argument != PVAVD_IS_NOT_ARGUMENT + && SYMBOL_CLASS (var) == LOC_COMPUTED + && (SYMBOL_COMPUTED_OPS (var)->read_variable_at_entry + != SYMBOL_COMPUTED_OPS (var)->read_variable)) + { + const struct symbol_computed_ops *ops; + unsigned len = TYPE_LENGTH (value_type (val)); + volatile struct gdb_exception entryval_ex; + + ops = SYMBOL_COMPUTED_OPS (var); + + TRY_CATCH (entryval_ex, RETURN_MASK_ERROR) + { + entryval = ops->read_variable_at_entry (var, frame); + } + + if (entryval_ex.reason < 0 || value_optimized_out (entryval)) + entryval = NULL; + else + { + if (!value_optimized_out (val) && value_lazy (entryval)) + value_fetch_lazy (entryval); + if (!value_optimized_out (val) + && value_available_contents_eq (val, 0, entryval, 0, len)) + entryval = NULL; + } + } + + if (print_argument != PVAVD_ARGUMENT_PRINT_ENTRYVAL_ONLY) + { + fprintf_filtered (stream, "%s%s = ", n_spaces (2 * indent), name); + common_val_print (val, stream, indent, &opts, current_language); + fputc_filtered ('\n', stream); + } + if (entryval) + { + fprintf_filtered (stream, "%s%s@entry = ", n_spaces (2 * indent), + name); + common_val_print (entryval, stream, indent, &opts, current_language); + fputc_filtered ('\n', stream); + } } if (except.reason < 0) - fprintf_filtered(stream, "", name, - except.message); - fprintf_filtered (stream, "\n"); + fprintf_filtered (stream, "%s%s = \n", + n_spaces (2 * indent), name, name, except.message); } /* printf "printf format string" ARG to STREAM. */ diff --git a/gdb/stack.c b/gdb/stack.c index 7d50435..e18c9e5 100644 --- a/gdb/stack.c +++ b/gdb/stack.c @@ -1611,6 +1611,7 @@ struct print_variable_and_value_data int num_tabs; struct ui_file *stream; int values_printed; + enum print_argument print_argument; }; /* The callback for the locals and args iterators. */ @@ -1622,13 +1623,13 @@ do_print_variable_and_value (const char *print_name, { struct print_variable_and_value_data *p = cb_data; - print_variable_and_value (print_name, sym, - p->frame, p->stream, p->num_tabs); + print_variable_and_value (print_name, sym, p->frame, p->stream, p->num_tabs, + p->print_argument); p->values_printed = 1; } static void -print_frame_local_vars (struct frame_info *frame, int num_tabs, +print_frame_local_vars (struct frame_info *frame, int from_frame, struct ui_file *stream) { struct print_variable_and_value_data cb_data; @@ -1650,10 +1651,17 @@ print_frame_local_vars (struct frame_info *frame, int num_tabs, } cb_data.frame = frame; - cb_data.num_tabs = 4 * num_tabs; + cb_data.num_tabs = from_frame ? 4 : 0; cb_data.stream = stream; cb_data.values_printed = 0; + if (from_frame) + { + cb_data.print_argument = PVAVD_ARGUMENT_PRINT_ENTRYVAL_ONLY; + iterate_over_block_arg_vars (block, do_print_variable_and_value, &cb_data); + } + + cb_data.print_argument = PVAVD_IS_NOT_ARGUMENT; iterate_over_block_local_vars (block, do_print_variable_and_value, &cb_data); @@ -1813,6 +1821,7 @@ print_frame_arg_vars (struct frame_info *frame, struct ui_file *stream) cb_data.stream = gdb_stdout; cb_data.values_printed = 0; + cb_data.print_argument = PVAVD_ARGUMENT_PRINT_BOTH; iterate_over_block_arg_vars (SYMBOL_BLOCK_VALUE (func), do_print_variable_and_value, &cb_data); diff --git a/gdb/symtab.h b/gdb/symtab.h index 12f52a2..2a3a62e 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -532,6 +532,11 @@ struct symbol_computed_ops struct value *(*read_variable) (struct symbol * symbol, struct frame_info * frame); + /* Like read_variable but for the first instruction of a function of FRAME. + Return NULL if such value is not known. */ + struct value *(*read_variable_at_entry) (struct symbol *symbol, + struct frame_info *frame); + /* Return non-zero if we need a frame to find the value of the SYMBOL. */ int (*read_needs_frame) (struct symbol * symbol); diff --git a/gdb/value.c b/gdb/value.c index ccd29c8..6b77522 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -728,6 +728,17 @@ allocate_computed_value (struct type *type, return v; } +struct value * +allocate_optimized_out_value (struct type *type) +{ + struct value *retval = allocate_value (type); + + VALUE_LVAL (retval) = not_lval; + set_value_optimized_out (retval, 1); + + return retval; +} + /* Accessor methods. */ struct value * diff --git a/gdb/value.h b/gdb/value.h index 65d0a02..41445da 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -207,6 +207,8 @@ extern struct value *allocate_computed_value (struct type *type, struct lval_funcs *funcs, void *closure); +extern struct value *allocate_optimized_out_value (struct type *type); + /* If VALUE is lval_computed, return its lval_funcs structure. */ extern struct lval_funcs *value_computed_funcs (struct value *value); @@ -798,11 +800,19 @@ extern int val_print_string (struct type *elttype, const char *encoding, struct ui_file *stream, const struct value_print_options *options); +enum print_argument +{ + PVAVD_IS_NOT_ARGUMENT, + PVAVD_ARGUMENT_PRINT_ENTRYVAL_ONLY, + PVAVD_ARGUMENT_PRINT_BOTH, +}; + extern void print_variable_and_value (const char *name, struct symbol *var, struct frame_info *frame, struct ui_file *stream, - int indent); + int indent, + enum print_argument print_argument); extern int check_field (struct type *, const char *); hooks/post-receive -- Repository for Project Archer.