32#include "gdbsupport/gdb-safe-ctype.h"
33#include "gdbsupport/selftest.h"
35#include <unordered_set>
48 static constexpr cooked_index_flag::string_mapping
mapping[] = {
75 auto munge = [] (
char c) ->
unsigned char
81 return TOLOWER ((
unsigned char) c);
86 && (munge (*stra) == munge (*strb)))
92 unsigned char c1 = munge (*stra);
93 unsigned char c2 = munge (*strb);
107 return c1 <
c2 ? -1 : 1;
125 mode_complete) == 0);
134 mode_complete) == 0);
143 mode_complete) == 0);
150 mode_complete) == 0);
165 mode_complete) == 0);
192 const char *sep =
nullptr;
211 obstack_grow0 (storage, local_name, strlen (local_name));
212 return (
const char *) obstack_finish (storage);
225 obstack_grow (storage, local_name, strlen (local_name));
226 obstack_grow (storage, sep, strlen (sep));
233 cooked_index_flag
flags,
const char *
name,
238 parent_entry, per_cu);
254 m_future = gdb::thread_pool::g_thread_pool->post_task ([
this] ()
262gdb::unique_xmalloc_ptr<char>
266 std::string canonical =
ada_decode (entry->name,
false,
false);
267 if (canonical.empty ())
269 std::vector<gdb::string_view> names =
split_name (canonical.c_str (),
271 gdb::string_view tail = names.back ();
275 for (
const auto &
name : names)
278 void **slot = htab_find_slot_with_hash (gnat_entries, &
name,
283 if (last ==
nullptr || last->
per_cu != entry->per_cu)
285 gdb::unique_xmalloc_ptr<char> new_name
286 = make_unique_xstrndup (
name.data (),
name.length ());
287 last =
create (entry->die_offset, DW_TAG_namespace,
288 0, new_name.get (), parent,
291 m_names.push_back (std::move (new_name));
298 entry->parent_entry = parent;
299 return make_unique_xstrndup (tail.data (), tail.length ());
307 auto hash_name_ptr = [] (
const void *p)
310 return htab_hash_pointer (entry->name);
313 auto eq_name_ptr = [] (
const void *a,
const void *b) ->
int
324 htab_up seen_names (htab_create_alloc (10, hash_name_ptr, eq_name_ptr,
327 auto hash_entry = [] (
const void *e)
333 auto eq_entry = [] (
const void *a,
const void *b) ->
int
336 const gdb::string_view *sv = (
const gdb::string_view *) b;
337 return (strlen (ae->
canonical) == sv->length ()
338 && strncasecmp (ae->
canonical, sv->data (), sv->length ()) == 0);
341 htab_up gnat_entries (htab_create_alloc (10, hash_entry, eq_entry,
348 gdb_assert (entry->canonical ==
nullptr);
350 entry->canonical = entry->name;
353 gdb::unique_xmalloc_ptr<char> canon_name
355 if (canon_name ==
nullptr)
356 entry->canonical = entry->name;
359 entry->canonical = canon_name.get ();
360 m_names.push_back (std::move (canon_name));
366 void **slot = htab_find_slot (seen_names.get (), entry,
368 if (*slot ==
nullptr)
370 gdb::unique_xmalloc_ptr<char> canon_name
374 if (canon_name ==
nullptr)
375 entry->canonical = entry->name;
378 entry->canonical = canon_name.get ();
379 m_names.push_back (std::move (canon_name));
391 entry->canonical = entry->name;
416 const std::string &n)
418 return cooked_index_entry::compare (entry->canonical, n.c_str (), mode) < 0;
422 [=] (
const std::string &n,
425 return cooked_index_entry::compare (entry->canonical, n.c_str (), mode) > 0;
428 return range (lower, upper);
438 std::chrono::milliseconds duration { 15 };
439 while (
m_future.wait_for (duration) == gdb::future_status::timeout)
447 : m_vector (
std::move (vec))
468 = gdb::thread_pool::g_thread_pool->post_task ([
this, per_bfd,
469#
if __cplusplus >= 201402L
470 ctx = std::move (ctx)
510 if (result !=
nullptr)
518std::vector<const addrmap *>
521 std::vector<const addrmap *> result;
523 result.push_back (index->m_addrmap);
532 std::vector<cooked_index_shard::range> result_range;
533 result_range.reserve (
m_vector.size ());
535 result_range.push_back (entry->find (
name, completing));
536 return range (std::move (result_range));
568 auto_obstack temp_storage;
581 gdb_printf (
" [%zu] ((cooked_index_entry *) %p)\n", i++, entry);
583 gdb_printf (
" canonical: %s\n", entry->canonical);
584 gdb_printf (
" qualified: %s\n", entry->full_name (&temp_storage,
false));
589 if (entry->parent_entry !=
nullptr)
590 gdb_printf (
" parent: ((cooked_index_entry *) %p) [%s]\n",
591 entry->parent_entry, entry->parent_entry->name);
593 gdb_printf (
" parent: ((cooked_index_entry *) 0)\n");
599 if (main_entry !=
nullptr)
600 gdb_printf (
" main: ((cooked_index_entry *) %p) [%s]\n", main_entry,
603 gdb_printf (
" main: ((cooked_index_entry *) 0)\n");
609 std::vector<const addrmap *> addrmaps = this->
get_addrmaps ();
610 for (i = 0; i < addrmaps.size (); ++i)
621 const char *start_addr_str =
paddress (arch, start_addr);
627 gdb_printf (
" [%s] ((dwarf2_per_cu_data *) %p)\n",
628 start_addr_str, per_cu);
631 gdb_printf (
" [%s] ((dwarf2_per_cu_data *) 0)\n",
659 item->wait_completely ();
675 selftests::register_test (
"cooked_index_entry::compare", test_compare);
680Wait until all pending writes to the index cache have completed.\n\
681Usage: maintenance wait-for-index-cache"),
std::string ada_decode(const char *encoded, bool wrap, bool operators)
void * xcalloc(size_t number, size_t size)
gdb::unique_xmalloc_ptr< char > c_canonicalize_name(const char *name)
gdb::future< void > m_future
iterator_range< std::vector< cooked_index_entry * >::const_iterator > range
std::vector< gdb::unique_xmalloc_ptr< char > > m_names
const cooked_index_entry * add(sect_offset die_offset, enum dwarf_tag tag, cooked_index_flag flags, const char *name, const cooked_index_entry *parent_entry, dwarf2_per_cu_data *per_cu)
gdb::unique_xmalloc_ptr< char > handle_gnat_encoded_entry(cooked_index_entry *entry, htab_t gnat_entries)
void wait(bool allow_quit=true) const
cooked_index_entry * m_main
cooked_index_entry * create(sect_offset die_offset, enum dwarf_tag tag, cooked_index_flag flags, const char *name, const cooked_index_entry *parent_entry, dwarf2_per_cu_data *per_cu)
range find(const std::string &name, bool completing) const
std::vector< cooked_index_entry * > m_entries
gdb::future< void > m_write_future
void wait_completely() override
void maybe_write_index(dwarf2_per_bfd *per_bfd, const index_cache_store_context &)
dwarf2_per_cu_data * lookup(CORE_ADDR addr)
void start_writing_index(dwarf2_per_bfd *per_bfd)
const cooked_index_entry * get_main() const
cooked_index(vec_type &&vec)
range_chain< cooked_index_shard::range > range
void dump(gdbarch *arch) const
std::vector< const addrmap * > get_addrmaps() const
range find(const std::string &name, bool completing) const
range all_entries() const
std::vector< std::unique_ptr< cooked_index_shard > > vec_type
void store(dwarf2_per_bfd *per_bfd, const index_cache_store_context &)
struct cmd_list_element * maintenancelist
struct cmd_list_element * add_cmd(const char *name, enum command_class theclass, const char *doc, struct cmd_list_element **list)
static std::unordered_set< cooked_index * > active_vectors
bool language_requires_canonicalization(enum language lang)
void _initialize_cooked_index()
static void wait_for_index_cache(int)
std::string to_string(cooked_index_flag flags)
static void maintenance_wait_for_index_cache(const char *args, int from_tty)
bool language_requires_canonicalization(enum language lang)
std::string to_string(cooked_index_flag flags)
gdb::unique_xmalloc_ptr< char > cp_canonicalize_string(const char *string)
mach_port_t kern_return_t mach_port_t mach_msg_type_name_t msgportsPoly mach_port_t kern_return_t pid_t pid mach_port_t kern_return_t mach_port_t task mach_port_t kern_return_t int flags
index_cache global_index_cache
uint32_t dwarf5_djb_hash(const char *str_)
observable< int > gdb_exiting
std::vector< gdb::string_view > split_name(const char *name, split_style style)
const char * dwarf_tag_name(unsigned tag)
int foreach(addrmap_foreach_const_fn fn) const
dwarf2_per_cu_data * per_cu
void write_scope(struct obstack *storage, const char *sep, bool for_name) const
static int compare(const char *stra, const char *strb, comparison_mode mode)
const char * full_name(struct obstack *storage, bool for_main=false) const
const cooked_index_entry * parent_entry
enum language lang(bool strict_p=true) const
static char * sect_offset_str(sect_offset offset)
const char * paddress(struct gdbarch *gdbarch, CORE_ADDR addr)
void gdb_printf(struct ui_file *stream, const char *format,...)