LLDB  mainline
Symtab.cpp
Go to the documentation of this file.
1 //===-- Symtab.cpp --------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include <map>
10 #include <set>
11 
12 #include "lldb/Core/Module.h"
14 #include "lldb/Core/Section.h"
15 #include "lldb/Symbol/ObjectFile.h"
16 #include "lldb/Symbol/Symbol.h"
18 #include "lldb/Symbol/Symtab.h"
19 #include "lldb/Target/Language.h"
21 #include "lldb/Utility/Stream.h"
22 #include "lldb/Utility/Timer.h"
23 
24 #include "llvm/ADT/StringRef.h"
25 
26 using namespace lldb;
27 using namespace lldb_private;
28 
29 Symtab::Symtab(ObjectFile *objfile)
30  : m_objfile(objfile), m_symbols(), m_file_addr_to_index(*this),
31  m_name_to_symbol_indices(), m_mutex(),
32  m_file_addr_to_index_computed(false), m_name_indexes_computed(false) {
33  m_name_to_symbol_indices.emplace(std::make_pair(
34  lldb::eFunctionNameTypeNone, UniqueCStringMap<uint32_t>()));
35  m_name_to_symbol_indices.emplace(std::make_pair(
36  lldb::eFunctionNameTypeBase, UniqueCStringMap<uint32_t>()));
37  m_name_to_symbol_indices.emplace(std::make_pair(
38  lldb::eFunctionNameTypeMethod, UniqueCStringMap<uint32_t>()));
39  m_name_to_symbol_indices.emplace(std::make_pair(
40  lldb::eFunctionNameTypeSelector, UniqueCStringMap<uint32_t>()));
41 }
42 
43 Symtab::~Symtab() = default;
44 
45 void Symtab::Reserve(size_t count) {
46  // Clients should grab the mutex from this symbol table and lock it manually
47  // when calling this function to avoid performance issues.
48  m_symbols.reserve(count);
49 }
50 
51 Symbol *Symtab::Resize(size_t count) {
52  // Clients should grab the mutex from this symbol table and lock it manually
53  // when calling this function to avoid performance issues.
54  m_symbols.resize(count);
55  return m_symbols.empty() ? nullptr : &m_symbols[0];
56 }
57 
59  // Clients should grab the mutex from this symbol table and lock it manually
60  // when calling this function to avoid performance issues.
61  uint32_t symbol_idx = m_symbols.size();
62  auto &name_to_index = GetNameToSymbolIndexMap(lldb::eFunctionNameTypeNone);
63  name_to_index.Clear();
65  m_symbols.push_back(symbol);
68  return symbol_idx;
69 }
70 
71 size_t Symtab::GetNumSymbols() const {
72  std::lock_guard<std::recursive_mutex> guard(m_mutex);
73  return m_symbols.size();
74 }
75 
77  auto &name_to_index = GetNameToSymbolIndexMap(lldb::eFunctionNameTypeNone);
78  name_to_index.Clear();
80 }
81 
82 void Symtab::Dump(Stream *s, Target *target, SortOrder sort_order,
83  Mangled::NamePreference name_preference) {
84  std::lock_guard<std::recursive_mutex> guard(m_mutex);
85 
86  // s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
87  s->Indent();
88  const FileSpec &file_spec = m_objfile->GetFileSpec();
89  const char *object_name = nullptr;
90  if (m_objfile->GetModule())
91  object_name = m_objfile->GetModule()->GetObjectName().GetCString();
92 
93  if (file_spec)
94  s->Printf("Symtab, file = %s%s%s%s, num_symbols = %" PRIu64,
95  file_spec.GetPath().c_str(), object_name ? "(" : "",
96  object_name ? object_name : "", object_name ? ")" : "",
97  (uint64_t)m_symbols.size());
98  else
99  s->Printf("Symtab, num_symbols = %" PRIu64 "", (uint64_t)m_symbols.size());
100 
101  if (!m_symbols.empty()) {
102  switch (sort_order) {
103  case eSortOrderNone: {
104  s->PutCString(":\n");
105  DumpSymbolHeader(s);
106  const_iterator begin = m_symbols.begin();
107  const_iterator end = m_symbols.end();
108  for (const_iterator pos = m_symbols.begin(); pos != end; ++pos) {
109  s->Indent();
110  pos->Dump(s, target, std::distance(begin, pos), name_preference);
111  }
112  } break;
113 
114  case eSortOrderByName: {
115  // Although we maintain a lookup by exact name map, the table isn't
116  // sorted by name. So we must make the ordered symbol list up ourselves.
117  s->PutCString(" (sorted by name):\n");
118  DumpSymbolHeader(s);
119 
120  std::multimap<llvm::StringRef, const Symbol *> name_map;
121  for (const_iterator pos = m_symbols.begin(), end = m_symbols.end();
122  pos != end; ++pos) {
123  const char *name = pos->GetName().AsCString();
124  if (name && name[0])
125  name_map.insert(std::make_pair(name, &(*pos)));
126  }
127 
128  for (const auto &name_to_symbol : name_map) {
129  const Symbol *symbol = name_to_symbol.second;
130  s->Indent();
131  symbol->Dump(s, target, symbol - &m_symbols[0], name_preference);
132  }
133  } break;
134 
135  case eSortOrderByAddress:
136  s->PutCString(" (sorted by address):\n");
137  DumpSymbolHeader(s);
140  const size_t num_entries = m_file_addr_to_index.GetSize();
141  for (size_t i = 0; i < num_entries; ++i) {
142  s->Indent();
143  const uint32_t symbol_idx = m_file_addr_to_index.GetEntryRef(i).data;
144  m_symbols[symbol_idx].Dump(s, target, symbol_idx, name_preference);
145  }
146  break;
147  }
148  } else {
149  s->PutCString("\n");
150  }
151 }
152 
153 void Symtab::Dump(Stream *s, Target *target, std::vector<uint32_t> &indexes,
154  Mangled::NamePreference name_preference) const {
155  std::lock_guard<std::recursive_mutex> guard(m_mutex);
156 
157  const size_t num_symbols = GetNumSymbols();
158  // s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
159  s->Indent();
160  s->Printf("Symtab %" PRIu64 " symbol indexes (%" PRIu64 " symbols total):\n",
161  (uint64_t)indexes.size(), (uint64_t)m_symbols.size());
162  s->IndentMore();
163 
164  if (!indexes.empty()) {
165  std::vector<uint32_t>::const_iterator pos;
166  std::vector<uint32_t>::const_iterator end = indexes.end();
167  DumpSymbolHeader(s);
168  for (pos = indexes.begin(); pos != end; ++pos) {
169  size_t idx = *pos;
170  if (idx < num_symbols) {
171  s->Indent();
172  m_symbols[idx].Dump(s, target, idx, name_preference);
173  }
174  }
175  }
176  s->IndentLess();
177 }
178 
180  s->Indent(" Debug symbol\n");
181  s->Indent(" |Synthetic symbol\n");
182  s->Indent(" ||Externally Visible\n");
183  s->Indent(" |||\n");
184  s->Indent("Index UserID DSX Type File Address/Value Load "
185  "Address Size Flags Name\n");
186  s->Indent("------- ------ --- --------------- ------------------ "
187  "------------------ ------------------ ---------- "
188  "----------------------------------\n");
189 }
190 
191 static int CompareSymbolID(const void *key, const void *p) {
192  const user_id_t match_uid = *(const user_id_t *)key;
193  const user_id_t symbol_uid = ((const Symbol *)p)->GetID();
194  if (match_uid < symbol_uid)
195  return -1;
196  if (match_uid > symbol_uid)
197  return 1;
198  return 0;
199 }
200 
202  std::lock_guard<std::recursive_mutex> guard(m_mutex);
203 
204  Symbol *symbol =
205  (Symbol *)::bsearch(&symbol_uid, &m_symbols[0], m_symbols.size(),
206  sizeof(m_symbols[0]), CompareSymbolID);
207  return symbol;
208 }
209 
211  // Clients should grab the mutex from this symbol table and lock it manually
212  // when calling this function to avoid performance issues.
213  if (idx < m_symbols.size())
214  return &m_symbols[idx];
215  return nullptr;
216 }
217 
218 const Symbol *Symtab::SymbolAtIndex(size_t idx) const {
219  // Clients should grab the mutex from this symbol table and lock it manually
220  // when calling this function to avoid performance issues.
221  if (idx < m_symbols.size())
222  return &m_symbols[idx];
223  return nullptr;
224 }
225 
226 static bool lldb_skip_name(llvm::StringRef mangled,
227  Mangled::ManglingScheme scheme) {
228  switch (scheme) {
229  case Mangled::eManglingSchemeItanium: {
230  if (mangled.size() < 3 || !mangled.startswith("_Z"))
231  return true;
232 
233  // Avoid the following types of symbols in the index.
234  switch (mangled[2]) {
235  case 'G': // guard variables
236  case 'T': // virtual tables, VTT structures, typeinfo structures + names
237  case 'Z': // named local entities (if we eventually handle
238  // eSymbolTypeData, we will want this back)
239  return true;
240 
241  default:
242  break;
243  }
244 
245  // Include this name in the index.
246  return false;
247  }
248 
249  // No filters for this scheme yet. Include all names in indexing.
250  case Mangled::eManglingSchemeMSVC:
251  return false;
252 
253  // No filters for this scheme yet. Include all names in indexing.
254  case Mangled::eManglingSchemeRustV0:
255  return false;
256 
257  // Don't try and demangle things we can't categorize.
258  case Mangled::eManglingSchemeNone:
259  return true;
260  }
261  llvm_unreachable("unknown scheme!");
262 }
263 
265  // Protected function, no need to lock mutex...
269 
270  // Collect all loaded language plugins.
271  std::vector<Language *> languages;
272  Language::ForEach([&languages](Language *l) {
273  languages.push_back(l);
274  return true;
275  });
276 
277  auto &name_to_index = GetNameToSymbolIndexMap(lldb::eFunctionNameTypeNone);
278  auto &basename_to_index =
279  GetNameToSymbolIndexMap(lldb::eFunctionNameTypeBase);
280  auto &method_to_index =
281  GetNameToSymbolIndexMap(lldb::eFunctionNameTypeMethod);
282  auto &selector_to_index =
283  GetNameToSymbolIndexMap(lldb::eFunctionNameTypeSelector);
284  // Create the name index vector to be able to quickly search by name
285  const size_t num_symbols = m_symbols.size();
286  name_to_index.Reserve(num_symbols);
287 
288  // The "const char *" in "class_contexts" and backlog::value_type::second
289  // must come from a ConstString::GetCString()
290  std::set<const char *> class_contexts;
291  std::vector<std::pair<NameToIndexMap::Entry, const char *>> backlog;
292  backlog.reserve(num_symbols / 2);
293 
294  // Instantiation of the demangler is expensive, so better use a single one
295  // for all entries during batch processing.
297  for (uint32_t value = 0; value < num_symbols; ++value) {
298  Symbol *symbol = &m_symbols[value];
299 
300  // Don't let trampolines get into the lookup by name map If we ever need
301  // the trampoline symbols to be searchable by name we can remove this and
302  // then possibly add a new bool to any of the Symtab functions that
303  // lookup symbols by name to indicate if they want trampolines. We also
304  // don't want any synthetic symbols with auto generated names in the
305  // name lookups.
306  if (symbol->IsTrampoline() || symbol->IsSyntheticWithAutoGeneratedName())
307  continue;
308 
309  // If the symbol's name string matched a Mangled::ManglingScheme, it is
310  // stored in the mangled field.
311  Mangled &mangled = symbol->GetMangled();
312  if (ConstString name = mangled.GetMangledName()) {
313  name_to_index.Append(name, value);
314 
315  if (symbol->ContainsLinkerAnnotations()) {
316  // If the symbol has linker annotations, also add the version without
317  // the annotations.
318  ConstString stripped = ConstString(
319  m_objfile->StripLinkerSymbolAnnotations(name.GetStringRef()));
320  name_to_index.Append(stripped, value);
321  }
322 
323  const SymbolType type = symbol->GetType();
324  if (type == eSymbolTypeCode || type == eSymbolTypeResolver) {
325  if (mangled.DemangleWithRichManglingInfo(rmc, lldb_skip_name))
326  RegisterMangledNameEntry(value, class_contexts, backlog, rmc);
327  }
328  }
329 
330  // Symbol name strings that didn't match a Mangled::ManglingScheme, are
331  // stored in the demangled field.
332  if (ConstString name = mangled.GetDemangledName()) {
333  name_to_index.Append(name, value);
334 
335  if (symbol->ContainsLinkerAnnotations()) {
336  // If the symbol has linker annotations, also add the version without
337  // the annotations.
338  name = ConstString(
339  m_objfile->StripLinkerSymbolAnnotations(name.GetStringRef()));
340  name_to_index.Append(name, value);
341  }
342 
343  // If the demangled name turns out to be an ObjC name, and is a category
344  // name, add the version without categories to the index too.
345  for (Language *lang : languages) {
346  for (auto variant : lang->GetMethodNameVariants(name)) {
347  if (variant.GetType() & lldb::eFunctionNameTypeSelector)
348  selector_to_index.Append(variant.GetName(), value);
349  else if (variant.GetType() & lldb::eFunctionNameTypeFull)
350  name_to_index.Append(variant.GetName(), value);
351  else if (variant.GetType() & lldb::eFunctionNameTypeMethod)
352  method_to_index.Append(variant.GetName(), value);
353  else if (variant.GetType() & lldb::eFunctionNameTypeBase)
354  basename_to_index.Append(variant.GetName(), value);
355  }
356  }
357  }
358  }
359 
360  for (const auto &record : backlog) {
361  RegisterBacklogEntry(record.first, record.second, class_contexts);
362  }
363 
364  name_to_index.Sort();
365  name_to_index.SizeToFit();
366  selector_to_index.Sort();
367  selector_to_index.SizeToFit();
368  basename_to_index.Sort();
369  basename_to_index.SizeToFit();
370  method_to_index.Sort();
371  method_to_index.SizeToFit();
372  }
373 }
374 
376  uint32_t value, std::set<const char *> &class_contexts,
377  std::vector<std::pair<NameToIndexMap::Entry, const char *>> &backlog,
378  RichManglingContext &rmc) {
379  // Only register functions that have a base name.
380  rmc.ParseFunctionBaseName();
381  llvm::StringRef base_name = rmc.GetBufferRef();
382  if (base_name.empty())
383  return;
384 
385  // The base name will be our entry's name.
386  NameToIndexMap::Entry entry(ConstString(base_name), value);
387 
389  llvm::StringRef decl_context = rmc.GetBufferRef();
390 
391  // Register functions with no context.
392  if (decl_context.empty()) {
393  // This has to be a basename
394  auto &basename_to_index =
395  GetNameToSymbolIndexMap(lldb::eFunctionNameTypeBase);
396  basename_to_index.Append(entry);
397  // If there is no context (no namespaces or class scopes that come before
398  // the function name) then this also could be a fullname.
399  auto &name_to_index = GetNameToSymbolIndexMap(lldb::eFunctionNameTypeNone);
400  name_to_index.Append(entry);
401  return;
402  }
403 
404  // Make sure we have a pool-string pointer and see if we already know the
405  // context name.
406  const char *decl_context_ccstr = ConstString(decl_context).GetCString();
407  auto it = class_contexts.find(decl_context_ccstr);
408 
409  auto &method_to_index =
410  GetNameToSymbolIndexMap(lldb::eFunctionNameTypeMethod);
411  // Register constructors and destructors. They are methods and create
412  // declaration contexts.
413  if (rmc.IsCtorOrDtor()) {
414  method_to_index.Append(entry);
415  if (it == class_contexts.end())
416  class_contexts.insert(it, decl_context_ccstr);
417  return;
418  }
419 
420  // Register regular methods with a known declaration context.
421  if (it != class_contexts.end()) {
422  method_to_index.Append(entry);
423  return;
424  }
425 
426  // Regular methods in unknown declaration contexts are put to the backlog. We
427  // will revisit them once we processed all remaining symbols.
428  backlog.push_back(std::make_pair(entry, decl_context_ccstr));
429 }
430 
432  const NameToIndexMap::Entry &entry, const char *decl_context,
433  const std::set<const char *> &class_contexts) {
434  auto &method_to_index =
435  GetNameToSymbolIndexMap(lldb::eFunctionNameTypeMethod);
436  auto it = class_contexts.find(decl_context);
437  if (it != class_contexts.end()) {
438  method_to_index.Append(entry);
439  } else {
440  // If we got here, we have something that had a context (was inside
441  // a namespace or class) yet we don't know the entry
442  method_to_index.Append(entry);
443  auto &basename_to_index =
444  GetNameToSymbolIndexMap(lldb::eFunctionNameTypeBase);
445  basename_to_index.Append(entry);
446  }
447 }
448 
450  std::lock_guard<std::recursive_mutex> guard(m_mutex);
451  InitNameIndexes();
452 }
453 
455  bool add_demangled, bool add_mangled,
456  NameToIndexMap &name_to_index_map) const {
458  if (add_demangled || add_mangled) {
459  std::lock_guard<std::recursive_mutex> guard(m_mutex);
460 
461  // Create the name index vector to be able to quickly search by name
462  const size_t num_indexes = indexes.size();
463  for (size_t i = 0; i < num_indexes; ++i) {
464  uint32_t value = indexes[i];
465  assert(i < m_symbols.size());
466  const Symbol *symbol = &m_symbols[value];
467 
468  const Mangled &mangled = symbol->GetMangled();
469  if (add_demangled) {
470  if (ConstString name = mangled.GetDemangledName())
471  name_to_index_map.Append(name, value);
472  }
473 
474  if (add_mangled) {
475  if (ConstString name = mangled.GetMangledName())
476  name_to_index_map.Append(name, value);
477  }
478  }
479  }
480 }
481 
483  std::vector<uint32_t> &indexes,
484  uint32_t start_idx,
485  uint32_t end_index) const {
486  std::lock_guard<std::recursive_mutex> guard(m_mutex);
487 
488  uint32_t prev_size = indexes.size();
489 
490  const uint32_t count = std::min<uint32_t>(m_symbols.size(), end_index);
491 
492  for (uint32_t i = start_idx; i < count; ++i) {
493  if (symbol_type == eSymbolTypeAny || m_symbols[i].GetType() == symbol_type)
494  indexes.push_back(i);
495  }
496 
497  return indexes.size() - prev_size;
498 }
499 
501  SymbolType symbol_type, uint32_t flags_value,
502  std::vector<uint32_t> &indexes, uint32_t start_idx,
503  uint32_t end_index) const {
504  std::lock_guard<std::recursive_mutex> guard(m_mutex);
505 
506  uint32_t prev_size = indexes.size();
507 
508  const uint32_t count = std::min<uint32_t>(m_symbols.size(), end_index);
509 
510  for (uint32_t i = start_idx; i < count; ++i) {
511  if ((symbol_type == eSymbolTypeAny ||
512  m_symbols[i].GetType() == symbol_type) &&
513  m_symbols[i].GetFlags() == flags_value)
514  indexes.push_back(i);
515  }
516 
517  return indexes.size() - prev_size;
518 }
519 
521  Debug symbol_debug_type,
522  Visibility symbol_visibility,
523  std::vector<uint32_t> &indexes,
524  uint32_t start_idx,
525  uint32_t end_index) const {
526  std::lock_guard<std::recursive_mutex> guard(m_mutex);
527 
528  uint32_t prev_size = indexes.size();
529 
530  const uint32_t count = std::min<uint32_t>(m_symbols.size(), end_index);
531 
532  for (uint32_t i = start_idx; i < count; ++i) {
533  if (symbol_type == eSymbolTypeAny ||
534  m_symbols[i].GetType() == symbol_type) {
535  if (CheckSymbolAtIndex(i, symbol_debug_type, symbol_visibility))
536  indexes.push_back(i);
537  }
538  }
539 
540  return indexes.size() - prev_size;
541 }
542 
544  if (!m_symbols.empty()) {
545  const Symbol *first_symbol = &m_symbols[0];
546  if (symbol >= first_symbol && symbol < first_symbol + m_symbols.size())
547  return symbol - first_symbol;
548  }
549  return UINT32_MAX;
550 }
551 
553  const bool sort_by_load_addr;
554  const Symbol *symbols;
555 };
556 
557 namespace {
558 struct SymbolIndexComparator {
559  const std::vector<Symbol> &symbols;
560  std::vector<lldb::addr_t> &addr_cache;
561 
562  // Getting from the symbol to the Address to the File Address involves some
563  // work. Since there are potentially many symbols here, and we're using this
564  // for sorting so we're going to be computing the address many times, cache
565  // that in addr_cache. The array passed in has to be the same size as the
566  // symbols array passed into the member variable symbols, and should be
567  // initialized with LLDB_INVALID_ADDRESS.
568  // NOTE: You have to make addr_cache externally and pass it in because
569  // std::stable_sort
570  // makes copies of the comparator it is initially passed in, and you end up
571  // spending huge amounts of time copying this array...
572 
573  SymbolIndexComparator(const std::vector<Symbol> &s,
574  std::vector<lldb::addr_t> &a)
575  : symbols(s), addr_cache(a) {
576  assert(symbols.size() == addr_cache.size());
577  }
578  bool operator()(uint32_t index_a, uint32_t index_b) {
579  addr_t value_a = addr_cache[index_a];
580  if (value_a == LLDB_INVALID_ADDRESS) {
581  value_a = symbols[index_a].GetAddressRef().GetFileAddress();
582  addr_cache[index_a] = value_a;
583  }
584 
585  addr_t value_b = addr_cache[index_b];
586  if (value_b == LLDB_INVALID_ADDRESS) {
587  value_b = symbols[index_b].GetAddressRef().GetFileAddress();
588  addr_cache[index_b] = value_b;
589  }
590 
591  if (value_a == value_b) {
592  // The if the values are equal, use the original symbol user ID
593  lldb::user_id_t uid_a = symbols[index_a].GetID();
594  lldb::user_id_t uid_b = symbols[index_b].GetID();
595  if (uid_a < uid_b)
596  return true;
597  if (uid_a > uid_b)
598  return false;
599  return false;
600  } else if (value_a < value_b)
601  return true;
602 
603  return false;
604  }
605 };
606 }
607 
608 void Symtab::SortSymbolIndexesByValue(std::vector<uint32_t> &indexes,
609  bool remove_duplicates) const {
610  std::lock_guard<std::recursive_mutex> guard(m_mutex);
612  // No need to sort if we have zero or one items...
613  if (indexes.size() <= 1)
614  return;
615 
616  // Sort the indexes in place using std::stable_sort.
617  // NOTE: The use of std::stable_sort instead of llvm::sort here is strictly
618  // for performance, not correctness. The indexes vector tends to be "close"
619  // to sorted, which the stable sort handles better.
620 
621  std::vector<lldb::addr_t> addr_cache(m_symbols.size(), LLDB_INVALID_ADDRESS);
622 
623  SymbolIndexComparator comparator(m_symbols, addr_cache);
624  std::stable_sort(indexes.begin(), indexes.end(), comparator);
625 
626  // Remove any duplicates if requested
627  if (remove_duplicates) {
628  auto last = std::unique(indexes.begin(), indexes.end());
629  indexes.erase(last, indexes.end());
630  }
631 }
632 
634  std::vector<uint32_t> &indexes) {
635  auto &name_to_index = GetNameToSymbolIndexMap(lldb::eFunctionNameTypeNone);
636  const uint32_t count = name_to_index.GetValues(symbol_name, indexes);
637  if (count)
638  return count;
639  // Synthetic symbol names are not added to the name indexes, but they start
640  // with a prefix and end with a the symbol UserID. This allows users to find
641  // these symbols without having to add them to the name indexes. These
642  // queries will not happen very often since the names don't mean anything, so
643  // performance is not paramount in this case.
644  llvm::StringRef name = symbol_name.GetStringRef();
645  // String the synthetic prefix if the name starts with it.
646  if (!name.consume_front(Symbol::GetSyntheticSymbolPrefix()))
647  return 0; // Not a synthetic symbol name
648 
649  // Extract the user ID from the symbol name
650  unsigned long long uid = 0;
651  if (getAsUnsignedInteger(name, /*Radix=*/10, uid))
652  return 0; // Failed to extract the user ID as an integer
653  Symbol *symbol = FindSymbolByID(uid);
654  if (symbol == nullptr)
655  return 0;
656  const uint32_t symbol_idx = GetIndexForSymbol(symbol);
657  if (symbol_idx == UINT32_MAX)
658  return 0;
659  indexes.push_back(symbol_idx);
660  return 1;
661 }
662 
664  std::vector<uint32_t> &indexes) {
665  std::lock_guard<std::recursive_mutex> guard(m_mutex);
666 
668  if (symbol_name) {
670  InitNameIndexes();
671 
672  return GetNameIndexes(symbol_name, indexes);
673  }
674  return 0;
675 }
676 
678  Debug symbol_debug_type,
679  Visibility symbol_visibility,
680  std::vector<uint32_t> &indexes) {
681  std::lock_guard<std::recursive_mutex> guard(m_mutex);
682 
684  if (symbol_name) {
685  const size_t old_size = indexes.size();
687  InitNameIndexes();
688 
689  std::vector<uint32_t> all_name_indexes;
690  const size_t name_match_count =
691  GetNameIndexes(symbol_name, all_name_indexes);
692  for (size_t i = 0; i < name_match_count; ++i) {
693  if (CheckSymbolAtIndex(all_name_indexes[i], symbol_debug_type,
694  symbol_visibility))
695  indexes.push_back(all_name_indexes[i]);
696  }
697  return indexes.size() - old_size;
698  }
699  return 0;
700 }
701 
702 uint32_t
704  SymbolType symbol_type,
705  std::vector<uint32_t> &indexes) {
706  std::lock_guard<std::recursive_mutex> guard(m_mutex);
707 
708  if (AppendSymbolIndexesWithName(symbol_name, indexes) > 0) {
709  std::vector<uint32_t>::iterator pos = indexes.begin();
710  while (pos != indexes.end()) {
711  if (symbol_type == eSymbolTypeAny ||
712  m_symbols[*pos].GetType() == symbol_type)
713  ++pos;
714  else
715  pos = indexes.erase(pos);
716  }
717  }
718  return indexes.size();
719 }
720 
722  ConstString symbol_name, SymbolType symbol_type,
723  Debug symbol_debug_type, Visibility symbol_visibility,
724  std::vector<uint32_t> &indexes) {
725  std::lock_guard<std::recursive_mutex> guard(m_mutex);
726 
727  if (AppendSymbolIndexesWithName(symbol_name, symbol_debug_type,
728  symbol_visibility, indexes) > 0) {
729  std::vector<uint32_t>::iterator pos = indexes.begin();
730  while (pos != indexes.end()) {
731  if (symbol_type == eSymbolTypeAny ||
732  m_symbols[*pos].GetType() == symbol_type)
733  ++pos;
734  else
735  pos = indexes.erase(pos);
736  }
737  }
738  return indexes.size();
739 }
740 
742  const RegularExpression &regexp, SymbolType symbol_type,
743  std::vector<uint32_t> &indexes) {
744  std::lock_guard<std::recursive_mutex> guard(m_mutex);
745 
746  uint32_t prev_size = indexes.size();
747  uint32_t sym_end = m_symbols.size();
748 
749  for (uint32_t i = 0; i < sym_end; i++) {
750  if (symbol_type == eSymbolTypeAny ||
751  m_symbols[i].GetType() == symbol_type) {
752  const char *name = m_symbols[i].GetName().AsCString();
753  if (name) {
754  if (regexp.Execute(name))
755  indexes.push_back(i);
756  }
757  }
758  }
759  return indexes.size() - prev_size;
760 }
761 
763  const RegularExpression &regexp, SymbolType symbol_type,
764  Debug symbol_debug_type, Visibility symbol_visibility,
765  std::vector<uint32_t> &indexes) {
766  std::lock_guard<std::recursive_mutex> guard(m_mutex);
767 
768  uint32_t prev_size = indexes.size();
769  uint32_t sym_end = m_symbols.size();
770 
771  for (uint32_t i = 0; i < sym_end; i++) {
772  if (symbol_type == eSymbolTypeAny ||
773  m_symbols[i].GetType() == symbol_type) {
774  if (!CheckSymbolAtIndex(i, symbol_debug_type, symbol_visibility))
775  continue;
776 
777  const char *name = m_symbols[i].GetName().AsCString();
778  if (name) {
779  if (regexp.Execute(name))
780  indexes.push_back(i);
781  }
782  }
783  }
784  return indexes.size() - prev_size;
785 }
786 
788  Debug symbol_debug_type,
789  Visibility symbol_visibility,
790  uint32_t &start_idx) {
791  std::lock_guard<std::recursive_mutex> guard(m_mutex);
792 
793  const size_t count = m_symbols.size();
794  for (size_t idx = start_idx; idx < count; ++idx) {
795  if (symbol_type == eSymbolTypeAny ||
796  m_symbols[idx].GetType() == symbol_type) {
797  if (CheckSymbolAtIndex(idx, symbol_debug_type, symbol_visibility)) {
798  start_idx = idx;
799  return &m_symbols[idx];
800  }
801  }
802  }
803  return nullptr;
804 }
805 
806 void
808  SymbolType symbol_type,
809  std::vector<uint32_t> &symbol_indexes) {
810  std::lock_guard<std::recursive_mutex> guard(m_mutex);
811 
813  // Initialize all of the lookup by name indexes before converting NAME to a
814  // uniqued string NAME_STR below.
816  InitNameIndexes();
817 
818  if (name) {
819  // The string table did have a string that matched, but we need to check
820  // the symbols and match the symbol_type if any was given.
821  AppendSymbolIndexesWithNameAndType(name, symbol_type, symbol_indexes);
822  }
823 }
824 
826  ConstString name, SymbolType symbol_type, Debug symbol_debug_type,
827  Visibility symbol_visibility, std::vector<uint32_t> &symbol_indexes) {
828  std::lock_guard<std::recursive_mutex> guard(m_mutex);
829 
831  // Initialize all of the lookup by name indexes before converting NAME to a
832  // uniqued string NAME_STR below.
834  InitNameIndexes();
835 
836  if (name) {
837  // The string table did have a string that matched, but we need to check
838  // the symbols and match the symbol_type if any was given.
839  AppendSymbolIndexesWithNameAndType(name, symbol_type, symbol_debug_type,
840  symbol_visibility, symbol_indexes);
841  }
842 }
843 
845  const RegularExpression &regex, SymbolType symbol_type,
846  Debug symbol_debug_type, Visibility symbol_visibility,
847  std::vector<uint32_t> &symbol_indexes) {
848  std::lock_guard<std::recursive_mutex> guard(m_mutex);
849 
850  AppendSymbolIndexesMatchingRegExAndType(regex, symbol_type, symbol_debug_type,
851  symbol_visibility, symbol_indexes);
852 }
853 
855  SymbolType symbol_type,
856  Debug symbol_debug_type,
857  Visibility symbol_visibility) {
858  std::lock_guard<std::recursive_mutex> guard(m_mutex);
861  InitNameIndexes();
862 
863  if (name) {
864  std::vector<uint32_t> matching_indexes;
865  // The string table did have a string that matched, but we need to check
866  // the symbols and match the symbol_type if any was given.
867  if (AppendSymbolIndexesWithNameAndType(name, symbol_type, symbol_debug_type,
868  symbol_visibility,
869  matching_indexes)) {
870  std::vector<uint32_t>::const_iterator pos, end = matching_indexes.end();
871  for (pos = matching_indexes.begin(); pos != end; ++pos) {
872  Symbol *symbol = SymbolAtIndex(*pos);
873 
874  if (symbol->Compare(name, symbol_type))
875  return symbol;
876  }
877  }
878  }
879  return nullptr;
880 }
881 
882 typedef struct {
883  const Symtab *symtab;
889 
890 // Add all the section file start address & size to the RangeVector, recusively
891 // adding any children sections.
892 static void AddSectionsToRangeMap(SectionList *sectlist,
893  RangeVector<addr_t, addr_t> &section_ranges) {
894  const int num_sections = sectlist->GetNumSections(0);
895  for (int i = 0; i < num_sections; i++) {
896  SectionSP sect_sp = sectlist->GetSectionAtIndex(i);
897  if (sect_sp) {
898  SectionList &child_sectlist = sect_sp->GetChildren();
899 
900  // If this section has children, add the children to the RangeVector.
901  // Else add this section to the RangeVector.
902  if (child_sectlist.GetNumSections(0) > 0) {
903  AddSectionsToRangeMap(&child_sectlist, section_ranges);
904  } else {
905  size_t size = sect_sp->GetByteSize();
906  if (size > 0) {
907  addr_t base_addr = sect_sp->GetFileAddress();
909  entry.SetRangeBase(base_addr);
910  entry.SetByteSize(size);
911  section_ranges.Append(entry);
912  }
913  }
914  }
915  }
916 }
917 
919  // Protected function, no need to lock mutex...
920  if (!m_file_addr_to_index_computed && !m_symbols.empty()) {
922 
924  const_iterator begin = m_symbols.begin();
925  const_iterator end = m_symbols.end();
926  for (const_iterator pos = m_symbols.begin(); pos != end; ++pos) {
927  if (pos->ValueIsAddress()) {
928  entry.SetRangeBase(pos->GetAddressRef().GetFileAddress());
929  entry.SetByteSize(pos->GetByteSize());
930  entry.data = std::distance(begin, pos);
932  }
933  }
934  const size_t num_entries = m_file_addr_to_index.GetSize();
935  if (num_entries > 0) {
937 
938  // Create a RangeVector with the start & size of all the sections for
939  // this objfile. We'll need to check this for any FileRangeToIndexMap
940  // entries with an uninitialized size, which could potentially be a large
941  // number so reconstituting the weak pointer is busywork when it is
942  // invariant information.
943  SectionList *sectlist = m_objfile->GetSectionList();
944  RangeVector<addr_t, addr_t> section_ranges;
945  if (sectlist) {
946  AddSectionsToRangeMap(sectlist, section_ranges);
947  section_ranges.Sort();
948  }
949 
950  // Iterate through the FileRangeToIndexMap and fill in the size for any
951  // entries that didn't already have a size from the Symbol (e.g. if we
952  // have a plain linker symbol with an address only, instead of debug info
953  // where we get an address and a size and a type, etc.)
954  for (size_t i = 0; i < num_entries; i++) {
957  if (entry->GetByteSize() == 0) {
958  addr_t curr_base_addr = entry->GetRangeBase();
959  const RangeVector<addr_t, addr_t>::Entry *containing_section =
960  section_ranges.FindEntryThatContains(curr_base_addr);
961 
962  // Use the end of the section as the default max size of the symbol
963  addr_t sym_size = 0;
964  if (containing_section) {
965  sym_size =
966  containing_section->GetByteSize() -
967  (entry->GetRangeBase() - containing_section->GetRangeBase());
968  }
969 
970  for (size_t j = i; j < num_entries; j++) {
971  FileRangeToIndexMap::Entry *next_entry =
973  addr_t next_base_addr = next_entry->GetRangeBase();
974  if (next_base_addr > curr_base_addr) {
975  addr_t size_to_next_symbol = next_base_addr - curr_base_addr;
976 
977  // Take the difference between this symbol and the next one as
978  // its size, if it is less than the size of the section.
979  if (sym_size == 0 || size_to_next_symbol < sym_size) {
980  sym_size = size_to_next_symbol;
981  }
982  break;
983  }
984  }
985 
986  if (sym_size > 0) {
987  entry->SetByteSize(sym_size);
988  Symbol &symbol = m_symbols[entry->data];
989  symbol.SetByteSize(sym_size);
990  symbol.SetSizeIsSynthesized(true);
991  }
992  }
993  }
994 
995  // Sort again in case the range size changes the ordering
997  }
998  }
999 }
1000 
1002  std::lock_guard<std::recursive_mutex> guard(m_mutex);
1003  // Size computation happens inside InitAddressIndexes.
1005 }
1006 
1008  std::lock_guard<std::recursive_mutex> guard(m_mutex);
1011 
1012  const FileRangeToIndexMap::Entry *entry =
1014  if (entry) {
1015  Symbol *symbol = SymbolAtIndex(entry->data);
1016  if (symbol->GetFileAddress() == file_addr)
1017  return symbol;
1018  }
1019  return nullptr;
1020 }
1021 
1023  std::lock_guard<std::recursive_mutex> guard(m_mutex);
1024 
1027 
1028  const FileRangeToIndexMap::Entry *entry =
1030  if (entry) {
1031  Symbol *symbol = SymbolAtIndex(entry->data);
1032  if (symbol->ContainsFileAddress(file_addr))
1033  return symbol;
1034  }
1035  return nullptr;
1036 }
1037 
1039  addr_t file_addr, std::function<bool(Symbol *)> const &callback) {
1040  std::lock_guard<std::recursive_mutex> guard(m_mutex);
1041 
1044 
1045  std::vector<uint32_t> all_addr_indexes;
1046 
1047  // Get all symbols with file_addr
1048  const size_t addr_match_count =
1050  all_addr_indexes);
1051 
1052  for (size_t i = 0; i < addr_match_count; ++i) {
1053  Symbol *symbol = SymbolAtIndex(all_addr_indexes[i]);
1054  if (symbol->ContainsFileAddress(file_addr)) {
1055  if (!callback(symbol))
1056  break;
1057  }
1058  }
1059 }
1060 
1062  std::vector<uint32_t> &symbol_indexes, SymbolContextList &sc_list) {
1063  // No need to protect this call using m_mutex all other method calls are
1064  // already thread safe.
1065 
1066  const bool merge_symbol_into_function = true;
1067  size_t num_indices = symbol_indexes.size();
1068  if (num_indices > 0) {
1069  SymbolContext sc;
1070  sc.module_sp = m_objfile->GetModule();
1071  for (size_t i = 0; i < num_indices; i++) {
1072  sc.symbol = SymbolAtIndex(symbol_indexes[i]);
1073  if (sc.symbol)
1074  sc_list.AppendIfUnique(sc, merge_symbol_into_function);
1075  }
1076  }
1077 }
1078 
1080  SymbolContextList &sc_list) {
1081  std::vector<uint32_t> symbol_indexes;
1082 
1083  // eFunctionNameTypeAuto should be pre-resolved by a call to
1084  // Module::LookupInfo::LookupInfo()
1085  assert((name_type_mask & eFunctionNameTypeAuto) == 0);
1086 
1087  if (name_type_mask & (eFunctionNameTypeBase | eFunctionNameTypeFull)) {
1088  std::vector<uint32_t> temp_symbol_indexes;
1089  FindAllSymbolsWithNameAndType(name, eSymbolTypeAny, temp_symbol_indexes);
1090 
1091  unsigned temp_symbol_indexes_size = temp_symbol_indexes.size();
1092  if (temp_symbol_indexes_size > 0) {
1093  std::lock_guard<std::recursive_mutex> guard(m_mutex);
1094  for (unsigned i = 0; i < temp_symbol_indexes_size; i++) {
1095  SymbolContext sym_ctx;
1096  sym_ctx.symbol = SymbolAtIndex(temp_symbol_indexes[i]);
1097  if (sym_ctx.symbol) {
1098  switch (sym_ctx.symbol->GetType()) {
1099  case eSymbolTypeCode:
1100  case eSymbolTypeResolver:
1101  case eSymbolTypeReExported:
1102  symbol_indexes.push_back(temp_symbol_indexes[i]);
1103  break;
1104  default:
1105  break;
1106  }
1107  }
1108  }
1109  }
1110  }
1111 
1113  InitNameIndexes();
1114 
1115  for (lldb::FunctionNameType type :
1116  {lldb::eFunctionNameTypeBase, lldb::eFunctionNameTypeMethod,
1117  lldb::eFunctionNameTypeSelector}) {
1118  if (name_type_mask & type) {
1119  auto map = GetNameToSymbolIndexMap(type);
1120 
1121  const UniqueCStringMap<uint32_t>::Entry *match;
1122  for (match = map.FindFirstValueForName(name); match != nullptr;
1123  match = map.FindNextValueForName(match)) {
1124  symbol_indexes.push_back(match->value);
1125  }
1126  }
1127  }
1128 
1129  if (!symbol_indexes.empty()) {
1130  llvm::sort(symbol_indexes.begin(), symbol_indexes.end());
1131  symbol_indexes.erase(
1132  std::unique(symbol_indexes.begin(), symbol_indexes.end()),
1133  symbol_indexes.end());
1134  SymbolIndicesToSymbolContextList(symbol_indexes, sc_list);
1135  }
1136 }
1137 
1138 const Symbol *Symtab::GetParent(Symbol *child_symbol) const {
1139  uint32_t child_idx = GetIndexForSymbol(child_symbol);
1140  if (child_idx != UINT32_MAX && child_idx > 0) {
1141  for (uint32_t idx = child_idx - 1; idx != UINT32_MAX; --idx) {
1142  const Symbol *symbol = SymbolAtIndex(idx);
1143  const uint32_t sibling_idx = symbol->GetSiblingIndex();
1144  if (sibling_idx != UINT32_MAX && sibling_idx > child_idx)
1145  return symbol;
1146  }
1147  }
1148  return nullptr;
1149 }
RegularExpression.h
SymbolSearchInfo::symtab
const Symtab * symtab
Definition: Symtab.cpp:883
lldb_private::Stream::IndentLess
void IndentLess(unsigned amount=2)
Decrement the current indentation level.
Definition: Stream.cpp:171
lldb_private::eSortOrderByAddress
@ eSortOrderByAddress
Definition: lldb-private-enumerations.h:110
lldb_private::Range::GetRangeBase
BaseType GetRangeBase() const
Definition: RangeMap.h:46
lldb_private::Symtab::m_file_addr_to_index
FileRangeToIndexMap m_file_addr_to_index
Definition: Symtab.h:176
lldb_private::RegularExpression
Definition: RegularExpression.h:18
lldb_private::ObjectFile::GetFileSpec
virtual FileSpec & GetFileSpec()
Get accessor to the object file specification.
Definition: ObjectFile.h:290
lldb_private::Symtab::m_objfile
ObjectFile * m_objfile
Definition: Symtab.h:174
lldb::eSymbolTypeCode
@ eSymbolTypeCode
Definition: lldb-enumerations.h:616
SymbolSearchInfo::file_addr
const addr_t file_addr
Definition: Symtab.cpp:884
lldb_private::Symtab::AppendSymbolIndexesWithTypeAndFlagsValue
uint32_t AppendSymbolIndexesWithTypeAndFlagsValue(lldb::SymbolType symbol_type, uint32_t flags_value, std::vector< uint32_t > &indexes, uint32_t start_idx=0, uint32_t end_index=UINT32_MAX) const
Definition: Symtab.cpp:500
lldb_private::Symtab::AppendSymbolNamesToMap
void AppendSymbolNamesToMap(const IndexCollection &indexes, bool add_demangled, bool add_mangled, NameToIndexMap &name_to_index_map) const
Definition: Symtab.cpp:454
lldb_private::RangeDataVector::GetEntryRef
Entry & GetEntryRef(size_t i)
Definition: RangeMap.h:489
lldb_private::Symbol::GetSyntheticSymbolPrefix
static llvm::StringRef GetSyntheticSymbolPrefix()
Definition: Symbol.h:234
lldb_private::Symtab::GetNameToSymbolIndexMap
UniqueCStringMap< uint32_t > & GetNameToSymbolIndexMap(lldb::FunctionNameType type)
Definition: Symtab.h:187
lldb_private::Symbol::SetSizeIsSynthesized
void SetSizeIsSynthesized(bool b)
Definition: Symbol.h:164
lldb_private::RangeVector::Sort
void Sort()
Definition: RangeMap.h:174
lldb_private::Symbol
Definition: Symbol.h:20
lldb_private::Symtab::GetParent
const Symbol * GetParent(Symbol *symbol) const
Get the parent symbol for the given symbol.
Definition: Symtab.cpp:1138
lldb_private::Symtab::PreloadSymbols
void PreloadSymbols()
Definition: Symtab.cpp:449
lldb_private::Symtab::m_symbols
collection m_symbols
Definition: Symtab.h:175
lldb_private::Symtab::Debug
Debug
Definition: Symtab.h:27
SymbolSearchInfo
Definition: Symtab.cpp:882
Module.h
lldb_private::RichManglingContext::IsCtorOrDtor
bool IsCtorOrDtor() const
If this symbol describes a constructor or destructor.
Definition: RichManglingContext.cpp:69
lldb_private::RangeDataVector::Sort
void Sort()
Definition: RangeMap.h:411
lldb_private::Symtab::~Symtab
~Symtab()
lldb_private::SymbolContextList
Definition: SymbolContext.h:379
AddSectionsToRangeMap
static void AddSectionsToRangeMap(SectionList *sectlist, RangeVector< addr_t, addr_t > &section_ranges)
Definition: Symtab.cpp:892
lldb_private::SectionList
Definition: Section.h:34
lldb_private::RangeDataVector::Clear
void Clear()
Definition: RangeMap.h:473
lldb_private::Stream
Definition: Stream.h:28
lldb_private::RangeData
Definition: RangeMap.h:373
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
Language.h
lldb_private::Symtab::SymbolAtIndex
Symbol * SymbolAtIndex(size_t idx)
Definition: Symtab.cpp:210
lldb_private::Symbol::IsSyntheticWithAutoGeneratedName
bool IsSyntheticWithAutoGeneratedName() const
Definition: Symbol.cpp:571
SymbolSortInfo::sort_by_load_addr
const bool sort_by_load_addr
Definition: Symtab.cpp:553
lldb_private::SectionList::GetNumSections
size_t GetNumSections(uint32_t depth) const
Definition: Section.cpp:465
lldb_private::SymbolContext
Definition: SymbolContext.h:33
lldb_private::Target
Definition: Target.h:450
Section.h
lldb_private::eSortOrderNone
@ eSortOrderNone
Definition: lldb-private-enumerations.h:110
lldb_private::RangeVector::Append
void Append(const Entry &entry)
Definition: RangeMap.h:136
lldb_private::Symtab::FindFunctionSymbols
void FindFunctionSymbols(ConstString name, uint32_t name_type_mask, SymbolContextList &sc_list)
Definition: Symtab.cpp:1079
lldb_private::Symtab::FindFirstSymbolWithNameAndType
Symbol * FindFirstSymbolWithNameAndType(ConstString name, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility)
Definition: Symtab.cpp:854
lldb_private::Symbol::ContainsFileAddress
bool ContainsFileAddress(lldb::addr_t file_addr) const
Definition: Symbol.cpp:567
lldb_private::RangeDataVector::FindEntryThatContains
Entry * FindEntryThatContains(B addr)
Definition: RangeMap.h:514
lldb_private::Symbol::Dump
void Dump(Stream *s, Target *target, uint32_t index, Mangled::NamePreference name_preference=Mangled::ePreferDemangled) const
Definition: Symbol.cpp:212
lldb_private::FileSpec
Definition: FileSpec.h:56
lldb::eSymbolTypeAny
@ eSymbolTypeAny
Definition: lldb-enumerations.h:613
lldb_private::SymbolContext::symbol
Symbol * symbol
The Symbol for a given query.
Definition: SymbolContext.h:323
lldb_private::ObjectFile::GetSectionList
virtual SectionList * GetSectionList(bool update_module_section_list=true)
Gets the section list for the currently selected architecture (and object for archives).
Definition: ObjectFile.cpp:583
lldb_private::Symtab::m_mutex
std::recursive_mutex m_mutex
Definition: Symtab.h:182
lldb_private::Symbol::SetByteSize
void SetByteSize(lldb::addr_t size)
Definition: Symbol.h:186
lldb_private::RangeDataVector::Append
void Append(const Entry &entry)
Definition: RangeMap.h:409
lldb_private::RangeDataVector::FindEntryIndexesThatContain
uint32_t FindEntryIndexesThatContain(B addr, std::vector< uint32_t > &indexes)
Definition: RangeMap.h:504
lldb_private::Stream::Indent
size_t Indent(llvm::StringRef s="")
Indent the current line in the stream.
Definition: Stream.cpp:130
lldb_private::Symtab::m_name_to_symbol_indices
std::map< lldb::FunctionNameType, UniqueCStringMap< uint32_t > > m_name_to_symbol_indices
Maps function names to symbol indices (grouped by FunctionNameTypes)
Definition: Symtab.h:180
lldb_private::Symtab::Dump
void Dump(Stream *s, Target *target, SortOrder sort_type, Mangled::NamePreference name_preference=Mangled::ePreferDemangled)
Definition: Symtab.cpp:82
lldb_private::ConstString::GetStringRef
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
Definition: ConstString.h:202
lldb_private::Symtab::DumpSymbolHeader
static void DumpSymbolHeader(Stream *s)
Definition: Symtab.cpp:179
lldb_private::UniqueCStringMap::FindFirstValueForName
const Entry * FindFirstValueForName(ConstString unique_cstr) const
Definition: UniqueCStringMap.h:98
lldb_private::Symtab::GetNameIndexes
uint32_t GetNameIndexes(ConstString symbol_name, std::vector< uint32_t > &indexes)
A helper function that looks up full function names.
Definition: Symtab.cpp:633
lldb_private::ObjectFile::StripLinkerSymbolAnnotations
virtual llvm::StringRef StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const
Definition: ObjectFile.h:658
lldb_private::RichManglingContext::ParseFunctionBaseName
void ParseFunctionBaseName()
Get the base name of a function.
Definition: RichManglingContext.cpp:115
lldb_private::RichManglingContext::ParseFunctionDeclContextName
void ParseFunctionDeclContextName()
Get the context name for a function.
Definition: RichManglingContext.cpp:133
lldb_private::Symtab::m_file_addr_to_index_computed
bool m_file_addr_to_index_computed
Definition: Symtab.h:183
lldb_private::ConstString
Definition: ConstString.h:40
lldb_private::Symtab::FindSymbolContainingFileAddress
Symbol * FindSymbolContainingFileAddress(lldb::addr_t file_addr)
Definition: Symtab.cpp:1022
Timer.h
lldb_private::Symtab::const_iterator
collection::const_iterator const_iterator
Definition: Symtab.h:146
lldb_private::SectionList::GetSectionAtIndex
lldb::SectionSP GetSectionAtIndex(size_t idx) const
Definition: Section.cpp:476
lldb_private::Range
Definition: Process.h:61
LLDB_SCOPED_TIMER
#define LLDB_SCOPED_TIMER()
Definition: Timer.h:83
lldb_private::Symbol::Compare
bool Compare(ConstString name, lldb::SymbolType type) const
Definition: Symbol.cpp:332
lldb_private::SymbolContextList::AppendIfUnique
bool AppendIfUnique(const SymbolContext &sc, bool merge_symbol_into_function)
Definition: SymbolContext.cpp:1209
lldb_private::Symtab::GetIndexForSymbol
uint32_t GetIndexForSymbol(const Symbol *symbol) const
Definition: Symtab.cpp:543
lldb_private::Symtab::InitAddressIndexes
void InitAddressIndexes()
Definition: Symtab.cpp:918
lldb_private::Symtab::FindSymbolWithType
Symbol * FindSymbolWithType(lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, uint32_t &start_idx)
Definition: Symtab.cpp:787
lldb_private::Symbol::ContainsLinkerAnnotations
bool ContainsLinkerAnnotations() const
Definition: Symbol.h:205
lldb_private::Symtab::FindSymbolAtFileAddress
Symbol * FindSymbolAtFileAddress(lldb::addr_t file_addr)
Definition: Symtab.cpp:1007
lldb_private::Symbol::GetMangled
Mangled & GetMangled()
Definition: Symbol.h:121
lldb::SymbolType
SymbolType
Symbol types.
Definition: lldb-enumerations.h:612
lldb_private::RangeVector
Definition: RangeMap.h:125
lldb_private::UniqueCStringMap< uint32_t >
lldb_private::Symtab::RegisterBacklogEntry
void RegisterBacklogEntry(const NameToIndexMap::Entry &entry, const char *decl_context, const std::set< const char * > &class_contexts)
Definition: Symtab.cpp:431
ObjectFile.h
lldb_private::RangeDataVector::FindEntryStartsAt
const Entry * FindEntryStartsAt(B addr) const
Definition: RangeMap.h:543
Symbol.h
lldb_private::Symtab::GetNumSymbols
size_t GetNumSymbols() const
Definition: Symtab.cpp:71
lldb_private::Symtab::Reserve
void Reserve(size_t count)
Definition: Symtab.cpp:45
SymbolSearchInfo::match_index_ptr
const uint32_t * match_index_ptr
Definition: Symtab.cpp:886
lldb_private::Symtab::InitNameIndexes
void InitNameIndexes()
Definition: Symtab.cpp:264
lldb_private::Symtab::AddSymbol
uint32_t AddSymbol(const Symbol &symbol)
Definition: Symtab.cpp:58
lldb_private::Symtab::CheckSymbolAtIndex
bool CheckSymbolAtIndex(size_t idx, Debug symbol_debug_type, Visibility symbol_visibility) const
Definition: Symtab.h:192
lldb_private::RichManglingContext
Uniform wrapper for access to rich mangling information from different providers.
Definition: RichManglingContext.h:25
lldb_private::Symtab::CalculateSymbolSizes
void CalculateSymbolSizes()
Definition: Symtab.cpp:1001
lldb_private::UniqueCStringMap::Append
void Append(ConstString unique_cstr, const T &value)
Definition: UniqueCStringMap.h:42
lldb_private::Symtab::AppendSymbolIndexesWithType
uint32_t AppendSymbolIndexesWithType(lldb::SymbolType symbol_type, std::vector< uint32_t > &indexes, uint32_t start_idx=0, uint32_t end_index=UINT32_MAX) const
Definition: Symtab.cpp:482
lldb_private::Symtab
Definition: Symtab.h:22
lldb_private::Symtab::AppendSymbolIndexesWithName
uint32_t AppendSymbolIndexesWithName(ConstString symbol_name, std::vector< uint32_t > &matches)
Definition: Symtab.cpp:663
uint32_t
lldb_private::Stream::IndentMore
void IndentMore(unsigned amount=2)
Increment the current indentation level.
Definition: Stream.cpp:168
lldb_private::Language
Definition: Language.h:29
lldb_private::RangeDataVector::GetSize
size_t GetSize() const
Definition: RangeMap.h:477
SymbolSearchInfo::match_symbol
Symbol * match_symbol
Definition: Symtab.cpp:885
lldb_skip_name
static bool lldb_skip_name(llvm::StringRef mangled, Mangled::ManglingScheme scheme)
Definition: Symtab.cpp:226
lldb_private::Symtab::FindSymbolByID
Symbol * FindSymbolByID(lldb::user_id_t uid) const
Definition: Symtab.cpp:201
Symtab.h
lldb_private::Range::SetRangeBase
void SetRangeBase(BaseType b)
Definition: RangeMap.h:48
lldb_private::Range::GetByteSize
SizeType GetByteSize() const
Definition: RangeMap.h:71
UINT32_MAX
#define UINT32_MAX
Definition: lldb-defines.h:31
lldb_private::Symtab::Visibility
Visibility
Definition: Symtab.h:33
lldb_private::Range::SetByteSize
void SetByteSize(SizeType s)
Definition: RangeMap.h:73
lldb_private::RichManglingContext::GetBufferRef
llvm::StringRef GetBufferRef() const
Obtain a StringRef to the internal buffer that holds the result of the most recent ParseXy() operatio...
Definition: RichManglingContext.h:61
lldb_private::ModuleChild::GetModule
lldb::ModuleSP GetModule() const
Get const accessor for the module pointer.
Definition: ModuleChild.cpp:24
lldb_private::Symtab::AppendSymbolIndexesWithNameAndType
uint32_t AppendSymbolIndexesWithNameAndType(ConstString symbol_name, lldb::SymbolType symbol_type, std::vector< uint32_t > &matches)
Definition: Symtab.cpp:703
lldb_private::SymbolContext::module_sp
lldb::ModuleSP module_sp
The Module for a given query.
Definition: SymbolContext.h:318
lldb_private::Symbol::GetFileAddress
lldb::addr_t GetFileAddress() const
Definition: Symbol.cpp:486
lldb_private::Symtab::SectionFileAddressesChanged
void SectionFileAddressesChanged()
Definition: Symtab.cpp:76
LLDB_INVALID_ADDRESS
#define LLDB_INVALID_ADDRESS
Definition: lldb-defines.h:86
lldb_private::ConstString::GetCString
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:216
lldb_private::SortOrder
SortOrder
Definition: lldb-private-enumerations.h:110
lldb_private::Stream::Printf
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:107
SymbolSortInfo::symbols
const Symbol * symbols
Definition: Symtab.cpp:554
lldb::user_id_t
uint64_t user_id_t
Definition: lldb-types.h:84
lldb::eSymbolTypeReExported
@ eSymbolTypeReExported
Definition: lldb-enumerations.h:643
SymbolContext.h
lldb_private::Symtab::RegisterMangledNameEntry
void RegisterMangledNameEntry(uint32_t value, std::set< const char * > &class_contexts, std::vector< std::pair< NameToIndexMap::Entry, const char * >> &backlog, RichManglingContext &rmc)
Definition: Symtab.cpp:375
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::RangeDataVector::GetMutableEntryAtIndex
Entry * GetMutableEntryAtIndex(size_t i)
Definition: RangeMap.h:483
lldb_private::Symtab::AppendSymbolIndexesMatchingRegExAndType
uint32_t AppendSymbolIndexesMatchingRegExAndType(const RegularExpression &regex, lldb::SymbolType symbol_type, std::vector< uint32_t > &indexes)
Definition: Symtab.cpp:741
lldb_private::Symtab::FindAllSymbolsWithNameAndType
void FindAllSymbolsWithNameAndType(ConstString name, lldb::SymbolType symbol_type, std::vector< uint32_t > &symbol_indexes)
Definition: Symtab.cpp:807
lldb_private::Symbol::IsTrampoline
bool IsTrampoline() const
Definition: Symbol.cpp:173
lldb_private::RegularExpression::Execute
bool Execute(llvm::StringRef string, llvm::SmallVectorImpl< llvm::StringRef > *matches=nullptr) const
Execute a regular expression match using the compiled regular expression that is already in this obje...
Definition: RegularExpression.cpp:23
lldb_private::Symtab::SortSymbolIndexesByValue
void SortSymbolIndexesByValue(std::vector< uint32_t > &indexes, bool remove_duplicates) const
Definition: Symtab.cpp:608
Entry
FormatEntity::Entry Entry
Definition: FormatEntity.cpp:82
lldb_private::eSortOrderByName
@ eSortOrderByName
Definition: lldb-private-enumerations.h:110
lldb_private::RangeVector::FindEntryThatContains
const Entry * FindEntryThatContains(B addr) const
Definition: RangeMap.h:295
lldb_private::Symtab::m_name_indexes_computed
bool m_name_indexes_computed
Definition: Symtab.h:183
RichManglingContext.h
Stream.h
lldb_private::Symtab::Resize
Symbol * Resize(size_t count)
Definition: Symtab.cpp:51
lldb_private::Stream::PutCString
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition: Stream.cpp:63
lldb_private::UniqueCStringMap::FindNextValueForName
const Entry * FindNextValueForName(const Entry *entry_ptr) const
Definition: UniqueCStringMap.h:111
lldb::eSymbolTypeResolver
@ eSymbolTypeResolver
Definition: lldb-enumerations.h:617
lldb_private::Language::ForEach
static void ForEach(std::function< bool(Language *)> callback)
Definition: Language.cpp:100
lldb_private::Symtab::IndexCollection
std::vector< uint32_t > IndexCollection
Definition: Symtab.h:24
lldb_private::RangeData::data
DataType data
Definition: RangeMap.h:376
lldb_private::FileSpec::GetPath
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition: FileSpec.cpp:348
lldb_private::Symbol::GetType
lldb::SymbolType GetType() const
Definition: Symbol.h:143
lldb
Definition: SBAddress.h:15
lldb_private::Symtab::FindAllSymbolsMatchingRexExAndType
void FindAllSymbolsMatchingRexExAndType(const RegularExpression &regex, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector< uint32_t > &symbol_indexes)
Definition: Symtab.cpp:844
lldb_private::Symtab::SymbolIndicesToSymbolContextList
void SymbolIndicesToSymbolContextList(std::vector< uint32_t > &symbol_indexes, SymbolContextList &sc_list)
Definition: Symtab.cpp:1061
lldb_private::ObjectFile
Definition: ObjectFile.h:58
SymbolSortInfo
Definition: Symtab.cpp:552
lldb_private::Symtab::ForEachSymbolContainingFileAddress
void ForEachSymbolContainingFileAddress(lldb::addr_t file_addr, std::function< bool(Symbol *)> const &callback)
Definition: Symtab.cpp:1038
CompareSymbolID
static int CompareSymbolID(const void *key, const void *p)
Definition: Symtab.cpp:191
lldb_private::Symbol::GetSiblingIndex
uint32_t GetSiblingIndex() const
Definition: Symbol.cpp:169
SymbolSearchInfo::match_offset
addr_t match_offset
Definition: Symtab.cpp:887