1 //===-- Symtab.cpp --------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
12 #include "lldb/Core/DataFileCache.h"
13 #include "lldb/Core/Module.h"
14 #include "lldb/Core/RichManglingContext.h"
15 #include "lldb/Core/Section.h"
16 #include "lldb/Symbol/ObjectFile.h"
17 #include "lldb/Symbol/Symbol.h"
18 #include "lldb/Symbol/SymbolContext.h"
19 #include "lldb/Symbol/Symtab.h"
20 #include "lldb/Target/Language.h"
21 #include "lldb/Utility/DataEncoder.h"
22 #include "lldb/Utility/Endian.h"
23 #include "lldb/Utility/RegularExpression.h"
24 #include "lldb/Utility/Stream.h"
25 #include "lldb/Utility/Timer.h"
27 #include "llvm/ADT/ArrayRef.h"
28 #include "llvm/ADT/StringRef.h"
29 #include "llvm/Support/DJB.h"
32 using namespace lldb_private
;
34 Symtab::Symtab(ObjectFile
*objfile
)
35 : m_objfile(objfile
), m_symbols(), m_file_addr_to_index(*this),
36 m_name_to_symbol_indices(), m_mutex(),
37 m_file_addr_to_index_computed(false), m_name_indexes_computed(false),
38 m_loaded_from_cache(false), m_saved_to_cache(false) {
39 m_name_to_symbol_indices
.emplace(std::make_pair(
40 lldb::eFunctionNameTypeNone
, UniqueCStringMap
<uint32_t>()));
41 m_name_to_symbol_indices
.emplace(std::make_pair(
42 lldb::eFunctionNameTypeBase
, UniqueCStringMap
<uint32_t>()));
43 m_name_to_symbol_indices
.emplace(std::make_pair(
44 lldb::eFunctionNameTypeMethod
, UniqueCStringMap
<uint32_t>()));
45 m_name_to_symbol_indices
.emplace(std::make_pair(
46 lldb::eFunctionNameTypeSelector
, UniqueCStringMap
<uint32_t>()));
49 Symtab::~Symtab() = default;
51 void Symtab::Reserve(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
.reserve(count
);
57 Symbol
*Symtab::Resize(size_t count
) {
58 // Clients should grab the mutex from this symbol table and lock it manually
59 // when calling this function to avoid performance issues.
60 m_symbols
.resize(count
);
61 return m_symbols
.empty() ? nullptr : &m_symbols
[0];
64 uint32_t Symtab::AddSymbol(const Symbol
&symbol
) {
65 // Clients should grab the mutex from this symbol table and lock it manually
66 // when calling this function to avoid performance issues.
67 uint32_t symbol_idx
= m_symbols
.size();
68 auto &name_to_index
= GetNameToSymbolIndexMap(lldb::eFunctionNameTypeNone
);
69 name_to_index
.Clear();
70 m_file_addr_to_index
.Clear();
71 m_symbols
.push_back(symbol
);
72 m_file_addr_to_index_computed
= false;
73 m_name_indexes_computed
= false;
77 size_t Symtab::GetNumSymbols() const {
78 std::lock_guard
<std::recursive_mutex
> guard(m_mutex
);
79 return m_symbols
.size();
82 void Symtab::SectionFileAddressesChanged() {
83 m_file_addr_to_index
.Clear();
84 m_file_addr_to_index_computed
= false;
87 void Symtab::Dump(Stream
*s
, Target
*target
, SortOrder sort_order
,
88 Mangled::NamePreference name_preference
) {
89 std::lock_guard
<std::recursive_mutex
> guard(m_mutex
);
91 // s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
93 const FileSpec
&file_spec
= m_objfile
->GetFileSpec();
94 const char *object_name
= nullptr;
95 if (m_objfile
->GetModule())
96 object_name
= m_objfile
->GetModule()->GetObjectName().GetCString();
99 s
->Printf("Symtab, file = %s%s%s%s, num_symbols = %" PRIu64
,
100 file_spec
.GetPath().c_str(), object_name
? "(" : "",
101 object_name
? object_name
: "", object_name
? ")" : "",
102 (uint64_t)m_symbols
.size());
104 s
->Printf("Symtab, num_symbols = %" PRIu64
"", (uint64_t)m_symbols
.size());
106 if (!m_symbols
.empty()) {
107 switch (sort_order
) {
108 case eSortOrderNone
: {
109 s
->PutCString(":\n");
111 const_iterator begin
= m_symbols
.begin();
112 const_iterator end
= m_symbols
.end();
113 for (const_iterator pos
= m_symbols
.begin(); pos
!= end
; ++pos
) {
115 pos
->Dump(s
, target
, std::distance(begin
, pos
), name_preference
);
120 case eSortOrderByName
: {
121 // Although we maintain a lookup by exact name map, the table isn't
122 // sorted by name. So we must make the ordered symbol list up ourselves.
123 s
->PutCString(" (sorted by name):\n");
126 std::multimap
<llvm::StringRef
, const Symbol
*> name_map
;
127 for (const Symbol
&symbol
: m_symbols
)
128 name_map
.emplace(symbol
.GetName().GetStringRef(), &symbol
);
130 for (const auto &name_to_symbol
: name_map
) {
131 const Symbol
*symbol
= name_to_symbol
.second
;
133 symbol
->Dump(s
, target
, symbol
- &m_symbols
[0], name_preference
);
137 case eSortOrderBySize
: {
138 s
->PutCString(" (sorted by size):\n");
141 std::multimap
<size_t, const Symbol
*, std::greater
<size_t>> size_map
;
142 for (const Symbol
&symbol
: m_symbols
)
143 size_map
.emplace(symbol
.GetByteSize(), &symbol
);
146 for (const auto &size_to_symbol
: size_map
) {
147 const Symbol
*symbol
= size_to_symbol
.second
;
149 symbol
->Dump(s
, target
, idx
++, name_preference
);
153 case eSortOrderByAddress
:
154 s
->PutCString(" (sorted by address):\n");
156 if (!m_file_addr_to_index_computed
)
157 InitAddressIndexes();
158 const size_t num_entries
= m_file_addr_to_index
.GetSize();
159 for (size_t i
= 0; i
< num_entries
; ++i
) {
161 const uint32_t symbol_idx
= m_file_addr_to_index
.GetEntryRef(i
).data
;
162 m_symbols
[symbol_idx
].Dump(s
, target
, symbol_idx
, name_preference
);
171 void Symtab::Dump(Stream
*s
, Target
*target
, std::vector
<uint32_t> &indexes
,
172 Mangled::NamePreference name_preference
) const {
173 std::lock_guard
<std::recursive_mutex
> guard(m_mutex
);
175 const size_t num_symbols
= GetNumSymbols();
176 // s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
178 s
->Printf("Symtab %" PRIu64
" symbol indexes (%" PRIu64
" symbols total):\n",
179 (uint64_t)indexes
.size(), (uint64_t)m_symbols
.size());
182 if (!indexes
.empty()) {
183 std::vector
<uint32_t>::const_iterator pos
;
184 std::vector
<uint32_t>::const_iterator end
= indexes
.end();
186 for (pos
= indexes
.begin(); pos
!= end
; ++pos
) {
188 if (idx
< num_symbols
) {
190 m_symbols
[idx
].Dump(s
, target
, idx
, name_preference
);
197 void Symtab::DumpSymbolHeader(Stream
*s
) {
198 s
->Indent(" Debug symbol\n");
199 s
->Indent(" |Synthetic symbol\n");
200 s
->Indent(" ||Externally Visible\n");
202 s
->Indent("Index UserID DSX Type File Address/Value Load "
203 "Address Size Flags Name\n");
204 s
->Indent("------- ------ --- --------------- ------------------ "
205 "------------------ ------------------ ---------- "
206 "----------------------------------\n");
209 static int CompareSymbolID(const void *key
, const void *p
) {
210 const user_id_t match_uid
= *(const user_id_t
*)key
;
211 const user_id_t symbol_uid
= ((const Symbol
*)p
)->GetID();
212 if (match_uid
< symbol_uid
)
214 if (match_uid
> symbol_uid
)
219 Symbol
*Symtab::FindSymbolByID(lldb::user_id_t symbol_uid
) const {
220 std::lock_guard
<std::recursive_mutex
> guard(m_mutex
);
223 (Symbol
*)::bsearch(&symbol_uid
, &m_symbols
[0], m_symbols
.size(),
224 sizeof(m_symbols
[0]), CompareSymbolID
);
228 Symbol
*Symtab::SymbolAtIndex(size_t idx
) {
229 // Clients should grab the mutex from this symbol table and lock it manually
230 // when calling this function to avoid performance issues.
231 if (idx
< m_symbols
.size())
232 return &m_symbols
[idx
];
236 const Symbol
*Symtab::SymbolAtIndex(size_t idx
) const {
237 // Clients should grab the mutex from this symbol table and lock it manually
238 // when calling this function to avoid performance issues.
239 if (idx
< m_symbols
.size())
240 return &m_symbols
[idx
];
244 static bool lldb_skip_name(llvm::StringRef mangled
,
245 Mangled::ManglingScheme scheme
) {
247 case Mangled::eManglingSchemeItanium
: {
248 if (mangled
.size() < 3 || !mangled
.starts_with("_Z"))
251 // Avoid the following types of symbols in the index.
252 switch (mangled
[2]) {
253 case 'G': // guard variables
254 case 'T': // virtual tables, VTT structures, typeinfo structures + names
255 case 'Z': // named local entities (if we eventually handle
256 // eSymbolTypeData, we will want this back)
263 // Include this name in the index.
267 // No filters for this scheme yet. Include all names in indexing.
268 case Mangled::eManglingSchemeMSVC
:
269 case Mangled::eManglingSchemeRustV0
:
270 case Mangled::eManglingSchemeD
:
271 case Mangled::eManglingSchemeSwift
:
274 // Don't try and demangle things we can't categorize.
275 case Mangled::eManglingSchemeNone
:
278 llvm_unreachable("unknown scheme!");
281 void Symtab::InitNameIndexes() {
282 // Protected function, no need to lock mutex...
283 if (!m_name_indexes_computed
) {
284 m_name_indexes_computed
= true;
285 ElapsedTime
elapsed(m_objfile
->GetModule()->GetSymtabIndexTime());
288 // Collect all loaded language plugins.
289 std::vector
<Language
*> languages
;
290 Language::ForEach([&languages
](Language
*l
) {
291 languages
.push_back(l
);
295 auto &name_to_index
= GetNameToSymbolIndexMap(lldb::eFunctionNameTypeNone
);
296 auto &basename_to_index
=
297 GetNameToSymbolIndexMap(lldb::eFunctionNameTypeBase
);
298 auto &method_to_index
=
299 GetNameToSymbolIndexMap(lldb::eFunctionNameTypeMethod
);
300 auto &selector_to_index
=
301 GetNameToSymbolIndexMap(lldb::eFunctionNameTypeSelector
);
302 // Create the name index vector to be able to quickly search by name
303 const size_t num_symbols
= m_symbols
.size();
304 name_to_index
.Reserve(num_symbols
);
306 // The "const char *" in "class_contexts" and backlog::value_type::second
307 // must come from a ConstString::GetCString()
308 std::set
<const char *> class_contexts
;
309 std::vector
<std::pair
<NameToIndexMap::Entry
, const char *>> backlog
;
310 backlog
.reserve(num_symbols
/ 2);
312 // Instantiation of the demangler is expensive, so better use a single one
313 // for all entries during batch processing.
314 RichManglingContext rmc
;
315 for (uint32_t value
= 0; value
< num_symbols
; ++value
) {
316 Symbol
*symbol
= &m_symbols
[value
];
318 // Don't let trampolines get into the lookup by name map If we ever need
319 // the trampoline symbols to be searchable by name we can remove this and
320 // then possibly add a new bool to any of the Symtab functions that
321 // lookup symbols by name to indicate if they want trampolines. We also
322 // don't want any synthetic symbols with auto generated names in the
324 if (symbol
->IsTrampoline() || symbol
->IsSyntheticWithAutoGeneratedName())
327 // If the symbol's name string matched a Mangled::ManglingScheme, it is
328 // stored in the mangled field.
329 Mangled
&mangled
= symbol
->GetMangled();
330 if (ConstString name
= mangled
.GetMangledName()) {
331 name_to_index
.Append(name
, value
);
333 if (symbol
->ContainsLinkerAnnotations()) {
334 // If the symbol has linker annotations, also add the version without
336 ConstString stripped
= ConstString(
337 m_objfile
->StripLinkerSymbolAnnotations(name
.GetStringRef()));
338 name_to_index
.Append(stripped
, value
);
341 const SymbolType type
= symbol
->GetType();
342 if (type
== eSymbolTypeCode
|| type
== eSymbolTypeResolver
) {
343 if (mangled
.GetRichManglingInfo(rmc
, lldb_skip_name
)) {
344 RegisterMangledNameEntry(value
, class_contexts
, backlog
, rmc
);
350 // Symbol name strings that didn't match a Mangled::ManglingScheme, are
351 // stored in the demangled field.
352 if (ConstString name
= mangled
.GetDemangledName()) {
353 name_to_index
.Append(name
, value
);
355 if (symbol
->ContainsLinkerAnnotations()) {
356 // If the symbol has linker annotations, also add the version without
359 m_objfile
->StripLinkerSymbolAnnotations(name
.GetStringRef()));
360 name_to_index
.Append(name
, value
);
363 // If the demangled name turns out to be an ObjC name, and is a category
364 // name, add the version without categories to the index too.
365 for (Language
*lang
: languages
) {
366 for (auto variant
: lang
->GetMethodNameVariants(name
)) {
367 if (variant
.GetType() & lldb::eFunctionNameTypeSelector
)
368 selector_to_index
.Append(variant
.GetName(), value
);
369 else if (variant
.GetType() & lldb::eFunctionNameTypeFull
)
370 name_to_index
.Append(variant
.GetName(), value
);
371 else if (variant
.GetType() & lldb::eFunctionNameTypeMethod
)
372 method_to_index
.Append(variant
.GetName(), value
);
373 else if (variant
.GetType() & lldb::eFunctionNameTypeBase
)
374 basename_to_index
.Append(variant
.GetName(), value
);
380 for (const auto &record
: backlog
) {
381 RegisterBacklogEntry(record
.first
, record
.second
, class_contexts
);
384 name_to_index
.Sort();
385 name_to_index
.SizeToFit();
386 selector_to_index
.Sort();
387 selector_to_index
.SizeToFit();
388 basename_to_index
.Sort();
389 basename_to_index
.SizeToFit();
390 method_to_index
.Sort();
391 method_to_index
.SizeToFit();
395 void Symtab::RegisterMangledNameEntry(
396 uint32_t value
, std::set
<const char *> &class_contexts
,
397 std::vector
<std::pair
<NameToIndexMap::Entry
, const char *>> &backlog
,
398 RichManglingContext
&rmc
) {
399 // Only register functions that have a base name.
400 llvm::StringRef base_name
= rmc
.ParseFunctionBaseName();
401 if (base_name
.empty())
404 // The base name will be our entry's name.
405 NameToIndexMap::Entry
entry(ConstString(base_name
), value
);
406 llvm::StringRef decl_context
= rmc
.ParseFunctionDeclContextName();
408 // Register functions with no context.
409 if (decl_context
.empty()) {
410 // This has to be a basename
411 auto &basename_to_index
=
412 GetNameToSymbolIndexMap(lldb::eFunctionNameTypeBase
);
413 basename_to_index
.Append(entry
);
414 // If there is no context (no namespaces or class scopes that come before
415 // the function name) then this also could be a fullname.
416 auto &name_to_index
= GetNameToSymbolIndexMap(lldb::eFunctionNameTypeNone
);
417 name_to_index
.Append(entry
);
421 // Make sure we have a pool-string pointer and see if we already know the
423 const char *decl_context_ccstr
= ConstString(decl_context
).GetCString();
424 auto it
= class_contexts
.find(decl_context_ccstr
);
426 auto &method_to_index
=
427 GetNameToSymbolIndexMap(lldb::eFunctionNameTypeMethod
);
428 // Register constructors and destructors. They are methods and create
429 // declaration contexts.
430 if (rmc
.IsCtorOrDtor()) {
431 method_to_index
.Append(entry
);
432 if (it
== class_contexts
.end())
433 class_contexts
.insert(it
, decl_context_ccstr
);
437 // Register regular methods with a known declaration context.
438 if (it
!= class_contexts
.end()) {
439 method_to_index
.Append(entry
);
443 // Regular methods in unknown declaration contexts are put to the backlog. We
444 // will revisit them once we processed all remaining symbols.
445 backlog
.push_back(std::make_pair(entry
, decl_context_ccstr
));
448 void Symtab::RegisterBacklogEntry(
449 const NameToIndexMap::Entry
&entry
, const char *decl_context
,
450 const std::set
<const char *> &class_contexts
) {
451 auto &method_to_index
=
452 GetNameToSymbolIndexMap(lldb::eFunctionNameTypeMethod
);
453 auto it
= class_contexts
.find(decl_context
);
454 if (it
!= class_contexts
.end()) {
455 method_to_index
.Append(entry
);
457 // If we got here, we have something that had a context (was inside
458 // a namespace or class) yet we don't know the entry
459 method_to_index
.Append(entry
);
460 auto &basename_to_index
=
461 GetNameToSymbolIndexMap(lldb::eFunctionNameTypeBase
);
462 basename_to_index
.Append(entry
);
466 void Symtab::PreloadSymbols() {
467 std::lock_guard
<std::recursive_mutex
> guard(m_mutex
);
471 void Symtab::AppendSymbolNamesToMap(const IndexCollection
&indexes
,
472 bool add_demangled
, bool add_mangled
,
473 NameToIndexMap
&name_to_index_map
) const {
475 if (add_demangled
|| add_mangled
) {
476 std::lock_guard
<std::recursive_mutex
> guard(m_mutex
);
478 // Create the name index vector to be able to quickly search by name
479 const size_t num_indexes
= indexes
.size();
480 for (size_t i
= 0; i
< num_indexes
; ++i
) {
481 uint32_t value
= indexes
[i
];
482 assert(i
< m_symbols
.size());
483 const Symbol
*symbol
= &m_symbols
[value
];
485 const Mangled
&mangled
= symbol
->GetMangled();
487 if (ConstString name
= mangled
.GetDemangledName())
488 name_to_index_map
.Append(name
, value
);
492 if (ConstString name
= mangled
.GetMangledName())
493 name_to_index_map
.Append(name
, value
);
499 uint32_t Symtab::AppendSymbolIndexesWithType(SymbolType symbol_type
,
500 std::vector
<uint32_t> &indexes
,
502 uint32_t end_index
) const {
503 std::lock_guard
<std::recursive_mutex
> guard(m_mutex
);
505 uint32_t prev_size
= indexes
.size();
507 const uint32_t count
= std::min
<uint32_t>(m_symbols
.size(), end_index
);
509 for (uint32_t i
= start_idx
; i
< count
; ++i
) {
510 if (symbol_type
== eSymbolTypeAny
|| m_symbols
[i
].GetType() == symbol_type
)
511 indexes
.push_back(i
);
514 return indexes
.size() - prev_size
;
517 uint32_t Symtab::AppendSymbolIndexesWithTypeAndFlagsValue(
518 SymbolType symbol_type
, uint32_t flags_value
,
519 std::vector
<uint32_t> &indexes
, uint32_t start_idx
,
520 uint32_t end_index
) const {
521 std::lock_guard
<std::recursive_mutex
> guard(m_mutex
);
523 uint32_t prev_size
= indexes
.size();
525 const uint32_t count
= std::min
<uint32_t>(m_symbols
.size(), end_index
);
527 for (uint32_t i
= start_idx
; i
< count
; ++i
) {
528 if ((symbol_type
== eSymbolTypeAny
||
529 m_symbols
[i
].GetType() == symbol_type
) &&
530 m_symbols
[i
].GetFlags() == flags_value
)
531 indexes
.push_back(i
);
534 return indexes
.size() - prev_size
;
537 uint32_t Symtab::AppendSymbolIndexesWithType(SymbolType symbol_type
,
538 Debug symbol_debug_type
,
539 Visibility symbol_visibility
,
540 std::vector
<uint32_t> &indexes
,
542 uint32_t end_index
) const {
543 std::lock_guard
<std::recursive_mutex
> guard(m_mutex
);
545 uint32_t prev_size
= indexes
.size();
547 const uint32_t count
= std::min
<uint32_t>(m_symbols
.size(), end_index
);
549 for (uint32_t i
= start_idx
; i
< count
; ++i
) {
550 if (symbol_type
== eSymbolTypeAny
||
551 m_symbols
[i
].GetType() == symbol_type
) {
552 if (CheckSymbolAtIndex(i
, symbol_debug_type
, symbol_visibility
))
553 indexes
.push_back(i
);
557 return indexes
.size() - prev_size
;
560 uint32_t Symtab::GetIndexForSymbol(const Symbol
*symbol
) const {
561 if (!m_symbols
.empty()) {
562 const Symbol
*first_symbol
= &m_symbols
[0];
563 if (symbol
>= first_symbol
&& symbol
< first_symbol
+ m_symbols
.size())
564 return symbol
- first_symbol
;
569 struct SymbolSortInfo
{
570 const bool sort_by_load_addr
;
571 const Symbol
*symbols
;
575 struct SymbolIndexComparator
{
576 const std::vector
<Symbol
> &symbols
;
577 std::vector
<lldb::addr_t
> &addr_cache
;
579 // Getting from the symbol to the Address to the File Address involves some
580 // work. Since there are potentially many symbols here, and we're using this
581 // for sorting so we're going to be computing the address many times, cache
582 // that in addr_cache. The array passed in has to be the same size as the
583 // symbols array passed into the member variable symbols, and should be
584 // initialized with LLDB_INVALID_ADDRESS.
585 // NOTE: You have to make addr_cache externally and pass it in because
587 // makes copies of the comparator it is initially passed in, and you end up
588 // spending huge amounts of time copying this array...
590 SymbolIndexComparator(const std::vector
<Symbol
> &s
,
591 std::vector
<lldb::addr_t
> &a
)
592 : symbols(s
), addr_cache(a
) {
593 assert(symbols
.size() == addr_cache
.size());
595 bool operator()(uint32_t index_a
, uint32_t index_b
) {
596 addr_t value_a
= addr_cache
[index_a
];
597 if (value_a
== LLDB_INVALID_ADDRESS
) {
598 value_a
= symbols
[index_a
].GetAddressRef().GetFileAddress();
599 addr_cache
[index_a
] = value_a
;
602 addr_t value_b
= addr_cache
[index_b
];
603 if (value_b
== LLDB_INVALID_ADDRESS
) {
604 value_b
= symbols
[index_b
].GetAddressRef().GetFileAddress();
605 addr_cache
[index_b
] = value_b
;
608 if (value_a
== value_b
) {
609 // The if the values are equal, use the original symbol user ID
610 lldb::user_id_t uid_a
= symbols
[index_a
].GetID();
611 lldb::user_id_t uid_b
= symbols
[index_b
].GetID();
617 } else if (value_a
< value_b
)
625 void Symtab::SortSymbolIndexesByValue(std::vector
<uint32_t> &indexes
,
626 bool remove_duplicates
) const {
627 std::lock_guard
<std::recursive_mutex
> guard(m_mutex
);
629 // No need to sort if we have zero or one items...
630 if (indexes
.size() <= 1)
633 // Sort the indexes in place using std::stable_sort.
634 // NOTE: The use of std::stable_sort instead of llvm::sort here is strictly
635 // for performance, not correctness. The indexes vector tends to be "close"
636 // to sorted, which the stable sort handles better.
638 std::vector
<lldb::addr_t
> addr_cache(m_symbols
.size(), LLDB_INVALID_ADDRESS
);
640 SymbolIndexComparator
comparator(m_symbols
, addr_cache
);
641 std::stable_sort(indexes
.begin(), indexes
.end(), comparator
);
643 // Remove any duplicates if requested
644 if (remove_duplicates
) {
645 auto last
= std::unique(indexes
.begin(), indexes
.end());
646 indexes
.erase(last
, indexes
.end());
650 uint32_t Symtab::GetNameIndexes(ConstString symbol_name
,
651 std::vector
<uint32_t> &indexes
) {
652 auto &name_to_index
= GetNameToSymbolIndexMap(lldb::eFunctionNameTypeNone
);
653 const uint32_t count
= name_to_index
.GetValues(symbol_name
, indexes
);
656 // Synthetic symbol names are not added to the name indexes, but they start
657 // with a prefix and end with a the symbol UserID. This allows users to find
658 // these symbols without having to add them to the name indexes. These
659 // queries will not happen very often since the names don't mean anything, so
660 // performance is not paramount in this case.
661 llvm::StringRef name
= symbol_name
.GetStringRef();
662 // String the synthetic prefix if the name starts with it.
663 if (!name
.consume_front(Symbol::GetSyntheticSymbolPrefix()))
664 return 0; // Not a synthetic symbol name
666 // Extract the user ID from the symbol name
667 unsigned long long uid
= 0;
668 if (getAsUnsignedInteger(name
, /*Radix=*/10, uid
))
669 return 0; // Failed to extract the user ID as an integer
670 Symbol
*symbol
= FindSymbolByID(uid
);
671 if (symbol
== nullptr)
673 const uint32_t symbol_idx
= GetIndexForSymbol(symbol
);
674 if (symbol_idx
== UINT32_MAX
)
676 indexes
.push_back(symbol_idx
);
680 uint32_t Symtab::AppendSymbolIndexesWithName(ConstString symbol_name
,
681 std::vector
<uint32_t> &indexes
) {
682 std::lock_guard
<std::recursive_mutex
> guard(m_mutex
);
685 if (!m_name_indexes_computed
)
688 return GetNameIndexes(symbol_name
, indexes
);
693 uint32_t Symtab::AppendSymbolIndexesWithName(ConstString symbol_name
,
694 Debug symbol_debug_type
,
695 Visibility symbol_visibility
,
696 std::vector
<uint32_t> &indexes
) {
697 std::lock_guard
<std::recursive_mutex
> guard(m_mutex
);
701 const size_t old_size
= indexes
.size();
702 if (!m_name_indexes_computed
)
705 std::vector
<uint32_t> all_name_indexes
;
706 const size_t name_match_count
=
707 GetNameIndexes(symbol_name
, all_name_indexes
);
708 for (size_t i
= 0; i
< name_match_count
; ++i
) {
709 if (CheckSymbolAtIndex(all_name_indexes
[i
], symbol_debug_type
,
711 indexes
.push_back(all_name_indexes
[i
]);
713 return indexes
.size() - old_size
;
719 Symtab::AppendSymbolIndexesWithNameAndType(ConstString symbol_name
,
720 SymbolType symbol_type
,
721 std::vector
<uint32_t> &indexes
) {
722 std::lock_guard
<std::recursive_mutex
> guard(m_mutex
);
724 if (AppendSymbolIndexesWithName(symbol_name
, indexes
) > 0) {
725 std::vector
<uint32_t>::iterator pos
= indexes
.begin();
726 while (pos
!= indexes
.end()) {
727 if (symbol_type
== eSymbolTypeAny
||
728 m_symbols
[*pos
].GetType() == symbol_type
)
731 pos
= indexes
.erase(pos
);
734 return indexes
.size();
737 uint32_t Symtab::AppendSymbolIndexesWithNameAndType(
738 ConstString symbol_name
, SymbolType symbol_type
,
739 Debug symbol_debug_type
, Visibility symbol_visibility
,
740 std::vector
<uint32_t> &indexes
) {
741 std::lock_guard
<std::recursive_mutex
> guard(m_mutex
);
743 if (AppendSymbolIndexesWithName(symbol_name
, symbol_debug_type
,
744 symbol_visibility
, indexes
) > 0) {
745 std::vector
<uint32_t>::iterator pos
= indexes
.begin();
746 while (pos
!= indexes
.end()) {
747 if (symbol_type
== eSymbolTypeAny
||
748 m_symbols
[*pos
].GetType() == symbol_type
)
751 pos
= indexes
.erase(pos
);
754 return indexes
.size();
757 uint32_t Symtab::AppendSymbolIndexesMatchingRegExAndType(
758 const RegularExpression
®exp
, SymbolType symbol_type
,
759 std::vector
<uint32_t> &indexes
, Mangled::NamePreference name_preference
) {
760 std::lock_guard
<std::recursive_mutex
> guard(m_mutex
);
762 uint32_t prev_size
= indexes
.size();
763 uint32_t sym_end
= m_symbols
.size();
765 for (uint32_t i
= 0; i
< sym_end
; i
++) {
766 if (symbol_type
== eSymbolTypeAny
||
767 m_symbols
[i
].GetType() == symbol_type
) {
769 m_symbols
[i
].GetMangled().GetName(name_preference
).AsCString();
771 if (regexp
.Execute(name
))
772 indexes
.push_back(i
);
776 return indexes
.size() - prev_size
;
779 uint32_t Symtab::AppendSymbolIndexesMatchingRegExAndType(
780 const RegularExpression
®exp
, SymbolType symbol_type
,
781 Debug symbol_debug_type
, Visibility symbol_visibility
,
782 std::vector
<uint32_t> &indexes
, Mangled::NamePreference name_preference
) {
783 std::lock_guard
<std::recursive_mutex
> guard(m_mutex
);
785 uint32_t prev_size
= indexes
.size();
786 uint32_t sym_end
= m_symbols
.size();
788 for (uint32_t i
= 0; i
< sym_end
; i
++) {
789 if (symbol_type
== eSymbolTypeAny
||
790 m_symbols
[i
].GetType() == symbol_type
) {
791 if (!CheckSymbolAtIndex(i
, symbol_debug_type
, symbol_visibility
))
795 m_symbols
[i
].GetMangled().GetName(name_preference
).AsCString();
797 if (regexp
.Execute(name
))
798 indexes
.push_back(i
);
802 return indexes
.size() - prev_size
;
805 Symbol
*Symtab::FindSymbolWithType(SymbolType symbol_type
,
806 Debug symbol_debug_type
,
807 Visibility symbol_visibility
,
808 uint32_t &start_idx
) {
809 std::lock_guard
<std::recursive_mutex
> guard(m_mutex
);
811 const size_t count
= m_symbols
.size();
812 for (size_t idx
= start_idx
; idx
< count
; ++idx
) {
813 if (symbol_type
== eSymbolTypeAny
||
814 m_symbols
[idx
].GetType() == symbol_type
) {
815 if (CheckSymbolAtIndex(idx
, symbol_debug_type
, symbol_visibility
)) {
817 return &m_symbols
[idx
];
825 Symtab::FindAllSymbolsWithNameAndType(ConstString name
,
826 SymbolType symbol_type
,
827 std::vector
<uint32_t> &symbol_indexes
) {
828 std::lock_guard
<std::recursive_mutex
> guard(m_mutex
);
830 // Initialize all of the lookup by name indexes before converting NAME to a
831 // uniqued string NAME_STR below.
832 if (!m_name_indexes_computed
)
836 // The string table did have a string that matched, but we need to check
837 // the symbols and match the symbol_type if any was given.
838 AppendSymbolIndexesWithNameAndType(name
, symbol_type
, symbol_indexes
);
842 void Symtab::FindAllSymbolsWithNameAndType(
843 ConstString name
, SymbolType symbol_type
, Debug symbol_debug_type
,
844 Visibility symbol_visibility
, std::vector
<uint32_t> &symbol_indexes
) {
845 std::lock_guard
<std::recursive_mutex
> guard(m_mutex
);
848 // Initialize all of the lookup by name indexes before converting NAME to a
849 // uniqued string NAME_STR below.
850 if (!m_name_indexes_computed
)
854 // The string table did have a string that matched, but we need to check
855 // the symbols and match the symbol_type if any was given.
856 AppendSymbolIndexesWithNameAndType(name
, symbol_type
, symbol_debug_type
,
857 symbol_visibility
, symbol_indexes
);
861 void Symtab::FindAllSymbolsMatchingRexExAndType(
862 const RegularExpression
®ex
, SymbolType symbol_type
,
863 Debug symbol_debug_type
, Visibility symbol_visibility
,
864 std::vector
<uint32_t> &symbol_indexes
,
865 Mangled::NamePreference name_preference
) {
866 std::lock_guard
<std::recursive_mutex
> guard(m_mutex
);
868 AppendSymbolIndexesMatchingRegExAndType(regex
, symbol_type
, symbol_debug_type
,
869 symbol_visibility
, symbol_indexes
,
873 Symbol
*Symtab::FindFirstSymbolWithNameAndType(ConstString name
,
874 SymbolType symbol_type
,
875 Debug symbol_debug_type
,
876 Visibility symbol_visibility
) {
877 std::lock_guard
<std::recursive_mutex
> guard(m_mutex
);
879 if (!m_name_indexes_computed
)
883 std::vector
<uint32_t> matching_indexes
;
884 // The string table did have a string that matched, but we need to check
885 // the symbols and match the symbol_type if any was given.
886 if (AppendSymbolIndexesWithNameAndType(name
, symbol_type
, symbol_debug_type
,
889 std::vector
<uint32_t>::const_iterator pos
, end
= matching_indexes
.end();
890 for (pos
= matching_indexes
.begin(); pos
!= end
; ++pos
) {
891 Symbol
*symbol
= SymbolAtIndex(*pos
);
893 if (symbol
->Compare(name
, symbol_type
))
902 const Symtab
*symtab
;
903 const addr_t file_addr
;
904 Symbol
*match_symbol
;
905 const uint32_t *match_index_ptr
;
909 // Add all the section file start address & size to the RangeVector, recusively
910 // adding any children sections.
911 static void AddSectionsToRangeMap(SectionList
*sectlist
,
912 RangeVector
<addr_t
, addr_t
> §ion_ranges
) {
913 const int num_sections
= sectlist
->GetNumSections(0);
914 for (int i
= 0; i
< num_sections
; i
++) {
915 SectionSP sect_sp
= sectlist
->GetSectionAtIndex(i
);
917 SectionList
&child_sectlist
= sect_sp
->GetChildren();
919 // If this section has children, add the children to the RangeVector.
920 // Else add this section to the RangeVector.
921 if (child_sectlist
.GetNumSections(0) > 0) {
922 AddSectionsToRangeMap(&child_sectlist
, section_ranges
);
924 size_t size
= sect_sp
->GetByteSize();
926 addr_t base_addr
= sect_sp
->GetFileAddress();
927 RangeVector
<addr_t
, addr_t
>::Entry entry
;
928 entry
.SetRangeBase(base_addr
);
929 entry
.SetByteSize(size
);
930 section_ranges
.Append(entry
);
937 void Symtab::InitAddressIndexes() {
938 // Protected function, no need to lock mutex...
939 if (!m_file_addr_to_index_computed
&& !m_symbols
.empty()) {
940 m_file_addr_to_index_computed
= true;
942 FileRangeToIndexMap::Entry entry
;
943 const_iterator begin
= m_symbols
.begin();
944 const_iterator end
= m_symbols
.end();
945 for (const_iterator pos
= m_symbols
.begin(); pos
!= end
; ++pos
) {
946 if (pos
->ValueIsAddress()) {
947 entry
.SetRangeBase(pos
->GetAddressRef().GetFileAddress());
948 entry
.SetByteSize(pos
->GetByteSize());
949 entry
.data
= std::distance(begin
, pos
);
950 m_file_addr_to_index
.Append(entry
);
953 const size_t num_entries
= m_file_addr_to_index
.GetSize();
954 if (num_entries
> 0) {
955 m_file_addr_to_index
.Sort();
957 // Create a RangeVector with the start & size of all the sections for
958 // this objfile. We'll need to check this for any FileRangeToIndexMap
959 // entries with an uninitialized size, which could potentially be a large
960 // number so reconstituting the weak pointer is busywork when it is
961 // invariant information.
962 SectionList
*sectlist
= m_objfile
->GetSectionList();
963 RangeVector
<addr_t
, addr_t
> section_ranges
;
965 AddSectionsToRangeMap(sectlist
, section_ranges
);
966 section_ranges
.Sort();
969 // Iterate through the FileRangeToIndexMap and fill in the size for any
970 // entries that didn't already have a size from the Symbol (e.g. if we
971 // have a plain linker symbol with an address only, instead of debug info
972 // where we get an address and a size and a type, etc.)
973 for (size_t i
= 0; i
< num_entries
; i
++) {
974 FileRangeToIndexMap::Entry
*entry
=
975 m_file_addr_to_index
.GetMutableEntryAtIndex(i
);
976 if (entry
->GetByteSize() == 0) {
977 addr_t curr_base_addr
= entry
->GetRangeBase();
978 const RangeVector
<addr_t
, addr_t
>::Entry
*containing_section
=
979 section_ranges
.FindEntryThatContains(curr_base_addr
);
981 // Use the end of the section as the default max size of the symbol
983 if (containing_section
) {
985 containing_section
->GetByteSize() -
986 (entry
->GetRangeBase() - containing_section
->GetRangeBase());
989 for (size_t j
= i
; j
< num_entries
; j
++) {
990 FileRangeToIndexMap::Entry
*next_entry
=
991 m_file_addr_to_index
.GetMutableEntryAtIndex(j
);
992 addr_t next_base_addr
= next_entry
->GetRangeBase();
993 if (next_base_addr
> curr_base_addr
) {
994 addr_t size_to_next_symbol
= next_base_addr
- curr_base_addr
;
996 // Take the difference between this symbol and the next one as
997 // its size, if it is less than the size of the section.
998 if (sym_size
== 0 || size_to_next_symbol
< sym_size
) {
999 sym_size
= size_to_next_symbol
;
1006 entry
->SetByteSize(sym_size
);
1007 Symbol
&symbol
= m_symbols
[entry
->data
];
1008 symbol
.SetByteSize(sym_size
);
1009 symbol
.SetSizeIsSynthesized(true);
1014 // Sort again in case the range size changes the ordering
1015 m_file_addr_to_index
.Sort();
1020 void Symtab::Finalize() {
1021 std::lock_guard
<std::recursive_mutex
> guard(m_mutex
);
1022 // Calculate the size of symbols inside InitAddressIndexes.
1023 InitAddressIndexes();
1024 // Shrink to fit the symbols so we don't waste memory
1025 m_symbols
.shrink_to_fit();
1029 Symbol
*Symtab::FindSymbolAtFileAddress(addr_t file_addr
) {
1030 std::lock_guard
<std::recursive_mutex
> guard(m_mutex
);
1031 if (!m_file_addr_to_index_computed
)
1032 InitAddressIndexes();
1034 const FileRangeToIndexMap::Entry
*entry
=
1035 m_file_addr_to_index
.FindEntryStartsAt(file_addr
);
1037 Symbol
*symbol
= SymbolAtIndex(entry
->data
);
1038 if (symbol
->GetFileAddress() == file_addr
)
1044 Symbol
*Symtab::FindSymbolContainingFileAddress(addr_t file_addr
) {
1045 std::lock_guard
<std::recursive_mutex
> guard(m_mutex
);
1047 if (!m_file_addr_to_index_computed
)
1048 InitAddressIndexes();
1050 const FileRangeToIndexMap::Entry
*entry
=
1051 m_file_addr_to_index
.FindEntryThatContains(file_addr
);
1053 Symbol
*symbol
= SymbolAtIndex(entry
->data
);
1054 if (symbol
->ContainsFileAddress(file_addr
))
1060 void Symtab::ForEachSymbolContainingFileAddress(
1061 addr_t file_addr
, std::function
<bool(Symbol
*)> const &callback
) {
1062 std::lock_guard
<std::recursive_mutex
> guard(m_mutex
);
1064 if (!m_file_addr_to_index_computed
)
1065 InitAddressIndexes();
1067 std::vector
<uint32_t> all_addr_indexes
;
1069 // Get all symbols with file_addr
1070 const size_t addr_match_count
=
1071 m_file_addr_to_index
.FindEntryIndexesThatContain(file_addr
,
1074 for (size_t i
= 0; i
< addr_match_count
; ++i
) {
1075 Symbol
*symbol
= SymbolAtIndex(all_addr_indexes
[i
]);
1076 if (symbol
->ContainsFileAddress(file_addr
)) {
1077 if (!callback(symbol
))
1083 void Symtab::SymbolIndicesToSymbolContextList(
1084 std::vector
<uint32_t> &symbol_indexes
, SymbolContextList
&sc_list
) {
1085 // No need to protect this call using m_mutex all other method calls are
1086 // already thread safe.
1088 const bool merge_symbol_into_function
= true;
1089 size_t num_indices
= symbol_indexes
.size();
1090 if (num_indices
> 0) {
1092 sc
.module_sp
= m_objfile
->GetModule();
1093 for (size_t i
= 0; i
< num_indices
; i
++) {
1094 sc
.symbol
= SymbolAtIndex(symbol_indexes
[i
]);
1096 sc_list
.AppendIfUnique(sc
, merge_symbol_into_function
);
1101 void Symtab::FindFunctionSymbols(ConstString name
, uint32_t name_type_mask
,
1102 SymbolContextList
&sc_list
) {
1103 std::vector
<uint32_t> symbol_indexes
;
1105 // eFunctionNameTypeAuto should be pre-resolved by a call to
1106 // Module::LookupInfo::LookupInfo()
1107 assert((name_type_mask
& eFunctionNameTypeAuto
) == 0);
1109 if (name_type_mask
& (eFunctionNameTypeBase
| eFunctionNameTypeFull
)) {
1110 std::vector
<uint32_t> temp_symbol_indexes
;
1111 FindAllSymbolsWithNameAndType(name
, eSymbolTypeAny
, temp_symbol_indexes
);
1113 unsigned temp_symbol_indexes_size
= temp_symbol_indexes
.size();
1114 if (temp_symbol_indexes_size
> 0) {
1115 std::lock_guard
<std::recursive_mutex
> guard(m_mutex
);
1116 for (unsigned i
= 0; i
< temp_symbol_indexes_size
; i
++) {
1117 SymbolContext sym_ctx
;
1118 sym_ctx
.symbol
= SymbolAtIndex(temp_symbol_indexes
[i
]);
1119 if (sym_ctx
.symbol
) {
1120 switch (sym_ctx
.symbol
->GetType()) {
1121 case eSymbolTypeCode
:
1122 case eSymbolTypeResolver
:
1123 case eSymbolTypeReExported
:
1124 case eSymbolTypeAbsolute
:
1125 symbol_indexes
.push_back(temp_symbol_indexes
[i
]);
1135 if (!m_name_indexes_computed
)
1138 for (lldb::FunctionNameType type
:
1139 {lldb::eFunctionNameTypeBase
, lldb::eFunctionNameTypeMethod
,
1140 lldb::eFunctionNameTypeSelector
}) {
1141 if (name_type_mask
& type
) {
1142 auto map
= GetNameToSymbolIndexMap(type
);
1144 const UniqueCStringMap
<uint32_t>::Entry
*match
;
1145 for (match
= map
.FindFirstValueForName(name
); match
!= nullptr;
1146 match
= map
.FindNextValueForName(match
)) {
1147 symbol_indexes
.push_back(match
->value
);
1152 if (!symbol_indexes
.empty()) {
1153 llvm::sort(symbol_indexes
);
1154 symbol_indexes
.erase(
1155 std::unique(symbol_indexes
.begin(), symbol_indexes
.end()),
1156 symbol_indexes
.end());
1157 SymbolIndicesToSymbolContextList(symbol_indexes
, sc_list
);
1161 const Symbol
*Symtab::GetParent(Symbol
*child_symbol
) const {
1162 uint32_t child_idx
= GetIndexForSymbol(child_symbol
);
1163 if (child_idx
!= UINT32_MAX
&& child_idx
> 0) {
1164 for (uint32_t idx
= child_idx
- 1; idx
!= UINT32_MAX
; --idx
) {
1165 const Symbol
*symbol
= SymbolAtIndex(idx
);
1166 const uint32_t sibling_idx
= symbol
->GetSiblingIndex();
1167 if (sibling_idx
!= UINT32_MAX
&& sibling_idx
> child_idx
)
1174 std::string
Symtab::GetCacheKey() {
1176 llvm::raw_string_ostream
strm(key
);
1177 // Symbol table can come from different object files for the same module. A
1178 // module can have one object file as the main executable and might have
1179 // another object file in a separate symbol file.
1180 strm
<< m_objfile
->GetModule()->GetCacheKey() << "-symtab-"
1181 << llvm::format_hex(m_objfile
->GetCacheHash(), 10);
1185 void Symtab::SaveToCache() {
1186 DataFileCache
*cache
= Module::GetIndexCache();
1188 return; // Caching is not enabled.
1189 InitNameIndexes(); // Init the name indexes so we can cache them as well.
1190 const auto byte_order
= endian::InlHostByteOrder();
1191 DataEncoder
file(byte_order
, /*addr_size=*/8);
1192 // Encode will return false if the symbol table's object file doesn't have
1193 // anything to make a signature from.
1195 if (cache
->SetCachedData(GetCacheKey(), file
.GetData()))
1196 SetWasSavedToCache();
1199 constexpr llvm::StringLiteral
kIdentifierCStrMap("CMAP");
1201 static void EncodeCStrMap(DataEncoder
&encoder
, ConstStringTable
&strtab
,
1202 const UniqueCStringMap
<uint32_t> &cstr_map
) {
1203 encoder
.AppendData(kIdentifierCStrMap
);
1204 encoder
.AppendU32(cstr_map
.GetSize());
1205 for (const auto &entry
: cstr_map
) {
1206 // Make sure there are no empty strings.
1207 assert((bool)entry
.cstring
);
1208 encoder
.AppendU32(strtab
.Add(entry
.cstring
));
1209 encoder
.AppendU32(entry
.value
);
1213 bool DecodeCStrMap(const DataExtractor
&data
, lldb::offset_t
*offset_ptr
,
1214 const StringTableReader
&strtab
,
1215 UniqueCStringMap
<uint32_t> &cstr_map
) {
1216 llvm::StringRef
identifier((const char *)data
.GetData(offset_ptr
, 4), 4);
1217 if (identifier
!= kIdentifierCStrMap
)
1219 const uint32_t count
= data
.GetU32(offset_ptr
);
1220 cstr_map
.Reserve(count
);
1221 for (uint32_t i
=0; i
<count
; ++i
)
1223 llvm::StringRef
str(strtab
.Get(data
.GetU32(offset_ptr
)));
1224 uint32_t value
= data
.GetU32(offset_ptr
);
1225 // No empty strings in the name indexes in Symtab
1228 cstr_map
.Append(ConstString(str
), value
);
1230 // We must sort the UniqueCStringMap after decoding it since it is a vector
1231 // of UniqueCStringMap::Entry objects which contain a ConstString and type T.
1232 // ConstString objects are sorted by "const char *" and then type T and
1233 // the "const char *" are point values that will depend on the order in which
1234 // ConstString objects are created and in which of the 256 string pools they
1235 // are created in. So after we decode all of the entries, we must sort the
1236 // name map to ensure name lookups succeed. If we encode and decode within
1237 // the same process we wouldn't need to sort, so unit testing didn't catch
1238 // this issue when first checked in.
1243 constexpr llvm::StringLiteral
kIdentifierSymbolTable("SYMB");
1244 constexpr uint32_t CURRENT_CACHE_VERSION
= 1;
1246 /// The encoding format for the symbol table is as follows:
1248 /// Signature signature;
1249 /// ConstStringTable strtab;
1250 /// Identifier four character code: 'SYMB'
1251 /// uint32_t version;
1252 /// uint32_t num_symbols;
1253 /// Symbol symbols[num_symbols];
1254 /// uint8_t num_cstr_maps;
1255 /// UniqueCStringMap<uint32_t> cstr_maps[num_cstr_maps]
1256 bool Symtab::Encode(DataEncoder
&encoder
) const {
1257 // Name indexes must be computed before calling this function.
1258 assert(m_name_indexes_computed
);
1260 // Encode the object file's signature
1261 CacheSignature
signature(m_objfile
);
1262 if (!signature
.Encode(encoder
))
1264 ConstStringTable strtab
;
1266 // Encoder the symbol table into a separate encoder first. This allows us
1267 // gather all of the strings we willl need in "strtab" as we will need to
1268 // write the string table out before the symbol table.
1269 DataEncoder
symtab_encoder(encoder
.GetByteOrder(),
1270 encoder
.GetAddressByteSize());
1271 symtab_encoder
.AppendData(kIdentifierSymbolTable
);
1272 // Encode the symtab data version.
1273 symtab_encoder
.AppendU32(CURRENT_CACHE_VERSION
);
1274 // Encode the number of symbols.
1275 symtab_encoder
.AppendU32(m_symbols
.size());
1276 // Encode the symbol data for all symbols.
1277 for (const auto &symbol
: m_symbols
)
1278 symbol
.Encode(symtab_encoder
, strtab
);
1280 // Emit a byte for how many C string maps we emit. We will fix this up after
1281 // we emit the C string maps since we skip emitting C string maps if they are
1283 size_t num_cmaps_offset
= symtab_encoder
.GetByteSize();
1284 uint8_t num_cmaps
= 0;
1285 symtab_encoder
.AppendU8(0);
1286 for (const auto &pair
: m_name_to_symbol_indices
) {
1287 if (pair
.second
.IsEmpty())
1290 symtab_encoder
.AppendU8(pair
.first
);
1291 EncodeCStrMap(symtab_encoder
, strtab
, pair
.second
);
1294 symtab_encoder
.PutU8(num_cmaps_offset
, num_cmaps
);
1296 // Now that all strings have been gathered, we will emit the string table.
1297 strtab
.Encode(encoder
);
1298 // Followed by the symbol table data.
1299 encoder
.AppendData(symtab_encoder
.GetData());
1303 bool Symtab::Decode(const DataExtractor
&data
, lldb::offset_t
*offset_ptr
,
1304 bool &signature_mismatch
) {
1305 signature_mismatch
= false;
1306 CacheSignature signature
;
1307 StringTableReader strtab
;
1308 { // Scope for "elapsed" object below so it can measure the time parse.
1309 ElapsedTime
elapsed(m_objfile
->GetModule()->GetSymtabParseTime());
1310 if (!signature
.Decode(data
, offset_ptr
))
1312 if (CacheSignature(m_objfile
) != signature
) {
1313 signature_mismatch
= true;
1316 // We now decode the string table for all strings in the data cache file.
1317 if (!strtab
.Decode(data
, offset_ptr
))
1320 // And now we can decode the symbol table with string table we just decoded.
1321 llvm::StringRef
identifier((const char *)data
.GetData(offset_ptr
, 4), 4);
1322 if (identifier
!= kIdentifierSymbolTable
)
1324 const uint32_t version
= data
.GetU32(offset_ptr
);
1325 if (version
!= CURRENT_CACHE_VERSION
)
1327 const uint32_t num_symbols
= data
.GetU32(offset_ptr
);
1328 if (num_symbols
== 0)
1330 m_symbols
.resize(num_symbols
);
1331 SectionList
*sections
= m_objfile
->GetModule()->GetSectionList();
1332 for (uint32_t i
=0; i
<num_symbols
; ++i
) {
1333 if (!m_symbols
[i
].Decode(data
, offset_ptr
, sections
, strtab
))
1338 { // Scope for "elapsed" object below so it can measure the time to index.
1339 ElapsedTime
elapsed(m_objfile
->GetModule()->GetSymtabIndexTime());
1340 const uint8_t num_cstr_maps
= data
.GetU8(offset_ptr
);
1341 for (uint8_t i
=0; i
<num_cstr_maps
; ++i
) {
1342 uint8_t type
= data
.GetU8(offset_ptr
);
1343 UniqueCStringMap
<uint32_t> &cstr_map
=
1344 GetNameToSymbolIndexMap((lldb::FunctionNameType
)type
);
1345 if (!DecodeCStrMap(data
, offset_ptr
, strtab
, cstr_map
))
1348 m_name_indexes_computed
= true;
1353 bool Symtab::LoadFromCache() {
1354 DataFileCache
*cache
= Module::GetIndexCache();
1358 std::unique_ptr
<llvm::MemoryBuffer
> mem_buffer_up
=
1359 cache
->GetCachedData(GetCacheKey());
1362 DataExtractor
data(mem_buffer_up
->getBufferStart(),
1363 mem_buffer_up
->getBufferSize(),
1364 m_objfile
->GetByteOrder(),
1365 m_objfile
->GetAddressByteSize());
1366 bool signature_mismatch
= false;
1367 lldb::offset_t offset
= 0;
1368 const bool result
= Decode(data
, &offset
, signature_mismatch
);
1369 if (signature_mismatch
)
1370 cache
->RemoveCacheFile(GetCacheKey());
1372 SetWasLoadedFromCache();