From 446fcb446f57dbb33728c3dbd5f092bca3ba3547 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Thu, 21 Apr 2022 07:28:56 -0600 Subject: [PATCH] Fix .debug_names regression with new indexer At AdaCore, we run the internal gdb test suite in several modes, including one using the .debug_names index. This caught a regression caused by the new DWARF indexer. First, the psymtabs-based .debug_names generator was completely wrong. However, to avoid making the rewrite series even bigger (fixing the writer will also require rewriting the .debug_names reader), it attempted to preserve the weirdness. However, this was not done properly. For example the old writer did this: - case STRUCT_DOMAIN: - return DW_TAG_structure_type; The new code, instead, simply preserves the actual DWARF tag -- but this makes future lookups fail, because the .debug_names reader only looks for DW_TAG_structure_type. This patch attempts to revert to the old behavior in the writer. --- gdb/dwarf2/cooked-index.h | 7 ++-- gdb/dwarf2/index-write.c | 14 +++++++- gdb/dwarf2/tag.h | 67 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 gdb/dwarf2/tag.h diff --git a/gdb/dwarf2/cooked-index.h b/gdb/dwarf2/cooked-index.h index e1ff05645c5..21bda8698c1 100644 --- a/gdb/dwarf2/cooked-index.h +++ b/gdb/dwarf2/cooked-index.h @@ -32,6 +32,7 @@ #include "gdbsupport/iterator-range.h" #include "gdbsupport/thread-pool.h" #include "dwarf2/mapped-index.h" +#include "dwarf2/tag.h" struct dwarf2_per_cu_data; @@ -107,11 +108,13 @@ struct cooked_index_entry : public allocate_on_obstack switch (kind) { case VARIABLES_DOMAIN: - return tag == DW_TAG_variable; + return (tag == DW_TAG_variable + || tag == DW_TAG_constant + || tag == DW_TAG_enumerator); case FUNCTIONS_DOMAIN: return tag == DW_TAG_subprogram; case TYPES_DOMAIN: - return tag == DW_TAG_typedef || tag == DW_TAG_structure_type; + return tag_is_type (tag); case MODULES_DOMAIN: return tag == DW_TAG_module; } diff --git a/gdb/dwarf2/index-write.c b/gdb/dwarf2/index-write.c index 3d1c78d4459..e27c2b5fddd 100644 --- a/gdb/dwarf2/index-write.c +++ b/gdb/dwarf2/index-write.c @@ -37,6 +37,7 @@ #include "gdbcmd.h" #include "objfiles.h" #include "ada-lang.h" +#include "dwarf2/tag.h" #include #include @@ -569,7 +570,18 @@ public: const auto it = m_cu_index_htab.find (entry->per_cu); gdb_assert (it != m_cu_index_htab.cend ()); const char *name = entry->full_name (&m_string_obstack); - insert (entry->tag, name, it->second, (entry->flags & IS_STATIC) != 0, + + /* This is incorrect but it mirrors gdb's historical behavior; and + because the current .debug_names generation is also incorrect, + it seems better to follow what was done before, rather than + introduce a mismatch between the newer and older gdb. */ + dwarf_tag tag = entry->tag; + if (tag != DW_TAG_typedef && tag_is_type (tag)) + tag = DW_TAG_structure_type; + else if (tag == DW_TAG_enumerator || tag == DW_TAG_constant) + tag = DW_TAG_variable; + + insert (tag, name, it->second, (entry->flags & IS_STATIC) != 0, entry->per_cu->is_debug_types ? unit_kind::tu : unit_kind::cu, entry->per_cu->lang); } diff --git a/gdb/dwarf2/tag.h b/gdb/dwarf2/tag.h new file mode 100644 index 00000000000..735a6d581be --- /dev/null +++ b/gdb/dwarf2/tag.h @@ -0,0 +1,67 @@ +/* Tag attributes + + Copyright (C) 2022 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifndef GDB_DWARF2_TAG_H +#define GDB_DWARF2_TAG_H + +#include "dwarf2.h" + +/* Return true if TAG represents a type, false otherwise. */ + +static inline bool +tag_is_type (dwarf_tag tag) +{ + switch (tag) + { + case DW_TAG_padding: + case DW_TAG_array_type: + case DW_TAG_class_type: + case DW_TAG_enumeration_type: + case DW_TAG_pointer_type: + case DW_TAG_reference_type: + case DW_TAG_string_type: + case DW_TAG_structure_type: + case DW_TAG_subroutine_type: + case DW_TAG_typedef: + case DW_TAG_union_type: + case DW_TAG_ptr_to_member_type: + case DW_TAG_set_type: + case DW_TAG_subrange_type: + case DW_TAG_base_type: + case DW_TAG_const_type: + case DW_TAG_packed_type: + case DW_TAG_template_type_param: + case DW_TAG_volatile_type: + case DW_TAG_restrict_type: + case DW_TAG_interface_type: + case DW_TAG_namespace: + case DW_TAG_unspecified_type: + case DW_TAG_shared_type: + case DW_TAG_rvalue_reference_type: + case DW_TAG_coarray_type: + case DW_TAG_dynamic_type: + case DW_TAG_atomic_type: + case DW_TAG_immutable_type: + return true; + default: + return false; + } +} + +#endif /* GDB_DWARF2_TAG_H */ -- 2.30.2