aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2read.c
diff options
context:
space:
mode:
authorAndrew Burgess <andrew.burgess@embecosm.com>2019-05-08 00:01:14 +0100
committerAndrew Burgess <andrew.burgess@embecosm.com>2019-07-12 12:09:53 +0100
commitb86352cfc17fb7f07d5da9efcfd59f8b2bd08eee (patch)
treedc4d45d16d17b894c3864560ceae7afeec01cfce /gdb/dwarf2read.c
parent603490bf53fe1885ef45f9d0fb783b32f8ef6049 (diff)
downloadgdb-b86352cfc17fb7f07d5da9efcfd59f8b2bd08eee.zip
gdb-b86352cfc17fb7f07d5da9efcfd59f8b2bd08eee.tar.gz
gdb-b86352cfc17fb7f07d5da9efcfd59f8b2bd08eee.tar.bz2
gdb/dwarf: Ensure the target type of ranges is not void
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.
Diffstat (limited to 'gdb/dwarf2read.c')
-rw-r--r--gdb/dwarf2read.c92
1 files changed, 52 insertions, 40 deletions
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index f479677..e918792 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -17752,6 +17752,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 *
@@ -17766,7 +17816,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
@@ -17848,45 +17899,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