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

#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/ClangExternalASTSourceCallbacks.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolVendor.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(),
                                                              oso_fun_symbol->GetAddressRef().GetFileAddress(),
                                                              std::min<addr_t>(exe_symbol->GetByteSize(), 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(),
                                                              oso_gsym_symbol->GetAddressRef().GetFileAddress(),
                                                              std::min<addr_t>(exe_symbol->GetByteSize(), 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)
    {
    }

    virtual
    ~DebugMapModule ()
    {
    }

    
    virtual SymbolVendor*
    GetSymbolVendor(bool can_create = true, lldb_private::Stream *feedback_strm = NULL)
    {
        // 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)
            {
                Mutex::Locker locker (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()
{
    // Install our external AST source callbacks so we can complete Clang types.
    llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> ast_source_ap (
        new ClangExternalASTSourceCallbacks (SymbolFileDWARFDebugMap::CompleteTagDecl,
                                             SymbolFileDWARFDebugMap::CompleteObjCInterfaceDecl,
                                             NULL,
                                             SymbolFileDWARFDebugMap::LayoutRecordType,
                                             this));

    GetClangASTContext().SetExternalSource (ast_source_ap);
}

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));
            
                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::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::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::ResolveClangOpaqueTypeDefinition (ClangASTType& clang_type)
{
    // We have a struct/union/class/enum that needs to be fully resolved.
    return false;
}

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 ClangNamespaceDecl *namespace_decl,
    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, namespace_decl, true, max_matches, variables))
                    if (variables.GetSize() > max_matches)
                        break;
            }
        }
    }
    return variables.GetSize() - original_size;
}

uint32_t
SymbolFileDWARFDebugMap::FindGlobalVariables (const ConstString &name, const ClangNamespaceDecl *namespace_decl, 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,
                                                                     namespace_decl,
                                                                     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 ClangNamespaceDecl *namespace_decl, 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, namespace_decl, 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 DWARFDebugInfoEntry *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 ClangNamespaceDecl *namespace_decl,
    bool append, 
    uint32_t max_matches, 
    TypeList& 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, namespace_decl, append, max_matches, types);
    }
    else
    {
        ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
            oso_dwarf->FindTypes (sc, name, namespace_decl, append, max_matches, types);
            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;
//}


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

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

            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);
                }
            }
        }
    }
}


void
SymbolFileDWARFDebugMap::CompleteTagDecl (void *baton, clang::TagDecl *decl)
{
    SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton;
    ClangASTType clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
    if (clang_type)
    {
        symbol_file_dwarf->ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
            if (oso_dwarf->HasForwardDeclForClangType (clang_type))
            {
                oso_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
                return true;
            }
            return false;
        });
    }
}

void
SymbolFileDWARFDebugMap::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl)
{
    SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton;
    ClangASTType clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
    if (clang_type)
    {
        symbol_file_dwarf->ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
            if (oso_dwarf->HasForwardDeclForClangType (clang_type))
            {
                oso_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
                return true;
            }
            return false;
        });
    }
}

bool
SymbolFileDWARFDebugMap::LayoutRecordType(void *baton, const clang::RecordDecl *record_decl, uint64_t &size,
                                          uint64_t &alignment,
                                          llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
                                          llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets,
                                          llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets)
{
    SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton;
    bool laid_out = false;
    symbol_file_dwarf->ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
        return (laid_out = oso_dwarf->LayoutRecordType (record_decl, size, alignment, field_offsets, base_offsets, vbase_offsets));
    });
    return laid_out;
}



clang::DeclContext*
SymbolFileDWARFDebugMap::GetClangDeclContextContainingTypeUID (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->GetClangDeclContextContainingTypeUID (type_uid);
    return NULL;
}

clang::DeclContext*
SymbolFileDWARFDebugMap::GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, 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->GetClangDeclContextForTypeUID (sc, type_uid);
    return NULL;
}

bool
SymbolFileDWARFDebugMap::AddOSOFileRange (CompileUnitInfo *cu_info,
                                          lldb::addr_t exe_file_addr,
                                          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);
        cu_info->file_range_map.Append(FileRangeMap::Entry(oso_file_addr, oso_byte_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)
                {
                    printf ("[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n", entry->GetRangeBase(), entry->GetRangeEnd());
                    debug_aranges->AppendRange(dwarf2Data->GetID(), entry->GetRangeBase(), entry->GetRangeEnd());
                    num_line_entries_added++;
                }
            }
        }
    }
    return num_line_entries_added;
}

