Home | History | Annotate | Line # | Download | only in dwarf2
cooked-index.h revision 1.1
      1  1.1  christos /* DIE indexing
      2  1.1  christos 
      3  1.1  christos    Copyright (C) 2022-2023 Free Software Foundation, Inc.
      4  1.1  christos 
      5  1.1  christos    This file is part of GDB.
      6  1.1  christos 
      7  1.1  christos    This program is free software; you can redistribute it and/or modify
      8  1.1  christos    it under the terms of the GNU General Public License as published by
      9  1.1  christos    the Free Software Foundation; either version 3 of the License, or
     10  1.1  christos    (at your option) any later version.
     11  1.1  christos 
     12  1.1  christos    This program is distributed in the hope that it will be useful,
     13  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15  1.1  christos    GNU General Public License for more details.
     16  1.1  christos 
     17  1.1  christos    You should have received a copy of the GNU General Public License
     18  1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     19  1.1  christos 
     20  1.1  christos #ifndef GDB_DWARF2_COOKED_INDEX_H
     21  1.1  christos #define GDB_DWARF2_COOKED_INDEX_H
     22  1.1  christos 
     23  1.1  christos #include "dwarf2.h"
     24  1.1  christos #include "gdbtypes.h"
     25  1.1  christos #include "symtab.h"
     26  1.1  christos #include "hashtab.h"
     27  1.1  christos #include "dwarf2/index-common.h"
     28  1.1  christos #include "gdbsupport/gdb_string_view.h"
     29  1.1  christos #include "quick-symbol.h"
     30  1.1  christos #include "gdbsupport/gdb_obstack.h"
     31  1.1  christos #include "addrmap.h"
     32  1.1  christos #include "gdbsupport/iterator-range.h"
     33  1.1  christos #include "gdbsupport/thread-pool.h"
     34  1.1  christos #include "dwarf2/mapped-index.h"
     35  1.1  christos #include "dwarf2/tag.h"
     36  1.1  christos #include "gdbsupport/range-chain.h"
     37  1.1  christos 
     38  1.1  christos struct dwarf2_per_cu_data;
     39  1.1  christos 
     40  1.1  christos /* Flags that describe an entry in the index.  */
     41  1.1  christos enum cooked_index_flag_enum : unsigned char
     42  1.1  christos {
     43  1.1  christos   /* True if this entry is the program's "main".  */
     44  1.1  christos   IS_MAIN = 1,
     45  1.1  christos   /* True if this entry represents a "static" object.  */
     46  1.1  christos   IS_STATIC = 2,
     47  1.1  christos   /* True if this entry is an "enum class".  */
     48  1.1  christos   IS_ENUM_CLASS = 4,
     49  1.1  christos   /* True if this entry uses the linkage name.  */
     50  1.1  christos   IS_LINKAGE = 8,
     51  1.1  christos   /* True if this entry is just for the declaration of a type, not the
     52  1.1  christos      definition.  */
     53  1.1  christos   IS_TYPE_DECLARATION = 16,
     54  1.1  christos };
     55  1.1  christos DEF_ENUM_FLAGS_TYPE (enum cooked_index_flag_enum, cooked_index_flag);
     56  1.1  christos 
     57  1.1  christos /* Return true if LANG requires canonicalization.  This is used
     58  1.1  christos    primarily to work around an issue computing the name of "main".
     59  1.1  christos    This function must be kept in sync with
     60  1.1  christos    cooked_index_shard::do_finalize.  */
     61  1.1  christos 
     62  1.1  christos extern bool language_requires_canonicalization (enum language lang);
     63  1.1  christos 
     64  1.1  christos /* A cooked_index_entry represents a single item in the index.  Note
     65  1.1  christos    that two entries can be created for the same DIE -- one using the
     66  1.1  christos    name, and another one using the linkage name, if any.
     67  1.1  christos 
     68  1.1  christos    This is an "open" class and the members are all directly
     69  1.1  christos    accessible.  It is read-only after the index has been fully read
     70  1.1  christos    and processed.  */
     71  1.1  christos struct cooked_index_entry : public allocate_on_obstack
     72  1.1  christos {
     73  1.1  christos   cooked_index_entry (sect_offset die_offset_, enum dwarf_tag tag_,
     74  1.1  christos 		      cooked_index_flag flags_, const char *name_,
     75  1.1  christos 		      const cooked_index_entry *parent_entry_,
     76  1.1  christos 		      dwarf2_per_cu_data *per_cu_)
     77  1.1  christos     : name (name_),
     78  1.1  christos       tag (tag_),
     79  1.1  christos       flags (flags_),
     80  1.1  christos       die_offset (die_offset_),
     81  1.1  christos       parent_entry (parent_entry_),
     82  1.1  christos       per_cu (per_cu_)
     83  1.1  christos   {
     84  1.1  christos   }
     85  1.1  christos 
     86  1.1  christos   /* Return true if this entry matches SEARCH_FLAGS.  */
     87  1.1  christos   bool matches (block_search_flags search_flags) const
     88  1.1  christos   {
     89  1.1  christos     /* Just reject type declarations.  */
     90  1.1  christos     if ((flags & IS_TYPE_DECLARATION) != 0)
     91  1.1  christos       return false;
     92  1.1  christos 
     93  1.1  christos     if ((search_flags & SEARCH_STATIC_BLOCK) != 0
     94  1.1  christos 	&& (flags & IS_STATIC) != 0)
     95  1.1  christos       return true;
     96  1.1  christos     if ((search_flags & SEARCH_GLOBAL_BLOCK) != 0
     97  1.1  christos 	&& (flags & IS_STATIC) == 0)
     98  1.1  christos       return true;
     99  1.1  christos     return false;
    100  1.1  christos   }
    101  1.1  christos 
    102  1.1  christos   /* Return true if this entry matches DOMAIN.  */
    103  1.1  christos   bool matches (domain_enum domain) const
    104  1.1  christos   {
    105  1.1  christos     /* Just reject type declarations.  */
    106  1.1  christos     if ((flags & IS_TYPE_DECLARATION) != 0)
    107  1.1  christos       return false;
    108  1.1  christos 
    109  1.1  christos     switch (domain)
    110  1.1  christos       {
    111  1.1  christos       case LABEL_DOMAIN:
    112  1.1  christos 	return false;
    113  1.1  christos 
    114  1.1  christos       case MODULE_DOMAIN:
    115  1.1  christos 	return tag == DW_TAG_module;
    116  1.1  christos 
    117  1.1  christos       case COMMON_BLOCK_DOMAIN:
    118  1.1  christos 	return tag == DW_TAG_common_block;
    119  1.1  christos       }
    120  1.1  christos 
    121  1.1  christos     return true;
    122  1.1  christos   }
    123  1.1  christos 
    124  1.1  christos   /* Return true if this entry matches KIND.  */
    125  1.1  christos   bool matches (enum search_domain kind) const
    126  1.1  christos   {
    127  1.1  christos     /* Just reject type declarations.  */
    128  1.1  christos     if ((flags & IS_TYPE_DECLARATION) != 0)
    129  1.1  christos       return false;
    130  1.1  christos 
    131  1.1  christos     switch (kind)
    132  1.1  christos       {
    133  1.1  christos       case VARIABLES_DOMAIN:
    134  1.1  christos 	return (tag == DW_TAG_variable
    135  1.1  christos 		|| tag == DW_TAG_constant
    136  1.1  christos 		|| tag == DW_TAG_enumerator);
    137  1.1  christos       case FUNCTIONS_DOMAIN:
    138  1.1  christos 	return tag == DW_TAG_subprogram;
    139  1.1  christos       case TYPES_DOMAIN:
    140  1.1  christos 	return tag_is_type (tag);
    141  1.1  christos       case MODULES_DOMAIN:
    142  1.1  christos 	return tag == DW_TAG_module;
    143  1.1  christos       }
    144  1.1  christos 
    145  1.1  christos     return true;
    146  1.1  christos   }
    147  1.1  christos 
    148  1.1  christos   /* Construct the fully-qualified name of this entry and return a
    149  1.1  christos      pointer to it.  If allocation is needed, it will be done on
    150  1.1  christos      STORAGE.  FOR_MAIN is true if we are computing the name of the
    151  1.1  christos      "main" entry -- one marked DW_AT_main_subprogram.  This matters
    152  1.1  christos      for avoiding name canonicalization and also a related race (if
    153  1.1  christos      "main" computation is done during finalization).  */
    154  1.1  christos   const char *full_name (struct obstack *storage, bool for_main = false) const;
    155  1.1  christos 
    156  1.1  christos   /* Comparison modes for the 'compare' function.  See the function
    157  1.1  christos      for a description.  */
    158  1.1  christos   enum comparison_mode
    159  1.1  christos   {
    160  1.1  christos     MATCH,
    161  1.1  christos     SORT,
    162  1.1  christos     COMPLETE,
    163  1.1  christos   };
    164  1.1  christos 
    165  1.1  christos   /* Compare two strings, case-insensitively.  Return -1 if STRA is
    166  1.1  christos      less than STRB, 0 if they are equal, and 1 if STRA is greater.
    167  1.1  christos 
    168  1.1  christos      When comparing, '<' is considered to be less than all other
    169  1.1  christos      printable characters.  This ensures that "t<x>" sorts before
    170  1.1  christos      "t1", which is necessary when looking up "t".  This '<' handling
    171  1.1  christos      is to ensure that certain C++ lookups work correctly.  It is
    172  1.1  christos      inexact, and applied regardless of the search language, but this
    173  1.1  christos      is ok because callers of this code do more precise filtering
    174  1.1  christos      according to their needs.  This is also why using a
    175  1.1  christos      case-insensitive comparison works even for languages that are
    176  1.1  christos      case sensitive.
    177  1.1  christos 
    178  1.1  christos      MODE controls how the comparison proceeds.
    179  1.1  christos 
    180  1.1  christos      MODE==SORT is used when sorting and the only special '<' handling
    181  1.1  christos      that it does is to ensure that '<' sorts before all other
    182  1.1  christos      printable characters.  This ensures that the resulting ordering
    183  1.1  christos      will be binary-searchable.
    184  1.1  christos 
    185  1.1  christos      MODE==MATCH is used when searching for a symbol.  In this case,
    186  1.1  christos      STRB must always be the search name, and STRA must be the name in
    187  1.1  christos      the index that is under consideration.  In compare mode, early
    188  1.1  christos      termination of STRB may match STRA -- for example, "t<int>" and
    189  1.1  christos      "t" will be considered to be equal.  (However, if A=="t" and
    190  1.1  christos      B=="t<int>", then this will not consider them as equal.)
    191  1.1  christos 
    192  1.1  christos      MODE==COMPLETE is used when searching for a symbol for
    193  1.1  christos      completion.  In this case, STRB must always be the search name,
    194  1.1  christos      and STRA must be the name in the index that is under
    195  1.1  christos      consideration.  In completion mode, early termination of STRB
    196  1.1  christos      always results in a match.  */
    197  1.1  christos   static int compare (const char *stra, const char *strb,
    198  1.1  christos 		      comparison_mode mode);
    199  1.1  christos 
    200  1.1  christos   /* Compare two entries by canonical name.  */
    201  1.1  christos   bool operator< (const cooked_index_entry &other) const
    202  1.1  christos   {
    203  1.1  christos     return compare (canonical, other.canonical, SORT) < 0;
    204  1.1  christos   }
    205  1.1  christos 
    206  1.1  christos   /* The name as it appears in DWARF.  This always points into one of
    207  1.1  christos      the mapped DWARF sections.  Note that this may be the name or the
    208  1.1  christos      linkage name -- two entries are created for DIEs which have both
    209  1.1  christos      attributes.  */
    210  1.1  christos   const char *name;
    211  1.1  christos   /* The canonical name.  For C++ names, this may differ from NAME.
    212  1.1  christos      In all other cases, this is equal to NAME.  */
    213  1.1  christos   const char *canonical = nullptr;
    214  1.1  christos   /* The DWARF tag.  */
    215  1.1  christos   enum dwarf_tag tag;
    216  1.1  christos   /* Any flags attached to this entry.  */
    217  1.1  christos   cooked_index_flag flags;
    218  1.1  christos   /* The offset of this DIE.  */
    219  1.1  christos   sect_offset die_offset;
    220  1.1  christos   /* The parent entry.  This is NULL for top-level entries.
    221  1.1  christos      Otherwise, it points to the parent entry, such as a namespace or
    222  1.1  christos      class.  */
    223  1.1  christos   const cooked_index_entry *parent_entry;
    224  1.1  christos   /* The CU from which this entry originates.  */
    225  1.1  christos   dwarf2_per_cu_data *per_cu;
    226  1.1  christos 
    227  1.1  christos private:
    228  1.1  christos 
    229  1.1  christos   /* A helper method for full_name.  Emits the full scope of this
    230  1.1  christos      object, followed by the separator, to STORAGE.  If this entry has
    231  1.1  christos      a parent, its write_scope method is called first.  */
    232  1.1  christos   void write_scope (struct obstack *storage, const char *sep,
    233  1.1  christos 		    bool for_name) const;
    234  1.1  christos };
    235  1.1  christos 
    236  1.1  christos class cooked_index_vector;
    237  1.1  christos 
    238  1.1  christos /* An index of interesting DIEs.  This is "cooked", in contrast to a
    239  1.1  christos    mapped .debug_names or .gdb_index, which are "raw".  An entry in
    240  1.1  christos    the index is of type cooked_index_entry.
    241  1.1  christos 
    242  1.1  christos    Operations on the index are described below.  They are chosen to
    243  1.1  christos    make it relatively simple to implement the symtab "quick"
    244  1.1  christos    methods.  */
    245  1.1  christos class cooked_index
    246  1.1  christos {
    247  1.1  christos public:
    248  1.1  christos   cooked_index () = default;
    249  1.1  christos   DISABLE_COPY_AND_ASSIGN (cooked_index);
    250  1.1  christos 
    251  1.1  christos   /* Create a new cooked_index_entry and register it with this object.
    252  1.1  christos      Entries are owned by this object.  The new item is returned.  */
    253  1.1  christos   const cooked_index_entry *add (sect_offset die_offset, enum dwarf_tag tag,
    254  1.1  christos 				 cooked_index_flag flags,
    255  1.1  christos 				 const char *name,
    256  1.1  christos 				 const cooked_index_entry *parent_entry,
    257  1.1  christos 				 dwarf2_per_cu_data *per_cu);
    258  1.1  christos 
    259  1.1  christos   /* Install a new fixed addrmap from the given mutable addrmap.  */
    260  1.1  christos   void install_addrmap (addrmap_mutable *map)
    261  1.1  christos   {
    262  1.1  christos     gdb_assert (m_addrmap == nullptr);
    263  1.1  christos     m_addrmap = new (&m_storage) addrmap_fixed (&m_storage, map);
    264  1.1  christos   }
    265  1.1  christos 
    266  1.1  christos   /* Finalize the index.  This should be called a single time, when
    267  1.1  christos      the index has been fully populated.  It enters all the entries
    268  1.1  christos      into the internal table.  */
    269  1.1  christos   void finalize ();
    270  1.1  christos 
    271  1.1  christos   /* Wait for this index's finalization to be complete.  */
    272  1.1  christos   void wait ()
    273  1.1  christos   {
    274  1.1  christos     m_future.wait ();
    275  1.1  christos   }
    276  1.1  christos 
    277  1.1  christos   friend class cooked_index_vector;
    278  1.1  christos 
    279  1.1  christos   /* A simple range over part of m_entries.  */
    280  1.1  christos   typedef iterator_range<std::vector<cooked_index_entry *>::iterator> range;
    281  1.1  christos 
    282  1.1  christos   /* Return a range of all the entries.  */
    283  1.1  christos   range all_entries ()
    284  1.1  christos   {
    285  1.1  christos     wait ();
    286  1.1  christos     return { m_entries.begin (), m_entries.end () };
    287  1.1  christos   }
    288  1.1  christos 
    289  1.1  christos   /* Look up an entry by name.  Returns a range of all matching
    290  1.1  christos      results.  If COMPLETING is true, then a larger range, suitable
    291  1.1  christos      for completion, will be returned.  */
    292  1.1  christos   range find (const std::string &name, bool completing);
    293  1.1  christos 
    294  1.1  christos private:
    295  1.1  christos 
    296  1.1  christos   /* Return the entry that is believed to represent the program's
    297  1.1  christos      "main".  This will return NULL if no such entry is available.  */
    298  1.1  christos   const cooked_index_entry *get_main () const
    299  1.1  christos   {
    300  1.1  christos     return m_main;
    301  1.1  christos   }
    302  1.1  christos 
    303  1.1  christos   /* Look up ADDR in the address map, and return either the
    304  1.1  christos      corresponding CU, or nullptr if the address could not be
    305  1.1  christos      found.  */
    306  1.1  christos   dwarf2_per_cu_data *lookup (CORE_ADDR addr)
    307  1.1  christos   {
    308  1.1  christos     return (dwarf2_per_cu_data *) m_addrmap->find (addr);
    309  1.1  christos   }
    310  1.1  christos 
    311  1.1  christos   /* Create a new cooked_index_entry and register it with this object.
    312  1.1  christos      Entries are owned by this object.  The new item is returned.  */
    313  1.1  christos   cooked_index_entry *create (sect_offset die_offset,
    314  1.1  christos 			      enum dwarf_tag tag,
    315  1.1  christos 			      cooked_index_flag flags,
    316  1.1  christos 			      const char *name,
    317  1.1  christos 			      const cooked_index_entry *parent_entry,
    318  1.1  christos 			      dwarf2_per_cu_data *per_cu)
    319  1.1  christos   {
    320  1.1  christos     return new (&m_storage) cooked_index_entry (die_offset, tag, flags,
    321  1.1  christos 						name, parent_entry,
    322  1.1  christos 						per_cu);
    323  1.1  christos   }
    324  1.1  christos 
    325  1.1  christos   /* GNAT only emits mangled ("encoded") names in the DWARF, and does
    326  1.1  christos      not emit the module structure.  However, we need this structure
    327  1.1  christos      to do lookups.  This function recreates that structure for an
    328  1.1  christos      existing entry.  It returns the base name (last element) of the
    329  1.1  christos      full decoded name.  */
    330  1.1  christos   gdb::unique_xmalloc_ptr<char> handle_gnat_encoded_entry
    331  1.1  christos        (cooked_index_entry *entry, htab_t gnat_entries);
    332  1.1  christos 
    333  1.1  christos   /* A helper method that does the work of 'finalize'.  */
    334  1.1  christos   void do_finalize ();
    335  1.1  christos 
    336  1.1  christos   /* Storage for the entries.  */
    337  1.1  christos   auto_obstack m_storage;
    338  1.1  christos   /* List of all entries.  */
    339  1.1  christos   std::vector<cooked_index_entry *> m_entries;
    340  1.1  christos   /* If we found an entry with 'is_main' set, store it here.  */
    341  1.1  christos   cooked_index_entry *m_main = nullptr;
    342  1.1  christos   /* The addrmap.  This maps address ranges to dwarf2_per_cu_data
    343  1.1  christos      objects.  */
    344  1.1  christos   addrmap *m_addrmap = nullptr;
    345  1.1  christos   /* Storage for canonical names.  */
    346  1.1  christos   std::vector<gdb::unique_xmalloc_ptr<char>> m_names;
    347  1.1  christos   /* A future that tracks when the 'finalize' method is done.  Note
    348  1.1  christos      that the 'get' method is never called on this future, only
    349  1.1  christos      'wait'.  */
    350  1.1  christos   gdb::future<void> m_future;
    351  1.1  christos };
    352  1.1  christos 
    353  1.1  christos /* The main index of DIEs.  The parallel DIE indexers create
    354  1.1  christos    cooked_index objects.  Then, these are all handled to a
    355  1.1  christos    cooked_index_vector for storage and final indexing.  The index is
    356  1.1  christos    made by iterating over the entries previously created.  */
    357  1.1  christos 
    358  1.1  christos class cooked_index_vector : public dwarf_scanner_base
    359  1.1  christos {
    360  1.1  christos public:
    361  1.1  christos 
    362  1.1  christos   /* A convenience typedef for the vector that is contained in this
    363  1.1  christos      object.  */
    364  1.1  christos   typedef std::vector<std::unique_ptr<cooked_index>> vec_type;
    365  1.1  christos 
    366  1.1  christos   explicit cooked_index_vector (vec_type &&vec);
    367  1.1  christos   DISABLE_COPY_AND_ASSIGN (cooked_index_vector);
    368  1.1  christos 
    369  1.1  christos   /* Wait until the finalization of the entire cooked_index_vector is
    370  1.1  christos      done.  */
    371  1.1  christos   void wait ()
    372  1.1  christos   {
    373  1.1  christos     for (auto &item : m_vector)
    374  1.1  christos       item->wait ();
    375  1.1  christos   }
    376  1.1  christos 
    377  1.1  christos   ~cooked_index_vector ()
    378  1.1  christos   {
    379  1.1  christos     /* The 'finalize' methods may be run in a different thread.  If
    380  1.1  christos        this object is destroyed before these complete, then one will
    381  1.1  christos        end up writing to freed memory.  Waiting for finalization to
    382  1.1  christos        complete avoids this problem; and the cost seems ignorable
    383  1.1  christos        because creating and immediately destroying the debug info is a
    384  1.1  christos        relatively rare thing to do.  */
    385  1.1  christos     wait ();
    386  1.1  christos   }
    387  1.1  christos 
    388  1.1  christos   /* A range over a vector of subranges.  */
    389  1.1  christos   typedef range_chain<cooked_index::range> range;
    390  1.1  christos 
    391  1.1  christos   /* Look up an entry by name.  Returns a range of all matching
    392  1.1  christos      results.  If COMPLETING is true, then a larger range, suitable
    393  1.1  christos      for completion, will be returned.  */
    394  1.1  christos   range find (const std::string &name, bool completing);
    395  1.1  christos 
    396  1.1  christos   /* Return a range of all the entries.  */
    397  1.1  christos   range all_entries ()
    398  1.1  christos   {
    399  1.1  christos     std::vector<cooked_index::range> result_range;
    400  1.1  christos     result_range.reserve (m_vector.size ());
    401  1.1  christos     for (auto &entry : m_vector)
    402  1.1  christos       result_range.push_back (entry->all_entries ());
    403  1.1  christos     return range (std::move (result_range));
    404  1.1  christos   }
    405  1.1  christos 
    406  1.1  christos   /* Look up ADDR in the address map, and return either the
    407  1.1  christos      corresponding CU, or nullptr if the address could not be
    408  1.1  christos      found.  */
    409  1.1  christos   dwarf2_per_cu_data *lookup (CORE_ADDR addr);
    410  1.1  christos 
    411  1.1  christos   /* Return a new vector of all the addrmaps used by all the indexes
    412  1.1  christos      held by this object.  */
    413  1.1  christos   std::vector<addrmap *> get_addrmaps ();
    414  1.1  christos 
    415  1.1  christos   /* Return the entry that is believed to represent the program's
    416  1.1  christos      "main".  This will return NULL if no such entry is available.  */
    417  1.1  christos   const cooked_index_entry *get_main () const;
    418  1.1  christos 
    419  1.1  christos   cooked_index_vector *index_for_writing () override
    420  1.1  christos   {
    421  1.1  christos     return this;
    422  1.1  christos   }
    423  1.1  christos 
    424  1.1  christos   quick_symbol_functions_up make_quick_functions () const override;
    425  1.1  christos 
    426  1.1  christos private:
    427  1.1  christos 
    428  1.1  christos   /* The vector of cooked_index objects.  This is stored because the
    429  1.1  christos      entries are stored on the obstacks in those objects.  */
    430  1.1  christos   vec_type m_vector;
    431  1.1  christos };
    432  1.1  christos 
    433  1.1  christos #endif /* GDB_DWARF2_COOKED_INDEX_H */
    434