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"
83 llvm::SmallString<128> path;
84 if (clang::driver::Driver::getDefaultModuleCachePath(path)) {
89 if (llvm::sys::path::cache_directory(path)) {
90 llvm::sys::path::append(path,
"lldb");
91 llvm::sys::path::append(path,
"IndexCache");
98 const uint32_t idx = ePropertyEnableExternalLookup;
99 return GetPropertyAtIndexAs<bool>(
100 idx, g_modulelist_properties[idx].default_uint_value != 0);
109 if (GetPropertyAtIndexAs<bool>(ePropertyEnableBackgroundLookup,
false))
112 const uint32_t idx = ePropertyAutoDownload;
113 return GetPropertyAtIndexAs<lldb::SymbolDownload>(
115 g_modulelist_properties[idx].default_uint_value));
119 const uint32_t idx = ePropertyClangModulesCachePath;
120 return GetPropertyAtIndexAs<FileSpec>(idx, {});
124 const uint32_t idx = ePropertyClangModulesCachePath;
129 const uint32_t idx = ePropertyLLDBIndexCachePath;
130 return GetPropertyAtIndexAs<FileSpec>(idx, {});
134 const uint32_t idx = ePropertyLLDBIndexCachePath;
139 const uint32_t idx = ePropertyEnableLLDBIndexCache;
140 return GetPropertyAtIndexAs<bool>(
141 idx, g_modulelist_properties[idx].default_uint_value != 0);
149 const uint32_t idx = ePropertyLLDBIndexCacheMaxByteSize;
150 return GetPropertyAtIndexAs<uint64_t>(
151 idx, g_modulelist_properties[idx].default_uint_value);
155 const uint32_t idx = ePropertyLLDBIndexCacheMaxPercent;
156 return GetPropertyAtIndexAs<uint64_t>(
157 idx, g_modulelist_properties[idx].default_uint_value);
161 const uint32_t idx = ePropertyLLDBIndexCacheExpirationDays;
162 return GetPropertyAtIndexAs<uint64_t>(
163 idx, g_modulelist_properties[idx].default_uint_value);
168 GetPropertyAtIndexAs<FileSpecList>(ePropertySymLinkPaths, {});
170 const bool notify =
false;
172 for (
auto symlink : list) {
186 const uint32_t idx = ePropertyLoadSymbolOnDemand;
187 return GetPropertyAtIndexAs<bool>(
188 idx, g_modulelist_properties[idx].default_uint_value != 0);
200 : m_modules(), m_modules_mutex(), m_notifier(notifier) {}
231 const bool elem_zero_is_executable
232 =
m_modules[0]->GetObjectFile()->GetType()
235 if (!elem_zero_is_executable && obj
259 ModuleSpec equivalent_module_spec(module_sp->GetFileSpec(),
260 module_sp->GetArchitecture());
262 module_sp->GetPlatformFileSpec();
267 if (test_module_sp->MatchesModuleSpec(equivalent_module_spec)) {
269 old_modules->push_back(test_module_sp);
284 if (module_sp.get() == new_module.get())
288 Append(new_module, notify);
311 collection::iterator pos, end =
m_modules.end();
312 for (pos =
m_modules.begin(); pos != end; ++pos) {
313 if (pos->get() == module_sp.get()) {
324ModuleList::collection::iterator
328 collection::iterator retval =
m_modules.erase(pos);
351 collection::iterator pos, end =
m_modules.end();
352 for (pos =
m_modules.begin(); pos != end; ++pos) {
353 if (pos->get() == module_ptr) {
354 if (pos->use_count() == 1) {
366 std::unique_lock<std::recursive_mutex> lock(
m_modules_mutex, std::defer_lock);
372 if (!lock.try_lock())
375 size_t remove_count = 0;
379 bool made_progress =
true;
380 while (made_progress) {
382 made_progress =
false;
383 collection::iterator pos =
m_modules.begin();
385 if (pos->use_count() == 1) {
389 made_progress =
true;
400 size_t num_removed = 0;
401 collection::iterator pos, end = module_list.
m_modules.end();
402 for (pos = module_list.
m_modules.begin(); pos != end; ++pos) {
442 FunctionNameType name_type_mask,
445 const size_t old_size = sc_list.
GetSize();
447 if (name_type_mask & eFunctionNameTypeAuto) {
456 const size_t new_size = sc_list.
GetSize();
458 if (old_size < new_size)
459 lookup_info.Prune(sc_list, old_size);
470 lldb::FunctionNameType name_type_mask,
472 const size_t old_size = sc_list.
GetSize();
474 if (name_type_mask & eFunctionNameTypeAuto) {
483 const size_t new_size = sc_list.
GetSize();
485 if (old_size < new_size)
486 lookup_info.
Prune(sc_list, old_size);
490 module_sp->FindFunctionSymbols(name, name_type_mask, sc_list);
500 module_sp->FindFunctions(name, options, sc_list);
507 module_sp->FindCompileUnits(path, sc_list);
524 module_sp->FindGlobalVariables(regex, max_matches, variable_list);
532 module_sp->FindSymbolsWithNameAndType(name, symbol_type, sc_list);
540 module_sp->FindSymbolsMatchingRegExAndType(regex, symbol_type, sc_list);
547 if (module_sp->MatchesModuleSpec(module_spec))
548 matching_module_list.
Append(module_sp);
558 collection::const_iterator pos, end =
m_modules.end();
560 for (pos =
m_modules.begin(); pos != end; ++pos) {
561 if ((*pos).get() == module_ptr) {
575 collection::const_iterator pos, end =
m_modules.end();
577 for (pos =
m_modules.begin(); pos != end; ++pos) {
578 if ((*pos)->GetUUID() == uuid) {
592 if (results.
Done(query))
595 for (
const auto &module_sp :
m_modules) {
596 if (search_first != module_sp.get()) {
597 module_sp->FindTypes(query, results);
598 if (results.
Done(query))
608 if (module_sp->FindSourceFile(orig_spec, new_spec))
615 const FileSpec &file, uint32_t line,
617 std::vector<Address> &output_local,
618 std::vector<Address> &output_extern) {
621 module_sp->FindAddressesForLine(target_sp, file, line, function,
622 output_local, output_extern);
629 collection::const_iterator pos, end =
m_modules.end();
630 for (pos =
m_modules.begin(); pos != end; ++pos) {
632 if (module_sp->MatchesModuleSpec(module_spec))
654 if (log !=
nullptr) {
656 collection::const_iterator pos, begin =
m_modules.begin(),
658 for (pos = begin; pos != end; ++pos) {
659 Module *module = pos->get();
661 LLDB_LOGF(log,
"%s[%u] %s (%s) \"%s\"", prefix_cstr ? prefix_cstr :
"",
662 (uint32_t)std::distance(begin, pos),
665 module_file_spec.
GetPath().c_str());
674 if (module_sp->ResolveFileAddress(vm_addr, so_addr))
683 SymbolContextItem resolve_scope,
686 uint32_t resolved_flags = 0;
690 module_sp->ResolveSymbolContextForAddress(so_addr, resolve_scope, sc);
693 collection::const_iterator pos, end =
m_modules.end();
694 for (pos =
m_modules.begin(); pos != end; ++pos) {
696 (*pos)->ResolveSymbolContextForAddress(so_addr, resolve_scope, sc);
697 if (resolved_flags != 0)
702 return resolved_flags;
706 const char *file_path, uint32_t line,
bool check_inlines,
710 resolve_scope, sc_list);
714 const FileSpec &file_spec, uint32_t line,
bool check_inlines,
718 module_sp->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
719 resolve_scope, sc_list);
728 collection::const_iterator pos;
729 collection::const_iterator begin =
m_modules.begin();
730 collection::const_iterator end =
m_modules.end();
731 for (pos = begin; pos != end; ++pos) {
732 if ((*pos).get() == module)
733 return std::distance(begin, pos);
740struct SharedModuleListInfo {
747 static SharedModuleListInfo *g_shared_module_list_info =
nullptr;
748 static llvm::once_flag g_once_flag;
749 llvm::call_once(g_once_flag, []() {
753 if (g_shared_module_list_info ==
nullptr)
754 g_shared_module_list_info =
new SharedModuleListInfo();
756 return *g_shared_module_list_info;
770 return shared_module_list.
FindModule(module_ptr).get() !=
nullptr;
792 bool *did_create_ptr,
bool always_create) {
794 std::lock_guard<std::recursive_mutex> guard(
803 *did_create_ptr =
false;
812 if (!always_create) {
814 shared_module_list.
FindModules(module_spec, matching_module_list);
815 const size_t num_matching_modules = matching_module_list.
GetSize();
817 if (num_matching_modules > 0) {
818 for (
size_t module_idx = 0; module_idx < num_matching_modules;
823 if (module_sp->FileHasChanged()) {
825 old_modules->push_back(module_sp);
830 log,
"%p '%s' module changed: removing from global module list",
831 static_cast<void *
>(module_sp.get()),
832 module_sp->GetFileSpec().GetFilename().GetCString());
834 shared_module_list.
Remove(module_sp);
848 module_sp = std::make_shared<Module>(module_spec);
852 if (module_sp->GetObjectFile()) {
855 if (uuid_ptr && *uuid_ptr != module_sp->GetUUID()) {
858 if (module_sp->GetObjectFile() &&
859 module_sp->GetObjectFile()->GetType() ==
863 if (did_create_ptr) {
864 *did_create_ptr =
true;
875 if (module_search_paths_ptr) {
876 const auto num_directories = module_search_paths_ptr->
GetSize();
877 for (
size_t idx = 0; idx < num_directories; ++idx) {
880 namespace fs = llvm::sys::fs;
883 search_path_spec.AppendPathComponent(
888 auto resolved_module_spec(module_spec);
889 resolved_module_spec.GetFileSpec() = search_path_spec;
890 module_sp = std::make_shared<Module>(resolved_module_spec);
891 if (module_sp->GetObjectFile()) {
894 if (uuid_ptr && *uuid_ptr != module_sp->GetUUID()) {
897 if (module_sp->GetObjectFile()->GetType() ==
902 *did_create_ptr =
true;
925 if (located_binary_modulespec.
GetFileSpec() != module_file_spec) {
930 module_file_spec.
GetPath(path,
sizeof(path));
935 std::string uuid_str;
936 if (uuid_ptr && uuid_ptr->
IsValid())
940 if (!uuid_str.empty())
941 error.SetErrorStringWithFormat(
942 "'%s' does not contain the %s architecture and UUID %s", path,
945 error.SetErrorStringWithFormat(
946 "'%s' does not contain the %s architecture.", path,
950 error.SetErrorStringWithFormat(
"'%s' does not exist", path);
968 shared_module_list.
FindModules(platform_module_spec, matching_module_list);
969 if (!matching_module_list.
IsEmpty()) {
974 if (platform_module_spec.
GetUUIDPtr() ==
nullptr) {
977 if (file_spec_mod_time != llvm::sys::TimePoint<>()) {
978 if (file_spec_mod_time != module_sp->GetModificationTime()) {
980 old_modules->push_back(module_sp);
981 shared_module_list.
Remove(module_sp);
989 module_sp = std::make_shared<Module>(platform_module_spec);
994 if (module_sp && module_sp->GetObjectFile()) {
995 if (module_sp->GetObjectFile()->GetType() ==
1000 *did_create_ptr =
true;
1009 error.SetErrorStringWithFormat(
1010 "unable to open %s architecture in '%s'",
1013 error.SetErrorStringWithFormat(
"unable to open '%s'", path);
1015 std::string uuid_str;
1016 if (uuid_ptr && uuid_ptr->
IsValid())
1019 if (!uuid_str.empty())
1020 error.SetErrorStringWithFormat(
1021 "cannot locate a module for UUID '%s'", uuid_str.c_str());
1023 error.SetErrorString(
"cannot locate a module");
1041 std::list<Status> &errors,
1043 bool continue_on_error) {
1050 if (!module->LoadScriptingResourceInTarget(target,
error,
1053 error.SetErrorStringWithFormat(
"unable to load scripting data for "
1054 "module %s - error reported was %s",
1055 module->GetFileSpec()
1056 .GetFileNameStrippingExtension()
1059 errors.push_back(
error);
1061 if (!continue_on_error)
1067 return errors.empty();
1071 std::function<
bool(
const ModuleSP &module_sp)>
const &callback)
const {
1073 for (
const auto &module_sp :
m_modules) {
1074 assert(module_sp !=
nullptr);
1076 if (!callback(module_sp))
1085 for (
const auto &module_sp :
m_modules) {
1086 assert(module_sp !=
nullptr);
1087 if (callback(*module_sp))
1097 std::scoped_lock<std::recursive_mutex, std::recursive_mutex> lock(
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)
lldb::SymbolDownload GetSymbolAutoDownload() const
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
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 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.
void Swap(ModuleList &other)
Atomically swaps the contents of this module list with other.
size_t GetIndexForModule(const Module *module) const
bool RemoveImpl(const lldb::ModuleSP &module_sp, bool use_notifier=true)
lldb::ModuleSP FindFirstModule(const ModuleSpec &module_spec) const
void Clear()
Clear the object's state.
ModuleList()
Default constructor.
void Dump(Stream *s) const
Dump the description of each module contained in this list.
void FindTypes(Module *search_first, const TypeQuery &query, lldb_private::TypeResults &results) const
Find types using a type-matching object that contains all search parameters.
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
bool AppendIfNeeded(const lldb::ModuleSP &new_module, bool notify=true)
Append a module to the module list, if it is not already there.
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&)
bool Remove(const lldb::ModuleSP &module_sp, bool notify=true)
Remove a module from the module list.
size_t RemoveOrphans(bool mandatory)
lldb::ModuleSP GetModuleAtIndex(size_t idx) const
Get the module shared pointer for the module at index idx.
void Append(const lldb::ModuleSP &module_sp, bool notify=true)
Append a module to the module list.
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)
bool LoadScriptingResourcesInTarget(Target *target, std::list< Status > &errors, Stream &feedback_stream, bool continue_on_error=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.
const ArchSpec & GetArchitecture() const
Get const accessor for the module architecture.
const FileSpec & GetFileSpec() const
Get const accessor for the module file specification.
void FindTypes(const TypeQuery &query, TypeResults &results)
Find types using a type-matching object that contains all search parameters.
A plug-in interface definition class for object file parsers.
@ eTypeExecutable
A normal executable.
@ eTypeStubLibrary
A library that can be linked against but not used for execution.
void Append(llvm::StringRef path, llvm::StringRef replacement, bool notify)
static ModuleSpec LocateExecutableObjectFile(const ModuleSpec &module_spec)
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.
A class that contains all state required for type lookups.
This class tracks the state and results of a TypeQuery.
bool Done(const TypeQuery &query) const
Check if the type matching has found all of the matches that it needs.
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.
std::shared_ptr< lldb_private::Target > TargetSP
@ eSymbolDownloadBackground
std::shared_ptr< lldb_private::Module > ModuleSP
Options used by Module::FindFunctions.