diff options
Diffstat (limited to 'lldb/source/Core')
-rw-r--r-- | lldb/source/Core/SearchFilter.cpp | 273 | ||||
-rw-r--r-- | lldb/source/Core/StructuredData.cpp | 42 |
2 files changed, 310 insertions, 5 deletions
diff --git a/lldb/source/Core/SearchFilter.cpp b/lldb/source/Core/SearchFilter.cpp index 5736b11bd23..aa214229f43 100644 --- a/lldb/source/Core/SearchFilter.cpp +++ b/lldb/source/Core/SearchFilter.cpp @@ -21,14 +21,37 @@ using namespace lldb; using namespace lldb_private; +const char *SearchFilter::g_ty_to_name[] = {"Unconstrained", "Exception", + "Module", "Modules", + "ModulesAndCU", "Unknown"}; + +const char + *SearchFilter::g_option_names[SearchFilter::OptionNames::LastOptionName] = { + "ModuleList", "CUList"}; + +const char *SearchFilter::FilterTyToName(enum FilterTy type) { + if (type > LastKnownFilterType) + return g_ty_to_name[UnknownFilter]; + + return g_ty_to_name[type]; +} + +SearchFilter::FilterTy SearchFilter::NameToFilterTy(const char *name) { + for (size_t i = 0; i < LastKnownFilterType; i++) { + if (strcmp(name, g_ty_to_name[i]) == 0) + return (FilterTy)i; + } + return UnknownFilter; +} + Searcher::Searcher() = default; Searcher::~Searcher() = default; void Searcher::GetDescription(Stream *s) {} -SearchFilter::SearchFilter(const TargetSP &target_sp) - : m_target_sp(target_sp) {} +SearchFilter::SearchFilter(const TargetSP &target_sp, unsigned char filterType) + : m_target_sp(target_sp), SubclassID(filterType) {} SearchFilter::SearchFilter(const SearchFilter &rhs) = default; @@ -36,6 +59,65 @@ SearchFilter &SearchFilter::operator=(const SearchFilter &rhs) = default; SearchFilter::~SearchFilter() = default; +SearchFilter *SearchFilter::CreateFromStructuredData( + Target &target, StructuredData::Dictionary &filter_dict, Error &error) { + SearchFilter *result = nullptr; + if (!filter_dict.IsValid()) { + error.SetErrorString("Can't deserialize from an invalid data object."); + return result; + } + + std::string subclass_name; + + bool success = filter_dict.GetValueForKeyAsString( + GetSerializationSubclassKey(), subclass_name); + if (!success) { + error.SetErrorStringWithFormat("Filter data missing subclass key"); + return result; + } + + FilterTy filter_type = NameToFilterTy(subclass_name.c_str()); + if (filter_type == UnknownFilter) { + error.SetErrorStringWithFormat("Unknown filter type: %s.", + subclass_name.c_str()); + return result; + } + + StructuredData::Dictionary *subclass_options = nullptr; + success = filter_dict.GetValueForKeyAsDictionary( + GetSerializationSubclassOptionsKey(), subclass_options); + if (!success || !subclass_options || !subclass_options->IsValid()) { + error.SetErrorString("Filter data missing subclass options key."); + return result; + } + + switch (filter_type) { + case Unconstrained: + result = SearchFilterForUnconstrainedSearches::CreateFromStructuredData( + target, *subclass_options, error); + break; + case ByModule: + result = SearchFilterByModule::CreateFromStructuredData( + target, *subclass_options, error); + break; + case ByModules: + result = SearchFilterByModuleList::CreateFromStructuredData( + target, *subclass_options, error); + break; + case ByModulesAndCU: + result = SearchFilterByModuleListAndCU::CreateFromStructuredData( + target, *subclass_options, error); + break; + case Exception: + error.SetErrorString("Can't serialize exception breakpoints yet."); + break; + default: + llvm_unreachable("Should never get an uresolvable filter type."); + } + + return result; +} + bool SearchFilter::ModulePasses(const FileSpec &spec) { return true; } bool SearchFilter::ModulePasses(const ModuleSP &module_sp) { return true; } @@ -62,6 +144,34 @@ lldb::SearchFilterSP SearchFilter::CopyForBreakpoint(Breakpoint &breakpoint) { } //---------------------------------------------------------------------- +// Helper functions for serialization. +//---------------------------------------------------------------------- + +StructuredData::DictionarySP +SearchFilter::WrapOptionsDict(StructuredData::DictionarySP options_dict_sp) { + if (!options_dict_sp || !options_dict_sp->IsValid()) + return StructuredData::DictionarySP(); + + StructuredData::DictionarySP type_dict_sp(new StructuredData::Dictionary()); + type_dict_sp->AddStringItem(GetSerializationSubclassKey(), GetFilterName()); + type_dict_sp->AddItem(GetSerializationSubclassOptionsKey(), options_dict_sp); + + return type_dict_sp; +} + +void SearchFilter::SerializeFileSpecList( + StructuredData::DictionarySP &options_dict_sp, OptionNames name, + FileSpecList &file_list) { + StructuredData::ArraySP module_array_sp(new StructuredData::Array()); + size_t num_modules = file_list.GetSize(); + for (size_t i = 0; i < num_modules; i++) { + module_array_sp->AddItem(StructuredData::StringSP( + new StructuredData::String(file_list.GetFileSpecAtIndex(i).GetPath()))); + } + options_dict_sp->AddItem(GetKey(name), module_array_sp); +} + +//---------------------------------------------------------------------- // UTILITY Functions to help iterate down through the elements of the // SymbolContext. //---------------------------------------------------------------------- @@ -202,6 +312,18 @@ Searcher::CallbackReturn SearchFilter::DoFunctionIteration( // Selects a shared library matching a given file spec, consulting the targets // "black list". //---------------------------------------------------------------------- +SearchFilter *SearchFilterForUnconstrainedSearches::CreateFromStructuredData( + Target &target, StructuredData::Dictionary &data_dict, Error &error) { + // No options for an unconstrained search. + return new SearchFilterForUnconstrainedSearches(target.shared_from_this()); +} + +StructuredData::ObjectSP +SearchFilterForUnconstrainedSearches::SerializeToStructuredData() { + // The options dictionary is an empty dictionary: + StructuredData::DictionarySP result_sp(new StructuredData::Dictionary()); + return WrapOptionsDict(result_sp); +} bool SearchFilterForUnconstrainedSearches::ModulePasses( const FileSpec &module_spec) { @@ -234,7 +356,7 @@ lldb::SearchFilterSP SearchFilterForUnconstrainedSearches::DoCopyForBreakpoint( SearchFilterByModule::SearchFilterByModule(const lldb::TargetSP &target_sp, const FileSpec &module) - : SearchFilter(target_sp), m_module_spec(module) {} + : SearchFilter(target_sp, FilterTy::ByModule), m_module_spec(module) {} SearchFilterByModule::SearchFilterByModule(const SearchFilterByModule &rhs) = default; @@ -325,6 +447,44 @@ SearchFilterByModule::DoCopyForBreakpoint(Breakpoint &breakpoint) { return ret_sp; } +SearchFilter *SearchFilterByModule::CreateFromStructuredData( + Target &target, StructuredData::Dictionary &data_dict, Error &error) { + StructuredData::Array *modules_array; + bool success = data_dict.GetValueForKeyAsArray(GetKey(OptionNames::ModList), + modules_array); + if (!success) { + error.SetErrorString("SFBM::CFSD: Could not find the module list key."); + return nullptr; + } + + size_t num_modules = modules_array->GetSize(); + if (num_modules > 1) { + error.SetErrorString( + "SFBM::CFSD: Only one modules allowed for SearchFilterByModule."); + return nullptr; + } + + std::string module; + success = modules_array->GetItemAtIndexAsString(0, module); + if (!success) { + error.SetErrorString("SFBM::CFSD: filter module item not a string."); + return nullptr; + } + FileSpec module_spec(module.c_str(), false); + + return new SearchFilterByModule(target.shared_from_this(), module_spec); +} + +StructuredData::ObjectSP SearchFilterByModule::SerializeToStructuredData() { + StructuredData::DictionarySP options_dict_sp( + new StructuredData::Dictionary()); + StructuredData::ArraySP module_array_sp(new StructuredData::Array()); + module_array_sp->AddItem(StructuredData::StringSP( + new StructuredData::String(m_module_spec.GetPath()))); + options_dict_sp->AddItem(GetKey(OptionNames::ModList), module_array_sp); + return WrapOptionsDict(options_dict_sp); +} + //---------------------------------------------------------------------- // SearchFilterByModuleList: // Selects a shared library matching a given file spec @@ -332,7 +492,13 @@ SearchFilterByModule::DoCopyForBreakpoint(Breakpoint &breakpoint) { SearchFilterByModuleList::SearchFilterByModuleList( const lldb::TargetSP &target_sp, const FileSpecList &module_list) - : SearchFilter(target_sp), m_module_spec_list(module_list) {} + : SearchFilter(target_sp, FilterTy::ByModules), + m_module_spec_list(module_list) {} + +SearchFilterByModuleList::SearchFilterByModuleList( + const lldb::TargetSP &target_sp, const FileSpecList &module_list, + enum FilterTy filter_ty) + : SearchFilter(target_sp, filter_ty), m_module_spec_list(module_list) {} SearchFilterByModuleList::SearchFilterByModuleList( const SearchFilterByModuleList &rhs) = default; @@ -456,6 +622,45 @@ SearchFilterByModuleList::DoCopyForBreakpoint(Breakpoint &breakpoint) { return ret_sp; } +SearchFilter *SearchFilterByModuleList::CreateFromStructuredData( + Target &target, StructuredData::Dictionary &data_dict, Error &error) { + StructuredData::Array *modules_array; + bool success = data_dict.GetValueForKeyAsArray(GetKey(OptionNames::ModList), + modules_array); + if (!success) { + error.SetErrorString("SFBM::CFSD: Could not find the module list key."); + return nullptr; + } + + size_t num_modules = modules_array->GetSize(); + FileSpecList modules; + for (size_t i = 0; i < num_modules; i++) { + std::string module; + success = modules_array->GetItemAtIndexAsString(i, module); + if (!success) { + error.SetErrorStringWithFormat( + "SFBM::CFSD: filter module item %zu not a string.", i); + return nullptr; + } + modules.Append(FileSpec(module.c_str(), false)); + } + + return new SearchFilterByModuleList(target.shared_from_this(), modules); +} + +void SearchFilterByModuleList::SerializeUnwrapped( + StructuredData::DictionarySP &options_dict_sp) { + SerializeFileSpecList(options_dict_sp, OptionNames::ModList, + m_module_spec_list); +} + +StructuredData::ObjectSP SearchFilterByModuleList::SerializeToStructuredData() { + StructuredData::DictionarySP options_dict_sp( + new StructuredData::Dictionary()); + SerializeUnwrapped(options_dict_sp); + return WrapOptionsDict(options_dict_sp); +} + //---------------------------------------------------------------------- // SearchFilterByModuleListAndCU: // Selects a shared library matching a given file spec @@ -464,7 +669,8 @@ SearchFilterByModuleList::DoCopyForBreakpoint(Breakpoint &breakpoint) { SearchFilterByModuleListAndCU::SearchFilterByModuleListAndCU( const lldb::TargetSP &target_sp, const FileSpecList &module_list, const FileSpecList &cu_list) - : SearchFilterByModuleList(target_sp, module_list), + : SearchFilterByModuleList(target_sp, module_list, + FilterTy::ByModulesAndCU), m_cu_spec_list(cu_list) {} SearchFilterByModuleListAndCU::SearchFilterByModuleListAndCU( @@ -482,6 +688,63 @@ operator=(const SearchFilterByModuleListAndCU &rhs) { SearchFilterByModuleListAndCU::~SearchFilterByModuleListAndCU() = default; +SearchFilter *SearchFilterByModuleListAndCU::CreateFromStructuredData( + Target &target, StructuredData::Dictionary &data_dict, Error &error) { + StructuredData::Array *modules_array; + bool success = data_dict.GetValueForKeyAsArray(GetKey(OptionNames::ModList), + modules_array); + if (!success) { + error.SetErrorString("SFBM::CFSD: Could not find the module list key."); + return nullptr; + } + + size_t num_modules = modules_array->GetSize(); + FileSpecList modules; + for (size_t i = 0; i < num_modules; i++) { + std::string module; + success = modules_array->GetItemAtIndexAsString(i, module); + if (!success) { + error.SetErrorStringWithFormat( + "SFBM::CFSD: filter module item %zu not a string.", i); + return nullptr; + } + modules.Append(FileSpec(module.c_str(), false)); + } + + StructuredData::Array *cus_array; + success = + data_dict.GetValueForKeyAsArray(GetKey(OptionNames::CUList), cus_array); + if (!success) { + error.SetErrorString("SFBM::CFSD: Could not find the CU list key."); + return nullptr; + } + + size_t num_cus = cus_array->GetSize(); + FileSpecList cus; + for (size_t i = 0; i < num_cus; i++) { + std::string cu; + success = modules_array->GetItemAtIndexAsString(i, cu); + if (!success) { + error.SetErrorStringWithFormat( + "SFBM::CFSD: filter cu item %zu not a string.", i); + return nullptr; + } + cus.Append(FileSpec(cu.c_str(), false)); + } + + return new SearchFilterByModuleListAndCU(target.shared_from_this(), modules, + cus); +} + +StructuredData::ObjectSP +SearchFilterByModuleListAndCU::SerializeToStructuredData() { + StructuredData::DictionarySP options_dict_sp( + new StructuredData::Dictionary()); + SearchFilterByModuleList::SerializeUnwrapped(options_dict_sp); + SerializeFileSpecList(options_dict_sp, OptionNames::CUList, m_cu_spec_list); + return WrapOptionsDict(options_dict_sp); +} + bool SearchFilterByModuleListAndCU::AddressPasses(Address &address) { return true; } diff --git a/lldb/source/Core/StructuredData.cpp b/lldb/source/Core/StructuredData.cpp index 6e544c1d537..5980e0fe645 100644 --- a/lldb/source/Core/StructuredData.cpp +++ b/lldb/source/Core/StructuredData.cpp @@ -14,7 +14,11 @@ #include <inttypes.h> #include <stdlib.h> +#include "lldb/Core/DataBuffer.h" +#include "lldb/Core/Error.h" #include "lldb/Core/StreamString.h" +#include "lldb/Host/File.h" +#include "lldb/Host/FileSpec.h" #include "lldb/Host/StringConvert.h" #include "lldb/Utility/JSON.h" @@ -27,6 +31,44 @@ static StructuredData::ObjectSP ParseJSONValue(JSONParser &json_parser); static StructuredData::ObjectSP ParseJSONObject(JSONParser &json_parser); static StructuredData::ObjectSP ParseJSONArray(JSONParser &json_parser); +StructuredData::ObjectSP StructuredData::ParseJSONFromFile(FileSpec &input_spec, + Error &error) { + StructuredData::ObjectSP return_sp; + if (!input_spec.Exists()) { + error.SetErrorStringWithFormat("input file %s does not exist.", + input_spec.GetPath().c_str()); + return return_sp; + } + + File input_file(nullptr, File::OpenOptions::eOpenOptionRead, + lldb::eFilePermissionsUserRead); + std::string input_path = input_spec.GetPath(); + error = + input_file.Open(input_path.c_str(), File::OpenOptions::eOpenOptionRead, + lldb::eFilePermissionsUserRead); + + if (!error.Success()) { + error.SetErrorStringWithFormat("could not open input file: %s - %s.", + input_spec.GetPath().c_str(), + error.AsCString()); + return return_sp; + } + + lldb::DataBufferSP input_data; + size_t num_bytes = SIZE_T_MAX; + off_t offset = 0; + error = input_file.Read(num_bytes, offset, true, input_data); + if (!error.Success()) { + error.SetErrorStringWithFormat("could not read input file: %s - %s.", + input_spec.GetPath().c_str(), + error.AsCString()); + return return_sp; + } + JSONParser json_parser((char *)input_data->GetBytes()); + return_sp = ParseJSONValue(json_parser); + return return_sp; +} + static StructuredData::ObjectSP ParseJSONObject(JSONParser &json_parser) { // The "JSONParser::Token::ObjectStart" token should have already been // consumed |