SymbolFileDWARFDebugMap.cpp revision 355940
140843Smsmith//===-- SymbolFileDWARFDebugMap.cpp -----------------------------*- C++ -*-===//
240843Smsmith//
340843Smsmith// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
440843Smsmith// See https://llvm.org/LICENSE.txt for license information.
540843Smsmith// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
640843Smsmith//
740843Smsmith//===----------------------------------------------------------------------===//
840843Smsmith
940843Smsmith#include "SymbolFileDWARFDebugMap.h"
1040843Smsmith#include "DWARFDebugAranges.h"
1140843Smsmith
1240843Smsmith#include "lldb/Core/Module.h"
1340843Smsmith#include "lldb/Core/ModuleList.h"
1440843Smsmith#include "lldb/Core/PluginManager.h"
1540843Smsmith#include "lldb/Core/Section.h"
1640843Smsmith#include "lldb/Host/FileSystem.h"
1740843Smsmith#include "lldb/Utility/RangeMap.h"
1840843Smsmith#include "lldb/Utility/RegularExpression.h"
1940843Smsmith#include "lldb/Utility/Timer.h"
2040843Smsmith
2140843Smsmith//#define DEBUG_OSO_DMAP // DO NOT CHECKIN WITH THIS NOT COMMENTED OUT
2240843Smsmith#if defined(DEBUG_OSO_DMAP)
2340843Smsmith#include "lldb/Core/StreamFile.h"
2440843Smsmith#endif
2540843Smsmith
2640843Smsmith#include "lldb/Symbol/CompileUnit.h"
2740843Smsmith#include "lldb/Symbol/LineTable.h"
2840843Smsmith#include "lldb/Symbol/ObjectFile.h"
2940843Smsmith#include "lldb/Symbol/SymbolVendor.h"
3040843Smsmith#include "lldb/Symbol/TypeMap.h"
3140843Smsmith#include "lldb/Symbol/VariableList.h"
3240843Smsmith#include "llvm/Support/ScopedPrinter.h"
3340843Smsmith
3440843Smsmith#include "LogChannelDWARF.h"
3540843Smsmith#include "SymbolFileDWARF.h"
3640843Smsmith
3740843Smsmith#include <memory>
3840843Smsmith
3940843Smsmithusing namespace lldb;
4040843Smsmithusing namespace lldb_private;
4140843Smsmith
4240843Smsmith// Subclass lldb_private::Module so we can intercept the
4340843Smsmith// "Module::GetObjectFile()" (so we can fixup the object file sections) and
4440843Smsmith// also for "Module::GetSymbolVendor()" (so we can fixup the symbol file id.
4540843Smsmith
4640843Smsmithconst SymbolFileDWARFDebugMap::FileRangeMap &
4740843SmsmithSymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(
4840843Smsmith    SymbolFileDWARFDebugMap *exe_symfile) {
4940843Smsmith  if (file_range_map_valid)
5040843Smsmith    return file_range_map;
5140843Smsmith
5240843Smsmith  file_range_map_valid = true;
5340843Smsmith
5440843Smsmith  Module *oso_module = exe_symfile->GetModuleByCompUnitInfo(this);
5540843Smsmith  if (!oso_module)
5640843Smsmith    return file_range_map;
5740843Smsmith
5840843Smsmith  ObjectFile *oso_objfile = oso_module->GetObjectFile();
5940843Smsmith  if (!oso_objfile)
6040843Smsmith    return file_range_map;
6140843Smsmith
6240843Smsmith  Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
6340843Smsmith  if (log)
6440843Smsmith    log->Printf(
6540843Smsmith        "%p: SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap ('%s')",
6640843Smsmith        static_cast<void *>(this),
6740843Smsmith        oso_module->GetSpecificationDescription().c_str());
6840843Smsmith
6940843Smsmith  std::vector<SymbolFileDWARFDebugMap::CompileUnitInfo *> cu_infos;
7040843Smsmith  if (exe_symfile->GetCompUnitInfosForModule(oso_module, cu_infos)) {
7140843Smsmith    for (auto comp_unit_info : cu_infos) {
7240843Smsmith      Symtab *exe_symtab = exe_symfile->GetObjectFile()->GetSymtab();
7340843Smsmith      ModuleSP oso_module_sp(oso_objfile->GetModule());
7440843Smsmith      Symtab *oso_symtab = oso_objfile->GetSymtab();
7540843Smsmith
7640843Smsmith      /// const uint32_t fun_resolve_flags = SymbolContext::Module |
7740843Smsmith      /// eSymbolContextCompUnit | eSymbolContextFunction;
7840843Smsmith      // SectionList *oso_sections = oso_objfile->Sections();
7940843Smsmith      // Now we need to make sections that map from zero based object file
8040843Smsmith      // addresses to where things ended up in the main executable.
8140843Smsmith
8240843Smsmith      assert(comp_unit_info->first_symbol_index != UINT32_MAX);
8340843Smsmith      // End index is one past the last valid symbol index
8440843Smsmith      const uint32_t oso_end_idx = comp_unit_info->last_symbol_index + 1;
8540843Smsmith      for (uint32_t idx = comp_unit_info->first_symbol_index +
8640843Smsmith                          2; // Skip the N_SO and N_OSO
8740843Smsmith           idx < oso_end_idx; ++idx) {
8840843Smsmith        Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx);
8940843Smsmith        if (exe_symbol) {
9040843Smsmith          if (!exe_symbol->IsDebug())
9140843Smsmith            continue;
9240843Smsmith
9340843Smsmith          switch (exe_symbol->GetType()) {
9440843Smsmith          default:
9540843Smsmith            break;
9640843Smsmith
9740843Smsmith          case eSymbolTypeCode: {
9840843Smsmith            // For each N_FUN, or function that we run into in the debug map we
9940843Smsmith            // make a new section that we add to the sections found in the .o
10040843Smsmith            // file. This new section has the file address set to what the
10140843Smsmith            // addresses are in the .o file, and the load address is adjusted
10240843Smsmith            // to match where it ended up in the final executable! We do this
10340843Smsmith            // before we parse any dwarf info so that when it goes get parsed
10440843Smsmith            // all section/offset addresses that get registered will resolve
10540843Smsmith            // correctly to the new addresses in the main executable.
10640843Smsmith
10740843Smsmith            // First we find the original symbol in the .o file's symbol table
10840843Smsmith            Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType(
10940843Smsmith                exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown,
11040843Smsmith                                                 Mangled::ePreferMangled),
11140843Smsmith                eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny);
11240843Smsmith            if (oso_fun_symbol) {
11340843Smsmith              // Add the inverse OSO file address to debug map entry mapping
11440843Smsmith              exe_symfile->AddOSOFileRange(
11540843Smsmith                  this, exe_symbol->GetAddressRef().GetFileAddress(),
11640843Smsmith                  exe_symbol->GetByteSize(),
11743078Smsmith                  oso_fun_symbol->GetAddressRef().GetFileAddress(),
11843078Smsmith                  oso_fun_symbol->GetByteSize());
11943078Smsmith            }
12043078Smsmith          } break;
12143078Smsmith
12243078Smsmith          case eSymbolTypeData: {
12343078Smsmith            // For each N_GSYM we remap the address for the global by making a
12443078Smsmith            // new section that we add to the sections found in the .o file.
12543078Smsmith            // This new section has the file address set to what the addresses
12643078Smsmith            // are in the .o file, and the load address is adjusted to match
12743078Smsmith            // where it ended up in the final executable! We do this before we
12843078Smsmith            // parse any dwarf info so that when it goes get parsed all
12943078Smsmith            // section/offset addresses that get registered will resolve
13040843Smsmith            // correctly to the new addresses in the main executable. We
13140843Smsmith            // initially set the section size to be 1 byte, but will need to
13240843Smsmith            // fix up these addresses further after all globals have been
13340843Smsmith            // parsed to span the gaps, or we can find the global variable
13440843Smsmith            // sizes from the DWARF info as we are parsing.
13540843Smsmith
13640843Smsmith            // Next we find the non-stab entry that corresponds to the N_GSYM
13740843Smsmith            // in the .o file
13840843Smsmith            Symbol *oso_gsym_symbol =
13940843Smsmith                oso_symtab->FindFirstSymbolWithNameAndType(
14040843Smsmith                    exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown,
14140843Smsmith                                                     Mangled::ePreferMangled),
14240843Smsmith                    eSymbolTypeData, Symtab::eDebugNo, Symtab::eVisibilityAny);
14340843Smsmith            if (exe_symbol && oso_gsym_symbol && exe_symbol->ValueIsAddress() &&
14440843Smsmith                oso_gsym_symbol->ValueIsAddress()) {
14540843Smsmith              // Add the inverse OSO file address to debug map entry mapping
14640843Smsmith              exe_symfile->AddOSOFileRange(
14740843Smsmith                  this, exe_symbol->GetAddressRef().GetFileAddress(),
14840843Smsmith                  exe_symbol->GetByteSize(),
14940843Smsmith                  oso_gsym_symbol->GetAddressRef().GetFileAddress(),
15040843Smsmith                  oso_gsym_symbol->GetByteSize());
15140843Smsmith            }
15240843Smsmith          } break;
15340843Smsmith          }
15440843Smsmith        }
15540843Smsmith      }
15640843Smsmith
15740843Smsmith      exe_symfile->FinalizeOSOFileRanges(this);
15840843Smsmith      // We don't need the symbols anymore for the .o files
15940843Smsmith      oso_objfile->ClearSymtab();
16040843Smsmith    }
16140843Smsmith  }
16240843Smsmith  return file_range_map;
16340843Smsmith}
16440843Smsmith
16540843Smsmithclass DebugMapModule : public Module {
16640843Smsmithpublic:
16740843Smsmith  DebugMapModule(const ModuleSP &exe_module_sp, uint32_t cu_idx,
16840843Smsmith                 const FileSpec &file_spec, const ArchSpec &arch,
16943078Smsmith                 const ConstString *object_name, off_t object_offset,
17043078Smsmith                 const llvm::sys::TimePoint<> object_mod_time)
17143078Smsmith      : Module(file_spec, arch, object_name, object_offset, object_mod_time),
17243078Smsmith        m_exe_module_wp(exe_module_sp), m_cu_idx(cu_idx) {}
17343078Smsmith
17443078Smsmith  ~DebugMapModule() override = default;
17543078Smsmith
17643078Smsmith  SymbolVendor *
17743078Smsmith  GetSymbolVendor(bool can_create = true,
17840843Smsmith                  lldb_private::Stream *feedback_strm = nullptr) override {
17940843Smsmith    // Scope for locker
18040843Smsmith    if (m_symfile_up.get() || !can_create)
18140843Smsmith      return m_symfile_up.get();
18240843Smsmith
18340843Smsmith    ModuleSP exe_module_sp(m_exe_module_wp.lock());
18440843Smsmith    if (exe_module_sp) {
18540843Smsmith      // Now get the object file outside of a locking scope
18640843Smsmith      ObjectFile *oso_objfile = GetObjectFile();
18740843Smsmith      if (oso_objfile) {
18840843Smsmith        std::lock_guard<std::recursive_mutex> guard(m_mutex);
18940843Smsmith        SymbolVendor *symbol_vendor =
19040843Smsmith            Module::GetSymbolVendor(can_create, feedback_strm);
19140843Smsmith        if (symbol_vendor) {
19240843Smsmith          // Set a pointer to this class to set our OSO DWARF file know that
19340843Smsmith          // the DWARF is being used along with a debug map and that it will
19440843Smsmith          // have the remapped sections that we do below.
19540843Smsmith          SymbolFileDWARF *oso_symfile =
19640843Smsmith              SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(
19740843Smsmith                  symbol_vendor->GetSymbolFile());
19840843Smsmith
19940843Smsmith          if (!oso_symfile)
20040843Smsmith            return nullptr;
20140843Smsmith
20240843Smsmith          ObjectFile *exe_objfile = exe_module_sp->GetObjectFile();
20340843Smsmith          SymbolVendor *exe_sym_vendor = exe_module_sp->GetSymbolVendor();
20440843Smsmith
20540843Smsmith          if (exe_objfile && exe_sym_vendor) {
20640843Smsmith            oso_symfile->SetDebugMapModule(exe_module_sp);
20740843Smsmith            // Set the ID of the symbol file DWARF to the index of the OSO
20840843Smsmith            // shifted left by 32 bits to provide a unique prefix for any
20940843Smsmith            // UserID's that get created in the symbol file.
21040843Smsmith            oso_symfile->SetID(((uint64_t)m_cu_idx + 1ull) << 32ull);
21140843Smsmith          }
21240843Smsmith          return symbol_vendor;
21340843Smsmith        }
21440843Smsmith      }
21540843Smsmith    }
21640843Smsmith    return nullptr;
21740843Smsmith  }
21840843Smsmith
21940843Smsmithprotected:
22040843Smsmith  ModuleWP m_exe_module_wp;
22140843Smsmith  const uint32_t m_cu_idx;
22240843Smsmith};
22340843Smsmith
22440843Smsmithvoid SymbolFileDWARFDebugMap::Initialize() {
22540843Smsmith  PluginManager::RegisterPlugin(GetPluginNameStatic(),
22640843Smsmith                                GetPluginDescriptionStatic(), CreateInstance);
22740843Smsmith}
22840843Smsmith
22940843Smsmithvoid SymbolFileDWARFDebugMap::Terminate() {
23040843Smsmith  PluginManager::UnregisterPlugin(CreateInstance);
23140949Smsmith}
23240977Sjkh
23340949Smsmithlldb_private::ConstString SymbolFileDWARFDebugMap::GetPluginNameStatic() {
23440949Smsmith  static ConstString g_name("dwarf-debugmap");
23540843Smsmith  return g_name;
23640843Smsmith}
23740843Smsmith
23840843Smsmithconst char *SymbolFileDWARFDebugMap::GetPluginDescriptionStatic() {
23940843Smsmith  return "DWARF and DWARF3 debug symbol file reader (debug map).";
24040843Smsmith}
24140843Smsmith
24240843SmsmithSymbolFile *SymbolFileDWARFDebugMap::CreateInstance(ObjectFile *obj_file) {
24340843Smsmith  return new SymbolFileDWARFDebugMap(obj_file);
24440843Smsmith}
24540843Smsmith
24640843SmsmithSymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap(ObjectFile *ofile)
24740843Smsmith    : SymbolFile(ofile), m_flags(), m_compile_unit_infos(), m_func_indexes(),
24840843Smsmith      m_glob_indexes(),
24940843Smsmith      m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate) {}
25040843Smsmith
25140843SmsmithSymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap() {}
25240843Smsmith
25340843Smsmithvoid SymbolFileDWARFDebugMap::InitializeObject() {}
25440843Smsmith
25540843Smsmithvoid SymbolFileDWARFDebugMap::InitOSO() {
25640843Smsmith  if (m_flags.test(kHaveInitializedOSOs))
25740843Smsmith    return;
25840843Smsmith
25940843Smsmith  m_flags.set(kHaveInitializedOSOs);
26040843Smsmith
26140843Smsmith  // If the object file has been stripped, there is no sense in looking further
26240843Smsmith  // as all of the debug symbols for the debug map will not be available
26340843Smsmith  if (m_obj_file->IsStripped())
26440843Smsmith    return;
26540843Smsmith
26640843Smsmith  // Also make sure the file type is some sort of executable. Core files, debug
26740843Smsmith  // info files (dSYM), object files (.o files), and stub libraries all can
26840843Smsmith  switch (m_obj_file->GetType()) {
26940843Smsmith  case ObjectFile::eTypeInvalid:
27040843Smsmith  case ObjectFile::eTypeCoreFile:
27140843Smsmith  case ObjectFile::eTypeDebugInfo:
27240843Smsmith  case ObjectFile::eTypeObjectFile:
27340843Smsmith  case ObjectFile::eTypeStubLibrary:
27440843Smsmith  case ObjectFile::eTypeUnknown:
27540843Smsmith  case ObjectFile::eTypeJIT:
27640843Smsmith    return;
27740843Smsmith
27840843Smsmith  case ObjectFile::eTypeExecutable:
27940843Smsmith  case ObjectFile::eTypeDynamicLinker:
28040843Smsmith  case ObjectFile::eTypeSharedLibrary:
28140843Smsmith    break;
28240843Smsmith  }
28340843Smsmith
28440843Smsmith  // In order to get the abilities of this plug-in, we look at the list of
28540843Smsmith  // N_OSO entries (object files) from the symbol table and make sure that
28640843Smsmith  // these files exist and also contain valid DWARF. If we get any of that then
28740843Smsmith  // we return the abilities of the first N_OSO's DWARF.
28840843Smsmith
28940843Smsmith  Symtab *symtab = m_obj_file->GetSymtab();
29040843Smsmith  if (symtab) {
29140843Smsmith    Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
29240843Smsmith
29340843Smsmith    std::vector<uint32_t> oso_indexes;
29440843Smsmith    // When a mach-o symbol is encoded, the n_type field is encoded in bits
29540843Smsmith    // 23:16, and the n_desc field is encoded in bits 15:0.
29640843Smsmith    //
29740843Smsmith    // To find all N_OSO entries that are part of the DWARF + debug map we find
29840843Smsmith    // only object file symbols with the flags value as follows: bits 23:16 ==
29940843Smsmith    // 0x66 (N_OSO) bits 15: 0 == 0x0001 (specifies this is a debug map object
30040843Smsmith    // file)
30140843Smsmith    const uint32_t k_oso_symbol_flags_value = 0x660001u;
30240843Smsmith
30340843Smsmith    const uint32_t oso_index_count =
30440843Smsmith        symtab->AppendSymbolIndexesWithTypeAndFlagsValue(
30540843Smsmith            eSymbolTypeObjectFile, k_oso_symbol_flags_value, oso_indexes);
30640843Smsmith
30740843Smsmith    if (oso_index_count > 0) {
30840843Smsmith      symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugYes,
30940843Smsmith                                          Symtab::eVisibilityAny,
31040843Smsmith                                          m_func_indexes);
31140843Smsmith      symtab->AppendSymbolIndexesWithType(eSymbolTypeData, Symtab::eDebugYes,
31240843Smsmith                                          Symtab::eVisibilityAny,
31340843Smsmith                                          m_glob_indexes);
31440843Smsmith
31540843Smsmith      symtab->SortSymbolIndexesByValue(m_func_indexes, true);
31640843Smsmith      symtab->SortSymbolIndexesByValue(m_glob_indexes, true);
31743078Smsmith
31843078Smsmith      for (uint32_t sym_idx : m_func_indexes) {
31943078Smsmith        const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
32043078Smsmith        lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress();
32143078Smsmith        lldb::addr_t byte_size = symbol->GetByteSize();
32243078Smsmith        DebugMap::Entry debug_map_entry(
32343078Smsmith            file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
32443078Smsmith        m_debug_map.Append(debug_map_entry);
32540843Smsmith      }
32640843Smsmith      for (uint32_t sym_idx : m_glob_indexes) {
32740843Smsmith        const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
32840843Smsmith        lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress();
32943078Smsmith        lldb::addr_t byte_size = symbol->GetByteSize();
33040843Smsmith        DebugMap::Entry debug_map_entry(
33140843Smsmith            file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
33240843Smsmith        m_debug_map.Append(debug_map_entry);
33340843Smsmith      }
33440843Smsmith      m_debug_map.Sort();
33540843Smsmith
33640843Smsmith      m_compile_unit_infos.resize(oso_index_count);
33740843Smsmith
33840843Smsmith      for (uint32_t i = 0; i < oso_index_count; ++i) {
33940843Smsmith        const uint32_t so_idx = oso_indexes[i] - 1;
34040843Smsmith        const uint32_t oso_idx = oso_indexes[i];
34140843Smsmith        const Symbol *so_symbol = symtab->SymbolAtIndex(so_idx);
34240843Smsmith        const Symbol *oso_symbol = symtab->SymbolAtIndex(oso_idx);
34340843Smsmith        if (so_symbol && oso_symbol &&
34440843Smsmith            so_symbol->GetType() == eSymbolTypeSourceFile &&
34540843Smsmith            oso_symbol->GetType() == eSymbolTypeObjectFile) {
34640843Smsmith          m_compile_unit_infos[i].so_file.SetFile(
34740843Smsmith              so_symbol->GetName().AsCString(), FileSpec::Style::native);
34840843Smsmith          m_compile_unit_infos[i].oso_path = oso_symbol->GetName();
34940843Smsmith          m_compile_unit_infos[i].oso_mod_time =
35040843Smsmith              llvm::sys::toTimePoint(oso_symbol->GetIntegerValue(0));
35140843Smsmith          uint32_t sibling_idx = so_symbol->GetSiblingIndex();
35240843Smsmith          // The sibling index can't be less that or equal to the current index
35340843Smsmith          // "i"
35440843Smsmith          if (sibling_idx == UINT32_MAX) {
35540843Smsmith            m_obj_file->GetModule()->ReportError(
35640843Smsmith                "N_SO in symbol with UID %u has invalid sibling in debug map, "
35740843Smsmith                "please file a bug and attach the binary listed in this error",
35840843Smsmith                so_symbol->GetID());
35940843Smsmith          } else {
36040843Smsmith            const Symbol *last_symbol = symtab->SymbolAtIndex(sibling_idx - 1);
36140843Smsmith            m_compile_unit_infos[i].first_symbol_index = so_idx;
36240843Smsmith            m_compile_unit_infos[i].last_symbol_index = sibling_idx - 1;
36340843Smsmith            m_compile_unit_infos[i].first_symbol_id = so_symbol->GetID();
36440843Smsmith            m_compile_unit_infos[i].last_symbol_id = last_symbol->GetID();
36540843Smsmith
36640843Smsmith            if (log)
36740843Smsmith              log->Printf("Initialized OSO 0x%8.8x: file=%s", i,
36840843Smsmith                          oso_symbol->GetName().GetCString());
36940843Smsmith          }
37040843Smsmith        } else {
37140843Smsmith          if (oso_symbol == nullptr)
37240843Smsmith            m_obj_file->GetModule()->ReportError(
37340843Smsmith                "N_OSO symbol[%u] can't be found, please file a bug and attach "
37440843Smsmith                "the binary listed in this error",
37540843Smsmith                oso_idx);
37640843Smsmith          else if (so_symbol == nullptr)
37740843Smsmith            m_obj_file->GetModule()->ReportError(
37840843Smsmith                "N_SO not found for N_OSO symbol[%u], please file a bug and "
37940843Smsmith                "attach the binary listed in this error",
38040843Smsmith                oso_idx);
38140843Smsmith          else if (so_symbol->GetType() != eSymbolTypeSourceFile)
38240843Smsmith            m_obj_file->GetModule()->ReportError(
38340843Smsmith                "N_SO has incorrect symbol type (%u) for N_OSO symbol[%u], "
38440843Smsmith                "please file a bug and attach the binary listed in this error",
38540843Smsmith                so_symbol->GetType(), oso_idx);
38640843Smsmith          else if (oso_symbol->GetType() != eSymbolTypeSourceFile)
38740843Smsmith            m_obj_file->GetModule()->ReportError(
38840843Smsmith                "N_OSO has incorrect symbol type (%u) for N_OSO symbol[%u], "
38940843Smsmith                "please file a bug and attach the binary listed in this error",
39040843Smsmith                oso_symbol->GetType(), oso_idx);
39140843Smsmith        }
39240843Smsmith      }
39340843Smsmith    }
39440843Smsmith  }
39540843Smsmith}
39640843Smsmith
39740843SmsmithModule *SymbolFileDWARFDebugMap::GetModuleByOSOIndex(uint32_t oso_idx) {
39840843Smsmith  const uint32_t cu_count = GetNumCompileUnits();
39940843Smsmith  if (oso_idx < cu_count)
40040843Smsmith    return GetModuleByCompUnitInfo(&m_compile_unit_infos[oso_idx]);
40140843Smsmith  return nullptr;
40240843Smsmith}
40340843Smsmith
40440843SmsmithModule *SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo(
40540843Smsmith    CompileUnitInfo *comp_unit_info) {
40640843Smsmith  if (!comp_unit_info->oso_sp) {
40740843Smsmith    auto pos = m_oso_map.find(
40840843Smsmith        {comp_unit_info->oso_path, comp_unit_info->oso_mod_time});
40940843Smsmith    if (pos != m_oso_map.end()) {
41040843Smsmith      comp_unit_info->oso_sp = pos->second;
41140843Smsmith    } else {
41240843Smsmith      ObjectFile *obj_file = GetObjectFile();
41340843Smsmith      comp_unit_info->oso_sp = std::make_shared<OSOInfo>();
41440843Smsmith      m_oso_map[{comp_unit_info->oso_path, comp_unit_info->oso_mod_time}] =
41540843Smsmith          comp_unit_info->oso_sp;
41640843Smsmith      const char *oso_path = comp_unit_info->oso_path.GetCString();
41740843Smsmith      FileSpec oso_file(oso_path);
41840843Smsmith      ConstString oso_object;
41940843Smsmith      if (FileSystem::Instance().Exists(oso_file)) {
42040843Smsmith        // The modification time returned by the FS can have a higher precision
42140843Smsmith        // than the one from the CU.
42240843Smsmith        auto oso_mod_time = std::chrono::time_point_cast<std::chrono::seconds>(
42340843Smsmith            FileSystem::Instance().GetModificationTime(oso_file));
42440843Smsmith        if (oso_mod_time != comp_unit_info->oso_mod_time) {
42540843Smsmith          obj_file->GetModule()->ReportError(
42640843Smsmith              "debug map object file '%s' has changed (actual time is "
42740843Smsmith              "%s, debug map time is %s"
42840843Smsmith              ") since this executable was linked, file will be ignored",
42940843Smsmith              oso_file.GetPath().c_str(), llvm::to_string(oso_mod_time).c_str(),
43040843Smsmith              llvm::to_string(comp_unit_info->oso_mod_time).c_str());
43140843Smsmith          return nullptr;
43240843Smsmith        }
43340843Smsmith
43440843Smsmith      } else {
43540843Smsmith        const bool must_exist = true;
43640843Smsmith
43740843Smsmith        if (!ObjectFile::SplitArchivePathWithObject(oso_path, oso_file,
43840843Smsmith                                                    oso_object, must_exist)) {
43940843Smsmith          return nullptr;
44040843Smsmith        }
44140843Smsmith      }
44240843Smsmith      // Always create a new module for .o files. Why? Because we use the debug
44340843Smsmith      // map, to add new sections to each .o file and even though a .o file
44440843Smsmith      // might not have changed, the sections that get added to the .o file can
44540843Smsmith      // change.
44640843Smsmith      ArchSpec oso_arch;
44740843Smsmith      // Only adopt the architecture from the module (not the vendor or OS)
44840843Smsmith      // since .o files for "i386-apple-ios" will historically show up as "i386
44940843Smsmith      // -apple-macosx" due to the lack of a LC_VERSION_MIN_MACOSX or
45040843Smsmith      // LC_VERSION_MIN_IPHONEOS load command...
45140843Smsmith      oso_arch.SetTriple(m_obj_file->GetModule()
45240843Smsmith                             ->GetArchitecture()
45340843Smsmith                             .GetTriple()
45440843Smsmith                             .getArchName()
45540843Smsmith                             .str()
45640843Smsmith                             .c_str());
45740843Smsmith      comp_unit_info->oso_sp->module_sp = std::make_shared<DebugMapModule>(
45840843Smsmith          obj_file->GetModule(), GetCompUnitInfoIndex(comp_unit_info), oso_file,
45940843Smsmith          oso_arch, oso_object ? &oso_object : nullptr, 0,
46040843Smsmith          oso_object ? comp_unit_info->oso_mod_time : llvm::sys::TimePoint<>());
46140843Smsmith    }
46240843Smsmith  }
46340843Smsmith  if (comp_unit_info->oso_sp)
46440843Smsmith    return comp_unit_info->oso_sp->module_sp.get();
46540843Smsmith  return nullptr;
46640843Smsmith}
46740843Smsmith
46840843Smsmithbool SymbolFileDWARFDebugMap::GetFileSpecForSO(uint32_t oso_idx,
46940843Smsmith                                               FileSpec &file_spec) {
47040843Smsmith  if (oso_idx < m_compile_unit_infos.size()) {
47140843Smsmith    if (m_compile_unit_infos[oso_idx].so_file) {
47240843Smsmith      file_spec = m_compile_unit_infos[oso_idx].so_file;
47340843Smsmith      return true;
47440843Smsmith    }
47540843Smsmith  }
47640843Smsmith  return false;
47740843Smsmith}
47840843Smsmith
47940843SmsmithObjectFile *SymbolFileDWARFDebugMap::GetObjectFileByOSOIndex(uint32_t oso_idx) {
48040843Smsmith  Module *oso_module = GetModuleByOSOIndex(oso_idx);
48140843Smsmith  if (oso_module)
48240843Smsmith    return oso_module->GetObjectFile();
48340843Smsmith  return nullptr;
48440843Smsmith}
48540843Smsmith
48640843SmsmithSymbolFileDWARF *
48740843SmsmithSymbolFileDWARFDebugMap::GetSymbolFile(const SymbolContext &sc) {
48840843Smsmith  return GetSymbolFile(*sc.comp_unit);
48940843Smsmith}
49040843Smsmith
49140843SmsmithSymbolFileDWARF *
49240843SmsmithSymbolFileDWARFDebugMap::GetSymbolFile(const CompileUnit &comp_unit) {
49340843Smsmith  CompileUnitInfo *comp_unit_info = GetCompUnitInfo(comp_unit);
49440843Smsmith  if (comp_unit_info)
49540843Smsmith    return GetSymbolFileByCompUnitInfo(comp_unit_info);
49640843Smsmith  return nullptr;
49740843Smsmith}
49840843Smsmith
49940843SmsmithObjectFile *SymbolFileDWARFDebugMap::GetObjectFileByCompUnitInfo(
50040843Smsmith    CompileUnitInfo *comp_unit_info) {
50140843Smsmith  Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info);
50240843Smsmith  if (oso_module)
50340843Smsmith    return oso_module->GetObjectFile();
50443078Smsmith  return nullptr;
50543078Smsmith}
50643078Smsmith
50743078Smsmithuint32_t SymbolFileDWARFDebugMap::GetCompUnitInfoIndex(
50843078Smsmith    const CompileUnitInfo *comp_unit_info) {
50943078Smsmith  if (!m_compile_unit_infos.empty()) {
51043078Smsmith    const CompileUnitInfo *first_comp_unit_info = &m_compile_unit_infos.front();
51140843Smsmith    const CompileUnitInfo *last_comp_unit_info = &m_compile_unit_infos.back();
51240843Smsmith    if (first_comp_unit_info <= comp_unit_info &&
51340843Smsmith        comp_unit_info <= last_comp_unit_info)
51440843Smsmith      return comp_unit_info - first_comp_unit_info;
51540843Smsmith  }
51640843Smsmith  return UINT32_MAX;
51740843Smsmith}
51840843Smsmith
51940843SmsmithSymbolFileDWARF *
52040843SmsmithSymbolFileDWARFDebugMap::GetSymbolFileByOSOIndex(uint32_t oso_idx) {
52140843Smsmith  unsigned size = m_compile_unit_infos.size();
52240843Smsmith  if (oso_idx < size)
52340843Smsmith    return GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[oso_idx]);
52440843Smsmith  return nullptr;
52540843Smsmith}
52640843Smsmith
52740843SmsmithSymbolFileDWARF *
52840843SmsmithSymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(SymbolFile *sym_file) {
52940843Smsmith  if (sym_file &&
53040843Smsmith      sym_file->GetPluginName() == SymbolFileDWARF::GetPluginNameStatic())
53140843Smsmith    return (SymbolFileDWARF *)sym_file;
53240843Smsmith  return nullptr;
53340843Smsmith}
53440843Smsmith
53540843SmsmithSymbolFileDWARF *SymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo(
53640843Smsmith    CompileUnitInfo *comp_unit_info) {
53740843Smsmith  Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info);
53840843Smsmith  if (oso_module) {
53940843Smsmith    SymbolVendor *sym_vendor = oso_module->GetSymbolVendor();
54040843Smsmith    if (sym_vendor)
54140843Smsmith      return GetSymbolFileAsSymbolFileDWARF(sym_vendor->GetSymbolFile());
54240843Smsmith  }
54340843Smsmith  return nullptr;
54440843Smsmith}
54540843Smsmith
54640843Smsmithuint32_t SymbolFileDWARFDebugMap::CalculateAbilities() {
54740843Smsmith  // In order to get the abilities of this plug-in, we look at the list of
54840843Smsmith  // N_OSO entries (object files) from the symbol table and make sure that
54943078Smsmith  // these files exist and also contain valid DWARF. If we get any of that then
55040843Smsmith  // we return the abilities of the first N_OSO's DWARF.
55140843Smsmith
55240843Smsmith  const uint32_t oso_index_count = GetNumCompileUnits();
55340843Smsmith  if (oso_index_count > 0) {
55440843Smsmith    InitOSO();
55540843Smsmith    if (!m_compile_unit_infos.empty()) {
55640843Smsmith      return SymbolFile::CompileUnits | SymbolFile::Functions |
55740843Smsmith             SymbolFile::Blocks | SymbolFile::GlobalVariables |
55840843Smsmith             SymbolFile::LocalVariables | SymbolFile::VariableTypes |
55940843Smsmith             SymbolFile::LineTables;
56040843Smsmith    }
56140843Smsmith  }
56240843Smsmith  return 0;
56340843Smsmith}
56440843Smsmith
56540843Smsmithuint32_t SymbolFileDWARFDebugMap::GetNumCompileUnits() {
56640843Smsmith  InitOSO();
56740843Smsmith  return m_compile_unit_infos.size();
56840843Smsmith}
56940843Smsmith
57040843SmsmithCompUnitSP SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx) {
57143078Smsmith  CompUnitSP comp_unit_sp;
57240843Smsmith  const uint32_t cu_count = GetNumCompileUnits();
57340843Smsmith
57440843Smsmith  if (cu_idx < cu_count) {
57540843Smsmith    Module *oso_module = GetModuleByCompUnitInfo(&m_compile_unit_infos[cu_idx]);
57640843Smsmith    if (oso_module) {
57740843Smsmith      FileSpec so_file_spec;
57840843Smsmith      if (GetFileSpecForSO(cu_idx, so_file_spec)) {
57940843Smsmith        // User zero as the ID to match the compile unit at offset zero in each
58040843Smsmith        // .o file since each .o file can only have one compile unit for now.
58140843Smsmith        lldb::user_id_t cu_id = 0;
58240843Smsmith        m_compile_unit_infos[cu_idx].compile_unit_sp =
58340843Smsmith            std::make_shared<CompileUnit>(
58440843Smsmith                m_obj_file->GetModule(), nullptr, so_file_spec, cu_id,
58540843Smsmith                eLanguageTypeUnknown, eLazyBoolCalculate);
58640843Smsmith
58740843Smsmith        if (m_compile_unit_infos[cu_idx].compile_unit_sp) {
58840843Smsmith          // Let our symbol vendor know about this compile unit
58940843Smsmith          m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(
59040843Smsmith              cu_idx, m_compile_unit_infos[cu_idx].compile_unit_sp);
59140843Smsmith        }
59240843Smsmith      }
59340843Smsmith    }
59440843Smsmith    comp_unit_sp = m_compile_unit_infos[cu_idx].compile_unit_sp;
59540843Smsmith  }
59640843Smsmith
59740843Smsmith  return comp_unit_sp;
59840843Smsmith}
59940843Smsmith
60040843SmsmithSymbolFileDWARFDebugMap::CompileUnitInfo *
60140843SmsmithSymbolFileDWARFDebugMap::GetCompUnitInfo(const SymbolContext &sc) {
60240843Smsmith  return GetCompUnitInfo(*sc.comp_unit);
60340843Smsmith}
60440843Smsmith
60540843SmsmithSymbolFileDWARFDebugMap::CompileUnitInfo *
60640843SmsmithSymbolFileDWARFDebugMap::GetCompUnitInfo(const CompileUnit &comp_unit) {
60740843Smsmith  const uint32_t cu_count = GetNumCompileUnits();
60840843Smsmith  for (uint32_t i = 0; i < cu_count; ++i) {
60940843Smsmith    if (comp_unit == m_compile_unit_infos[i].compile_unit_sp.get())
61040843Smsmith      return &m_compile_unit_infos[i];
61140843Smsmith  }
61240843Smsmith  return nullptr;
61340843Smsmith}
61440843Smsmith
61540843Smsmithsize_t SymbolFileDWARFDebugMap::GetCompUnitInfosForModule(
61640843Smsmith    const lldb_private::Module *module,
61740843Smsmith    std::vector<CompileUnitInfo *> &cu_infos) {
61840843Smsmith  const uint32_t cu_count = GetNumCompileUnits();
61940843Smsmith  for (uint32_t i = 0; i < cu_count; ++i) {
62040843Smsmith    if (module == GetModuleByCompUnitInfo(&m_compile_unit_infos[i]))
62140843Smsmith      cu_infos.push_back(&m_compile_unit_infos[i]);
62240843Smsmith  }
62340843Smsmith  return cu_infos.size();
62440843Smsmith}
62540843Smsmith
62640843Smsmithlldb::LanguageType
62740843SmsmithSymbolFileDWARFDebugMap::ParseLanguage(CompileUnit &comp_unit) {
62840843Smsmith  SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
62940843Smsmith  if (oso_dwarf)
63040843Smsmith    return oso_dwarf->ParseLanguage(comp_unit);
63140843Smsmith  return eLanguageTypeUnknown;
63240843Smsmith}
63340843Smsmith
63440843Smsmithsize_t SymbolFileDWARFDebugMap::ParseFunctions(CompileUnit &comp_unit) {
63540843Smsmith  SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
63640843Smsmith  if (oso_dwarf)
63740843Smsmith    return oso_dwarf->ParseFunctions(comp_unit);
63840843Smsmith  return 0;
63940843Smsmith}
64040843Smsmith
64140843Smsmithbool SymbolFileDWARFDebugMap::ParseLineTable(CompileUnit &comp_unit) {
64240843Smsmith  SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
64340843Smsmith  if (oso_dwarf)
64440843Smsmith    return oso_dwarf->ParseLineTable(comp_unit);
64540843Smsmith  return false;
64640843Smsmith}
64740843Smsmith
64840843Smsmithbool SymbolFileDWARFDebugMap::ParseDebugMacros(CompileUnit &comp_unit) {
64940843Smsmith  SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
65040843Smsmith  if (oso_dwarf)
65140843Smsmith    return oso_dwarf->ParseDebugMacros(comp_unit);
65240843Smsmith  return false;
65340843Smsmith}
65440843Smsmith
65540843Smsmithbool SymbolFileDWARFDebugMap::ParseSupportFiles(CompileUnit &comp_unit,
65640843Smsmith                                                FileSpecList &support_files) {
65740843Smsmith  SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
65840843Smsmith  if (oso_dwarf)
65940843Smsmith    return oso_dwarf->ParseSupportFiles(comp_unit, support_files);
66040843Smsmith  return false;
66140843Smsmith}
66240843Smsmith
66340843Smsmithbool SymbolFileDWARFDebugMap::ParseIsOptimized(CompileUnit &comp_unit) {
66440843Smsmith  SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
66540843Smsmith  if (oso_dwarf)
66640843Smsmith    return oso_dwarf->ParseIsOptimized(comp_unit);
66740843Smsmith  return false;
66840843Smsmith}
66940843Smsmith
67040843Smsmithbool SymbolFileDWARFDebugMap::ParseImportedModules(
67140843Smsmith    const SymbolContext &sc, std::vector<SourceModule> &imported_modules) {
67240843Smsmith  SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
67340843Smsmith  if (oso_dwarf)
67440843Smsmith    return oso_dwarf->ParseImportedModules(sc, imported_modules);
67540843Smsmith  return false;
67640843Smsmith}
67740843Smsmith
67840843Smsmithsize_t SymbolFileDWARFDebugMap::ParseBlocksRecursive(Function &func) {
67940843Smsmith  CompileUnit *comp_unit = func.GetCompileUnit();
68040843Smsmith  if (!comp_unit)
68140843Smsmith    return 0;
68240843Smsmith
68340843Smsmith  SymbolFileDWARF *oso_dwarf = GetSymbolFile(*comp_unit);
68440843Smsmith  if (oso_dwarf)
68540843Smsmith    return oso_dwarf->ParseBlocksRecursive(func);
68640843Smsmith  return 0;
68740843Smsmith}
68840843Smsmith
68940843Smsmithsize_t SymbolFileDWARFDebugMap::ParseTypes(CompileUnit &comp_unit) {
69040843Smsmith  SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit);
69140843Smsmith  if (oso_dwarf)
69240843Smsmith    return oso_dwarf->ParseTypes(comp_unit);
69340843Smsmith  return 0;
69440843Smsmith}
69540843Smsmith
69640843Smsmithsize_t
69740843SmsmithSymbolFileDWARFDebugMap::ParseVariablesForContext(const SymbolContext &sc) {
69840843Smsmith  SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
69940843Smsmith  if (oso_dwarf)
70040843Smsmith    return oso_dwarf->ParseVariablesForContext(sc);
70140843Smsmith  return 0;
70240843Smsmith}
70340843Smsmith
70440843SmsmithType *SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid) {
70540843Smsmith  const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid);
70640843Smsmith  SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
70740843Smsmith  if (oso_dwarf)
70840843Smsmith    return oso_dwarf->ResolveTypeUID(type_uid);
70940843Smsmith  return nullptr;
71040843Smsmith}
71140843Smsmith
71240843Smsmithllvm::Optional<SymbolFile::ArrayInfo>
71343078SmsmithSymbolFileDWARFDebugMap::GetDynamicArrayInfoForUID(
71443078Smsmith    lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) {
71540843Smsmith  const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid);
71640843Smsmith  SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
71740843Smsmith  if (oso_dwarf)
71840843Smsmith    return oso_dwarf->GetDynamicArrayInfoForUID(type_uid, exe_ctx);
71940843Smsmith  return llvm::None;
72040843Smsmith}
72140843Smsmith
72240843Smsmithbool SymbolFileDWARFDebugMap::CompleteType(CompilerType &compiler_type) {
72340843Smsmith  bool success = false;
72440843Smsmith  if (compiler_type) {
72540843Smsmith    ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
72643078Smsmith      if (oso_dwarf->HasForwardDeclForClangType(compiler_type)) {
72743078Smsmith        oso_dwarf->CompleteType(compiler_type);
72840843Smsmith        success = true;
72940843Smsmith        return true;
73040843Smsmith      }
73143078Smsmith      return false;
73240843Smsmith    });
73340843Smsmith  }
73440989Sjkh  return success;
73540989Sjkh}
73640989Sjkh
73740989Sjkhuint32_t
73840989SjkhSymbolFileDWARFDebugMap::ResolveSymbolContext(const Address &exe_so_addr,
73940989Sjkh                                              SymbolContextItem resolve_scope,
74040989Sjkh                                              SymbolContext &sc) {
74140989Sjkh  uint32_t resolved_flags = 0;
74240843Smsmith  Symtab *symtab = m_obj_file->GetSymtab();
74340843Smsmith  if (symtab) {
74440843Smsmith    const addr_t exe_file_addr = exe_so_addr.GetFileAddress();
74540843Smsmith
74640843Smsmith    const DebugMap::Entry *debug_map_entry =
74740843Smsmith        m_debug_map.FindEntryThatContains(exe_file_addr);
74840843Smsmith    if (debug_map_entry) {
74940843Smsmith
75040843Smsmith      sc.symbol =
75140843Smsmith          symtab->SymbolAtIndex(debug_map_entry->data.GetExeSymbolIndex());
75240843Smsmith
75340843Smsmith      if (sc.symbol != nullptr) {
75440843Smsmith        resolved_flags |= eSymbolContextSymbol;
75540843Smsmith
75640843Smsmith        uint32_t oso_idx = 0;
75740843Smsmith        CompileUnitInfo *comp_unit_info =
75840843Smsmith            GetCompileUnitInfoForSymbolWithID(sc.symbol->GetID(), &oso_idx);
75940843Smsmith        if (comp_unit_info) {
76040843Smsmith          comp_unit_info->GetFileRangeMap(this);
76140843Smsmith          Module *oso_module = GetModuleByCompUnitInfo(comp_unit_info);
76240843Smsmith          if (oso_module) {
76340843Smsmith            lldb::addr_t oso_file_addr =
76440843Smsmith                exe_file_addr - debug_map_entry->GetRangeBase() +
76540843Smsmith                debug_map_entry->data.GetOSOFileAddress();
76640843Smsmith            Address oso_so_addr;
76740843Smsmith            if (oso_module->ResolveFileAddress(oso_file_addr, oso_so_addr)) {
76840843Smsmith              resolved_flags |=
76940843Smsmith                  oso_module->GetSymbolVendor()->ResolveSymbolContext(
77040843Smsmith                      oso_so_addr, resolve_scope, sc);
77140843Smsmith            }
77240843Smsmith          }
77340843Smsmith        }
77440843Smsmith      }
77540843Smsmith    }
77640843Smsmith  }
77740843Smsmith  return resolved_flags;
77840843Smsmith}
77940843Smsmith
78040843Smsmithuint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext(
78140843Smsmith    const FileSpec &file_spec, uint32_t line, bool check_inlines,
78240843Smsmith    SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
78340843Smsmith  const uint32_t initial = sc_list.GetSize();
78440843Smsmith  const uint32_t cu_count = GetNumCompileUnits();
78540843Smsmith
78640843Smsmith  for (uint32_t i = 0; i < cu_count; ++i) {
78740843Smsmith    // If we are checking for inlines, then we need to look through all compile
78840843Smsmith    // units no matter if "file_spec" matches.
78940843Smsmith    bool resolve = check_inlines;
79040843Smsmith
79140843Smsmith    if (!resolve) {
79240843Smsmith      FileSpec so_file_spec;
79340843Smsmith      if (GetFileSpecForSO(i, so_file_spec)) {
79440843Smsmith        // Match the full path if the incoming file_spec has a directory (not
79540843Smsmith        // just a basename)
79640843Smsmith        const bool full_match = (bool)file_spec.GetDirectory();
79740843Smsmith        resolve = FileSpec::Equal(file_spec, so_file_spec, full_match);
79840843Smsmith      }
79940843Smsmith    }
80042679Sabial    if (resolve) {
80142679Sabial      SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(i);
80242679Sabial      if (oso_dwarf)
80342634Sabial        oso_dwarf->ResolveSymbolContext(file_spec, line, check_inlines,
80442634Sabial                                        resolve_scope, sc_list);
80540843Smsmith    }
80640843Smsmith  }
80740843Smsmith  return sc_list.GetSize() - initial;
80840843Smsmith}
80940843Smsmith
810uint32_t SymbolFileDWARFDebugMap::PrivateFindGlobalVariables(
811    ConstString name, const CompilerDeclContext *parent_decl_ctx,
812    const std::vector<uint32_t>
813        &indexes, // Indexes into the symbol table that match "name"
814    uint32_t max_matches, VariableList &variables) {
815  const uint32_t original_size = variables.GetSize();
816  const size_t match_count = indexes.size();
817  for (size_t i = 0; i < match_count; ++i) {
818    uint32_t oso_idx;
819    CompileUnitInfo *comp_unit_info =
820        GetCompileUnitInfoForSymbolWithIndex(indexes[i], &oso_idx);
821    if (comp_unit_info) {
822      SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
823      if (oso_dwarf) {
824        if (oso_dwarf->FindGlobalVariables(name, parent_decl_ctx, max_matches,
825                                           variables))
826          if (variables.GetSize() > max_matches)
827            break;
828      }
829    }
830  }
831  return variables.GetSize() - original_size;
832}
833
834uint32_t SymbolFileDWARFDebugMap::FindGlobalVariables(
835    ConstString name, const CompilerDeclContext *parent_decl_ctx,
836    uint32_t max_matches, VariableList &variables) {
837
838  // Remember how many variables are in the list before we search.
839  const uint32_t original_size = variables.GetSize();
840
841  uint32_t total_matches = 0;
842
843  ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
844    const uint32_t oso_matches = oso_dwarf->FindGlobalVariables(
845        name, parent_decl_ctx, max_matches, variables);
846    if (oso_matches > 0) {
847      total_matches += oso_matches;
848
849      // Are we getting all matches?
850      if (max_matches == UINT32_MAX)
851        return false; // Yep, continue getting everything
852
853      // If we have found enough matches, lets get out
854      if (max_matches >= total_matches)
855        return true;
856
857      // Update the max matches for any subsequent calls to find globals in any
858      // other object files with DWARF
859      max_matches -= oso_matches;
860    }
861
862    return false;
863  });
864
865  // Return the number of variable that were appended to the list
866  return variables.GetSize() - original_size;
867}
868
869uint32_t
870SymbolFileDWARFDebugMap::FindGlobalVariables(const RegularExpression &regex,
871                                             uint32_t max_matches,
872                                             VariableList &variables) {
873  // Remember how many variables are in the list before we search.
874  const uint32_t original_size = variables.GetSize();
875
876  uint32_t total_matches = 0;
877  ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
878    const uint32_t oso_matches =
879        oso_dwarf->FindGlobalVariables(regex, max_matches, variables);
880    if (oso_matches > 0) {
881      total_matches += oso_matches;
882
883      // Are we getting all matches?
884      if (max_matches == UINT32_MAX)
885        return false; // Yep, continue getting everything
886
887      // If we have found enough matches, lets get out
888      if (max_matches >= total_matches)
889        return true;
890
891      // Update the max matches for any subsequent calls to find globals in any
892      // other object files with DWARF
893      max_matches -= oso_matches;
894    }
895
896    return false;
897  });
898
899  // Return the number of variable that were appended to the list
900  return variables.GetSize() - original_size;
901}
902
903int SymbolFileDWARFDebugMap::SymbolContainsSymbolWithIndex(
904    uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info) {
905  const uint32_t symbol_idx = *symbol_idx_ptr;
906
907  if (symbol_idx < comp_unit_info->first_symbol_index)
908    return -1;
909
910  if (symbol_idx <= comp_unit_info->last_symbol_index)
911    return 0;
912
913  return 1;
914}
915
916int SymbolFileDWARFDebugMap::SymbolContainsSymbolWithID(
917    user_id_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info) {
918  const user_id_t symbol_id = *symbol_idx_ptr;
919
920  if (symbol_id < comp_unit_info->first_symbol_id)
921    return -1;
922
923  if (symbol_id <= comp_unit_info->last_symbol_id)
924    return 0;
925
926  return 1;
927}
928
929SymbolFileDWARFDebugMap::CompileUnitInfo *
930SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithIndex(
931    uint32_t symbol_idx, uint32_t *oso_idx_ptr) {
932  const uint32_t oso_index_count = m_compile_unit_infos.size();
933  CompileUnitInfo *comp_unit_info = nullptr;
934  if (oso_index_count) {
935    comp_unit_info = (CompileUnitInfo *)bsearch(
936        &symbol_idx, &m_compile_unit_infos[0], m_compile_unit_infos.size(),
937        sizeof(CompileUnitInfo),
938        (ComparisonFunction)SymbolContainsSymbolWithIndex);
939  }
940
941  if (oso_idx_ptr) {
942    if (comp_unit_info != nullptr)
943      *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
944    else
945      *oso_idx_ptr = UINT32_MAX;
946  }
947  return comp_unit_info;
948}
949
950SymbolFileDWARFDebugMap::CompileUnitInfo *
951SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithID(
952    user_id_t symbol_id, uint32_t *oso_idx_ptr) {
953  const uint32_t oso_index_count = m_compile_unit_infos.size();
954  CompileUnitInfo *comp_unit_info = nullptr;
955  if (oso_index_count) {
956    comp_unit_info = (CompileUnitInfo *)::bsearch(
957        &symbol_id, &m_compile_unit_infos[0], m_compile_unit_infos.size(),
958        sizeof(CompileUnitInfo),
959        (ComparisonFunction)SymbolContainsSymbolWithID);
960  }
961
962  if (oso_idx_ptr) {
963    if (comp_unit_info != nullptr)
964      *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
965    else
966      *oso_idx_ptr = UINT32_MAX;
967  }
968  return comp_unit_info;
969}
970
971static void RemoveFunctionsWithModuleNotEqualTo(const ModuleSP &module_sp,
972                                                SymbolContextList &sc_list,
973                                                uint32_t start_idx) {
974  // We found functions in .o files. Not all functions in the .o files will
975  // have made it into the final output file. The ones that did make it into
976  // the final output file will have a section whose module matches the module
977  // from the ObjectFile for this SymbolFile. When the modules don't match,
978  // then we have something that was in a .o file, but doesn't map to anything
979  // in the final executable.
980  uint32_t i = start_idx;
981  while (i < sc_list.GetSize()) {
982    SymbolContext sc;
983    sc_list.GetContextAtIndex(i, sc);
984    if (sc.function) {
985      const SectionSP section_sp(
986          sc.function->GetAddressRange().GetBaseAddress().GetSection());
987      if (section_sp->GetModule() != module_sp) {
988        sc_list.RemoveContextAtIndex(i);
989        continue;
990      }
991    }
992    ++i;
993  }
994}
995
996uint32_t SymbolFileDWARFDebugMap::FindFunctions(
997    ConstString name, const CompilerDeclContext *parent_decl_ctx,
998    FunctionNameType name_type_mask, bool include_inlines, bool append,
999    SymbolContextList &sc_list) {
1000  static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
1001  Timer scoped_timer(func_cat,
1002                     "SymbolFileDWARFDebugMap::FindFunctions (name = %s)",
1003                     name.GetCString());
1004
1005  uint32_t initial_size = 0;
1006  if (append)
1007    initial_size = sc_list.GetSize();
1008  else
1009    sc_list.Clear();
1010
1011  ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1012    uint32_t sc_idx = sc_list.GetSize();
1013    if (oso_dwarf->FindFunctions(name, parent_decl_ctx, name_type_mask,
1014                                 include_inlines, true, sc_list)) {
1015      RemoveFunctionsWithModuleNotEqualTo(m_obj_file->GetModule(), sc_list,
1016                                          sc_idx);
1017    }
1018    return false;
1019  });
1020
1021  return sc_list.GetSize() - initial_size;
1022}
1023
1024uint32_t SymbolFileDWARFDebugMap::FindFunctions(const RegularExpression &regex,
1025                                                bool include_inlines,
1026                                                bool append,
1027                                                SymbolContextList &sc_list) {
1028  static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
1029  Timer scoped_timer(func_cat,
1030                     "SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')",
1031                     regex.GetText().str().c_str());
1032
1033  uint32_t initial_size = 0;
1034  if (append)
1035    initial_size = sc_list.GetSize();
1036  else
1037    sc_list.Clear();
1038
1039  ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1040    uint32_t sc_idx = sc_list.GetSize();
1041
1042    if (oso_dwarf->FindFunctions(regex, include_inlines, true, sc_list)) {
1043      RemoveFunctionsWithModuleNotEqualTo(m_obj_file->GetModule(), sc_list,
1044                                          sc_idx);
1045    }
1046    return false;
1047  });
1048
1049  return sc_list.GetSize() - initial_size;
1050}
1051
1052size_t SymbolFileDWARFDebugMap::GetTypes(SymbolContextScope *sc_scope,
1053                                         lldb::TypeClass type_mask,
1054                                         TypeList &type_list) {
1055  static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
1056  Timer scoped_timer(func_cat,
1057                     "SymbolFileDWARFDebugMap::GetTypes (type_mask = 0x%8.8x)",
1058                     type_mask);
1059
1060  uint32_t initial_size = type_list.GetSize();
1061  SymbolFileDWARF *oso_dwarf = nullptr;
1062  if (sc_scope) {
1063    SymbolContext sc;
1064    sc_scope->CalculateSymbolContext(&sc);
1065
1066    CompileUnitInfo *cu_info = GetCompUnitInfo(sc);
1067    if (cu_info) {
1068      oso_dwarf = GetSymbolFileByCompUnitInfo(cu_info);
1069      if (oso_dwarf)
1070        oso_dwarf->GetTypes(sc_scope, type_mask, type_list);
1071    }
1072  } else {
1073    ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1074      oso_dwarf->GetTypes(sc_scope, type_mask, type_list);
1075      return false;
1076    });
1077  }
1078  return type_list.GetSize() - initial_size;
1079}
1080
1081std::vector<lldb_private::CallEdge>
1082SymbolFileDWARFDebugMap::ParseCallEdgesInFunction(UserID func_id) {
1083  uint32_t oso_idx = GetOSOIndexFromUserID(func_id.GetID());
1084  SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
1085  if (oso_dwarf)
1086    return oso_dwarf->ParseCallEdgesInFunction(func_id);
1087  return {};
1088}
1089
1090TypeSP SymbolFileDWARFDebugMap::FindDefinitionTypeForDWARFDeclContext(
1091    const DWARFDeclContext &die_decl_ctx) {
1092  TypeSP type_sp;
1093  ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1094    type_sp = oso_dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
1095    return ((bool)type_sp);
1096  });
1097  return type_sp;
1098}
1099
1100bool SymbolFileDWARFDebugMap::Supports_DW_AT_APPLE_objc_complete_type(
1101    SymbolFileDWARF *skip_dwarf_oso) {
1102  if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate) {
1103    m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
1104    ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1105      if (skip_dwarf_oso != oso_dwarf &&
1106          oso_dwarf->Supports_DW_AT_APPLE_objc_complete_type(nullptr)) {
1107        m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
1108        return true;
1109      }
1110      return false;
1111    });
1112  }
1113  return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
1114}
1115
1116TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE(
1117    const DWARFDIE &die, ConstString type_name,
1118    bool must_be_implementation) {
1119  // If we have a debug map, we will have an Objective-C symbol whose name is
1120  // the type name and whose type is eSymbolTypeObjCClass. If we can find that
1121  // symbol and find its containing parent, we can locate the .o file that will
1122  // contain the implementation definition since it will be scoped inside the
1123  // N_SO and we can then locate the SymbolFileDWARF that corresponds to that
1124  // N_SO.
1125  SymbolFileDWARF *oso_dwarf = nullptr;
1126  TypeSP type_sp;
1127  ObjectFile *module_objfile = m_obj_file->GetModule()->GetObjectFile();
1128  if (module_objfile) {
1129    Symtab *symtab = module_objfile->GetSymtab();
1130    if (symtab) {
1131      Symbol *objc_class_symbol = symtab->FindFirstSymbolWithNameAndType(
1132          type_name, eSymbolTypeObjCClass, Symtab::eDebugAny,
1133          Symtab::eVisibilityAny);
1134      if (objc_class_symbol) {
1135        // Get the N_SO symbol that contains the objective C class symbol as
1136        // this should be the .o file that contains the real definition...
1137        const Symbol *source_file_symbol = symtab->GetParent(objc_class_symbol);
1138
1139        if (source_file_symbol &&
1140            source_file_symbol->GetType() == eSymbolTypeSourceFile) {
1141          const uint32_t source_file_symbol_idx =
1142              symtab->GetIndexForSymbol(source_file_symbol);
1143          if (source_file_symbol_idx != UINT32_MAX) {
1144            CompileUnitInfo *compile_unit_info =
1145                GetCompileUnitInfoForSymbolWithIndex(source_file_symbol_idx,
1146                                                     nullptr);
1147            if (compile_unit_info) {
1148              oso_dwarf = GetSymbolFileByCompUnitInfo(compile_unit_info);
1149              if (oso_dwarf) {
1150                TypeSP type_sp(oso_dwarf->FindCompleteObjCDefinitionTypeForDIE(
1151                    die, type_name, must_be_implementation));
1152                if (type_sp) {
1153                  return type_sp;
1154                }
1155              }
1156            }
1157          }
1158        }
1159      }
1160    }
1161  }
1162
1163  // Only search all .o files for the definition if we don't need the
1164  // implementation because otherwise, with a valid debug map we should have
1165  // the ObjC class symbol and the code above should have found it.
1166  if (!must_be_implementation) {
1167    TypeSP type_sp;
1168
1169    ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1170      type_sp = oso_dwarf->FindCompleteObjCDefinitionTypeForDIE(
1171          die, type_name, must_be_implementation);
1172      return (bool)type_sp;
1173    });
1174
1175    return type_sp;
1176  }
1177  return TypeSP();
1178}
1179
1180uint32_t SymbolFileDWARFDebugMap::FindTypes(
1181    ConstString name, const CompilerDeclContext *parent_decl_ctx,
1182    bool append, uint32_t max_matches,
1183    llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
1184    TypeMap &types) {
1185  if (!append)
1186    types.Clear();
1187
1188  const uint32_t initial_types_size = types.GetSize();
1189
1190  ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1191    oso_dwarf->FindTypes(name, parent_decl_ctx, append, max_matches,
1192                         searched_symbol_files, types);
1193    return types.GetSize() >= max_matches;
1194  });
1195
1196  return types.GetSize() - initial_types_size;
1197}
1198
1199//
1200// uint32_t
1201// SymbolFileDWARFDebugMap::FindTypes (const SymbolContext& sc, const
1202// RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding
1203// encoding, lldb::user_id_t udt_uid, TypeList& types)
1204//{
1205//  SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
1206//  if (oso_dwarf)
1207//      return oso_dwarf->FindTypes (sc, regex, append, max_matches, encoding,
1208//      udt_uid, types);
1209//  return 0;
1210//}
1211
1212CompilerDeclContext SymbolFileDWARFDebugMap::FindNamespace(
1213    lldb_private::ConstString name,
1214    const CompilerDeclContext *parent_decl_ctx) {
1215  CompilerDeclContext matching_namespace;
1216
1217  ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1218    matching_namespace = oso_dwarf->FindNamespace(name, parent_decl_ctx);
1219
1220    return (bool)matching_namespace;
1221  });
1222
1223  return matching_namespace;
1224}
1225
1226void SymbolFileDWARFDebugMap::DumpClangAST(Stream &s) {
1227  ForEachSymbolFile([&s](SymbolFileDWARF *oso_dwarf) -> bool {
1228    oso_dwarf->DumpClangAST(s);
1229    return true;
1230  });
1231}
1232
1233// PluginInterface protocol
1234lldb_private::ConstString SymbolFileDWARFDebugMap::GetPluginName() {
1235  return GetPluginNameStatic();
1236}
1237
1238uint32_t SymbolFileDWARFDebugMap::GetPluginVersion() { return 1; }
1239
1240lldb::CompUnitSP
1241SymbolFileDWARFDebugMap::GetCompileUnit(SymbolFileDWARF *oso_dwarf) {
1242  if (oso_dwarf) {
1243    const uint32_t cu_count = GetNumCompileUnits();
1244    for (uint32_t cu_idx = 0; cu_idx < cu_count; ++cu_idx) {
1245      SymbolFileDWARF *oso_symfile =
1246          GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[cu_idx]);
1247      if (oso_symfile == oso_dwarf) {
1248        if (!m_compile_unit_infos[cu_idx].compile_unit_sp)
1249          m_compile_unit_infos[cu_idx].compile_unit_sp =
1250              ParseCompileUnitAtIndex(cu_idx);
1251
1252        return m_compile_unit_infos[cu_idx].compile_unit_sp;
1253      }
1254    }
1255  }
1256  llvm_unreachable("this shouldn't happen");
1257}
1258
1259SymbolFileDWARFDebugMap::CompileUnitInfo *
1260SymbolFileDWARFDebugMap::GetCompileUnitInfo(SymbolFileDWARF *oso_dwarf) {
1261  if (oso_dwarf) {
1262    const uint32_t cu_count = GetNumCompileUnits();
1263    for (uint32_t cu_idx = 0; cu_idx < cu_count; ++cu_idx) {
1264      SymbolFileDWARF *oso_symfile =
1265          GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[cu_idx]);
1266      if (oso_symfile == oso_dwarf) {
1267        return &m_compile_unit_infos[cu_idx];
1268      }
1269    }
1270  }
1271  return nullptr;
1272}
1273
1274void SymbolFileDWARFDebugMap::SetCompileUnit(SymbolFileDWARF *oso_dwarf,
1275                                             const CompUnitSP &cu_sp) {
1276  if (oso_dwarf) {
1277    const uint32_t cu_count = GetNumCompileUnits();
1278    for (uint32_t cu_idx = 0; cu_idx < cu_count; ++cu_idx) {
1279      SymbolFileDWARF *oso_symfile =
1280          GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[cu_idx]);
1281      if (oso_symfile == oso_dwarf) {
1282        if (m_compile_unit_infos[cu_idx].compile_unit_sp) {
1283          assert(m_compile_unit_infos[cu_idx].compile_unit_sp.get() ==
1284                 cu_sp.get());
1285        } else {
1286          m_compile_unit_infos[cu_idx].compile_unit_sp = cu_sp;
1287          m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(
1288              cu_idx, cu_sp);
1289        }
1290      }
1291    }
1292  }
1293}
1294
1295CompilerDeclContext
1296SymbolFileDWARFDebugMap::GetDeclContextForUID(lldb::user_id_t type_uid) {
1297  const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid);
1298  SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
1299  if (oso_dwarf)
1300    return oso_dwarf->GetDeclContextForUID(type_uid);
1301  return CompilerDeclContext();
1302}
1303
1304CompilerDeclContext
1305SymbolFileDWARFDebugMap::GetDeclContextContainingUID(lldb::user_id_t type_uid) {
1306  const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid);
1307  SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
1308  if (oso_dwarf)
1309    return oso_dwarf->GetDeclContextContainingUID(type_uid);
1310  return CompilerDeclContext();
1311}
1312
1313void SymbolFileDWARFDebugMap::ParseDeclsForContext(
1314    lldb_private::CompilerDeclContext decl_ctx) {
1315  ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1316    oso_dwarf->ParseDeclsForContext(decl_ctx);
1317    return true; // Keep iterating
1318  });
1319}
1320
1321bool SymbolFileDWARFDebugMap::AddOSOFileRange(CompileUnitInfo *cu_info,
1322                                              lldb::addr_t exe_file_addr,
1323                                              lldb::addr_t exe_byte_size,
1324                                              lldb::addr_t oso_file_addr,
1325                                              lldb::addr_t oso_byte_size) {
1326  const uint32_t debug_map_idx =
1327      m_debug_map.FindEntryIndexThatContains(exe_file_addr);
1328  if (debug_map_idx != UINT32_MAX) {
1329    DebugMap::Entry *debug_map_entry =
1330        m_debug_map.FindEntryThatContains(exe_file_addr);
1331    debug_map_entry->data.SetOSOFileAddress(oso_file_addr);
1332    addr_t range_size = std::min<addr_t>(exe_byte_size, oso_byte_size);
1333    if (range_size == 0) {
1334      range_size = std::max<addr_t>(exe_byte_size, oso_byte_size);
1335      if (range_size == 0)
1336        range_size = 1;
1337    }
1338    cu_info->file_range_map.Append(
1339        FileRangeMap::Entry(oso_file_addr, range_size, exe_file_addr));
1340    return true;
1341  }
1342  return false;
1343}
1344
1345void SymbolFileDWARFDebugMap::FinalizeOSOFileRanges(CompileUnitInfo *cu_info) {
1346  cu_info->file_range_map.Sort();
1347#if defined(DEBUG_OSO_DMAP)
1348  const FileRangeMap &oso_file_range_map = cu_info->GetFileRangeMap(this);
1349  const size_t n = oso_file_range_map.GetSize();
1350  printf("SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (cu_info = %p) %s\n",
1351         cu_info, cu_info->oso_sp->module_sp->GetFileSpec().GetPath().c_str());
1352  for (size_t i = 0; i < n; ++i) {
1353    const FileRangeMap::Entry &entry = oso_file_range_map.GetEntryRef(i);
1354    printf("oso [0x%16.16" PRIx64 " - 0x%16.16" PRIx64
1355           ") ==> exe [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n",
1356           entry.GetRangeBase(), entry.GetRangeEnd(), entry.data,
1357           entry.data + entry.GetByteSize());
1358  }
1359#endif
1360}
1361
1362lldb::addr_t
1363SymbolFileDWARFDebugMap::LinkOSOFileAddress(SymbolFileDWARF *oso_symfile,
1364                                            lldb::addr_t oso_file_addr) {
1365  CompileUnitInfo *cu_info = GetCompileUnitInfo(oso_symfile);
1366  if (cu_info) {
1367    const FileRangeMap::Entry *oso_range_entry =
1368        cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
1369    if (oso_range_entry) {
1370      const DebugMap::Entry *debug_map_entry =
1371          m_debug_map.FindEntryThatContains(oso_range_entry->data);
1372      if (debug_map_entry) {
1373        const lldb::addr_t offset =
1374            oso_file_addr - oso_range_entry->GetRangeBase();
1375        const lldb::addr_t exe_file_addr =
1376            debug_map_entry->GetRangeBase() + offset;
1377        return exe_file_addr;
1378      }
1379    }
1380  }
1381  return LLDB_INVALID_ADDRESS;
1382}
1383
1384bool SymbolFileDWARFDebugMap::LinkOSOAddress(Address &addr) {
1385  // Make sure this address hasn't been fixed already
1386  Module *exe_module = GetObjectFile()->GetModule().get();
1387  Module *addr_module = addr.GetModule().get();
1388  if (addr_module == exe_module)
1389    return true; // Address is already in terms of the main executable module
1390
1391  CompileUnitInfo *cu_info = GetCompileUnitInfo(GetSymbolFileAsSymbolFileDWARF(
1392      addr_module->GetSymbolVendor()->GetSymbolFile()));
1393  if (cu_info) {
1394    const lldb::addr_t oso_file_addr = addr.GetFileAddress();
1395    const FileRangeMap::Entry *oso_range_entry =
1396        cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
1397    if (oso_range_entry) {
1398      const DebugMap::Entry *debug_map_entry =
1399          m_debug_map.FindEntryThatContains(oso_range_entry->data);
1400      if (debug_map_entry) {
1401        const lldb::addr_t offset =
1402            oso_file_addr - oso_range_entry->GetRangeBase();
1403        const lldb::addr_t exe_file_addr =
1404            debug_map_entry->GetRangeBase() + offset;
1405        return exe_module->ResolveFileAddress(exe_file_addr, addr);
1406      }
1407    }
1408  }
1409  return true;
1410}
1411
1412LineTable *SymbolFileDWARFDebugMap::LinkOSOLineTable(SymbolFileDWARF *oso_dwarf,
1413                                                     LineTable *line_table) {
1414  CompileUnitInfo *cu_info = GetCompileUnitInfo(oso_dwarf);
1415  if (cu_info)
1416    return line_table->LinkLineTable(cu_info->GetFileRangeMap(this));
1417  return nullptr;
1418}
1419
1420size_t
1421SymbolFileDWARFDebugMap::AddOSOARanges(SymbolFileDWARF *dwarf2Data,
1422                                       DWARFDebugAranges *debug_aranges) {
1423  size_t num_line_entries_added = 0;
1424  if (debug_aranges && dwarf2Data) {
1425    CompileUnitInfo *compile_unit_info = GetCompileUnitInfo(dwarf2Data);
1426    if (compile_unit_info) {
1427      const FileRangeMap &file_range_map =
1428          compile_unit_info->GetFileRangeMap(this);
1429      for (size_t idx = 0; idx < file_range_map.GetSize(); idx++) {
1430        const FileRangeMap::Entry *entry = file_range_map.GetEntryAtIndex(idx);
1431        if (entry) {
1432          debug_aranges->AppendRange(dwarf2Data->GetID(), entry->GetRangeBase(),
1433                                     entry->GetRangeEnd());
1434          num_line_entries_added++;
1435        }
1436      }
1437    }
1438  }
1439  return num_line_entries_added;
1440}
1441