예제 #1
0
void ManualDWARFIndex::IndexUnit(DWARFUnit &unit, IndexSet &set) {
  assert(!unit.GetSymbolFileDWARF()->GetBaseCompileUnit() &&
      "DWARFUnit associated with .dwo or .dwp should not be indexed directly");

  Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS);

  if (log) {
    m_module.LogMessage(
        log, "ManualDWARFIndex::IndexUnit for compile unit at .debug_info[0x%8.8x]",
        unit.GetOffset());
  }

  const LanguageType cu_language = unit.GetLanguageType();
  DWARFFormValue::FixedFormSizes fixed_form_sizes = unit.GetFixedFormSizes();

  IndexUnitImpl(unit, cu_language, fixed_form_sizes, unit.GetOffset(), set);

  SymbolFileDWARFDwo *dwo_symbol_file = unit.GetDwoSymbolFile();
  if (dwo_symbol_file && dwo_symbol_file->GetCompileUnit()) {
    IndexUnitImpl(*dwo_symbol_file->GetCompileUnit(), cu_language,
                  fixed_form_sizes, unit.GetOffset(), set);
  }
}
예제 #2
0
void ManualDWARFIndex::GetGlobalVariables(const DWARFUnit &cu,
                                          DIEArray &offsets) {
  Index();
  m_set.globals.FindAllEntriesForCompileUnit(cu.GetOffset(), offsets);
}
예제 #3
0
void ManualDWARFIndex::Index() {
  if (!m_debug_info)
    return;

  DWARFDebugInfo &debug_info = *m_debug_info;
  m_debug_info = nullptr;

  static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
  Timer scoped_timer(func_cat, "%p", static_cast<void *>(&debug_info));

  std::vector<DWARFUnit *> units_to_index;
  units_to_index.reserve(debug_info.GetNumCompileUnits());
  for (size_t U = 0; U < debug_info.GetNumCompileUnits(); ++U) {
    DWARFUnit *unit = debug_info.GetCompileUnitAtIndex(U);
    if (unit && m_units_to_avoid.count(unit->GetOffset()) == 0)
      units_to_index.push_back(unit);
  }
  if (units_to_index.empty())
    return;

  std::vector<IndexSet> sets(units_to_index.size());

  // Keep memory down by clearing DIEs for any compile units if indexing
  // caused us to load the compile unit's DIEs.
  std::vector<llvm::Optional<DWARFUnit::ScopedExtractDIEs>> clear_cu_dies(
      units_to_index.size());
  auto parser_fn = [&](size_t cu_idx) {
    IndexUnit(*units_to_index[cu_idx], sets[cu_idx]);
  };

  auto extract_fn = [&units_to_index, &clear_cu_dies](size_t cu_idx) {
    clear_cu_dies[cu_idx] = units_to_index[cu_idx]->ExtractDIEsScoped();
  };

  // Create a task runner that extracts dies for each DWARF compile unit in a
  // separate thread
  // First figure out which compile units didn't have their DIEs already
  // parsed and remember this.  If no DIEs were parsed prior to this index
  // function call, we are going to want to clear the CU dies after we are
  // done indexing to make sure we don't pull in all DWARF dies, but we need
  // to wait until all compile units have been indexed in case a DIE in one
  // compile unit refers to another and the indexes accesses those DIEs.
  TaskMapOverInt(0, units_to_index.size(), extract_fn);

  // Now create a task runner that can index each DWARF compile unit in a
  // separate thread so we can index quickly.

  TaskMapOverInt(0, units_to_index.size(), parser_fn);

  auto finalize_fn = [this, &sets](NameToDIE(IndexSet::*index)) {
    NameToDIE &result = m_set.*index;
    for (auto &set : sets)
      result.Append(set.*index);
    result.Finalize();
  };

  TaskPool::RunTasks([&]() { finalize_fn(&IndexSet::function_basenames); },
                     [&]() { finalize_fn(&IndexSet::function_fullnames); },
                     [&]() { finalize_fn(&IndexSet::function_methods); },
                     [&]() { finalize_fn(&IndexSet::function_selectors); },
                     [&]() { finalize_fn(&IndexSet::objc_class_selectors); },
                     [&]() { finalize_fn(&IndexSet::globals); },
                     [&]() { finalize_fn(&IndexSet::types); },
                     [&]() { finalize_fn(&IndexSet::namespaces); });
}