34#include "clang/Driver/Driver.h"
35#include "llvm/ADT/StringRef.h"
36#include "llvm/Support/FileSystem.h"
37#include "llvm/Support/Threading.h"
38#include "llvm/Support/raw_ostream.h"
67#define LLDB_PROPERTIES_modulelist
68#include "CoreProperties.inc"
71#define LLDB_PROPERTIES_modulelist
72#include "CorePropertiesEnum.inc"
79 std::make_shared<OptionValueProperties>(
ConstString(
"symbols"));
84 llvm::SmallString<128> path;
85 if (clang::driver::Driver::getDefaultModuleCachePath(path)) {
90 if (llvm::sys::path::cache_directory(path)) {
91 llvm::sys::path::append(path,
"lldb");
92 llvm::sys::path::append(path,
"IndexCache");
99 const uint32_t idx = ePropertyEnableExternalLookup;
100 return GetPropertyAtIndexAs<bool>(
101 idx, g_modulelist_properties[idx].default_uint_value != 0);
109 const uint32_t idx = ePropertyEnableBackgroundLookup;
110 return GetPropertyAtIndexAs<bool>(
111 idx, g_modulelist_properties[idx].default_uint_value != 0);
115 const uint32_t idx = ePropertyClangModulesCachePath;
116 return GetPropertyAtIndexAs<FileSpec>(idx, {});
120 const uint32_t idx = ePropertyClangModulesCachePath;
125 const uint32_t idx = ePropertyLLDBIndexCachePath;
126 return GetPropertyAtIndexAs<FileSpec>(idx, {});
130 const uint32_t idx = ePropertyLLDBIndexCachePath;
135 const uint32_t idx = ePropertyEnableLLDBIndexCache;
136 return GetPropertyAtIndexAs<bool>(
137 idx, g_modulelist_properties[idx].default_uint_value != 0);
145 const uint32_t idx = ePropertyLLDBIndexCacheMaxByteSize;
146 return GetPropertyAtIndexAs<uint64_t>(
147 idx, g_modulelist_properties[idx].default_uint_value);
151 const uint32_t idx = ePropertyLLDBIndexCacheMaxPercent;
152 return GetPropertyAtIndexAs<uint64_t>(
153 idx, g_modulelist_properties[idx].default_uint_value);
157 const uint32_t idx = ePropertyLLDBIndexCacheExpirationDays;
158 return GetPropertyAtIndexAs<uint64_t>(
159 idx, g_modulelist_properties[idx].default_uint_value);
164 GetPropertyAtIndexAs<FileSpecList>(ePropertySymLinkPaths, {});
166 const bool notify =
false;
182 const uint32_t idx = ePropertyLoadSymbolOnDemand;
183 return GetPropertyAtIndexAs<bool>(
184 idx, g_modulelist_properties[idx].default_uint_value != 0);
196 : m_modules(), m_modules_mutex(), m_notifier(notifier) {}
226 const ModuleSP &module_sp,
233 ModuleSpec equivalent_module_spec(module_sp->GetFileSpec(),
234 module_sp->GetArchitecture());
236 module_sp->GetPlatformFileSpec();
241 if (test_module_sp->MatchesModuleSpec(equivalent_module_spec)) {
243 old_modules->push_back(test_module_sp);
257 for (
const ModuleSP &module_sp :
m_modules) {
258 if (module_sp.get() == new_module.get())
262 Append(new_module, notify);
285 collection::iterator pos, end =
m_modules.end();
286 for (pos =
m_modules.begin(); pos != end; ++pos) {
287 if (pos->get() == module_sp.get()) {
298ModuleList::collection::iterator
301 ModuleSP module_sp(*pos);
302 collection::iterator retval =
m_modules.erase(pos);
313 const lldb::ModuleSP &new_module_sp) {
325 collection::iterator pos, end =
m_modules.end();
326 for (pos =
m_modules.begin(); pos != end; ++pos) {
327 if (pos->get() == module_ptr) {
340 std::unique_lock<std::recursive_mutex> lock(
m_modules_mutex, std::defer_lock);
346 if (!lock.try_lock())
349 size_t remove_count = 0;
353 bool made_progress =
true;
354 while (made_progress) {
356 made_progress =
false;
357 collection::iterator pos =
m_modules.begin();
363 made_progress =
true;
374 size_t num_removed = 0;
375 collection::iterator pos, end = module_list.
m_modules.end();
376 for (pos = module_list.
m_modules.begin(); pos != end; ++pos) {
416 FunctionNameType name_type_mask,
419 const size_t old_size = sc_list.
GetSize();
421 if (name_type_mask & eFunctionNameTypeAuto) {
425 for (
const ModuleSP &module_sp :
m_modules) {
430 const size_t new_size = sc_list.
GetSize();
432 if (old_size < new_size)
433 lookup_info.Prune(sc_list, old_size);
436 for (
const ModuleSP &module_sp :
m_modules) {
444 lldb::FunctionNameType name_type_mask,
446 const size_t old_size = sc_list.
GetSize();
448 if (name_type_mask & eFunctionNameTypeAuto) {
452 for (
const ModuleSP &module_sp :
m_modules) {
457 const size_t new_size = sc_list.
GetSize();
459 if (old_size < new_size)
460 lookup_info.
Prune(sc_list, old_size);
463 for (
const ModuleSP &module_sp :
m_modules) {
464 module_sp->FindFunctionSymbols(name, name_type_mask, sc_list);
473 for (
const ModuleSP &module_sp :
m_modules)
474 module_sp->FindFunctions(name, options, sc_list);
480 for (
const ModuleSP &module_sp :
m_modules)
481 module_sp->FindCompileUnits(path, sc_list);
487 for (
const ModuleSP &module_sp :
m_modules) {
497 for (
const ModuleSP &module_sp :
m_modules)
498 module_sp->FindGlobalVariables(regex, max_matches, variable_list);
505 for (
const ModuleSP &module_sp :
m_modules)
506 module_sp->FindSymbolsWithNameAndType(name, symbol_type, sc_list);
513 for (
const ModuleSP &module_sp :
m_modules)
514 module_sp->FindSymbolsMatchingRegExAndType(regex, symbol_type, sc_list);
520 for (
const ModuleSP &module_sp :
m_modules) {
521 if (module_sp->MatchesModuleSpec(module_spec))
522 matching_module_list.
Append(module_sp);
532 collection::const_iterator pos, end =
m_modules.end();
534 for (pos =
m_modules.begin(); pos != end; ++pos) {
535 if ((*pos).get() == module_ptr) {
549 collection::const_iterator pos, end =
m_modules.end();
551 for (pos =
m_modules.begin(); pos != end; ++pos) {
552 if ((*pos)->GetUUID() == uuid) {
562 bool name_is_fully_qualified,
size_t max_matches,
563 llvm::DenseSet<SymbolFile *> &searched_symbol_files,
567 collection::const_iterator pos, end =
m_modules.end();
569 for (pos =
m_modules.begin(); pos != end; ++pos) {
570 if (search_first == pos->get()) {
571 search_first->
FindTypes(name, name_is_fully_qualified, max_matches,
572 searched_symbol_files, types);
574 if (types.
GetSize() >= max_matches)
580 for (pos =
m_modules.begin(); pos != end; ++pos) {
584 if (search_first != pos->get())
585 (*pos)->FindTypes(name, name_is_fully_qualified, max_matches,
586 searched_symbol_files, types);
588 if (types.
GetSize() >= max_matches)
596 for (
const ModuleSP &module_sp :
m_modules) {
597 if (module_sp->FindSourceFile(orig_spec, new_spec))
606 std::vector<Address> &output_local,
607 std::vector<Address> &output_extern) {
609 for (
const ModuleSP &module_sp :
m_modules) {
610 module_sp->FindAddressesForLine(target_sp, file, line, function,
611 output_local, output_extern);
618 collection::const_iterator pos, end =
m_modules.end();
619 for (pos =
m_modules.begin(); pos != end; ++pos) {
620 ModuleSP module_sp(*pos);
621 if (module_sp->MatchesModuleSpec(module_spec))
638 for (
const ModuleSP &module_sp :
m_modules)
643 if (log !=
nullptr) {
645 collection::const_iterator pos, begin =
m_modules.begin(),
647 for (pos = begin; pos != end; ++pos) {
648 Module *module = pos->get();
650 LLDB_LOGF(log,
"%s[%u] %s (%s) \"%s\"", prefix_cstr ? prefix_cstr :
"",
651 (
uint32_t)std::distance(begin, pos),
654 module_file_spec.
GetPath().c_str());
662 for (
const ModuleSP &module_sp :
m_modules) {
663 if (module_sp->ResolveFileAddress(vm_addr, so_addr))
672 SymbolContextItem resolve_scope,
679 module_sp->ResolveSymbolContextForAddress(so_addr, resolve_scope, sc);
682 collection::const_iterator pos, end =
m_modules.end();
683 for (pos =
m_modules.begin(); pos != end; ++pos) {
685 (*pos)->ResolveSymbolContextForAddress(so_addr, resolve_scope, sc);
686 if (resolved_flags != 0)
691 return resolved_flags;
695 const char *file_path,
uint32_t line,
bool check_inlines,
699 resolve_scope, sc_list);
706 for (
const ModuleSP &module_sp :
m_modules) {
707 module_sp->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
708 resolve_scope, sc_list);
717 collection::const_iterator pos;
718 collection::const_iterator begin =
m_modules.begin();
719 collection::const_iterator end =
m_modules.end();
720 for (pos = begin; pos != end; ++pos) {
721 if ((*pos).get() == module)
722 return std::distance(begin, pos);
729struct SharedModuleListInfo {
736 static SharedModuleListInfo *g_shared_module_list_info =
nullptr;
737 static llvm::once_flag g_once_flag;
738 llvm::call_once(g_once_flag, []() {
742 if (g_shared_module_list_info ==
nullptr)
743 g_shared_module_list_info =
new SharedModuleListInfo();
745 return *g_shared_module_list_info;
759 return shared_module_list.
FindModule(module_ptr).get() !=
nullptr;
781 bool *did_create_ptr,
bool always_create) {
783 std::lock_guard<std::recursive_mutex> guard(
792 *did_create_ptr =
false;
801 if (!always_create) {
803 shared_module_list.
FindModules(module_spec, matching_module_list);
804 const size_t num_matching_modules = matching_module_list.
GetSize();
806 if (num_matching_modules > 0) {
807 for (
size_t module_idx = 0; module_idx < num_matching_modules;
812 if (module_sp->FileHasChanged()) {
814 old_modules->push_back(module_sp);
819 log,
"%p '%s' module changed: removing from global module list",
820 static_cast<void *
>(module_sp.get()),
821 module_sp->GetFileSpec().GetFilename().GetCString());
823 shared_module_list.
Remove(module_sp);
837 module_sp = std::make_shared<Module>(module_spec);
841 if (module_sp->GetObjectFile()) {
844 if (uuid_ptr && *uuid_ptr != module_sp->GetUUID()) {
847 if (module_sp->GetObjectFile() &&
848 module_sp->GetObjectFile()->GetType() ==
852 if (did_create_ptr) {
853 *did_create_ptr =
true;
864 if (module_search_paths_ptr) {
865 const auto num_directories = module_search_paths_ptr->
GetSize();
866 for (
size_t idx = 0; idx < num_directories; ++idx) {
869 namespace fs = llvm::sys::fs;
872 search_path_spec.AppendPathComponent(
877 auto resolved_module_spec(module_spec);
878 resolved_module_spec.GetFileSpec() = search_path_spec;
879 module_sp = std::make_shared<Module>(resolved_module_spec);
880 if (module_sp->GetObjectFile()) {
883 if (uuid_ptr && *uuid_ptr != module_sp->GetUUID()) {
886 if (module_sp->GetObjectFile()->GetType() ==
891 *did_create_ptr =
true;
914 if (located_binary_modulespec.
GetFileSpec() != module_file_spec) {
919 module_file_spec.
GetPath(path,
sizeof(path));
924 std::string uuid_str;
925 if (uuid_ptr && uuid_ptr->
IsValid())
929 if (!uuid_str.empty())
930 error.SetErrorStringWithFormat(
931 "'%s' does not contain the %s architecture and UUID %s", path,
934 error.SetErrorStringWithFormat(
935 "'%s' does not contain the %s architecture.", path,
939 error.SetErrorStringWithFormat(
"'%s' does not exist", path);
957 shared_module_list.
FindModules(platform_module_spec, matching_module_list);
958 if (!matching_module_list.
IsEmpty()) {
963 if (platform_module_spec.
GetUUIDPtr() ==
nullptr) {
966 if (file_spec_mod_time != llvm::sys::TimePoint<>()) {
967 if (file_spec_mod_time != module_sp->GetModificationTime()) {
969 old_modules->push_back(module_sp);
970 shared_module_list.
Remove(module_sp);
978 module_sp = std::make_shared<Module>(platform_module_spec);
983 if (module_sp && module_sp->GetObjectFile()) {
984 if (module_sp->GetObjectFile()->GetType() ==
989 *did_create_ptr =
true;
998 error.SetErrorStringWithFormat(
999 "unable to open %s architecture in '%s'",
1002 error.SetErrorStringWithFormat(
"unable to open '%s'", path);
1004 std::string uuid_str;
1005 if (uuid_ptr && uuid_ptr->
IsValid())
1008 if (!uuid_str.empty())
1009 error.SetErrorStringWithFormat(
1010 "cannot locate a module for UUID '%s'", uuid_str.c_str());
1012 error.SetErrorString(
"cannot locate a module");
1030 std::list<Status> &errors,
1032 bool continue_on_error) {
1039 if (!module->LoadScriptingResourceInTarget(target,
error,
1042 error.SetErrorStringWithFormat(
"unable to load scripting data for "
1043 "module %s - error reported was %s",
1044 module->GetFileSpec()
1045 .GetFileNameStrippingExtension()
1048 errors.push_back(
error);
1050 if (!continue_on_error)
1056 return errors.empty();
1060 std::function<
bool(
const ModuleSP &module_sp)>
const &callback)
const {
1062 for (
const auto &module_sp :
m_modules) {
1063 assert(module_sp !=
nullptr);
1065 if (!callback(module_sp))
1074 for (
const auto &module_sp :
m_modules) {
1075 assert(module_sp !=
nullptr);
1076 if (callback(*module_sp))
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOGF(log,...)
static SharedModuleListInfo & GetSharedModuleListInfo()
static ModuleList & GetSharedModuleList()
A section + offset based address class.
lldb::ModuleSP GetModule() const
Get accessor for the module for this address.
An architecture specification class.
bool IsValid() const
Tests if this ArchSpec is valid.
const char * GetArchitectureName() const
Returns a static string representing the current architecture.
Represents a generic declaration context in a program.
A uniqued constant string class.
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
const FileSpec & GetFileSpecAtIndex(size_t idx) const
Get file at index.
size_t GetSize() const
Get the number of files in the file list.
const ConstString & GetFilename() const
Filename string const get accessor.
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
void Resolve(llvm::SmallVectorImpl< char > &path)
Resolve path to make it canonical.
llvm::sys::TimePoint GetModificationTime(const FileSpec &file_spec) const
Returns the modification time of the given file.
Status Readlink(const FileSpec &src, FileSpec &dst)
static FileSystem & Instance()
A class that describes a function.
bool SetClangModulesCachePath(const FileSpec &path)
bool GetEnableExternalLookup() const
bool SetLLDBIndexCachePath(const FileSpec &path)
bool GetEnableLLDBIndexCache() const
bool SetEnableExternalLookup(bool new_value)
FileSpec GetLLDBIndexCachePath() const
PathMappingList GetSymlinkMappings() const
uint64_t GetLLDBIndexCacheMaxByteSize()
PathMappingList m_symlink_paths
bool GetLoadSymbolOnDemand()
FileSpec GetClangModulesCachePath() const
llvm::sys::RWMutex m_symlink_paths_mutex
bool GetEnableBackgroundLookup() const
uint64_t GetLLDBIndexCacheMaxPercent()
void UpdateSymlinkMappings()
bool SetEnableLLDBIndexCache(bool new_value)
uint64_t GetLLDBIndexCacheExpirationDays()
virtual void NotifyModuleAdded(const ModuleList &module_list, const lldb::ModuleSP &module_sp)=0
virtual void NotifyModuleUpdated(const ModuleList &module_list, const lldb::ModuleSP &old_module_sp, const lldb::ModuleSP &new_module_sp)=0
virtual void NotifyModuleRemoved(const ModuleList &module_list, const lldb::ModuleSP &module_sp)=0
virtual void NotifyWillClearList(const ModuleList &module_list)=0
virtual void NotifyModulesRemoved(lldb_private::ModuleList &module_list)=0
A collection class for Module objects.
bool ReplaceModule(const lldb::ModuleSP &old_module_sp, const lldb::ModuleSP &new_module_sp)
collection m_modules
The collection of modules.
void ClearImpl(bool use_notifier=true)
void FindTypes(Module *search_first, ConstString name, bool name_is_fully_qualified, size_t max_matches, llvm::DenseSet< SymbolFile * > &searched_symbol_files, TypeList &types) const
Find types by name.
bool RemoveImpl(const lldb::ModuleSP &module_sp, bool use_notifier=true)
void ForEach(std::function< bool(const lldb::ModuleSP &module_sp)> const &callback) const
Applies 'callback' to each module in this ModuleList.
uint32_t ResolveSymbolContextsForFileSpec(const FileSpec &file_spec, uint32_t line, bool check_inlines, lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) const
Resolve items in the symbol context for a given file and line. (const FileSpec&,...
static bool RemoveSharedModule(lldb::ModuleSP &module_sp)
void FindFunctions(ConstString name, lldb::FunctionNameType name_type_mask, const ModuleFunctionSearchOptions &options, SymbolContextList &sc_list) const
bool FindSourceFile(const FileSpec &orig_spec, FileSpec &new_spec) const
bool AnyOf(std::function< bool(lldb_private::Module &module)> const &callback) const
Returns true if 'callback' returns true for one of the modules in this ModuleList.
static bool ModuleIsInCache(const Module *module_ptr)
void FindGlobalVariables(ConstString name, size_t max_matches, VariableList &variable_list) const
Find global and static variables by name.
size_t GetIndexForModule(const Module *module) const
lldb::ModuleSP FindFirstModule(const ModuleSpec &module_spec) const
void Clear()
Clear the object's state.
bool Remove(const lldb::ModuleSP &module_sp, bool notify=true)
Remove a module from the module list.
ModuleList()
Default constructor.
void Dump(Stream *s) const
Dump the description of each module contained in this list.
bool LoadScriptingResourcesInTarget(Target *target, std::list< Status > &errors, Stream *feedback_stream=nullptr, bool continue_on_error=true)
uint32_t ResolveSymbolContextForFilePath(const char *file_path, uint32_t line, bool check_inlines, lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) const
Resolve items in the symbol context for a given file and line. (const char*,uint32_t,...
static bool RemoveSharedModuleIfOrphaned(const Module *module_ptr)
lldb::ModuleSP GetModuleAtIndexUnlocked(size_t idx) const
Get the module shared pointer for the module at index idx without acquiring the ModuleList mutex.
void FindCompileUnits(const FileSpec &path, SymbolContextList &sc_list) const
Find compile units by partial or full path.
const ModuleList & operator=(const ModuleList &rhs)
Assignment operator.
std::recursive_mutex m_modules_mutex
static Status GetSharedModule(const ModuleSpec &module_spec, lldb::ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr, llvm::SmallVectorImpl< lldb::ModuleSP > *old_modules, bool *did_create_ptr, bool always_create=false)
Module * GetModulePointerAtIndex(size_t idx) const
Get the module pointer for the module at index idx.
void FindSymbolsWithNameAndType(ConstString name, lldb::SymbolType symbol_type, SymbolContextList &sc_list) const
static lldb::ModuleSP FindSharedModule(const UUID &uuid)
lldb::ModuleSP FindModule(const Module *module_ptr) const
static ModuleListProperties & GetGlobalModuleListProperties()
void FindModules(const ModuleSpec &module_spec, ModuleList &matching_module_list) const
Finds the first module whose file specification matches file_spec.
void FindAddressesForLine(const lldb::TargetSP target_sp, const FileSpec &file, uint32_t line, Function *function, std::vector< Address > &output_local, std::vector< Address > &output_extern)
Find addresses by file/line.
uint32_t ResolveSymbolContextForAddress(const Address &so_addr, lldb::SymbolContextItem resolve_scope, SymbolContext &sc) const
Resolve the symbol context for the given address. (const Address&,uint32_t,SymbolContext&)
size_t RemoveOrphans(bool mandatory)
void Append(const lldb::ModuleSP &module_sp, bool notify=true)
Append a module to the module list.
lldb::ModuleSP GetModuleAtIndex(size_t idx) const
Get the module shared pointer for the module at index idx.
bool AppendIfNeeded(const lldb::ModuleSP &new_module, bool notify=true)
Append a module to the module list, if it is not already there.
static size_t RemoveOrphanSharedModules(bool mandatory)
void Destroy()
Clear the object's state.
bool RemoveIfOrphaned(const Module *module_ptr)
void AppendImpl(const lldb::ModuleSP &module_sp, bool use_notifier=true)
void ReplaceEquivalent(const lldb::ModuleSP &module_sp, llvm::SmallVectorImpl< lldb::ModuleSP > *old_modules=nullptr)
Append a module to the module list and remove any equivalent modules.
void FindFunctionSymbols(ConstString name, lldb::FunctionNameType name_type_mask, SymbolContextList &sc_list)
static void FindSharedModules(const ModuleSpec &module_spec, ModuleList &matching_module_list)
void FindSymbolsMatchingRegExAndType(const RegularExpression ®ex, lldb::SymbolType symbol_type, SymbolContextList &sc_list) const
bool ResolveFileAddress(lldb::addr_t vm_addr, Address &so_addr) const
size_t GetSize() const
Gets the size of the module list.
void LogUUIDAndPaths(Log *log, const char *prefix_cstr)
FileSpec & GetPlatformFileSpec()
ArchSpec & GetArchitecture()
FileSpec & GetSymbolFileSpec()
A class that encapsulates name lookup information.
lldb::FunctionNameType GetNameTypeMask() const
ConstString GetLookupName() const
void Prune(SymbolContextList &sc_list, size_t start_idx) const
A class that describes an executable image and its associated object and symbol files.
const lldb_private::UUID & GetUUID()
Get a reference to the UUID value contained in this object.
void FindTypes(ConstString type_name, bool exact_match, size_t max_matches, llvm::DenseSet< lldb_private::SymbolFile * > &searched_symbol_files, TypeList &types)
Find types by name.
const ArchSpec & GetArchitecture() const
Get const accessor for the module architecture.
const FileSpec & GetFileSpec() const
Get const accessor for the module file specification.
@ eTypeStubLibrary
A library that can be linked against but not used for execution.
void Append(llvm::StringRef path, llvm::StringRef replacement, bool notify)
lldb::OptionValuePropertiesSP m_collection_sp
bool SetPropertyAtIndex(uint32_t idx, T t, const ExecutionContext *exe_ctx=nullptr) const
bool Success() const
Test for success condition.
A stream class that can stream formatted output to a file.
Defines a list of symbol context objects.
uint32_t GetSize() const
Get accessor for a symbol context list size.
Defines a symbol context baton that can be handed other debug core functions.
Provides public interface for all SymbolFiles.
static ModuleSpec LocateExecutableObjectFile(const ModuleSpec &module_spec)
std::string GetAsString(llvm::StringRef separator="-") const
#define LLDB_INVALID_INDEX32
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
@ eLanguageTypeUnknown
Unknown or invalid language value.
Options used by Module::FindFunctions.