From patchwork Thu May 9 22:22:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 32625 Received: (qmail 26976 invoked by alias); 9 May 2019 22:22:29 -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 26923 invoked by uid 89); 9 May 2019 22:22:29 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-22.5 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=muller, sect_offset_str, int_type, sect_off X-HELO: mail-wr1-f67.google.com Received: from mail-wr1-f67.google.com (HELO mail-wr1-f67.google.com) (209.85.221.67) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 09 May 2019 22:22:26 +0000 Received: by mail-wr1-f67.google.com with SMTP id f7so5144877wrq.1 for ; Thu, 09 May 2019 15:22:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=0Ty/rW0JbVeijQ55St0yQc3whyshb5NprVnqLW15rwg=; b=CJ2Q6HA5KpMz6xbu00vwSZBkRRW0+CBI3DUsV8NKx41loTdwo+eQepmHB4uqa0J+am 0OnLlQxohZKTVSi0OzsqiTV8dFT/i2NNZYYVaFOxZIhBuZx8dQyOfYjz2icQHaf8U3AS WiMHUQXiM5igpk7iXMjwmgnQkKIwHYu4RXyK1UlE1htft73FZ0+hb2n29NEciOsh5lJC JW3lOgiRKpreZlDWuieEk8cMxZsrvYxVMhkOnM2AtZNUTsBgSxgkwVWaZ1D5oz9b+Fzl swK6HqvGeb/tGshCUTM0nUEV23bXnD5p+tBL/Yg9LcQQ0g1leib8FCO7JZDDAsF9T0ia qEkQ== Return-Path: Received: from localhost (host109-154-100-57.range109-154.btcentralplus.com. [109.154.100.57]) by smtp.gmail.com with ESMTPSA id d3sm6441884wmf.46.2019.05.09.15.22.23 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 09 May 2019 15:22:23 -0700 (PDT) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: Andrew Burgess Subject: [PATCHv2 3/5] gdb/dwarf: Ensure the target type of ranges is not void Date: Thu, 9 May 2019 23:22:14 +0100 Message-Id: <4ee490ace14e77dff3d3d8133ef94724a2312c55.1557439866.git.andrew.burgess@embecosm.com> In-Reply-To: References: In-Reply-To: References: X-IsSubscribed: yes If a DW_TAG_subrange_type DWARF entry has no DW_AT_type then a default type based on the size of an address on the current target is assumed. We store this type as the target type for GDB's range types. Currently GDB can create ranges for which the target type is VOID, this is incorrect but seems to cause no problems. I believe the reason this doesn't cause any issues is because the languages (for example Ada) that actually make use of a ranges target type also have compilers that generate DWARF that includes a DW_AT_type attribute. However, gfortran does not include a DW_AT_type, its DWARF instead relies on the default target type. This isn't currently a problem for GDB as gfortran doesn't make use of the target type when printing subranges, but it shouldn't hurt to fix this issue now. I've added an assert into create_range_type that will catch this issue if it comes up again. This was tested on an x86-64/GNU-Linux machine with both the Ada and gfortran compilers available with both '--target_board=unix' and '--target_board=unix/-m32'. There are no user visible changes after this commit. gdb/ChangeLog: * dwarf2read.c (read_subrange_index_type): New function. (read_subrange_type): Move code into new function and call it. * gdbtypes.c (create_range_type): Add some asserts. --- gdb/ChangeLog | 6 ++++ gdb/dwarf2read.c | 92 ++++++++++++++++++++++++++++++++------------------------ gdb/gdbtypes.c | 5 +++ 3 files changed, 63 insertions(+), 40 deletions(-) diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index b29c089606d..e9c53148961 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -17809,6 +17809,56 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die, return 1; } +/* Read the DW_AT_type attribute for a sub-range. If this attribute is not + present (which is valid) then compute the default type based on the + compilation units address size. */ + +static struct type * +read_subrange_index_type (struct die_info *die, struct dwarf2_cu *cu) +{ + struct type *index_type = die_type (die, cu); + + /* Dwarf-2 specifications explicitly allows to create subrange types + without specifying a base type. + In that case, the base type must be set to the type of + the lower bound, upper bound or count, in that order, if any of these + three attributes references an object that has a type. + If no base type is found, the Dwarf-2 specifications say that + a signed integer type of size equal to the size of an address should + be used. + For the following C code: `extern char gdb_int [];' + GCC produces an empty range DIE. + FIXME: muller/2010-05-28: Possible references to object for low bound, + high bound or count are not yet handled by this code. */ + if (TYPE_CODE (index_type) == TYPE_CODE_VOID) + { + struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile; + struct gdbarch *gdbarch = get_objfile_arch (objfile); + int addr_size = gdbarch_addr_bit (gdbarch) /8; + struct type *int_type = objfile_type (objfile)->builtin_int; + + /* Test "int", "long int", and "long long int" objfile types, + and select the first one having a size above or equal to the + architecture address size. */ + if (int_type && TYPE_LENGTH (int_type) >= addr_size) + index_type = int_type; + else + { + int_type = objfile_type (objfile)->builtin_long; + if (int_type && TYPE_LENGTH (int_type) >= addr_size) + index_type = int_type; + else + { + int_type = objfile_type (objfile)->builtin_long_long; + if (int_type && TYPE_LENGTH (int_type) >= addr_size) + index_type = int_type; + } + } + } + + return index_type; +} + /* Read the given DW_AT_subrange DIE. */ static struct type * @@ -17823,7 +17873,8 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) const char *name; ULONGEST negative_mask; - orig_base_type = die_type (die, cu); + orig_base_type = read_subrange_index_type (die, cu); + /* If ORIG_BASE_TYPE is a typedef, it will not be TYPE_UNSIGNED, whereas the real type might be. So, we use ORIG_BASE_TYPE when creating the range type, but we use the result of check_typedef @@ -17905,45 +17956,6 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) sect_offset_str (die->sect_off), objfile_name (cu->per_cu->dwarf2_per_objfile->objfile)); } - - } - - /* Dwarf-2 specifications explicitly allows to create subrange types - without specifying a base type. - In that case, the base type must be set to the type of - the lower bound, upper bound or count, in that order, if any of these - three attributes references an object that has a type. - If no base type is found, the Dwarf-2 specifications say that - a signed integer type of size equal to the size of an address should - be used. - For the following C code: `extern char gdb_int [];' - GCC produces an empty range DIE. - FIXME: muller/2010-05-28: Possible references to object for low bound, - high bound or count are not yet handled by this code. */ - if (TYPE_CODE (base_type) == TYPE_CODE_VOID) - { - struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile; - struct gdbarch *gdbarch = get_objfile_arch (objfile); - int addr_size = gdbarch_addr_bit (gdbarch) /8; - struct type *int_type = objfile_type (objfile)->builtin_int; - - /* Test "int", "long int", and "long long int" objfile types, - and select the first one having a size above or equal to the - architecture address size. */ - if (int_type && TYPE_LENGTH (int_type) >= addr_size) - base_type = int_type; - else - { - int_type = objfile_type (objfile)->builtin_long; - if (int_type && TYPE_LENGTH (int_type) >= addr_size) - base_type = int_type; - else - { - int_type = objfile_type (objfile)->builtin_long_long; - if (int_type && TYPE_LENGTH (int_type) >= addr_size) - base_type = int_type; - } - } } /* Normally, the DWARF producers are expected to use a signed diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index ec4c4783a60..c6e8aca451b 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -914,6 +914,11 @@ create_range_type (struct type *result_type, struct type *index_type, const struct dynamic_prop *low_bound, const struct dynamic_prop *high_bound) { + /* The INDEX_TYPE should be a type capable of holding the upper and lower + bounds, as such a zero sized, or void type makes no sense. */ + gdb_assert (TYPE_CODE (index_type) != TYPE_CODE_VOID); + gdb_assert (TYPE_LENGTH (index_type) > 0); + if (result_type == NULL) result_type = alloc_type_copy (index_type); TYPE_CODE (result_type) = TYPE_CODE_RANGE;