From patchwork Fri Jul 11 09:21:21 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Keven Boell X-Patchwork-Id: 2016 Received: (qmail 30168 invoked by alias); 11 Jul 2014 09:21:50 -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 30106 invoked by uid 89); 11 Jul 2014 09:21:49 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mga02.intel.com Received: from mga02.intel.com (HELO mga02.intel.com) (134.134.136.20) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 11 Jul 2014 09:21:44 +0000 Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga101.jf.intel.com with ESMTP; 11 Jul 2014 02:21:44 -0700 X-ExtLoop1: 1 Received: from irvmail001.ir.intel.com ([163.33.26.43]) by orsmga001.jf.intel.com with ESMTP; 11 Jul 2014 02:21:42 -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 s6B9LgTJ020728; Fri, 11 Jul 2014 10:21:42 +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 s6B9Lhdl007029; Fri, 11 Jul 2014 11:21:43 +0200 Received: (from kboell@localhost) by ullecvh004g04.iul.intel.com (8.13.8/8.13.8/Submit) id s6B9LgQH007028; Fri, 11 Jul 2014 11:21:42 +0200 From: Keven Boell To: gdb-patches@sourceware.org Cc: keven.boell@intel.com, sanimir.agovic@intel.com Subject: [V2 09/23] vla: changed string length semantic. Date: Fri, 11 Jul 2014 11:21:21 +0200 Message-Id: <1405070495-6948-10-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 changes the semantic of the Dwarf string length attribute to reflect the standard. This serves as pre-work to get variable strings in Fortran to work. 2014-05-28 Keven Boell Sanimir Agovic * dwarf2read.c (read_tag_string_type): changed semantic of DW_AT_string_length to be able to handle Dwarf blocks as well. Support for DW_AT_byte_length added to get correct length if specified in combination with DW_AT_string_length. (attr_to_dynamic_prop): added functionality to add Dwarf operators to baton data attribute. Added post values to baton as required by the string evaluation case. (read_subrange_type): Adapt caller. (set_die_type): Adapt caller. (add_post_values_to_baton): New function. * dwarf2loc.c (dwarf2_evaluate_property): Evaluate post processing dwarf. * dwarf2loc.h (struct dwarf2_property_baton): Add post dwarf values attribute. Change-Id: I6edfa005f416cddc8e364d34891b9abf6b44f757 Signed-off-by: Keven Boell --- gdb/dwarf2read.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 126 insertions(+), 18 deletions(-) } + /* Parse dwarf attribute if it's a block, reference or constant and put the resulting value of the attribute into struct bound_prop. Returns 1 if ATTR could be resolved into PROP, 0 otherwise. */ static int attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die, - struct dwarf2_cu *cu, struct dynamic_prop *prop) + struct dwarf2_cu *cu, struct dynamic_prop *prop, + const gdb_byte *additional_data, int additional_data_size) { struct dwarf2_property_baton *baton; struct obstack *obstack = &cu->objfile->objfile_obstack; @@ -14559,8 +14632,25 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die, baton = obstack_alloc (obstack, sizeof (*baton)); baton->referenced_type = NULL; baton->locexpr.per_cu = cu->per_cu; - baton->locexpr.size = DW_BLOCK (attr)->size; - baton->locexpr.data = DW_BLOCK (attr)->data; + + if (additional_data != NULL && additional_data_size > 0) + { + gdb_byte *data; + + data = obstack_alloc (&cu->objfile->objfile_obstack, + DW_BLOCK (attr)->size + additional_data_size); + memcpy (data, DW_BLOCK (attr)->data, DW_BLOCK (attr)->size); + memcpy (data + DW_BLOCK (attr)->size, + additional_data, additional_data_size); + + baton->locexpr.data = data; + baton->locexpr.size = DW_BLOCK (attr)->size + additional_data_size; + } + else + { + baton->locexpr.data = DW_BLOCK (attr)->data; + baton->locexpr.size = DW_BLOCK (attr)->size; + } prop->data.baton = baton; prop->kind = PROP_LOCEXPR; gdb_assert (prop->data.baton != NULL); @@ -14590,8 +14680,26 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die, baton = obstack_alloc (obstack, sizeof (*baton)); baton->referenced_type = die_type (target_die, target_cu); baton->locexpr.per_cu = cu->per_cu; - baton->locexpr.size = DW_BLOCK (target_attr)->size; - baton->locexpr.data = DW_BLOCK (target_attr)->data; + + if (additional_data != NULL && additional_data_size > 0) + { + gdb_byte *data; + + data = obstack_alloc (&cu->objfile->objfile_obstack, + DW_BLOCK (attr)->size + additional_data_size); + memcpy (data, DW_BLOCK (attr)->data, DW_BLOCK (attr)->size); + memcpy (data + DW_BLOCK (attr)->size, + additional_data, additional_data_size); + + baton->locexpr.data = data; + baton->locexpr.size = DW_BLOCK (attr)->size + additional_data_size; + } + else + { + baton->locexpr.data = DW_BLOCK (attr)->data; + baton->locexpr.size = DW_BLOCK (attr)->size; + } + prop->data.baton = baton; prop->kind = PROP_LOCEXPR; gdb_assert (prop->data.baton != NULL); @@ -14681,17 +14789,17 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) attr = dwarf2_attr (die, DW_AT_lower_bound, cu); if (attr) - attr_to_dynamic_prop (attr, die, cu, &low); + attr_to_dynamic_prop (attr, die, cu, &low, NULL, 0); else if (!low_default_is_valid) complaint (&symfile_complaints, _("Missing DW_AT_lower_bound " "- DIE at 0x%x [in module %s]"), die->offset.sect_off, objfile_name (cu->objfile)); attr = dwarf2_attr (die, DW_AT_upper_bound, cu); - if (!attr_to_dynamic_prop (attr, die, cu, &high)) + if (!attr_to_dynamic_prop (attr, die, cu, &high, NULL, 0)) { attr = dwarf2_attr (die, DW_AT_count, cu); - if (attr_to_dynamic_prop (attr, die, cu, &high)) + if (attr_to_dynamic_prop (attr, die, cu, &high, NULL, 0)) { /* If bounds are constant do the final calculation here. */ if (low.kind == PROP_CONST && high.kind == PROP_CONST) @@ -21695,7 +21803,7 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu) { struct dynamic_prop prop; - if (attr_to_dynamic_prop (attr, die, cu, &prop)) + if (attr_to_dynamic_prop (attr, die, cu, &prop, NULL, 0)) { TYPE_ALLOCATED_PROP (type) = obstack_alloc (&objfile->objfile_obstack, sizeof (prop)); @@ -21709,7 +21817,7 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu) { struct dynamic_prop prop; - if (attr_to_dynamic_prop (attr, die, cu, &prop)) + if (attr_to_dynamic_prop (attr, die, cu, &prop, NULL, 0)) { TYPE_ASSOCIATED_PROP (type) = obstack_alloc (&objfile->objfile_obstack, sizeof (prop)); @@ -21719,7 +21827,7 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu) /* Read DW_AT_data_location and set in type. */ attr = dwarf2_attr (die, DW_AT_data_location, cu); - if (attr_to_dynamic_prop (attr, die, cu, &prop)) + if (attr_to_dynamic_prop (attr, die, cu, &prop, NULL, 0)) { TYPE_DATA_LOCATION (type) = obstack_alloc (&objfile->objfile_obstack, sizeof (prop)); diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index f612cd8..9b755b2 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -1847,6 +1847,12 @@ static void free_dwo_file_cleanup (void *); static void process_cu_includes (void); static void check_producer (struct dwarf2_cu *cu); + +static int +attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die, + struct dwarf2_cu *cu, struct dynamic_prop *prop, + const gdb_byte *additional_data, int additional_data_size); + /* Various complaints about symbol reading that don't abort the process. */ @@ -14201,29 +14207,94 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu) struct gdbarch *gdbarch = get_objfile_arch (objfile); struct type *type, *range_type, *index_type, *char_type; struct attribute *attr; - unsigned int length; + unsigned int length = UINT_MAX; + index_type = objfile_type (objfile)->builtin_int; + range_type = create_static_range_type (NULL, index_type, 1, length); + + /* If DW_AT_string_length is defined, the length is stored at some location + * in memory. */ attr = dwarf2_attr (die, DW_AT_string_length, cu); if (attr) { - length = DW_UNSND (attr); + if (attr_form_is_block (attr)) + { + struct attribute *byte_size, *bit_size; + struct dynamic_prop high; + + byte_size = dwarf2_attr (die, DW_AT_byte_size, cu); + bit_size = dwarf2_attr (die, DW_AT_bit_size, cu); + + /* DW_AT_byte_size should never occur together in combination with + DW_AT_string_length. */ + if ((byte_size == NULL && bit_size != NULL) || + (byte_size != NULL && bit_size == NULL)) + complaint (&symfile_complaints, _("DW_AT_byte_size AND " + "DW_AT_bit_size found together at the same time.")); + + /* If DW_AT_string_length AND DW_AT_byte_size exist together, it + describes the number of bytes that should be read from the length + memory location. */ + if (byte_size != NULL && bit_size == NULL) + { + /* Build new dwarf2_locexpr_baton structure with additions to the + data attribute, to reflect DWARF specialities to get address + sizes. */ + const gdb_byte append_ops[] = { + /* DW_OP_deref_size: size of an address on the target machine + (bytes), where the size will be specified by the next + operand. */ + DW_OP_deref_size, + /* Operand for DW_OP_deref_size. */ + DW_UNSND (byte_size) }; + + if (!attr_to_dynamic_prop (attr, die, cu, &high, + append_ops, ARRAY_SIZE (append_ops))) + complaint (&symfile_complaints, + _("Could not parse DW_AT_byte_size")); + } + else if (bit_size != NULL && byte_size == NULL) + complaint (&symfile_complaints, _("DW_AT_string_length AND " + "DW_AT_bit_size found but not supported yet.")); + /* If DW_AT_string_length WITHOUT DW_AT_byte_size exist, the default + is the address size of the target machine. */ + else + { + const gdb_byte append_ops[] = { DW_OP_deref }; + + if (!attr_to_dynamic_prop (attr, die, cu, &high, append_ops, + ARRAY_SIZE (append_ops))) + complaint (&symfile_complaints, + _("Could not parse DW_AT_string_length")); + } + + TYPE_RANGE_DATA (range_type)->high = high; + } + else + { + TYPE_HIGH_BOUND (range_type) = DW_UNSND (attr); + TYPE_HIGH_BOUND_KIND (range_type) = PROP_CONST; + } } else { - /* Check for the DW_AT_byte_size attribute. */ + /* Check for the DW_AT_byte_size attribute, which represents the length + in this case. */ attr = dwarf2_attr (die, DW_AT_byte_size, cu); if (attr) { - length = DW_UNSND (attr); + TYPE_HIGH_BOUND (range_type) = DW_UNSND (attr); + TYPE_HIGH_BOUND_KIND (range_type) = PROP_CONST; } else { - length = 1; + TYPE_HIGH_BOUND (range_type) = 1; + TYPE_HIGH_BOUND_KIND (range_type) = PROP_CONST; } } - index_type = objfile_type (objfile)->builtin_int; - range_type = create_static_range_type (NULL, index_type, 1, length); char_type = language_string_char_type (cu->language_defn, gdbarch); type = create_string_type (NULL, char_type, range_type); @@ -14540,13 +14611,15 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu) return set_die_type (die, type, cu);