mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-08-06 06:45:56 +08:00
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:
@ -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:
|
||||
|
Reference in New Issue
Block a user