gdb: Dynamic string length support

Add support for strings with dynamic length using the DWARF attribute
DW_AT_string_length.

Currently gFortran generates DWARF for some strings that make use of
DW_AT_string_length like this:

 <1><2cc>: Abbrev Number: 20 (DW_TAG_string_type)
    <2cd>   DW_AT_string_length: 5 byte block: 99 bd 1 0 0      (DW_OP_call4: <0x1bd>)
    <2d3>   DW_AT_byte_size   : 4
    <2d4>   DW_AT_sibling     : <0x2e2>

In this type entry the DW_AT_string_length attribute references a
second DW_TAG_formal_parameter that contains the string length.  The
DW_AT_byte_size indicates that the length is a 4-byte value.

This commit extends GDB's DWARF parsing for strings so that we can
create dynamic types as well as static types, based on the attribute
the DWARF contains.

I then extend the dynamic type resolution code in gdbtypes.c to add
support for resolving dynamic strings.

gdb/ChangeLog:

	* dwarf2read.c (read_tag_string_type): Read the fields required to
	make a dynamic string, and possibly create a dynamic range for the
	string.
	(attr_to_dynamic_prop): Setup is_reference based on the type of
	attribute being processed.
	* gdbtypes.c (is_dynamic_type_internal): Handle TYPE_CODE_STRING.
	(resolve_dynamic_array): Rename to...
	(resolve_dynamic_array_or_string): ...this, update header comment,
	and accept TYPE_CODE_STRING.
	(resolve_dynamic_type_internal): Handle TYPE_CODE_STRING.

gdb/testsuite/ChangeLog:

	* gdb.fortran/array-slices.exp: Add test for dynamic strings.

Change-Id: I03f2d181b26156f48f27a03c8a59f9bd4d71ac17
This commit is contained in:
Andrew Burgess
2019-11-29 00:14:35 +00:00
parent 11a8b1641e
commit 216a7e6b9e
5 changed files with 128 additions and 24 deletions

View File

@ -1967,6 +1967,9 @@ is_dynamic_type_internal (struct type *type, int top_level)
|| is_dynamic_type_internal (TYPE_TARGET_TYPE (type), 0));
}
case TYPE_CODE_STRING:
/* Strings are very much like an array of characters, and can be
treated as one here. */
case TYPE_CODE_ARRAY:
{
gdb_assert (TYPE_NFIELDS (type) == 1);
@ -2088,13 +2091,13 @@ resolve_dynamic_range (struct type *dyn_range_type,
return static_range_type;
}
/* Resolves dynamic bound values of an array type TYPE to static ones.
ADDR_STACK is a stack of struct property_addr_info to be used
if needed during the dynamic resolution. */
/* Resolves dynamic bound values of an array or string type TYPE to static
ones. ADDR_STACK is a stack of struct property_addr_info to be used if
needed during the dynamic resolution. */
static struct type *
resolve_dynamic_array (struct type *type,
struct property_addr_info *addr_stack)
resolve_dynamic_array_or_string (struct type *type,
struct property_addr_info *addr_stack)
{
CORE_ADDR value;
struct type *elt_type;
@ -2103,7 +2106,10 @@ resolve_dynamic_array (struct type *type,
struct dynamic_prop *prop;
unsigned int bit_stride = 0;
gdb_assert (TYPE_CODE (type) == TYPE_CODE_ARRAY);
/* For dynamic type resolution strings can be treated like arrays of
characters. */
gdb_assert (TYPE_CODE (type) == TYPE_CODE_ARRAY
|| TYPE_CODE (type) == TYPE_CODE_STRING);
type = copy_type (type);
@ -2129,7 +2135,7 @@ resolve_dynamic_array (struct type *type,
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 (ary_dim, addr_stack);
elt_type = resolve_dynamic_array_or_string (ary_dim, addr_stack);
else
elt_type = TYPE_TARGET_TYPE (type);
@ -2332,8 +2338,11 @@ resolve_dynamic_type_internal (struct type *type,
break;
}
case TYPE_CODE_STRING:
/* Strings are very much like an array of characters, and can be
treated as one here. */
case TYPE_CODE_ARRAY:
resolved_type = resolve_dynamic_array (type, addr_stack);
resolved_type = resolve_dynamic_array_or_string (type, addr_stack);
break;
case TYPE_CODE_RANGE: