/* DWARF 2 debugging format support for GDB.
- Copyright (C) 1994-2021 Free Software Foundation, Inc.
+ Copyright (C) 1994-2022 Free Software Foundation, Inc.
Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
Inc. with support from Florida State University (under contract
static line_header_up dwarf_decode_line_header (sect_offset sect_off,
struct dwarf2_cu *cu);
-struct file_and_directory;
static void dwarf_decode_lines (struct line_header *,
const file_and_directory &,
struct dwarf2_cu *, dwarf2_psymtab *,
delete data;
}
-/* The return type of find_file_and_directory. Note, the enclosed
- string pointers are only valid while this object is valid. */
-
-struct file_and_directory
-{
- /* The filename. This is never NULL. */
- const char *name;
-
- /* The compilation directory. NULL if not known. If we needed to
- compute a new string, it will be stored in the per-BFD string
- bcache; otherwise, points directly to the DW_AT_comp_dir string
- attribute owned by the obstack that owns the DIE. */
- const char *comp_dir;
-};
-
-static file_and_directory find_file_and_directory (struct die_info *die,
- struct dwarf2_cu *cu);
+static file_and_directory &find_file_and_directory
+ (struct die_info *die, struct dwarf2_cu *cu);
static const char *compute_include_file_name
(const struct line_header *lh,
lh = dwarf_decode_line_header (line_offset, cu);
}
- file_and_directory fnd = find_file_and_directory (comp_unit_die, cu);
+ file_and_directory &fnd = find_file_and_directory (comp_unit_die, cu);
int offset = 0;
- if (strcmp (fnd.name, "<unknown>") != 0)
+ if (!fnd.is_unknown ())
++offset;
else if (lh == nullptr)
return;
}
qfn->num_file_names = offset + include_names.size ();
- qfn->comp_dir = fnd.comp_dir;
+ qfn->comp_dir = fnd.intern_comp_dir (per_objfile->objfile);
qfn->file_names =
XOBNEWVEC (&per_objfile->per_bfd->obstack, const char *,
qfn->num_file_names);
if (offset != 0)
- qfn->file_names[0] = xstrdup (fnd.name);
+ qfn->file_names[0] = xstrdup (fnd.get_name ());
if (!include_names.empty ())
memcpy (&qfn->file_names[offset], include_names.data (),
compunit_symtab *get_compunit_symtab (struct objfile *objfile) const override
{
- return nullptr;
+ compunit_symtab *cust = includer ()->get_compunit_symtab (objfile);
+ while (cust != nullptr && cust->user != nullptr)
+ cust = cust->user;
+ return cust;
}
private:
prepare_one_comp_unit (cu, comp_unit_die, pretend_language);
/* Allocate a new partial symbol table structure. */
- gdb::unique_xmalloc_ptr<char> debug_filename;
static const char artificial[] = "<artificial>";
- file_and_directory fnd = find_file_and_directory (comp_unit_die, cu);
- if (strcmp (fnd.name, artificial) == 0)
+ file_and_directory &fnd = find_file_and_directory (comp_unit_die, cu);
+ if (strcmp (fnd.get_name (), artificial) == 0)
{
- debug_filename.reset (concat (artificial, "@",
- sect_offset_str (per_cu->sect_off),
- (char *) NULL));
- fnd.name = debug_filename.get ();
+ gdb::unique_xmalloc_ptr<char> debug_filename
+ (concat (artificial, "@",
+ sect_offset_str (per_cu->sect_off),
+ (char *) NULL));
+ fnd.set_name (std::move (debug_filename));
}
- pst = create_partial_symtab (per_cu, per_objfile, fnd.name);
+ pst = create_partial_symtab (per_cu, per_objfile, fnd.get_name ());
/* This must be done before calling dwarf2_build_include_psymtabs. */
pst->dirname = dwarf2_string_attr (comp_unit_die, DW_AT_comp_dir, cu);
return cu->producer_is_gcc_lt_4_3;
}
-static file_and_directory
+static file_and_directory &
find_file_and_directory (struct die_info *die, struct dwarf2_cu *cu)
{
- file_and_directory res;
+ if (cu->per_cu->fnd != nullptr)
+ return *cu->per_cu->fnd;
/* Find the filename. Do not use dwarf2_name here, since the filename
is not a source language identifier. */
- res.name = dwarf2_string_attr (die, DW_AT_name, cu);
- res.comp_dir = dwarf2_string_attr (die, DW_AT_comp_dir, cu);
-
- if (res.comp_dir == NULL
- && producer_is_gcc_lt_4_3 (cu) && res.name != NULL
- && IS_ABSOLUTE_PATH (res.name))
- {
- std::string comp_dir_storage = ldirname (res.name);
- if (!comp_dir_storage.empty ())
- res.comp_dir
- = cu->per_objfile->objfile->intern (comp_dir_storage.c_str ());
- }
- if (res.comp_dir != NULL)
- {
- /* Irix 6.2 native cc prepends <machine>.: to the compilation
- directory, get rid of it. */
- const char *cp = strchr (res.comp_dir, ':');
+ file_and_directory res (dwarf2_string_attr (die, DW_AT_name, cu),
+ dwarf2_string_attr (die, DW_AT_comp_dir, cu));
- if (cp && cp != res.comp_dir && cp[-1] == '.' && cp[1] == '/')
- res.comp_dir = cp + 1;
- }
-
- if (res.name == NULL)
- res.name = "<unknown>";
+ if (res.get_comp_dir () == nullptr
+ && producer_is_gcc_lt_4_3 (cu)
+ && res.get_name () != nullptr
+ && IS_ABSOLUTE_PATH (res.get_name ()))
+ res.set_comp_dir (ldirname (res.get_name ()));
- return res;
+ cu->per_cu->fnd.reset (new file_and_directory (std::move (res)));
+ return *cu->per_cu->fnd;
}
/* Handle DW_AT_stmt_list for a compilation unit.
lowpc = highpc;
lowpc = gdbarch_adjust_dwarf2_addr (gdbarch, lowpc + baseaddr);
- file_and_directory fnd = find_file_and_directory (die, cu);
+ file_and_directory &fnd = find_file_and_directory (die, cu);
- cu->start_symtab (fnd.name, fnd.comp_dir, lowpc);
+ cu->start_symtab (fnd.get_name (), fnd.intern_comp_dir (objfile), lowpc);
gdb_assert (per_objfile->sym_cu == nullptr);
scoped_restore restore_sym_cu
/* Decode line number information if present. We do this before
processing child DIEs, so that the line header table is available
- for DW_AT_decl_file. */
- handle_DW_AT_stmt_list (die, cu, fnd, lowpc);
+ for DW_AT_decl_file. The PC check is here because, if LOWPC and
+ HIGHPC are both 0x0, then there won't be any interesting code in
+ the CU, but a check later on (in
+ lnp_state_machine::check_line_address) will fail to properly
+ exclude an entry that was removed via --gc-sections. */
+ if (lowpc != highpc)
+ handle_DW_AT_stmt_list (die, cu, fnd, lowpc);
/* Process all dies in compilation unit. */
if (die->child != NULL)
{
cu->producer_is_gxx_lt_4_6 = major < 4 || (major == 4 && minor < 6);
cu->producer_is_gcc_lt_4_3 = major < 4 || (major == 4 && minor < 3);
+ cu->producer_is_gcc_11 = major == 11;
}
else if (producer_is_icc (cu->producer, &major, &minor))
{
if (attr->form_is_constant ())
{
LONGEST offset = attr->constant_value (0);
+
+ /* Work around this GCC 11 bug, where it would erroneously use -1
+ data member locations, instead of 0:
+
+ Negative DW_AT_data_member_location
+ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101378
+ */
+ if (offset == -1 && cu->producer_is_gcc_11)
+ {
+ complaint (_("DW_AT_data_member_location value of -1, assuming 0"));
+ offset = 0;
+ }
+
field->set_loc_bitpos (offset * bits_per_byte);
}
else if (attr->form_is_section_offset ())
break;
case DW_ATE_UTF:
{
- if (bits == 16)
- type = builtin_type (arch)->builtin_char16;
- else if (bits == 32)
- type = builtin_type (arch)->builtin_char32;
- else
- {
- complaint (_("unsupported DW_ATE_UTF bit size: '%d'"),
- bits);
- type = dwarf2_init_integer_type (cu, objfile, bits, 1, name);
- }
+ type = init_character_type (objfile, bits, 1, name);
return set_die_type (die, type, cu);
}
break;
break;
}
- if (name && strcmp (name, "char") == 0)
+ if (type->code () == TYPE_CODE_INT
+ && name != nullptr
+ && strcmp (name, "char") == 0)
type->set_has_no_signedness (true);
maybe_set_alignment (cu, die, type);
gdb::unique_xmalloc_ptr<char> hold_compare;
if (!IS_ABSOLUTE_PATH (include_name)
- && (dir_name != NULL || cu_info.comp_dir != NULL))
+ && (dir_name != nullptr || cu_info.get_comp_dir () != nullptr))
{
/* Avoid creating a duplicate name for CU_INFO.
We do this by comparing INCLUDE_NAME and CU_INFO.
include_name = name_holder->get ();
include_name_to_compare = include_name;
}
- if (!IS_ABSOLUTE_PATH (include_name) && cu_info.comp_dir != nullptr)
+ if (!IS_ABSOLUTE_PATH (include_name)
+ && cu_info.get_comp_dir () != nullptr)
{
- hold_compare.reset (concat (cu_info.comp_dir, SLASH_STRING,
+ hold_compare.reset (concat (cu_info.get_comp_dir (), SLASH_STRING,
include_name, (char *) NULL));
include_name_to_compare = hold_compare.get ();
}
}
gdb::unique_xmalloc_ptr<char> copied_name;
- const char *cu_filename = cu_info.name;
- if (!IS_ABSOLUTE_PATH (cu_filename) && cu_info.comp_dir != nullptr)
+ const char *cu_filename = cu_info.get_name ();
+ if (!IS_ABSOLUTE_PATH (cu_filename) && cu_info.get_comp_dir () != nullptr)
{
- copied_name.reset (concat (cu_info.comp_dir, SLASH_STRING,
+ copied_name.reset (concat (cu_info.get_comp_dir (), SLASH_STRING,
cu_filename, (char *) NULL));
cu_filename = copied_name.get ();
}
{
unsigned int i;
- print_spaces (indent, f);
- fprintf_unfiltered (f, "Die: %s (abbrev %d, offset %s)\n",
+ fprintf_unfiltered (f, "%*sDie: %s (abbrev %d, offset %s)\n",
+ indent, "",
dwarf_tag_name (die->tag), die->abbrev,
sect_offset_str (die->sect_off));
if (die->parent != NULL)
- {
- print_spaces (indent, f);
- fprintf_unfiltered (f, " parent at offset: %s\n",
- sect_offset_str (die->parent->sect_off));
- }
+ fprintf_unfiltered (f, "%*s parent at offset: %s\n",
+ indent, "",
+ sect_offset_str (die->parent->sect_off));
- print_spaces (indent, f);
- fprintf_unfiltered (f, " has children: %s\n",
- dwarf_bool_name (die->child != NULL));
+ fprintf_unfiltered (f, "%*s has children: %s\n",
+ indent, "",
+ dwarf_bool_name (die->child != NULL));
- print_spaces (indent, f);
- fprintf_unfiltered (f, " attributes:\n");
+ fprintf_unfiltered (f, "%*s attributes:\n", indent, "");
for (i = 0; i < die->num_attrs; ++i)
{
- print_spaces (indent, f);
- fprintf_unfiltered (f, " %s (%s) ",
- dwarf_attr_name (die->attrs[i].name),
- dwarf_form_name (die->attrs[i].form));
+ fprintf_unfiltered (f, "%*s %s (%s) ",
+ indent, "",
+ dwarf_attr_name (die->attrs[i].name),
+ dwarf_form_name (die->attrs[i].form));
switch (die->attrs[i].form)
{
if (die->child != NULL)
{
- print_spaces (indent, f);
- fprintf_unfiltered (f, " Children:");
+ fprintf_unfiltered (f, "%*s Children:", indent, "");
if (level + 1 < max_level)
{
fprintf_unfiltered (f, "\n");