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