Module.cpp revision 3508c387c3f0c9ecc439d98048fd7694d41bab1b
14b95526e5c4eb4fecde1cd642cf991a82c51b9f2johannkoenig@chromium.org//===-- Module.cpp ----------------------------------------------*- C++ -*-===//
24b95526e5c4eb4fecde1cd642cf991a82c51b9f2johannkoenig@chromium.org//
36fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org//                     The LLVM Compiler Infrastructure
46fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org//
56fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org// This file is distributed under the University of Illinois Open Source
66fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org// License. See LICENSE.TXT for details.
76fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org//
86fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org//===----------------------------------------------------------------------===//
96fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
10dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#include "lldb/Core/Module.h"
11dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#include "lldb/Core/DataBuffer.h"
12dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#include "lldb/Core/DataBufferHeap.h"
13dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#include "lldb/Core/Log.h"
146fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "lldb/Core/ModuleList.h"
156fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "lldb/Core/RegularExpression.h"
166fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "lldb/Core/StreamString.h"
176fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "lldb/Core/Timer.h"
186fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "lldb/Host/Host.h"
196fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "lldb/lldb-private-log.h"
206fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "lldb/Symbol/ObjectFile.h"
216fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "lldb/Symbol/SymbolContext.h"
226fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "lldb/Symbol/SymbolVendor.h"
236fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "lldb/Target/Process.h"
246fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "lldb/Target/Target.h"
256fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
266fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgusing namespace lldb;
276fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgusing namespace lldb_private;
286fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
29daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org// Shared pointers to modules track module lifetimes in
30daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org// targets and in the global module, but this collection
31daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org// will track all module objects that are still alive
32daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.orgtypedef std::vector<Module *> ModuleCollection;
33daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
346fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgstatic ModuleCollection &
35daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.orgGetModuleCollection()
36daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org{
37daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    // This module collection needs to live past any module, so we could either make it a
386fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    // shared pointer in each module or just leak is.  Since it is only an empty vector by
39daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    // the time all the modules have gone away, we just leak it for now.  If we decide this
40daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    // is a big problem we can introduce a Finalize method that will tear everything down in
41daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    // a predictable order.
426fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
43daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    static ModuleCollection *g_module_collection = NULL;
44daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    if (g_module_collection == NULL)
45daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        g_module_collection = new ModuleCollection();
46daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
47daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    return *g_module_collection;
486fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
49daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
50daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.orgMutex *
516fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgModule::GetAllocationModuleCollectionMutex()
52daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org{
53daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    // NOTE: The mutex below must be leaked since the global module list in
546fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    // the ModuleList class will get torn at some point, and we can't know
55daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    // if it will tear itself down before the "g_module_collection_mutex" below
56daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    // will. So we leak a Mutex object below to safeguard against that
576fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
58daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    static Mutex *g_module_collection_mutex = NULL;
59daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    if (g_module_collection_mutex == NULL)
60daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        g_module_collection_mutex = new Mutex (Mutex::eMutexTypeRecursive); // NOTE: known leak
61daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    return g_module_collection_mutex;
626fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
63daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
64daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.orgsize_t
65daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.orgModule::GetNumberAllocatedModules ()
66daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org{
676fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    Mutex::Locker locker (GetAllocationModuleCollectionMutex());
68daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    return GetModuleCollection().size();
69daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org}
70daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
71daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.orgModule *
726fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgModule::GetAllocatedModuleAtIndex (size_t idx)
73daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org{
74daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    Mutex::Locker locker (GetAllocationModuleCollectionMutex());
75daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    ModuleCollection &modules = GetModuleCollection();
766fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    if (idx < modules.size())
77daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        return modules[idx];
78daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    return NULL;
79daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org}
80daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org#if 0
816fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
826fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org// These functions help us to determine if modules are still loaded, yet don't require that
836fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org// you have a command interpreter and can easily be called from an external debugger.
846fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgnamespace lldb {
856fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
866fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    void
876fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    ClearModuleInfo (void)
886fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    {
896fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        ModuleList::RemoveOrphanSharedModules();
906fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    }
91daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
92daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    void
93daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    DumpModuleInfo (void)
946fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    {
95daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        Mutex::Locker locker (Module::GetAllocationModuleCollectionMutex());
96daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        ModuleCollection &modules = GetModuleCollection();
97daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        const size_t count = modules.size();
986fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        printf ("%s: %zu modules:\n", __PRETTY_FUNCTION__, count);
99118f379ec73bf762ee63784bc5f41ffd41107470johannkoenig@chromium.org        for (size_t i=0; i<count; ++i)
100118f379ec73bf762ee63784bc5f41ffd41107470johannkoenig@chromium.org        {
101daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
1026fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org            StreamString strm;
103daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org            Module *module = modules[i];
104daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org            const bool in_shared_module_list = ModuleList::ModuleIsInCache (module);
105daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org            module->GetDescription(&strm, eDescriptionLevelFull);
1066fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org            printf ("%p: shared = %i, ref_count = %3u, module = %s\n",
107daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                    module,
108daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                    in_shared_module_list,
109daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                    (uint32_t)module->use_count(),
110daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                    strm.GetString().c_str());
1116fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        }
112daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    }
113daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org}
114daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
115daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org#endif
1166fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
117daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
118daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.orgModule::Module(const FileSpec& file_spec, const lldb::ProcessSP &process_sp, lldb::addr_t header_addr) :
119daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    m_mutex (Mutex::eMutexTypeRecursive),
1206fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    m_mod_time (),
121daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    m_arch (),
122daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    m_uuid (),
123daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    m_file (file_spec),
1246fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    m_platform_file(),
125daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    m_symfile_spec (),
126daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    m_object_name (),
127daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    m_object_offset (),
128daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    m_objfile_sp (),
1296fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    m_symfile_ap (),
130daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    m_ast (),
131daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    m_did_load_objfile (false),
1326fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    m_did_load_symbol_vendor (false),
1336fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    m_did_parse_uuid (false),
1346fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    m_did_init_ast (false),
1356fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    m_is_dynamic_loader_module (false),
1366fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    m_was_modified (false)
137daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org{
138daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    // Scope for locker below...
139daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    {
1406fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        Mutex::Locker locker (GetAllocationModuleCollectionMutex());
1416fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        GetModuleCollection().push_back(this);
1426fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    }
1436fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    StreamString s;
144daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    if (m_file.GetFilename())
145daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        s << m_file.GetFilename();
146daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    s.Printf("[0x%16.16llx]", header_addr);
147daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    m_file.GetFilename().SetCString (s.GetData());
1486fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    Mutex::Locker locker (m_mutex);
149daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    DataBufferSP data_sp;
150daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    if (process_sp)
151daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    {
1526fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        m_did_load_objfile = true;
153daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        std::auto_ptr<DataBufferHeap> data_ap (new DataBufferHeap (512, 0));
154daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        Error error;
155daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        const size_t bytes_read = process_sp->ReadMemory (header_addr,
156daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                                                          data_ap->GetBytes(),
1576fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                                          data_ap->GetByteSize(),
158daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                                                          error);
159daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        if (bytes_read == 512)
1606fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        {
161daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org            data_sp.reset (data_ap.release());
162daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org            m_objfile_sp = ObjectFile::FindPlugin(shared_from_this(), process_sp, header_addr, data_sp);
163daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org            if (m_objfile_sp)
164daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org            {
1656fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                // Once we get the object file, update our module with the object file's
166daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                // architecture since it might differ in vendor/os if some parts were
167daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                // unknown.
168daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                m_objfile_sp->GetArchitecture (m_arch);
169daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org            }
1706fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        }
171daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    }
172daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org}
173daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
174daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.orgModule::Module(const FileSpec& file_spec,
1756fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org               const ArchSpec& arch,
176daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org               const ConstString *object_name,
177daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org               off_t object_offset) :
178daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    m_mutex (Mutex::eMutexTypeRecursive),
179daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    m_mod_time (file_spec.GetModificationTime()),
1806fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    m_arch (arch),
181daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    m_uuid (),
182daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    m_file (file_spec),
183daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    m_platform_file(),
184daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    m_symfile_spec (),
1856fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    m_object_name (),
186daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    m_object_offset (object_offset),
187daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    m_objfile_sp (),
188daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    m_symfile_ap (),
189daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    m_ast (),
1906fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    m_did_load_objfile (false),
191daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    m_did_load_symbol_vendor (false),
192daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    m_did_parse_uuid (false),
193daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    m_did_init_ast (false),
194daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    m_is_dynamic_loader_module (false),
1956fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    m_was_modified (false)
196daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org{
197daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    // Scope for locker below...
198daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    {
199daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        Mutex::Locker locker (GetAllocationModuleCollectionMutex());
2006fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        GetModuleCollection().push_back(this);
201daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    }
202daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
203daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    if (object_name)
204daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        m_object_name = *object_name;
2056fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
206daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    if (log)
207daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        log->Printf ("%p Module::Module((%s) '%s/%s%s%s%s')",
208daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                     this,
2096fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                     m_arch.GetArchitectureName(),
210daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                     m_file.GetDirectory().AsCString(""),
211daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                     m_file.GetFilename().AsCString(""),
212daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                     m_object_name.IsEmpty() ? "" : "(",
213daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                     m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""),
2146fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                     m_object_name.IsEmpty() ? "" : ")");
215daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org}
216daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
217daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.orgModule::~Module()
218daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org{
2196fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    // Scope for locker below...
220daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    {
221daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        Mutex::Locker locker (GetAllocationModuleCollectionMutex());
222daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        ModuleCollection &modules = GetModuleCollection();
223daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        ModuleCollection::iterator end = modules.end();
2246fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        ModuleCollection::iterator pos = std::find(modules.begin(), end, this);
225daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        if (pos != end)
226daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org            modules.erase(pos);
227daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    }
228daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
2296fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    if (log)
230daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        log->Printf ("%p Module::~Module((%s) '%s/%s%s%s%s')",
231daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                     this,
232daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                     m_arch.GetArchitectureName(),
2336fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                     m_file.GetDirectory().AsCString(""),
234daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                     m_file.GetFilename().AsCString(""),
235daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                     m_object_name.IsEmpty() ? "" : "(",
2366fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                     m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""),
237daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                     m_object_name.IsEmpty() ? "" : ")");
238daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    // Release any auto pointers before we start tearing down our member
2396fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    // variables since the object file and symbol files might need to make
240daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    // function calls back into this module object. The ordering is important
241daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    // here because symbol files can require the module object file. So we tear
2426fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    // down the symbol file first, then the object file.
243daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    m_symfile_ap.reset();
244daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    m_objfile_sp.reset();
245daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org}
2466fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
247daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
248daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.orgconst lldb_private::UUID&
24988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.orgModule::GetUUID()
25088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org{
2516fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    Mutex::Locker locker (m_mutex);
252daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    if (m_did_parse_uuid == false)
253daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    {
2546fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        ObjectFile * obj_file = GetObjectFile ();
2556fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
2566fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        if (obj_file != NULL)
2576fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        {
2586fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org            obj_file->GetUUID(&m_uuid);
2596fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org            m_did_parse_uuid = true;
2606fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        }
261daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    }
262daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    return m_uuid;
263daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org}
264daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
2656fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgClangASTContext &
266daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.orgModule::GetClangASTContext ()
267daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org{
268daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    Mutex::Locker locker (m_mutex);
2696fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    if (m_did_init_ast == false)
270daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    {
271daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        ObjectFile * objfile = GetObjectFile();
272daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        ArchSpec object_arch;
273daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        if (objfile && objfile->GetArchitecture(object_arch))
274daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        {
275daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org            m_did_init_ast = true;
276daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org            m_ast.SetArchitecture (object_arch);
277daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        }
2786fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    }
2796fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    return m_ast;
2806fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
2816fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
2826fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgvoid
2836fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgModule::ParseAllDebugSymbols()
284daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org{
285daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    Mutex::Locker locker (m_mutex);
286daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    uint32_t num_comp_units = GetNumCompileUnits();
2876fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    if (num_comp_units == 0)
2886fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        return;
2896fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
2906fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    SymbolContext sc;
2916fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    sc.module_sp = shared_from_this();
292daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    uint32_t cu_idx;
293daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    SymbolVendor *symbols = GetSymbolVendor ();
294daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
295daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    for (cu_idx = 0; cu_idx < num_comp_units; cu_idx++)
296daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    {
297daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        sc.comp_unit = symbols->GetCompileUnitAtIndex(cu_idx).get();
298daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        if (sc.comp_unit)
299daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        {
3006fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org            sc.function = NULL;
3016fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org            symbols->ParseVariablesForContext(sc);
3026fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
3036fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org            symbols->ParseCompileUnitFunctions(sc);
3046fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
305daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org            uint32_t func_idx;
306daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org            for (func_idx = 0; (sc.function = sc.comp_unit->GetFunctionAtIndex(func_idx).get()) != NULL; ++func_idx)
307daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org            {
308daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                symbols->ParseFunctionBlocks(sc);
309daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
310daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                // Parse the variables for this function and all its blocks
311daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                symbols->ParseVariablesForContext(sc);
312daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org            }
313daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
314daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
315daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org            // Parse all types for this compile unit
316daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org            sc.function = NULL;
3176fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org            symbols->ParseTypes(sc);
3186fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        }
3196fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    }
3206fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
3216fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
322daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.orgvoid
323daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.orgModule::CalculateSymbolContext(SymbolContext* sc)
324daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org{
3256fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    sc->module_sp = shared_from_this();
326daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org}
327daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
328daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.orgModuleSP
329daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.orgModule::CalculateSymbolContextModule ()
3306fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org{
331daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    return shared_from_this();
332daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org}
333daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
3346fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgvoid
335daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.orgModule::DumpSymbolContext(Stream *s)
336daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org{
337daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    s->Printf(", Module{%p}", this);
3386fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
339daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
340daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.orguint32_t
341daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.orgModule::GetNumCompileUnits()
3426fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org{
3436fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    Mutex::Locker locker (m_mutex);
3446fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    Timer scoped_timer(__PRETTY_FUNCTION__, "Module::GetNumCompileUnits (module = %p)", this);
3456fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    SymbolVendor *symbols = GetSymbolVendor ();
3466fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    if (symbols)
3476fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        return symbols->GetNumCompileUnits();
3486fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    return 0;
3496fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
3506fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
3516fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgCompUnitSP
3526fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgModule::GetCompileUnitAtIndex (uint32_t index)
353daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org{
354daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    Mutex::Locker locker (m_mutex);
355daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    uint32_t num_comp_units = GetNumCompileUnits ();
356daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    CompUnitSP cu_sp;
357daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
358daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    if (index < num_comp_units)
359daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    {
360daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        SymbolVendor *symbols = GetSymbolVendor ();
361daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        if (symbols)
362daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org            cu_sp = symbols->GetCompileUnitAtIndex(index);
363daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    }
364daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    return cu_sp;
3656fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
3666fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
3676fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgbool
3686fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgModule::ResolveFileAddress (lldb::addr_t vm_addr, Address& so_addr)
369daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org{
370daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    Mutex::Locker locker (m_mutex);
371daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    Timer scoped_timer(__PRETTY_FUNCTION__, "Module::ResolveFileAddress (vm_addr = 0x%llx)", vm_addr);
372daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    ObjectFile* ofile = GetObjectFile();
373daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    if (ofile)
3746fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        return so_addr.ResolveAddressUsingFileSections(vm_addr, ofile->GetSectionList());
375daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    return false;
376daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org}
377daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
378daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.orguint32_t
3796fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgModule::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
380daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org{
381daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    Mutex::Locker locker (m_mutex);
382daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    uint32_t resolved_flags = 0;
383daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
384daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    // Clear the result symbol context in case we don't find anything
3856fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    sc.Clear();
386daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
387daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    // Get the section from the section/offset address.
388daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    SectionSP section_sp (so_addr.GetSection());
389daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
390daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    // Make sure the section matches this module before we try and match anything
3916fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    if (section_sp && section_sp->GetModule().get() == this)
392daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    {
393daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        // If the section offset based address resolved itself, then this
394daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        // is the right module.
395daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        sc.module_sp = shared_from_this();
3966fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        resolved_flags |= eSymbolContextModule;
397daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
398daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        // Resolve the compile unit, function, block, line table or line
399daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        // entry if requested.
400daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        if (resolve_scope & eSymbolContextCompUnit    ||
401daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org            resolve_scope & eSymbolContextFunction    ||
4026fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org            resolve_scope & eSymbolContextBlock       ||
403daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org            resolve_scope & eSymbolContextLineEntry   )
404daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        {
405daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org            SymbolVendor *symbols = GetSymbolVendor ();
406daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org            if (symbols)
407daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                resolved_flags |= symbols->ResolveSymbolContext (so_addr, resolve_scope, sc);
4086fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        }
409daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
410daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        // Resolve the symbol if requested, but don't re-look it up if we've already found it.
411daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        if (resolve_scope & eSymbolContextSymbol && !(resolved_flags & eSymbolContextSymbol))
412daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        {
4136fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org            ObjectFile* ofile = GetObjectFile();
414daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org            if (ofile)
415daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org            {
416daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                Symtab *symtab = ofile->GetSymtab();
417daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                if (symtab)
4186fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                {
419daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                    if (so_addr.IsSectionOffset())
420daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                    {
421daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                        sc.symbol = symtab->FindSymbolContainingFileAddress(so_addr.GetFileAddress());
422daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                        if (sc.symbol)
4236fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                            resolved_flags |= eSymbolContextSymbol;
4246fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                    }
4256fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                }
4266fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org            }
4276fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        }
4286fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    }
429daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    return resolved_flags;
430daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org}
431daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
432daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.orguint32_t
433daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.orgModule::ResolveSymbolContextForFilePath
4346fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org(
4356fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    const char *file_path,
4366fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    uint32_t line,
4376fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    bool check_inlines,
4386fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    uint32_t resolve_scope,
439daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    SymbolContextList& sc_list
440daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org)
441daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org{
442daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    FileSpec file_spec(file_path, false);
4436fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    return ResolveSymbolContextsForFileSpec (file_spec, line, check_inlines, resolve_scope, sc_list);
444daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org}
445daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
446daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.orguint32_t
447daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.orgModule::ResolveSymbolContextsForFileSpec (const FileSpec &file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
4486fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org{
449daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    Mutex::Locker locker (m_mutex);
450daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    Timer scoped_timer(__PRETTY_FUNCTION__,
451daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                       "Module::ResolveSymbolContextForFilePath (%s%s%s:%u, check_inlines = %s, resolve_scope = 0x%8.8x)",
452daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                       file_spec.GetDirectory().AsCString(""),
4536fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                       file_spec.GetDirectory() ? "/" : "",
454daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                       file_spec.GetFilename().AsCString(""),
455daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                       line,
456daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                       check_inlines ? "yes" : "no",
457daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                       resolve_scope);
458daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
459daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    const uint32_t initial_count = sc_list.GetSize();
460daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
461daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    SymbolVendor *symbols = GetSymbolVendor  ();
462daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    if (symbols)
463daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        symbols->ResolveSymbolContext (file_spec, line, check_inlines, resolve_scope, sc_list);
464daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
465daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    return sc_list.GetSize() - initial_count;
466daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org}
467daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
468daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
469daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.orguint32_t
470daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.orgModule::FindGlobalVariables(const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, VariableList& variables)
471daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org{
472daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    SymbolVendor *symbols = GetSymbolVendor ();
473daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    if (symbols)
474daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        return symbols->FindGlobalVariables(name, namespace_decl, append, max_matches, variables);
475daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    return 0;
476daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org}
477daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.orguint32_t
4786fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgModule::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
4796fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org{
4806fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    SymbolVendor *symbols = GetSymbolVendor ();
4816fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    if (symbols)
4826fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        return symbols->FindGlobalVariables(regex, append, max_matches, variables);
4836fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    return 0;
4846fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
4856fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
4866fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orguint32_t
4876fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgModule::FindCompileUnits (const FileSpec &path,
4886fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                          bool append,
4896fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                          SymbolContextList &sc_list)
4906fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org{
4916fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    if (!append)
492daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        sc_list.Clear();
493daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
494daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    const uint32_t start_size = sc_list.GetSize();
495daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    const uint32_t num_compile_units = GetNumCompileUnits();
496daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    SymbolContext sc;
497daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    sc.module_sp = shared_from_this();
498daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    const bool compare_directory = path.GetDirectory();
499daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    for (uint32_t i=0; i<num_compile_units; ++i)
500daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    {
501daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        sc.comp_unit = GetCompileUnitAtIndex(i).get();
502daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        if (FileSpec::Equal (*sc.comp_unit, path, compare_directory))
503daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org            sc_list.Append(sc);
504daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    }
505daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    return sc_list.GetSize() - start_size;
506daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org}
507daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
508daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.orguint32_t
509daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.orgModule::FindFunctions (const ConstString &name,
510daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                       const ClangNamespaceDecl *namespace_decl,
51188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org                       uint32_t name_type_mask,
51288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org                       bool include_symbols,
5136fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                       bool include_inlines,
5146fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                       bool append,
5156fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                       SymbolContextList& sc_list)
5166fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org{
5176fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    if (!append)
518daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        sc_list.Clear();
519daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
5206fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    const uint32_t start_size = sc_list.GetSize();
5216fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
522daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    // Find all the functions (not symbols, but debug information functions...
523daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    SymbolVendor *symbols = GetSymbolVendor ();
524daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    if (symbols)
5256fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        symbols->FindFunctions(name, namespace_decl, name_type_mask, include_inlines, append, sc_list);
5266fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
527daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    // Now check our symbol table for symbols that are code symbols if requested
528daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    if (include_symbols)
529daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    {
530daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        ObjectFile *objfile = GetObjectFile();
531daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        if (objfile)
532daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        {
533daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org            Symtab *symtab = objfile->GetSymtab();
534daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org            if (symtab)
535daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org            {
536daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                std::vector<uint32_t> symbol_indexes;
537daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                symtab->FindAllSymbolsWithNameAndType (name, eSymbolTypeCode, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes);
538daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                const uint32_t num_matches = symbol_indexes.size();
539daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                if (num_matches)
540daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                {
541daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                    const bool merge_symbol_into_function = true;
542daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                    SymbolContext sc(this);
543daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                    for (uint32_t i=0; i<num_matches; i++)
544daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                    {
545daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                        sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
546daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                        sc_list.AppendIfUnique (sc, merge_symbol_into_function);
547daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                    }
548daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                }
549daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org            }
550daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org        }
551daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    }
552daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org    return sc_list.GetSize() - start_size;
553daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org}
554daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org
555daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.orguint32_t
556daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.orgModule::FindFunctions (const RegularExpression& regex,
557daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                       bool include_symbols,
558daa317752787969f0b39e74dacf35acc11e4b79afgalligan@chromium.org                       bool include_inlines,
5596fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                       bool append,
5606fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                       SymbolContextList& sc_list)
561dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org{
562dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    if (!append)
563dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org        sc_list.Clear();
564dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
565dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org    const uint32_t start_size = sc_list.GetSize();
5666fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
567    SymbolVendor *symbols = GetSymbolVendor ();
568    if (symbols)
569        symbols->FindFunctions(regex, include_inlines, append, sc_list);
570    // Now check our symbol table for symbols that are code symbols if requested
571    if (include_symbols)
572    {
573        ObjectFile *objfile = GetObjectFile();
574        if (objfile)
575        {
576            Symtab *symtab = objfile->GetSymtab();
577            if (symtab)
578            {
579                std::vector<uint32_t> symbol_indexes;
580                symtab->AppendSymbolIndexesMatchingRegExAndType (regex, eSymbolTypeCode, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes);
581                const uint32_t num_matches = symbol_indexes.size();
582                if (num_matches)
583                {
584                    const bool merge_symbol_into_function = true;
585                    SymbolContext sc(this);
586                    for (uint32_t i=0; i<num_matches; i++)
587                    {
588                        sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
589                        sc_list.AppendIfUnique (sc, merge_symbol_into_function);
590                    }
591                }
592            }
593        }
594    }
595    return sc_list.GetSize() - start_size;
596}
597
598uint32_t
599Module::FindTypes_Impl (const SymbolContext& sc, const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, TypeList& types)
600{
601    Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
602    if (sc.module_sp.get() == NULL || sc.module_sp.get() == this)
603    {
604        SymbolVendor *symbols = GetSymbolVendor ();
605        if (symbols)
606            return symbols->FindTypes(sc, name, namespace_decl, append, max_matches, types);
607    }
608    return 0;
609}
610
611// depending on implementation details, type lookup might fail because of
612// embedded spurious namespace:: prefixes. this call strips them, paying
613// attention to the fact that a type might have namespace'd type names as
614// arguments to templates, and those must not be stripped off
615static const char*
616StripTypeName(const char* name_cstr)
617{
618    // Protect against null c string.
619    if (!name_cstr)
620        return name_cstr;
621    const char* skip_namespace = strstr(name_cstr, "::");
622    const char* template_arg_char = strchr(name_cstr, '<');
623    while (skip_namespace != NULL)
624    {
625        if (template_arg_char != NULL &&
626            skip_namespace > template_arg_char) // but namespace'd template arguments are still good to go
627            break;
628        name_cstr = skip_namespace+2;
629        skip_namespace = strstr(name_cstr, "::");
630    }
631    return name_cstr;
632}
633
634uint32_t
635Module::FindTypes (const SymbolContext& sc,  const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, TypeList& types)
636{
637    uint32_t retval = FindTypes_Impl(sc, name, namespace_decl, append, max_matches, types);
638
639    if (retval == 0)
640    {
641        const char *orig_name = name.GetCString();
642        const char *stripped = StripTypeName(orig_name);
643        // Only do this lookup if StripTypeName has stripped the name:
644        if (stripped != orig_name)
645           return FindTypes_Impl(sc, ConstString(stripped), namespace_decl, append, max_matches, types);
646        else
647            return 0;
648    }
649    else
650        return retval;
651
652}
653
654//uint32_t
655//Module::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, const char *udt_name, TypeList& types)
656//{
657//  Timer scoped_timer(__PRETTY_FUNCTION__);
658//  SymbolVendor *symbols = GetSymbolVendor ();
659//  if (symbols)
660//      return symbols->FindTypes(sc, regex, append, max_matches, encoding, udt_name, types);
661//  return 0;
662//
663//}
664
665SymbolVendor*
666Module::GetSymbolVendor (bool can_create)
667{
668    Mutex::Locker locker (m_mutex);
669    if (m_did_load_symbol_vendor == false && can_create)
670    {
671        ObjectFile *obj_file = GetObjectFile ();
672        if (obj_file != NULL)
673        {
674            Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
675            m_symfile_ap.reset(SymbolVendor::FindPlugin(shared_from_this()));
676            m_did_load_symbol_vendor = true;
677        }
678    }
679    return m_symfile_ap.get();
680}
681
682void
683Module::SetFileSpecAndObjectName (const FileSpec &file, const ConstString &object_name)
684{
685    // Container objects whose paths do not specify a file directly can call
686    // this function to correct the file and object names.
687    m_file = file;
688    m_mod_time = file.GetModificationTime();
689    m_object_name = object_name;
690}
691
692const ArchSpec&
693Module::GetArchitecture () const
694{
695    return m_arch;
696}
697
698void
699Module::GetDescription (Stream *s, lldb::DescriptionLevel level)
700{
701    Mutex::Locker locker (m_mutex);
702
703    if (level >= eDescriptionLevelFull)
704    {
705        if (m_arch.IsValid())
706            s->Printf("(%s) ", m_arch.GetArchitectureName());
707    }
708
709    if (level == eDescriptionLevelBrief)
710    {
711        const char *filename = m_file.GetFilename().GetCString();
712        if (filename)
713            s->PutCString (filename);
714    }
715    else
716    {
717        char path[PATH_MAX];
718        if (m_file.GetPath(path, sizeof(path)))
719            s->PutCString(path);
720    }
721
722    const char *object_name = m_object_name.GetCString();
723    if (object_name)
724        s->Printf("(%s)", object_name);
725}
726
727void
728Module::ReportError (const char *format, ...)
729{
730    if (format && format[0])
731    {
732        StreamString strm;
733        strm.PutCString("error: ");
734        GetDescription(&strm, lldb::eDescriptionLevelBrief);
735        strm.PutChar (' ');
736        va_list args;
737        va_start (args, format);
738        strm.PrintfVarArg(format, args);
739        va_end (args);
740
741        const int format_len = strlen(format);
742        if (format_len > 0)
743        {
744            const char last_char = format[format_len-1];
745            if (last_char != '\n' || last_char != '\r')
746                strm.EOL();
747        }
748        Host::SystemLog (Host::eSystemLogError, "%s", strm.GetString().c_str());
749
750    }
751}
752
753void
754Module::ReportErrorIfModifyDetected (const char *format, ...)
755{
756    if (!GetModified(true) && GetModified(false))
757    {
758        if (format)
759        {
760            StreamString strm;
761            strm.PutCString("error: the object file ");
762            GetDescription(&strm, lldb::eDescriptionLevelFull);
763            strm.PutCString (" has been modified\n");
764
765            va_list args;
766            va_start (args, format);
767            strm.PrintfVarArg(format, args);
768            va_end (args);
769
770            const int format_len = strlen(format);
771            if (format_len > 0)
772            {
773                const char last_char = format[format_len-1];
774                if (last_char != '\n' || last_char != '\r')
775                    strm.EOL();
776            }
777            strm.PutCString("The debug session should be aborted as the original debug information has been overwritten.\n");
778            Host::SystemLog (Host::eSystemLogError, "%s", strm.GetString().c_str());
779        }
780    }
781}
782
783void
784Module::ReportWarning (const char *format, ...)
785{
786    if (format && format[0])
787    {
788        StreamString strm;
789        strm.PutCString("warning: ");
790        GetDescription(&strm, lldb::eDescriptionLevelFull);
791        strm.PutChar (' ');
792
793        va_list args;
794        va_start (args, format);
795        strm.PrintfVarArg(format, args);
796        va_end (args);
797
798        const int format_len = strlen(format);
799        if (format_len > 0)
800        {
801            const char last_char = format[format_len-1];
802            if (last_char != '\n' || last_char != '\r')
803                strm.EOL();
804        }
805        Host::SystemLog (Host::eSystemLogWarning, "%s", strm.GetString().c_str());
806    }
807}
808
809void
810Module::LogMessage (Log *log, const char *format, ...)
811{
812    if (log)
813    {
814        StreamString log_message;
815        GetDescription(&log_message, lldb::eDescriptionLevelFull);
816        log_message.PutCString (": ");
817        va_list args;
818        va_start (args, format);
819        log_message.PrintfVarArg (format, args);
820        va_end (args);
821        log->PutCString(log_message.GetString().c_str());
822    }
823}
824
825bool
826Module::GetModified (bool use_cached_only)
827{
828    if (m_was_modified == false && use_cached_only == false)
829    {
830        TimeValue curr_mod_time (m_file.GetModificationTime());
831        m_was_modified = curr_mod_time != m_mod_time;
832    }
833    return m_was_modified;
834}
835
836bool
837Module::SetModified (bool b)
838{
839    const bool prev_value = m_was_modified;
840    m_was_modified = b;
841    return prev_value;
842}
843
844
845void
846Module::Dump(Stream *s)
847{
848    Mutex::Locker locker (m_mutex);
849    //s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
850    s->Indent();
851    s->Printf("Module %s/%s%s%s%s\n",
852              m_file.GetDirectory().AsCString(),
853              m_file.GetFilename().AsCString(),
854              m_object_name ? "(" : "",
855              m_object_name ? m_object_name.GetCString() : "",
856              m_object_name ? ")" : "");
857
858    s->IndentMore();
859    ObjectFile *objfile = GetObjectFile ();
860
861    if (objfile)
862        objfile->Dump(s);
863
864    SymbolVendor *symbols = GetSymbolVendor ();
865
866    if (symbols)
867        symbols->Dump(s);
868
869    s->IndentLess();
870}
871
872
873TypeList*
874Module::GetTypeList ()
875{
876    SymbolVendor *symbols = GetSymbolVendor ();
877    if (symbols)
878        return &symbols->GetTypeList();
879    return NULL;
880}
881
882const ConstString &
883Module::GetObjectName() const
884{
885    return m_object_name;
886}
887
888ObjectFile *
889Module::GetObjectFile()
890{
891    Mutex::Locker locker (m_mutex);
892    if (m_did_load_objfile == false)
893    {
894        m_did_load_objfile = true;
895        Timer scoped_timer(__PRETTY_FUNCTION__,
896                           "Module::GetObjectFile () module = %s", GetFileSpec().GetFilename().AsCString(""));
897        DataBufferSP file_data_sp;
898        m_objfile_sp = ObjectFile::FindPlugin (shared_from_this(),
899                                               &m_file,
900                                               m_object_offset,
901                                               m_file.GetByteSize(),
902                                               file_data_sp);
903        if (m_objfile_sp)
904        {
905			// Once we get the object file, update our module with the object file's
906			// architecture since it might differ in vendor/os if some parts were
907			// unknown.
908            m_objfile_sp->GetArchitecture (m_arch);
909        }
910    }
911    return m_objfile_sp.get();
912}
913
914
915const Symbol *
916Module::FindFirstSymbolWithNameAndType (const ConstString &name, SymbolType symbol_type)
917{
918    Timer scoped_timer(__PRETTY_FUNCTION__,
919                       "Module::FindFirstSymbolWithNameAndType (name = %s, type = %i)",
920                       name.AsCString(),
921                       symbol_type);
922    ObjectFile *objfile = GetObjectFile();
923    if (objfile)
924    {
925        Symtab *symtab = objfile->GetSymtab();
926        if (symtab)
927            return symtab->FindFirstSymbolWithNameAndType (name, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny);
928    }
929    return NULL;
930}
931void
932Module::SymbolIndicesToSymbolContextList (Symtab *symtab, std::vector<uint32_t> &symbol_indexes, SymbolContextList &sc_list)
933{
934    // No need to protect this call using m_mutex all other method calls are
935    // already thread safe.
936
937    size_t num_indices = symbol_indexes.size();
938    if (num_indices > 0)
939    {
940        SymbolContext sc;
941        CalculateSymbolContext (&sc);
942        for (size_t i = 0; i < num_indices; i++)
943        {
944            sc.symbol = symtab->SymbolAtIndex (symbol_indexes[i]);
945            if (sc.symbol)
946                sc_list.Append (sc);
947        }
948    }
949}
950
951size_t
952Module::FindSymbolsWithNameAndType (const ConstString &name, SymbolType symbol_type, SymbolContextList &sc_list)
953{
954    // No need to protect this call using m_mutex all other method calls are
955    // already thread safe.
956
957
958    Timer scoped_timer(__PRETTY_FUNCTION__,
959                       "Module::FindSymbolsWithNameAndType (name = %s, type = %i)",
960                       name.AsCString(),
961                       symbol_type);
962    const size_t initial_size = sc_list.GetSize();
963    ObjectFile *objfile = GetObjectFile ();
964    if (objfile)
965    {
966        Symtab *symtab = objfile->GetSymtab();
967        if (symtab)
968        {
969            std::vector<uint32_t> symbol_indexes;
970            symtab->FindAllSymbolsWithNameAndType (name, symbol_type, symbol_indexes);
971            SymbolIndicesToSymbolContextList (symtab, symbol_indexes, sc_list);
972        }
973    }
974    return sc_list.GetSize() - initial_size;
975}
976
977size_t
978Module::FindSymbolsMatchingRegExAndType (const RegularExpression &regex, SymbolType symbol_type, SymbolContextList &sc_list)
979{
980    // No need to protect this call using m_mutex all other method calls are
981    // already thread safe.
982
983    Timer scoped_timer(__PRETTY_FUNCTION__,
984                       "Module::FindSymbolsMatchingRegExAndType (regex = %s, type = %i)",
985                       regex.GetText(),
986                       symbol_type);
987    const size_t initial_size = sc_list.GetSize();
988    ObjectFile *objfile = GetObjectFile ();
989    if (objfile)
990    {
991        Symtab *symtab = objfile->GetSymtab();
992        if (symtab)
993        {
994            std::vector<uint32_t> symbol_indexes;
995            symtab->FindAllSymbolsMatchingRexExAndType (regex, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes);
996            SymbolIndicesToSymbolContextList (symtab, symbol_indexes, sc_list);
997        }
998    }
999    return sc_list.GetSize() - initial_size;
1000}
1001
1002const TimeValue &
1003Module::GetModificationTime () const
1004{
1005    return m_mod_time;
1006}
1007
1008bool
1009Module::IsExecutable ()
1010{
1011    if (GetObjectFile() == NULL)
1012        return false;
1013    else
1014        return GetObjectFile()->IsExecutable();
1015}
1016
1017bool
1018Module::IsLoadedInTarget (Target *target)
1019{
1020    ObjectFile *obj_file = GetObjectFile();
1021    if (obj_file)
1022    {
1023        SectionList *sections = obj_file->GetSectionList();
1024        if (sections != NULL)
1025        {
1026            size_t num_sections = sections->GetSize();
1027            for (size_t sect_idx = 0; sect_idx < num_sections; sect_idx++)
1028            {
1029                SectionSP section_sp = sections->GetSectionAtIndex(sect_idx);
1030                if (section_sp->GetLoadBaseAddress(target) != LLDB_INVALID_ADDRESS)
1031                {
1032                    return true;
1033                }
1034            }
1035        }
1036    }
1037    return false;
1038}
1039bool
1040Module::SetArchitecture (const ArchSpec &new_arch)
1041{
1042    if (!m_arch.IsValid())
1043    {
1044        m_arch = new_arch;
1045        return true;
1046    }
1047    return m_arch == new_arch;
1048}
1049
1050bool
1051Module::SetLoadAddress (Target &target, lldb::addr_t offset, bool &changed)
1052{
1053    changed = false;
1054    ObjectFile *image_object_file = GetObjectFile();
1055    if (image_object_file)
1056    {
1057        SectionList *section_list = image_object_file->GetSectionList ();
1058        if (section_list)
1059        {
1060            const size_t num_sections = section_list->GetSize();
1061            size_t sect_idx = 0;
1062            for (sect_idx = 0; sect_idx < num_sections; ++sect_idx)
1063            {
1064                // Iterate through the object file sections to find the
1065                // first section that starts of file offset zero and that
1066                // has bytes in the file...
1067                Section *section = section_list->GetSectionAtIndex (sect_idx).get();
1068                if (section)
1069                {
1070                    if (target.GetSectionLoadList().SetSectionLoadAddress (section, section->GetFileAddress() + offset))
1071                        changed = true;
1072                }
1073            }
1074            return sect_idx > 0;
1075        }
1076    }
1077    return false;
1078}
1079
1080