diff options
Diffstat (limited to 'source/Core/SearchFilter.cpp')
-rw-r--r-- | source/Core/SearchFilter.cpp | 816 |
1 files changed, 816 insertions, 0 deletions
diff --git a/source/Core/SearchFilter.cpp b/source/Core/SearchFilter.cpp new file mode 100644 index 000000000000..54937c0afeca --- /dev/null +++ b/source/Core/SearchFilter.cpp @@ -0,0 +1,816 @@ +//===-- SearchFilter.cpp ----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes + +#include "lldb/lldb-private.h" +#include "lldb/Core/SearchFilter.h" +#include "lldb/Core/Module.h" +#include "lldb/Symbol/CompileUnit.h" +#include "lldb/Target/Target.h" + +using namespace lldb; +using namespace lldb_private; + +//---------------------------------------------------------------------- +// SearchFilter constructor +//---------------------------------------------------------------------- +Searcher::Searcher () +{ + +} + +Searcher::~Searcher () +{ + +} + +void +Searcher::GetDescription (Stream *s) +{ +} + +//---------------------------------------------------------------------- +// SearchFilter constructor +//---------------------------------------------------------------------- +SearchFilter::SearchFilter(const TargetSP &target_sp) : + m_target_sp (target_sp) +{ +} + +//---------------------------------------------------------------------- +// SearchFilter copy constructor +//---------------------------------------------------------------------- +SearchFilter::SearchFilter(const SearchFilter& rhs) : + m_target_sp (rhs.m_target_sp) +{ +} + +//---------------------------------------------------------------------- +// SearchFilter assignment operator +//---------------------------------------------------------------------- +const SearchFilter& +SearchFilter::operator=(const SearchFilter& rhs) +{ + m_target_sp = rhs.m_target_sp; + return *this; +} + +//---------------------------------------------------------------------- +// Destructor +//---------------------------------------------------------------------- +SearchFilter::~SearchFilter() +{ +} + +bool +SearchFilter::ModulePasses (const FileSpec &spec) +{ + return true; +} + +bool +SearchFilter::ModulePasses (const ModuleSP &module_sp) +{ + return true; +} + +bool +SearchFilter::AddressPasses (Address &address) +{ + return true; +} + +bool +SearchFilter::CompUnitPasses (FileSpec &fileSpec) +{ + return true; +} + +bool +SearchFilter::CompUnitPasses (CompileUnit &compUnit) +{ + return true; +} + +uint32_t +SearchFilter::GetFilterRequiredItems() +{ + return (lldb::SymbolContextItem) 0; +} + +void +SearchFilter::GetDescription (Stream *s) +{ +} + +void +SearchFilter::Dump (Stream *s) const +{ + +} + +//---------------------------------------------------------------------- +// UTILITY Functions to help iterate down through the elements of the +// SymbolContext. +//---------------------------------------------------------------------- + +void +SearchFilter::Search (Searcher &searcher) +{ + SymbolContext empty_sc; + + if (!m_target_sp) + return; + empty_sc.target_sp = m_target_sp; + + if (searcher.GetDepth() == Searcher::eDepthTarget) + searcher.SearchCallback (*this, empty_sc, NULL, false); + else + DoModuleIteration(empty_sc, searcher); +} + +void +SearchFilter::SearchInModuleList (Searcher &searcher, ModuleList &modules) +{ + SymbolContext empty_sc; + + if (!m_target_sp) + return; + empty_sc.target_sp = m_target_sp; + + if (searcher.GetDepth() == Searcher::eDepthTarget) + searcher.SearchCallback (*this, empty_sc, NULL, false); + else + { + Mutex::Locker modules_locker(modules.GetMutex()); + const size_t numModules = modules.GetSize(); + + for (size_t i = 0; i < numModules; i++) + { + ModuleSP module_sp(modules.GetModuleAtIndexUnlocked(i)); + if (ModulePasses(module_sp)) + { + if (DoModuleIteration(module_sp, searcher) == Searcher::eCallbackReturnStop) + return; + } + } + } +} + + +Searcher::CallbackReturn +SearchFilter::DoModuleIteration (const lldb::ModuleSP& module_sp, Searcher &searcher) +{ + SymbolContext matchingContext (m_target_sp, module_sp); + return DoModuleIteration(matchingContext, searcher); +} + +Searcher::CallbackReturn +SearchFilter::DoModuleIteration (const SymbolContext &context, Searcher &searcher) +{ + if (searcher.GetDepth () >= Searcher::eDepthModule) + { + if (context.module_sp) + { + if (searcher.GetDepth () == Searcher::eDepthModule) + { + SymbolContext matchingContext(context.module_sp.get()); + searcher.SearchCallback (*this, matchingContext, NULL, false); + } + else + { + return DoCUIteration(context.module_sp, context, searcher); + } + } + else + { + const ModuleList &target_images = m_target_sp->GetImages(); + Mutex::Locker modules_locker(target_images.GetMutex()); + + size_t n_modules = target_images.GetSize(); + for (size_t i = 0; i < n_modules; i++) + { + // If this is the last level supplied, then call the callback directly, + // otherwise descend. + ModuleSP module_sp(target_images.GetModuleAtIndexUnlocked (i)); + if (!ModulePasses (module_sp)) + continue; + + if (searcher.GetDepth () == Searcher::eDepthModule) + { + SymbolContext matchingContext(m_target_sp, module_sp); + + Searcher::CallbackReturn shouldContinue = searcher.SearchCallback (*this, matchingContext, NULL, false); + if (shouldContinue == Searcher::eCallbackReturnStop + || shouldContinue == Searcher::eCallbackReturnPop) + return shouldContinue; + } + else + { + Searcher::CallbackReturn shouldContinue = DoCUIteration(module_sp, context, searcher); + if (shouldContinue == Searcher::eCallbackReturnStop) + return shouldContinue; + else if (shouldContinue == Searcher::eCallbackReturnPop) + continue; + } + } + } + } + return Searcher::eCallbackReturnContinue; +} + +Searcher::CallbackReturn +SearchFilter::DoCUIteration (const ModuleSP &module_sp, const SymbolContext &context, Searcher &searcher) +{ + Searcher::CallbackReturn shouldContinue; + if (context.comp_unit == NULL) + { + const size_t num_comp_units = module_sp->GetNumCompileUnits(); + for (size_t i = 0; i < num_comp_units; i++) + { + CompUnitSP cu_sp (module_sp->GetCompileUnitAtIndex (i)); + if (cu_sp) + { + if (!CompUnitPasses (*(cu_sp.get()))) + continue; + + if (searcher.GetDepth () == Searcher::eDepthCompUnit) + { + SymbolContext matchingContext(m_target_sp, module_sp, cu_sp.get()); + + shouldContinue = searcher.SearchCallback (*this, matchingContext, NULL, false); + + if (shouldContinue == Searcher::eCallbackReturnPop) + return Searcher::eCallbackReturnContinue; + else if (shouldContinue == Searcher::eCallbackReturnStop) + return shouldContinue; + } + else + { + // FIXME Descend to block. + } + } + } + } + else + { + if (CompUnitPasses(*context.comp_unit)) + { + SymbolContext matchingContext (m_target_sp, module_sp, context.comp_unit); + return searcher.SearchCallback (*this, matchingContext, NULL, false); + } + } + return Searcher::eCallbackReturnContinue; +} + +Searcher::CallbackReturn +SearchFilter::DoFunctionIteration (Function *function, const SymbolContext &context, Searcher &searcher) +{ + // FIXME: Implement... + return Searcher::eCallbackReturnContinue; +} + +//---------------------------------------------------------------------- +// SearchFilterForNonModuleSpecificSearches: +// Selects a shared library matching a given file spec, consulting the targets "black list". +//---------------------------------------------------------------------- + + bool + SearchFilterForNonModuleSpecificSearches::ModulePasses (const FileSpec &module_spec) + { + if (m_target_sp->ModuleIsExcludedForNonModuleSpecificSearches (module_spec)) + return false; + else + return true; + } + + bool + SearchFilterForNonModuleSpecificSearches::ModulePasses (const lldb::ModuleSP &module_sp) + { + if (!module_sp) + return true; + else if (m_target_sp->ModuleIsExcludedForNonModuleSpecificSearches (module_sp)) + return false; + else + return true; + } + +//---------------------------------------------------------------------- +// SearchFilterByModule: +// Selects a shared library matching a given file spec +//---------------------------------------------------------------------- + +//---------------------------------------------------------------------- +// SearchFilterByModule constructors +//---------------------------------------------------------------------- + +SearchFilterByModule::SearchFilterByModule (const lldb::TargetSP &target_sp, const FileSpec &module) : + SearchFilter (target_sp), + m_module_spec (module) +{ +} + + +//---------------------------------------------------------------------- +// SearchFilterByModule copy constructor +//---------------------------------------------------------------------- +SearchFilterByModule::SearchFilterByModule(const SearchFilterByModule& rhs) : + SearchFilter (rhs), + m_module_spec (rhs.m_module_spec) +{ +} + +//---------------------------------------------------------------------- +// SearchFilterByModule assignment operator +//---------------------------------------------------------------------- +const SearchFilterByModule& +SearchFilterByModule::operator=(const SearchFilterByModule& rhs) +{ + m_target_sp = rhs.m_target_sp; + m_module_spec = rhs.m_module_spec; + return *this; +} + +//---------------------------------------------------------------------- +// Destructor +//---------------------------------------------------------------------- +SearchFilterByModule::~SearchFilterByModule() +{ +} + +bool +SearchFilterByModule::ModulePasses (const ModuleSP &module_sp) +{ + if (module_sp && FileSpec::Equal(module_sp->GetFileSpec(), m_module_spec, false)) + return true; + else + return false; +} + +bool +SearchFilterByModule::ModulePasses (const FileSpec &spec) +{ + // Do a full match only if "spec" has a directory + const bool full_match = spec.GetDirectory(); + return FileSpec::Equal(spec, m_module_spec, full_match); +} + +bool +SearchFilterByModule::AddressPasses (Address &address) +{ + // FIXME: Not yet implemented + return true; +} + + +bool +SearchFilterByModule::CompUnitPasses (FileSpec &fileSpec) +{ + return true; +} + +bool +SearchFilterByModule::CompUnitPasses (CompileUnit &compUnit) +{ + return true; +} + +void +SearchFilterByModule::Search (Searcher &searcher) +{ + if (!m_target_sp) + return; + + if (searcher.GetDepth() == Searcher::eDepthTarget) + { + SymbolContext empty_sc; + empty_sc.target_sp = m_target_sp; + searcher.SearchCallback (*this, empty_sc, NULL, false); + } + + // If the module file spec is a full path, then we can just find the one + // filespec that passes. Otherwise, we need to go through all modules and + // find the ones that match the file name. + + const ModuleList &target_modules = m_target_sp->GetImages(); + Mutex::Locker modules_locker (target_modules.GetMutex()); + + const size_t num_modules = target_modules.GetSize (); + for (size_t i = 0; i < num_modules; i++) + { + Module* module = target_modules.GetModulePointerAtIndexUnlocked(i); + const bool full_match = m_module_spec.GetDirectory(); + if (FileSpec::Equal (m_module_spec, module->GetFileSpec(), full_match)) + { + SymbolContext matchingContext(m_target_sp, module->shared_from_this()); + Searcher::CallbackReturn shouldContinue; + + shouldContinue = DoModuleIteration(matchingContext, searcher); + if (shouldContinue == Searcher::eCallbackReturnStop) + return; + } + } +} + +void +SearchFilterByModule::GetDescription (Stream *s) +{ + s->PutCString(", module = "); + if (s->GetVerbose()) + { + char buffer[2048]; + m_module_spec.GetPath(buffer, 2047); + s->PutCString(buffer); + } + else + { + s->PutCString(m_module_spec.GetFilename().AsCString("<unknown>")); + } +} + +uint32_t +SearchFilterByModule::GetFilterRequiredItems() +{ + return eSymbolContextModule; +} + +void +SearchFilterByModule::Dump (Stream *s) const +{ + +} +//---------------------------------------------------------------------- +// SearchFilterByModuleList: +// Selects a shared library matching a given file spec +//---------------------------------------------------------------------- + +//---------------------------------------------------------------------- +// SearchFilterByModuleList constructors +//---------------------------------------------------------------------- + +SearchFilterByModuleList::SearchFilterByModuleList (const lldb::TargetSP &target_sp, const FileSpecList &module_list) : + SearchFilter (target_sp), + m_module_spec_list (module_list) +{ +} + + +//---------------------------------------------------------------------- +// SearchFilterByModuleList copy constructor +//---------------------------------------------------------------------- +SearchFilterByModuleList::SearchFilterByModuleList(const SearchFilterByModuleList& rhs) : + SearchFilter (rhs), + m_module_spec_list (rhs.m_module_spec_list) +{ +} + +//---------------------------------------------------------------------- +// SearchFilterByModuleList assignment operator +//---------------------------------------------------------------------- +const SearchFilterByModuleList& +SearchFilterByModuleList::operator=(const SearchFilterByModuleList& rhs) +{ + m_target_sp = rhs.m_target_sp; + m_module_spec_list = rhs.m_module_spec_list; + return *this; +} + +//---------------------------------------------------------------------- +// Destructor +//---------------------------------------------------------------------- +SearchFilterByModuleList::~SearchFilterByModuleList() +{ +} + +bool +SearchFilterByModuleList::ModulePasses (const ModuleSP &module_sp) +{ + if (m_module_spec_list.GetSize() == 0) + return true; + + if (module_sp && m_module_spec_list.FindFileIndex(0, module_sp->GetFileSpec(), false) != UINT32_MAX) + return true; + else + return false; +} + +bool +SearchFilterByModuleList::ModulePasses (const FileSpec &spec) +{ + if (m_module_spec_list.GetSize() == 0) + return true; + + if (m_module_spec_list.FindFileIndex(0, spec, true) != UINT32_MAX) + return true; + else + return false; +} + +bool +SearchFilterByModuleList::AddressPasses (Address &address) +{ + // FIXME: Not yet implemented + return true; +} + + +bool +SearchFilterByModuleList::CompUnitPasses (FileSpec &fileSpec) +{ + return true; +} + +bool +SearchFilterByModuleList::CompUnitPasses (CompileUnit &compUnit) +{ + return true; +} + +void +SearchFilterByModuleList::Search (Searcher &searcher) +{ + if (!m_target_sp) + return; + + if (searcher.GetDepth() == Searcher::eDepthTarget) + { + SymbolContext empty_sc; + empty_sc.target_sp = m_target_sp; + searcher.SearchCallback (*this, empty_sc, NULL, false); + } + + // If the module file spec is a full path, then we can just find the one + // filespec that passes. Otherwise, we need to go through all modules and + // find the ones that match the file name. + + const ModuleList &target_modules = m_target_sp->GetImages(); + Mutex::Locker modules_locker (target_modules.GetMutex()); + + const size_t num_modules = target_modules.GetSize (); + for (size_t i = 0; i < num_modules; i++) + { + Module* module = target_modules.GetModulePointerAtIndexUnlocked(i); + if (m_module_spec_list.FindFileIndex(0, module->GetFileSpec(), false) != UINT32_MAX) + { + SymbolContext matchingContext(m_target_sp, module->shared_from_this()); + Searcher::CallbackReturn shouldContinue; + + shouldContinue = DoModuleIteration(matchingContext, searcher); + if (shouldContinue == Searcher::eCallbackReturnStop) + return; + } + } +} + +void +SearchFilterByModuleList::GetDescription (Stream *s) +{ + size_t num_modules = m_module_spec_list.GetSize(); + if (num_modules == 1) + { + s->Printf (", module = "); + if (s->GetVerbose()) + { + char buffer[2048]; + m_module_spec_list.GetFileSpecAtIndex(0).GetPath(buffer, 2047); + s->PutCString(buffer); + } + else + { + s->PutCString(m_module_spec_list.GetFileSpecAtIndex(0).GetFilename().AsCString("<unknown>")); + } + } + else + { + s->Printf (", modules(%zu) = ", num_modules); + for (size_t i = 0; i < num_modules; i++) + { + if (s->GetVerbose()) + { + char buffer[2048]; + m_module_spec_list.GetFileSpecAtIndex(i).GetPath(buffer, 2047); + s->PutCString(buffer); + } + else + { + s->PutCString(m_module_spec_list.GetFileSpecAtIndex(i).GetFilename().AsCString("<unknown>")); + } + if (i != num_modules - 1) + s->PutCString (", "); + } + } +} + +uint32_t +SearchFilterByModuleList::GetFilterRequiredItems() +{ + return eSymbolContextModule; +} + +void +SearchFilterByModuleList::Dump (Stream *s) const +{ + +} + +//---------------------------------------------------------------------- +// SearchFilterByModuleListAndCU: +// Selects a shared library matching a given file spec +//---------------------------------------------------------------------- + +//---------------------------------------------------------------------- +// SearchFilterByModuleListAndCU constructors +//---------------------------------------------------------------------- + +SearchFilterByModuleListAndCU::SearchFilterByModuleListAndCU (const lldb::TargetSP &target_sp, + const FileSpecList &module_list, + const FileSpecList &cu_list) : + SearchFilterByModuleList (target_sp, module_list), + m_cu_spec_list (cu_list) +{ +} + + +//---------------------------------------------------------------------- +// SearchFilterByModuleListAndCU copy constructor +//---------------------------------------------------------------------- +SearchFilterByModuleListAndCU::SearchFilterByModuleListAndCU(const SearchFilterByModuleListAndCU& rhs) : + SearchFilterByModuleList (rhs), + m_cu_spec_list (rhs.m_cu_spec_list) +{ +} + +//---------------------------------------------------------------------- +// SearchFilterByModuleListAndCU assignment operator +//---------------------------------------------------------------------- +const SearchFilterByModuleListAndCU& +SearchFilterByModuleListAndCU::operator=(const SearchFilterByModuleListAndCU& rhs) +{ + if (&rhs != this) + { + m_target_sp = rhs.m_target_sp; + m_module_spec_list = rhs.m_module_spec_list; + m_cu_spec_list = rhs.m_cu_spec_list; + } + return *this; +} + +//---------------------------------------------------------------------- +// Destructor +//---------------------------------------------------------------------- +SearchFilterByModuleListAndCU::~SearchFilterByModuleListAndCU() +{ +} + +bool +SearchFilterByModuleListAndCU::AddressPasses (Address &address) +{ + return true; +} + + +bool +SearchFilterByModuleListAndCU::CompUnitPasses (FileSpec &fileSpec) +{ + return m_cu_spec_list.FindFileIndex(0, fileSpec, false) != UINT32_MAX; +} + +bool +SearchFilterByModuleListAndCU::CompUnitPasses (CompileUnit &compUnit) +{ + bool in_cu_list = m_cu_spec_list.FindFileIndex(0, compUnit, false) != UINT32_MAX; + if (in_cu_list) + { + ModuleSP module_sp(compUnit.GetModule()); + if (module_sp) + { + bool module_passes = SearchFilterByModuleList::ModulePasses(module_sp); + return module_passes; + } + else + return true; + } + else + return false; +} + +void +SearchFilterByModuleListAndCU::Search (Searcher &searcher) +{ + if (!m_target_sp) + return; + + if (searcher.GetDepth() == Searcher::eDepthTarget) + { + SymbolContext empty_sc; + empty_sc.target_sp = m_target_sp; + searcher.SearchCallback (*this, empty_sc, NULL, false); + } + + // If the module file spec is a full path, then we can just find the one + // filespec that passes. Otherwise, we need to go through all modules and + // find the ones that match the file name. + + ModuleList matching_modules; + const ModuleList &target_images = m_target_sp->GetImages(); + Mutex::Locker modules_locker(target_images.GetMutex()); + + const size_t num_modules = target_images.GetSize (); + bool no_modules_in_filter = m_module_spec_list.GetSize() == 0; + for (size_t i = 0; i < num_modules; i++) + { + lldb::ModuleSP module_sp = target_images.GetModuleAtIndexUnlocked(i); + if (no_modules_in_filter || m_module_spec_list.FindFileIndex(0, module_sp->GetFileSpec(), false) != UINT32_MAX) + { + SymbolContext matchingContext(m_target_sp, module_sp); + Searcher::CallbackReturn shouldContinue; + + if (searcher.GetDepth() == Searcher::eDepthModule) + { + shouldContinue = DoModuleIteration(matchingContext, searcher); + if (shouldContinue == Searcher::eCallbackReturnStop) + return; + } + else + { + const size_t num_cu = module_sp->GetNumCompileUnits(); + for (size_t cu_idx = 0; cu_idx < num_cu; cu_idx++) + { + CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(cu_idx); + matchingContext.comp_unit = cu_sp.get(); + if (matchingContext.comp_unit) + { + if (m_cu_spec_list.FindFileIndex(0, *matchingContext.comp_unit, false) != UINT32_MAX) + { + shouldContinue = DoCUIteration(module_sp, matchingContext, searcher); + if (shouldContinue == Searcher::eCallbackReturnStop) + return; + } + } + } + } + } + } +} + +void +SearchFilterByModuleListAndCU::GetDescription (Stream *s) +{ + size_t num_modules = m_module_spec_list.GetSize(); + if (num_modules == 1) + { + s->Printf (", module = "); + if (s->GetVerbose()) + { + char buffer[2048]; + m_module_spec_list.GetFileSpecAtIndex(0).GetPath(buffer, 2047); + s->PutCString(buffer); + } + else + { + s->PutCString(m_module_spec_list.GetFileSpecAtIndex(0).GetFilename().AsCString("<unknown>")); + } + } + else if (num_modules > 0) + { + s->Printf (", modules(%zd) = ", num_modules); + for (size_t i = 0; i < num_modules; i++) + { + if (s->GetVerbose()) + { + char buffer[2048]; + m_module_spec_list.GetFileSpecAtIndex(i).GetPath(buffer, 2047); + s->PutCString(buffer); + } + else + { + s->PutCString(m_module_spec_list.GetFileSpecAtIndex(i).GetFilename().AsCString("<unknown>")); + } + if (i != num_modules - 1) + s->PutCString (", "); + } + } +} + +uint32_t +SearchFilterByModuleListAndCU::GetFilterRequiredItems() +{ + return eSymbolContextModule | eSymbolContextCompUnit; +} + +void +SearchFilterByModuleListAndCU::Dump (Stream *s) const +{ + +} + |