From patchwork Fri Jul 11 09:21:16 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keven Boell X-Patchwork-Id: 2023 Received: (qmail 31961 invoked by alias); 11 Jul 2014 09:22:03 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 31715 invoked by uid 89); 11 Jul 2014 09:22:01 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.3 required=5.0 tests=AWL, BAYES_00, KAM_STOCKGEN, RP_MATCHES_RCVD autolearn=no version=3.3.2 X-HELO: mga03.intel.com Received: from mga03.intel.com (HELO mga03.intel.com) (143.182.124.21) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 11 Jul 2014 09:21:56 +0000 Received: from azsmga001.ch.intel.com ([10.2.17.19]) by azsmga101.ch.intel.com with ESMTP; 11 Jul 2014 02:21:54 -0700 X-ExtLoop1: 1 Received: from irvmail001.ir.intel.com ([163.33.26.43]) by azsmga001.ch.intel.com with ESMTP; 11 Jul 2014 02:21:39 -0700 Received: from ullecvh004g04.iul.intel.com (ullecvh004g04.iul.intel.com [172.28.50.14]) by irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id s6B9LdHx020712; Fri, 11 Jul 2014 10:21:39 +0100 Received: from ullecvh004g04.iul.intel.com (ullecvh004g04.iul.intel.com [127.0.0.1]) by ullecvh004g04.iul.intel.com (8.13.8/8.13.8) with ESMTP id s6B9LeB9007009; Fri, 11 Jul 2014 11:21:40 +0200 Received: (from kboell@localhost) by ullecvh004g04.iul.intel.com (8.13.8/8.13.8/Submit) id s6B9LeIk007008; Fri, 11 Jul 2014 11:21:40 +0200 From: Keven Boell To: gdb-patches@sourceware.org Cc: keven.boell@intel.com, sanimir.agovic@intel.com Subject: [V2 04/23] vla: make dynamic fortran arrays functional. Date: Fri, 11 Jul 2014 11:21:16 +0200 Message-Id: <1405070495-6948-5-git-send-email-keven.boell@intel.com> In-Reply-To: <1405070495-6948-1-git-send-email-keven.boell@intel.com> References: <1405070495-6948-1-git-send-email-keven.boell@intel.com> This patch enables GDB to print the value of a dynamic array (VLA) if allocated/associated in fortran. If not the allocation status will be printed to the command line. (gdb) p vla_not_allocated $1 = (gdb) p vla_allocated $1 = (1, 2, 3) (gdb) p vla_not_associated $1 = (gdb) p vla_associated $1 = (3, 2, 1) The patch covers various locations where the allocation/ association status makes sense to print. 2014-05-28 Keven Boell Sanimir Agovic * dwarf2loc.c (dwarf2_address_data_valid): New function. * dwarf2loc.h (dwarf2_address_data_valid): New function. * f-typeprint.c (f_print_type): Print allocation/ association status. (f_type_print_varspec_suffix): Print allocation/ association status for &-operator usages. * gdbtypes.c (create_array_type_with_stride): Add query for valid data location. (is_dynamic_type): Extend dynamic type detection with allocated/associated. Add type detection for fields. (resolve_dynamic_range): Copy type before resolving it as dynamic attributes need to be preserved. (resolve_dynamic_array): Copy type before resolving it as dynamic attributes need to be preserved. Add resolving of allocated/associated attributes. (resolve_dynamic_type): Add call to nested type resolving. (copy_type_recursive): Add allocated/associated attributes to be copied. (copy_type): Copy allocated/associated/data_location as well as the fields structure if available. * valarith.c (value_subscripted_rvalue): Print allocated/ associated status when indexing a VLA. * valprint.c (valprint_check_validity): Print allocated/ associated status. (val_print_not_allocated): New function. (val_print_not_associated): New function. * valprint.h (val_print_not_allocated): New function. (val_print_not_associated): New function. * value.c (set_value_component_location): Adjust the value address for single value prints. Change-Id: Idfb44c8a6b38008f8e2c84cb0fdb13729ec160f4 Signed-off-by: Keven Boell --- gdb/dwarf2loc.c | 19 ++++++++++ gdb/dwarf2loc.h | 6 ++++ gdb/f-typeprint.c | 62 ++++++++++++++++++++++----------- gdb/gdbtypes.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++--- gdb/valarith.c | 9 ++++- gdb/valprint.c | 40 +++++++++++++++++++++ gdb/valprint.h | 4 +++ gdb/value.c | 20 +++++++++++ 8 files changed, 233 insertions(+), 27 deletions(-) diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c index eaa499e..a624dac 100644 --- a/gdb/dwarf2loc.c +++ b/gdb/dwarf2loc.c @@ -2346,6 +2346,11 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, int in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 0); do_cleanups (value_chain); + + /* Select right frame to correctly evaluate VLA's during a backtrace. */ + if (is_dynamic_type (type)) + select_frame (frame); + retval = value_at_lazy (type, address + byte_offset); if (in_stack_memory) set_value_stack (retval, 1); @@ -2569,6 +2574,20 @@ dwarf2_evaluate_property (const struct dynamic_prop *prop, CORE_ADDR address, return 0; } +/* See dwarf2loc.h. */ + +int +dwarf2_address_data_valid (const struct type *type) +{ + if (TYPE_NOT_ASSOCIATED (type)) + return 0; + + if (TYPE_NOT_ALLOCATED (type)) + return 0; + + return 1; +} + /* Helper functions and baton for dwarf2_loc_desc_needs_frame. */ diff --git a/gdb/dwarf2loc.h b/gdb/dwarf2loc.h index 04e2792..fb65c5c 100644 --- a/gdb/dwarf2loc.h +++ b/gdb/dwarf2loc.h @@ -102,6 +102,12 @@ int dwarf2_evaluate_property (const struct dynamic_prop *prop, CORE_ADDR dwarf2_read_addr_index (struct dwarf2_per_cu_data *per_cu, unsigned int addr_index); +/* Checks if a dwarf location definition is valid. + Returns 1 if valid; 0 otherwise. */ + +extern int dwarf2_address_data_valid (const struct type *type); + + /* The symbol location baton types used by the DWARF-2 reader (i.e. SYMBOL_LOCATION_BATON for a LOC_COMPUTED symbol). "struct dwarf2_locexpr_baton" is for a symbol with a single location diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c index 8356aab..69e67f4 100644 --- a/gdb/f-typeprint.c +++ b/gdb/f-typeprint.c @@ -30,6 +30,7 @@ #include "gdbcore.h" #include "target.h" #include "f-lang.h" +#include "valprint.h" #include #include @@ -56,6 +57,17 @@ f_print_type (struct type *type, const char *varstring, struct ui_file *stream, enum type_code code; int demangled_args; + if (TYPE_NOT_ASSOCIATED (type)) + { + val_print_not_associated (stream); + return; + } + if (TYPE_NOT_ALLOCATED (type)) + { + val_print_not_allocated (stream); + return; + } + f_type_print_base (type, stream, show, level); code = TYPE_CODE (type); if ((varstring != NULL && *varstring != '\0') @@ -170,28 +182,36 @@ f_type_print_varspec_suffix (struct type *type, struct ui_file *stream, if (arrayprint_recurse_level == 1) fprintf_filtered (stream, "("); - if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_ARRAY) - f_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0, 0, - arrayprint_recurse_level); - - lower_bound = f77_get_lowerbound (type); - if (lower_bound != 1) /* Not the default. */ - fprintf_filtered (stream, "%d:", lower_bound); - - /* Make sure that, if we have an assumed size array, we - print out a warning and print the upperbound as '*'. */ - - if (TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (type)) - fprintf_filtered (stream, "*"); + if (TYPE_NOT_ASSOCIATED (type)) + val_print_not_associated (stream); + else if (TYPE_NOT_ALLOCATED (type)) + val_print_not_allocated (stream); else - { - upper_bound = f77_get_upperbound (type); - fprintf_filtered (stream, "%d", upper_bound); - } - - if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_ARRAY) - f_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0, 0, - arrayprint_recurse_level); + { + + if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_ARRAY) + f_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0, 0, + arrayprint_recurse_level); + + lower_bound = f77_get_lowerbound (type); + if (lower_bound != 1) /* Not the default. */ + fprintf_filtered (stream, "%d:", lower_bound); + + /* Make sure that, if we have an assumed size array, we + print out a warning and print the upperbound as '*'. */ + + if (TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (type)) + fprintf_filtered (stream, "*"); + else + { + upper_bound = f77_get_upperbound (type); + fprintf_filtered (stream, "%d", upper_bound); + } + + if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_ARRAY) + f_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0, 0, + arrayprint_recurse_level); + } if (arrayprint_recurse_level == 1) fprintf_filtered (stream, ")"); else diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index f4da142..c7c5c3b 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -1003,7 +1003,8 @@ create_array_type_with_stride (struct type *result_type, TYPE_CODE (result_type) = TYPE_CODE_ARRAY; TYPE_TARGET_TYPE (result_type) = element_type; - if (has_static_range (TYPE_RANGE_DATA (range_type))) + if (has_static_range (TYPE_RANGE_DATA (range_type)) + && dwarf2_address_data_valid (result_type)) { LONGEST low_bound, high_bound; @@ -1616,11 +1617,30 @@ stub_noname_complaint (void) int is_dynamic_type (struct type *type) { + int index; + + if (!type) + return 0; + type = check_typedef (type); if (TYPE_CODE (type) == TYPE_CODE_REF) type = check_typedef (TYPE_TARGET_TYPE (type)); + if (TYPE_ASSOCIATED_PROP (type)) + return 1; + + if (TYPE_ALLOCATED_PROP (type)) + return 1; + + /* Scan field types in the Fortran case for nested dynamic types. + This will be done only for Fortran as in the C++ case an endless recursion + can occur in the area of classes. */ + if (current_language->la_language == language_fortran) + for (index = 0; index < TYPE_NFIELDS (type); index++) + if (is_dynamic_type (TYPE_FIELD_TYPE (type, index))) + return 1; + switch (TYPE_CODE (type)) { case TYPE_CODE_RANGE: @@ -1672,6 +1692,7 @@ resolve_dynamic_range (struct type *dyn_range_type, CORE_ADDR addr) const struct dynamic_prop *prop; const struct dwarf2_locexpr_baton *baton; struct dynamic_prop low_bound, high_bound; + struct type *range_copy = copy_type (dyn_range_type); gdb_assert (TYPE_CODE (dyn_range_type) == TYPE_CODE_RANGE); @@ -1703,8 +1724,8 @@ resolve_dynamic_range (struct type *dyn_range_type, CORE_ADDR addr) high_bound.data.const_val = 0; } - static_range_type = create_range_type (copy_type (dyn_range_type), - TYPE_TARGET_TYPE (dyn_range_type), + static_range_type = create_range_type (range_copy, + TYPE_TARGET_TYPE (range_copy), &low_bound, &high_bound); TYPE_RANGE_DATA (static_range_type)->flag_bound_evaluated = 1; return static_range_type; @@ -1721,6 +1742,8 @@ resolve_dynamic_array (struct type *type, CORE_ADDR addr) struct type *elt_type; struct type *range_type; struct type *ary_dim; + struct dynamic_prop *prop; + struct type *copy = copy_type (type); gdb_assert (TYPE_CODE (type) == TYPE_CODE_ARRAY); @@ -1728,14 +1751,28 @@ resolve_dynamic_array (struct type *type, CORE_ADDR addr) range_type = check_typedef (TYPE_INDEX_TYPE (elt_type)); range_type = resolve_dynamic_range (range_type, addr); + prop = TYPE_ALLOCATED_PROP (type); + if (dwarf2_evaluate_property (prop, addr, &value)) + { + TYPE_ALLOCATED_PROP (copy)->kind = PROP_CONST; + TYPE_ALLOCATED_PROP (copy)->data.const_val = value; + } + + prop = TYPE_ASSOCIATED_PROP (type); + if (dwarf2_evaluate_property (prop, addr, &value)) + { + TYPE_ASSOCIATED_PROP (copy)->kind = PROP_CONST; + TYPE_ASSOCIATED_PROP (copy)->data.const_val = value; + } + ary_dim = check_typedef (TYPE_TARGET_TYPE (elt_type)); if (ary_dim != NULL && TYPE_CODE (ary_dim) == TYPE_CODE_ARRAY) - elt_type = resolve_dynamic_array (TYPE_TARGET_TYPE (type), addr); + elt_type = resolve_dynamic_array (TYPE_TARGET_TYPE (copy), addr); else elt_type = TYPE_TARGET_TYPE (type); - return create_array_type (copy_type (type), + return create_array_type (copy, elt_type, range_type); } @@ -1831,6 +1868,7 @@ resolve_dynamic_struct (struct type *type, CORE_ADDR addr) return resolved_type; } + /* See gdbtypes.h */ struct type * @@ -4105,6 +4143,20 @@ copy_type_recursive (struct objfile *objfile, *TYPE_DATA_LOCATION (new_type) = *TYPE_DATA_LOCATION (type); } + /* Copy allocated information. */ + if (TYPE_ALLOCATED_PROP (type) != NULL) + { + TYPE_ALLOCATED_PROP (new_type) = xmalloc (sizeof (struct dynamic_prop)); + *TYPE_ALLOCATED_PROP (new_type) = *TYPE_ALLOCATED_PROP (type); + } + + /* Copy associated information. */ + if (TYPE_ASSOCIATED_PROP (type) != NULL) + { + TYPE_ASSOCIATED_PROP (new_type) = xmalloc (sizeof (struct dynamic_prop)); + *TYPE_ASSOCIATED_PROP (new_type) = *TYPE_ASSOCIATED_PROP (type); + } + /* Copy pointers to other types. */ if (TYPE_TARGET_TYPE (type)) TYPE_TARGET_TYPE (new_type) = @@ -4151,6 +4203,44 @@ copy_type (const struct type *type) memcpy (TYPE_MAIN_TYPE (new_type), TYPE_MAIN_TYPE (type), sizeof (struct main_type)); + if (TYPE_ALLOCATED_PROP (type)) + { + TYPE_ALLOCATED_PROP (new_type) + = OBSTACK_ZALLOC (&TYPE_OWNER (type).objfile->objfile_obstack, + struct dynamic_prop); + memcpy (TYPE_ALLOCATED_PROP (new_type), TYPE_ALLOCATED_PROP (type), + sizeof (struct dynamic_prop)); + } + + if (TYPE_ASSOCIATED_PROP (type)) + { + TYPE_ASSOCIATED_PROP (new_type) + = OBSTACK_ZALLOC (&TYPE_OWNER (type).objfile->objfile_obstack, + struct dynamic_prop); + memcpy (TYPE_ASSOCIATED_PROP (new_type), TYPE_ASSOCIATED_PROP (type), + sizeof (struct dynamic_prop)); + } + + if (TYPE_DATA_LOCATION (type)) + { + TYPE_DATA_LOCATION (new_type) + = OBSTACK_ZALLOC (&TYPE_OWNER (type).objfile->objfile_obstack, + struct dynamic_prop); + memcpy (TYPE_DATA_LOCATION (new_type), TYPE_DATA_LOCATION (type), + sizeof (struct dynamic_prop)); + } + + if (TYPE_NFIELDS (type)) + { + int nfields = TYPE_NFIELDS (type); + + TYPE_FIELDS (new_type) + = OBSTACK_CALLOC (&TYPE_OWNER (type).objfile->objfile_obstack, + nfields, struct field); + memcpy (TYPE_FIELDS (new_type), TYPE_FIELDS (type), + nfields * sizeof (struct field)); + } + return new_type; } diff --git a/gdb/valarith.c b/gdb/valarith.c index 4da41cb..3e7685a 100644 --- a/gdb/valarith.c +++ b/gdb/valarith.c @@ -200,7 +200,14 @@ value_subscripted_rvalue (struct value *array, LONGEST index, int lowerbound) if (index < lowerbound || (!TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (array_type) && elt_offs >= TYPE_LENGTH (array_type))) - error (_("no such vector element")); + { + if (TYPE_NOT_ASSOCIATED (array_type)) + error (_("no such vector element because not associated")); + else if (TYPE_NOT_ALLOCATED (array_type)) + error (_("no such vector element because not allocated")); + else + error (_("no such vector element")); + } if (VALUE_LVAL (array) == lval_memory && value_lazy (array)) v = allocate_value_lazy (elt_type); diff --git a/gdb/valprint.c b/gdb/valprint.c index 8600b34..2f8eac1 100644 --- a/gdb/valprint.c +++ b/gdb/valprint.c @@ -307,6 +307,18 @@ valprint_check_validity (struct ui_file *stream, { CHECK_TYPEDEF (type); + if (TYPE_NOT_ASSOCIATED (type)) + { + val_print_not_associated (stream); + return 0; + } + + if (TYPE_NOT_ALLOCATED (type)) + { + val_print_not_allocated (stream); + return 0; + } + if (TYPE_CODE (type) != TYPE_CODE_UNION && TYPE_CODE (type) != TYPE_CODE_STRUCT && TYPE_CODE (type) != TYPE_CODE_ARRAY) @@ -362,6 +374,18 @@ val_print_invalid_address (struct ui_file *stream) fprintf_filtered (stream, _("")); } +void +val_print_not_allocated (struct ui_file *stream) +{ + fprintf_filtered (stream, _("")); +} + +void +val_print_not_associated (struct ui_file *stream) +{ + fprintf_filtered (stream, _("")); +} + /* A generic val_print that is suitable for use by language implementations of the la_val_print method. This function can handle most type codes, though not all, notably exception @@ -803,12 +827,16 @@ static int value_check_printable (struct value *val, struct ui_file *stream, const struct value_print_options *options) { + const struct type *type; + if (val == 0) { fprintf_filtered (stream, _("
")); return 0; } + type = value_type (val); + if (value_entirely_optimized_out (val)) { if (options->summary && !val_print_scalar_type_p (value_type (val))) @@ -834,6 +862,18 @@ value_check_printable (struct value *val, struct ui_file *stream, return 0; } + if (TYPE_NOT_ASSOCIATED (type)) + { + val_print_not_associated (stream); + return 0; + } + + if (TYPE_NOT_ALLOCATED (type)) + { + val_print_not_allocated (stream); + return 0; + } + return 1; } diff --git a/gdb/valprint.h b/gdb/valprint.h index 6698247..7a415cf 100644 --- a/gdb/valprint.h +++ b/gdb/valprint.h @@ -217,4 +217,8 @@ extern void output_command_const (const char *args, int from_tty); extern int val_print_scalar_type_p (struct type *type); +extern void val_print_not_allocated (struct ui_file *stream); + +extern void val_print_not_associated (struct ui_file *stream); + #endif diff --git a/gdb/value.c b/gdb/value.c index 3c73683..1d514a5 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -43,6 +43,7 @@ #include "tracepoint.h" #include "cp-abi.h" #include "user-regs.h" +#include "dwarf2loc.h" /* Prototypes for exported functions. */ @@ -1646,6 +1647,25 @@ set_value_component_location (struct value *component, if (funcs->copy_closure) component->location.computed.closure = funcs->copy_closure (whole); } + + /* For dynamic types compute the address of the component value location in + sub range types based on the location of the sub range type, if not being + an internal GDB variable or parts of it. */ + if (VALUE_LVAL (component) != lval_internalvar + && VALUE_LVAL (component) != lval_internalvar_component) + { + CORE_ADDR addr; + struct type *type = value_type (whole); + + addr = value_raw_address (component); + + if (TYPE_DATA_LOCATION (type) + && TYPE_DATA_LOCATION_KIND (type) == PROP_CONST) + { + addr = TYPE_DATA_LOCATION_ADDR (type); + set_value_address (component, addr); + } + } }