/* When non-zero, do not reject deprecated .gdb_index sections. */
static int use_deprecated_index_sections = 0;
-static const struct objfile_data *dwarf2_objfile_data_key;
+static const struct objfile_key<dwarf2_per_objfile> dwarf2_objfile_data_key;
/* The "aclass" indices for various kinds of computed DWARF symbols. */
bool symbol_name_slot_invalid (offset_type idx) const override
{
const auto &bucket = this->symbol_table[idx];
- return bucket.name == 0 && bucket.vec;
+ return bucket.name == 0 && bucket.vec == 0;
}
/* Convenience method to get at the name of the symbol at IDX in the
dwarf2_per_objfile *
get_dwarf2_per_objfile (struct objfile *objfile)
{
- return ((struct dwarf2_per_objfile *)
- objfile_data (objfile, dwarf2_objfile_data_key));
-}
-
-/* Set the dwarf2_per_objfile associated to OBJFILE. */
-
-void
-set_dwarf2_per_objfile (struct objfile *objfile,
- struct dwarf2_per_objfile *dwarf2_per_objfile)
-{
- gdb_assert (get_dwarf2_per_objfile (objfile) == NULL);
- set_objfile_data (objfile, dwarf2_objfile_data_key, dwarf2_per_objfile);
+ return dwarf2_objfile_data_key.get (objfile);
}
/* Default names of the debugging sections. */
return &file_names[vec_index];
}
- /* Const version of the above. */
- const file_entry *file_name_at (unsigned int index) const
- {
- if (index >= file_names.size ())
- return NULL;
- return &file_names[index];
- }
-
/* Offset of line number information in .debug_line section. */
sect_offset sect_off {};
static struct partial_die_info *load_partial_dies
(const struct die_reader_specs *, const gdb_byte *, int);
-static struct partial_die_info *find_partial_die (sect_offset, int,
- struct dwarf2_cu *);
+/* A pair of partial_die_info and compilation unit. */
+struct cu_partial_die_info
+{
+ /* The compilation unit of the partial_die_info. */
+ struct dwarf2_cu *cu;
+ /* A partial_die_info. */
+ struct partial_die_info *pdi;
+
+ cu_partial_die_info (struct dwarf2_cu *cu, struct partial_die_info *pdi)
+ : cu (cu),
+ pdi (pdi)
+ { /* Nothhing. */ }
+
+private:
+ cu_partial_die_info () = delete;
+};
+
+static const struct cu_partial_die_info find_partial_die (sect_offset, int,
+ struct dwarf2_cu *);
static const gdb_byte *read_attribute (const struct die_reader_specs *,
struct attribute *, struct attr_abbrev *,
static unsigned int read_2_bytes (bfd *, const gdb_byte *);
+/* Read the next three bytes (little-endian order) as an unsigned integer. */
+static unsigned int read_3_bytes (bfd *, const gdb_byte *);
+
static unsigned int read_4_bytes (bfd *, const gdb_byte *);
static ULONGEST read_8_bytes (bfd *, const gdb_byte *);
{
CORE_ADDR addr;
- if (attr->form != DW_FORM_addr && attr->form != DW_FORM_GNU_addr_index)
+ if (attr->form != DW_FORM_addr && attr->form != DW_FORM_addrx
+ && attr->form != DW_FORM_GNU_addr_index)
{
/* Aside from a few clearly defined exceptions, attributes that
contain an address must always be in DW_FORM_addr form.
= get_dwarf2_per_objfile (objfile);
if (dwarf2_per_objfile == NULL)
- {
- /* Initialize per-objfile state. */
- dwarf2_per_objfile
- = new (&objfile->objfile_obstack) struct dwarf2_per_objfile (objfile,
- names);
- set_dwarf2_per_objfile (objfile, dwarf2_per_objfile);
- }
+ dwarf2_per_objfile = dwarf2_objfile_data_key.emplace (objfile, objfile,
+ names);
+
return (!dwarf2_per_objfile->info.is_virtual
&& dwarf2_per_objfile->info.s.section != NULL
&& !dwarf2_per_objfile->abbrev.is_virtual
asection **sectp, const gdb_byte **bufp,
bfd_size_type *sizep)
{
- struct dwarf2_per_objfile *data
- = (struct dwarf2_per_objfile *) objfile_data (objfile,
- dwarf2_objfile_data_key);
+ struct dwarf2_per_objfile *data = dwarf2_objfile_data_key.get (objfile);
struct dwarf2_section_info *info;
/* We may see an objfile without any DWARF, in which case we just
comp_dir = dwarf2_attr (stub_comp_unit_die, DW_AT_comp_dir, cu);
/* There should be a DW_AT_addr_base attribute here (if needed).
- We need the value before we can process DW_FORM_GNU_addr_index. */
+ We need the value before we can process DW_FORM_GNU_addr_index
+ or DW_FORM_addrx. */
cu->addr_base = 0;
attr = dwarf2_attr (stub_comp_unit_die, DW_AT_GNU_addr_base, cu);
if (attr)
real_pdi = pdi;
while (real_pdi->has_specification)
- real_pdi = find_partial_die (real_pdi->spec_offset,
- real_pdi->spec_is_dwz, cu);
+ {
+ auto res = find_partial_die (real_pdi->spec_offset,
+ real_pdi->spec_is_dwz, cu);
+ real_pdi = res.pdi;
+ cu = res.cu;
+ }
parent = real_pdi->die_parent;
if (parent == NULL)
/* FIXME drow/2004-04-01: What should we be doing with
function-local names? For partial symbols, we should probably be
ignoring them. */
- complaint (_("unhandled containing DIE tag %d for DIE at %s"),
- parent->tag, sect_offset_str (pdi->sect_off));
+ complaint (_("unhandled containing DIE tag %s for DIE at %s"),
+ dwarf_tag_name (parent->tag),
+ sect_offset_str (pdi->sect_off));
parent->scope = grandparent_scope;
}
0, cu->language, objfile);
break;
case DW_TAG_module:
- add_psymbol_to_list (actual_name, strlen (actual_name),
- built_actual_name != NULL,
- MODULE_DOMAIN, LOC_TYPEDEF, -1,
- psymbol_placement::GLOBAL,
- 0, cu->language, objfile);
+ /* With Fortran 77 there might be a "BLOCK DATA" module
+ available without any name. If so, we skip the module as it
+ doesn't bring any value. */
+ if (actual_name != nullptr)
+ add_psymbol_to_list (actual_name, strlen (actual_name),
+ built_actual_name != NULL,
+ MODULE_DOMAIN, LOC_TYPEDEF, -1,
+ psymbol_placement::GLOBAL,
+ 0, cu->language, objfile);
break;
case DW_TAG_class_type:
case DW_TAG_interface_type:
case DW_FORM_block4:
info_ptr += 4 + read_4_bytes (abfd, info_ptr);
break;
+ case DW_FORM_addrx:
+ case DW_FORM_strx:
case DW_FORM_sdata:
case DW_FORM_udata:
case DW_FORM_ref_udata:
newobj->name = new_symbol (die, read_type_die (die, cu), cu,
(struct symbol *) templ_func);
+ if (dwarf2_flag_true_p (die, DW_AT_main_subprogram, cu))
+ set_objfile_main_name (objfile, SYMBOL_LINKAGE_NAME (newobj->name),
+ cu->language);
+
/* If there is a location expression for DW_AT_frame_base, record
it. */
attr = dwarf2_attr (die, DW_AT_frame_base, cu);
field for our sole member child. */
struct attribute *discr = dwarf2_attr (child_die, DW_AT_discr_value, cu);
- for (struct die_info *variant_child = child_die->child;
+ for (die_info *variant_child = child_die->child;
variant_child != NULL;
variant_child = sibling_die (variant_child))
{
if (has_template_parameters)
{
- /* Make sure that the symtab is set on the new symbols.
- Even though they don't appear in this symtab directly,
- other parts of gdb assume that symbols do, and this is
- reasonably true. */
- for (int i = 0; i < TYPE_N_TEMPLATE_ARGUMENTS (type); ++i)
- symbol_set_symtab (TYPE_TEMPLATE_ARGUMENT (type, i),
- symbol_symtab (sym));
+ struct symtab *symtab;
+ if (sym != nullptr)
+ symtab = symbol_symtab (sym);
+ else if (cu->line_header != nullptr)
+ {
+ /* Any related symtab will do. */
+ symtab
+ = cu->line_header->file_name_at (file_name_index (1))->symtab;
+ }
+ else
+ {
+ symtab = nullptr;
+ complaint (_("could not find suitable "
+ "symtab for template parameter"
+ " - DIE at %s [in module %s]"),
+ sect_offset_str (die->sect_off),
+ objfile_name (objfile));
+ }
+
+ if (symtab != nullptr)
+ {
+ /* Make sure that the symtab is set on the new symbols.
+ Even though they don't appear in this symtab directly,
+ other parts of gdb assume that symbols do, and this is
+ reasonably true. */
+ for (int i = 0; i < TYPE_N_TEMPLATE_ARGUMENTS (type); ++i)
+ symbol_set_symtab (TYPE_TEMPLATE_ARGUMENT (type, i), symtab);
+ }
}
}
}
struct type *type;
module_name = dwarf2_name (die, cu);
- if (!module_name)
- complaint (_("DW_TAG_module has no name, offset %s"),
- sect_offset_str (die->sect_off));
type = init_type (objfile, TYPE_CODE_MODULE, 0, module_name);
return set_die_type (die, type, cu);
gdbarch *gdbarch = get_objfile_arch (objfile);
struct type *tt = nullptr;
- switch (bits)
+ /* Try to find a suitable floating point builtin type of size BITS.
+ We're going to use the name of this type as the name for the complex
+ target type that we are about to create. */
+ switch (cu->language)
{
- case 32:
- tt = builtin_type (gdbarch)->builtin_float;
- break;
- case 64:
- tt = builtin_type (gdbarch)->builtin_double;
+ case language_fortran:
+ switch (bits)
+ {
+ case 32:
+ tt = builtin_f_type (gdbarch)->builtin_real;
+ break;
+ case 64:
+ tt = builtin_f_type (gdbarch)->builtin_real_s8;
+ break;
+ case 96: /* The x86-32 ABI specifies 96-bit long double. */
+ case 128:
+ tt = builtin_f_type (gdbarch)->builtin_real_s16;
+ break;
+ }
break;
- case 128:
- tt = builtin_type (gdbarch)->builtin_long_double;
+ default:
+ switch (bits)
+ {
+ case 32:
+ tt = builtin_type (gdbarch)->builtin_float;
+ break;
+ case 64:
+ tt = builtin_type (gdbarch)->builtin_double;
+ break;
+ case 96: /* The x86-32 ABI specifies 96-bit long double. */
+ case 128:
+ tt = builtin_type (gdbarch)->builtin_long_double;
+ break;
+ }
break;
}
+ /* If the type we found doesn't match the size we were looking for, then
+ pretend we didn't find a type at all, the complex target type we
+ create will then be nameless. */
+ if (tt != nullptr && TYPE_LENGTH (tt) * TARGET_CHAR_BIT != bits)
+ tt = nullptr;
+
const char *name = (tt == nullptr) ? nullptr : TYPE_NAME (tt);
return dwarf2_init_float_type (objfile, bits, name, name_hint);
}
outside their CU (they do however referencing other types via
DW_FORM_ref_sig8). */
-static struct partial_die_info *
+static const struct cu_partial_die_info
find_partial_die (sect_offset sect_off, int offset_in_dwz, struct dwarf2_cu *cu)
{
struct dwarf2_per_objfile *dwarf2_per_objfile
{
pd = cu->find_partial_die (sect_off);
if (pd != NULL)
- return pd;
+ return { cu, pd };
/* We missed recording what we needed.
Load all dies and try again. */
per_cu = cu->per_cu;
_("could not find partial DIE %s "
"in cache [from module %s]\n"),
sect_offset_str (sect_off), bfd_get_filename (objfile->obfd));
- return pd;
+ return { per_cu->cu, pd };
}
/* See if we can figure out if the class lives in a namespace. We do
real_pdi = struct_pdi;
while (real_pdi->has_specification)
- real_pdi = find_partial_die (real_pdi->spec_offset,
- real_pdi->spec_is_dwz, cu);
+ {
+ auto res = find_partial_die (real_pdi->spec_offset,
+ real_pdi->spec_is_dwz, cu);
+ real_pdi = res.pdi;
+ cu = res.cu;
+ }
if (real_pdi->die_parent != NULL)
return;
{
struct partial_die_info *spec_die;
- spec_die = find_partial_die (spec_offset, spec_is_dwz, cu);
+ auto res = find_partial_die (spec_offset, spec_is_dwz, cu);
+ spec_die = res.pdi;
+ cu = res.cu;
spec_die->fixup (cu);
case DW_FORM_implicit_const:
DW_SND (attr) = implicit_const;
break;
+ case DW_FORM_addrx:
case DW_FORM_GNU_addr_index:
if (reader->dwo_file == NULL)
{
DW_ADDR (attr) = read_addr_index_from_leb128 (cu, info_ptr, &bytes_read);
info_ptr += bytes_read;
break;
+ case DW_FORM_strx:
+ case DW_FORM_strx1:
+ case DW_FORM_strx2:
+ case DW_FORM_strx3:
+ case DW_FORM_strx4:
case DW_FORM_GNU_str_index:
if (reader->dwo_file == NULL)
{
bfd_get_filename (abfd));
}
{
- ULONGEST str_index =
- read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
-
+ ULONGEST str_index;
+ if (form == DW_FORM_strx1)
+ {
+ str_index = read_1_byte (abfd, info_ptr);
+ info_ptr += 1;
+ }
+ else if (form == DW_FORM_strx2)
+ {
+ str_index = read_2_bytes (abfd, info_ptr);
+ info_ptr += 2;
+ }
+ else if (form == DW_FORM_strx3)
+ {
+ str_index = read_3_bytes (abfd, info_ptr);
+ info_ptr += 3;
+ }
+ else if (form == DW_FORM_strx4)
+ {
+ str_index = read_4_bytes (abfd, info_ptr);
+ info_ptr += 4;
+ }
+ else
+ {
+ str_index = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ }
DW_STRING (attr) = read_str_index (reader, str_index);
DW_STRING_IS_CANONICAL (attr) = 0;
- info_ptr += bytes_read;
}
break;
default:
return bfd_get_signed_16 (abfd, buf);
}
+static unsigned int
+read_3_bytes (bfd *abfd, const gdb_byte *buf)
+{
+ unsigned int result = 0;
+ for (int i = 0; i < 3; ++i)
+ {
+ unsigned char byte = bfd_get_8 (abfd, buf);
+ buf++;
+ result |= ((unsigned int) byte << (i * 8));
+ }
+ return result;
+}
+
static unsigned int
read_4_bytes (bfd *abfd, const gdb_byte *buf)
{
addr_size);
}
-/* Given a DW_FORM_GNU_str_index, fetch the string.
+/* Given a DW_FORM_GNU_str_index or DW_FORM_strx, fetch the string.
This is only used by the Fission support. */
static const char *
&reader->dwo_file->sections.str_offsets;
const gdb_byte *info_ptr;
ULONGEST str_offset;
- static const char form_name[] = "DW_FORM_GNU_str_index";
+ static const char form_name[] = "DW_FORM_GNU_str_index or DW_FORM_strx";
dwarf2_read_section (objfile, str_section);
dwarf2_read_section (objfile, str_offsets_section);
{
if (attr->form == DW_FORM_strp || attr->form == DW_FORM_line_strp
|| attr->form == DW_FORM_string
+ || attr->form == DW_FORM_strx
|| attr->form == DW_FORM_GNU_str_index
|| attr->form == DW_FORM_GNU_strp_alt)
str = DW_STRING (attr);
/* Handle one degenerate form of location expression specially, to
preserve GDB's previous behavior when section offsets are
- specified. If this is just a DW_OP_addr or DW_OP_GNU_addr_index
- then mark this symbol as LOC_STATIC. */
+ specified. If this is just a DW_OP_addr, DW_OP_addrx, or
+ DW_OP_GNU_addr_index then mark this symbol as LOC_STATIC. */
if (attr_form_is_block (attr)
&& ((DW_BLOCK (attr)->data[0] == DW_OP_addr
&& DW_BLOCK (attr)->size == 1 + cu_header->addr_size)
- || (DW_BLOCK (attr)->data[0] == DW_OP_GNU_addr_index
+ || ((DW_BLOCK (attr)->data[0] == DW_OP_GNU_addr_index
+ || DW_BLOCK (attr)->data[0] == DW_OP_addrx)
&& (DW_BLOCK (attr)->size
== 1 + leb128_size (&DW_BLOCK (attr)->data[1])))))
{
switch (attr->form)
{
case DW_FORM_addr:
+ case DW_FORM_addrx:
case DW_FORM_GNU_addr_index:
{
gdb_byte *data;
break;
case DW_FORM_string:
case DW_FORM_strp:
+ case DW_FORM_strx:
case DW_FORM_GNU_str_index:
case DW_FORM_GNU_strp_alt:
/* DW_STRING is already allocated on the objfile obstack, point
return follow_die_ref (die, attr, ext_cu);
}
+/* A convenience function that returns an "unknown" DWARF name,
+ including the value of V. STR is the name of the entity being
+ printed, e.g., "TAG". */
+
+static const char *
+dwarf_unknown (const char *str, unsigned v)
+{
+ char *cell = get_print_cell ();
+ xsnprintf (cell, PRINT_CELL_SIZE, "DW_%s_<unknown: %u>", str, v);
+ return cell;
+}
+
/* Convert a DIE tag into its string name. */
static const char *
const char *name = get_DW_TAG_name (tag);
if (name == NULL)
- return "DW_TAG_<unknown>";
+ return dwarf_unknown ("TAG", tag);
return name;
}
name = get_DW_AT_name (attr);
if (name == NULL)
- return "DW_AT_<unknown>";
+ return dwarf_unknown ("AT", attr);
return name;
}
const char *name = get_DW_FORM_name (form);
if (name == NULL)
- return "DW_FORM_<unknown>";
+ return dwarf_unknown ("FORM", form);
return name;
}
const char *name = get_DW_ATE_name (enc);
if (name == NULL)
- return "DW_ATE_<unknown>";
+ return dwarf_unknown ("ATE", enc);
return name;
}
switch (die->attrs[i].form)
{
case DW_FORM_addr:
+ case DW_FORM_addrx:
case DW_FORM_GNU_addr_index:
fprintf_unfiltered (f, "address: ");
fputs_filtered (hex_string (DW_ADDR (&die->attrs[i])), f);
case DW_FORM_string:
case DW_FORM_strp:
case DW_FORM_line_strp:
+ case DW_FORM_strx:
case DW_FORM_GNU_str_index:
case DW_FORM_GNU_strp_alt:
fprintf_unfiltered (f, "string: \"%s\" (%s canonicalized)",
switch (attr->form)
{
case DW_FORM_addr:
+ case DW_FORM_addrx:
case DW_FORM_GNU_addr_index:
{
gdb_byte *tem;
break;
case DW_FORM_string:
case DW_FORM_strp:
+ case DW_FORM_strx:
case DW_FORM_GNU_str_index:
case DW_FORM_GNU_strp_alt:
/* DW_STRING is already allocated on the objfile obstack, point
case DW_OP_GNU_uninit:
break;
+ case DW_OP_addrx:
case DW_OP_GNU_addr_index:
case DW_OP_GNU_const_index:
stack[++stacki] = read_addr_index_from_leb128 (cu, &data[i],
bytes += 4 + read_4_bytes (abfd, bytes);
break;
+ case DW_FORM_addrx:
case DW_FORM_sdata:
+ case DW_FORM_strx:
case DW_FORM_udata:
case DW_FORM_GNU_addr_index:
case DW_FORM_GNU_str_index:
is_define ? _("definition") : _("undefinition"),
line == 0 ? _("zero") : _("non-zero"), line, body);
- if (is_define)
+ if (body == NULL)
+ {
+ /* Fedora's rpm-build's "debugedit" binary
+ corrupted .debug_macro sections.
+
+ For more info, see
+ https://bugzilla.redhat.com/show_bug.cgi?id=1708786 */
+ complaint (_("debug info gives %s invalid macro %s "
+ "without body (corrupted?) at line %d "
+ "on file %s"),
+ at_commandline ? _("command-line") : _("in-file"),
+ is_define ? _("definition") : _("undefinition"),
+ line, current_file->filename);
+ }
+ else if (is_define)
parse_macro_definition (current_file, line, body);
else
{
}
}
-/* Cleanup function for the dwarf2_per_objfile data. */
-
-static void
-dwarf2_free_objfile (struct objfile *objfile, void *datum)
-{
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = static_cast<struct dwarf2_per_objfile *> (datum);
-
- delete dwarf2_per_objfile;
-}
-
/* A set of CU "per_cu" pointer, DIE offset, and GDB type pointer.
We store these in a hash table separate from the DIEs, and preserve them
when the DIEs are flushed out of cache.
void
_initialize_dwarf2_read (void)
{
- dwarf2_objfile_data_key
- = register_objfile_data_with_cleanup (nullptr, dwarf2_free_objfile);
-
add_prefix_cmd ("dwarf", class_maintenance, set_dwarf_cmd, _("\
Set DWARF specific variables.\n\
Configure DWARF variables such as the cache size"),