Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Andrew Burgess <andrew.burgess@embecosm.com>
To: gdb-patches@sourceware.org
Cc: Andrew Burgess <andrew.burgess@embecosm.com>
Subject: [PATCHv2 3/5] gdb/dwarf: Ensure the target type of ranges is not void
Date: Thu, 09 May 2019 22:22:00 -0000	[thread overview]
Message-ID: <4ee490ace14e77dff3d3d8133ef94724a2312c55.1557439866.git.andrew.burgess@embecosm.com> (raw)
In-Reply-To: <cover.1557439866.git.andrew.burgess@embecosm.com>
In-Reply-To: <cover.1557439866.git.andrew.burgess@embecosm.com>

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;
-- 
2.14.5


  parent reply	other threads:[~2019-05-09 22:22 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-05-09 22:22 [PATCHv2 0/5] Improve handling of negative dynamic properties Andrew Burgess
2019-05-05 20:57 ` [PATCH 0/3] " Andrew Burgess
2019-05-05 20:57   ` [PATCH 2/3] gdb: Convert dwarf2_evaluate_property to return bool Andrew Burgess
2019-05-06 13:57     ` Tom Tromey
2019-05-05 20:57   ` [PATCH 3/3] gdb: Handle dynamic properties with negative values Andrew Burgess
2019-05-06 14:55     ` Tom Tromey
2019-05-05 20:57   ` [PATCH 1/3] gdb: Update type of lower bound in value_subscripted_rvalue Andrew Burgess
2019-05-06 13:57     ` Tom Tromey
2019-05-09 22:22   ` [PATCHv2 4/5] gdb: Carry default property type around with dynamic properties Andrew Burgess
2019-05-22 19:05     ` Tom Tromey
2019-06-10 22:29       ` Andrew Burgess
     [not found]         ` <20190710141321.GL23204@embecosm.com>
2019-07-10 15:06           ` Tom Tromey
2019-05-09 22:22   ` [PATCHv2 2/5] gdb: Convert dwarf2_evaluate_property to return bool Andrew Burgess
2019-05-09 22:22   ` [PATCHv2 1/5] gdb: Update type of lower bound in value_subscripted_rvalue Andrew Burgess
2019-05-09 22:22   ` Andrew Burgess [this message]
2019-05-22 18:36     ` [PATCHv2 3/5] gdb/dwarf: Ensure the target type of ranges is not void Tom Tromey
2019-05-09 22:22   ` [PATCHv2 5/5] gdb: Better support for dynamic properties with negative values Andrew Burgess
2019-05-22 19:37     ` Tom Tromey
2019-06-10 22:17       ` Andrew Burgess
2019-07-10 15:03         ` Tom Tromey

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4ee490ace14e77dff3d3d8133ef94724a2312c55.1557439866.git.andrew.burgess@embecosm.com \
    --to=andrew.burgess@embecosm.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox