/* DWARF 2 debugging format support for GDB.
- Copyright (C) 1994-2019 Free Software Foundation, Inc.
+ Copyright (C) 1994-2020 Free Software Foundation, Inc.
+ Copyright (C) 2019-2020 Advanced Micro Devices, Inc. All rights reserved.
Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
Inc. with support from Florida State University (under contract
{
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);
struct symbol *sym;
sym = allocate_symbol (objfile);
- SYMBOL_SET_LANGUAGE (sym, language_go, &objfile->objfile_obstack);
- SYMBOL_SET_NAMES (sym, saved_package_name, false, objfile);
+ sym->set_language (language_go, &objfile->objfile_obstack);
+ sym->compute_and_set_names (saved_package_name, false, objfile->per_bfd);
/* This is not VAR_DOMAIN because we want a way to ensure a lookup of,
e.g., "main" finds the "main" module and not C's main(). */
SYMBOL_DOMAIN (sym) = STRUCT_DOMAIN;
/* For Fortran GDB prefers DW_AT_*linkage_name for the physname if present
but otherwise compute it by typename_concat inside GDB.
FIXME: Actually this is not really true, or at least not always true.
- It's all very confusing. SYMBOL_SET_NAMES doesn't try to demangle
+ It's all very confusing. compute_and_set_names doesn't try to demangle
Fortran names because there is no mangling standard. So new_symbol
will set the demangled name to the result of dwarf2_full_name, and it is
the demangled name that GDB uses if it exists. */
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
&& (type_name[len] == '\0' || type_name[len] == '<'));
}
+/* Check if the given VALUE is a recognized enum
+ dwarf_defaulted_attribute constant according to DWARF5 spec,
+ Table 7.24. */
+
+static bool
+is_valid_DW_AT_defaulted (ULONGEST value)
+{
+ switch (value)
+ {
+ case DW_DEFAULTED_no:
+ case DW_DEFAULTED_in_class:
+ case DW_DEFAULTED_out_of_class:
+ return true;
+ }
+
+ complaint (_("unrecognized DW_AT_defaulted value (%s)"), pulongest (value));
+ return false;
+}
+
/* Add a member function to the proper fieldlist. */
static void
if (attr && DW_UNSND (attr) != 0)
fnp->is_artificial = 1;
+ /* Check for defaulted methods. */
+ attr = dwarf2_attr (die, DW_AT_defaulted, cu);
+ if (attr != nullptr && is_valid_DW_AT_defaulted (DW_UNSND (attr)))
+ fnp->defaulted = (enum dwarf_defaulted_attribute) DW_UNSND (attr);
+
+ /* Check for deleted methods. */
+ attr = dwarf2_attr (die, DW_AT_deleted, cu);
+ if (attr != nullptr && DW_UNSND (attr) != 0)
+ fnp->is_deleted = 1;
+
fnp->is_constructor = dwarf2_is_constructor (die, cu);
/* Get index in virtual function table if it is a virtual member
objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
}
+/* Check if the given VALUE is a valid enum dwarf_calling_convention
+ constant for a type, according to DWARF5 spec, Table 5.5. */
+
+static bool
+is_valid_DW_AT_calling_convention_for_type (ULONGEST value)
+{
+ switch (value)
+ {
+ case DW_CC_normal:
+ case DW_CC_pass_by_reference:
+ case DW_CC_pass_by_value:
+ return true;
+
+ default:
+ complaint (_("unrecognized DW_AT_calling_convention value "
+ "(%s) for a type"), pulongest (value));
+ return false;
+ }
+}
+
+/* Check if the given VALUE is a valid enum dwarf_calling_convention
+ constant for a subroutine, according to DWARF5 spec, Table 3.3, and
+ also according to GNU-specific values (see include/dwarf2.h). */
+
+static bool
+is_valid_DW_AT_calling_convention_for_subroutine (ULONGEST value)
+{
+ switch (value)
+ {
+ case DW_CC_normal:
+ case DW_CC_program:
+ case DW_CC_nocall:
+ return true;
+
+ case DW_CC_GNU_renesas_sh:
+ case DW_CC_GNU_borland_fastcall_i386:
+ case DW_CC_GDB_IBM_OpenCL:
+ return true;
+
+ default:
+ complaint (_("unrecognized DW_AT_calling_convention value "
+ "(%s) for a subroutine"), pulongest (value));
+ return false;
+ }
+}
+
/* Called when we find the DIE that starts a structure or union scope
(definition) to create a type for the structure or union. Fill in
the type's name and general properties; the members will not be
if (cu->language == language_cplus && die->tag == DW_TAG_class_type)
TYPE_DECLARED_CLASS (type) = 1;
+ /* Store the calling convention in the type if it's available in
+ the die. Otherwise the calling convention remains set to
+ the default value DW_CC_normal. */
+ attr = dwarf2_attr (die, DW_AT_calling_convention, cu);
+ if (attr != nullptr
+ && is_valid_DW_AT_calling_convention_for_type (DW_UNSND (attr)))
+ {
+ ALLOCATE_CPLUS_STRUCT_TYPE (type);
+ TYPE_CPLUS_CALLING_CONVENTION (type)
+ = (enum dwarf_calling_convention) (DW_UNSND (attr));
+ }
+
attr = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr != nullptr)
{
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)
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);
the subroutine die. Otherwise set the calling convention to
the default value DW_CC_normal. */
attr = dwarf2_attr (die, DW_AT_calling_convention, cu);
- if (attr != nullptr)
- TYPE_CALLING_CONVENTION (ftype) = DW_UNSND (attr);
+ if (attr != nullptr
+ && is_valid_DW_AT_calling_convention_for_subroutine (DW_UNSND (attr)))
+ TYPE_CALLING_CONVENTION (ftype)
+ = (enum dwarf_calling_convention) (DW_UNSND (attr));
else if (cu->producer && strstr (cu->producer, "IBM XL C for OpenCL"))
TYPE_CALLING_CONVENTION (ftype) = DW_CC_GDB_IBM_OpenCL;
else
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;
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);
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;
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
struct type *type;
struct attribute *attr;
int encoding = 0, bits = 0;
- int endianity = 0;
const char *name;
gdbarch *arch;
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:
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);
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);
}
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);
list_in_scope = get_builder ()->get_file_symbols ();
- get_builder ()->record_debugformat ("DWARF 2");
+ get_builder ()->record_debugformat (xstrprintf ("DWARF %d", this->header.version));
get_builder ()->record_producer (producer);
processing_has_namespace_info = false;
OBJSTAT (objfile, n_syms++);
/* Cache this symbol's name and the name's demangled form (if any). */
- SYMBOL_SET_LANGUAGE (sym, cu->language, &objfile->objfile_obstack);
+ sym->set_language (cu->language, &objfile->objfile_obstack);
linkagename = dwarf2_physname (name, die, cu);
- SYMBOL_SET_NAMES (sym, linkagename, false, objfile);
+ sym->compute_and_set_names (linkagename, false, objfile->per_bfd);
/* Fortran does not have mangling standard and the mangling does differ
between gfortran, iFort etc. */