diff options
author | 2020-08-03 14:33:06 +0000 | |
---|---|---|
committer | 2020-08-03 14:33:06 +0000 | |
commit | 061da546b983eb767bad15e67af1174fb0bcf31c (patch) | |
tree | 83c78b820819d70aa40c36d90447978b300078c5 /gnu/llvm/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp | |
parent | Import LLVM 10.0.0 release including clang, lld and lldb. (diff) | |
download | wireguard-openbsd-061da546b983eb767bad15e67af1174fb0bcf31c.tar.xz wireguard-openbsd-061da546b983eb767bad15e67af1174fb0bcf31c.zip |
Import LLVM 10.0.0 release including clang, lld and lldb.
ok hackroom
tested by plenty
Diffstat (limited to 'gnu/llvm/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp')
-rw-r--r-- | gnu/llvm/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/gnu/llvm/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp b/gnu/llvm/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp new file mode 100644 index 00000000000..6b600a7cf12 --- /dev/null +++ b/gnu/llvm/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp @@ -0,0 +1,172 @@ +//===-- BreakpointResolverFileRegex.cpp -------------------------*- C++-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Breakpoint/BreakpointResolverFileRegex.h" + +#include "lldb/Breakpoint/BreakpointLocation.h" +#include "lldb/Core/SourceManager.h" +#include "lldb/Symbol/CompileUnit.h" +#include "lldb/Target/Target.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/StreamString.h" + +using namespace lldb; +using namespace lldb_private; + +// BreakpointResolverFileRegex: +BreakpointResolverFileRegex::BreakpointResolverFileRegex( + Breakpoint *bkpt, RegularExpression regex, + const std::unordered_set<std::string> &func_names, bool exact_match) + : BreakpointResolver(bkpt, BreakpointResolver::FileRegexResolver), + m_regex(std::move(regex)), m_exact_match(exact_match), + m_function_names(func_names) {} + +BreakpointResolverFileRegex::~BreakpointResolverFileRegex() {} + +BreakpointResolver *BreakpointResolverFileRegex::CreateFromStructuredData( + Breakpoint *bkpt, const StructuredData::Dictionary &options_dict, + Status &error) { + bool success; + + llvm::StringRef regex_string; + success = options_dict.GetValueForKeyAsString( + GetKey(OptionNames::RegexString), regex_string); + if (!success) { + error.SetErrorString("BRFR::CFSD: Couldn't find regex entry."); + return nullptr; + } + RegularExpression regex(regex_string); + + bool exact_match; + success = options_dict.GetValueForKeyAsBoolean( + GetKey(OptionNames::ExactMatch), exact_match); + if (!success) { + error.SetErrorString("BRFL::CFSD: Couldn't find exact match entry."); + return nullptr; + } + + // The names array is optional: + std::unordered_set<std::string> names_set; + StructuredData::Array *names_array; + success = options_dict.GetValueForKeyAsArray( + GetKey(OptionNames::SymbolNameArray), names_array); + if (success && names_array) { + size_t num_names = names_array->GetSize(); + for (size_t i = 0; i < num_names; i++) { + llvm::StringRef name; + success = names_array->GetItemAtIndexAsString(i, name); + if (!success) { + error.SetErrorStringWithFormat( + "BRFR::CFSD: Malformed element %zu in the names array.", i); + return nullptr; + } + names_set.insert(name); + } + } + + return new BreakpointResolverFileRegex(bkpt, std::move(regex), names_set, + exact_match); +} + +StructuredData::ObjectSP +BreakpointResolverFileRegex::SerializeToStructuredData() { + StructuredData::DictionarySP options_dict_sp( + new StructuredData::Dictionary()); + + options_dict_sp->AddStringItem(GetKey(OptionNames::RegexString), + m_regex.GetText()); + options_dict_sp->AddBooleanItem(GetKey(OptionNames::ExactMatch), + m_exact_match); + if (!m_function_names.empty()) { + StructuredData::ArraySP names_array_sp(new StructuredData::Array()); + for (std::string name : m_function_names) { + StructuredData::StringSP item(new StructuredData::String(name)); + names_array_sp->AddItem(item); + } + options_dict_sp->AddItem(GetKey(OptionNames::LineNumber), names_array_sp); + } + + return WrapOptionsDict(options_dict_sp); +} + +Searcher::CallbackReturn BreakpointResolverFileRegex::SearchCallback( + SearchFilter &filter, SymbolContext &context, Address *addr) { + + assert(m_breakpoint != nullptr); + if (!context.target_sp) + return eCallbackReturnContinue; + + CompileUnit *cu = context.comp_unit; + FileSpec cu_file_spec = cu->GetPrimaryFile(); + std::vector<uint32_t> line_matches; + context.target_sp->GetSourceManager().FindLinesMatchingRegex( + cu_file_spec, m_regex, 1, UINT32_MAX, line_matches); + + uint32_t num_matches = line_matches.size(); + for (uint32_t i = 0; i < num_matches; i++) { + SymbolContextList sc_list; + const bool search_inlines = false; + + cu->ResolveSymbolContext(cu_file_spec, line_matches[i], search_inlines, + m_exact_match, eSymbolContextEverything, sc_list); + // Find all the function names: + if (!m_function_names.empty()) { + std::vector<size_t> sc_to_remove; + for (size_t i = 0; i < sc_list.GetSize(); i++) { + SymbolContext sc_ctx; + sc_list.GetContextAtIndex(i, sc_ctx); + std::string name( + sc_ctx + .GetFunctionName( + Mangled::NamePreference::ePreferDemangledWithoutArguments) + .AsCString()); + if (!m_function_names.count(name)) { + sc_to_remove.push_back(i); + } + } + + if (!sc_to_remove.empty()) { + std::vector<size_t>::reverse_iterator iter; + std::vector<size_t>::reverse_iterator rend = sc_to_remove.rend(); + for (iter = sc_to_remove.rbegin(); iter != rend; iter++) { + sc_list.RemoveContextAtIndex(*iter); + } + } + } + + const bool skip_prologue = true; + + BreakpointResolver::SetSCMatchesByLine(filter, sc_list, skip_prologue, + m_regex.GetText()); + } + assert(m_breakpoint != nullptr); + + return Searcher::eCallbackReturnContinue; +} + +lldb::SearchDepth BreakpointResolverFileRegex::GetDepth() { + return lldb::eSearchDepthCompUnit; +} + +void BreakpointResolverFileRegex::GetDescription(Stream *s) { + s->Printf("source regex = \"%s\", exact_match = %d", + m_regex.GetText().str().c_str(), m_exact_match); +} + +void BreakpointResolverFileRegex::Dump(Stream *s) const {} + +lldb::BreakpointResolverSP +BreakpointResolverFileRegex::CopyForBreakpoint(Breakpoint &breakpoint) { + lldb::BreakpointResolverSP ret_sp(new BreakpointResolverFileRegex( + &breakpoint, m_regex, m_function_names, m_exact_match)); + return ret_sp; +} + +void BreakpointResolverFileRegex::AddFunctionName(const char *func_name) { + m_function_names.insert(func_name); +} |