1ac7ddfbfSEd Maste //===-- Module.cpp ----------------------------------------------*- C++ -*-===//
2ac7ddfbfSEd Maste //
3ac7ddfbfSEd Maste //                     The LLVM Compiler Infrastructure
4ac7ddfbfSEd Maste //
5ac7ddfbfSEd Maste // This file is distributed under the University of Illinois Open Source
6ac7ddfbfSEd Maste // License. See LICENSE.TXT for details.
7ac7ddfbfSEd Maste //
8ac7ddfbfSEd Maste //===----------------------------------------------------------------------===//
9ac7ddfbfSEd Maste 
104bb0738eSEd Maste #include "lldb/Core/Module.h"
114bb0738eSEd Maste 
12*b5893f02SDimitry Andric #include "lldb/Core/AddressRange.h"
1335617911SEd Maste #include "lldb/Core/AddressResolverFileLine.h"
14*b5893f02SDimitry Andric #include "lldb/Core/Debugger.h"
15*b5893f02SDimitry Andric #include "lldb/Core/FileSpecList.h"
16*b5893f02SDimitry Andric #include "lldb/Core/Mangled.h"
17ac7ddfbfSEd Maste #include "lldb/Core/ModuleSpec.h"
18*b5893f02SDimitry Andric #include "lldb/Core/SearchFilter.h"
19ac7ddfbfSEd Maste #include "lldb/Core/Section.h"
20435933ddSDimitry Andric #include "lldb/Host/FileSystem.h"
21ac7ddfbfSEd Maste #include "lldb/Host/Host.h"
22ac7ddfbfSEd Maste #include "lldb/Interpreter/CommandInterpreter.h"
23ac7ddfbfSEd Maste #include "lldb/Interpreter/ScriptInterpreter.h"
24ac7ddfbfSEd Maste #include "lldb/Symbol/CompileUnit.h"
25*b5893f02SDimitry Andric #include "lldb/Symbol/Function.h"
26ac7ddfbfSEd Maste #include "lldb/Symbol/ObjectFile.h"
27*b5893f02SDimitry Andric #include "lldb/Symbol/Symbol.h"
28ac7ddfbfSEd Maste #include "lldb/Symbol/SymbolContext.h"
299f2f44ceSEd Maste #include "lldb/Symbol/SymbolFile.h"
30ac7ddfbfSEd Maste #include "lldb/Symbol/SymbolVendor.h"
31*b5893f02SDimitry Andric #include "lldb/Symbol/Symtab.h"
32*b5893f02SDimitry Andric #include "lldb/Symbol/Type.h"
33*b5893f02SDimitry Andric #include "lldb/Symbol/TypeList.h"
34435933ddSDimitry Andric #include "lldb/Symbol/TypeMap.h"
359f2f44ceSEd Maste #include "lldb/Symbol/TypeSystem.h"
369f2f44ceSEd Maste #include "lldb/Target/Language.h"
37*b5893f02SDimitry Andric #include "lldb/Target/Platform.h"
38ac7ddfbfSEd Maste #include "lldb/Target/Process.h"
39ac7ddfbfSEd Maste #include "lldb/Target/Target.h"
40f678e45dSDimitry Andric #include "lldb/Utility/DataBufferHeap.h"
414ba319b5SDimitry Andric #include "lldb/Utility/LLDBAssert.h"
42f678e45dSDimitry Andric #include "lldb/Utility/Log.h"
43*b5893f02SDimitry Andric #include "lldb/Utility/Logging.h"
44f678e45dSDimitry Andric #include "lldb/Utility/RegularExpression.h"
455517e702SDimitry Andric #include "lldb/Utility/Status.h"
46*b5893f02SDimitry Andric #include "lldb/Utility/Stream.h"
47f678e45dSDimitry Andric #include "lldb/Utility/StreamString.h"
48a580b014SDimitry Andric #include "lldb/Utility/Timer.h"
49ac7ddfbfSEd Maste 
504ba319b5SDimitry Andric #if defined(_WIN32)
51*b5893f02SDimitry Andric #include "lldb/Host/windows/PosixApi.h"
52f678e45dSDimitry Andric #endif
53f678e45dSDimitry Andric 
54f678e45dSDimitry Andric #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
55f678e45dSDimitry Andric #include "Plugins/Language/ObjC/ObjCLanguage.h"
560127ef0fSEd Maste 
57*b5893f02SDimitry Andric #include "llvm/ADT/STLExtras.h"
58*b5893f02SDimitry Andric #include "llvm/Support/Compiler.h"
59f678e45dSDimitry Andric #include "llvm/Support/FileSystem.h"
60f678e45dSDimitry Andric #include "llvm/Support/Signals.h"
61*b5893f02SDimitry Andric #include "llvm/Support/raw_ostream.h"
62f678e45dSDimitry Andric 
63*b5893f02SDimitry Andric #include <assert.h>
64*b5893f02SDimitry Andric #include <cstdint>
65*b5893f02SDimitry Andric #include <inttypes.h>
66*b5893f02SDimitry Andric #include <map>
67*b5893f02SDimitry Andric #include <stdarg.h>
68*b5893f02SDimitry Andric #include <string.h>
69*b5893f02SDimitry Andric #include <type_traits>
70*b5893f02SDimitry Andric #include <utility>
71f678e45dSDimitry Andric 
72f678e45dSDimitry Andric namespace lldb_private {
73f678e45dSDimitry Andric class CompilerDeclContext;
74f678e45dSDimitry Andric }
75f678e45dSDimitry Andric namespace lldb_private {
76f678e45dSDimitry Andric class VariableList;
77f678e45dSDimitry Andric }
78f678e45dSDimitry Andric 
79ac7ddfbfSEd Maste using namespace lldb;
80ac7ddfbfSEd Maste using namespace lldb_private;
81ac7ddfbfSEd Maste 
824ba319b5SDimitry Andric // Shared pointers to modules track module lifetimes in targets and in the
834ba319b5SDimitry Andric // global module, but this collection will track all module objects that are
844ba319b5SDimitry Andric // still alive
85ac7ddfbfSEd Maste typedef std::vector<Module *> ModuleCollection;
86ac7ddfbfSEd Maste 
GetModuleCollection()87435933ddSDimitry Andric static ModuleCollection &GetModuleCollection() {
88435933ddSDimitry Andric   // This module collection needs to live past any module, so we could either
894ba319b5SDimitry Andric   // make it a shared pointer in each module or just leak is.  Since it is only
904ba319b5SDimitry Andric   // an empty vector by the time all the modules have gone away, we just leak
914ba319b5SDimitry Andric   // it for now.  If we decide this is a big problem we can introduce a
924ba319b5SDimitry Andric   // Finalize method that will tear everything down in a predictable order.
93ac7ddfbfSEd Maste 
944bb0738eSEd Maste   static ModuleCollection *g_module_collection = nullptr;
954bb0738eSEd Maste   if (g_module_collection == nullptr)
96ac7ddfbfSEd Maste     g_module_collection = new ModuleCollection();
97ac7ddfbfSEd Maste 
98ac7ddfbfSEd Maste   return *g_module_collection;
99ac7ddfbfSEd Maste }
100ac7ddfbfSEd Maste 
GetAllocationModuleCollectionMutex()101435933ddSDimitry Andric std::recursive_mutex &Module::GetAllocationModuleCollectionMutex() {
102ac7ddfbfSEd Maste   // NOTE: The mutex below must be leaked since the global module list in
1034ba319b5SDimitry Andric   // the ModuleList class will get torn at some point, and we can't know if it
1044ba319b5SDimitry Andric   // will tear itself down before the "g_module_collection_mutex" below will.
1054ba319b5SDimitry Andric   // So we leak a Mutex object below to safeguard against that
106ac7ddfbfSEd Maste 
1074bb0738eSEd Maste   static std::recursive_mutex *g_module_collection_mutex = nullptr;
1084bb0738eSEd Maste   if (g_module_collection_mutex == nullptr)
1094bb0738eSEd Maste     g_module_collection_mutex = new std::recursive_mutex; // NOTE: known leak
1104bb0738eSEd Maste   return *g_module_collection_mutex;
111ac7ddfbfSEd Maste }
112ac7ddfbfSEd Maste 
GetNumberAllocatedModules()113435933ddSDimitry Andric size_t Module::GetNumberAllocatedModules() {
114435933ddSDimitry Andric   std::lock_guard<std::recursive_mutex> guard(
115435933ddSDimitry Andric       GetAllocationModuleCollectionMutex());
116ac7ddfbfSEd Maste   return GetModuleCollection().size();
117ac7ddfbfSEd Maste }
118ac7ddfbfSEd Maste 
GetAllocatedModuleAtIndex(size_t idx)119435933ddSDimitry Andric Module *Module::GetAllocatedModuleAtIndex(size_t idx) {
120435933ddSDimitry Andric   std::lock_guard<std::recursive_mutex> guard(
121435933ddSDimitry Andric       GetAllocationModuleCollectionMutex());
122ac7ddfbfSEd Maste   ModuleCollection &modules = GetModuleCollection();
123ac7ddfbfSEd Maste   if (idx < modules.size())
124ac7ddfbfSEd Maste     return modules[idx];
1254bb0738eSEd Maste   return nullptr;
126ac7ddfbfSEd Maste }
127ac7ddfbfSEd Maste 
Module(const ModuleSpec & module_spec)1284bb0738eSEd Maste Module::Module(const ModuleSpec &module_spec)
129435933ddSDimitry Andric     : m_object_offset(0), m_file_has_changed(false),
130435933ddSDimitry Andric       m_first_file_changed_log(false) {
131ac7ddfbfSEd Maste   // Scope for locker below...
132ac7ddfbfSEd Maste   {
133435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
134435933ddSDimitry Andric         GetAllocationModuleCollectionMutex());
135ac7ddfbfSEd Maste     GetModuleCollection().push_back(this);
136ac7ddfbfSEd Maste   }
137ac7ddfbfSEd Maste 
138435933ddSDimitry Andric   Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_OBJECT |
139435933ddSDimitry Andric                                                   LIBLLDB_LOG_MODULES));
1404bb0738eSEd Maste   if (log != nullptr)
1414bb0738eSEd Maste     log->Printf("%p Module::Module((%s) '%s%s%s%s')", static_cast<void *>(this),
142435933ddSDimitry Andric                 module_spec.GetArchitecture().GetArchitectureName(),
143435933ddSDimitry Andric                 module_spec.GetFileSpec().GetPath().c_str(),
1440127ef0fSEd Maste                 module_spec.GetObjectName().IsEmpty() ? "" : "(",
145435933ddSDimitry Andric                 module_spec.GetObjectName().IsEmpty()
146435933ddSDimitry Andric                     ? ""
147435933ddSDimitry Andric                     : module_spec.GetObjectName().AsCString(""),
1480127ef0fSEd Maste                 module_spec.GetObjectName().IsEmpty() ? "" : ")");
1490127ef0fSEd Maste 
1504ba319b5SDimitry Andric   // First extract all module specifications from the file using the local file
1514ba319b5SDimitry Andric   // path. If there are no specifications, then don't fill anything in
1520127ef0fSEd Maste   ModuleSpecList modules_specs;
153435933ddSDimitry Andric   if (ObjectFile::GetModuleSpecifications(module_spec.GetFileSpec(), 0, 0,
154435933ddSDimitry Andric                                           modules_specs) == 0)
1550127ef0fSEd Maste     return;
1560127ef0fSEd Maste 
1570127ef0fSEd Maste   // Now make sure that one of the module specifications matches what we just
158435933ddSDimitry Andric   // extract. We might have a module specification that specifies a file
1594ba319b5SDimitry Andric   // "/usr/lib/dyld" with UUID XXX, but we might have a local version of
1604ba319b5SDimitry Andric   // "/usr/lib/dyld" that has
1610127ef0fSEd Maste   // UUID YYY and we don't want those to match. If they don't match, just don't
1620127ef0fSEd Maste   // fill any ivars in so we don't accidentally grab the wrong file later since
1630127ef0fSEd Maste   // they don't match...
1640127ef0fSEd Maste   ModuleSpec matching_module_spec;
165*b5893f02SDimitry Andric   if (!modules_specs.FindMatchingModuleSpec(module_spec,
166*b5893f02SDimitry Andric                                             matching_module_spec)) {
167*b5893f02SDimitry Andric     if (log) {
168*b5893f02SDimitry Andric       log->Printf("Found local object file but the specs didn't match");
169*b5893f02SDimitry Andric     }
1700127ef0fSEd Maste     return;
171*b5893f02SDimitry Andric   }
1720127ef0fSEd Maste 
1730127ef0fSEd Maste   if (module_spec.GetFileSpec())
174*b5893f02SDimitry Andric     m_mod_time = FileSystem::Instance().GetModificationTime(module_spec.GetFileSpec());
1750127ef0fSEd Maste   else if (matching_module_spec.GetFileSpec())
176435933ddSDimitry Andric     m_mod_time =
177*b5893f02SDimitry Andric         FileSystem::Instance().GetModificationTime(matching_module_spec.GetFileSpec());
1780127ef0fSEd Maste 
1794ba319b5SDimitry Andric   // Copy the architecture from the actual spec if we got one back, else use
1804ba319b5SDimitry Andric   // the one that was specified
1810127ef0fSEd Maste   if (matching_module_spec.GetArchitecture().IsValid())
1820127ef0fSEd Maste     m_arch = matching_module_spec.GetArchitecture();
1830127ef0fSEd Maste   else if (module_spec.GetArchitecture().IsValid())
1840127ef0fSEd Maste     m_arch = module_spec.GetArchitecture();
1850127ef0fSEd Maste 
1860127ef0fSEd Maste   // Copy the file spec over and use the specified one (if there was one) so we
187435933ddSDimitry Andric   // don't use a path that might have gotten resolved a path in
188435933ddSDimitry Andric   // 'matching_module_spec'
1890127ef0fSEd Maste   if (module_spec.GetFileSpec())
1900127ef0fSEd Maste     m_file = module_spec.GetFileSpec();
1910127ef0fSEd Maste   else if (matching_module_spec.GetFileSpec())
1920127ef0fSEd Maste     m_file = matching_module_spec.GetFileSpec();
1930127ef0fSEd Maste 
1940127ef0fSEd Maste   // Copy the platform file spec over
1950127ef0fSEd Maste   if (module_spec.GetPlatformFileSpec())
1960127ef0fSEd Maste     m_platform_file = module_spec.GetPlatformFileSpec();
1970127ef0fSEd Maste   else if (matching_module_spec.GetPlatformFileSpec())
1980127ef0fSEd Maste     m_platform_file = matching_module_spec.GetPlatformFileSpec();
1990127ef0fSEd Maste 
2000127ef0fSEd Maste   // Copy the symbol file spec over
2010127ef0fSEd Maste   if (module_spec.GetSymbolFileSpec())
2020127ef0fSEd Maste     m_symfile_spec = module_spec.GetSymbolFileSpec();
2030127ef0fSEd Maste   else if (matching_module_spec.GetSymbolFileSpec())
2040127ef0fSEd Maste     m_symfile_spec = matching_module_spec.GetSymbolFileSpec();
2050127ef0fSEd Maste 
2060127ef0fSEd Maste   // Copy the object name over
2070127ef0fSEd Maste   if (matching_module_spec.GetObjectName())
2080127ef0fSEd Maste     m_object_name = matching_module_spec.GetObjectName();
2090127ef0fSEd Maste   else
2100127ef0fSEd Maste     m_object_name = module_spec.GetObjectName();
2110127ef0fSEd Maste 
2124ba319b5SDimitry Andric   // Always trust the object offset (file offset) and object modification time
2134ba319b5SDimitry Andric   // (for mod time in a BSD static archive) of from the matching module
2144ba319b5SDimitry Andric   // specification
2150127ef0fSEd Maste   m_object_offset = matching_module_spec.GetObjectOffset();
2160127ef0fSEd Maste   m_object_mod_time = matching_module_spec.GetObjectModificationTime();
217ac7ddfbfSEd Maste }
218ac7ddfbfSEd Maste 
Module(const FileSpec & file_spec,const ArchSpec & arch,const ConstString * object_name,lldb::offset_t object_offset,const llvm::sys::TimePoint<> & object_mod_time)219435933ddSDimitry Andric Module::Module(const FileSpec &file_spec, const ArchSpec &arch,
220435933ddSDimitry Andric                const ConstString *object_name, lldb::offset_t object_offset,
221435933ddSDimitry Andric                const llvm::sys::TimePoint<> &object_mod_time)
222*b5893f02SDimitry Andric     : m_mod_time(FileSystem::Instance().GetModificationTime(file_spec)), m_arch(arch),
223435933ddSDimitry Andric       m_file(file_spec), m_object_offset(object_offset),
224435933ddSDimitry Andric       m_object_mod_time(object_mod_time), m_file_has_changed(false),
225435933ddSDimitry Andric       m_first_file_changed_log(false) {
226ac7ddfbfSEd Maste   // Scope for locker below...
227ac7ddfbfSEd Maste   {
228435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
229435933ddSDimitry Andric         GetAllocationModuleCollectionMutex());
230ac7ddfbfSEd Maste     GetModuleCollection().push_back(this);
231ac7ddfbfSEd Maste   }
232ac7ddfbfSEd Maste 
233ac7ddfbfSEd Maste   if (object_name)
234ac7ddfbfSEd Maste     m_object_name = *object_name;
235ac7ddfbfSEd Maste 
236435933ddSDimitry Andric   Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_OBJECT |
237435933ddSDimitry Andric                                                   LIBLLDB_LOG_MODULES));
2384bb0738eSEd Maste   if (log != nullptr)
239435933ddSDimitry Andric     log->Printf("%p Module::Module((%s) '%s%s%s%s')", static_cast<void *>(this),
240435933ddSDimitry Andric                 m_arch.GetArchitectureName(), m_file.GetPath().c_str(),
241435933ddSDimitry Andric                 m_object_name.IsEmpty() ? "" : "(",
242435933ddSDimitry Andric                 m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""),
243435933ddSDimitry Andric                 m_object_name.IsEmpty() ? "" : ")");
244ac7ddfbfSEd Maste }
245ac7ddfbfSEd Maste 
Module()2464bb0738eSEd Maste Module::Module()
247435933ddSDimitry Andric     : m_object_offset(0), m_file_has_changed(false),
248435933ddSDimitry Andric       m_first_file_changed_log(false) {
249435933ddSDimitry Andric   std::lock_guard<std::recursive_mutex> guard(
250435933ddSDimitry Andric       GetAllocationModuleCollectionMutex());
2510127ef0fSEd Maste   GetModuleCollection().push_back(this);
2520127ef0fSEd Maste }
2530127ef0fSEd Maste 
~Module()254435933ddSDimitry Andric Module::~Module() {
2554ba319b5SDimitry Andric   // Lock our module down while we tear everything down to make sure we don't
2564ba319b5SDimitry Andric   // get any access to the module while it is being destroyed
2574bb0738eSEd Maste   std::lock_guard<std::recursive_mutex> guard(m_mutex);
258ac7ddfbfSEd Maste   // Scope for locker below...
259ac7ddfbfSEd Maste   {
260435933ddSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
261435933ddSDimitry Andric         GetAllocationModuleCollectionMutex());
262ac7ddfbfSEd Maste     ModuleCollection &modules = GetModuleCollection();
263ac7ddfbfSEd Maste     ModuleCollection::iterator end = modules.end();
264ac7ddfbfSEd Maste     ModuleCollection::iterator pos = std::find(modules.begin(), end, this);
265ac7ddfbfSEd Maste     assert(pos != end);
266ac7ddfbfSEd Maste     modules.erase(pos);
267ac7ddfbfSEd Maste   }
268435933ddSDimitry Andric   Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_OBJECT |
269435933ddSDimitry Andric                                                   LIBLLDB_LOG_MODULES));
2704bb0738eSEd Maste   if (log != nullptr)
271ac7ddfbfSEd Maste     log->Printf("%p Module::~Module((%s) '%s%s%s%s')",
272435933ddSDimitry Andric                 static_cast<void *>(this), m_arch.GetArchitectureName(),
273435933ddSDimitry Andric                 m_file.GetPath().c_str(), m_object_name.IsEmpty() ? "" : "(",
274ac7ddfbfSEd Maste                 m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""),
275ac7ddfbfSEd Maste                 m_object_name.IsEmpty() ? "" : ")");
276ac7ddfbfSEd Maste   // Release any auto pointers before we start tearing down our member
277ac7ddfbfSEd Maste   // variables since the object file and symbol files might need to make
278ac7ddfbfSEd Maste   // function calls back into this module object. The ordering is important
279ac7ddfbfSEd Maste   // here because symbol files can require the module object file. So we tear
280ac7ddfbfSEd Maste   // down the symbol file first, then the object file.
281ac7ddfbfSEd Maste   m_sections_ap.reset();
282ac7ddfbfSEd Maste   m_symfile_ap.reset();
283ac7ddfbfSEd Maste   m_objfile_sp.reset();
284ac7ddfbfSEd Maste }
285ac7ddfbfSEd Maste 
GetMemoryObjectFile(const lldb::ProcessSP & process_sp,lldb::addr_t header_addr,Status & error,size_t size_to_read)286435933ddSDimitry Andric ObjectFile *Module::GetMemoryObjectFile(const lldb::ProcessSP &process_sp,
2875517e702SDimitry Andric                                         lldb::addr_t header_addr, Status &error,
288435933ddSDimitry Andric                                         size_t size_to_read) {
289435933ddSDimitry Andric   if (m_objfile_sp) {
290ac7ddfbfSEd Maste     error.SetErrorString("object file already exists");
291435933ddSDimitry Andric   } else {
2924bb0738eSEd Maste     std::lock_guard<std::recursive_mutex> guard(m_mutex);
293435933ddSDimitry Andric     if (process_sp) {
294ac7ddfbfSEd Maste       m_did_load_objfile = true;
295f678e45dSDimitry Andric       auto data_ap = llvm::make_unique<DataBufferHeap>(size_to_read, 0);
2965517e702SDimitry Andric       Status readmem_error;
297435933ddSDimitry Andric       const size_t bytes_read =
298435933ddSDimitry Andric           process_sp->ReadMemory(header_addr, data_ap->GetBytes(),
299435933ddSDimitry Andric                                  data_ap->GetByteSize(), readmem_error);
300435933ddSDimitry Andric       if (bytes_read == size_to_read) {
301ac7ddfbfSEd Maste         DataBufferSP data_sp(data_ap.release());
302435933ddSDimitry Andric         m_objfile_sp = ObjectFile::FindPlugin(shared_from_this(), process_sp,
303435933ddSDimitry Andric                                               header_addr, data_sp);
304435933ddSDimitry Andric         if (m_objfile_sp) {
305ac7ddfbfSEd Maste           StreamString s;
306ac7ddfbfSEd Maste           s.Printf("0x%16.16" PRIx64, header_addr);
307435933ddSDimitry Andric           m_object_name.SetString(s.GetString());
308ac7ddfbfSEd Maste 
309435933ddSDimitry Andric           // Once we get the object file, update our module with the object
3104ba319b5SDimitry Andric           // file's architecture since it might differ in vendor/os if some
3114ba319b5SDimitry Andric           // parts were unknown.
312*b5893f02SDimitry Andric           m_arch = m_objfile_sp->GetArchitecture();
313435933ddSDimitry Andric         } else {
314ac7ddfbfSEd Maste           error.SetErrorString("unable to find suitable object file plug-in");
315ac7ddfbfSEd Maste         }
316435933ddSDimitry Andric       } else {
317435933ddSDimitry Andric         error.SetErrorStringWithFormat("unable to read header from memory: %s",
318435933ddSDimitry Andric                                        readmem_error.AsCString());
319ac7ddfbfSEd Maste       }
320435933ddSDimitry Andric     } else {
321ac7ddfbfSEd Maste       error.SetErrorString("invalid process");
322ac7ddfbfSEd Maste     }
323ac7ddfbfSEd Maste   }
324ac7ddfbfSEd Maste   return m_objfile_sp.get();
325ac7ddfbfSEd Maste }
326ac7ddfbfSEd Maste 
GetUUID()327435933ddSDimitry Andric const lldb_private::UUID &Module::GetUUID() {
3284ba319b5SDimitry Andric   if (!m_did_set_uuid.load()) {
3294bb0738eSEd Maste     std::lock_guard<std::recursive_mutex> guard(m_mutex);
3304ba319b5SDimitry Andric     if (!m_did_set_uuid.load()) {
331ac7ddfbfSEd Maste       ObjectFile *obj_file = GetObjectFile();
332ac7ddfbfSEd Maste 
333435933ddSDimitry Andric       if (obj_file != nullptr) {
334ac7ddfbfSEd Maste         obj_file->GetUUID(&m_uuid);
3354ba319b5SDimitry Andric         m_did_set_uuid = true;
336ac7ddfbfSEd Maste       }
337ac7ddfbfSEd Maste     }
3389f2f44ceSEd Maste   }
339ac7ddfbfSEd Maste   return m_uuid;
340ac7ddfbfSEd Maste }
341ac7ddfbfSEd Maste 
SetUUID(const lldb_private::UUID & uuid)3424ba319b5SDimitry Andric void Module::SetUUID(const lldb_private::UUID &uuid) {
3434ba319b5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(m_mutex);
3444ba319b5SDimitry Andric   if (!m_did_set_uuid) {
3454ba319b5SDimitry Andric     m_uuid = uuid;
3464ba319b5SDimitry Andric     m_did_set_uuid = true;
3474ba319b5SDimitry Andric   } else {
3484ba319b5SDimitry Andric     lldbassert(0 && "Attempting to overwrite the existing module UUID");
3494ba319b5SDimitry Andric   }
3504ba319b5SDimitry Andric }
3514ba319b5SDimitry Andric 
GetTypeSystemForLanguage(LanguageType language)352435933ddSDimitry Andric TypeSystem *Module::GetTypeSystemForLanguage(LanguageType language) {
3539f2f44ceSEd Maste   return m_type_system_map.GetTypeSystemForLanguage(language, this, true);
354ac7ddfbfSEd Maste }
355ac7ddfbfSEd Maste 
ParseAllDebugSymbols()356435933ddSDimitry Andric void Module::ParseAllDebugSymbols() {
3574bb0738eSEd Maste   std::lock_guard<std::recursive_mutex> guard(m_mutex);
358ac7ddfbfSEd Maste   size_t num_comp_units = GetNumCompileUnits();
359ac7ddfbfSEd Maste   if (num_comp_units == 0)
360ac7ddfbfSEd Maste     return;
361ac7ddfbfSEd Maste 
362ac7ddfbfSEd Maste   SymbolContext sc;
363ac7ddfbfSEd Maste   sc.module_sp = shared_from_this();
364ac7ddfbfSEd Maste   SymbolVendor *symbols = GetSymbolVendor();
365ac7ddfbfSEd Maste 
366435933ddSDimitry Andric   for (size_t cu_idx = 0; cu_idx < num_comp_units; cu_idx++) {
367ac7ddfbfSEd Maste     sc.comp_unit = symbols->GetCompileUnitAtIndex(cu_idx).get();
368*b5893f02SDimitry Andric     if (!sc.comp_unit)
369*b5893f02SDimitry Andric       continue;
370*b5893f02SDimitry Andric 
371ac7ddfbfSEd Maste     symbols->ParseVariablesForContext(sc);
372ac7ddfbfSEd Maste 
373*b5893f02SDimitry Andric     symbols->ParseFunctions(*sc.comp_unit);
374ac7ddfbfSEd Maste 
375*b5893f02SDimitry Andric     sc.comp_unit->ForeachFunction([&sc, &symbols](const FunctionSP &f) {
376*b5893f02SDimitry Andric       symbols->ParseBlocksRecursive(*f);
377ac7ddfbfSEd Maste 
378ac7ddfbfSEd Maste       // Parse the variables for this function and all its blocks
379*b5893f02SDimitry Andric       sc.function = f.get();
380ac7ddfbfSEd Maste       symbols->ParseVariablesForContext(sc);
381*b5893f02SDimitry Andric       return false;
382*b5893f02SDimitry Andric     });
383ac7ddfbfSEd Maste 
384ac7ddfbfSEd Maste     // Parse all types for this compile unit
385*b5893f02SDimitry Andric     symbols->ParseTypes(*sc.comp_unit);
386ac7ddfbfSEd Maste   }
387ac7ddfbfSEd Maste }
388ac7ddfbfSEd Maste 
CalculateSymbolContext(SymbolContext * sc)389435933ddSDimitry Andric void Module::CalculateSymbolContext(SymbolContext *sc) {
390ac7ddfbfSEd Maste   sc->module_sp = shared_from_this();
391ac7ddfbfSEd Maste }
392ac7ddfbfSEd Maste 
CalculateSymbolContextModule()393435933ddSDimitry Andric ModuleSP Module::CalculateSymbolContextModule() { return shared_from_this(); }
394ac7ddfbfSEd Maste 
DumpSymbolContext(Stream * s)395435933ddSDimitry Andric void Module::DumpSymbolContext(Stream *s) {
3960127ef0fSEd Maste   s->Printf(", Module{%p}", static_cast<void *>(this));
397ac7ddfbfSEd Maste }
398ac7ddfbfSEd Maste 
GetNumCompileUnits()399435933ddSDimitry Andric size_t Module::GetNumCompileUnits() {
4004bb0738eSEd Maste   std::lock_guard<std::recursive_mutex> guard(m_mutex);
4015517e702SDimitry Andric   static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
4025517e702SDimitry Andric   Timer scoped_timer(func_cat, "Module::GetNumCompileUnits (module = %p)",
4030127ef0fSEd Maste                      static_cast<void *>(this));
404ac7ddfbfSEd Maste   SymbolVendor *symbols = GetSymbolVendor();
405ac7ddfbfSEd Maste   if (symbols)
406ac7ddfbfSEd Maste     return symbols->GetNumCompileUnits();
407ac7ddfbfSEd Maste   return 0;
408ac7ddfbfSEd Maste }
409ac7ddfbfSEd Maste 
GetCompileUnitAtIndex(size_t index)410435933ddSDimitry Andric CompUnitSP Module::GetCompileUnitAtIndex(size_t index) {
4114bb0738eSEd Maste   std::lock_guard<std::recursive_mutex> guard(m_mutex);
412ac7ddfbfSEd Maste   size_t num_comp_units = GetNumCompileUnits();
413ac7ddfbfSEd Maste   CompUnitSP cu_sp;
414ac7ddfbfSEd Maste 
415435933ddSDimitry Andric   if (index < num_comp_units) {
416ac7ddfbfSEd Maste     SymbolVendor *symbols = GetSymbolVendor();
417ac7ddfbfSEd Maste     if (symbols)
418ac7ddfbfSEd Maste       cu_sp = symbols->GetCompileUnitAtIndex(index);
419ac7ddfbfSEd Maste   }
420ac7ddfbfSEd Maste   return cu_sp;
421ac7ddfbfSEd Maste }
422ac7ddfbfSEd Maste 
ResolveFileAddress(lldb::addr_t vm_addr,Address & so_addr)423435933ddSDimitry Andric bool Module::ResolveFileAddress(lldb::addr_t vm_addr, Address &so_addr) {
4244bb0738eSEd Maste   std::lock_guard<std::recursive_mutex> guard(m_mutex);
4255517e702SDimitry Andric   static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
4265517e702SDimitry Andric   Timer scoped_timer(func_cat,
427435933ddSDimitry Andric                      "Module::ResolveFileAddress (vm_addr = 0x%" PRIx64 ")",
428435933ddSDimitry Andric                      vm_addr);
429ac7ddfbfSEd Maste   SectionList *section_list = GetSectionList();
430ac7ddfbfSEd Maste   if (section_list)
431ac7ddfbfSEd Maste     return so_addr.ResolveAddressUsingFileSections(vm_addr, section_list);
432ac7ddfbfSEd Maste   return false;
433ac7ddfbfSEd Maste }
434ac7ddfbfSEd Maste 
ResolveSymbolContextForAddress(const Address & so_addr,lldb::SymbolContextItem resolve_scope,SymbolContext & sc,bool resolve_tail_call_address)435435933ddSDimitry Andric uint32_t Module::ResolveSymbolContextForAddress(
436*b5893f02SDimitry Andric     const Address &so_addr, lldb::SymbolContextItem resolve_scope,
437*b5893f02SDimitry Andric     SymbolContext &sc, bool resolve_tail_call_address) {
4384bb0738eSEd Maste   std::lock_guard<std::recursive_mutex> guard(m_mutex);
439ac7ddfbfSEd Maste   uint32_t resolved_flags = 0;
440ac7ddfbfSEd Maste 
441435933ddSDimitry Andric   // Clear the result symbol context in case we don't find anything, but don't
442435933ddSDimitry Andric   // clear the target
443ac7ddfbfSEd Maste   sc.Clear(false);
444ac7ddfbfSEd Maste 
445ac7ddfbfSEd Maste   // Get the section from the section/offset address.
446ac7ddfbfSEd Maste   SectionSP section_sp(so_addr.GetSection());
447ac7ddfbfSEd Maste 
448ac7ddfbfSEd Maste   // Make sure the section matches this module before we try and match anything
449435933ddSDimitry Andric   if (section_sp && section_sp->GetModule().get() == this) {
4504ba319b5SDimitry Andric     // If the section offset based address resolved itself, then this is the
4514ba319b5SDimitry Andric     // right module.
452ac7ddfbfSEd Maste     sc.module_sp = shared_from_this();
453ac7ddfbfSEd Maste     resolved_flags |= eSymbolContextModule;
454ac7ddfbfSEd Maste 
45535617911SEd Maste     SymbolVendor *sym_vendor = GetSymbolVendor();
45635617911SEd Maste     if (!sym_vendor)
45735617911SEd Maste       return resolved_flags;
45835617911SEd Maste 
4594ba319b5SDimitry Andric     // Resolve the compile unit, function, block, line table or line entry if
4604ba319b5SDimitry Andric     // requested.
461ac7ddfbfSEd Maste     if (resolve_scope & eSymbolContextCompUnit ||
462ac7ddfbfSEd Maste         resolve_scope & eSymbolContextFunction ||
463ac7ddfbfSEd Maste         resolve_scope & eSymbolContextBlock ||
4644bb0738eSEd Maste         resolve_scope & eSymbolContextLineEntry ||
465435933ddSDimitry Andric         resolve_scope & eSymbolContextVariable) {
466435933ddSDimitry Andric       resolved_flags |=
467435933ddSDimitry Andric           sym_vendor->ResolveSymbolContext(so_addr, resolve_scope, sc);
468ac7ddfbfSEd Maste     }
469ac7ddfbfSEd Maste 
4704ba319b5SDimitry Andric     // Resolve the symbol if requested, but don't re-look it up if we've
4714ba319b5SDimitry Andric     // already found it.
472435933ddSDimitry Andric     if (resolve_scope & eSymbolContextSymbol &&
473435933ddSDimitry Andric         !(resolved_flags & eSymbolContextSymbol)) {
474ac7ddfbfSEd Maste       Symtab *symtab = sym_vendor->GetSymtab();
475435933ddSDimitry Andric       if (symtab && so_addr.IsSectionOffset()) {
476a8bcc4d8SDimitry Andric         Symbol *matching_symbol = nullptr;
477a8bcc4d8SDimitry Andric 
478435933ddSDimitry Andric         symtab->ForEachSymbolContainingFileAddress(
479435933ddSDimitry Andric             so_addr.GetFileAddress(),
480a8bcc4d8SDimitry Andric             [&matching_symbol](Symbol *symbol) -> bool {
481435933ddSDimitry Andric               if (symbol->GetType() != eSymbolTypeInvalid) {
482a8bcc4d8SDimitry Andric                 matching_symbol = symbol;
483a8bcc4d8SDimitry Andric                 return false; // Stop iterating
484a8bcc4d8SDimitry Andric               }
485a8bcc4d8SDimitry Andric               return true; // Keep iterating
486a8bcc4d8SDimitry Andric             });
487a8bcc4d8SDimitry Andric         sc.symbol = matching_symbol;
488435933ddSDimitry Andric         if (!sc.symbol && resolve_scope & eSymbolContextFunction &&
489435933ddSDimitry Andric             !(resolved_flags & eSymbolContextFunction)) {
490435933ddSDimitry Andric           bool verify_unique = false; // No need to check again since
491435933ddSDimitry Andric                                       // ResolveSymbolContext failed to find a
492435933ddSDimitry Andric                                       // symbol at this address.
49335617911SEd Maste           if (ObjectFile *obj_file = sc.module_sp->GetObjectFile())
494435933ddSDimitry Andric             sc.symbol =
495435933ddSDimitry Andric                 obj_file->ResolveSymbolForAddress(so_addr, verify_unique);
49635617911SEd Maste         }
49735617911SEd Maste 
498435933ddSDimitry Andric         if (sc.symbol) {
499435933ddSDimitry Andric           if (sc.symbol->IsSynthetic()) {
5004ba319b5SDimitry Andric             // We have a synthetic symbol so lets check if the object file from
5014ba319b5SDimitry Andric             // the symbol file in the symbol vendor is different than the
5024ba319b5SDimitry Andric             // object file for the module, and if so search its symbol table to
5034ba319b5SDimitry Andric             // see if we can come up with a better symbol. For example dSYM
5044ba319b5SDimitry Andric             // files on MacOSX have an unstripped symbol table inside of them.
50535617911SEd Maste             ObjectFile *symtab_objfile = symtab->GetObjectFile();
506435933ddSDimitry Andric             if (symtab_objfile && symtab_objfile->IsStripped()) {
50735617911SEd Maste               SymbolFile *symfile = sym_vendor->GetSymbolFile();
508435933ddSDimitry Andric               if (symfile) {
50935617911SEd Maste                 ObjectFile *symfile_objfile = symfile->GetObjectFile();
510435933ddSDimitry Andric                 if (symfile_objfile != symtab_objfile) {
51135617911SEd Maste                   Symtab *symfile_symtab = symfile_objfile->GetSymtab();
512435933ddSDimitry Andric                   if (symfile_symtab) {
513435933ddSDimitry Andric                     Symbol *symbol =
514435933ddSDimitry Andric                         symfile_symtab->FindSymbolContainingFileAddress(
515435933ddSDimitry Andric                             so_addr.GetFileAddress());
516435933ddSDimitry Andric                     if (symbol && !symbol->IsSynthetic()) {
51735617911SEd Maste                       sc.symbol = symbol;
51835617911SEd Maste                     }
51935617911SEd Maste                   }
52035617911SEd Maste                 }
52135617911SEd Maste               }
52235617911SEd Maste             }
52335617911SEd Maste           }
524ac7ddfbfSEd Maste           resolved_flags |= eSymbolContextSymbol;
525ac7ddfbfSEd Maste         }
526ac7ddfbfSEd Maste       }
527ac7ddfbfSEd Maste     }
52835617911SEd Maste 
529435933ddSDimitry Andric     // For function symbols, so_addr may be off by one.  This is a convention
5304ba319b5SDimitry Andric     // consistent with FDE row indices in eh_frame sections, but requires extra
5314ba319b5SDimitry Andric     // logic here to permit symbol lookup for disassembly and unwind.
532435933ddSDimitry Andric     if (resolve_scope & eSymbolContextSymbol &&
533435933ddSDimitry Andric         !(resolved_flags & eSymbolContextSymbol) && resolve_tail_call_address &&
534435933ddSDimitry Andric         so_addr.IsSectionOffset()) {
53535617911SEd Maste       Address previous_addr = so_addr;
53635617911SEd Maste       previous_addr.Slide(-1);
53735617911SEd Maste 
53835617911SEd Maste       bool do_resolve_tail_call_address = false; // prevent recursion
539435933ddSDimitry Andric       const uint32_t flags = ResolveSymbolContextForAddress(
540435933ddSDimitry Andric           previous_addr, resolve_scope, sc, do_resolve_tail_call_address);
541435933ddSDimitry Andric       if (flags & eSymbolContextSymbol) {
54235617911SEd Maste         AddressRange addr_range;
543435933ddSDimitry Andric         if (sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,
544435933ddSDimitry Andric                                false, addr_range)) {
545435933ddSDimitry Andric           if (addr_range.GetBaseAddress().GetSection() ==
546435933ddSDimitry Andric               so_addr.GetSection()) {
547435933ddSDimitry Andric             // If the requested address is one past the address range of a
5484ba319b5SDimitry Andric             // function (i.e. a tail call), or the decremented address is the
5494ba319b5SDimitry Andric             // start of a function (i.e. some forms of trampoline), indicate
5504ba319b5SDimitry Andric             // that the symbol has been resolved.
551435933ddSDimitry Andric             if (so_addr.GetOffset() ==
552435933ddSDimitry Andric                     addr_range.GetBaseAddress().GetOffset() ||
553435933ddSDimitry Andric                 so_addr.GetOffset() ==
554435933ddSDimitry Andric                     addr_range.GetBaseAddress().GetOffset() +
555435933ddSDimitry Andric                         addr_range.GetByteSize()) {
55635617911SEd Maste               resolved_flags |= flags;
55735617911SEd Maste             }
558435933ddSDimitry Andric           } else {
559435933ddSDimitry Andric             sc.symbol =
560435933ddSDimitry Andric                 nullptr; // Don't trust the symbol if the sections didn't match.
56135617911SEd Maste           }
56235617911SEd Maste         }
56335617911SEd Maste       }
564ac7ddfbfSEd Maste     }
565ac7ddfbfSEd Maste   }
566ac7ddfbfSEd Maste   return resolved_flags;
567ac7ddfbfSEd Maste }
568ac7ddfbfSEd Maste 
ResolveSymbolContextForFilePath(const char * file_path,uint32_t line,bool check_inlines,lldb::SymbolContextItem resolve_scope,SymbolContextList & sc_list)569*b5893f02SDimitry Andric uint32_t Module::ResolveSymbolContextForFilePath(
570*b5893f02SDimitry Andric     const char *file_path, uint32_t line, bool check_inlines,
571*b5893f02SDimitry Andric     lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
572*b5893f02SDimitry Andric   FileSpec file_spec(file_path);
573435933ddSDimitry Andric   return ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
574435933ddSDimitry Andric                                           resolve_scope, sc_list);
575ac7ddfbfSEd Maste }
576ac7ddfbfSEd Maste 
ResolveSymbolContextsForFileSpec(const FileSpec & file_spec,uint32_t line,bool check_inlines,lldb::SymbolContextItem resolve_scope,SymbolContextList & sc_list)577*b5893f02SDimitry Andric uint32_t Module::ResolveSymbolContextsForFileSpec(
578*b5893f02SDimitry Andric     const FileSpec &file_spec, uint32_t line, bool check_inlines,
579*b5893f02SDimitry Andric     lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
5804bb0738eSEd Maste   std::lock_guard<std::recursive_mutex> guard(m_mutex);
5815517e702SDimitry Andric   static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
5825517e702SDimitry Andric   Timer scoped_timer(func_cat,
583435933ddSDimitry Andric                      "Module::ResolveSymbolContextForFilePath (%s:%u, "
584435933ddSDimitry Andric                      "check_inlines = %s, resolve_scope = 0x%8.8x)",
585435933ddSDimitry Andric                      file_spec.GetPath().c_str(), line,
586435933ddSDimitry Andric                      check_inlines ? "yes" : "no", resolve_scope);
587ac7ddfbfSEd Maste 
588ac7ddfbfSEd Maste   const uint32_t initial_count = sc_list.GetSize();
589ac7ddfbfSEd Maste 
590ac7ddfbfSEd Maste   SymbolVendor *symbols = GetSymbolVendor();
591ac7ddfbfSEd Maste   if (symbols)
592435933ddSDimitry Andric     symbols->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope,
593435933ddSDimitry Andric                                   sc_list);
594ac7ddfbfSEd Maste 
595ac7ddfbfSEd Maste   return sc_list.GetSize() - initial_count;
596ac7ddfbfSEd Maste }
597ac7ddfbfSEd Maste 
FindGlobalVariables(const ConstString & name,const CompilerDeclContext * parent_decl_ctx,size_t max_matches,VariableList & variables)598435933ddSDimitry Andric size_t Module::FindGlobalVariables(const ConstString &name,
5999f2f44ceSEd Maste                                    const CompilerDeclContext *parent_decl_ctx,
600ac7ddfbfSEd Maste                                    size_t max_matches,
601435933ddSDimitry Andric                                    VariableList &variables) {
602ac7ddfbfSEd Maste   SymbolVendor *symbols = GetSymbolVendor();
603ac7ddfbfSEd Maste   if (symbols)
6044ba319b5SDimitry Andric     return symbols->FindGlobalVariables(name, parent_decl_ctx, max_matches,
6054ba319b5SDimitry Andric                                         variables);
6064ba319b5SDimitry Andric   return 0;
6074ba319b5SDimitry Andric }
6084ba319b5SDimitry Andric 
FindGlobalVariables(const RegularExpression & regex,size_t max_matches,VariableList & variables)6094ba319b5SDimitry Andric size_t Module::FindGlobalVariables(const RegularExpression &regex,
6104ba319b5SDimitry Andric                                    size_t max_matches,
6114ba319b5SDimitry Andric                                    VariableList &variables) {
6124ba319b5SDimitry Andric   SymbolVendor *symbols = GetSymbolVendor();
6134ba319b5SDimitry Andric   if (symbols)
6144ba319b5SDimitry Andric     return symbols->FindGlobalVariables(regex, max_matches, variables);
615ac7ddfbfSEd Maste   return 0;
616ac7ddfbfSEd Maste }
617ac7ddfbfSEd Maste 
FindCompileUnits(const FileSpec & path,bool append,SymbolContextList & sc_list)618435933ddSDimitry Andric size_t Module::FindCompileUnits(const FileSpec &path, bool append,
619435933ddSDimitry Andric                                 SymbolContextList &sc_list) {
620ac7ddfbfSEd Maste   if (!append)
621ac7ddfbfSEd Maste     sc_list.Clear();
622ac7ddfbfSEd Maste 
623ac7ddfbfSEd Maste   const size_t start_size = sc_list.GetSize();
624ac7ddfbfSEd Maste   const size_t num_compile_units = GetNumCompileUnits();
625ac7ddfbfSEd Maste   SymbolContext sc;
626ac7ddfbfSEd Maste   sc.module_sp = shared_from_this();
62735617911SEd Maste   const bool compare_directory = (bool)path.GetDirectory();
628435933ddSDimitry Andric   for (size_t i = 0; i < num_compile_units; ++i) {
629ac7ddfbfSEd Maste     sc.comp_unit = GetCompileUnitAtIndex(i).get();
630435933ddSDimitry Andric     if (sc.comp_unit) {
631ac7ddfbfSEd Maste       if (FileSpec::Equal(*sc.comp_unit, path, compare_directory))
632ac7ddfbfSEd Maste         sc_list.Append(sc);
633ac7ddfbfSEd Maste     }
634ac7ddfbfSEd Maste   }
635ac7ddfbfSEd Maste   return sc_list.GetSize() - start_size;
636ac7ddfbfSEd Maste }
637ac7ddfbfSEd Maste 
LookupInfo(const ConstString & name,FunctionNameType name_type_mask,LanguageType language)638*b5893f02SDimitry Andric Module::LookupInfo::LookupInfo(const ConstString &name,
639*b5893f02SDimitry Andric                                FunctionNameType name_type_mask,
640*b5893f02SDimitry Andric                                LanguageType language)
641*b5893f02SDimitry Andric     : m_name(name), m_lookup_name(), m_language(language),
642*b5893f02SDimitry Andric       m_name_type_mask(eFunctionNameTypeNone),
643435933ddSDimitry Andric       m_match_name_after_lookup(false) {
6444bb0738eSEd Maste   const char *name_cstr = name.GetCString();
6454bb0738eSEd Maste   llvm::StringRef basename;
6464bb0738eSEd Maste   llvm::StringRef context;
6474bb0738eSEd Maste 
648435933ddSDimitry Andric   if (name_type_mask & eFunctionNameTypeAuto) {
6494bb0738eSEd Maste     if (CPlusPlusLanguage::IsCPPMangledName(name_cstr))
6504bb0738eSEd Maste       m_name_type_mask = eFunctionNameTypeFull;
6514bb0738eSEd Maste     else if ((language == eLanguageTypeUnknown ||
6524bb0738eSEd Maste               Language::LanguageIsObjC(language)) &&
6534bb0738eSEd Maste              ObjCLanguage::IsPossibleObjCMethodName(name_cstr))
6544bb0738eSEd Maste       m_name_type_mask = eFunctionNameTypeFull;
655435933ddSDimitry Andric     else if (Language::LanguageIsC(language)) {
6564bb0738eSEd Maste       m_name_type_mask = eFunctionNameTypeFull;
657435933ddSDimitry Andric     } else {
6584bb0738eSEd Maste       if ((language == eLanguageTypeUnknown ||
6594bb0738eSEd Maste            Language::LanguageIsObjC(language)) &&
6604bb0738eSEd Maste           ObjCLanguage::IsPossibleObjCSelector(name_cstr))
6614bb0738eSEd Maste         m_name_type_mask |= eFunctionNameTypeSelector;
6624bb0738eSEd Maste 
6634bb0738eSEd Maste       CPlusPlusLanguage::MethodName cpp_method(name);
6644bb0738eSEd Maste       basename = cpp_method.GetBasename();
665435933ddSDimitry Andric       if (basename.empty()) {
666435933ddSDimitry Andric         if (CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,
667435933ddSDimitry Andric                                                            basename))
6684bb0738eSEd Maste           m_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);
6694bb0738eSEd Maste         else
6704bb0738eSEd Maste           m_name_type_mask |= eFunctionNameTypeFull;
671435933ddSDimitry Andric       } else {
6724bb0738eSEd Maste         m_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);
6734bb0738eSEd Maste       }
6744bb0738eSEd Maste     }
675435933ddSDimitry Andric   } else {
6764bb0738eSEd Maste     m_name_type_mask = name_type_mask;
677435933ddSDimitry Andric     if (name_type_mask & eFunctionNameTypeMethod ||
678435933ddSDimitry Andric         name_type_mask & eFunctionNameTypeBase) {
679435933ddSDimitry Andric       // If they've asked for a CPP method or function name and it can't be
6804ba319b5SDimitry Andric       // that, we don't even need to search for CPP methods or names.
6814bb0738eSEd Maste       CPlusPlusLanguage::MethodName cpp_method(name);
682435933ddSDimitry Andric       if (cpp_method.IsValid()) {
6834bb0738eSEd Maste         basename = cpp_method.GetBasename();
6844bb0738eSEd Maste 
685435933ddSDimitry Andric         if (!cpp_method.GetQualifiers().empty()) {
686435933ddSDimitry Andric           // There is a "const" or other qualifier following the end of the
6874ba319b5SDimitry Andric           // function parens, this can't be a eFunctionNameTypeBase
6884bb0738eSEd Maste           m_name_type_mask &= ~(eFunctionNameTypeBase);
6894bb0738eSEd Maste           if (m_name_type_mask == eFunctionNameTypeNone)
6904bb0738eSEd Maste             return;
6914bb0738eSEd Maste         }
692435933ddSDimitry Andric       } else {
693435933ddSDimitry Andric         // If the CPP method parser didn't manage to chop this up, try to fill
6944ba319b5SDimitry Andric         // in the base name if we can. If a::b::c is passed in, we need to just
6954ba319b5SDimitry Andric         // look up "c", and then we'll filter the result later.
696435933ddSDimitry Andric         CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,
697435933ddSDimitry Andric                                                        basename);
6984bb0738eSEd Maste       }
6994bb0738eSEd Maste     }
7004bb0738eSEd Maste 
701435933ddSDimitry Andric     if (name_type_mask & eFunctionNameTypeSelector) {
702435933ddSDimitry Andric       if (!ObjCLanguage::IsPossibleObjCSelector(name_cstr)) {
7034bb0738eSEd Maste         m_name_type_mask &= ~(eFunctionNameTypeSelector);
7044bb0738eSEd Maste         if (m_name_type_mask == eFunctionNameTypeNone)
7054bb0738eSEd Maste           return;
7064bb0738eSEd Maste       }
7074bb0738eSEd Maste     }
7084bb0738eSEd Maste 
709435933ddSDimitry Andric     // Still try and get a basename in case someone specifies a name type mask
710f678e45dSDimitry Andric     // of eFunctionNameTypeFull and a name like "A::func"
711435933ddSDimitry Andric     if (basename.empty()) {
712f678e45dSDimitry Andric       if (name_type_mask & eFunctionNameTypeFull &&
713f678e45dSDimitry Andric           !CPlusPlusLanguage::IsCPPMangledName(name_cstr)) {
7144bb0738eSEd Maste         CPlusPlusLanguage::MethodName cpp_method(name);
7154bb0738eSEd Maste         basename = cpp_method.GetBasename();
7164bb0738eSEd Maste         if (basename.empty())
717435933ddSDimitry Andric           CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,
718435933ddSDimitry Andric                                                          basename);
7194bb0738eSEd Maste       }
7204bb0738eSEd Maste     }
7214bb0738eSEd Maste   }
7224bb0738eSEd Maste 
723435933ddSDimitry Andric   if (!basename.empty()) {
7244ba319b5SDimitry Andric     // The name supplied was a partial C++ path like "a::count". In this case
7254ba319b5SDimitry Andric     // we want to do a lookup on the basename "count" and then make sure any
7264ba319b5SDimitry Andric     // matching results contain "a::count" so that it would match "b::a::count"
7274ba319b5SDimitry Andric     // and "a::count". This is why we set "match_name_after_lookup" to true
7284bb0738eSEd Maste     m_lookup_name.SetString(basename);
7294bb0738eSEd Maste     m_match_name_after_lookup = true;
730435933ddSDimitry Andric   } else {
731435933ddSDimitry Andric     // The name is already correct, just use the exact name as supplied, and we
7324ba319b5SDimitry Andric     // won't need to check if any matches contain "name"
7334bb0738eSEd Maste     m_lookup_name = name;
7344bb0738eSEd Maste     m_match_name_after_lookup = false;
7354bb0738eSEd Maste   }
7364bb0738eSEd Maste }
7374bb0738eSEd Maste 
Prune(SymbolContextList & sc_list,size_t start_idx) const738435933ddSDimitry Andric void Module::LookupInfo::Prune(SymbolContextList &sc_list,
739435933ddSDimitry Andric                                size_t start_idx) const {
740435933ddSDimitry Andric   if (m_match_name_after_lookup && m_name) {
7414bb0738eSEd Maste     SymbolContext sc;
7424bb0738eSEd Maste     size_t i = start_idx;
743435933ddSDimitry Andric     while (i < sc_list.GetSize()) {
7444bb0738eSEd Maste       if (!sc_list.GetContextAtIndex(i, sc))
7454bb0738eSEd Maste         break;
7464bb0738eSEd Maste       ConstString full_name(sc.GetFunctionName());
747435933ddSDimitry Andric       if (full_name &&
748435933ddSDimitry Andric           ::strstr(full_name.GetCString(), m_name.GetCString()) == nullptr) {
7494bb0738eSEd Maste         sc_list.RemoveContextAtIndex(i);
750435933ddSDimitry Andric       } else {
7514bb0738eSEd Maste         ++i;
7524bb0738eSEd Maste       }
7534bb0738eSEd Maste     }
7544bb0738eSEd Maste   }
7554bb0738eSEd Maste 
756435933ddSDimitry Andric   // If we have only full name matches we might have tried to set breakpoint on
757f678e45dSDimitry Andric   // "func" and specified eFunctionNameTypeFull, but we might have found
758f678e45dSDimitry Andric   // "a::func()", "a::b::func()", "c::func()", "func()" and "func". Only
759f678e45dSDimitry Andric   // "func()" and "func" should end up matching.
760435933ddSDimitry Andric   if (m_name_type_mask == eFunctionNameTypeFull) {
7614bb0738eSEd Maste     SymbolContext sc;
7624bb0738eSEd Maste     size_t i = start_idx;
763435933ddSDimitry Andric     while (i < sc_list.GetSize()) {
7644bb0738eSEd Maste       if (!sc_list.GetContextAtIndex(i, sc))
7654bb0738eSEd Maste         break;
7664ba319b5SDimitry Andric       // Make sure the mangled and demangled names don't match before we try to
7674ba319b5SDimitry Andric       // pull anything out
768f678e45dSDimitry Andric       ConstString mangled_name(sc.GetFunctionName(Mangled::ePreferMangled));
7694bb0738eSEd Maste       ConstString full_name(sc.GetFunctionName());
770f678e45dSDimitry Andric       if (mangled_name != m_name && full_name != m_name)
771f678e45dSDimitry Andric       {
7724bb0738eSEd Maste         CPlusPlusLanguage::MethodName cpp_method(full_name);
773435933ddSDimitry Andric         if (cpp_method.IsValid()) {
774435933ddSDimitry Andric           if (cpp_method.GetContext().empty()) {
775435933ddSDimitry Andric             if (cpp_method.GetBasename().compare(m_name.GetStringRef()) != 0) {
7764bb0738eSEd Maste               sc_list.RemoveContextAtIndex(i);
7774bb0738eSEd Maste               continue;
7784bb0738eSEd Maste             }
779435933ddSDimitry Andric           } else {
780f678e45dSDimitry Andric             std::string qualified_name;
781f678e45dSDimitry Andric             llvm::StringRef anon_prefix("(anonymous namespace)");
782f678e45dSDimitry Andric             if (cpp_method.GetContext() == anon_prefix)
783f678e45dSDimitry Andric               qualified_name = cpp_method.GetBasename().str();
784f678e45dSDimitry Andric             else
785f678e45dSDimitry Andric               qualified_name = cpp_method.GetScopeQualifiedName();
786*b5893f02SDimitry Andric             if (qualified_name != m_name.GetCString()) {
7874bb0738eSEd Maste               sc_list.RemoveContextAtIndex(i);
7884bb0738eSEd Maste               continue;
7894bb0738eSEd Maste             }
7904bb0738eSEd Maste           }
7914bb0738eSEd Maste         }
792f678e45dSDimitry Andric       }
7934bb0738eSEd Maste       ++i;
7944bb0738eSEd Maste     }
7954bb0738eSEd Maste   }
7964bb0738eSEd Maste }
7974bb0738eSEd Maste 
FindFunctions(const ConstString & name,const CompilerDeclContext * parent_decl_ctx,FunctionNameType name_type_mask,bool include_symbols,bool include_inlines,bool append,SymbolContextList & sc_list)798435933ddSDimitry Andric size_t Module::FindFunctions(const ConstString &name,
7999f2f44ceSEd Maste                              const CompilerDeclContext *parent_decl_ctx,
800*b5893f02SDimitry Andric                              FunctionNameType name_type_mask,
801*b5893f02SDimitry Andric                              bool include_symbols, bool include_inlines,
802*b5893f02SDimitry Andric                              bool append, SymbolContextList &sc_list) {
803ac7ddfbfSEd Maste   if (!append)
804ac7ddfbfSEd Maste     sc_list.Clear();
805ac7ddfbfSEd Maste 
806ac7ddfbfSEd Maste   const size_t old_size = sc_list.GetSize();
807ac7ddfbfSEd Maste 
808ac7ddfbfSEd Maste   // Find all the functions (not symbols, but debug information functions...
809ac7ddfbfSEd Maste   SymbolVendor *symbols = GetSymbolVendor();
810ac7ddfbfSEd Maste 
811435933ddSDimitry Andric   if (name_type_mask & eFunctionNameTypeAuto) {
8124bb0738eSEd Maste     LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown);
813ac7ddfbfSEd Maste 
814435933ddSDimitry Andric     if (symbols) {
815435933ddSDimitry Andric       symbols->FindFunctions(lookup_info.GetLookupName(), parent_decl_ctx,
816435933ddSDimitry Andric                              lookup_info.GetNameTypeMask(), include_inlines,
817435933ddSDimitry Andric                              append, sc_list);
818ac7ddfbfSEd Maste 
819435933ddSDimitry Andric       // Now check our symbol table for symbols that are code symbols if
820435933ddSDimitry Andric       // requested
821435933ddSDimitry Andric       if (include_symbols) {
822ac7ddfbfSEd Maste         Symtab *symtab = symbols->GetSymtab();
823ac7ddfbfSEd Maste         if (symtab)
824435933ddSDimitry Andric           symtab->FindFunctionSymbols(lookup_info.GetLookupName(),
825435933ddSDimitry Andric                                       lookup_info.GetNameTypeMask(), sc_list);
826ac7ddfbfSEd Maste       }
827ac7ddfbfSEd Maste     }
828ac7ddfbfSEd Maste 
8294bb0738eSEd Maste     const size_t new_size = sc_list.GetSize();
8304bb0738eSEd Maste 
8314bb0738eSEd Maste     if (old_size < new_size)
8324bb0738eSEd Maste       lookup_info.Prune(sc_list, old_size);
833435933ddSDimitry Andric   } else {
834435933ddSDimitry Andric     if (symbols) {
835435933ddSDimitry Andric       symbols->FindFunctions(name, parent_decl_ctx, name_type_mask,
836435933ddSDimitry Andric                              include_inlines, append, sc_list);
837ac7ddfbfSEd Maste 
838435933ddSDimitry Andric       // Now check our symbol table for symbols that are code symbols if
839435933ddSDimitry Andric       // requested
840435933ddSDimitry Andric       if (include_symbols) {
841ac7ddfbfSEd Maste         Symtab *symtab = symbols->GetSymtab();
842ac7ddfbfSEd Maste         if (symtab)
843ac7ddfbfSEd Maste           symtab->FindFunctionSymbols(name, name_type_mask, sc_list);
844ac7ddfbfSEd Maste       }
845ac7ddfbfSEd Maste     }
846ac7ddfbfSEd Maste   }
847ac7ddfbfSEd Maste 
848ac7ddfbfSEd Maste   return sc_list.GetSize() - old_size;
849ac7ddfbfSEd Maste }
850ac7ddfbfSEd Maste 
FindFunctions(const RegularExpression & regex,bool include_symbols,bool include_inlines,bool append,SymbolContextList & sc_list)851435933ddSDimitry Andric size_t Module::FindFunctions(const RegularExpression &regex,
852435933ddSDimitry Andric                              bool include_symbols, bool include_inlines,
853435933ddSDimitry Andric                              bool append, SymbolContextList &sc_list) {
854ac7ddfbfSEd Maste   if (!append)
855ac7ddfbfSEd Maste     sc_list.Clear();
856ac7ddfbfSEd Maste 
857ac7ddfbfSEd Maste   const size_t start_size = sc_list.GetSize();
858ac7ddfbfSEd Maste 
859ac7ddfbfSEd Maste   SymbolVendor *symbols = GetSymbolVendor();
860435933ddSDimitry Andric   if (symbols) {
861ac7ddfbfSEd Maste     symbols->FindFunctions(regex, include_inlines, append, sc_list);
862ac7ddfbfSEd Maste 
8634ba319b5SDimitry Andric     // Now check our symbol table for symbols that are code symbols if
8644ba319b5SDimitry Andric     // requested
865435933ddSDimitry Andric     if (include_symbols) {
866ac7ddfbfSEd Maste       Symtab *symtab = symbols->GetSymtab();
867435933ddSDimitry Andric       if (symtab) {
868ac7ddfbfSEd Maste         std::vector<uint32_t> symbol_indexes;
869435933ddSDimitry Andric         symtab->AppendSymbolIndexesMatchingRegExAndType(
870435933ddSDimitry Andric             regex, eSymbolTypeAny, Symtab::eDebugAny, Symtab::eVisibilityAny,
871435933ddSDimitry Andric             symbol_indexes);
872ac7ddfbfSEd Maste         const size_t num_matches = symbol_indexes.size();
873435933ddSDimitry Andric         if (num_matches) {
874ac7ddfbfSEd Maste           SymbolContext sc(this);
875ac7ddfbfSEd Maste           const size_t end_functions_added_index = sc_list.GetSize();
876435933ddSDimitry Andric           size_t num_functions_added_to_sc_list =
877435933ddSDimitry Andric               end_functions_added_index - start_size;
878435933ddSDimitry Andric           if (num_functions_added_to_sc_list == 0) {
8794ba319b5SDimitry Andric             // No functions were added, just symbols, so we can just append
8804ba319b5SDimitry Andric             // them
881435933ddSDimitry Andric             for (size_t i = 0; i < num_matches; ++i) {
882ac7ddfbfSEd Maste               sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
883ac7ddfbfSEd Maste               SymbolType sym_type = sc.symbol->GetType();
884ac7ddfbfSEd Maste               if (sc.symbol && (sym_type == eSymbolTypeCode ||
885ac7ddfbfSEd Maste                                 sym_type == eSymbolTypeResolver))
886ac7ddfbfSEd Maste                 sc_list.Append(sc);
887ac7ddfbfSEd Maste             }
888435933ddSDimitry Andric           } else {
889ac7ddfbfSEd Maste             typedef std::map<lldb::addr_t, uint32_t> FileAddrToIndexMap;
890ac7ddfbfSEd Maste             FileAddrToIndexMap file_addr_to_index;
891435933ddSDimitry Andric             for (size_t i = start_size; i < end_functions_added_index; ++i) {
892ac7ddfbfSEd Maste               const SymbolContext &sc = sc_list[i];
893ac7ddfbfSEd Maste               if (sc.block)
894ac7ddfbfSEd Maste                 continue;
895435933ddSDimitry Andric               file_addr_to_index[sc.function->GetAddressRange()
896435933ddSDimitry Andric                                      .GetBaseAddress()
897435933ddSDimitry Andric                                      .GetFileAddress()] = i;
898ac7ddfbfSEd Maste             }
899ac7ddfbfSEd Maste 
900ac7ddfbfSEd Maste             FileAddrToIndexMap::const_iterator end = file_addr_to_index.end();
901ac7ddfbfSEd Maste             // Functions were added so we need to merge symbols into any
902ac7ddfbfSEd Maste             // existing function symbol contexts
903435933ddSDimitry Andric             for (size_t i = start_size; i < num_matches; ++i) {
904ac7ddfbfSEd Maste               sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
905ac7ddfbfSEd Maste               SymbolType sym_type = sc.symbol->GetType();
906435933ddSDimitry Andric               if (sc.symbol && sc.symbol->ValueIsAddress() &&
907435933ddSDimitry Andric                   (sym_type == eSymbolTypeCode ||
908435933ddSDimitry Andric                    sym_type == eSymbolTypeResolver)) {
909435933ddSDimitry Andric                 FileAddrToIndexMap::const_iterator pos =
910435933ddSDimitry Andric                     file_addr_to_index.find(
911435933ddSDimitry Andric                         sc.symbol->GetAddressRef().GetFileAddress());
912ac7ddfbfSEd Maste                 if (pos == end)
913ac7ddfbfSEd Maste                   sc_list.Append(sc);
914ac7ddfbfSEd Maste                 else
915ac7ddfbfSEd Maste                   sc_list[pos->second].symbol = sc.symbol;
916ac7ddfbfSEd Maste               }
917ac7ddfbfSEd Maste             }
918ac7ddfbfSEd Maste           }
919ac7ddfbfSEd Maste         }
920ac7ddfbfSEd Maste       }
921ac7ddfbfSEd Maste     }
922ac7ddfbfSEd Maste   }
923ac7ddfbfSEd Maste   return sc_list.GetSize() - start_size;
924ac7ddfbfSEd Maste }
925ac7ddfbfSEd Maste 
FindAddressesForLine(const lldb::TargetSP target_sp,const FileSpec & file,uint32_t line,Function * function,std::vector<Address> & output_local,std::vector<Address> & output_extern)926435933ddSDimitry Andric void Module::FindAddressesForLine(const lldb::TargetSP target_sp,
92735617911SEd Maste                                   const FileSpec &file, uint32_t line,
92835617911SEd Maste                                   Function *function,
929435933ddSDimitry Andric                                   std::vector<Address> &output_local,
930435933ddSDimitry Andric                                   std::vector<Address> &output_extern) {
93135617911SEd Maste   SearchFilterByModule filter(target_sp, m_file);
93235617911SEd Maste   AddressResolverFileLine resolver(file, line, true);
93335617911SEd Maste   resolver.ResolveAddress(filter);
93435617911SEd Maste 
935435933ddSDimitry Andric   for (size_t n = 0; n < resolver.GetNumberOfAddresses(); n++) {
93635617911SEd Maste     Address addr = resolver.GetAddressRangeAtIndex(n).GetBaseAddress();
93735617911SEd Maste     Function *f = addr.CalculateSymbolContextFunction();
93835617911SEd Maste     if (f && f == function)
93935617911SEd Maste       output_local.push_back(addr);
94035617911SEd Maste     else
94135617911SEd Maste       output_extern.push_back(addr);
94235617911SEd Maste   }
94335617911SEd Maste }
94435617911SEd Maste 
FindTypes_Impl(const ConstString & name,const CompilerDeclContext * parent_decl_ctx,bool append,size_t max_matches,llvm::DenseSet<lldb_private::SymbolFile * > & searched_symbol_files,TypeMap & types)945435933ddSDimitry Andric size_t Module::FindTypes_Impl(
946*b5893f02SDimitry Andric     const ConstString &name, const CompilerDeclContext *parent_decl_ctx,
947*b5893f02SDimitry Andric     bool append, size_t max_matches,
9484bb0738eSEd Maste     llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
949435933ddSDimitry Andric     TypeMap &types) {
9505517e702SDimitry Andric   static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
9515517e702SDimitry Andric   Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
952ac7ddfbfSEd Maste   SymbolVendor *symbols = GetSymbolVendor();
953ac7ddfbfSEd Maste   if (symbols)
954*b5893f02SDimitry Andric     return symbols->FindTypes(name, parent_decl_ctx, append, max_matches,
955435933ddSDimitry Andric                               searched_symbol_files, types);
956ac7ddfbfSEd Maste   return 0;
957ac7ddfbfSEd Maste }
958ac7ddfbfSEd Maste 
FindTypesInNamespace(const ConstString & type_name,const CompilerDeclContext * parent_decl_ctx,size_t max_matches,TypeList & type_list)959*b5893f02SDimitry Andric size_t Module::FindTypesInNamespace(const ConstString &type_name,
9609f2f44ceSEd Maste                                     const CompilerDeclContext *parent_decl_ctx,
961435933ddSDimitry Andric                                     size_t max_matches, TypeList &type_list) {
962ac7ddfbfSEd Maste   const bool append = true;
9639f2f44ceSEd Maste   TypeMap types_map;
9644bb0738eSEd Maste   llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
965435933ddSDimitry Andric   size_t num_types =
966*b5893f02SDimitry Andric       FindTypes_Impl(type_name, parent_decl_ctx, append, max_matches,
967435933ddSDimitry Andric                      searched_symbol_files, types_map);
968*b5893f02SDimitry Andric   if (num_types > 0) {
969*b5893f02SDimitry Andric     SymbolContext sc;
970*b5893f02SDimitry Andric     sc.module_sp = shared_from_this();
9719f2f44ceSEd Maste     sc.SortTypeList(types_map, type_list);
972*b5893f02SDimitry Andric   }
9739f2f44ceSEd Maste   return num_types;
974ac7ddfbfSEd Maste }
975ac7ddfbfSEd Maste 
FindFirstType(const SymbolContext & sc,const ConstString & name,bool exact_match)976435933ddSDimitry Andric lldb::TypeSP Module::FindFirstType(const SymbolContext &sc,
977435933ddSDimitry Andric                                    const ConstString &name, bool exact_match) {
978ac7ddfbfSEd Maste   TypeList type_list;
9794bb0738eSEd Maste   llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
980435933ddSDimitry Andric   const size_t num_matches =
981*b5893f02SDimitry Andric       FindTypes(name, exact_match, 1, searched_symbol_files, type_list);
982ac7ddfbfSEd Maste   if (num_matches)
983ac7ddfbfSEd Maste     return type_list.GetTypeAtIndex(0);
984ac7ddfbfSEd Maste   return TypeSP();
985ac7ddfbfSEd Maste }
986ac7ddfbfSEd Maste 
FindTypes(const ConstString & name,bool exact_match,size_t max_matches,llvm::DenseSet<lldb_private::SymbolFile * > & searched_symbol_files,TypeList & types)987435933ddSDimitry Andric size_t Module::FindTypes(
988*b5893f02SDimitry Andric     const ConstString &name, bool exact_match, size_t max_matches,
9894bb0738eSEd Maste     llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
990435933ddSDimitry Andric     TypeList &types) {
991ac7ddfbfSEd Maste   size_t num_matches = 0;
992ac7ddfbfSEd Maste   const char *type_name_cstr = name.GetCString();
993f1a29dd3SDimitry Andric   llvm::StringRef type_scope;
994f1a29dd3SDimitry Andric   llvm::StringRef type_basename;
995ac7ddfbfSEd Maste   const bool append = true;
996ac7ddfbfSEd Maste   TypeClass type_class = eTypeClassAny;
9979f2f44ceSEd Maste   TypeMap typesmap;
9984ba319b5SDimitry Andric 
999435933ddSDimitry Andric   if (Type::GetTypeScopeAndBasename(type_name_cstr, type_scope, type_basename,
1000435933ddSDimitry Andric                                     type_class)) {
1001ac7ddfbfSEd Maste     // Check if "name" starts with "::" which means the qualified type starts
1002ac7ddfbfSEd Maste     // from the root namespace and implies and exact match. The typenames we
1003ac7ddfbfSEd Maste     // get back from clang do not start with "::" so we need to strip this off
10040127ef0fSEd Maste     // in order to get the qualified names to match
1005f1a29dd3SDimitry Andric     exact_match = type_scope.consume_front("::");
1006ac7ddfbfSEd Maste 
1007f1a29dd3SDimitry Andric     ConstString type_basename_const_str(type_basename);
1008*b5893f02SDimitry Andric     if (FindTypes_Impl(type_basename_const_str, nullptr, append, max_matches,
1009*b5893f02SDimitry Andric                        searched_symbol_files, typesmap)) {
1010435933ddSDimitry Andric       typesmap.RemoveMismatchedTypes(type_scope, type_basename, type_class,
1011435933ddSDimitry Andric                                      exact_match);
10129f2f44ceSEd Maste       num_matches = typesmap.GetSize();
1013ac7ddfbfSEd Maste     }
1014435933ddSDimitry Andric   } else {
1015435933ddSDimitry Andric     // The type is not in a namespace/class scope, just search for it by
1016435933ddSDimitry Andric     // basename
10174ba319b5SDimitry Andric     if (type_class != eTypeClassAny && !type_basename.empty()) {
1018435933ddSDimitry Andric       // The "type_name_cstr" will have been modified if we have a valid type
10194ba319b5SDimitry Andric       // class prefix (like "struct", "class", "union", "typedef" etc).
1020*b5893f02SDimitry Andric       FindTypes_Impl(ConstString(type_basename), nullptr, append, UINT_MAX,
1021*b5893f02SDimitry Andric                      searched_symbol_files, typesmap);
10224ba319b5SDimitry Andric       typesmap.RemoveMismatchedTypes(type_scope, type_basename, type_class,
10234ba319b5SDimitry Andric                                      exact_match);
10249f2f44ceSEd Maste       num_matches = typesmap.GetSize();
1025435933ddSDimitry Andric     } else {
1026*b5893f02SDimitry Andric       num_matches = FindTypes_Impl(name, nullptr, append, UINT_MAX,
1027435933ddSDimitry Andric                                    searched_symbol_files, typesmap);
10284ba319b5SDimitry Andric       if (exact_match) {
10294ba319b5SDimitry Andric         std::string name_str(name.AsCString(""));
10304ba319b5SDimitry Andric         typesmap.RemoveMismatchedTypes(type_scope, name_str, type_class,
10314ba319b5SDimitry Andric                                        exact_match);
10324ba319b5SDimitry Andric         num_matches = typesmap.GetSize();
10334ba319b5SDimitry Andric       }
1034ac7ddfbfSEd Maste     }
1035ac7ddfbfSEd Maste   }
1036*b5893f02SDimitry Andric   if (num_matches > 0) {
1037*b5893f02SDimitry Andric     SymbolContext sc;
1038*b5893f02SDimitry Andric     sc.module_sp = shared_from_this();
10399f2f44ceSEd Maste     sc.SortTypeList(typesmap, types);
1040*b5893f02SDimitry Andric   }
1041ac7ddfbfSEd Maste   return num_matches;
1042ac7ddfbfSEd Maste }
1043ac7ddfbfSEd Maste 
GetSymbolVendor(bool can_create,lldb_private::Stream * feedback_strm)1044435933ddSDimitry Andric SymbolVendor *Module::GetSymbolVendor(bool can_create,
1045435933ddSDimitry Andric                                       lldb_private::Stream *feedback_strm) {
1046435933ddSDimitry Andric   if (!m_did_load_symbol_vendor.load()) {
10474bb0738eSEd Maste     std::lock_guard<std::recursive_mutex> guard(m_mutex);
1048435933ddSDimitry Andric     if (!m_did_load_symbol_vendor.load() && can_create) {
1049ac7ddfbfSEd Maste       ObjectFile *obj_file = GetObjectFile();
1050435933ddSDimitry Andric       if (obj_file != nullptr) {
10515517e702SDimitry Andric         static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
10525517e702SDimitry Andric         Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
1053435933ddSDimitry Andric         m_symfile_ap.reset(
1054435933ddSDimitry Andric             SymbolVendor::FindPlugin(shared_from_this(), feedback_strm));
1055ac7ddfbfSEd Maste         m_did_load_symbol_vendor = true;
1056ac7ddfbfSEd Maste       }
1057ac7ddfbfSEd Maste     }
10589f2f44ceSEd Maste   }
1059ac7ddfbfSEd Maste   return m_symfile_ap.get();
1060ac7ddfbfSEd Maste }
1061ac7ddfbfSEd Maste 
SetFileSpecAndObjectName(const FileSpec & file,const ConstString & object_name)1062435933ddSDimitry Andric void Module::SetFileSpecAndObjectName(const FileSpec &file,
1063435933ddSDimitry Andric                                       const ConstString &object_name) {
10644ba319b5SDimitry Andric   // Container objects whose paths do not specify a file directly can call this
10654ba319b5SDimitry Andric   // function to correct the file and object names.
1066ac7ddfbfSEd Maste   m_file = file;
1067*b5893f02SDimitry Andric   m_mod_time = FileSystem::Instance().GetModificationTime(file);
1068ac7ddfbfSEd Maste   m_object_name = object_name;
1069ac7ddfbfSEd Maste }
1070ac7ddfbfSEd Maste 
GetArchitecture() const1071435933ddSDimitry Andric const ArchSpec &Module::GetArchitecture() const { return m_arch; }
1072ac7ddfbfSEd Maste 
GetSpecificationDescription() const1073435933ddSDimitry Andric std::string Module::GetSpecificationDescription() const {
1074ac7ddfbfSEd Maste   std::string spec(GetFileSpec().GetPath());
1075435933ddSDimitry Andric   if (m_object_name) {
1076ac7ddfbfSEd Maste     spec += '(';
1077ac7ddfbfSEd Maste     spec += m_object_name.GetCString();
1078ac7ddfbfSEd Maste     spec += ')';
1079ac7ddfbfSEd Maste   }
1080ac7ddfbfSEd Maste   return spec;
1081ac7ddfbfSEd Maste }
1082ac7ddfbfSEd Maste 
GetDescription(Stream * s,lldb::DescriptionLevel level)1083435933ddSDimitry Andric void Module::GetDescription(Stream *s, lldb::DescriptionLevel level) {
10844bb0738eSEd Maste   std::lock_guard<std::recursive_mutex> guard(m_mutex);
1085ac7ddfbfSEd Maste 
1086435933ddSDimitry Andric   if (level >= eDescriptionLevelFull) {
1087ac7ddfbfSEd Maste     if (m_arch.IsValid())
1088ac7ddfbfSEd Maste       s->Printf("(%s) ", m_arch.GetArchitectureName());
1089ac7ddfbfSEd Maste   }
1090ac7ddfbfSEd Maste 
1091435933ddSDimitry Andric   if (level == eDescriptionLevelBrief) {
1092ac7ddfbfSEd Maste     const char *filename = m_file.GetFilename().GetCString();
1093ac7ddfbfSEd Maste     if (filename)
1094ac7ddfbfSEd Maste       s->PutCString(filename);
1095435933ddSDimitry Andric   } else {
1096ac7ddfbfSEd Maste     char path[PATH_MAX];
1097ac7ddfbfSEd Maste     if (m_file.GetPath(path, sizeof(path)))
1098ac7ddfbfSEd Maste       s->PutCString(path);
1099ac7ddfbfSEd Maste   }
1100ac7ddfbfSEd Maste 
1101ac7ddfbfSEd Maste   const char *object_name = m_object_name.GetCString();
1102ac7ddfbfSEd Maste   if (object_name)
1103ac7ddfbfSEd Maste     s->Printf("(%s)", object_name);
1104ac7ddfbfSEd Maste }
1105ac7ddfbfSEd Maste 
ReportError(const char * format,...)1106435933ddSDimitry Andric void Module::ReportError(const char *format, ...) {
1107435933ddSDimitry Andric   if (format && format[0]) {
1108ac7ddfbfSEd Maste     StreamString strm;
1109ac7ddfbfSEd Maste     strm.PutCString("error: ");
1110ac7ddfbfSEd Maste     GetDescription(&strm, lldb::eDescriptionLevelBrief);
1111ac7ddfbfSEd Maste     strm.PutChar(' ');
1112ac7ddfbfSEd Maste     va_list args;
1113ac7ddfbfSEd Maste     va_start(args, format);
1114ac7ddfbfSEd Maste     strm.PrintfVarArg(format, args);
1115ac7ddfbfSEd Maste     va_end(args);
1116ac7ddfbfSEd Maste 
1117ac7ddfbfSEd Maste     const int format_len = strlen(format);
1118435933ddSDimitry Andric     if (format_len > 0) {
1119ac7ddfbfSEd Maste       const char last_char = format[format_len - 1];
1120ac7ddfbfSEd Maste       if (last_char != '\n' || last_char != '\r')
1121ac7ddfbfSEd Maste         strm.EOL();
1122ac7ddfbfSEd Maste     }
1123435933ddSDimitry Andric     Host::SystemLog(Host::eSystemLogError, "%s", strm.GetData());
1124ac7ddfbfSEd Maste   }
1125ac7ddfbfSEd Maste }
1126ac7ddfbfSEd Maste 
FileHasChanged() const1127435933ddSDimitry Andric bool Module::FileHasChanged() const {
11284bb0738eSEd Maste   if (!m_file_has_changed)
1129435933ddSDimitry Andric     m_file_has_changed =
1130*b5893f02SDimitry Andric         (FileSystem::Instance().GetModificationTime(m_file) != m_mod_time);
1131ac7ddfbfSEd Maste   return m_file_has_changed;
1132ac7ddfbfSEd Maste }
1133ac7ddfbfSEd Maste 
ReportErrorIfModifyDetected(const char * format,...)1134435933ddSDimitry Andric void Module::ReportErrorIfModifyDetected(const char *format, ...) {
1135435933ddSDimitry Andric   if (!m_first_file_changed_log) {
1136435933ddSDimitry Andric     if (FileHasChanged()) {
1137ac7ddfbfSEd Maste       m_first_file_changed_log = true;
1138435933ddSDimitry Andric       if (format) {
1139ac7ddfbfSEd Maste         StreamString strm;
1140ac7ddfbfSEd Maste         strm.PutCString("error: the object file ");
1141ac7ddfbfSEd Maste         GetDescription(&strm, lldb::eDescriptionLevelFull);
1142ac7ddfbfSEd Maste         strm.PutCString(" has been modified\n");
1143ac7ddfbfSEd Maste 
1144ac7ddfbfSEd Maste         va_list args;
1145ac7ddfbfSEd Maste         va_start(args, format);
1146ac7ddfbfSEd Maste         strm.PrintfVarArg(format, args);
1147ac7ddfbfSEd Maste         va_end(args);
1148ac7ddfbfSEd Maste 
1149ac7ddfbfSEd Maste         const int format_len = strlen(format);
1150435933ddSDimitry Andric         if (format_len > 0) {
1151ac7ddfbfSEd Maste           const char last_char = format[format_len - 1];
1152ac7ddfbfSEd Maste           if (last_char != '\n' || last_char != '\r')
1153ac7ddfbfSEd Maste             strm.EOL();
1154ac7ddfbfSEd Maste         }
1155435933ddSDimitry Andric         strm.PutCString("The debug session should be aborted as the original "
1156435933ddSDimitry Andric                         "debug information has been overwritten.\n");
1157435933ddSDimitry Andric         Host::SystemLog(Host::eSystemLogError, "%s", strm.GetData());
1158ac7ddfbfSEd Maste       }
1159ac7ddfbfSEd Maste     }
1160ac7ddfbfSEd Maste   }
1161ac7ddfbfSEd Maste }
1162ac7ddfbfSEd Maste 
ReportWarning(const char * format,...)1163435933ddSDimitry Andric void Module::ReportWarning(const char *format, ...) {
1164435933ddSDimitry Andric   if (format && format[0]) {
1165ac7ddfbfSEd Maste     StreamString strm;
1166ac7ddfbfSEd Maste     strm.PutCString("warning: ");
1167ac7ddfbfSEd Maste     GetDescription(&strm, lldb::eDescriptionLevelFull);
1168ac7ddfbfSEd Maste     strm.PutChar(' ');
1169ac7ddfbfSEd Maste 
1170ac7ddfbfSEd Maste     va_list args;
1171ac7ddfbfSEd Maste     va_start(args, format);
1172ac7ddfbfSEd Maste     strm.PrintfVarArg(format, args);
1173ac7ddfbfSEd Maste     va_end(args);
1174ac7ddfbfSEd Maste 
1175ac7ddfbfSEd Maste     const int format_len = strlen(format);
1176435933ddSDimitry Andric     if (format_len > 0) {
1177ac7ddfbfSEd Maste       const char last_char = format[format_len - 1];
1178ac7ddfbfSEd Maste       if (last_char != '\n' || last_char != '\r')
1179ac7ddfbfSEd Maste         strm.EOL();
1180ac7ddfbfSEd Maste     }
1181435933ddSDimitry Andric     Host::SystemLog(Host::eSystemLogWarning, "%s", strm.GetData());
1182ac7ddfbfSEd Maste   }
1183ac7ddfbfSEd Maste }
1184ac7ddfbfSEd Maste 
LogMessage(Log * log,const char * format,...)1185435933ddSDimitry Andric void Module::LogMessage(Log *log, const char *format, ...) {
1186435933ddSDimitry Andric   if (log != nullptr) {
1187ac7ddfbfSEd Maste     StreamString log_message;
1188ac7ddfbfSEd Maste     GetDescription(&log_message, lldb::eDescriptionLevelFull);
1189ac7ddfbfSEd Maste     log_message.PutCString(": ");
1190ac7ddfbfSEd Maste     va_list args;
1191ac7ddfbfSEd Maste     va_start(args, format);
1192ac7ddfbfSEd Maste     log_message.PrintfVarArg(format, args);
1193ac7ddfbfSEd Maste     va_end(args);
1194435933ddSDimitry Andric     log->PutCString(log_message.GetData());
1195ac7ddfbfSEd Maste   }
1196ac7ddfbfSEd Maste }
1197ac7ddfbfSEd Maste 
LogMessageVerboseBacktrace(Log * log,const char * format,...)1198435933ddSDimitry Andric void Module::LogMessageVerboseBacktrace(Log *log, const char *format, ...) {
1199435933ddSDimitry Andric   if (log != nullptr) {
1200ac7ddfbfSEd Maste     StreamString log_message;
1201ac7ddfbfSEd Maste     GetDescription(&log_message, lldb::eDescriptionLevelFull);
1202ac7ddfbfSEd Maste     log_message.PutCString(": ");
1203ac7ddfbfSEd Maste     va_list args;
1204ac7ddfbfSEd Maste     va_start(args, format);
1205ac7ddfbfSEd Maste     log_message.PrintfVarArg(format, args);
1206ac7ddfbfSEd Maste     va_end(args);
1207435933ddSDimitry Andric     if (log->GetVerbose()) {
12081c3bbb01SEd Maste       std::string back_trace;
12091c3bbb01SEd Maste       llvm::raw_string_ostream stream(back_trace);
12101c3bbb01SEd Maste       llvm::sys::PrintStackTrace(stream);
1211435933ddSDimitry Andric       log_message.PutCString(back_trace);
12121c3bbb01SEd Maste     }
1213435933ddSDimitry Andric     log->PutCString(log_message.GetData());
1214ac7ddfbfSEd Maste   }
1215ac7ddfbfSEd Maste }
1216ac7ddfbfSEd Maste 
Dump(Stream * s)1217435933ddSDimitry Andric void Module::Dump(Stream *s) {
12184bb0738eSEd Maste   std::lock_guard<std::recursive_mutex> guard(m_mutex);
1219ac7ddfbfSEd Maste   // s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
1220ac7ddfbfSEd Maste   s->Indent();
1221435933ddSDimitry Andric   s->Printf("Module %s%s%s%s\n", m_file.GetPath().c_str(),
1222ac7ddfbfSEd Maste             m_object_name ? "(" : "",
1223ac7ddfbfSEd Maste             m_object_name ? m_object_name.GetCString() : "",
1224ac7ddfbfSEd Maste             m_object_name ? ")" : "");
1225ac7ddfbfSEd Maste 
1226ac7ddfbfSEd Maste   s->IndentMore();
1227ac7ddfbfSEd Maste 
1228ac7ddfbfSEd Maste   ObjectFile *objfile = GetObjectFile();
1229ac7ddfbfSEd Maste   if (objfile)
1230ac7ddfbfSEd Maste     objfile->Dump(s);
1231ac7ddfbfSEd Maste 
1232ac7ddfbfSEd Maste   SymbolVendor *symbols = GetSymbolVendor();
1233ac7ddfbfSEd Maste   if (symbols)
1234ac7ddfbfSEd Maste     symbols->Dump(s);
1235ac7ddfbfSEd Maste 
1236ac7ddfbfSEd Maste   s->IndentLess();
1237ac7ddfbfSEd Maste }
1238ac7ddfbfSEd Maste 
GetTypeList()1239435933ddSDimitry Andric TypeList *Module::GetTypeList() {
1240ac7ddfbfSEd Maste   SymbolVendor *symbols = GetSymbolVendor();
1241ac7ddfbfSEd Maste   if (symbols)
1242ac7ddfbfSEd Maste     return &symbols->GetTypeList();
12434bb0738eSEd Maste   return nullptr;
1244ac7ddfbfSEd Maste }
1245ac7ddfbfSEd Maste 
GetObjectName() const1246435933ddSDimitry Andric const ConstString &Module::GetObjectName() const { return m_object_name; }
1247ac7ddfbfSEd Maste 
GetObjectFile()1248435933ddSDimitry Andric ObjectFile *Module::GetObjectFile() {
1249435933ddSDimitry Andric   if (!m_did_load_objfile.load()) {
12504bb0738eSEd Maste     std::lock_guard<std::recursive_mutex> guard(m_mutex);
1251435933ddSDimitry Andric     if (!m_did_load_objfile.load()) {
12525517e702SDimitry Andric       static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
12535517e702SDimitry Andric       Timer scoped_timer(func_cat, "Module::GetObjectFile () module = %s",
1254435933ddSDimitry Andric                          GetFileSpec().GetFilename().AsCString(""));
1255ac7ddfbfSEd Maste       DataBufferSP data_sp;
1256ac7ddfbfSEd Maste       lldb::offset_t data_offset = 0;
1257*b5893f02SDimitry Andric       const lldb::offset_t file_size =
1258*b5893f02SDimitry Andric           FileSystem::Instance().GetByteSize(m_file);
1259435933ddSDimitry Andric       if (file_size > m_object_offset) {
1260ac7ddfbfSEd Maste         m_did_load_objfile = true;
1261435933ddSDimitry Andric         m_objfile_sp = ObjectFile::FindPlugin(
1262435933ddSDimitry Andric             shared_from_this(), &m_file, m_object_offset,
1263435933ddSDimitry Andric             file_size - m_object_offset, data_sp, data_offset);
1264435933ddSDimitry Andric         if (m_objfile_sp) {
1265435933ddSDimitry Andric           // Once we get the object file, update our module with the object
12664ba319b5SDimitry Andric           // file's architecture since it might differ in vendor/os if some
12674ba319b5SDimitry Andric           // parts were unknown.  But since the matching arch might already be
12684ba319b5SDimitry Andric           // more specific than the generic COFF architecture, only merge in
12694ba319b5SDimitry Andric           // those values that overwrite unspecified unknown values.
1270*b5893f02SDimitry Andric           m_arch.MergeFrom(m_objfile_sp->GetArchitecture());
1271435933ddSDimitry Andric         } else {
1272435933ddSDimitry Andric           ReportError("failed to load objfile for %s",
1273435933ddSDimitry Andric                       GetFileSpec().GetPath().c_str());
12747aa51b79SEd Maste         }
1275ac7ddfbfSEd Maste       }
1276ac7ddfbfSEd Maste     }
12779f2f44ceSEd Maste   }
1278ac7ddfbfSEd Maste   return m_objfile_sp.get();
1279ac7ddfbfSEd Maste }
1280ac7ddfbfSEd Maste 
GetSectionList()1281435933ddSDimitry Andric SectionList *Module::GetSectionList() {
12824ba319b5SDimitry Andric   // Populate m_sections_ap with sections from objfile.
1283435933ddSDimitry Andric   if (!m_sections_ap) {
1284ac7ddfbfSEd Maste     ObjectFile *obj_file = GetObjectFile();
12854bb0738eSEd Maste     if (obj_file != nullptr)
1286ac7ddfbfSEd Maste       obj_file->CreateSections(*GetUnifiedSectionList());
1287ac7ddfbfSEd Maste   }
1288ac7ddfbfSEd Maste   return m_sections_ap.get();
1289ac7ddfbfSEd Maste }
1290ac7ddfbfSEd Maste 
SectionFileAddressesChanged()1291435933ddSDimitry Andric void Module::SectionFileAddressesChanged() {
12920127ef0fSEd Maste   ObjectFile *obj_file = GetObjectFile();
12930127ef0fSEd Maste   if (obj_file)
12940127ef0fSEd Maste     obj_file->SectionFileAddressesChanged();
12950127ef0fSEd Maste   SymbolVendor *sym_vendor = GetSymbolVendor();
12964bb0738eSEd Maste   if (sym_vendor != nullptr)
12970127ef0fSEd Maste     sym_vendor->SectionFileAddressesChanged();
12980127ef0fSEd Maste }
12990127ef0fSEd Maste 
GetUnifiedSectionList()1300435933ddSDimitry Andric SectionList *Module::GetUnifiedSectionList() {
13014bb0738eSEd Maste   if (!m_sections_ap)
1302f678e45dSDimitry Andric     m_sections_ap = llvm::make_unique<SectionList>();
1303ac7ddfbfSEd Maste   return m_sections_ap.get();
1304ac7ddfbfSEd Maste }
1305ac7ddfbfSEd Maste 
FindFirstSymbolWithNameAndType(const ConstString & name,SymbolType symbol_type)1306435933ddSDimitry Andric const Symbol *Module::FindFirstSymbolWithNameAndType(const ConstString &name,
1307435933ddSDimitry Andric                                                      SymbolType symbol_type) {
13085517e702SDimitry Andric   static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
1309435933ddSDimitry Andric   Timer scoped_timer(
13105517e702SDimitry Andric       func_cat, "Module::FindFirstSymbolWithNameAndType (name = %s, type = %i)",
1311435933ddSDimitry Andric       name.AsCString(), symbol_type);
1312ac7ddfbfSEd Maste   SymbolVendor *sym_vendor = GetSymbolVendor();
1313435933ddSDimitry Andric   if (sym_vendor) {
1314ac7ddfbfSEd Maste     Symtab *symtab = sym_vendor->GetSymtab();
1315ac7ddfbfSEd Maste     if (symtab)
1316435933ddSDimitry Andric       return symtab->FindFirstSymbolWithNameAndType(
1317435933ddSDimitry Andric           name, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny);
1318ac7ddfbfSEd Maste   }
13194bb0738eSEd Maste   return nullptr;
1320ac7ddfbfSEd Maste }
SymbolIndicesToSymbolContextList(Symtab * symtab,std::vector<uint32_t> & symbol_indexes,SymbolContextList & sc_list)1321435933ddSDimitry Andric void Module::SymbolIndicesToSymbolContextList(
1322435933ddSDimitry Andric     Symtab *symtab, std::vector<uint32_t> &symbol_indexes,
1323435933ddSDimitry Andric     SymbolContextList &sc_list) {
1324ac7ddfbfSEd Maste   // No need to protect this call using m_mutex all other method calls are
1325ac7ddfbfSEd Maste   // already thread safe.
1326ac7ddfbfSEd Maste 
1327ac7ddfbfSEd Maste   size_t num_indices = symbol_indexes.size();
1328435933ddSDimitry Andric   if (num_indices > 0) {
1329ac7ddfbfSEd Maste     SymbolContext sc;
1330ac7ddfbfSEd Maste     CalculateSymbolContext(&sc);
1331435933ddSDimitry Andric     for (size_t i = 0; i < num_indices; i++) {
1332ac7ddfbfSEd Maste       sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
1333ac7ddfbfSEd Maste       if (sc.symbol)
1334ac7ddfbfSEd Maste         sc_list.Append(sc);
1335ac7ddfbfSEd Maste     }
1336ac7ddfbfSEd Maste   }
1337ac7ddfbfSEd Maste }
1338ac7ddfbfSEd Maste 
FindFunctionSymbols(const ConstString & name,uint32_t name_type_mask,SymbolContextList & sc_list)1339435933ddSDimitry Andric size_t Module::FindFunctionSymbols(const ConstString &name,
1340ac7ddfbfSEd Maste                                    uint32_t name_type_mask,
1341435933ddSDimitry Andric                                    SymbolContextList &sc_list) {
13425517e702SDimitry Andric   static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
13435517e702SDimitry Andric   Timer scoped_timer(func_cat,
1344ac7ddfbfSEd Maste                      "Module::FindSymbolsFunctions (name = %s, mask = 0x%8.8x)",
1345435933ddSDimitry Andric                      name.AsCString(), name_type_mask);
1346ac7ddfbfSEd Maste   SymbolVendor *sym_vendor = GetSymbolVendor();
1347435933ddSDimitry Andric   if (sym_vendor) {
1348ac7ddfbfSEd Maste     Symtab *symtab = sym_vendor->GetSymtab();
1349ac7ddfbfSEd Maste     if (symtab)
1350ac7ddfbfSEd Maste       return symtab->FindFunctionSymbols(name, name_type_mask, sc_list);
1351ac7ddfbfSEd Maste   }
1352ac7ddfbfSEd Maste   return 0;
1353ac7ddfbfSEd Maste }
1354ac7ddfbfSEd Maste 
FindSymbolsWithNameAndType(const ConstString & name,SymbolType symbol_type,SymbolContextList & sc_list)1355435933ddSDimitry Andric size_t Module::FindSymbolsWithNameAndType(const ConstString &name,
1356435933ddSDimitry Andric                                           SymbolType symbol_type,
1357435933ddSDimitry Andric                                           SymbolContextList &sc_list) {
1358ac7ddfbfSEd Maste   // No need to protect this call using m_mutex all other method calls are
1359ac7ddfbfSEd Maste   // already thread safe.
1360ac7ddfbfSEd Maste 
13615517e702SDimitry Andric   static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
1362435933ddSDimitry Andric   Timer scoped_timer(
13635517e702SDimitry Andric       func_cat, "Module::FindSymbolsWithNameAndType (name = %s, type = %i)",
1364435933ddSDimitry Andric       name.AsCString(), symbol_type);
1365ac7ddfbfSEd Maste   const size_t initial_size = sc_list.GetSize();
1366ac7ddfbfSEd Maste   SymbolVendor *sym_vendor = GetSymbolVendor();
1367435933ddSDimitry Andric   if (sym_vendor) {
1368ac7ddfbfSEd Maste     Symtab *symtab = sym_vendor->GetSymtab();
1369435933ddSDimitry Andric     if (symtab) {
1370ac7ddfbfSEd Maste       std::vector<uint32_t> symbol_indexes;
1371ac7ddfbfSEd Maste       symtab->FindAllSymbolsWithNameAndType(name, symbol_type, symbol_indexes);
1372ac7ddfbfSEd Maste       SymbolIndicesToSymbolContextList(symtab, symbol_indexes, sc_list);
1373ac7ddfbfSEd Maste     }
1374ac7ddfbfSEd Maste   }
1375ac7ddfbfSEd Maste   return sc_list.GetSize() - initial_size;
1376ac7ddfbfSEd Maste }
1377ac7ddfbfSEd Maste 
FindSymbolsMatchingRegExAndType(const RegularExpression & regex,SymbolType symbol_type,SymbolContextList & sc_list)1378435933ddSDimitry Andric size_t Module::FindSymbolsMatchingRegExAndType(const RegularExpression &regex,
1379435933ddSDimitry Andric                                                SymbolType symbol_type,
1380435933ddSDimitry Andric                                                SymbolContextList &sc_list) {
1381ac7ddfbfSEd Maste   // No need to protect this call using m_mutex all other method calls are
1382ac7ddfbfSEd Maste   // already thread safe.
1383ac7ddfbfSEd Maste 
13845517e702SDimitry Andric   static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
1385435933ddSDimitry Andric   Timer scoped_timer(
13865517e702SDimitry Andric       func_cat,
1387ac7ddfbfSEd Maste       "Module::FindSymbolsMatchingRegExAndType (regex = %s, type = %i)",
1388435933ddSDimitry Andric       regex.GetText().str().c_str(), symbol_type);
1389ac7ddfbfSEd Maste   const size_t initial_size = sc_list.GetSize();
1390ac7ddfbfSEd Maste   SymbolVendor *sym_vendor = GetSymbolVendor();
1391435933ddSDimitry Andric   if (sym_vendor) {
1392ac7ddfbfSEd Maste     Symtab *symtab = sym_vendor->GetSymtab();
1393435933ddSDimitry Andric     if (symtab) {
1394ac7ddfbfSEd Maste       std::vector<uint32_t> symbol_indexes;
1395435933ddSDimitry Andric       symtab->FindAllSymbolsMatchingRexExAndType(
1396435933ddSDimitry Andric           regex, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny,
1397435933ddSDimitry Andric           symbol_indexes);
1398ac7ddfbfSEd Maste       SymbolIndicesToSymbolContextList(symtab, symbol_indexes, sc_list);
1399ac7ddfbfSEd Maste     }
1400ac7ddfbfSEd Maste   }
1401ac7ddfbfSEd Maste   return sc_list.GetSize() - initial_size;
1402ac7ddfbfSEd Maste }
1403ac7ddfbfSEd Maste 
PreloadSymbols()1404f37b6182SDimitry Andric void Module::PreloadSymbols() {
1405f37b6182SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(m_mutex);
1406f37b6182SDimitry Andric   SymbolVendor * sym_vendor = GetSymbolVendor();
1407f37b6182SDimitry Andric   if (!sym_vendor) {
1408f37b6182SDimitry Andric     return;
1409f37b6182SDimitry Andric   }
1410f37b6182SDimitry Andric   // Prime the symbol file first, since it adds symbols to the symbol table.
1411f37b6182SDimitry Andric   if (SymbolFile *symbol_file = sym_vendor->GetSymbolFile()) {
1412f37b6182SDimitry Andric     symbol_file->PreloadSymbols();
1413f37b6182SDimitry Andric   }
1414f37b6182SDimitry Andric   // Now we can prime the symbol table.
1415f37b6182SDimitry Andric   if (Symtab * symtab = sym_vendor->GetSymtab()) {
1416f37b6182SDimitry Andric     symtab->PreloadSymbols();
1417f37b6182SDimitry Andric   }
1418f37b6182SDimitry Andric }
1419f37b6182SDimitry Andric 
SetSymbolFileFileSpec(const FileSpec & file)1420435933ddSDimitry Andric void Module::SetSymbolFileFileSpec(const FileSpec &file) {
1421*b5893f02SDimitry Andric   if (!FileSystem::Instance().Exists(file))
14221c3bbb01SEd Maste     return;
1423435933ddSDimitry Andric   if (m_symfile_ap) {
1424435933ddSDimitry Andric     // Remove any sections in the unified section list that come from the
1425435933ddSDimitry Andric     // current symbol vendor.
1426ac7ddfbfSEd Maste     SectionList *section_list = GetSectionList();
1427ac7ddfbfSEd Maste     SymbolFile *symbol_file = m_symfile_ap->GetSymbolFile();
1428435933ddSDimitry Andric     if (section_list && symbol_file) {
1429ac7ddfbfSEd Maste       ObjectFile *obj_file = symbol_file->GetObjectFile();
1430435933ddSDimitry Andric       // Make sure we have an object file and that the symbol vendor's objfile
14314ba319b5SDimitry Andric       // isn't the same as the module's objfile before we remove any sections
14324ba319b5SDimitry Andric       // for it...
1433435933ddSDimitry Andric       if (obj_file) {
1434435933ddSDimitry Andric         // Check to make sure we aren't trying to specify the file we already
1435435933ddSDimitry Andric         // have
1436435933ddSDimitry Andric         if (obj_file->GetFileSpec() == file) {
14371c3bbb01SEd Maste           // We are being told to add the exact same file that we already have
14381c3bbb01SEd Maste           // we don't have to do anything.
14391c3bbb01SEd Maste           return;
14401c3bbb01SEd Maste         }
14411c3bbb01SEd Maste 
1442435933ddSDimitry Andric         // Cleare the current symtab as we are going to replace it with a new
1443435933ddSDimitry Andric         // one
14449f2f44ceSEd Maste         obj_file->ClearSymtab();
14459f2f44ceSEd Maste 
1446435933ddSDimitry Andric         // The symbol file might be a directory bundle ("/tmp/a.out.dSYM")
14474ba319b5SDimitry Andric         // instead of a full path to the symbol file within the bundle
1448435933ddSDimitry Andric         // ("/tmp/a.out.dSYM/Contents/Resources/DWARF/a.out"). So we need to
1449435933ddSDimitry Andric         // check this
14501c3bbb01SEd Maste 
1451*b5893f02SDimitry Andric         if (FileSystem::Instance().IsDirectory(file)) {
14521c3bbb01SEd Maste           std::string new_path(file.GetPath());
14531c3bbb01SEd Maste           std::string old_path(obj_file->GetFileSpec().GetPath());
1454435933ddSDimitry Andric           if (old_path.find(new_path) == 0) {
1455435933ddSDimitry Andric             // We specified the same bundle as the symbol file that we already
1456435933ddSDimitry Andric             // have
14571c3bbb01SEd Maste             return;
14581c3bbb01SEd Maste           }
14591c3bbb01SEd Maste         }
14601c3bbb01SEd Maste 
1461435933ddSDimitry Andric         if (obj_file != m_objfile_sp.get()) {
1462ac7ddfbfSEd Maste           size_t num_sections = section_list->GetNumSections(0);
1463435933ddSDimitry Andric           for (size_t idx = num_sections; idx > 0; --idx) {
1464435933ddSDimitry Andric             lldb::SectionSP section_sp(
1465435933ddSDimitry Andric                 section_list->GetSectionAtIndex(idx - 1));
1466435933ddSDimitry Andric             if (section_sp->GetObjectFile() == obj_file) {
1467ac7ddfbfSEd Maste               section_list->DeleteSection(idx - 1);
1468ac7ddfbfSEd Maste             }
1469ac7ddfbfSEd Maste           }
1470ac7ddfbfSEd Maste         }
1471ac7ddfbfSEd Maste       }
1472ac7ddfbfSEd Maste     }
1473435933ddSDimitry Andric     // Keep all old symbol files around in case there are any lingering type
14744ba319b5SDimitry Andric     // references in any SBValue objects that might have been handed out.
14751c3bbb01SEd Maste     m_old_symfiles.push_back(std::move(m_symfile_ap));
14761c3bbb01SEd Maste   }
1477ac7ddfbfSEd Maste   m_symfile_spec = file;
1478ac7ddfbfSEd Maste   m_symfile_ap.reset();
1479ac7ddfbfSEd Maste   m_did_load_symbol_vendor = false;
1480ac7ddfbfSEd Maste }
1481ac7ddfbfSEd Maste 
IsExecutable()1482435933ddSDimitry Andric bool Module::IsExecutable() {
14834bb0738eSEd Maste   if (GetObjectFile() == nullptr)
1484ac7ddfbfSEd Maste     return false;
1485ac7ddfbfSEd Maste   else
1486ac7ddfbfSEd Maste     return GetObjectFile()->IsExecutable();
1487ac7ddfbfSEd Maste }
1488ac7ddfbfSEd Maste 
IsLoadedInTarget(Target * target)1489435933ddSDimitry Andric bool Module::IsLoadedInTarget(Target *target) {
1490ac7ddfbfSEd Maste   ObjectFile *obj_file = GetObjectFile();
1491435933ddSDimitry Andric   if (obj_file) {
1492ac7ddfbfSEd Maste     SectionList *sections = GetSectionList();
1493435933ddSDimitry Andric     if (sections != nullptr) {
1494ac7ddfbfSEd Maste       size_t num_sections = sections->GetSize();
1495435933ddSDimitry Andric       for (size_t sect_idx = 0; sect_idx < num_sections; sect_idx++) {
1496ac7ddfbfSEd Maste         SectionSP section_sp = sections->GetSectionAtIndex(sect_idx);
1497435933ddSDimitry Andric         if (section_sp->GetLoadBaseAddress(target) != LLDB_INVALID_ADDRESS) {
1498ac7ddfbfSEd Maste           return true;
1499ac7ddfbfSEd Maste         }
1500ac7ddfbfSEd Maste       }
1501ac7ddfbfSEd Maste     }
1502ac7ddfbfSEd Maste   }
1503ac7ddfbfSEd Maste   return false;
1504ac7ddfbfSEd Maste }
1505ac7ddfbfSEd Maste 
LoadScriptingResourceInTarget(Target * target,Status & error,Stream * feedback_stream)15065517e702SDimitry Andric bool Module::LoadScriptingResourceInTarget(Target *target, Status &error,
1507435933ddSDimitry Andric                                            Stream *feedback_stream) {
1508435933ddSDimitry Andric   if (!target) {
1509ac7ddfbfSEd Maste     error.SetErrorString("invalid destination Target");
1510ac7ddfbfSEd Maste     return false;
1511ac7ddfbfSEd Maste   }
1512ac7ddfbfSEd Maste 
1513435933ddSDimitry Andric   LoadScriptFromSymFile should_load =
1514435933ddSDimitry Andric       target->TargetProperties::GetLoadScriptFromSymbolFile();
15150127ef0fSEd Maste 
15160127ef0fSEd Maste   if (should_load == eLoadScriptFromSymFileFalse)
15170127ef0fSEd Maste     return false;
1518ac7ddfbfSEd Maste 
1519ac7ddfbfSEd Maste   Debugger &debugger = target->GetDebugger();
1520ac7ddfbfSEd Maste   const ScriptLanguage script_language = debugger.GetScriptLanguage();
1521435933ddSDimitry Andric   if (script_language != eScriptLanguageNone) {
1522ac7ddfbfSEd Maste 
1523ac7ddfbfSEd Maste     PlatformSP platform_sp(target->GetPlatform());
1524ac7ddfbfSEd Maste 
1525435933ddSDimitry Andric     if (!platform_sp) {
1526ac7ddfbfSEd Maste       error.SetErrorString("invalid Platform");
1527ac7ddfbfSEd Maste       return false;
1528ac7ddfbfSEd Maste     }
1529ac7ddfbfSEd Maste 
1530435933ddSDimitry Andric     FileSpecList file_specs = platform_sp->LocateExecutableScriptingResources(
1531435933ddSDimitry Andric         target, *this, feedback_stream);
1532ac7ddfbfSEd Maste 
1533ac7ddfbfSEd Maste     const uint32_t num_specs = file_specs.GetSize();
1534435933ddSDimitry Andric     if (num_specs) {
1535435933ddSDimitry Andric       ScriptInterpreter *script_interpreter =
1536435933ddSDimitry Andric           debugger.GetCommandInterpreter().GetScriptInterpreter();
1537435933ddSDimitry Andric       if (script_interpreter) {
1538435933ddSDimitry Andric         for (uint32_t i = 0; i < num_specs; ++i) {
1539ac7ddfbfSEd Maste           FileSpec scripting_fspec(file_specs.GetFileSpecAtIndex(i));
1540*b5893f02SDimitry Andric           if (scripting_fspec &&
1541*b5893f02SDimitry Andric               FileSystem::Instance().Exists(scripting_fspec)) {
1542435933ddSDimitry Andric             if (should_load == eLoadScriptFromSymFileWarn) {
1543ac7ddfbfSEd Maste               if (feedback_stream)
1544435933ddSDimitry Andric                 feedback_stream->Printf(
1545435933ddSDimitry Andric                     "warning: '%s' contains a debug script. To run this script "
1546435933ddSDimitry Andric                     "in "
1547435933ddSDimitry Andric                     "this debug session:\n\n    command script import "
1548435933ddSDimitry Andric                     "\"%s\"\n\n"
1549ac7ddfbfSEd Maste                     "To run all discovered debug scripts in this session:\n\n"
1550435933ddSDimitry Andric                     "    settings set target.load-script-from-symbol-file "
1551435933ddSDimitry Andric                     "true\n",
1552ac7ddfbfSEd Maste                     GetFileSpec().GetFileNameStrippingExtension().GetCString(),
1553ac7ddfbfSEd Maste                     scripting_fspec.GetPath().c_str());
1554ac7ddfbfSEd Maste               return false;
1555ac7ddfbfSEd Maste             }
1556ac7ddfbfSEd Maste             StreamString scripting_stream;
1557ac7ddfbfSEd Maste             scripting_fspec.Dump(&scripting_stream);
1558ac7ddfbfSEd Maste             const bool can_reload = true;
1559ac7ddfbfSEd Maste             const bool init_lldb_globals = false;
1560435933ddSDimitry Andric             bool did_load = script_interpreter->LoadScriptingModule(
1561435933ddSDimitry Andric                 scripting_stream.GetData(), can_reload, init_lldb_globals,
1562ac7ddfbfSEd Maste                 error);
1563ac7ddfbfSEd Maste             if (!did_load)
1564ac7ddfbfSEd Maste               return false;
1565ac7ddfbfSEd Maste           }
1566ac7ddfbfSEd Maste         }
1567435933ddSDimitry Andric       } else {
1568ac7ddfbfSEd Maste         error.SetErrorString("invalid ScriptInterpreter");
1569ac7ddfbfSEd Maste         return false;
1570ac7ddfbfSEd Maste       }
1571ac7ddfbfSEd Maste     }
1572ac7ddfbfSEd Maste   }
1573ac7ddfbfSEd Maste   return true;
1574ac7ddfbfSEd Maste }
1575ac7ddfbfSEd Maste 
SetArchitecture(const ArchSpec & new_arch)1576435933ddSDimitry Andric bool Module::SetArchitecture(const ArchSpec &new_arch) {
1577435933ddSDimitry Andric   if (!m_arch.IsValid()) {
1578ac7ddfbfSEd Maste     m_arch = new_arch;
1579ac7ddfbfSEd Maste     return true;
1580ac7ddfbfSEd Maste   }
15811c3bbb01SEd Maste   return m_arch.IsCompatibleMatch(new_arch);
1582ac7ddfbfSEd Maste }
1583ac7ddfbfSEd Maste 
SetLoadAddress(Target & target,lldb::addr_t value,bool value_is_offset,bool & changed)1584435933ddSDimitry Andric bool Module::SetLoadAddress(Target &target, lldb::addr_t value,
1585435933ddSDimitry Andric                             bool value_is_offset, bool &changed) {
158612b93ac6SEd Maste   ObjectFile *object_file = GetObjectFile();
1587435933ddSDimitry Andric   if (object_file != nullptr) {
158812b93ac6SEd Maste     changed = object_file->SetLoadAddress(target, value, value_is_offset);
158912b93ac6SEd Maste     return true;
1590435933ddSDimitry Andric   } else {
159112b93ac6SEd Maste     changed = false;
1592ac7ddfbfSEd Maste   }
159312b93ac6SEd Maste   return false;
1594ac7ddfbfSEd Maste }
1595ac7ddfbfSEd Maste 
MatchesModuleSpec(const ModuleSpec & module_ref)1596435933ddSDimitry Andric bool Module::MatchesModuleSpec(const ModuleSpec &module_ref) {
1597ac7ddfbfSEd Maste   const UUID &uuid = module_ref.GetUUID();
1598ac7ddfbfSEd Maste 
1599435933ddSDimitry Andric   if (uuid.IsValid()) {
1600ac7ddfbfSEd Maste     // If the UUID matches, then nothing more needs to match...
16014bb0738eSEd Maste     return (uuid == GetUUID());
1602ac7ddfbfSEd Maste   }
1603ac7ddfbfSEd Maste 
1604ac7ddfbfSEd Maste   const FileSpec &file_spec = module_ref.GetFileSpec();
1605435933ddSDimitry Andric   if (file_spec) {
16069f2f44ceSEd Maste     if (!FileSpec::Equal(file_spec, m_file, (bool)file_spec.GetDirectory()) &&
1607435933ddSDimitry Andric         !FileSpec::Equal(file_spec, m_platform_file,
1608435933ddSDimitry Andric                          (bool)file_spec.GetDirectory()))
1609ac7ddfbfSEd Maste       return false;
1610ac7ddfbfSEd Maste   }
1611ac7ddfbfSEd Maste 
1612ac7ddfbfSEd Maste   const FileSpec &platform_file_spec = module_ref.GetPlatformFileSpec();
1613435933ddSDimitry Andric   if (platform_file_spec) {
1614435933ddSDimitry Andric     if (!FileSpec::Equal(platform_file_spec, GetPlatformFileSpec(),
1615435933ddSDimitry Andric                          (bool)platform_file_spec.GetDirectory()))
1616ac7ddfbfSEd Maste       return false;
1617ac7ddfbfSEd Maste   }
1618ac7ddfbfSEd Maste 
1619ac7ddfbfSEd Maste   const ArchSpec &arch = module_ref.GetArchitecture();
1620435933ddSDimitry Andric   if (arch.IsValid()) {
1621ac7ddfbfSEd Maste     if (!m_arch.IsCompatibleMatch(arch))
1622ac7ddfbfSEd Maste       return false;
1623ac7ddfbfSEd Maste   }
1624ac7ddfbfSEd Maste 
1625ac7ddfbfSEd Maste   const ConstString &object_name = module_ref.GetObjectName();
1626435933ddSDimitry Andric   if (object_name) {
1627ac7ddfbfSEd Maste     if (object_name != GetObjectName())
1628ac7ddfbfSEd Maste       return false;
1629ac7ddfbfSEd Maste   }
1630ac7ddfbfSEd Maste   return true;
1631ac7ddfbfSEd Maste }
1632ac7ddfbfSEd Maste 
FindSourceFile(const FileSpec & orig_spec,FileSpec & new_spec) const1633435933ddSDimitry Andric bool Module::FindSourceFile(const FileSpec &orig_spec,
1634435933ddSDimitry Andric                             FileSpec &new_spec) const {
16354bb0738eSEd Maste   std::lock_guard<std::recursive_mutex> guard(m_mutex);
1636ac7ddfbfSEd Maste   return m_source_mappings.FindFile(orig_spec, new_spec);
1637ac7ddfbfSEd Maste }
1638ac7ddfbfSEd Maste 
RemapSourceFile(llvm::StringRef path,std::string & new_path) const1639435933ddSDimitry Andric bool Module::RemapSourceFile(llvm::StringRef path,
1640435933ddSDimitry Andric                              std::string &new_path) const {
16414bb0738eSEd Maste   std::lock_guard<std::recursive_mutex> guard(m_mutex);
1642ac7ddfbfSEd Maste   return m_source_mappings.RemapPath(path, new_path);
1643ac7ddfbfSEd Maste }
1644ac7ddfbfSEd Maste 
GetVersion()16454ba319b5SDimitry Andric llvm::VersionTuple Module::GetVersion() {
16464ba319b5SDimitry Andric   if (ObjectFile *obj_file = GetObjectFile())
16474ba319b5SDimitry Andric     return obj_file->GetVersion();
16484ba319b5SDimitry Andric   return llvm::VersionTuple();
16490127ef0fSEd Maste }
16500127ef0fSEd Maste 
GetIsDynamicLinkEditor()1651435933ddSDimitry Andric bool Module::GetIsDynamicLinkEditor() {
16521c3bbb01SEd Maste   ObjectFile *obj_file = GetObjectFile();
16531c3bbb01SEd Maste 
16541c3bbb01SEd Maste   if (obj_file)
16551c3bbb01SEd Maste     return obj_file->GetIsDynamicLinkEditor();
16561c3bbb01SEd Maste 
16571c3bbb01SEd Maste   return false;
16581c3bbb01SEd Maste }
1659