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