]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/dwarf2/cooked-index.c
gdb/alpha: Redefine fpcr with fpcr_flags type
[thirdparty/binutils-gdb.git] / gdb / dwarf2 / cooked-index.c
CommitLineData
51f5a4b8
TT
1/* DIE indexing
2
d01e8234 3 Copyright (C) 2022-2025 Free Software Foundation, Inc.
51f5a4b8
TT
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
51f5a4b8
TT
20#include "dwarf2/cooked-index.h"
21#include "dwarf2/read.h"
7d82b08e 22#include "dwarf2/stringify.h"
e5dc0d5d 23#include "event-top.h"
cc552602 24#include "maint.h"
52e5e48e
TT
25#include "observable.h"
26#include "run-on-main-thread.h"
e5afccc7 27#include "gdbsupport/task-group.h"
f0c3dcc1 28#include "cli/cli-cmds.h"
52e5e48e
TT
29
30/* We don't want gdb to exit while it is in the process of writing to
31 the index cache. So, all live cooked index vectors are stored
32 here, and then these are all waited for before exit proceeds. */
890d1d38 33static gdb::unordered_set<cooked_index *> active_vectors;
ac37b79c 34
5021c5bb
TT
35/* Return true if LANG requires canonicalization. This is used
36 primarily to work around an issue computing the name of "main".
37 This function must be kept in sync with
38 cooked_index_shard::finalize. */
7d82b08e 39
5021c5bb 40static bool
47fe57c9
TT
41language_requires_canonicalization (enum language lang)
42{
43 return (lang == language_ada
44 || lang == language_c
45 || lang == language_cplus);
46}
47
aca98091 48cooked_index::cooked_index (cooked_index_worker_up &&worker)
6fca4d96 49 : m_state (std::move (worker))
20a26f4e 50{
52e5e48e
TT
51 /* ACTIVE_VECTORS is not locked, and this assert ensures that this
52 will be caught if ever moved to the background. */
53 gdb_assert (is_main_thread ());
54 active_vectors.insert (this);
55}
56
33c6eaae
TT
57void
58cooked_index::start_reading ()
59{
60 m_state->start ();
61}
6f214d0f
TT
62
63void
33c6eaae 64cooked_index::wait (cooked_state desired_state, bool allow_quit)
6f214d0f 65{
33c6eaae 66 gdb_assert (desired_state != cooked_state::INITIAL);
8adc5522 67
33c6eaae
TT
68 /* If the state object has been deleted, then that means waiting is
69 completely done. */
70 if (m_state == nullptr)
71 return;
72
73 if (m_state->wait (desired_state, allow_quit))
74 {
75 /* Only the main thread can modify this. */
76 gdb_assert (is_main_thread ());
77 m_state.reset (nullptr);
78 }
79}
80
81void
60ac9c60 82cooked_index::set_contents ()
33c6eaae 83{
8e745eac 84 gdb_assert (m_shards.empty ());
60ac9c60 85 m_shards = m_state->release_shards ();
33c6eaae
TT
86
87 m_state->set (cooked_state::MAIN_AVAILABLE);
88
33c6eaae
TT
89 /* This is run after finalization is done -- but not before. If
90 this task were submitted earlier, it would have to wait for
91 finalization. However, that would take a slot in the global
92 thread pool, and if enough such tasks were submitted at once, it
93 would cause a livelock. */
60ac9c60 94 gdb::task_group finalizers ([this] ()
33c6eaae
TT
95 {
96 m_state->set (cooked_state::FINALIZED);
60ac9c60 97 m_state->write_to_cache (index_for_writing ());
ed29a346 98 m_state->set (cooked_state::CACHE_DONE);
33c6eaae
TT
99 });
100
8e745eac 101 for (auto &shard : m_shards)
33c6eaae 102 {
8e745eac 103 auto this_shard = shard.get ();
60ac9c60 104 const parent_map_map *parent_maps = m_state->get_parent_map_map ();
cc552602
SM
105 finalizers.add_task ([=] ()
106 {
c6115b5e
TV
107 scoped_time_it time_it ("DWARF finalize worker",
108 m_state->m_per_command_time);
cc552602
SM
109 this_shard->finalize (parent_maps);
110 });
33c6eaae
TT
111 }
112
113 finalizers.start ();
6f214d0f
TT
114}
115
52e5e48e
TT
116cooked_index::~cooked_index ()
117{
33c6eaae 118 /* Wait for index-creation to be done, though this one must also
52e5e48e
TT
119 waited for by the per-BFD object to ensure the required data
120 remains live. */
33c6eaae 121 wait (cooked_state::CACHE_DONE);
52e5e48e
TT
122
123 /* Remove our entry from the global list. See the assert in the
124 constructor to understand this. */
125 gdb_assert (is_main_thread ());
126 active_vectors.erase (this);
20a26f4e
TT
127}
128
129/* See cooked-index.h. */
130
b55c841c 131dwarf2_per_cu *
bdb4b803 132cooked_index::lookup (unrelocated_addr addr)
20a26f4e 133{
33c6eaae
TT
134 /* Ensure that the address maps are ready. */
135 wait (cooked_state::MAIN_AVAILABLE, true);
8e745eac 136 for (const auto &shard : m_shards)
20a26f4e 137 {
b55c841c 138 dwarf2_per_cu *result = shard->lookup (addr);
20a26f4e
TT
139 if (result != nullptr)
140 return result;
141 }
142 return nullptr;
143}
144
145/* See cooked-index.h. */
146
70ca3a6b 147std::vector<const addrmap *>
33c6eaae 148cooked_index::get_addrmaps ()
20a26f4e 149{
33c6eaae
TT
150 /* Ensure that the address maps are ready. */
151 wait (cooked_state::MAIN_AVAILABLE, true);
70ca3a6b 152 std::vector<const addrmap *> result;
8e745eac
SM
153 for (const auto &shard : m_shards)
154 result.push_back (shard->m_addrmap);
20a26f4e
TT
155 return result;
156}
157
158/* See cooked-index.h. */
159
19455ee1 160cooked_index::range
33c6eaae 161cooked_index::find (const std::string &name, bool completing)
20a26f4e 162{
33c6eaae 163 wait (cooked_state::FINALIZED, true);
a8dc6718 164 std::vector<cooked_index_shard::range> result_range;
8e745eac
SM
165 result_range.reserve (m_shards.size ());
166 for (auto &shard : m_shards)
167 result_range.push_back (shard->find (name, completing));
20a26f4e
TT
168 return range (std::move (result_range));
169}
170
171/* See cooked-index.h. */
172
33c6eaae
TT
173const char *
174cooked_index::get_main_name (struct obstack *obstack, enum language *lang)
175 const
176{
177 const cooked_index_entry *entry = get_main ();
178 if (entry == nullptr)
179 return nullptr;
180
5902fa8a 181 *lang = entry->lang;
c05c9914 182 return entry->full_name (obstack, FOR_MAIN);
33c6eaae
TT
183}
184
185/* See cooked_index.h. */
186
20a26f4e 187const cooked_index_entry *
19455ee1 188cooked_index::get_main () const
20a26f4e 189{
33c6eaae 190 const cooked_index_entry *best_entry = nullptr;
8e745eac 191 for (const auto &shard : m_shards)
20a26f4e 192 {
8e745eac 193 const cooked_index_entry *entry = shard->get_main ();
33c6eaae
TT
194 /* Choose the first "main" we see. We only do this for names
195 not requiring canonicalization. At this point in the process
196 names might not have been canonicalized. However, currently,
197 languages that require this step also do not use
198 DW_AT_main_subprogram. An assert is appropriate here because
199 this filtering is done in get_main. */
200 if (entry != nullptr)
47fe57c9 201 {
33c6eaae
TT
202 if ((entry->flags & IS_MAIN) != 0)
203 {
5902fa8a 204 if (!language_requires_canonicalization (entry->lang))
33c6eaae
TT
205 {
206 /* There won't be one better than this. */
207 return entry;
208 }
209 }
210 else
211 {
212 /* This is one that is named "main". Here we don't care
213 if the language requires canonicalization, due to how
214 the entry is detected. Entries like this have worse
215 priority than IS_MAIN entries. */
216 if (best_entry == nullptr)
217 best_entry = entry;
218 }
47fe57c9 219 }
20a26f4e
TT
220 }
221
33c6eaae 222 return best_entry;
20a26f4e 223}
ac37b79c 224
9fac3e79
TT
225quick_symbol_functions_up
226cooked_index::make_quick_functions () const
227{
228 return quick_symbol_functions_up (new cooked_index_functions);
229}
230
7d82b08e
SM
231/* See cooked-index.h. */
232
233void
33c6eaae 234cooked_index::dump (gdbarch *arch)
7d82b08e 235{
8f258a6c
TV
236 auto_obstack temp_storage;
237
7d82b08e
SM
238 gdb_printf (" entries:\n");
239 gdb_printf ("\n");
240
241 size_t i = 0;
242 for (const cooked_index_entry *entry : this->all_entries ())
243 {
244 QUIT;
245
246 gdb_printf (" [%zu] ((cooked_index_entry *) %p)\n", i++, entry);
247 gdb_printf (" name: %s\n", entry->name);
248 gdb_printf (" canonical: %s\n", entry->canonical);
3e0c29b2 249 gdb_printf (" qualified: %s\n",
c05c9914 250 entry->full_name (&temp_storage, 0, "::"));
7d82b08e
SM
251 gdb_printf (" DWARF tag: %s\n", dwarf_tag_name (entry->tag));
252 gdb_printf (" flags: %s\n", to_string (entry->flags).c_str ());
b8a175b4 253 gdb_printf (" DIE offset: %s\n", sect_offset_str (entry->die_offset));
7d82b08e 254
42bd6b5f
TV
255 if ((entry->flags & IS_PARENT_DEFERRED) != 0)
256 gdb_printf (" parent: deferred (%" PRIx64 ")\n",
257 entry->get_deferred_parent ());
258 else if (entry->get_parent () != nullptr)
7d82b08e 259 gdb_printf (" parent: ((cooked_index_entry *) %p) [%s]\n",
850fce8b 260 entry->get_parent (), entry->get_parent ()->name);
7d82b08e
SM
261 else
262 gdb_printf (" parent: ((cooked_index_entry *) 0)\n");
263
264 gdb_printf ("\n");
265 }
266
267 const cooked_index_entry *main_entry = this->get_main ();
268 if (main_entry != nullptr)
269 gdb_printf (" main: ((cooked_index_entry *) %p) [%s]\n", main_entry,
270 main_entry->name);
271 else
272 gdb_printf (" main: ((cooked_index_entry *) 0)\n");
273
274 gdb_printf ("\n");
275 gdb_printf (" address maps:\n");
276 gdb_printf ("\n");
277
278 std::vector<const addrmap *> addrmaps = this->get_addrmaps ();
279 for (i = 0; i < addrmaps.size (); ++i)
280 {
de33cf88 281 const addrmap *addrmap = addrmaps[i];
7d82b08e 282
de33cf88 283 gdb_printf (" [%zu] ((addrmap *) %p)\n", i, addrmap);
7d82b08e
SM
284 gdb_printf ("\n");
285
de33cf88
SM
286 if (addrmap == nullptr)
287 continue;
288
289 addrmap->foreach ([arch] (CORE_ADDR start_addr, const void *obj)
7d82b08e
SM
290 {
291 QUIT;
292
293 const char *start_addr_str = paddress (arch, start_addr);
294
295 if (obj != nullptr)
296 {
b55c841c
SM
297 const dwarf2_per_cu *per_cu
298 = static_cast<const dwarf2_per_cu *> (obj);
299 gdb_printf (" [%s] ((dwarf2_per_cu *) %p)\n",
7d82b08e
SM
300 start_addr_str, per_cu);
301 }
302 else
b55c841c 303 gdb_printf (" [%s] ((dwarf2_per_cu *) 0)\n", start_addr_str);
7d82b08e
SM
304
305 return 0;
306 });
307
308 gdb_printf ("\n");
309 }
310}
311
52e5e48e
TT
312/* Wait for all the index cache entries to be written before gdb
313 exits. */
314static void
315wait_for_index_cache (int)
316{
317 gdb_assert (is_main_thread ());
318 for (cooked_index *item : active_vectors)
319 item->wait_completely ();
320}
321
f0c3dcc1
TT
322/* A maint command to wait for the cache. */
323
324static void
325maintenance_wait_for_index_cache (const char *args, int from_tty)
326{
327 wait_for_index_cache (0);
328}
329
5fe70629 330INIT_GDB_FILE (cooked_index)
ac37b79c 331{
f0c3dcc1
TT
332 add_cmd ("wait-for-index-cache", class_maintenance,
333 maintenance_wait_for_index_cache, _("\
4779ed97
TT
334Wait until all pending writes to the index cache have completed.\n\
335Usage: maintenance wait-for-index-cache"),
f0c3dcc1
TT
336 &maintenancelist);
337
52e5e48e 338 gdb::observers::gdb_exiting.attach (wait_for_index_cache, "cooked-index");
ac37b79c 339}