//===-- Symtab.cpp --------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include <map>
#include <set>

#include "lldb/Core/DataFileCache.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/RichManglingContext.h"
#include "lldb/Core/Section.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/Symtab.h"
#include "lldb/Target/Language.h"
#include "lldb/Utility/DataEncoder.h"
#include "lldb/Utility/Endian.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/Timer.h"

#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DJB.h"

using namespace lldb;
using namespace lldb_private;

Symtab::Symtab(ObjectFile *objfile)
    : m_objfile(objfile), m_symbols(), m_file_addr_to_index(*this),
      m_name_to_symbol_indices(), m_mutex(),
      m_file_addr_to_index_computed(false), m_name_indexes_computed(false),
      m_loaded_from_cache(false), m_saved_to_cache(false) {
  m_name_to_symbol_indices.emplace(std::make_pair(
      lldb::eFunctionNameTypeNone, UniqueCStringMap<uint32_t>()));
  m_name_to_symbol_indices.emplace(std::make_pair(
      lldb::eFunctionNameTypeBase, UniqueCStringMap<uint32_t>()));
  m_name_to_symbol_indices.emplace(std::make_pair(
      lldb::eFunctionNameTypeMethod, UniqueCStringMap<uint32_t>()));
  m_name_to_symbol_indices.emplace(std::make_pair(
      lldb::eFunctionNameTypeSelector, UniqueCStringMap<uint32_t>()));
}

Symtab::~Symtab() = default;

void Symtab::Reserve(size_t count) {
  // Clients should grab the mutex from this symbol table and lock it manually
  // when calling this function to avoid performance issues.
  m_symbols.reserve(count);
}

Symbol *Symtab::Resize(size_t count) {
  // Clients should grab the mutex from this symbol table and lock it manually
  // when calling this function to avoid performance issues.
  m_symbols.resize(count);
  return m_symbols.empty() ? nullptr : &m_symbols[0];
}

uint32_t Symtab::AddSymbol(const Symbol &symbol) {
  // Clients should grab the mutex from this symbol table and lock it manually
  // when calling this function to avoid performance issues.
  uint32_t symbol_idx = m_symbols.size();
  auto &name_to_index = GetNameToSymbolIndexMap(lldb::eFunctionNameTypeNone);
  name_to_index.Clear();
  m_file_addr_to_index.Clear();
  m_symbols.push_back(symbol);
  m_file_addr_to_index_computed = false;
  m_name_indexes_computed = false;
  return symbol_idx;
}

size_t Symtab::GetNumSymbols() const {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  return m_symbols.size();
}

void Symtab::SectionFileAddressesChanged() {
  m_file_addr_to_index.Clear();
  m_file_addr_to_index_computed = false;
}

void Symtab::Dump(Stream *s, Target *target, SortOrder sort_order,
                  Mangled::NamePreference name_preference) {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);

  //    s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
  s->Indent();
  const FileSpec &file_spec = m_objfile->GetFileSpec();
  const char *object_name = nullptr;
  if (m_objfile->GetModule())
    object_name = m_objfile->GetModule()->GetObjectName().GetCString();

  if (file_spec)
    s->Printf("Symtab, file = %s%s%s%s, num_symbols = %" PRIu64,
              file_spec.GetPath().c_str(), object_name ? "(" : "",
              object_name ? object_name : "", object_name ? ")" : "",
              (uint64_t)m_symbols.size());
  else
    s->Printf("Symtab, num_symbols = %" PRIu64 "", (uint64_t)m_symbols.size());

  if (!m_symbols.empty()) {
    switch (sort_order) {
    case eSortOrderNone: {
      s->PutCString(":\n");
      DumpSymbolHeader(s);
      const_iterator begin = m_symbols.begin();
      const_iterator end = m_symbols.end();
      for (const_iterator pos = m_symbols.begin(); pos != end; ++pos) {
        s->Indent();
        pos->Dump(s, target, std::distance(begin, pos), name_preference);
      }
    }
    break;

    case eSortOrderByName: {
      // Although we maintain a lookup by exact name map, the table isn't
      // sorted by name. So we must make the ordered symbol list up ourselves.
      s->PutCString(" (sorted by name):\n");
      DumpSymbolHeader(s);

      std::multimap<llvm::StringRef, const Symbol *> name_map;
      for (const Symbol &symbol : m_symbols)
        name_map.emplace(symbol.GetName().GetStringRef(), &symbol);

      for (const auto &name_to_symbol : name_map) {
        const Symbol *symbol = name_to_symbol.second;
        s->Indent();
        symbol->Dump(s, target, symbol - &m_symbols[0], name_preference);
      }
    } break;

    case eSortOrderBySize: {
      s->PutCString(" (sorted by size):\n");
      DumpSymbolHeader(s);

      std::multimap<size_t, const Symbol *, std::greater<size_t>> size_map;
      for (const Symbol &symbol : m_symbols)
        size_map.emplace(symbol.GetByteSize(), &symbol);

      size_t idx = 0;
      for (const auto &size_to_symbol : size_map) {
        const Symbol *symbol = size_to_symbol.second;
        s->Indent();
        symbol->Dump(s, target, idx++, name_preference);
      }
    } break;

    case eSortOrderByAddress:
      s->PutCString(" (sorted by address):\n");
      DumpSymbolHeader(s);
      if (!m_file_addr_to_index_computed)
        InitAddressIndexes();
      const size_t num_entries = m_file_addr_to_index.GetSize();
      for (size_t i = 0; i < num_entries; ++i) {
        s->Indent();
        const uint32_t symbol_idx = m_file_addr_to_index.GetEntryRef(i).data;
        m_symbols[symbol_idx].Dump(s, target, symbol_idx, name_preference);
      }
      break;
    }
  } else {
    s->PutCString("\n");
  }
}

void Symtab::Dump(Stream *s, Target *target, std::vector<uint32_t> &indexes,
                  Mangled::NamePreference name_preference) const {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);

  const size_t num_symbols = GetNumSymbols();
  // s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
  s->Indent();
  s->Printf("Symtab %" PRIu64 " symbol indexes (%" PRIu64 " symbols total):\n",
            (uint64_t)indexes.size(), (uint64_t)m_symbols.size());
  s->IndentMore();

  if (!indexes.empty()) {
    std::vector<uint32_t>::const_iterator pos;
    std::vector<uint32_t>::const_iterator end = indexes.end();
    DumpSymbolHeader(s);
    for (pos = indexes.begin(); pos != end; ++pos) {
      size_t idx = *pos;
      if (idx < num_symbols) {
        s->Indent();
        m_symbols[idx].Dump(s, target, idx, name_preference);
      }
    }
  }
  s->IndentLess();
}

void Symtab::DumpSymbolHeader(Stream *s) {
  s->Indent("               Debug symbol\n");
  s->Indent("               |Synthetic symbol\n");
  s->Indent("               ||Externally Visible\n");
  s->Indent("               |||\n");
  s->Indent("Index   UserID DSX Type            File Address/Value Load "
            "Address       Size               Flags      Name\n");
  s->Indent("------- ------ --- --------------- ------------------ "
            "------------------ ------------------ ---------- "
            "----------------------------------\n");
}

static int CompareSymbolID(const void *key, const void *p) {
  const user_id_t match_uid = *(const user_id_t *)key;
  const user_id_t symbol_uid = ((const Symbol *)p)->GetID();
  if (match_uid < symbol_uid)
    return -1;
  if (match_uid > symbol_uid)
    return 1;
  return 0;
}

Symbol *Symtab::FindSymbolByID(lldb::user_id_t symbol_uid) const {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);

  Symbol *symbol =
      (Symbol *)::bsearch(&symbol_uid, &m_symbols[0], m_symbols.size(),
                          sizeof(m_symbols[0]), CompareSymbolID);
  return symbol;
}

Symbol *Symtab::SymbolAtIndex(size_t idx) {
  // Clients should grab the mutex from this symbol table and lock it manually
  // when calling this function to avoid performance issues.
  if (idx < m_symbols.size())
    return &m_symbols[idx];
  return nullptr;
}

const Symbol *Symtab::SymbolAtIndex(size_t idx) const {
  // Clients should grab the mutex from this symbol table and lock it manually
  // when calling this function to avoid performance issues.
  if (idx < m_symbols.size())
    return &m_symbols[idx];
  return nullptr;
}

static bool lldb_skip_name(llvm::StringRef mangled,
                           Mangled::ManglingScheme scheme) {
  switch (scheme) {
  case Mangled::eManglingSchemeItanium: {
    if (mangled.size() < 3 || !mangled.starts_with("_Z"))
      return true;

    // Avoid the following types of symbols in the index.
    switch (mangled[2]) {
    case 'G': // guard variables
    case 'T': // virtual tables, VTT structures, typeinfo structures + names
    case 'Z': // named local entities (if we eventually handle
              // eSymbolTypeData, we will want this back)
      return true;

    default:
      break;
    }

    // Include this name in the index.
    return false;
  }

  // No filters for this scheme yet. Include all names in indexing.
  case Mangled::eManglingSchemeMSVC:
  case Mangled::eManglingSchemeRustV0:
  case Mangled::eManglingSchemeD:
  case Mangled::eManglingSchemeSwift:
    return false;

  // Don't try and demangle things we can't categorize.
  case Mangled::eManglingSchemeNone:
    return true;
  }
  llvm_unreachable("unknown scheme!");
}

void Symtab::InitNameIndexes() {
  // Protected function, no need to lock mutex...
  if (!m_name_indexes_computed) {
    m_name_indexes_computed = true;
    ElapsedTime elapsed(m_objfile->GetModule()->GetSymtabIndexTime());
    LLDB_SCOPED_TIMER();

    // Collect all loaded language plugins.
    std::vector<Language *> languages;
    Language::ForEach([&languages](Language *l) {
      languages.push_back(l);
      return IterationAction::Continue;
    });

    auto &name_to_index = GetNameToSymbolIndexMap(lldb::eFunctionNameTypeNone);
    auto &basename_to_index =
        GetNameToSymbolIndexMap(lldb::eFunctionNameTypeBase);
    auto &method_to_index =
        GetNameToSymbolIndexMap(lldb::eFunctionNameTypeMethod);
    auto &selector_to_index =
        GetNameToSymbolIndexMap(lldb::eFunctionNameTypeSelector);
    // Create the name index vector to be able to quickly search by name
    const size_t num_symbols = m_symbols.size();
    name_to_index.Reserve(num_symbols);

    // The "const char *" in "class_contexts" and backlog::value_type::second
    // must come from a ConstString::GetCString()
    std::set<const char *> class_contexts;
    std::vector<std::pair<NameToIndexMap::Entry, const char *>> backlog;
    backlog.reserve(num_symbols / 2);

    // Instantiation of the demangler is expensive, so better use a single one
    // for all entries during batch processing.
    RichManglingContext rmc;
    for (uint32_t value = 0; value < num_symbols; ++value) {
      Symbol *symbol = &m_symbols[value];

      // Don't let trampolines get into the lookup by name map If we ever need
      // the trampoline symbols to be searchable by name we can remove this and
      // then possibly add a new bool to any of the Symtab functions that
      // lookup symbols by name to indicate if they want trampolines. We also
      // don't want any synthetic symbols with auto generated names in the
      // name lookups.
      if (symbol->IsTrampoline() || symbol->IsSyntheticWithAutoGeneratedName())
        continue;

      // If the symbol's name string matched a Mangled::ManglingScheme, it is
      // stored in the mangled field.
      Mangled &mangled = symbol->GetMangled();
      if (ConstString name = mangled.GetMangledName()) {
        name_to_index.Append(name, value);

        if (symbol->ContainsLinkerAnnotations()) {
          // If the symbol has linker annotations, also add the version without
          // the annotations.
          ConstString stripped = ConstString(
              m_objfile->StripLinkerSymbolAnnotations(name.GetStringRef()));
          name_to_index.Append(stripped, value);
        }

        const SymbolType type = symbol->GetType();
        if (type == eSymbolTypeCode || type == eSymbolTypeResolver) {
          if (mangled.GetRichManglingInfo(rmc, lldb_skip_name)) {
            RegisterMangledNameEntry(value, class_contexts, backlog, rmc);
            continue;
          }
        }
      }

      // Symbol name strings that didn't match a Mangled::ManglingScheme, are
      // stored in the demangled field.
      if (ConstString name = mangled.GetDemangledName()) {
        name_to_index.Append(name, value);

        if (symbol->ContainsLinkerAnnotations()) {
          // If the symbol has linker annotations, also add the version without
          // the annotations.
          name = ConstString(
              m_objfile->StripLinkerSymbolAnnotations(name.GetStringRef()));
          name_to_index.Append(name, value);
        }

        // If the demangled name turns out to be an ObjC name, and is a category
        // name, add the version without categories to the index too.
        for (Language *lang : languages) {
          for (auto variant : lang->GetMethodNameVariants(name)) {
            if (variant.GetType() & lldb::eFunctionNameTypeSelector)
              selector_to_index.Append(variant.GetName(), value);
            else if (variant.GetType() & lldb::eFunctionNameTypeFull)
              name_to_index.Append(variant.GetName(), value);
            else if (variant.GetType() & lldb::eFunctionNameTypeMethod)
              method_to_index.Append(variant.GetName(), value);
            else if (variant.GetType() & lldb::eFunctionNameTypeBase)
              basename_to_index.Append(variant.GetName(), value);
          }
        }
      }
    }

    for (const auto &record : backlog) {
      RegisterBacklogEntry(record.first, record.second, class_contexts);
    }

    name_to_index.Sort();
    name_to_index.SizeToFit();
    selector_to_index.Sort();
    selector_to_index.SizeToFit();
    basename_to_index.Sort();
    basename_to_index.SizeToFit();
    method_to_index.Sort();
    method_to_index.SizeToFit();
  }
}

void Symtab::RegisterMangledNameEntry(
    uint32_t value, std::set<const char *> &class_contexts,
    std::vector<std::pair<NameToIndexMap::Entry, const char *>> &backlog,
    RichManglingContext &rmc) {
  // Only register functions that have a base name.
  llvm::StringRef base_name = rmc.ParseFunctionBaseName();
  if (base_name.empty())
    return;

  // The base name will be our entry's name.
  NameToIndexMap::Entry entry(ConstString(base_name), value);
  llvm::StringRef decl_context = rmc.ParseFunctionDeclContextName();

  // Register functions with no context.
  if (decl_context.empty()) {
    // This has to be a basename
    auto &basename_to_index =
        GetNameToSymbolIndexMap(lldb::eFunctionNameTypeBase);
    basename_to_index.Append(entry);
    // If there is no context (no namespaces or class scopes that come before
    // the function name) then this also could be a fullname.
    auto &name_to_index = GetNameToSymbolIndexMap(lldb::eFunctionNameTypeNone);
    name_to_index.Append(entry);
    return;
  }

  // Make sure we have a pool-string pointer and see if we already know the
  // context name.
  const char *decl_context_ccstr = ConstString(decl_context).GetCString();
  auto it = class_contexts.find(decl_context_ccstr);

  auto &method_to_index =
      GetNameToSymbolIndexMap(lldb::eFunctionNameTypeMethod);
  // Register constructors and destructors. They are methods and create
  // declaration contexts.
  if (rmc.IsCtorOrDtor()) {
    method_to_index.Append(entry);
    if (it == class_contexts.end())
      class_contexts.insert(it, decl_context_ccstr);
    return;
  }

  // Register regular methods with a known declaration context.
  if (it != class_contexts.end()) {
    method_to_index.Append(entry);
    return;
  }

  // Regular methods in unknown declaration contexts are put to the backlog. We
  // will revisit them once we processed all remaining symbols.
  backlog.push_back(std::make_pair(entry, decl_context_ccstr));
}

void Symtab::RegisterBacklogEntry(
    const NameToIndexMap::Entry &entry, const char *decl_context,
    const std::set<const char *> &class_contexts) {
  auto &method_to_index =
      GetNameToSymbolIndexMap(lldb::eFunctionNameTypeMethod);
  auto it = class_contexts.find(decl_context);
  if (it != class_contexts.end()) {
    method_to_index.Append(entry);
  } else {
    // If we got here, we have something that had a context (was inside
    // a namespace or class) yet we don't know the entry
    method_to_index.Append(entry);
    auto &basename_to_index =
        GetNameToSymbolIndexMap(lldb::eFunctionNameTypeBase);
    basename_to_index.Append(entry);
  }
}

void Symtab::PreloadSymbols() {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  InitNameIndexes();
}

void Symtab::AppendSymbolNamesToMap(const IndexCollection &indexes,
                                    bool add_demangled, bool add_mangled,
                                    NameToIndexMap &name_to_index_map) const {
  LLDB_SCOPED_TIMER();
  if (add_demangled || add_mangled) {
    std::lock_guard<std::recursive_mutex> guard(m_mutex);

    // Create the name index vector to be able to quickly search by name
    const size_t num_indexes = indexes.size();
    for (size_t i = 0; i < num_indexes; ++i) {
      uint32_t value = indexes[i];
      assert(i < m_symbols.size());
      const Symbol *symbol = &m_symbols[value];

      const Mangled &mangled = symbol->GetMangled();
      if (add_demangled) {
        if (ConstString name = mangled.GetDemangledName())
          name_to_index_map.Append(name, value);
      }

      if (add_mangled) {
        if (ConstString name = mangled.GetMangledName())
          name_to_index_map.Append(name, value);
      }
    }
  }
}

uint32_t Symtab::AppendSymbolIndexesWithType(SymbolType symbol_type,
                                             std::vector<uint32_t> &indexes,
                                             uint32_t start_idx,
                                             uint32_t end_index) const {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);

  uint32_t prev_size = indexes.size();

  const uint32_t count = std::min<uint32_t>(m_symbols.size(), end_index);

  for (uint32_t i = start_idx; i < count; ++i) {
    if (symbol_type == eSymbolTypeAny || m_symbols[i].GetType() == symbol_type)
      indexes.push_back(i);
  }

  return indexes.size() - prev_size;
}

uint32_t Symtab::AppendSymbolIndexesWithTypeAndFlagsValue(
    SymbolType symbol_type, uint32_t flags_value,
    std::vector<uint32_t> &indexes, uint32_t start_idx,
    uint32_t end_index) const {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);

  uint32_t prev_size = indexes.size();

  const uint32_t count = std::min<uint32_t>(m_symbols.size(), end_index);

  for (uint32_t i = start_idx; i < count; ++i) {
    if ((symbol_type == eSymbolTypeAny ||
         m_symbols[i].GetType() == symbol_type) &&
        m_symbols[i].GetFlags() == flags_value)
      indexes.push_back(i);
  }

  return indexes.size() - prev_size;
}

uint32_t Symtab::AppendSymbolIndexesWithType(SymbolType symbol_type,
                                             Debug symbol_debug_type,
                                             Visibility symbol_visibility,
                                             std::vector<uint32_t> &indexes,
                                             uint32_t start_idx,
                                             uint32_t end_index) const {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);

  uint32_t prev_size = indexes.size();

  const uint32_t count = std::min<uint32_t>(m_symbols.size(), end_index);

  for (uint32_t i = start_idx; i < count; ++i) {
    if (symbol_type == eSymbolTypeAny ||
        m_symbols[i].GetType() == symbol_type) {
      if (CheckSymbolAtIndex(i, symbol_debug_type, symbol_visibility))
        indexes.push_back(i);
    }
  }

  return indexes.size() - prev_size;
}

uint32_t Symtab::GetIndexForSymbol(const Symbol *symbol) const {
  if (!m_symbols.empty()) {
    const Symbol *first_symbol = &m_symbols[0];
    if (symbol >= first_symbol && symbol < first_symbol + m_symbols.size())
      return symbol - first_symbol;
  }
  return UINT32_MAX;
}

struct SymbolSortInfo {
  const bool sort_by_load_addr;
  const Symbol *symbols;
};

namespace {
struct SymbolIndexComparator {
  const std::vector<Symbol> &symbols;
  std::vector<lldb::addr_t> &addr_cache;

  // Getting from the symbol to the Address to the File Address involves some
  // work. Since there are potentially many symbols here, and we're using this
  // for sorting so we're going to be computing the address many times, cache
  // that in addr_cache. The array passed in has to be the same size as the
  // symbols array passed into the member variable symbols, and should be
  // initialized with LLDB_INVALID_ADDRESS.
  // NOTE: You have to make addr_cache externally and pass it in because
  // std::stable_sort
  // makes copies of the comparator it is initially passed in, and you end up
  // spending huge amounts of time copying this array...

  SymbolIndexComparator(const std::vector<Symbol> &s,
                        std::vector<lldb::addr_t> &a)
      : symbols(s), addr_cache(a) {
    assert(symbols.size() == addr_cache.size());
  }
  bool operator()(uint32_t index_a, uint32_t index_b) {
    addr_t value_a = addr_cache[index_a];
    if (value_a == LLDB_INVALID_ADDRESS) {
      value_a = symbols[index_a].GetAddressRef().GetFileAddress();
      addr_cache[index_a] = value_a;
    }

    addr_t value_b = addr_cache[index_b];
    if (value_b == LLDB_INVALID_ADDRESS) {
      value_b = symbols[index_b].GetAddressRef().GetFileAddress();
      addr_cache[index_b] = value_b;
    }

    if (value_a == value_b) {
      // The if the values are equal, use the original symbol user ID
      lldb::user_id_t uid_a = symbols[index_a].GetID();
      lldb::user_id_t uid_b = symbols[index_b].GetID();
      if (uid_a < uid_b)
        return true;
      if (uid_a > uid_b)
        return false;
      return false;
    } else if (value_a < value_b)
      return true;

    return false;
  }
};
}

void Symtab::SortSymbolIndexesByValue(std::vector<uint32_t> &indexes,
                                      bool remove_duplicates) const {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  LLDB_SCOPED_TIMER();
  // No need to sort if we have zero or one items...
  if (indexes.size() <= 1)
    return;

  // Sort the indexes in place using std::stable_sort.
  // NOTE: The use of std::stable_sort instead of llvm::sort here is strictly
  // for performance, not correctness.  The indexes vector tends to be "close"
  // to sorted, which the stable sort handles better.

  std::vector<lldb::addr_t> addr_cache(m_symbols.size(), LLDB_INVALID_ADDRESS);

  SymbolIndexComparator comparator(m_symbols, addr_cache);
  llvm::stable_sort(indexes, comparator);

  // Remove any duplicates if requested
  if (remove_duplicates) {
    auto last = llvm::unique(indexes);
    indexes.erase(last, indexes.end());
  }
}

uint32_t Symtab::GetNameIndexes(ConstString symbol_name,
                                std::vector<uint32_t> &indexes) {
  auto &name_to_index = GetNameToSymbolIndexMap(lldb::eFunctionNameTypeNone);
  const uint32_t count = name_to_index.GetValues(symbol_name, indexes);
  if (count)
    return count;
  // Synthetic symbol names are not added to the name indexes, but they start
  // with a prefix and end with the symbol file address. This allows users to
  // find these symbols without having to add them to the name indexes. These
  // queries will not happen very often since the names don't mean anything, so
  // performance is not paramount in this case.
  llvm::StringRef name = symbol_name.GetStringRef();
  // String the synthetic prefix if the name starts with it.
  if (!name.consume_front(Symbol::GetSyntheticSymbolPrefix()))
    return 0; // Not a synthetic symbol name

  // Extract the file address from the symbol name
  unsigned long long file_address = 0;
  if (getAsUnsignedInteger(name, /*Radix=*/16, file_address))
    return 0; // Failed to extract the user ID as an integer

  const Symbol *symbol =
      FindSymbolAtFileAddress(static_cast<addr_t>(file_address));
  if (symbol == nullptr)
    return 0;
  const uint32_t symbol_idx = GetIndexForSymbol(symbol);
  if (symbol_idx == UINT32_MAX)
    return 0;
  indexes.push_back(symbol_idx);
  return 1;
}

uint32_t Symtab::AppendSymbolIndexesWithName(ConstString symbol_name,
                                             std::vector<uint32_t> &indexes) {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);

  if (symbol_name) {
    if (!m_name_indexes_computed)
      InitNameIndexes();

    return GetNameIndexes(symbol_name, indexes);
  }
  return 0;
}

uint32_t Symtab::AppendSymbolIndexesWithName(ConstString symbol_name,
                                             Debug symbol_debug_type,
                                             Visibility symbol_visibility,
                                             std::vector<uint32_t> &indexes) {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);

  LLDB_SCOPED_TIMER();
  if (symbol_name) {
    const size_t old_size = indexes.size();
    if (!m_name_indexes_computed)
      InitNameIndexes();

    std::vector<uint32_t> all_name_indexes;
    const size_t name_match_count =
        GetNameIndexes(symbol_name, all_name_indexes);
    for (size_t i = 0; i < name_match_count; ++i) {
      if (CheckSymbolAtIndex(all_name_indexes[i], symbol_debug_type,
                             symbol_visibility))
        indexes.push_back(all_name_indexes[i]);
    }
    return indexes.size() - old_size;
  }
  return 0;
}

uint32_t
Symtab::AppendSymbolIndexesWithNameAndType(ConstString symbol_name,
                                           SymbolType symbol_type,
                                           std::vector<uint32_t> &indexes) {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);

  if (AppendSymbolIndexesWithName(symbol_name, indexes) > 0 &&
      symbol_type != eSymbolTypeAny) {
    llvm::erase_if(indexes, [this, symbol_type](uint32_t index) {
      return m_symbols[index].GetType() != symbol_type;
    });
  }
  return indexes.size();
}

uint32_t Symtab::AppendSymbolIndexesWithNameAndType(
    ConstString symbol_name, SymbolType symbol_type,
    Debug symbol_debug_type, Visibility symbol_visibility,
    std::vector<uint32_t> &indexes) {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);

  if (AppendSymbolIndexesWithName(symbol_name, symbol_debug_type,
                                  symbol_visibility, indexes) > 0 &&
      symbol_type != eSymbolTypeAny) {
    llvm::erase_if(indexes, [this, symbol_type](uint32_t index) {
      return m_symbols[index].GetType() != symbol_type;
    });
  }
  return indexes.size();
}

uint32_t Symtab::AppendSymbolIndexesMatchingRegExAndType(
    const RegularExpression &regexp, SymbolType symbol_type,
    std::vector<uint32_t> &indexes, Mangled::NamePreference name_preference) {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);

  uint32_t prev_size = indexes.size();
  uint32_t sym_end = m_symbols.size();

  for (uint32_t i = 0; i < sym_end; i++) {
    if (symbol_type == eSymbolTypeAny ||
        m_symbols[i].GetType() == symbol_type) {
      const char *name =
          m_symbols[i].GetMangled().GetName(name_preference).AsCString();
      if (name) {
        if (regexp.Execute(name))
          indexes.push_back(i);
      }
    }
  }
  return indexes.size() - prev_size;
}

uint32_t Symtab::AppendSymbolIndexesMatchingRegExAndType(
    const RegularExpression &regexp, SymbolType symbol_type,
    Debug symbol_debug_type, Visibility symbol_visibility,
    std::vector<uint32_t> &indexes, Mangled::NamePreference name_preference) {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);

  uint32_t prev_size = indexes.size();
  uint32_t sym_end = m_symbols.size();

  for (uint32_t i = 0; i < sym_end; i++) {
    if (symbol_type == eSymbolTypeAny ||
        m_symbols[i].GetType() == symbol_type) {
      if (!CheckSymbolAtIndex(i, symbol_debug_type, symbol_visibility))
        continue;

      const char *name =
          m_symbols[i].GetMangled().GetName(name_preference).AsCString();
      if (name) {
        if (regexp.Execute(name))
          indexes.push_back(i);
      }
    }
  }
  return indexes.size() - prev_size;
}

Symbol *Symtab::FindSymbolWithType(SymbolType symbol_type,
                                   Debug symbol_debug_type,
                                   Visibility symbol_visibility,
                                   uint32_t &start_idx) {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);

  const size_t count = m_symbols.size();
  for (size_t idx = start_idx; idx < count; ++idx) {
    if (symbol_type == eSymbolTypeAny ||
        m_symbols[idx].GetType() == symbol_type) {
      if (CheckSymbolAtIndex(idx, symbol_debug_type, symbol_visibility)) {
        start_idx = idx;
        return &m_symbols[idx];
      }
    }
  }
  return nullptr;
}

void
Symtab::FindAllSymbolsWithNameAndType(ConstString name,
                                      SymbolType symbol_type,
                                      std::vector<uint32_t> &symbol_indexes) {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);

  // Initialize all of the lookup by name indexes before converting NAME to a
  // uniqued string NAME_STR below.
  if (!m_name_indexes_computed)
    InitNameIndexes();

  if (name) {
    // The string table did have a string that matched, but we need to check
    // the symbols and match the symbol_type if any was given.
    AppendSymbolIndexesWithNameAndType(name, symbol_type, symbol_indexes);
  }
}

void Symtab::FindAllSymbolsWithNameAndType(
    ConstString name, SymbolType symbol_type, Debug symbol_debug_type,
    Visibility symbol_visibility, std::vector<uint32_t> &symbol_indexes) {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);

  LLDB_SCOPED_TIMER();
  // Initialize all of the lookup by name indexes before converting NAME to a
  // uniqued string NAME_STR below.
  if (!m_name_indexes_computed)
    InitNameIndexes();

  if (name) {
    // The string table did have a string that matched, but we need to check
    // the symbols and match the symbol_type if any was given.
    AppendSymbolIndexesWithNameAndType(name, symbol_type, symbol_debug_type,
                                       symbol_visibility, symbol_indexes);
  }
}

void Symtab::FindAllSymbolsMatchingRexExAndType(
    const RegularExpression &regex, SymbolType symbol_type,
    Debug symbol_debug_type, Visibility symbol_visibility,
    std::vector<uint32_t> &symbol_indexes,
    Mangled::NamePreference name_preference) {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);

  AppendSymbolIndexesMatchingRegExAndType(regex, symbol_type, symbol_debug_type,
                                          symbol_visibility, symbol_indexes,
                                          name_preference);
}

Symbol *Symtab::FindFirstSymbolWithNameAndType(ConstString name,
                                               SymbolType symbol_type,
                                               Debug symbol_debug_type,
                                               Visibility symbol_visibility) {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  LLDB_SCOPED_TIMER();
  if (!m_name_indexes_computed)
    InitNameIndexes();

  if (name) {
    std::vector<uint32_t> matching_indexes;
    // The string table did have a string that matched, but we need to check
    // the symbols and match the symbol_type if any was given.
    if (AppendSymbolIndexesWithNameAndType(name, symbol_type, symbol_debug_type,
                                           symbol_visibility,
                                           matching_indexes)) {
      std::vector<uint32_t>::const_iterator pos, end = matching_indexes.end();
      for (pos = matching_indexes.begin(); pos != end; ++pos) {
        Symbol *symbol = SymbolAtIndex(*pos);

        if (symbol->Compare(name, symbol_type))
          return symbol;
      }
    }
  }
  return nullptr;
}

typedef struct {
  const Symtab *symtab;
  const addr_t file_addr;
  Symbol *match_symbol;
  const uint32_t *match_index_ptr;
  addr_t match_offset;
} SymbolSearchInfo;

// Add all the section file start address & size to the RangeVector, recusively
// adding any children sections.
static void AddSectionsToRangeMap(SectionList *sectlist,
                                  RangeVector<addr_t, addr_t> &section_ranges) {
  const int num_sections = sectlist->GetNumSections(0);
  for (int i = 0; i < num_sections; i++) {
    SectionSP sect_sp = sectlist->GetSectionAtIndex(i);
    if (sect_sp) {
      SectionList &child_sectlist = sect_sp->GetChildren();

      // If this section has children, add the children to the RangeVector.
      // Else add this section to the RangeVector.
      if (child_sectlist.GetNumSections(0) > 0) {
        AddSectionsToRangeMap(&child_sectlist, section_ranges);
      } else {
        size_t size = sect_sp->GetByteSize();
        if (size > 0) {
          addr_t base_addr = sect_sp->GetFileAddress();
          RangeVector<addr_t, addr_t>::Entry entry;
          entry.SetRangeBase(base_addr);
          entry.SetByteSize(size);
          section_ranges.Append(entry);
        }
      }
    }
  }
}

void Symtab::InitAddressIndexes() {
  // Protected function, no need to lock mutex...
  if (!m_file_addr_to_index_computed && !m_symbols.empty()) {
    m_file_addr_to_index_computed = true;

    FileRangeToIndexMap::Entry entry;
    const_iterator begin = m_symbols.begin();
    const_iterator end = m_symbols.end();
    for (const_iterator pos = m_symbols.begin(); pos != end; ++pos) {
      if (pos->ValueIsAddress()) {
        entry.SetRangeBase(pos->GetAddressRef().GetFileAddress());
        entry.SetByteSize(pos->GetByteSize());
        entry.data = std::distance(begin, pos);
        m_file_addr_to_index.Append(entry);
      }
    }
    const size_t num_entries = m_file_addr_to_index.GetSize();
    if (num_entries > 0) {
      m_file_addr_to_index.Sort();

      // Create a RangeVector with the start & size of all the sections for
      // this objfile.  We'll need to check this for any FileRangeToIndexMap
      // entries with an uninitialized size, which could potentially be a large
      // number so reconstituting the weak pointer is busywork when it is
      // invariant information.
      SectionList *sectlist = m_objfile->GetSectionList();
      RangeVector<addr_t, addr_t> section_ranges;
      if (sectlist) {
        AddSectionsToRangeMap(sectlist, section_ranges);
        section_ranges.Sort();
      }

      // Iterate through the FileRangeToIndexMap and fill in the size for any
      // entries that didn't already have a size from the Symbol (e.g. if we
      // have a plain linker symbol with an address only, instead of debug info
      // where we get an address and a size and a type, etc.)
      for (size_t i = 0; i < num_entries; i++) {
        FileRangeToIndexMap::Entry *entry =
            m_file_addr_to_index.GetMutableEntryAtIndex(i);
        if (entry->GetByteSize() == 0) {
          addr_t curr_base_addr = entry->GetRangeBase();
          const RangeVector<addr_t, addr_t>::Entry *containing_section =
              section_ranges.FindEntryThatContains(curr_base_addr);

          // Use the end of the section as the default max size of the symbol
          addr_t sym_size = 0;
          if (containing_section) {
            sym_size =
                containing_section->GetByteSize() -
                (entry->GetRangeBase() - containing_section->GetRangeBase());
          }

          for (size_t j = i; j < num_entries; j++) {
            FileRangeToIndexMap::Entry *next_entry =
                m_file_addr_to_index.GetMutableEntryAtIndex(j);
            addr_t next_base_addr = next_entry->GetRangeBase();
            if (next_base_addr > curr_base_addr) {
              addr_t size_to_next_symbol = next_base_addr - curr_base_addr;

              // Take the difference between this symbol and the next one as
              // its size, if it is less than the size of the section.
              if (sym_size == 0 || size_to_next_symbol < sym_size) {
                sym_size = size_to_next_symbol;
              }
              break;
            }
          }

          if (sym_size > 0) {
            entry->SetByteSize(sym_size);
            Symbol &symbol = m_symbols[entry->data];
            symbol.SetByteSize(sym_size);
            symbol.SetSizeIsSynthesized(true);
          }
        }
      }

      // Sort again in case the range size changes the ordering
      m_file_addr_to_index.Sort();
    }
  }
}

void Symtab::Finalize() {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  // Calculate the size of symbols inside InitAddressIndexes.
  InitAddressIndexes();
  // Shrink to fit the symbols so we don't waste memory
  m_symbols.shrink_to_fit();
  SaveToCache();
}

Symbol *Symtab::FindSymbolAtFileAddress(addr_t file_addr) {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);
  if (!m_file_addr_to_index_computed)
    InitAddressIndexes();

  const FileRangeToIndexMap::Entry *entry =
      m_file_addr_to_index.FindEntryStartsAt(file_addr);
  if (entry) {
    Symbol *symbol = SymbolAtIndex(entry->data);
    if (symbol->GetFileAddress() == file_addr)
      return symbol;
  }
  return nullptr;
}

Symbol *Symtab::FindSymbolContainingFileAddress(addr_t file_addr) {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);

  if (!m_file_addr_to_index_computed)
    InitAddressIndexes();

  const FileRangeToIndexMap::Entry *entry =
      m_file_addr_to_index.FindEntryThatContains(file_addr);
  if (entry) {
    Symbol *symbol = SymbolAtIndex(entry->data);
    if (symbol->ContainsFileAddress(file_addr))
      return symbol;
  }
  return nullptr;
}

void Symtab::ForEachSymbolContainingFileAddress(
    addr_t file_addr, std::function<bool(Symbol *)> const &callback) {
  std::lock_guard<std::recursive_mutex> guard(m_mutex);

  if (!m_file_addr_to_index_computed)
    InitAddressIndexes();

  std::vector<uint32_t> all_addr_indexes;

  // Get all symbols with file_addr
  const size_t addr_match_count =
      m_file_addr_to_index.FindEntryIndexesThatContain(file_addr,
                                                       all_addr_indexes);

  for (size_t i = 0; i < addr_match_count; ++i) {
    Symbol *symbol = SymbolAtIndex(all_addr_indexes[i]);
    if (symbol->ContainsFileAddress(file_addr)) {
      if (!callback(symbol))
        break;
    }
  }
}

void Symtab::SymbolIndicesToSymbolContextList(
    std::vector<uint32_t> &symbol_indexes, SymbolContextList &sc_list) {
  // No need to protect this call using m_mutex all other method calls are
  // already thread safe.

  const bool merge_symbol_into_function = true;
  size_t num_indices = symbol_indexes.size();
  if (num_indices > 0) {
    SymbolContext sc;
    sc.module_sp = m_objfile->GetModule();
    for (size_t i = 0; i < num_indices; i++) {
      sc.symbol = SymbolAtIndex(symbol_indexes[i]);
      if (sc.symbol)
        sc_list.AppendIfUnique(sc, merge_symbol_into_function);
    }
  }
}

void Symtab::FindFunctionSymbols(ConstString name, uint32_t name_type_mask,
                                 SymbolContextList &sc_list) {
  std::vector<uint32_t> symbol_indexes;

  // eFunctionNameTypeAuto should be pre-resolved by a call to
  // Module::LookupInfo::LookupInfo()
  assert((name_type_mask & eFunctionNameTypeAuto) == 0);

  if (name_type_mask & (eFunctionNameTypeBase | eFunctionNameTypeFull)) {
    std::vector<uint32_t> temp_symbol_indexes;
    FindAllSymbolsWithNameAndType(name, eSymbolTypeAny, temp_symbol_indexes);

    unsigned temp_symbol_indexes_size = temp_symbol_indexes.size();
    if (temp_symbol_indexes_size > 0) {
      std::lock_guard<std::recursive_mutex> guard(m_mutex);
      for (unsigned i = 0; i < temp_symbol_indexes_size; i++) {
        SymbolContext sym_ctx;
        sym_ctx.symbol = SymbolAtIndex(temp_symbol_indexes[i]);
        if (sym_ctx.symbol) {
          switch (sym_ctx.symbol->GetType()) {
          case eSymbolTypeCode:
          case eSymbolTypeResolver:
          case eSymbolTypeReExported:
          case eSymbolTypeAbsolute:
            symbol_indexes.push_back(temp_symbol_indexes[i]);
            break;
          default:
            break;
          }
        }
      }
    }
  }

  if (!m_name_indexes_computed)
    InitNameIndexes();

  for (lldb::FunctionNameType type :
       {lldb::eFunctionNameTypeBase, lldb::eFunctionNameTypeMethod,
        lldb::eFunctionNameTypeSelector}) {
    if (name_type_mask & type) {
      auto map = GetNameToSymbolIndexMap(type);

      const UniqueCStringMap<uint32_t>::Entry *match;
      for (match = map.FindFirstValueForName(name); match != nullptr;
           match = map.FindNextValueForName(match)) {
        symbol_indexes.push_back(match->value);
      }
    }
  }

  if (!symbol_indexes.empty()) {
    llvm::sort(symbol_indexes);
    symbol_indexes.erase(llvm::unique(symbol_indexes), symbol_indexes.end());
    SymbolIndicesToSymbolContextList(symbol_indexes, sc_list);
  }
}

const Symbol *Symtab::GetParent(Symbol *child_symbol) const {
  uint32_t child_idx = GetIndexForSymbol(child_symbol);
  if (child_idx != UINT32_MAX && child_idx > 0) {
    for (uint32_t idx = child_idx - 1; idx != UINT32_MAX; --idx) {
      const Symbol *symbol = SymbolAtIndex(idx);
      const uint32_t sibling_idx = symbol->GetSiblingIndex();
      if (sibling_idx != UINT32_MAX && sibling_idx > child_idx)
        return symbol;
    }
  }
  return nullptr;
}

std::string Symtab::GetCacheKey() {
  std::string key;
  llvm::raw_string_ostream strm(key);
  // Symbol table can come from different object files for the same module. A
  // module can have one object file as the main executable and might have
  // another object file in a separate symbol file.
  strm << m_objfile->GetModule()->GetCacheKey() << "-symtab-"
      << llvm::format_hex(m_objfile->GetCacheHash(), 10);
  return key;
}

void Symtab::SaveToCache() {
  DataFileCache *cache = Module::GetIndexCache();
  if (!cache)
    return; // Caching is not enabled.
  InitNameIndexes(); // Init the name indexes so we can cache them as well.
  const auto byte_order = endian::InlHostByteOrder();
  DataEncoder file(byte_order, /*addr_size=*/8);
  // Encode will return false if the symbol table's object file doesn't have
  // anything to make a signature from.
  if (Encode(file))
    if (cache->SetCachedData(GetCacheKey(), file.GetData()))
      SetWasSavedToCache();
}

constexpr llvm::StringLiteral kIdentifierCStrMap("CMAP");

static void EncodeCStrMap(DataEncoder &encoder, ConstStringTable &strtab,
                          const UniqueCStringMap<uint32_t> &cstr_map) {
  encoder.AppendData(kIdentifierCStrMap);
  encoder.AppendU32(cstr_map.GetSize());
  for (const auto &entry: cstr_map) {
    // Make sure there are no empty strings.
    assert((bool)entry.cstring);
    encoder.AppendU32(strtab.Add(entry.cstring));
    encoder.AppendU32(entry.value);
  }
}

bool DecodeCStrMap(const DataExtractor &data, lldb::offset_t *offset_ptr,
                   const StringTableReader &strtab,
                   UniqueCStringMap<uint32_t> &cstr_map) {
  llvm::StringRef identifier((const char *)data.GetData(offset_ptr, 4), 4);
  if (identifier != kIdentifierCStrMap)
    return false;
  const uint32_t count = data.GetU32(offset_ptr);
  cstr_map.Reserve(count);
  for (uint32_t i=0; i<count; ++i)
  {
    llvm::StringRef str(strtab.Get(data.GetU32(offset_ptr)));
    uint32_t value = data.GetU32(offset_ptr);
    // No empty strings in the name indexes in Symtab
    if (str.empty())
      return false;
    cstr_map.Append(ConstString(str), value);
  }
  // We must sort the UniqueCStringMap after decoding it since it is a vector
  // of UniqueCStringMap::Entry objects which contain a ConstString and type T.
  // ConstString objects are sorted by "const char *" and then type T and
  // the "const char *" are point values that will depend on the order in which
  // ConstString objects are created and in which of the 256 string pools they
  // are created in. So after we decode all of the entries, we must sort the
  // name map to ensure name lookups succeed. If we encode and decode within
  // the same process we wouldn't need to sort, so unit testing didn't catch
  // this issue when first checked in.
  cstr_map.Sort();
  return true;
}

constexpr llvm::StringLiteral kIdentifierSymbolTable("SYMB");
constexpr uint32_t CURRENT_CACHE_VERSION = 1;

/// The encoding format for the symbol table is as follows:
///
/// Signature signature;
/// ConstStringTable strtab;
/// Identifier four character code: 'SYMB'
/// uint32_t version;
/// uint32_t num_symbols;
/// Symbol symbols[num_symbols];
/// uint8_t num_cstr_maps;
/// UniqueCStringMap<uint32_t> cstr_maps[num_cstr_maps]
bool Symtab::Encode(DataEncoder &encoder) const {
  // Name indexes must be computed before calling this function.
  assert(m_name_indexes_computed);

  // Encode the object file's signature
  CacheSignature signature(m_objfile);
  if (!signature.Encode(encoder))
    return false;
  ConstStringTable strtab;

  // Encoder the symbol table into a separate encoder first. This allows us
  // gather all of the strings we willl need in "strtab" as we will need to
  // write the string table out before the symbol table.
  DataEncoder symtab_encoder(encoder.GetByteOrder(),
                              encoder.GetAddressByteSize());
  symtab_encoder.AppendData(kIdentifierSymbolTable);
  // Encode the symtab data version.
  symtab_encoder.AppendU32(CURRENT_CACHE_VERSION);
  // Encode the number of symbols.
  symtab_encoder.AppendU32(m_symbols.size());
  // Encode the symbol data for all symbols.
  for (const auto &symbol: m_symbols)
    symbol.Encode(symtab_encoder, strtab);

  // Emit a byte for how many C string maps we emit. We will fix this up after
  // we emit the C string maps since we skip emitting C string maps if they are
  // empty.
  size_t num_cmaps_offset = symtab_encoder.GetByteSize();
  uint8_t num_cmaps = 0;
  symtab_encoder.AppendU8(0);
  for (const auto &pair: m_name_to_symbol_indices) {
    if (pair.second.IsEmpty())
      continue;
    ++num_cmaps;
    symtab_encoder.AppendU8(pair.first);
    EncodeCStrMap(symtab_encoder, strtab, pair.second);
  }
  if (num_cmaps > 0)
    symtab_encoder.PutU8(num_cmaps_offset, num_cmaps);

  // Now that all strings have been gathered, we will emit the string table.
  strtab.Encode(encoder);
  // Followed by the symbol table data.
  encoder.AppendData(symtab_encoder.GetData());
  return true;
}

bool Symtab::Decode(const DataExtractor &data, lldb::offset_t *offset_ptr,
                    bool &signature_mismatch) {
  signature_mismatch = false;
  CacheSignature signature;
  StringTableReader strtab;
  { // Scope for "elapsed" object below so it can measure the time parse.
    ElapsedTime elapsed(m_objfile->GetModule()->GetSymtabParseTime());
    if (!signature.Decode(data, offset_ptr))
      return false;
    if (CacheSignature(m_objfile) != signature) {
      signature_mismatch = true;
      return false;
    }
    // We now decode the string table for all strings in the data cache file.
    if (!strtab.Decode(data, offset_ptr))
      return false;

    // And now we can decode the symbol table with string table we just decoded.
    llvm::StringRef identifier((const char *)data.GetData(offset_ptr, 4), 4);
    if (identifier != kIdentifierSymbolTable)
      return false;
    const uint32_t version = data.GetU32(offset_ptr);
    if (version != CURRENT_CACHE_VERSION)
      return false;
    const uint32_t num_symbols = data.GetU32(offset_ptr);
    if (num_symbols == 0)
      return true;
    m_symbols.resize(num_symbols);
    SectionList *sections = m_objfile->GetModule()->GetSectionList();
    for (uint32_t i=0; i<num_symbols; ++i) {
      if (!m_symbols[i].Decode(data, offset_ptr, sections, strtab))
        return false;
    }
  }

  { // Scope for "elapsed" object below so it can measure the time to index.
    ElapsedTime elapsed(m_objfile->GetModule()->GetSymtabIndexTime());
    const uint8_t num_cstr_maps = data.GetU8(offset_ptr);
    for (uint8_t i=0; i<num_cstr_maps; ++i) {
      uint8_t type = data.GetU8(offset_ptr);
      UniqueCStringMap<uint32_t> &cstr_map =
          GetNameToSymbolIndexMap((lldb::FunctionNameType)type);
      if (!DecodeCStrMap(data, offset_ptr, strtab, cstr_map))
        return false;
    }
    m_name_indexes_computed = true;
  }
  return true;
}

bool Symtab::LoadFromCache() {
  DataFileCache *cache = Module::GetIndexCache();
  if (!cache)
    return false;

  std::unique_ptr<llvm::MemoryBuffer> mem_buffer_up =
      cache->GetCachedData(GetCacheKey());
  if (!mem_buffer_up)
    return false;
  DataExtractor data(mem_buffer_up->getBufferStart(),
                     mem_buffer_up->getBufferSize(),
                     m_objfile->GetByteOrder(),
                     m_objfile->GetAddressByteSize());
  bool signature_mismatch = false;
  lldb::offset_t offset = 0;
  const bool result = Decode(data, &offset, signature_mismatch);
  if (signature_mismatch)
    cache->RemoveCacheFile(GetCacheKey());
  if (result)
    SetWasLoadedFromCache();
  return result;
}
