X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fdwarf2read.c;h=6a09d5568b3bf6963b0afa7de63819d672c63660;hb=c1b5c1ebc938b6dc0277363b8c47d75b0b5a621f;hp=40626a1562f0ca96106dfa78b727b0cb712e704f;hpb=8d9a2568651d55eb518d3ac6c0dd0b4719da7f77;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 40626a1562..6a09d5568b 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -1910,6 +1910,9 @@ static void process_queue (struct dwarf2_per_objfile *dwarf2_per_objfile); static struct type *dwarf2_per_cu_addr_type (struct dwarf2_per_cu_data *per_cu); static struct type *dwarf2_per_cu_addr_sized_int_type (struct dwarf2_per_cu_data *per_cu, bool unsigned_p); +static struct type *dwarf2_per_cu_int_type + (struct dwarf2_per_cu_data *per_cu, int size_in_bytes, + bool unsigned_p); /* Class, the destructor of which frees all allocated queue entries. This will only have work to do if an error was thrown while processing the @@ -9913,7 +9916,7 @@ fixup_go_packaging (struct dwarf2_cu *cu) { struct symbol *sym = list->symbol[i]; - if (SYMBOL_LANGUAGE (sym) == language_go + if (sym->language () == language_go && SYMBOL_CLASS (sym) == LOC_BLOCK) { char *this_package_name = go_symbol_package_name (sym); @@ -15124,7 +15127,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, attr = dwarf2_attr (die, DW_AT_bit_offset, cu); if (attr != nullptr) { - if (gdbarch_bits_big_endian (gdbarch)) + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) { /* For big endian bits, the DW_AT_bit_offset gives the additional bit offset from the MSB of the containing @@ -15252,13 +15255,18 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, /* Normally a DW_TAG_variant_part won't have a size, but our representation requires one, so set it to the maximum of the - child sizes. */ + child sizes, being sure to account for the offset at which + each child is seen. */ if (TYPE_LENGTH (fp->type) == 0) { unsigned max = 0; for (int i = 0; i < TYPE_NFIELDS (fp->type); ++i) - if (TYPE_LENGTH (TYPE_FIELD_TYPE (fp->type, i)) > max) - max = TYPE_LENGTH (TYPE_FIELD_TYPE (fp->type, i)); + { + unsigned len = ((TYPE_FIELD_BITPOS (fp->type, i) + 7) / 8 + + TYPE_LENGTH (TYPE_FIELD_TYPE (fp->type, i))); + if (len > max) + max = len; + } TYPE_LENGTH (fp->type) = max; } } @@ -16052,7 +16060,7 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) read the discriminant member, so we can record it later in the discriminant_info. */ bool is_variant_part = TYPE_FLAG_DISCRIMINATED_UNION (type); - sect_offset discr_offset; + sect_offset discr_offset {}; bool has_template_parameters = false; if (is_variant_part) @@ -17315,29 +17323,90 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu) struct gdbarch *gdbarch = get_objfile_arch (objfile); struct type *type, *range_type, *index_type, *char_type; struct attribute *attr; - unsigned int length; + struct dynamic_prop prop; + bool length_is_constant = true; + LONGEST length; + + /* There are a couple of places where bit sizes might be made use of + when parsing a DW_TAG_string_type, however, no producer that we know + of make use of these. Handling bit sizes that are a multiple of the + byte size is easy enough, but what about other bit sizes? Lets deal + with that problem when we have to. Warn about these attributes being + unsupported, then parse the type and ignore them like we always + have. */ + if (dwarf2_attr (die, DW_AT_bit_size, cu) != nullptr + || dwarf2_attr (die, DW_AT_string_length_bit_size, cu) != nullptr) + { + static bool warning_printed = false; + if (!warning_printed) + { + warning (_("DW_AT_bit_size and DW_AT_string_length_bit_size not " + "currently supported on DW_TAG_string_type.")); + warning_printed = true; + } + } attr = dwarf2_attr (die, DW_AT_string_length, cu); - if (attr != nullptr) + if (attr != nullptr && !attr_form_is_constant (attr)) + { + /* The string length describes the location at which the length of + the string can be found. The size of the length field can be + specified with one of the attributes below. */ + struct type *prop_type; + struct attribute *len + = dwarf2_attr (die, DW_AT_string_length_byte_size, cu); + if (len == nullptr) + len = dwarf2_attr (die, DW_AT_byte_size, cu); + if (len != nullptr && attr_form_is_constant (len)) + { + /* Pass 0 as the default as we know this attribute is constant + and the default value will not be returned. */ + LONGEST sz = dwarf2_get_attr_constant_value (len, 0); + prop_type = dwarf2_per_cu_int_type (cu->per_cu, sz, true); + } + else + { + /* If the size is not specified then we assume it is the size of + an address on this target. */ + prop_type = dwarf2_per_cu_addr_sized_int_type (cu->per_cu, true); + } + + /* Convert the attribute into a dynamic property. */ + if (!attr_to_dynamic_prop (attr, die, cu, &prop, prop_type)) + length = 1; + else + length_is_constant = false; + } + else if (attr != nullptr) { - length = DW_UNSND (attr); + /* This DW_AT_string_length just contains the length with no + indirection. There's no need to create a dynamic property in this + case. Pass 0 for the default value as we know it will not be + returned in this case. */ + length = dwarf2_get_attr_constant_value (attr, 0); + } + else if ((attr = dwarf2_attr (die, DW_AT_byte_size, cu)) != nullptr) + { + /* We don't currently support non-constant byte sizes for strings. */ + length = dwarf2_get_attr_constant_value (attr, 1); } else { - /* Check for the DW_AT_byte_size attribute. */ - attr = dwarf2_attr (die, DW_AT_byte_size, cu); - if (attr != nullptr) - { - length = DW_UNSND (attr); - } - else - { - length = 1; - } + /* Use 1 as a fallback length if we have nothing else. */ + length = 1; } index_type = objfile_type (objfile)->builtin_int; - range_type = create_static_range_type (NULL, index_type, 1, length); + if (length_is_constant) + range_type = create_static_range_type (NULL, index_type, 1, length); + else + { + struct dynamic_prop low_bound; + + low_bound.kind = PROP_CONST; + low_bound.data.const_val = 1; + range_type = create_range_type (NULL, index_type, &low_bound, &prop, 0); + } char_type = language_string_char_type (cu->language_defn, gdbarch); type = create_string_type (NULL, char_type, range_type); @@ -17555,7 +17624,7 @@ read_typedef (struct die_info *die, struct dwarf2_cu *cu) static struct type * dwarf2_init_float_type (struct objfile *objfile, int bits, const char *name, - const char *name_hint) + const char *name_hint, enum bfd_endian byte_order) { struct gdbarch *gdbarch = get_objfile_arch (objfile); const struct floatformat **format; @@ -17563,7 +17632,7 @@ dwarf2_init_float_type (struct objfile *objfile, int bits, const char *name, format = gdbarch_floatformat_for_type (gdbarch, name_hint, bits); if (format) - type = init_float_type (objfile, bits, name, format); + type = init_float_type (objfile, bits, name, format, byte_order); else type = init_type (objfile, TYPE_CODE_ERROR, bits, name); @@ -17602,7 +17671,8 @@ dwarf2_init_integer_type (struct dwarf2_cu *cu, struct objfile *objfile, static struct type * dwarf2_init_complex_target_type (struct dwarf2_cu *cu, struct objfile *objfile, - int bits, const char *name_hint) + int bits, const char *name_hint, + enum bfd_endian byte_order) { gdbarch *gdbarch = get_objfile_arch (objfile); struct type *tt = nullptr; @@ -17651,7 +17721,7 @@ dwarf2_init_complex_target_type (struct dwarf2_cu *cu, tt = nullptr; const char *name = (tt == nullptr) ? nullptr : TYPE_NAME (tt); - return dwarf2_init_float_type (objfile, bits, name, name_hint); + return dwarf2_init_float_type (objfile, bits, name, name_hint, byte_order); } /* Find a representation of a given base type and install @@ -17664,7 +17734,6 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu) struct type *type; struct attribute *attr; int encoding = 0, bits = 0; - int endianity = 0; const char *name; gdbarch *arch; @@ -17677,11 +17746,29 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu) name = dwarf2_name (die, cu); if (!name) complaint (_("DW_AT_name missing from DW_TAG_base_type")); + + arch = get_objfile_arch (objfile); + enum bfd_endian byte_order = gdbarch_byte_order (arch); + attr = dwarf2_attr (die, DW_AT_endianity, cu); if (attr) - endianity = DW_UNSND (attr); + { + int endianity = DW_UNSND (attr); + + switch (endianity) + { + case DW_END_big: + byte_order = BFD_ENDIAN_BIG; + break; + case DW_END_little: + byte_order = BFD_ENDIAN_LITTLE; + break; + default: + complaint (_("DW_AT_endianity has unrecognized value %d"), endianity); + break; + } + } - arch = get_objfile_arch (objfile); switch (encoding) { case DW_ATE_address: @@ -17693,14 +17780,15 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu) type = init_boolean_type (objfile, bits, 1, name); break; case DW_ATE_complex_float: - type = dwarf2_init_complex_target_type (cu, objfile, bits / 2, name); + type = dwarf2_init_complex_target_type (cu, objfile, bits / 2, name, + byte_order); type = init_complex_type (objfile, name, type); break; case DW_ATE_decimal_float: type = init_decfloat_type (objfile, bits, name); break; case DW_ATE_float: - type = dwarf2_init_float_type (objfile, bits, name, name); + type = dwarf2_init_float_type (objfile, bits, name, name, byte_order); break; case DW_ATE_signed: type = dwarf2_init_integer_type (cu, objfile, bits, 0, name); @@ -17758,17 +17846,7 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu) maybe_set_alignment (cu, die, type); - switch (endianity) - { - case DW_END_big: - if (gdbarch_byte_order (arch) == BFD_ENDIAN_LITTLE) - TYPE_ENDIANITY_NOT_DEFAULT (type) = 1; - break; - case DW_END_little: - if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG) - TYPE_ENDIANITY_NOT_DEFAULT (type) = 1; - break; - } + TYPE_ENDIANITY_NOT_DEFAULT (type) = gdbarch_byte_order (arch) != byte_order; return set_die_type (die, type, cu); } @@ -17798,7 +17876,15 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die, baton->locexpr.per_cu = cu->per_cu; baton->locexpr.size = DW_BLOCK (attr)->size; baton->locexpr.data = DW_BLOCK (attr)->data; - baton->locexpr.is_reference = false; + switch (attr->name) + { + case DW_AT_string_length: + baton->locexpr.is_reference = true; + break; + default: + baton->locexpr.is_reference = false; + break; + } prop->data.baton = baton; prop->kind = PROP_LOCEXPR; gdb_assert (prop->data.baton != NULL); @@ -17882,24 +17968,22 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die, return 1; } -/* Find an integer type the same size as the address size given in the - compilation unit header for PER_CU. UNSIGNED_P controls if the integer - is unsigned or not. */ +/* Find an integer type SIZE_IN_BYTES bytes in size and return it. + UNSIGNED_P controls if the integer is unsigned or not. */ static struct type * -dwarf2_per_cu_addr_sized_int_type (struct dwarf2_per_cu_data *per_cu, - bool unsigned_p) +dwarf2_per_cu_int_type (struct dwarf2_per_cu_data *per_cu, + int size_in_bytes, bool unsigned_p) { struct objfile *objfile = per_cu->dwarf2_per_objfile->objfile; - int addr_size = dwarf2_per_cu_addr_size (per_cu); struct type *int_type; /* Helper macro to examine the various builtin types. */ -#define TRY_TYPE(F) \ - int_type = (unsigned_p \ - ? objfile_type (objfile)->builtin_unsigned_ ## F \ - : objfile_type (objfile)->builtin_ ## F); \ - if (int_type != NULL && TYPE_LENGTH (int_type) == addr_size) \ +#define TRY_TYPE(F) \ + int_type = (unsigned_p \ + ? objfile_type (objfile)->builtin_unsigned_ ## F \ + : objfile_type (objfile)->builtin_ ## F); \ + if (int_type != NULL && TYPE_LENGTH (int_type) == size_in_bytes) \ return int_type TRY_TYPE (char); @@ -17913,6 +17997,18 @@ dwarf2_per_cu_addr_sized_int_type (struct dwarf2_per_cu_data *per_cu, gdb_assert_not_reached ("unable to find suitable integer type"); } +/* Find an integer type the same size as the address size given in the + compilation unit header for PER_CU. UNSIGNED_P controls if the integer + is unsigned or not. */ + +static struct type * +dwarf2_per_cu_addr_sized_int_type (struct dwarf2_per_cu_data *per_cu, + bool unsigned_p) +{ + int addr_size = dwarf2_per_cu_addr_size (per_cu); + return dwarf2_per_cu_int_type (per_cu, addr_size, unsigned_p); +} + /* 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. */ @@ -18060,7 +18156,52 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) && !TYPE_UNSIGNED (base_type) && (high.data.const_val & negative_mask)) high.data.const_val |= negative_mask; - range_type = create_range_type (NULL, orig_base_type, &low, &high, bias); + /* Check for bit and byte strides. */ + struct dynamic_prop byte_stride_prop; + attribute *attr_byte_stride = dwarf2_attr (die, DW_AT_byte_stride, cu); + if (attr_byte_stride != nullptr) + { + struct type *prop_type + = dwarf2_per_cu_addr_sized_int_type (cu->per_cu, false); + attr_to_dynamic_prop (attr_byte_stride, die, cu, &byte_stride_prop, + prop_type); + } + + struct dynamic_prop bit_stride_prop; + attribute *attr_bit_stride = dwarf2_attr (die, DW_AT_bit_stride, cu); + if (attr_bit_stride != nullptr) + { + /* It only makes sense to have either a bit or byte stride. */ + if (attr_byte_stride != nullptr) + { + complaint (_("Found DW_AT_bit_stride and DW_AT_byte_stride " + "- DIE at %s [in module %s]"), + sect_offset_str (die->sect_off), + objfile_name (cu->per_cu->dwarf2_per_objfile->objfile)); + attr_bit_stride = nullptr; + } + else + { + struct type *prop_type + = dwarf2_per_cu_addr_sized_int_type (cu->per_cu, false); + attr_to_dynamic_prop (attr_bit_stride, die, cu, &bit_stride_prop, + prop_type); + } + } + + if (attr_byte_stride != nullptr + || attr_bit_stride != nullptr) + { + bool byte_stride_p = (attr_byte_stride != nullptr); + struct dynamic_prop *stride + = byte_stride_p ? &byte_stride_prop : &bit_stride_prop; + + range_type + = create_range_type_with_stride (NULL, orig_base_type, &low, + &high, bias, stride, byte_stride_p); + } + else + range_type = create_range_type (NULL, orig_base_type, &low, &high, bias); if (high_bound_is_count) TYPE_RANGE_DATA (range_type)->flag_upper_bound_is_count = 1;