//===-- SymbolFileDWARFDebugMap.cpp -----------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "SymbolFileDWARFDebugMap.h"

#include "DWARFDebugAranges.h"

#include "lldb/Core/RangeMap.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/Section.h"

//#define DEBUG_OSO_DMAP // DO NOT CHECKIN WITH THIS NOT COMMENTED OUT
#if defined(DEBUG_OSO_DMAP)
#include "lldb/Core/StreamFile.h"
#endif
#include "lldb/Core/Timer.h"

#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/TypeMap.h"
#include "lldb/Symbol/VariableList.h"

#include "LogChannelDWARF.h"
#include "SymbolFileDWARF.h"

using namespace lldb;
using namespace lldb_private;

// Subclass lldb_private::Module so we can intercept the "Module::GetObjectFile()" 
// (so we can fixup the object file sections) and also for "Module::GetSymbolVendor()"
// (so we can fixup the symbol file id.

const SymbolFileDWARFDebugMap::FileRangeMap &
SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile)
{
    if (file_range_map_valid)
        return file_range_map;

    file_range_map_valid = true;

    Module *oso_module = exe_symfile->GetModuleByCompUnitInfo (this);
    if (!oso_module)
        return file_range_map;

    ObjectFile *oso_objfile = oso_module->GetObjectFile();
    if (!oso_objfile)
        return file_range_map;

    Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
    if (log)
    {
        ConstString object_name (oso_module->GetObjectName());
        log->Printf("%p: SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap ('%s')",
                    static_cast<void*>(this),
                    oso_module->GetSpecificationDescription().c_str());
    }

    std::vector<SymbolFileDWARFDebugMap::CompileUnitInfo *> cu_infos;
    if (exe_symfile->GetCompUnitInfosForModule(oso_module, cu_infos))
    {
        for (auto comp_unit_info : cu_infos)
        {
            Symtab *exe_symtab = exe_symfile->GetObjectFile()->GetSymtab();
            ModuleSP oso_module_sp (oso_objfile->GetModule());
            Symtab *oso_symtab = oso_objfile->GetSymtab();

            ///const uint32_t fun_resolve_flags = SymbolContext::Module | eSymbolContextCompUnit | eSymbolContextFunction;
            //SectionList *oso_sections = oso_objfile->Sections();
            // Now we need to make sections that map from zero based object
            // file addresses to where things ended up in the main executable.

            assert (comp_unit_info->first_symbol_index != UINT32_MAX);
            // End index is one past the last valid symbol index
            const uint32_t oso_end_idx = comp_unit_info->last_symbol_index + 1;
            for (uint32_t idx = comp_unit_info->first_symbol_index + 2; // Skip the N_SO and N_OSO
                 idx < oso_end_idx;
                 ++idx)
            {
                Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx);
                if (exe_symbol)
                {
                    if (exe_symbol->IsDebug() == false)
                        continue;

                    switch (exe_symbol->GetType())
                    {
                    default:
                        break;

                    case eSymbolTypeCode:
                        {
                            // For each N_FUN, or function that we run into in the debug map
                            // we make a new section that we add to the sections found in the
                            // .o file. This new section has the file address set to what the
                            // addresses are in the .o file, and the load address is adjusted
                            // to match where it ended up in the final executable! We do this
                            // before we parse any dwarf info so that when it goes get parsed
                            // all section/offset addresses that get registered will resolve
                            // correctly to the new addresses in the main executable.

                            // First we find the original symbol in the .o file's symbol table
                            Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled),
                                                                                                 eSymbolTypeCode,
                                                                                                 Symtab::eDebugNo,
                                                                                                 Symtab::eVisibilityAny);
                            if (oso_fun_symbol)
                            {
                                // Add the inverse OSO file address to debug map entry mapping
                                exe_symfile->AddOSOFileRange (this,
                                                              exe_symbol->GetAddressRef().GetFileAddress(),
                                                              exe_symbol->GetByteSize(),
                                                              oso_fun_symbol->GetAddressRef().GetFileAddress(),
                                                              oso_fun_symbol->GetByteSize());

                            }
                        }
                        break;

                    case eSymbolTypeData:
                        {
                            // For each N_GSYM we remap the address for the global by making
                            // a new section that we add to the sections found in the .o file.
                            // This new section has the file address set to what the
                            // addresses are in the .o file, and the load address is adjusted
                            // to match where it ended up in the final executable! We do this
                            // before we parse any dwarf info so that when it goes get parsed
                            // all section/offset addresses that get registered will resolve
                            // correctly to the new addresses in the main executable. We
                            // initially set the section size to be 1 byte, but will need to
                            // fix up these addresses further after all globals have been
                            // parsed to span the gaps, or we can find the global variable
                            // sizes from the DWARF info as we are parsing.

                            // Next we find the non-stab entry that corresponds to the N_GSYM in the .o file
                            Symbol *oso_gsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled),
                                                                                                  eSymbolTypeData,
                                                                                                  Symtab::eDebugNo,
                                                                                                  Symtab::eVisibilityAny);
                            if (exe_symbol && oso_gsym_symbol &&
                                exe_symbol->ValueIsAddress() &&
                                oso_gsym_symbol->ValueIsAddress())
                            {
                                // Add the inverse OSO file address to debug map entry mapping
                                exe_symfile->AddOSOFileRange (this,
                                                              exe_symbol->GetAddressRef().GetFileAddress(),
                                                              exe_symbol->GetByteSize(),
                                                              oso_gsym_symbol->GetAddressRef().GetFileAddress(),
                                                              oso_gsym_symbol->GetByteSize());
                            }
                        }
                        break;
                    }
                }
            }

            exe_symfile->FinalizeOSOFileRanges (this);
            // We don't need the symbols anymore for the .o files
            oso_objfile->ClearSymtab();
        }
    }
    return file_range_map;
}

class DebugMapModule : public Module
{
public:
    DebugMapModule (const ModuleSP &exe_module_sp,
                    uint32_t cu_idx,
                    const FileSpec& file_spec,
                    const ArchSpec& arch,
                    const ConstString *object_name,
                    off_t object_offset,
                    const TimeValue *object_mod_time_ptr) :
        Module (file_spec, arch, object_name, object_offset, object_mod_time_ptr),
        m_exe_module_wp (exe_module_sp),
        m_cu_idx (cu_idx)
    {
    }

    ~DebugMapModule() override = default;

    SymbolVendor*
    GetSymbolVendor(bool can_create = true, lldb_private::Stream *feedback_strm = NULL) override
    {
        // Scope for locker
        if (m_symfile_ap.get() || can_create == false)
            return m_symfile_ap.get();

        ModuleSP exe_module_sp (m_exe_module_wp.lock());
        if (exe_module_sp)
        {
            // Now get the object file outside of a locking scope
            ObjectFile *oso_objfile = GetObjectFile ();
            if (oso_objfile)
            {
                std::lock_guard<std::recursive_mutex> guard(m_mutex);
                SymbolVendor* symbol_vendor = Module::GetSymbolVendor(can_create, feedback_strm);
                if (symbol_vendor)
                {
                    // Set a pointer to this class to set our OSO DWARF file know
                    // that the DWARF is being used along with a debug map and that
                    // it will have the remapped sections that we do below.
                    SymbolFileDWARF *oso_symfile = SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF(symbol_vendor->GetSymbolFile());
                    
                    if (!oso_symfile)
                        return NULL;

                    ObjectFile *exe_objfile = exe_module_sp->GetObjectFile();
                    SymbolVendor *exe_sym_vendor = exe_module_sp->GetSymbolVendor();
                    
                    if (exe_objfile && exe_sym_vendor)
                    {
                        oso_symfile->SetDebugMapModule(exe_module_sp);
                        // Set the ID of the symbol file DWARF to the index of the OSO
                        // shifted left by 32 bits to provide a unique prefix for any
                        // UserID's that get created in the symbol file.
                        oso_symfile->SetID (((uint64_t)m_cu_idx + 1ull) << 32ull);
                    }
                    return symbol_vendor;
                }
            }
        }
        return NULL;
    }

protected:
    ModuleWP m_exe_module_wp;
    const uint32_t m_cu_idx;
};

void
SymbolFileDWARFDebugMap::Initialize()
{
    PluginManager::RegisterPlugin (GetPluginNameStatic(),
                                   GetPluginDescriptionStatic(),
                                   CreateInstance);
}

void
SymbolFileDWARFDebugMap::Terminate()
{
    PluginManager::UnregisterPlugin (CreateInstance);
}

lldb_private::ConstString
SymbolFileDWARFDebugMap::GetPluginNameStatic()
{
    static ConstString g_name("dwarf-debugmap");
    return g_name;
}

const char *
SymbolFileDWARFDebugMap::GetPluginDescriptionStatic()
{
    return "DWARF and DWARF3 debug symbol file reader (debug map).";
}

SymbolFile*
SymbolFileDWARFDebugMap::CreateInstance (ObjectFile* obj_file)
{
    return new SymbolFileDWARFDebugMap (obj_file);
}

SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap (ObjectFile* ofile) :
    SymbolFile(ofile),
    m_flags(),
    m_compile_unit_infos(),
    m_func_indexes(),
    m_glob_indexes(),
    m_supports_DW_AT_APPLE_objc_complete_type (eLazyBoolCalculate)
{
}

SymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap()
{
}

void
SymbolFileDWARFDebugMap::InitializeObject()
{
}

void
SymbolFileDWARFDebugMap::InitOSO()
{
    if (m_flags.test(kHaveInitializedOSOs))
        return;
    
    m_flags.set(kHaveInitializedOSOs);
    
    // If the object file has been stripped, there is no sense in looking further
    // as all of the debug symbols for the debug map will not be available
    if (m_obj_file->IsStripped())
        return;
    
    // Also make sure the file type is some sort of executable. Core files, debug
    // info files (dSYM), object files (.o files), and stub libraries all can
    switch (m_obj_file->GetType())
    {
        case ObjectFile::eTypeInvalid:
        case ObjectFile::eTypeCoreFile:
        case ObjectFile::eTypeDebugInfo:
        case ObjectFile::eTypeObjectFile:
        case ObjectFile::eTypeStubLibrary:
        case ObjectFile::eTypeUnknown:
        case ObjectFile::eTypeJIT:
            return;
            
        case ObjectFile::eTypeExecutable:
        case ObjectFile::eTypeDynamicLinker:
        case ObjectFile::eTypeSharedLibrary:
            break;
    }

    // In order to get the abilities of this plug-in, we look at the list of
    // N_OSO entries (object files) from the symbol table and make sure that
    // these files exist and also contain valid DWARF. If we get any of that
    // then we return the abilities of the first N_OSO's DWARF.

    Symtab* symtab = m_obj_file->GetSymtab();
    if (symtab)
    {
        Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));

        std::vector<uint32_t> oso_indexes;
        // When a mach-o symbol is encoded, the n_type field is encoded in bits
        // 23:16, and the n_desc field is encoded in bits 15:0.
        // 
        // To find all N_OSO entries that are part of the DWARF + debug map
        // we find only object file symbols with the flags value as follows:
        // bits 23:16 == 0x66 (N_OSO)
        // bits 15: 0 == 0x0001 (specifies this is a debug map object file)
        const uint32_t k_oso_symbol_flags_value = 0x660001u;

        const uint32_t oso_index_count = symtab->AppendSymbolIndexesWithTypeAndFlagsValue(eSymbolTypeObjectFile, k_oso_symbol_flags_value, oso_indexes);

        if (oso_index_count > 0)
        {
            symtab->AppendSymbolIndexesWithType (eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, m_func_indexes);
            symtab->AppendSymbolIndexesWithType (eSymbolTypeData, Symtab::eDebugYes, Symtab::eVisibilityAny, m_glob_indexes);

            symtab->SortSymbolIndexesByValue(m_func_indexes, true);
            symtab->SortSymbolIndexesByValue(m_glob_indexes, true);

            for (uint32_t sym_idx : m_func_indexes)
            {
                const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
                lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress();
                lldb::addr_t byte_size = symbol->GetByteSize();
                DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
                m_debug_map.Append(debug_map_entry);
            }
            for (uint32_t sym_idx : m_glob_indexes)
            {
                const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
                lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress();
                lldb::addr_t byte_size = symbol->GetByteSize();
                DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
                m_debug_map.Append(debug_map_entry);
            }
            m_debug_map.Sort();

            m_compile_unit_infos.resize(oso_index_count);

            for (uint32_t i=0; i<oso_index_count; ++i)
            {
                const uint32_t so_idx = oso_indexes[i] - 1;
                const uint32_t oso_idx = oso_indexes[i];
                const Symbol *so_symbol = symtab->SymbolAtIndex(so_idx);
                const Symbol *oso_symbol = symtab->SymbolAtIndex(oso_idx);
                if (so_symbol &&
                    oso_symbol &&
                    so_symbol->GetType() == eSymbolTypeSourceFile &&
                    oso_symbol->GetType() == eSymbolTypeObjectFile)
                {
                    m_compile_unit_infos[i].so_file.SetFile(so_symbol->GetName().AsCString(), false);
                    m_compile_unit_infos[i].oso_path = oso_symbol->GetName();
                    TimeValue oso_mod_time;
                    oso_mod_time.OffsetWithSeconds(oso_symbol->GetIntegerValue(0));
                    m_compile_unit_infos[i].oso_mod_time = oso_mod_time;
                    uint32_t sibling_idx = so_symbol->GetSiblingIndex();
                    // The sibling index can't be less that or equal to the current index "i"
                    if (sibling_idx == UINT32_MAX)
                    {
                        m_obj_file->GetModule()->ReportError ("N_SO in symbol with UID %u has invalid sibling in debug map, please file a bug and attach the binary listed in this error", so_symbol->GetID());
                    }
                    else
                    {
                        const Symbol* last_symbol = symtab->SymbolAtIndex (sibling_idx - 1);
                        m_compile_unit_infos[i].first_symbol_index = so_idx;
                        m_compile_unit_infos[i].last_symbol_index = sibling_idx - 1;
                        m_compile_unit_infos[i].first_symbol_id = so_symbol->GetID();
                        m_compile_unit_infos[i].last_symbol_id = last_symbol->GetID();
                        
                        if (log)
                            log->Printf("Initialized OSO 0x%8.8x: file=%s", i, oso_symbol->GetName().GetCString());
                    }
                }
                else
                {
                    if (oso_symbol == NULL)
                        m_obj_file->GetModule()->ReportError ("N_OSO symbol[%u] can't be found, please file a bug and attach the binary listed in this error", oso_idx);
                    else if (so_symbol == NULL)
                        m_obj_file->GetModule()->ReportError ("N_SO not found for N_OSO symbol[%u], please file a bug and attach the binary listed in this error", oso_idx);
                    else if (so_symbol->GetType() != eSymbolTypeSourceFile)
                        m_obj_file->GetModule()->ReportError ("N_SO has incorrect symbol type (%u) for N_OSO symbol[%u], please file a bug and attach the binary listed in this error", so_symbol->GetType(), oso_idx);
                    else if (oso_symbol->GetType() != eSymbolTypeSourceFile)
                        m_obj_file->GetModule()->ReportError ("N_OSO has incorrect symbol type (%u) for N_OSO symbol[%u], please file a bug and attach the binary listed in this error", oso_symbol->GetType(), oso_idx);
                }
            }
        }
    }
}

Module *
SymbolFileDWARFDebugMap::GetModuleByOSOIndex (uint32_t oso_idx)
{
    const uint32_t cu_count = GetNumCompileUnits();
    if (oso_idx < cu_count)
        return GetModuleByCompUnitInfo (&m_compile_unit_infos[oso_idx]);
    return NULL;
}

Module *
SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo (CompileUnitInfo *comp_unit_info)
{
    if (!comp_unit_info->oso_sp)
    {
        auto pos = m_oso_map.find (comp_unit_info->oso_path);
        if (pos != m_oso_map.end())
        {
            comp_unit_info->oso_sp = pos->second;
        }
        else
        {
            ObjectFile *obj_file = GetObjectFile();
            comp_unit_info->oso_sp.reset (new OSOInfo());
            m_oso_map[comp_unit_info->oso_path] = comp_unit_info->oso_sp;
            const char *oso_path = comp_unit_info->oso_path.GetCString();
            FileSpec oso_file (oso_path, false);
            ConstString oso_object;
            if (oso_file.Exists())
            {
                TimeValue oso_mod_time (oso_file.GetModificationTime());
                if (oso_mod_time != comp_unit_info->oso_mod_time)
                {
                    obj_file->GetModule()->ReportError ("debug map object file '%s' has changed (actual time is 0x%" PRIx64 ", debug map time is 0x%" PRIx64 ") since this executable was linked, file will be ignored",
                                                        oso_file.GetPath().c_str(),
                                                        oso_mod_time.GetAsSecondsSinceJan1_1970(),
                                                        comp_unit_info->oso_mod_time.GetAsSecondsSinceJan1_1970());
                    return NULL;
                }

            }
            else
            {
                const bool must_exist = true;

                if (!ObjectFile::SplitArchivePathWithObject (oso_path,
                                                             oso_file,
                                                             oso_object,
                                                             must_exist))
                {
                    return NULL;
                }
            }
            // Always create a new module for .o files. Why? Because we
            // use the debug map, to add new sections to each .o file and
            // even though a .o file might not have changed, the sections
            // that get added to the .o file can change.
            ArchSpec oso_arch;
            // Only adopt the architecture from the module (not the vendor or OS)
            // since .o files for "i386-apple-ios" will historically show up as "i386-apple-macosx"
            // due to the lack of a LC_VERSION_MIN_MACOSX or LC_VERSION_MIN_IPHONEOS
            // load command...
            oso_arch.SetTriple(m_obj_file->GetModule()->GetArchitecture().GetTriple().getArchName().str().c_str());
            comp_unit_info->oso_sp->module_sp.reset (new DebugMapModule (obj_file->GetModule(),
                                                                         GetCompUnitInfoIndex(comp_unit_info),
                                                                         oso_file,
                                                                         oso_arch,
                                                                         oso_object ? &oso_object : NULL,
                                                                         0,
                                                                         oso_object ? &comp_unit_info->oso_mod_time : NULL));
        }
    }
    if (comp_unit_info->oso_sp)
        return comp_unit_info->oso_sp->module_sp.get();
    return NULL;
}

bool
SymbolFileDWARFDebugMap::GetFileSpecForSO (uint32_t oso_idx, FileSpec &file_spec)
{
    if (oso_idx < m_compile_unit_infos.size())
    {
        if (m_compile_unit_infos[oso_idx].so_file)
        {
            file_spec = m_compile_unit_infos[oso_idx].so_file;
            return true;
        }
    }
    return false;
}

ObjectFile *
SymbolFileDWARFDebugMap::GetObjectFileByOSOIndex (uint32_t oso_idx)
{
    Module *oso_module = GetModuleByOSOIndex (oso_idx);
    if (oso_module)
        return oso_module->GetObjectFile();
    return NULL;
}

SymbolFileDWARF *
SymbolFileDWARFDebugMap::GetSymbolFile (const SymbolContext& sc)
{
    CompileUnitInfo *comp_unit_info = GetCompUnitInfo (sc);
    if (comp_unit_info)
        return GetSymbolFileByCompUnitInfo (comp_unit_info);
    return NULL;
}

ObjectFile *
SymbolFileDWARFDebugMap::GetObjectFileByCompUnitInfo (CompileUnitInfo *comp_unit_info)
{
    Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
    if (oso_module)
        return oso_module->GetObjectFile();
    return NULL;
}

uint32_t
SymbolFileDWARFDebugMap::GetCompUnitInfoIndex (const CompileUnitInfo *comp_unit_info)
{
    if (!m_compile_unit_infos.empty())
    {
        const CompileUnitInfo *first_comp_unit_info = &m_compile_unit_infos.front();
        const CompileUnitInfo *last_comp_unit_info = &m_compile_unit_infos.back();
        if (first_comp_unit_info <= comp_unit_info && comp_unit_info <= last_comp_unit_info)
            return comp_unit_info - first_comp_unit_info;
    }
    return UINT32_MAX;
}

SymbolFileDWARF *
SymbolFileDWARFDebugMap::GetSymbolFileByOSOIndex (uint32_t oso_idx)
{
    if (oso_idx < m_compile_unit_infos.size())
        return GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[oso_idx]);
    return NULL;
}

SymbolFileDWARF *
SymbolFileDWARFDebugMap::GetSymbolFileAsSymbolFileDWARF (SymbolFile *sym_file)
{
    if (sym_file && sym_file->GetPluginName() == SymbolFileDWARF::GetPluginNameStatic())
        return (SymbolFileDWARF *)sym_file;
    return NULL;
}

SymbolFileDWARF *
SymbolFileDWARFDebugMap::GetSymbolFileByCompUnitInfo (CompileUnitInfo *comp_unit_info)
{
    Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
    if (oso_module)
    {
        SymbolVendor *sym_vendor = oso_module->GetSymbolVendor();
        if (sym_vendor)
            return GetSymbolFileAsSymbolFileDWARF (sym_vendor->GetSymbolFile());
    }
    return NULL;
}

uint32_t
SymbolFileDWARFDebugMap::CalculateAbilities ()
{
    // In order to get the abilities of this plug-in, we look at the list of
    // N_OSO entries (object files) from the symbol table and make sure that
    // these files exist and also contain valid DWARF. If we get any of that
    // then we return the abilities of the first N_OSO's DWARF.

    const uint32_t oso_index_count = GetNumCompileUnits();
    if (oso_index_count > 0)
    {
        InitOSO();
        if (!m_compile_unit_infos.empty())
        {
            return SymbolFile::CompileUnits    |
                   SymbolFile::Functions       |
                   SymbolFile::Blocks          |
                   SymbolFile::GlobalVariables |
                   SymbolFile::LocalVariables  |
                   SymbolFile::VariableTypes   |
                   SymbolFile::LineTables      ;
        }
    }
    return 0;
}

uint32_t
SymbolFileDWARFDebugMap::GetNumCompileUnits()
{
    InitOSO ();
    return m_compile_unit_infos.size();
}

CompUnitSP
SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx)
{
    CompUnitSP comp_unit_sp;
    const uint32_t cu_count = GetNumCompileUnits();

    if (cu_idx < cu_count)
    {
        Module *oso_module = GetModuleByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
        if (oso_module)
        {
            FileSpec so_file_spec;
            if (GetFileSpecForSO (cu_idx, so_file_spec))
            {
                // User zero as the ID to match the compile unit at offset
                // zero in each .o file since each .o file can only have
                // one compile unit for now.
                lldb::user_id_t cu_id = 0;
                m_compile_unit_infos[cu_idx].compile_unit_sp.reset(new CompileUnit(
                    m_obj_file->GetModule(), NULL, so_file_spec, cu_id, eLanguageTypeUnknown, eLazyBoolCalculate));

                if (m_compile_unit_infos[cu_idx].compile_unit_sp)
                {
                    // Let our symbol vendor know about this compile unit
                    m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex (cu_idx, m_compile_unit_infos[cu_idx].compile_unit_sp);
                }
            }
        }
        comp_unit_sp = m_compile_unit_infos[cu_idx].compile_unit_sp;
    }

    return comp_unit_sp;
}

SymbolFileDWARFDebugMap::CompileUnitInfo *
SymbolFileDWARFDebugMap::GetCompUnitInfo (const SymbolContext& sc)
{
    const uint32_t cu_count = GetNumCompileUnits();
    for (uint32_t i=0; i<cu_count; ++i)
    {
        if (sc.comp_unit == m_compile_unit_infos[i].compile_unit_sp.get())
            return &m_compile_unit_infos[i];
    }
    return NULL;
}

size_t
SymbolFileDWARFDebugMap::GetCompUnitInfosForModule (const lldb_private::Module *module, std::vector<CompileUnitInfo *>& cu_infos)
{
    const uint32_t cu_count = GetNumCompileUnits();
    for (uint32_t i=0; i<cu_count; ++i)
    {
        if (module == GetModuleByCompUnitInfo (&m_compile_unit_infos[i]))
            cu_infos.push_back (&m_compile_unit_infos[i]);
    }
    return cu_infos.size();
}

lldb::LanguageType
SymbolFileDWARFDebugMap::ParseCompileUnitLanguage (const SymbolContext& sc)
{
    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
    if (oso_dwarf)
        return oso_dwarf->ParseCompileUnitLanguage (sc);
    return eLanguageTypeUnknown;
}

size_t
SymbolFileDWARFDebugMap::ParseCompileUnitFunctions (const SymbolContext& sc)
{
    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
    if (oso_dwarf)
        return oso_dwarf->ParseCompileUnitFunctions (sc);
    return 0;
}

bool
SymbolFileDWARFDebugMap::ParseCompileUnitLineTable (const SymbolContext& sc)
{
    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
    if (oso_dwarf)
        return oso_dwarf->ParseCompileUnitLineTable (sc);
    return false;
}

bool
SymbolFileDWARFDebugMap::ParseCompileUnitDebugMacros (const SymbolContext& sc)
{
    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
    if (oso_dwarf)
        return oso_dwarf->ParseCompileUnitDebugMacros (sc);
    return false;
}

bool
SymbolFileDWARFDebugMap::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList &support_files)
{
    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
    if (oso_dwarf)
        return oso_dwarf->ParseCompileUnitSupportFiles (sc, support_files);
    return false;
}

bool
SymbolFileDWARFDebugMap::ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc)
{
    SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc);
    if (oso_dwarf)
        return oso_dwarf->ParseCompileUnitIsOptimized(sc);
    return false;
}

bool
SymbolFileDWARFDebugMap::ParseImportedModules(const SymbolContext &sc, std::vector<ConstString> &imported_modules)
{
    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
    if (oso_dwarf)
        return oso_dwarf->ParseImportedModules(sc, imported_modules);
    return false;
}

size_t
SymbolFileDWARFDebugMap::ParseFunctionBlocks (const SymbolContext& sc)
{
    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
    if (oso_dwarf)
        return oso_dwarf->ParseFunctionBlocks (sc);
    return 0;
}

size_t
SymbolFileDWARFDebugMap::ParseTypes (const SymbolContext& sc)
{
    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
    if (oso_dwarf)
        return oso_dwarf->ParseTypes (sc);
    return 0;
}

size_t
SymbolFileDWARFDebugMap::ParseVariablesForContext (const SymbolContext& sc)
{
    SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
    if (oso_dwarf)
        return oso_dwarf->ParseVariablesForContext (sc);
    return 0;
}

Type*
SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid)
{
    const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
    SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
    if (oso_dwarf)
        return oso_dwarf->ResolveTypeUID (type_uid);
    return NULL;
}

bool
SymbolFileDWARFDebugMap::CompleteType (CompilerType& compiler_type)
{
    bool success = false;
    if (compiler_type)
    {
        ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
            if (oso_dwarf->HasForwardDeclForClangType (compiler_type))
            {
                oso_dwarf->CompleteType (compiler_type);
                success = true;
                return true;
            }
            return false;
        });
    }
    return success;
}

uint32_t
SymbolFileDWARFDebugMap::ResolveSymbolContext (const Address& exe_so_addr, uint32_t resolve_scope, SymbolContext& sc)
{
    uint32_t resolved_flags = 0;
    Symtab* symtab = m_obj_file->GetSymtab();
    if (symtab)
    {
        const addr_t exe_file_addr = exe_so_addr.GetFileAddress();

        const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains (exe_file_addr);
        if (debug_map_entry)
        {

            sc.symbol = symtab->SymbolAtIndex(debug_map_entry->data.GetExeSymbolIndex());

            if (sc.symbol != NULL)
            {
                resolved_flags |= eSymbolContextSymbol;

                uint32_t oso_idx = 0;
                CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithID (sc.symbol->GetID(), &oso_idx);
                if (comp_unit_info)
                {
                    comp_unit_info->GetFileRangeMap(this);
                    Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
                    if (oso_module)
                    {
                        lldb::addr_t oso_file_addr = exe_file_addr - debug_map_entry->GetRangeBase() + debug_map_entry->data.GetOSOFileAddress();
                        Address oso_so_addr;
                        if (oso_module->ResolveFileAddress(oso_file_addr, oso_so_addr))
                        {
                            resolved_flags |= oso_module->GetSymbolVendor()->ResolveSymbolContext (oso_so_addr, resolve_scope, sc);
                        }
                    }
                }
            }
        }
    }
    return resolved_flags;
}

uint32_t
SymbolFileDWARFDebugMap::ResolveSymbolContext (const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
{
    const uint32_t initial = sc_list.GetSize();
    const uint32_t cu_count = GetNumCompileUnits();

    for (uint32_t i=0; i<cu_count; ++i)
    {
        // If we are checking for inlines, then we need to look through all
        // compile units no matter if "file_spec" matches.
        bool resolve = check_inlines;
        
        if (!resolve)
        {
            FileSpec so_file_spec;
            if (GetFileSpecForSO (i, so_file_spec))
            {
                // Match the full path if the incoming file_spec has a directory (not just a basename)
                const bool full_match = (bool)file_spec.GetDirectory();
                resolve = FileSpec::Equal (file_spec, so_file_spec, full_match);
            }
        }
        if (resolve)
        {
            SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (i);
            if (oso_dwarf)
                oso_dwarf->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope, sc_list);
        }
    }
    return sc_list.GetSize() - initial;
}

uint32_t
SymbolFileDWARFDebugMap::PrivateFindGlobalVariables
(
    const ConstString &name,
    const CompilerDeclContext *parent_decl_ctx,
    const std::vector<uint32_t> &indexes,   // Indexes into the symbol table that match "name"
    uint32_t max_matches,
    VariableList& variables
)
{
    const uint32_t original_size = variables.GetSize();
    const size_t match_count = indexes.size();
    for (size_t i=0; i<match_count; ++i)
    {
        uint32_t oso_idx;
        CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithIndex (indexes[i], &oso_idx);
        if (comp_unit_info)
        {
            SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
            if (oso_dwarf)
            {
                if (oso_dwarf->FindGlobalVariables(name, parent_decl_ctx, true, max_matches, variables))
                    if (variables.GetSize() > max_matches)
                        break;
            }
        }
    }
    return variables.GetSize() - original_size;
}

uint32_t
SymbolFileDWARFDebugMap::FindGlobalVariables (const ConstString &name,
                                              const CompilerDeclContext *parent_decl_ctx,
                                              bool append,
                                              uint32_t max_matches,
                                              VariableList& variables)
{

    // If we aren't appending the results to this list, then clear the list
    if (!append)
        variables.Clear();

    // Remember how many variables are in the list before we search in case
    // we are appending the results to a variable list.
    const uint32_t original_size = variables.GetSize();

    uint32_t total_matches = 0;
    
    ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
        const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (name,
                                                                     parent_decl_ctx,
                                                                     true,
                                                                     max_matches,
                                                                     variables);
        if (oso_matches > 0)
        {
            total_matches += oso_matches;
            
            // Are we getting all matches?
            if (max_matches == UINT32_MAX)
                return false;   // Yep, continue getting everything
            
            // If we have found enough matches, lets get out
            if (max_matches >= total_matches)
                return true;
            
            // Update the max matches for any subsequent calls to find globals
            // in any other object files with DWARF
            max_matches -= oso_matches;
        }
        
        return false;
    });

    // Return the number of variable that were appended to the list
    return variables.GetSize() - original_size;
}

uint32_t
SymbolFileDWARFDebugMap::FindGlobalVariables (const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
{
    // If we aren't appending the results to this list, then clear the list
    if (!append)
        variables.Clear();

    // Remember how many variables are in the list before we search in case
    // we are appending the results to a variable list.
    const uint32_t original_size = variables.GetSize();

    uint32_t total_matches = 0;
    ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
        const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (regex,
                                                                     true, 
                                                                     max_matches, 
                                                                     variables);
        if (oso_matches > 0)
        {
            total_matches += oso_matches;

            // Are we getting all matches?
            if (max_matches == UINT32_MAX)
                return false;   // Yep, continue getting everything

            // If we have found enough matches, lets get out
            if (max_matches >= total_matches)
                return true;

            // Update the max matches for any subsequent calls to find globals
            // in any other object files with DWARF
            max_matches -= oso_matches;
        }
        
        return false;
    });
        
    // Return the number of variable that were appended to the list
    return variables.GetSize() - original_size;
}

int
SymbolFileDWARFDebugMap::SymbolContainsSymbolWithIndex (uint32_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info)
{
    const uint32_t symbol_idx = *symbol_idx_ptr;

    if (symbol_idx < comp_unit_info->first_symbol_index)
        return -1;

    if (symbol_idx <= comp_unit_info->last_symbol_index)
        return 0;

    return 1;
}

int
SymbolFileDWARFDebugMap::SymbolContainsSymbolWithID (user_id_t *symbol_idx_ptr, const CompileUnitInfo *comp_unit_info)
{
    const user_id_t symbol_id = *symbol_idx_ptr;

    if (symbol_id < comp_unit_info->first_symbol_id)
        return -1;

    if (symbol_id <= comp_unit_info->last_symbol_id)
        return 0;

    return 1;
}

SymbolFileDWARFDebugMap::CompileUnitInfo*
SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithIndex (uint32_t symbol_idx, uint32_t *oso_idx_ptr)
{
    const uint32_t oso_index_count = m_compile_unit_infos.size();
    CompileUnitInfo *comp_unit_info = NULL;
    if (oso_index_count)
    {
        comp_unit_info = (CompileUnitInfo*)bsearch(&symbol_idx, 
                                                   &m_compile_unit_infos[0], 
                                                   m_compile_unit_infos.size(), 
                                                   sizeof(CompileUnitInfo), 
                                                   (ComparisonFunction)SymbolContainsSymbolWithIndex);
    }

    if (oso_idx_ptr)
    {
        if (comp_unit_info != NULL)
            *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
        else
            *oso_idx_ptr = UINT32_MAX;
    }
    return comp_unit_info;
}

SymbolFileDWARFDebugMap::CompileUnitInfo*
SymbolFileDWARFDebugMap::GetCompileUnitInfoForSymbolWithID (user_id_t symbol_id, uint32_t *oso_idx_ptr)
{
    const uint32_t oso_index_count = m_compile_unit_infos.size();
    CompileUnitInfo *comp_unit_info = NULL;
    if (oso_index_count)
    {
        comp_unit_info = (CompileUnitInfo*)::bsearch (&symbol_id, 
                                                      &m_compile_unit_infos[0], 
                                                      m_compile_unit_infos.size(), 
                                                      sizeof(CompileUnitInfo), 
                                                      (ComparisonFunction)SymbolContainsSymbolWithID);
    }

    if (oso_idx_ptr)
    {
        if (comp_unit_info != NULL)
            *oso_idx_ptr = comp_unit_info - &m_compile_unit_infos[0];
        else
            *oso_idx_ptr = UINT32_MAX;
    }
    return comp_unit_info;
}

static void
RemoveFunctionsWithModuleNotEqualTo (const ModuleSP &module_sp, SymbolContextList &sc_list, uint32_t start_idx)
{
    // We found functions in .o files. Not all functions in the .o files
    // will have made it into the final output file. The ones that did
    // make it into the final output file will have a section whose module
    // matches the module from the ObjectFile for this SymbolFile. When
    // the modules don't match, then we have something that was in a
    // .o file, but doesn't map to anything in the final executable.
    uint32_t i=start_idx;
    while (i < sc_list.GetSize())
    {
        SymbolContext sc;
        sc_list.GetContextAtIndex(i, sc);
        if (sc.function)
        {
            const SectionSP section_sp (sc.function->GetAddressRange().GetBaseAddress().GetSection());
            if (section_sp->GetModule() != module_sp)
            {
                sc_list.RemoveContextAtIndex(i);
                continue;
            }
        }
        ++i;
    }
}

uint32_t
SymbolFileDWARFDebugMap::FindFunctions(const ConstString &name,
                                       const CompilerDeclContext *parent_decl_ctx,
                                       uint32_t name_type_mask,
                                       bool include_inlines,
                                       bool append,
                                       SymbolContextList& sc_list)
{
    Timer scoped_timer (__PRETTY_FUNCTION__,
                        "SymbolFileDWARFDebugMap::FindFunctions (name = %s)",
                        name.GetCString());

    uint32_t initial_size = 0;
    if (append)
        initial_size = sc_list.GetSize();
    else
        sc_list.Clear();

    ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
        uint32_t sc_idx = sc_list.GetSize();
        if (oso_dwarf->FindFunctions(name, parent_decl_ctx, name_type_mask, include_inlines, true, sc_list))
        {
            RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx);
        }
        return false;
    });

    return sc_list.GetSize() - initial_size;
}

uint32_t
SymbolFileDWARFDebugMap::FindFunctions (const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list)
{
    Timer scoped_timer (__PRETTY_FUNCTION__,
                        "SymbolFileDWARFDebugMap::FindFunctions (regex = '%s')",
                        regex.GetText());

    uint32_t initial_size = 0;
    if (append)
        initial_size = sc_list.GetSize();
    else
        sc_list.Clear();

    ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
        uint32_t sc_idx = sc_list.GetSize();
        
        if (oso_dwarf->FindFunctions(regex, include_inlines, true, sc_list))
        {
            RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx);
        }
        return false;
    });

    return sc_list.GetSize() - initial_size;
}

size_t
SymbolFileDWARFDebugMap::GetTypes (SymbolContextScope *sc_scope,
                                   uint32_t type_mask,
                                   TypeList &type_list)
{
    Timer scoped_timer (__PRETTY_FUNCTION__,
                        "SymbolFileDWARFDebugMap::GetTypes (type_mask = 0x%8.8x)",
                        type_mask);

    uint32_t initial_size = type_list.GetSize();
    SymbolFileDWARF *oso_dwarf = NULL;
    if (sc_scope)
    {
        SymbolContext sc;
        sc_scope->CalculateSymbolContext(&sc);
        
        CompileUnitInfo *cu_info = GetCompUnitInfo (sc);
        if (cu_info)
        {
            oso_dwarf = GetSymbolFileByCompUnitInfo (cu_info);
            if (oso_dwarf)
                oso_dwarf->GetTypes (sc_scope, type_mask, type_list);
        }
    }
    else
    {
        ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
            oso_dwarf->GetTypes (sc_scope, type_mask, type_list);
            return false;
        });
    }
    return type_list.GetSize() - initial_size;
}

TypeSP
SymbolFileDWARFDebugMap::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx)
{
    TypeSP type_sp;
    ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
        type_sp = oso_dwarf->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx);
        return ((bool)type_sp);
    });
    return type_sp;
}

bool
SymbolFileDWARFDebugMap::Supports_DW_AT_APPLE_objc_complete_type (SymbolFileDWARF *skip_dwarf_oso)
{
    if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate)
    {
        m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
        ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
            if (skip_dwarf_oso != oso_dwarf && oso_dwarf->Supports_DW_AT_APPLE_objc_complete_type(NULL))
            {
                m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
                return true;
            }
            return false;
        });
    }
    return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
}

TypeSP
SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE (const DWARFDIE &die,
                                                               const ConstString &type_name,
                                                               bool must_be_implementation)
{
    // If we have a debug map, we will have an Objective C symbol whose name is
    // the type name and whose type is eSymbolTypeObjCClass. If we can find that
    // symbol and find its containing parent, we can locate the .o file that will
    // contain the implementation definition since it will be scoped inside the N_SO
    // and we can then locate the SymbolFileDWARF that corresponds to that N_SO.
    SymbolFileDWARF *oso_dwarf = NULL;
    TypeSP type_sp;
    ObjectFile *module_objfile = m_obj_file->GetModule()->GetObjectFile();
    if (module_objfile)
    {
        Symtab *symtab = module_objfile->GetSymtab();
        if (symtab)
        {
            Symbol *objc_class_symbol = symtab->FindFirstSymbolWithNameAndType(type_name, eSymbolTypeObjCClass, Symtab::eDebugAny, Symtab::eVisibilityAny);
            if (objc_class_symbol)
            {
                // Get the N_SO symbol that contains the objective C class symbol as this
                // should be the .o file that contains the real definition...
                const Symbol *source_file_symbol = symtab->GetParent(objc_class_symbol);

                if (source_file_symbol && source_file_symbol->GetType() == eSymbolTypeSourceFile)
                {
                    const uint32_t source_file_symbol_idx = symtab->GetIndexForSymbol(source_file_symbol);
                    if (source_file_symbol_idx != UINT32_MAX)
                    {
                        CompileUnitInfo *compile_unit_info = GetCompileUnitInfoForSymbolWithIndex (source_file_symbol_idx, NULL);
                        if (compile_unit_info)
                        {
                            oso_dwarf = GetSymbolFileByCompUnitInfo (compile_unit_info);
                            if (oso_dwarf)
                            {
                                TypeSP type_sp (oso_dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name, must_be_implementation));
                                if (type_sp)
                                {
                                    return type_sp;
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    // Only search all .o files for the definition if we don't need the implementation
    // because otherwise, with a valid debug map we should have the ObjC class symbol and
    // the code above should have found it.
    if (must_be_implementation == false)
    {
        TypeSP type_sp;
        
        ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
            type_sp = oso_dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name, must_be_implementation);
            return (bool)type_sp;
        });
        
        return type_sp;
    }
    return TypeSP();
}

uint32_t
SymbolFileDWARFDebugMap::FindTypes 
(
    const SymbolContext& sc, 
    const ConstString &name,
    const CompilerDeclContext *parent_decl_ctx,
    bool append,
    uint32_t max_matches,
    llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
    TypeMap& types
)
{
    if (!append)
        types.Clear();

    const uint32_t initial_types_size = types.GetSize();
    SymbolFileDWARF *oso_dwarf;

    if (sc.comp_unit)
    {
        oso_dwarf = GetSymbolFile (sc);
        if (oso_dwarf)
            return oso_dwarf->FindTypes (sc, name, parent_decl_ctx, append, max_matches, searched_symbol_files, types);
    }
    else
    {
        ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
            oso_dwarf->FindTypes (sc, name, parent_decl_ctx, append, max_matches, searched_symbol_files, types);
            if (types.GetSize() >= max_matches)
                return true;
            else
                return false;
        });
    }

    return types.GetSize() - initial_types_size;
}

//
//uint32_t
//SymbolFileDWARFDebugMap::FindTypes (const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types)
//{
//  SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc);
//  if (oso_dwarf)
//      return oso_dwarf->FindTypes (sc, regex, append, max_matches, encoding, udt_uid, types);
//  return 0;
//}


CompilerDeclContext
SymbolFileDWARFDebugMap::FindNamespace (const lldb_private::SymbolContext& sc, 
                                        const lldb_private::ConstString &name,
                                        const CompilerDeclContext *parent_decl_ctx)
{
    CompilerDeclContext matching_namespace;
    SymbolFileDWARF *oso_dwarf;

    if (sc.comp_unit)
    {
        oso_dwarf = GetSymbolFile (sc);
        if (oso_dwarf)
            matching_namespace = oso_dwarf->FindNamespace (sc, name, parent_decl_ctx);
    }
    else
    {
        ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
            matching_namespace = oso_dwarf->FindNamespace (sc, name, parent_decl_ctx);

            return (bool)matching_namespace;
        });
    }

    return matching_namespace;
}

//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
lldb_private::ConstString
SymbolFileDWARFDebugMap::GetPluginName()
{
    return GetPluginNameStatic();
}

uint32_t
SymbolFileDWARFDebugMap::GetPluginVersion()
{
    return 1;
}

lldb::CompUnitSP
SymbolFileDWARFDebugMap::GetCompileUnit (SymbolFileDWARF *oso_dwarf)
{
    if (oso_dwarf)
    {
        const uint32_t cu_count = GetNumCompileUnits();
        for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
        {
            SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
            if (oso_symfile == oso_dwarf)
            {
                if (!m_compile_unit_infos[cu_idx].compile_unit_sp)
                    m_compile_unit_infos[cu_idx].compile_unit_sp = ParseCompileUnitAtIndex (cu_idx);

                return m_compile_unit_infos[cu_idx].compile_unit_sp;
            }
        }
    }
    assert(!"this shouldn't happen");
    return lldb::CompUnitSP();
}

SymbolFileDWARFDebugMap::CompileUnitInfo *
SymbolFileDWARFDebugMap::GetCompileUnitInfo (SymbolFileDWARF *oso_dwarf)
{
    if (oso_dwarf)
    {
        const uint32_t cu_count = GetNumCompileUnits();
        for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
        {
            SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
            if (oso_symfile == oso_dwarf)
            {
                return &m_compile_unit_infos[cu_idx];
            }
        }
    }
    return NULL;
}

void
SymbolFileDWARFDebugMap::SetCompileUnit (SymbolFileDWARF *oso_dwarf, const CompUnitSP &cu_sp)
{
    if (oso_dwarf)
    {
        const uint32_t cu_count = GetNumCompileUnits();
        for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
        {
            SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
            if (oso_symfile == oso_dwarf)
            {
                if (m_compile_unit_infos[cu_idx].compile_unit_sp)
                {
                    assert (m_compile_unit_infos[cu_idx].compile_unit_sp.get() == cu_sp.get());
                }
                else
                {
                    m_compile_unit_infos[cu_idx].compile_unit_sp = cu_sp;
                    m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp);
                }
            }
        }
    }
}

CompilerDeclContext
SymbolFileDWARFDebugMap::GetDeclContextForUID (lldb::user_id_t type_uid)
{
    const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
    SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
    if (oso_dwarf)
        return oso_dwarf->GetDeclContextForUID (type_uid);
    return CompilerDeclContext();
}

CompilerDeclContext
SymbolFileDWARFDebugMap::GetDeclContextContainingUID (lldb::user_id_t type_uid)
{
    const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
    SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
    if (oso_dwarf)
        return oso_dwarf->GetDeclContextContainingUID (type_uid);
    return CompilerDeclContext();
}

void
SymbolFileDWARFDebugMap::ParseDeclsForContext (lldb_private::CompilerDeclContext decl_ctx)
{
    ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
        oso_dwarf->ParseDeclsForContext (decl_ctx);
        return true; // Keep iterating
    });
}

bool
SymbolFileDWARFDebugMap::AddOSOFileRange (CompileUnitInfo *cu_info,
                                          lldb::addr_t exe_file_addr,
                                          lldb::addr_t exe_byte_size,
                                          lldb::addr_t oso_file_addr,
                                          lldb::addr_t oso_byte_size)
{
    const uint32_t debug_map_idx = m_debug_map.FindEntryIndexThatContains(exe_file_addr);
    if (debug_map_idx != UINT32_MAX)
    {
        DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(exe_file_addr);
        debug_map_entry->data.SetOSOFileAddress(oso_file_addr);
        addr_t range_size = std::min<addr_t>(exe_byte_size, oso_byte_size);
        if (range_size == 0)
        {
            range_size = std::max<addr_t>(exe_byte_size, oso_byte_size);
            if (range_size == 0)
                range_size = 1;
        }
        cu_info->file_range_map.Append(FileRangeMap::Entry(oso_file_addr, range_size, exe_file_addr));
        return true;
    }
    return false;
}

void
SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (CompileUnitInfo *cu_info)
{
    cu_info->file_range_map.Sort();
#if defined(DEBUG_OSO_DMAP)
    const FileRangeMap &oso_file_range_map = cu_info->GetFileRangeMap(this);
    const size_t n = oso_file_range_map.GetSize();
    printf ("SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (cu_info = %p) %s\n",
            cu_info,
            cu_info->oso_sp->module_sp->GetFileSpec().GetPath().c_str());
    for (size_t i=0; i<n; ++i)
    {
        const FileRangeMap::Entry &entry = oso_file_range_map.GetEntryRef(i);
        printf ("oso [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") ==> exe [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n",
                entry.GetRangeBase(), entry.GetRangeEnd(),
                entry.data, entry.data + entry.GetByteSize());
    }
#endif
}

lldb::addr_t
SymbolFileDWARFDebugMap::LinkOSOFileAddress (SymbolFileDWARF *oso_symfile, lldb::addr_t oso_file_addr)
{
    CompileUnitInfo *cu_info = GetCompileUnitInfo (oso_symfile);
    if (cu_info)
    {
        const FileRangeMap::Entry *oso_range_entry = cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
        if (oso_range_entry)
        {
            const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(oso_range_entry->data);
            if (debug_map_entry)
            {
                const lldb::addr_t offset = oso_file_addr - oso_range_entry->GetRangeBase();
                const lldb::addr_t exe_file_addr = debug_map_entry->GetRangeBase() + offset;
                return exe_file_addr;
            }
        }
    }
    return LLDB_INVALID_ADDRESS;
}

bool
SymbolFileDWARFDebugMap::LinkOSOAddress (Address &addr)
{
    // Make sure this address hasn't been fixed already
    Module *exe_module = GetObjectFile()->GetModule().get();
    Module *addr_module = addr.GetModule().get();
    if (addr_module == exe_module)
        return true; // Address is already in terms of the main executable module

    CompileUnitInfo *cu_info = GetCompileUnitInfo (GetSymbolFileAsSymbolFileDWARF(addr_module->GetSymbolVendor()->GetSymbolFile()));
    if (cu_info)
    {
        const lldb::addr_t oso_file_addr = addr.GetFileAddress();
        const FileRangeMap::Entry *oso_range_entry = cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
        if (oso_range_entry)
        {
            const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(oso_range_entry->data);
            if (debug_map_entry)
            {
                const lldb::addr_t offset = oso_file_addr - oso_range_entry->GetRangeBase();
                const lldb::addr_t exe_file_addr = debug_map_entry->GetRangeBase() + offset;
                return exe_module->ResolveFileAddress(exe_file_addr, addr);
            }
        }
    }
    return true;
}

LineTable *
SymbolFileDWARFDebugMap::LinkOSOLineTable (SymbolFileDWARF *oso_dwarf, LineTable *line_table)
{
    CompileUnitInfo *cu_info = GetCompileUnitInfo (oso_dwarf);
    if (cu_info)
        return line_table->LinkLineTable(cu_info->GetFileRangeMap(this));
    return NULL;
}

size_t
SymbolFileDWARFDebugMap::AddOSOARanges (SymbolFileDWARF* dwarf2Data, DWARFDebugAranges* debug_aranges)
{
    size_t num_line_entries_added = 0;
    if (debug_aranges && dwarf2Data)
    {
        CompileUnitInfo *compile_unit_info = GetCompileUnitInfo(dwarf2Data);
        if (compile_unit_info)
        {
            const FileRangeMap &file_range_map = compile_unit_info->GetFileRangeMap(this);
            for (size_t idx = 0;
                 idx < file_range_map.GetSize();
                 idx++)
            {
                const FileRangeMap::Entry* entry = file_range_map.GetEntryAtIndex(idx);
                if (entry)
                {
                    debug_aranges->AppendRange(dwarf2Data->GetID(), entry->GetRangeBase(), entry->GetRangeEnd());
                    num_line_entries_added++;
                }
            }
        }
    }
    return num_line_entries_added;
}
