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

#include "lldb/Core/ModuleList.h"

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/Symbols.h"
#include "lldb/Symbol/ClangNamespaceDecl.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/VariableList.h"

using namespace lldb;
using namespace lldb_private;

//----------------------------------------------------------------------
// ModuleList constructor
//----------------------------------------------------------------------
ModuleList::ModuleList() :
    m_modules(),
    m_modules_mutex (Mutex::eMutexTypeRecursive),
    m_notifier(NULL)
{
}

//----------------------------------------------------------------------
// Copy constructor
//----------------------------------------------------------------------
ModuleList::ModuleList(const ModuleList& rhs) :
    m_modules(),
    m_modules_mutex (Mutex::eMutexTypeRecursive)
{
    Mutex::Locker lhs_locker(m_modules_mutex);
    Mutex::Locker rhs_locker(rhs.m_modules_mutex);
    m_modules = rhs.m_modules;
}

ModuleList::ModuleList (ModuleList::Notifier* notifier) :
    m_modules(),
    m_modules_mutex (Mutex::eMutexTypeRecursive),
    m_notifier(notifier)
{
}

//----------------------------------------------------------------------
// Assignment operator
//----------------------------------------------------------------------
const ModuleList&
ModuleList::operator= (const ModuleList& rhs)
{
    if (this != &rhs)
    {
        Mutex::Locker lhs_locker(m_modules_mutex);
        Mutex::Locker rhs_locker(rhs.m_modules_mutex);
        m_modules = rhs.m_modules;
    }
    return *this;
}

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
ModuleList::~ModuleList()
{
}

void
ModuleList::AppendImpl (const ModuleSP &module_sp, bool use_notifier)
{
    if (module_sp)
    {
        Mutex::Locker locker(m_modules_mutex);
        m_modules.push_back(module_sp);
        if (use_notifier && m_notifier)
            m_notifier->ModuleAdded(*this, module_sp);
    }
}

void
ModuleList::Append (const ModuleSP &module_sp)
{
    AppendImpl (module_sp);
}

void
ModuleList::ReplaceEquivalent (const ModuleSP &module_sp)
{
    if (module_sp)
    {
        Mutex::Locker locker(m_modules_mutex);

        // First remove any equivalent modules. Equivalent modules are modules
        // whose path, platform path and architecture match.
        ModuleSpec equivalent_module_spec (module_sp->GetFileSpec(), module_sp->GetArchitecture());
        equivalent_module_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec();

        size_t idx = 0;
        while (idx < m_modules.size())
        {
            ModuleSP module_sp (m_modules[idx]);
            if (module_sp->MatchesModuleSpec (equivalent_module_spec))
                RemoveImpl(m_modules.begin() + idx);
            else
                ++idx;
        }
        // Now add the new module to the list
        Append(module_sp);
    }
}

bool
ModuleList::AppendIfNeeded (const ModuleSP &module_sp)
{
    if (module_sp)
    {
        Mutex::Locker locker(m_modules_mutex);
        collection::iterator pos, end = m_modules.end();
        for (pos = m_modules.begin(); pos != end; ++pos)
        {
            if (pos->get() == module_sp.get())
                return false; // Already in the list
        }
        // Only push module_sp on the list if it wasn't already in there.
        Append(module_sp);
        return true;
    }
    return false;
}

void
ModuleList::Append (const ModuleList& module_list)
{
    for (auto pos : module_list.m_modules)
        Append(pos);
}

bool
ModuleList::AppendIfNeeded (const ModuleList& module_list)
{
    bool any_in = false;
    for (auto pos : module_list.m_modules)
        any_in = AppendIfNeeded(pos) | any_in;
    return any_in;
}

bool
ModuleList::RemoveImpl (const ModuleSP &module_sp, bool use_notifier)
{
    if (module_sp)
    {
        Mutex::Locker locker(m_modules_mutex);
        collection::iterator pos, end = m_modules.end();
        for (pos = m_modules.begin(); pos != end; ++pos)
        {
            if (pos->get() == module_sp.get())
            {
                m_modules.erase (pos);
                if (use_notifier && m_notifier)
                    m_notifier->ModuleRemoved(*this, module_sp);
                return true;
            }
        }
    }
    return false;
}

ModuleList::collection::iterator
ModuleList::RemoveImpl (ModuleList::collection::iterator pos, bool use_notifier)
{
    ModuleSP module_sp(*pos);
    collection::iterator retval = m_modules.erase(pos);
    if (use_notifier && m_notifier)
        m_notifier->ModuleRemoved(*this, module_sp);
    return retval;
}

bool
ModuleList::Remove (const ModuleSP &module_sp)
{
    return RemoveImpl (module_sp);
}

bool
ModuleList::ReplaceModule (const lldb::ModuleSP &old_module_sp, const lldb::ModuleSP &new_module_sp)
{
    if (!RemoveImpl(old_module_sp, false))
        return false;
    AppendImpl (new_module_sp, false);
    if (m_notifier)
        m_notifier->ModuleUpdated(*this, old_module_sp,new_module_sp);
    return true;
}

bool
ModuleList::RemoveIfOrphaned (const Module *module_ptr)
{
    if (module_ptr)
    {
        Mutex::Locker locker(m_modules_mutex);
        collection::iterator pos, end = m_modules.end();
        for (pos = m_modules.begin(); pos != end; ++pos)
        {
            if (pos->get() == module_ptr)
            {
                if (pos->unique())
                {
                    pos = RemoveImpl(pos);
                    return true;
                }
                else
                    return false;
            }
        }
    }
    return false;
}

size_t
ModuleList::RemoveOrphans (bool mandatory)
{
    Mutex::Locker locker;
    
    if (mandatory)
    {
        locker.Lock (m_modules_mutex);
    }
    else
    {
        // Not mandatory, remove orphans if we can get the mutex
        if (!locker.TryLock(m_modules_mutex))
            return 0;
    }
    collection::iterator pos = m_modules.begin();
    size_t remove_count = 0;
    while (pos != m_modules.end())
    {
        if (pos->unique())
        {
            pos = RemoveImpl(pos);
            ++remove_count;
        }
        else
        {
            ++pos;
        }
    }
    return remove_count;
}

size_t
ModuleList::Remove (ModuleList &module_list)
{
    Mutex::Locker locker(m_modules_mutex);
    size_t num_removed = 0;
    collection::iterator pos, end = module_list.m_modules.end();
    for (pos = module_list.m_modules.begin(); pos != end; ++pos)
    {
        if (Remove (*pos))
            ++num_removed;
    }
    return num_removed;
}


void
ModuleList::Clear()
{
    ClearImpl();
}

void
ModuleList::Destroy()
{
    ClearImpl();
}

void
ModuleList::ClearImpl (bool use_notifier)
{
    Mutex::Locker locker(m_modules_mutex);
    if (use_notifier && m_notifier)
        m_notifier->WillClearList(*this);
    m_modules.clear();
}

Module*
ModuleList::GetModulePointerAtIndex (size_t idx) const
{
    Mutex::Locker locker(m_modules_mutex);
    return GetModulePointerAtIndexUnlocked(idx);
}

Module*
ModuleList::GetModulePointerAtIndexUnlocked (size_t idx) const
{
    if (idx < m_modules.size())
        return m_modules[idx].get();
    return NULL;
}

ModuleSP
ModuleList::GetModuleAtIndex(size_t idx) const
{
    Mutex::Locker locker(m_modules_mutex);
    return GetModuleAtIndexUnlocked(idx);
}

ModuleSP
ModuleList::GetModuleAtIndexUnlocked(size_t idx) const
{
    ModuleSP module_sp;
    if (idx < m_modules.size())
        module_sp = m_modules[idx];
    return module_sp;
}

size_t
ModuleList::FindFunctions (const ConstString &name, 
                           uint32_t name_type_mask, 
                           bool include_symbols,
                           bool include_inlines,
                           bool append, 
                           SymbolContextList &sc_list) const
{
    if (!append)
        sc_list.Clear();
    
    const size_t old_size = sc_list.GetSize();
    
    if (name_type_mask & eFunctionNameTypeAuto)
    {
        ConstString lookup_name;
        uint32_t lookup_name_type_mask = 0;
        bool match_name_after_lookup = false;
        Module::PrepareForFunctionNameLookup (name, name_type_mask,
                                              lookup_name,
                                              lookup_name_type_mask,
                                              match_name_after_lookup);
    
        Mutex::Locker locker(m_modules_mutex);
        collection::const_iterator pos, end = m_modules.end();
        for (pos = m_modules.begin(); pos != end; ++pos)
        {
            (*pos)->FindFunctions (lookup_name,
                                   NULL,
                                   lookup_name_type_mask,
                                   include_symbols,
                                   include_inlines,
                                   true,
                                   sc_list);
        }
        
        if (match_name_after_lookup)
        {
            SymbolContext sc;
            size_t i = old_size;
            while (i<sc_list.GetSize())
            {
                if (sc_list.GetContextAtIndex(i, sc))
                {
                    const char *func_name = sc.GetFunctionName().GetCString();
                    if (func_name && strstr (func_name, name.GetCString()) == NULL)
                    {
                        // Remove the current context
                        sc_list.RemoveContextAtIndex(i);
                        // Don't increment i and continue in the loop
                        continue;
                    }
                }
                ++i;
            }
        }

    }
    else
    {
        Mutex::Locker locker(m_modules_mutex);
        collection::const_iterator pos, end = m_modules.end();
        for (pos = m_modules.begin(); pos != end; ++pos)
        {
            (*pos)->FindFunctions (name, NULL, name_type_mask, include_symbols, include_inlines, true, sc_list);
        }
    }
    return sc_list.GetSize() - old_size;
}

size_t
ModuleList::FindFunctionSymbols (const ConstString &name,
                                 uint32_t name_type_mask,
                                 SymbolContextList& sc_list)
{
    const size_t old_size = sc_list.GetSize();

    if (name_type_mask & eFunctionNameTypeAuto)
    {
        ConstString lookup_name;
        uint32_t lookup_name_type_mask = 0;
        bool match_name_after_lookup = false;
        Module::PrepareForFunctionNameLookup (name, name_type_mask,
                                              lookup_name,
                                              lookup_name_type_mask,
                                              match_name_after_lookup);
    
        Mutex::Locker locker(m_modules_mutex);
        collection::const_iterator pos, end = m_modules.end();
        for (pos = m_modules.begin(); pos != end; ++pos)
        {
            (*pos)->FindFunctionSymbols (lookup_name,
                                   lookup_name_type_mask,
                                   sc_list);
        }
        
        if (match_name_after_lookup)
        {
            SymbolContext sc;
            size_t i = old_size;
            while (i<sc_list.GetSize())
            {
                if (sc_list.GetContextAtIndex(i, sc))
                {
                    const char *func_name = sc.GetFunctionName().GetCString();
                    if (func_name && strstr (func_name, name.GetCString()) == NULL)
                    {
                        // Remove the current context
                        sc_list.RemoveContextAtIndex(i);
                        // Don't increment i and continue in the loop
                        continue;
                    }
                }
                ++i;
            }
        }

    }
    else
    {
        Mutex::Locker locker(m_modules_mutex);
        collection::const_iterator pos, end = m_modules.end();
        for (pos = m_modules.begin(); pos != end; ++pos)
        {
            (*pos)->FindFunctionSymbols (name, name_type_mask, sc_list);
        }
    }

    return sc_list.GetSize() - old_size;
}

size_t
ModuleList::FindCompileUnits (const FileSpec &path, 
                              bool append, 
                              SymbolContextList &sc_list) const
{
    if (!append)
        sc_list.Clear();
    
    Mutex::Locker locker(m_modules_mutex);
    collection::const_iterator pos, end = m_modules.end();
    for (pos = m_modules.begin(); pos != end; ++pos)
    {
        (*pos)->FindCompileUnits (path, true, sc_list);
    }
    
    return sc_list.GetSize();
}

size_t
ModuleList::FindGlobalVariables (const ConstString &name, 
                                 bool append, 
                                 size_t max_matches,
                                 VariableList& variable_list) const
{
    size_t initial_size = variable_list.GetSize();
    Mutex::Locker locker(m_modules_mutex);
    collection::const_iterator pos, end = m_modules.end();
    for (pos = m_modules.begin(); pos != end; ++pos)
    {
        (*pos)->FindGlobalVariables (name, NULL, append, max_matches, variable_list);
    }
    return variable_list.GetSize() - initial_size;
}


size_t
ModuleList::FindGlobalVariables (const RegularExpression& regex, 
                                 bool append, 
                                 size_t max_matches,
                                 VariableList& variable_list) const
{
    size_t initial_size = variable_list.GetSize();
    Mutex::Locker locker(m_modules_mutex);
    collection::const_iterator pos, end = m_modules.end();
    for (pos = m_modules.begin(); pos != end; ++pos)
    {
        (*pos)->FindGlobalVariables (regex, append, max_matches, variable_list);
    }
    return variable_list.GetSize() - initial_size;
}


size_t
ModuleList::FindSymbolsWithNameAndType (const ConstString &name, 
                                        SymbolType symbol_type, 
                                        SymbolContextList &sc_list,
                                        bool append) const
{
    Mutex::Locker locker(m_modules_mutex);
    if (!append)
        sc_list.Clear();
    size_t initial_size = sc_list.GetSize();
    
    collection::const_iterator pos, end = m_modules.end();
    for (pos = m_modules.begin(); pos != end; ++pos)
        (*pos)->FindSymbolsWithNameAndType (name, symbol_type, sc_list);
    return sc_list.GetSize() - initial_size;
}

size_t
ModuleList::FindSymbolsMatchingRegExAndType (const RegularExpression &regex, 
                                             lldb::SymbolType symbol_type, 
                                             SymbolContextList &sc_list,
                                             bool append) const
{
    Mutex::Locker locker(m_modules_mutex);
    if (!append)
        sc_list.Clear();
    size_t initial_size = sc_list.GetSize();
    
    collection::const_iterator pos, end = m_modules.end();
    for (pos = m_modules.begin(); pos != end; ++pos)
        (*pos)->FindSymbolsMatchingRegExAndType (regex, symbol_type, sc_list);
    return sc_list.GetSize() - initial_size;
}

size_t
ModuleList::FindModules (const ModuleSpec &module_spec, ModuleList& matching_module_list) const
{
    size_t existing_matches = matching_module_list.GetSize();

    Mutex::Locker locker(m_modules_mutex);
    collection::const_iterator pos, end = m_modules.end();
    for (pos = m_modules.begin(); pos != end; ++pos)
    {
        ModuleSP module_sp(*pos);
        if (module_sp->MatchesModuleSpec (module_spec))
            matching_module_list.Append(module_sp);
    }
    return matching_module_list.GetSize() - existing_matches;
}

ModuleSP
ModuleList::FindModule (const Module *module_ptr) const
{
    ModuleSP module_sp;

    // Scope for "locker"
    {
        Mutex::Locker locker(m_modules_mutex);
        collection::const_iterator pos, end = m_modules.end();

        for (pos = m_modules.begin(); pos != end; ++pos)
        {
            if ((*pos).get() == module_ptr)
            {
                module_sp = (*pos);
                break;
            }
        }
    }
    return module_sp;

}

ModuleSP
ModuleList::FindModule (const UUID &uuid) const
{
    ModuleSP module_sp;
    
    if (uuid.IsValid())
    {
        Mutex::Locker locker(m_modules_mutex);
        collection::const_iterator pos, end = m_modules.end();
        
        for (pos = m_modules.begin(); pos != end; ++pos)
        {
            if ((*pos)->GetUUID() == uuid)
            {
                module_sp = (*pos);
                break;
            }
        }
    }
    return module_sp;
}


size_t
ModuleList::FindTypes (const SymbolContext& sc, const ConstString &name, bool name_is_fully_qualified, size_t max_matches, TypeList& types) const
{
    Mutex::Locker locker(m_modules_mutex);

    size_t total_matches = 0;
    collection::const_iterator pos, end = m_modules.end();
    if (sc.module_sp)
    {
        // The symbol context "sc" contains a module so we want to search that
        // one first if it is in our list...
        for (pos = m_modules.begin(); pos != end; ++pos)
        {
            if (sc.module_sp.get() == (*pos).get())
            {
                total_matches += (*pos)->FindTypes (sc, name, name_is_fully_qualified, max_matches, types);

                if (total_matches >= max_matches)
                    break;
            }
        }
    }
    
    if (total_matches < max_matches)
    {
        SymbolContext world_sc;
        for (pos = m_modules.begin(); pos != end; ++pos)
        {
            // Search the module if the module is not equal to the one in the symbol
            // context "sc". If "sc" contains a empty module shared pointer, then
            // the comparisong will always be true (valid_module_ptr != NULL).
            if (sc.module_sp.get() != (*pos).get())
                total_matches += (*pos)->FindTypes (world_sc, name, name_is_fully_qualified, max_matches, types);
            
            if (total_matches >= max_matches)
                break;
        }
    }
    
    return total_matches;
}

bool
ModuleList::FindSourceFile (const FileSpec &orig_spec, FileSpec &new_spec) const
{
    Mutex::Locker locker(m_modules_mutex);
    collection::const_iterator pos, end = m_modules.end();
    for (pos = m_modules.begin(); pos != end; ++pos)
    {
        if ((*pos)->FindSourceFile (orig_spec, new_spec))
            return true;
    }
    return false;
}



ModuleSP
ModuleList::FindFirstModule (const ModuleSpec &module_spec) const
{
    ModuleSP module_sp;
    Mutex::Locker locker(m_modules_mutex);
    collection::const_iterator pos, end = m_modules.end();
    for (pos = m_modules.begin(); pos != end; ++pos)
    {
        ModuleSP module_sp(*pos);
        if (module_sp->MatchesModuleSpec (module_spec))
            return module_sp;
    }
    return module_sp;

}

size_t
ModuleList::GetSize() const
{
    size_t size = 0;
    {
        Mutex::Locker locker(m_modules_mutex);
        size = m_modules.size();
    }
    return size;
}


void
ModuleList::Dump(Stream *s) const
{
//  s.Printf("%.*p: ", (int)sizeof(void*) * 2, this);
//  s.Indent();
//  s << "ModuleList\n";

    Mutex::Locker locker(m_modules_mutex);
    collection::const_iterator pos, end = m_modules.end();
    for (pos = m_modules.begin(); pos != end; ++pos)
    {
        (*pos)->Dump(s);
    }
}

void
ModuleList::LogUUIDAndPaths (Log *log, const char *prefix_cstr)
{
    if (log)
    {   
        Mutex::Locker locker(m_modules_mutex);
        collection::const_iterator pos, begin = m_modules.begin(), end = m_modules.end();
        for (pos = begin; pos != end; ++pos)
        {
            Module *module = pos->get();
            const FileSpec &module_file_spec = module->GetFileSpec();
            log->Printf ("%s[%u] %s (%s) \"%s\"",
                         prefix_cstr ? prefix_cstr : "",
                         (uint32_t)std::distance (begin, pos),
                         module->GetUUID().GetAsString().c_str(),
                         module->GetArchitecture().GetArchitectureName(),
                         module_file_spec.GetPath().c_str());
        }
    }
}

bool
ModuleList::ResolveFileAddress (lldb::addr_t vm_addr, Address& so_addr) const
{
    Mutex::Locker locker(m_modules_mutex);
    collection::const_iterator pos, end = m_modules.end();
    for (pos = m_modules.begin(); pos != end; ++pos)
    {
        if ((*pos)->ResolveFileAddress (vm_addr, so_addr))
            return true;
    }

    return false;
}

uint32_t
ModuleList::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc) const
{
    // The address is already section offset so it has a module
    uint32_t resolved_flags = 0;
    ModuleSP module_sp (so_addr.GetModule());
    if (module_sp)
    {
        resolved_flags = module_sp->ResolveSymbolContextForAddress (so_addr,
                                                                    resolve_scope,
                                                                    sc);
    }
    else
    {
        Mutex::Locker locker(m_modules_mutex);
        collection::const_iterator pos, end = m_modules.end();
        for (pos = m_modules.begin(); pos != end; ++pos)
        {
            resolved_flags = (*pos)->ResolveSymbolContextForAddress (so_addr,
                                                                     resolve_scope,
                                                                     sc);
            if (resolved_flags != 0)
                break;
        }
    }

    return resolved_flags;
}

uint32_t
ModuleList::ResolveSymbolContextForFilePath 
(
    const char *file_path, 
    uint32_t line, 
    bool check_inlines, 
    uint32_t resolve_scope, 
    SymbolContextList& sc_list
)  const
{
    FileSpec file_spec(file_path, false);
    return ResolveSymbolContextsForFileSpec (file_spec, line, check_inlines, resolve_scope, sc_list);
}

uint32_t
ModuleList::ResolveSymbolContextsForFileSpec (const FileSpec &file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list) const
{
    Mutex::Locker locker(m_modules_mutex);
    collection::const_iterator pos, end = m_modules.end();
    for (pos = m_modules.begin(); pos != end; ++pos)
    {
        (*pos)->ResolveSymbolContextsForFileSpec (file_spec, line, check_inlines, resolve_scope, sc_list);
    }

    return sc_list.GetSize();
}

size_t
ModuleList::GetIndexForModule (const Module *module) const
{
    if (module)
    {
        Mutex::Locker locker(m_modules_mutex);
        collection::const_iterator pos;
        collection::const_iterator begin = m_modules.begin();
        collection::const_iterator end = m_modules.end();
        for (pos = begin; pos != end; ++pos)
        {
            if ((*pos).get() == module)
                return std::distance (begin, pos);
        }
    }
    return LLDB_INVALID_INDEX32;
}

static ModuleList &
GetSharedModuleList ()
{
    // NOTE: Intentionally leak the module list so a program doesn't have to
    // cleanup all modules and object files as it exits. This just wastes time
    // doing a bunch of cleanup that isn't required.
    static ModuleList *g_shared_module_list = NULL;
    if (g_shared_module_list == NULL)
        g_shared_module_list = new ModuleList(); // <--- Intentional leak!!!
    
    return *g_shared_module_list;
}

bool
ModuleList::ModuleIsInCache (const Module *module_ptr)
{
    if (module_ptr)
    {
        ModuleList &shared_module_list = GetSharedModuleList ();
        return shared_module_list.FindModule (module_ptr).get() != NULL;
    }
    return false;
}

size_t
ModuleList::FindSharedModules (const ModuleSpec &module_spec, ModuleList &matching_module_list)
{
    return GetSharedModuleList ().FindModules (module_spec, matching_module_list);
}

size_t
ModuleList::RemoveOrphanSharedModules (bool mandatory)
{
    return GetSharedModuleList ().RemoveOrphans(mandatory);
}

Error
ModuleList::GetSharedModule
(
    const ModuleSpec &module_spec,
    ModuleSP &module_sp,
    const FileSpecList *module_search_paths_ptr,
    ModuleSP *old_module_sp_ptr,
    bool *did_create_ptr,
    bool always_create
)
{
    ModuleList &shared_module_list = GetSharedModuleList ();
    Mutex::Locker locker(shared_module_list.m_modules_mutex);
    char path[PATH_MAX];

    Error error;

    module_sp.reset();

    if (did_create_ptr)
        *did_create_ptr = false;
    if (old_module_sp_ptr)
        old_module_sp_ptr->reset();

    const UUID *uuid_ptr = module_spec.GetUUIDPtr();
    const FileSpec &module_file_spec = module_spec.GetFileSpec();
    const ArchSpec &arch = module_spec.GetArchitecture();

    // Make sure no one else can try and get or create a module while this
    // function is actively working on it by doing an extra lock on the
    // global mutex list.
    if (always_create == false)
    {
        ModuleList matching_module_list;
        const size_t num_matching_modules = shared_module_list.FindModules (module_spec, matching_module_list);
        if (num_matching_modules > 0)
        {
            for (size_t module_idx = 0; module_idx < num_matching_modules; ++module_idx)
            {
                module_sp = matching_module_list.GetModuleAtIndex(module_idx);
                
                // Make sure the file for the module hasn't been modified
                if (module_sp->FileHasChanged())
                {
                    if (old_module_sp_ptr && !old_module_sp_ptr->get())
                        *old_module_sp_ptr = module_sp;

                    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_MODULES));
                    if (log)
                        log->Printf("module changed: %p, removing from global module list", module_sp.get());

                    shared_module_list.Remove (module_sp);
                    module_sp.reset();
                }
                else
                {
                    // The module matches and the module was not modified from
                    // when it was last loaded.
                    return error;
                }
            }
        }
    }

    if (module_sp)
        return error;
    else
    {
        module_sp.reset (new Module (module_spec));
        // Make sure there are a module and an object file since we can specify
        // a valid file path with an architecture that might not be in that file.
        // By getting the object file we can guarantee that the architecture matches
        if (module_sp)
        {
            if (module_sp->GetObjectFile())
            {
                // If we get in here we got the correct arch, now we just need
                // to verify the UUID if one was given
                if (uuid_ptr && *uuid_ptr != module_sp->GetUUID())
                    module_sp.reset();
                else
                {
                    if (did_create_ptr)
                        *did_create_ptr = true;
                    
                    shared_module_list.ReplaceEquivalent(module_sp);
                    return error;
                }
            }
            else
                module_sp.reset();
        }
    }

    // Either the file didn't exist where at the path, or no path was given, so
    // we now have to use more extreme measures to try and find the appropriate
    // module.

    // Fixup the incoming path in case the path points to a valid file, yet
    // the arch or UUID (if one was passed in) don't match.
    FileSpec file_spec = Symbols::LocateExecutableObjectFile (module_spec);

    // Don't look for the file if it appears to be the same one we already
    // checked for above...
    if (file_spec != module_file_spec)
    {
        if (!file_spec.Exists())
        {
            file_spec.GetPath(path, sizeof(path));
            if (path[0] == '\0')
                module_file_spec.GetPath(path, sizeof(path));
            if (file_spec.Exists())
            {
                std::string uuid_str;
                if (uuid_ptr && uuid_ptr->IsValid())
                    uuid_str = uuid_ptr->GetAsString();

                if (arch.IsValid())
                {
                    if (!uuid_str.empty())
                        error.SetErrorStringWithFormat("'%s' does not contain the %s architecture and UUID %s", path, arch.GetArchitectureName(), uuid_str.c_str());
                    else
                        error.SetErrorStringWithFormat("'%s' does not contain the %s architecture.", path, arch.GetArchitectureName());
                }
            }
            else
            {
                error.SetErrorStringWithFormat("'%s' does not exist", path);
            }
            if (error.Fail())
                module_sp.reset();
            return error;
        }


        // Make sure no one else can try and get or create a module while this
        // function is actively working on it by doing an extra lock on the
        // global mutex list.
        ModuleSpec platform_module_spec(module_spec);
        platform_module_spec.GetFileSpec() = file_spec;
        platform_module_spec.GetPlatformFileSpec() = file_spec;
        ModuleList matching_module_list;
        if (shared_module_list.FindModules (platform_module_spec, matching_module_list) > 0)
        {
            module_sp = matching_module_list.GetModuleAtIndex(0);

            // If we didn't have a UUID in mind when looking for the object file,
            // then we should make sure the modification time hasn't changed!
            if (platform_module_spec.GetUUIDPtr() == NULL)
            {
                TimeValue file_spec_mod_time(file_spec.GetModificationTime());
                if (file_spec_mod_time.IsValid())
                {
                    if (file_spec_mod_time != module_sp->GetModificationTime())
                    {
                        if (old_module_sp_ptr)
                            *old_module_sp_ptr = module_sp;
                        shared_module_list.Remove (module_sp);
                        module_sp.reset();
                    }
                }
            }
        }

        if (module_sp.get() == NULL)
        {
            module_sp.reset (new Module (platform_module_spec));
            // Make sure there are a module and an object file since we can specify
            // a valid file path with an architecture that might not be in that file.
            // By getting the object file we can guarantee that the architecture matches
            if (module_sp && module_sp->GetObjectFile())
            {
                if (did_create_ptr)
                    *did_create_ptr = true;

                shared_module_list.ReplaceEquivalent(module_sp);
            }
            else
            {
                file_spec.GetPath(path, sizeof(path));

                if (file_spec)
                {
                    if (arch.IsValid())
                        error.SetErrorStringWithFormat("unable to open %s architecture in '%s'", arch.GetArchitectureName(), path);
                    else
                        error.SetErrorStringWithFormat("unable to open '%s'", path);
                }
                else
                {
                    std::string uuid_str;
                    if (uuid_ptr && uuid_ptr->IsValid())
                        uuid_str = uuid_ptr->GetAsString();

                    if (!uuid_str.empty())
                        error.SetErrorStringWithFormat("cannot locate a module for UUID '%s'", uuid_str.c_str());
                    else
                        error.SetErrorStringWithFormat("cannot locate a module");
                }
            }
        }
    }

    return error;
}

bool
ModuleList::RemoveSharedModule (lldb::ModuleSP &module_sp)
{
    return GetSharedModuleList ().Remove (module_sp);
}

bool
ModuleList::RemoveSharedModuleIfOrphaned (const Module *module_ptr)
{
    return GetSharedModuleList ().RemoveIfOrphaned (module_ptr);
}

bool
ModuleList::LoadScriptingResourcesInTarget (Target *target,
                                            std::list<Error>& errors,
                                            Stream *feedback_stream,
                                            bool continue_on_error)
{
    if (!target)
        return false;
    Mutex::Locker locker(m_modules_mutex);
    for (auto module : m_modules)
    {
        Error error;
        if (module)
        {
            if (!module->LoadScriptingResourceInTarget(target, error, feedback_stream))
            {
                if (error.Fail() && error.AsCString())
                {
                    error.SetErrorStringWithFormat("unable to load scripting data for module %s - error reported was %s",
                                                   module->GetFileSpec().GetFileNameStrippingExtension().GetCString(),
                                                   error.AsCString());
                    errors.push_back(error);
                }
                if (!continue_on_error)
                    return false;
            }
        }
    }
    return errors.size() == 0;
}
