xref: /freebsd-src/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverName.cpp (revision 1db9f3b21e39176dd5b67cf8ac378633b172463e)
15ffd83dbSDimitry Andric //===-- BreakpointResolverName.cpp ----------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "lldb/Breakpoint/BreakpointResolverName.h"
100b57cec5SDimitry Andric 
110b57cec5SDimitry Andric #include "lldb/Breakpoint/BreakpointLocation.h"
120b57cec5SDimitry Andric #include "lldb/Core/Architecture.h"
130b57cec5SDimitry Andric #include "lldb/Core/Module.h"
140b57cec5SDimitry Andric #include "lldb/Symbol/Block.h"
150b57cec5SDimitry Andric #include "lldb/Symbol/Function.h"
160b57cec5SDimitry Andric #include "lldb/Symbol/Symbol.h"
170b57cec5SDimitry Andric #include "lldb/Symbol/SymbolContext.h"
180b57cec5SDimitry Andric #include "lldb/Target/Language.h"
1981ad6265SDimitry Andric #include "lldb/Target/Target.h"
2081ad6265SDimitry Andric #include "lldb/Utility/LLDBLog.h"
210b57cec5SDimitry Andric #include "lldb/Utility/Log.h"
220b57cec5SDimitry Andric #include "lldb/Utility/StreamString.h"
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric using namespace lldb;
250b57cec5SDimitry Andric using namespace lldb_private;
260b57cec5SDimitry Andric 
BreakpointResolverName(const BreakpointSP & bkpt,const char * name_cstr,FunctionNameType name_type_mask,LanguageType language,Breakpoint::MatchType type,lldb::addr_t offset,bool skip_prologue)275ffd83dbSDimitry Andric BreakpointResolverName::BreakpointResolverName(const BreakpointSP &bkpt,
285ffd83dbSDimitry Andric     const char *name_cstr, FunctionNameType name_type_mask,
290b57cec5SDimitry Andric     LanguageType language, Breakpoint::MatchType type, lldb::addr_t offset,
300b57cec5SDimitry Andric     bool skip_prologue)
310b57cec5SDimitry Andric     : BreakpointResolver(bkpt, BreakpointResolver::NameResolver, offset),
3281ad6265SDimitry Andric       m_match_type(type), m_language(language), m_skip_prologue(skip_prologue) {
330b57cec5SDimitry Andric   if (m_match_type == Breakpoint::Regexp) {
34fe6060f1SDimitry Andric     m_regex = RegularExpression(name_cstr);
359dba64beSDimitry Andric     if (!m_regex.IsValid()) {
3681ad6265SDimitry Andric       Log *log = GetLog(LLDBLog::Breakpoints);
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric       if (log)
390b57cec5SDimitry Andric         log->Warning("function name regexp: \"%s\" did not compile.",
400b57cec5SDimitry Andric                      name_cstr);
410b57cec5SDimitry Andric     }
420b57cec5SDimitry Andric   } else {
430b57cec5SDimitry Andric     AddNameLookup(ConstString(name_cstr), name_type_mask);
440b57cec5SDimitry Andric   }
450b57cec5SDimitry Andric }
460b57cec5SDimitry Andric 
BreakpointResolverName(const BreakpointSP & bkpt,const char * names[],size_t num_names,FunctionNameType name_type_mask,LanguageType language,lldb::addr_t offset,bool skip_prologue)470b57cec5SDimitry Andric BreakpointResolverName::BreakpointResolverName(
485ffd83dbSDimitry Andric     const BreakpointSP &bkpt, const char *names[], size_t num_names,
490b57cec5SDimitry Andric     FunctionNameType name_type_mask, LanguageType language, lldb::addr_t offset,
500b57cec5SDimitry Andric     bool skip_prologue)
510b57cec5SDimitry Andric     : BreakpointResolver(bkpt, BreakpointResolver::NameResolver, offset),
520b57cec5SDimitry Andric       m_match_type(Breakpoint::Exact), m_language(language),
530b57cec5SDimitry Andric       m_skip_prologue(skip_prologue) {
540b57cec5SDimitry Andric   for (size_t i = 0; i < num_names; i++) {
550b57cec5SDimitry Andric     AddNameLookup(ConstString(names[i]), name_type_mask);
560b57cec5SDimitry Andric   }
570b57cec5SDimitry Andric }
580b57cec5SDimitry Andric 
BreakpointResolverName(const BreakpointSP & bkpt,const std::vector<std::string> & names,FunctionNameType name_type_mask,LanguageType language,lldb::addr_t offset,bool skip_prologue)595f757f3fSDimitry Andric BreakpointResolverName::BreakpointResolverName(
605f757f3fSDimitry Andric     const BreakpointSP &bkpt, const std::vector<std::string> &names,
615f757f3fSDimitry Andric     FunctionNameType name_type_mask, LanguageType language, lldb::addr_t offset,
620b57cec5SDimitry Andric     bool skip_prologue)
630b57cec5SDimitry Andric     : BreakpointResolver(bkpt, BreakpointResolver::NameResolver, offset),
640b57cec5SDimitry Andric       m_match_type(Breakpoint::Exact), m_language(language),
650b57cec5SDimitry Andric       m_skip_prologue(skip_prologue) {
660b57cec5SDimitry Andric   for (const std::string &name : names) {
670b57cec5SDimitry Andric     AddNameLookup(ConstString(name.c_str(), name.size()), name_type_mask);
680b57cec5SDimitry Andric   }
690b57cec5SDimitry Andric }
700b57cec5SDimitry Andric 
BreakpointResolverName(const BreakpointSP & bkpt,RegularExpression func_regex,lldb::LanguageType language,lldb::addr_t offset,bool skip_prologue)715ffd83dbSDimitry Andric BreakpointResolverName::BreakpointResolverName(const BreakpointSP &bkpt,
729dba64beSDimitry Andric                                                RegularExpression func_regex,
730b57cec5SDimitry Andric                                                lldb::LanguageType language,
740b57cec5SDimitry Andric                                                lldb::addr_t offset,
750b57cec5SDimitry Andric                                                bool skip_prologue)
760b57cec5SDimitry Andric     : BreakpointResolver(bkpt, BreakpointResolver::NameResolver, offset),
779dba64beSDimitry Andric       m_class_name(nullptr), m_regex(std::move(func_regex)),
780b57cec5SDimitry Andric       m_match_type(Breakpoint::Regexp), m_language(language),
790b57cec5SDimitry Andric       m_skip_prologue(skip_prologue) {}
800b57cec5SDimitry Andric 
BreakpointResolverName(const BreakpointResolverName & rhs)810b57cec5SDimitry Andric BreakpointResolverName::BreakpointResolverName(
820b57cec5SDimitry Andric     const BreakpointResolverName &rhs)
835ffd83dbSDimitry Andric     : BreakpointResolver(rhs.GetBreakpoint(), BreakpointResolver::NameResolver,
845ffd83dbSDimitry Andric                          rhs.GetOffset()),
850b57cec5SDimitry Andric       m_lookups(rhs.m_lookups), m_class_name(rhs.m_class_name),
860b57cec5SDimitry Andric       m_regex(rhs.m_regex), m_match_type(rhs.m_match_type),
870b57cec5SDimitry Andric       m_language(rhs.m_language), m_skip_prologue(rhs.m_skip_prologue) {}
880b57cec5SDimitry Andric 
CreateFromStructuredData(const StructuredData::Dictionary & options_dict,Status & error)895f757f3fSDimitry Andric BreakpointResolverSP BreakpointResolverName::CreateFromStructuredData(
905f757f3fSDimitry Andric     const StructuredData::Dictionary &options_dict, Status &error) {
910b57cec5SDimitry Andric   LanguageType language = eLanguageTypeUnknown;
920b57cec5SDimitry Andric   llvm::StringRef language_name;
930b57cec5SDimitry Andric   bool success = options_dict.GetValueForKeyAsString(
940b57cec5SDimitry Andric       GetKey(OptionNames::LanguageName), language_name);
950b57cec5SDimitry Andric   if (success) {
960b57cec5SDimitry Andric     language = Language::GetLanguageTypeFromString(language_name);
970b57cec5SDimitry Andric     if (language == eLanguageTypeUnknown) {
980b57cec5SDimitry Andric       error.SetErrorStringWithFormatv("BRN::CFSD: Unknown language: {0}.",
990b57cec5SDimitry Andric                                       language_name);
1000b57cec5SDimitry Andric       return nullptr;
1010b57cec5SDimitry Andric     }
1020b57cec5SDimitry Andric   }
1030b57cec5SDimitry Andric 
10406c3fb27SDimitry Andric   lldb::offset_t offset = 0;
1050b57cec5SDimitry Andric   success =
1060b57cec5SDimitry Andric       options_dict.GetValueForKeyAsInteger(GetKey(OptionNames::Offset), offset);
1070b57cec5SDimitry Andric   if (!success) {
108e8d8bef9SDimitry Andric     error.SetErrorString("BRN::CFSD: Missing offset entry.");
1090b57cec5SDimitry Andric     return nullptr;
1100b57cec5SDimitry Andric   }
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric   bool skip_prologue;
1130b57cec5SDimitry Andric   success = options_dict.GetValueForKeyAsBoolean(
1140b57cec5SDimitry Andric       GetKey(OptionNames::SkipPrologue), skip_prologue);
1150b57cec5SDimitry Andric   if (!success) {
116e8d8bef9SDimitry Andric     error.SetErrorString("BRN::CFSD: Missing Skip prologue entry.");
1170b57cec5SDimitry Andric     return nullptr;
1180b57cec5SDimitry Andric   }
1190b57cec5SDimitry Andric 
1200b57cec5SDimitry Andric   llvm::StringRef regex_text;
1210b57cec5SDimitry Andric   success = options_dict.GetValueForKeyAsString(
1220b57cec5SDimitry Andric       GetKey(OptionNames::RegexString), regex_text);
1230b57cec5SDimitry Andric   if (success) {
1245f757f3fSDimitry Andric     return std::make_shared<BreakpointResolverName>(
1255f757f3fSDimitry Andric         nullptr, RegularExpression(regex_text), language, offset,
1265f757f3fSDimitry Andric         skip_prologue);
1270b57cec5SDimitry Andric   } else {
1280b57cec5SDimitry Andric     StructuredData::Array *names_array;
1290b57cec5SDimitry Andric     success = options_dict.GetValueForKeyAsArray(
1300b57cec5SDimitry Andric         GetKey(OptionNames::SymbolNameArray), names_array);
1310b57cec5SDimitry Andric     if (!success) {
132e8d8bef9SDimitry Andric       error.SetErrorString("BRN::CFSD: Missing symbol names entry.");
1330b57cec5SDimitry Andric       return nullptr;
1340b57cec5SDimitry Andric     }
1350b57cec5SDimitry Andric     StructuredData::Array *names_mask_array;
1360b57cec5SDimitry Andric     success = options_dict.GetValueForKeyAsArray(
1370b57cec5SDimitry Andric         GetKey(OptionNames::NameMaskArray), names_mask_array);
1380b57cec5SDimitry Andric     if (!success) {
139e8d8bef9SDimitry Andric       error.SetErrorString("BRN::CFSD: Missing symbol names mask entry.");
1400b57cec5SDimitry Andric       return nullptr;
1410b57cec5SDimitry Andric     }
1420b57cec5SDimitry Andric 
1430b57cec5SDimitry Andric     size_t num_elem = names_array->GetSize();
1440b57cec5SDimitry Andric     if (num_elem != names_mask_array->GetSize()) {
1450b57cec5SDimitry Andric       error.SetErrorString(
1460b57cec5SDimitry Andric           "BRN::CFSD: names and names mask arrays have different sizes.");
1470b57cec5SDimitry Andric       return nullptr;
1480b57cec5SDimitry Andric     }
1490b57cec5SDimitry Andric 
1500b57cec5SDimitry Andric     if (num_elem == 0) {
1510b57cec5SDimitry Andric       error.SetErrorString(
1520b57cec5SDimitry Andric           "BRN::CFSD: no name entry in a breakpoint by name breakpoint.");
1530b57cec5SDimitry Andric       return nullptr;
1540b57cec5SDimitry Andric     }
1550b57cec5SDimitry Andric     std::vector<std::string> names;
1560b57cec5SDimitry Andric     std::vector<FunctionNameType> name_masks;
1570b57cec5SDimitry Andric     for (size_t i = 0; i < num_elem; i++) {
1585f757f3fSDimitry Andric       std::optional<llvm::StringRef> maybe_name =
1595f757f3fSDimitry Andric           names_array->GetItemAtIndexAsString(i);
1605f757f3fSDimitry Andric       if (!maybe_name) {
1610b57cec5SDimitry Andric         error.SetErrorString("BRN::CFSD: name entry is not a string.");
1620b57cec5SDimitry Andric         return nullptr;
1630b57cec5SDimitry Andric       }
164*1db9f3b2SDimitry Andric       auto maybe_fnt = names_mask_array->GetItemAtIndexAsInteger<
165*1db9f3b2SDimitry Andric           std::underlying_type<FunctionNameType>::type>(i);
166*1db9f3b2SDimitry Andric       if (!maybe_fnt) {
1670b57cec5SDimitry Andric         error.SetErrorString("BRN::CFSD: name mask entry is not an integer.");
1680b57cec5SDimitry Andric         return nullptr;
1690b57cec5SDimitry Andric       }
1705f757f3fSDimitry Andric       names.push_back(std::string(*maybe_name));
171*1db9f3b2SDimitry Andric       name_masks.push_back(static_cast<FunctionNameType>(*maybe_fnt));
1720b57cec5SDimitry Andric     }
1730b57cec5SDimitry Andric 
1745f757f3fSDimitry Andric     std::shared_ptr<BreakpointResolverName> resolver_sp =
1755f757f3fSDimitry Andric         std::make_shared<BreakpointResolverName>(
1765f757f3fSDimitry Andric             nullptr, names[0].c_str(), name_masks[0], language,
1770b57cec5SDimitry Andric             Breakpoint::MatchType::Exact, offset, skip_prologue);
1780b57cec5SDimitry Andric     for (size_t i = 1; i < num_elem; i++) {
1795f757f3fSDimitry Andric       resolver_sp->AddNameLookup(ConstString(names[i]), name_masks[i]);
1800b57cec5SDimitry Andric     }
1815f757f3fSDimitry Andric     return resolver_sp;
1820b57cec5SDimitry Andric   }
1830b57cec5SDimitry Andric }
1840b57cec5SDimitry Andric 
SerializeToStructuredData()1850b57cec5SDimitry Andric StructuredData::ObjectSP BreakpointResolverName::SerializeToStructuredData() {
1860b57cec5SDimitry Andric   StructuredData::DictionarySP options_dict_sp(
1870b57cec5SDimitry Andric       new StructuredData::Dictionary());
1880b57cec5SDimitry Andric 
1890b57cec5SDimitry Andric   if (m_regex.IsValid()) {
1900b57cec5SDimitry Andric     options_dict_sp->AddStringItem(GetKey(OptionNames::RegexString),
1910b57cec5SDimitry Andric                                    m_regex.GetText());
1920b57cec5SDimitry Andric   } else {
1930b57cec5SDimitry Andric     StructuredData::ArraySP names_sp(new StructuredData::Array());
1940b57cec5SDimitry Andric     StructuredData::ArraySP name_masks_sp(new StructuredData::Array());
1950b57cec5SDimitry Andric     for (auto lookup : m_lookups) {
1960b57cec5SDimitry Andric       names_sp->AddItem(StructuredData::StringSP(
1975ffd83dbSDimitry Andric           new StructuredData::String(lookup.GetName().GetStringRef())));
19806c3fb27SDimitry Andric       name_masks_sp->AddItem(StructuredData::UnsignedIntegerSP(
19906c3fb27SDimitry Andric           new StructuredData::UnsignedInteger(lookup.GetNameTypeMask())));
2000b57cec5SDimitry Andric     }
2010b57cec5SDimitry Andric     options_dict_sp->AddItem(GetKey(OptionNames::SymbolNameArray), names_sp);
2020b57cec5SDimitry Andric     options_dict_sp->AddItem(GetKey(OptionNames::NameMaskArray), name_masks_sp);
2030b57cec5SDimitry Andric   }
2040b57cec5SDimitry Andric   if (m_language != eLanguageTypeUnknown)
2050b57cec5SDimitry Andric     options_dict_sp->AddStringItem(
2060b57cec5SDimitry Andric         GetKey(OptionNames::LanguageName),
2070b57cec5SDimitry Andric         Language::GetNameForLanguageType(m_language));
2080b57cec5SDimitry Andric   options_dict_sp->AddBooleanItem(GetKey(OptionNames::SkipPrologue),
2090b57cec5SDimitry Andric                                   m_skip_prologue);
2100b57cec5SDimitry Andric 
2110b57cec5SDimitry Andric   return WrapOptionsDict(options_dict_sp);
2120b57cec5SDimitry Andric }
2130b57cec5SDimitry Andric 
AddNameLookup(ConstString name,FunctionNameType name_type_mask)2140b57cec5SDimitry Andric void BreakpointResolverName::AddNameLookup(ConstString name,
2150b57cec5SDimitry Andric                                            FunctionNameType name_type_mask) {
2160b57cec5SDimitry Andric 
2170b57cec5SDimitry Andric   Module::LookupInfo lookup(name, name_type_mask, m_language);
2180b57cec5SDimitry Andric   m_lookups.emplace_back(lookup);
2190b57cec5SDimitry Andric 
2200b57cec5SDimitry Andric   auto add_variant_funcs = [&](Language *lang) {
221fe6060f1SDimitry Andric     for (Language::MethodNameVariant variant :
222fe6060f1SDimitry Andric          lang->GetMethodNameVariants(name)) {
223fe6060f1SDimitry Andric       // FIXME: Should we be adding variants that aren't of type Full?
224fe6060f1SDimitry Andric       if (variant.GetType() & lldb::eFunctionNameTypeFull) {
225fe6060f1SDimitry Andric         Module::LookupInfo variant_lookup(name, variant.GetType(),
2260b57cec5SDimitry Andric                                           lang->GetLanguageType());
227fe6060f1SDimitry Andric         variant_lookup.SetLookupName(variant.GetName());
2280b57cec5SDimitry Andric         m_lookups.emplace_back(variant_lookup);
2290b57cec5SDimitry Andric       }
230fe6060f1SDimitry Andric     }
2310b57cec5SDimitry Andric     return true;
2320b57cec5SDimitry Andric   };
2330b57cec5SDimitry Andric 
2340b57cec5SDimitry Andric   if (Language *lang = Language::FindPlugin(m_language)) {
2350b57cec5SDimitry Andric     add_variant_funcs(lang);
2360b57cec5SDimitry Andric   } else {
2370b57cec5SDimitry Andric     // Most likely m_language is eLanguageTypeUnknown. We check each language for
2380b57cec5SDimitry Andric     // possible variants or more qualified names and create lookups for those as
2390b57cec5SDimitry Andric     // well.
2400b57cec5SDimitry Andric     Language::ForEach(add_variant_funcs);
2410b57cec5SDimitry Andric   }
2420b57cec5SDimitry Andric }
2430b57cec5SDimitry Andric 
2440b57cec5SDimitry Andric // FIXME: Right now we look at the module level, and call the module's
2450b57cec5SDimitry Andric // "FindFunctions".
2460b57cec5SDimitry Andric // Greg says he will add function tables, maybe at the CompileUnit level to
2470b57cec5SDimitry Andric // accelerate function lookup.  At that point, we should switch the depth to
2480b57cec5SDimitry Andric // CompileUnit, and look in these tables.
2490b57cec5SDimitry Andric 
2500b57cec5SDimitry Andric Searcher::CallbackReturn
SearchCallback(SearchFilter & filter,SymbolContext & context,Address * addr)2510b57cec5SDimitry Andric BreakpointResolverName::SearchCallback(SearchFilter &filter,
2529dba64beSDimitry Andric                                        SymbolContext &context, Address *addr) {
25381ad6265SDimitry Andric   Log *log = GetLog(LLDBLog::Breakpoints);
2540b57cec5SDimitry Andric 
2550b57cec5SDimitry Andric   if (m_class_name) {
2560b57cec5SDimitry Andric     if (log)
2570b57cec5SDimitry Andric       log->Warning("Class/method function specification not supported yet.\n");
2580b57cec5SDimitry Andric     return Searcher::eCallbackReturnStop;
2590b57cec5SDimitry Andric   }
2605ffd83dbSDimitry Andric 
2615ffd83dbSDimitry Andric   SymbolContextList func_list;
2620b57cec5SDimitry Andric   bool filter_by_cu =
2630b57cec5SDimitry Andric       (filter.GetFilterRequiredItems() & eSymbolContextCompUnit) != 0;
2640b57cec5SDimitry Andric   bool filter_by_language = (m_language != eLanguageTypeUnknown);
265349cc55cSDimitry Andric 
266349cc55cSDimitry Andric   ModuleFunctionSearchOptions function_options;
267349cc55cSDimitry Andric   function_options.include_symbols = !filter_by_cu;
268349cc55cSDimitry Andric   function_options.include_inlines = true;
2690b57cec5SDimitry Andric 
2700b57cec5SDimitry Andric   switch (m_match_type) {
2710b57cec5SDimitry Andric   case Breakpoint::Exact:
2720b57cec5SDimitry Andric     if (context.module_sp) {
2730b57cec5SDimitry Andric       for (const auto &lookup : m_lookups) {
2740b57cec5SDimitry Andric         const size_t start_func_idx = func_list.GetSize();
275bdd1243dSDimitry Andric         context.module_sp->FindFunctions(lookup, CompilerDeclContext(),
276bdd1243dSDimitry Andric                                          function_options, func_list);
2770b57cec5SDimitry Andric 
2780b57cec5SDimitry Andric         const size_t end_func_idx = func_list.GetSize();
2790b57cec5SDimitry Andric 
2800b57cec5SDimitry Andric         if (start_func_idx < end_func_idx)
2810b57cec5SDimitry Andric           lookup.Prune(func_list, start_func_idx);
2820b57cec5SDimitry Andric       }
2830b57cec5SDimitry Andric     }
2840b57cec5SDimitry Andric     break;
2850b57cec5SDimitry Andric   case Breakpoint::Regexp:
2860b57cec5SDimitry Andric     if (context.module_sp) {
287349cc55cSDimitry Andric       context.module_sp->FindFunctions(m_regex, function_options, func_list);
2880b57cec5SDimitry Andric     }
2890b57cec5SDimitry Andric     break;
2900b57cec5SDimitry Andric   case Breakpoint::Glob:
2910b57cec5SDimitry Andric     if (log)
2920b57cec5SDimitry Andric       log->Warning("glob is not supported yet.");
2930b57cec5SDimitry Andric     break;
2940b57cec5SDimitry Andric   }
2950b57cec5SDimitry Andric 
2960b57cec5SDimitry Andric   // If the filter specifies a Compilation Unit, remove the ones that don't
2970b57cec5SDimitry Andric   // pass at this point.
2980b57cec5SDimitry Andric   if (filter_by_cu || filter_by_language) {
2990b57cec5SDimitry Andric     uint32_t num_functions = func_list.GetSize();
3000b57cec5SDimitry Andric 
3010b57cec5SDimitry Andric     for (size_t idx = 0; idx < num_functions; idx++) {
3020b57cec5SDimitry Andric       bool remove_it = false;
3030b57cec5SDimitry Andric       SymbolContext sc;
3040b57cec5SDimitry Andric       func_list.GetContextAtIndex(idx, sc);
3050b57cec5SDimitry Andric       if (filter_by_cu) {
3060b57cec5SDimitry Andric         if (!sc.comp_unit || !filter.CompUnitPasses(*sc.comp_unit))
3070b57cec5SDimitry Andric           remove_it = true;
3080b57cec5SDimitry Andric       }
3090b57cec5SDimitry Andric 
3100b57cec5SDimitry Andric       if (filter_by_language) {
3110b57cec5SDimitry Andric         LanguageType sym_language = sc.GetLanguage();
3120b57cec5SDimitry Andric         if ((Language::GetPrimaryLanguage(sym_language) !=
3130b57cec5SDimitry Andric              Language::GetPrimaryLanguage(m_language)) &&
3140b57cec5SDimitry Andric             (sym_language != eLanguageTypeUnknown)) {
3150b57cec5SDimitry Andric           remove_it = true;
3160b57cec5SDimitry Andric         }
3170b57cec5SDimitry Andric       }
3180b57cec5SDimitry Andric 
3190b57cec5SDimitry Andric       if (remove_it) {
3200b57cec5SDimitry Andric         func_list.RemoveContextAtIndex(idx);
3210b57cec5SDimitry Andric         num_functions--;
3220b57cec5SDimitry Andric         idx--;
3230b57cec5SDimitry Andric       }
3240b57cec5SDimitry Andric     }
3250b57cec5SDimitry Andric   }
3260b57cec5SDimitry Andric 
3275ffd83dbSDimitry Andric   BreakpointSP breakpoint_sp = GetBreakpoint();
3285ffd83dbSDimitry Andric   Breakpoint &breakpoint = *breakpoint_sp;
3295ffd83dbSDimitry Andric   Address break_addr;
3305ffd83dbSDimitry Andric 
3310b57cec5SDimitry Andric   // Remove any duplicates between the function list and the symbol list
33206c3fb27SDimitry Andric   for (const SymbolContext &sc : func_list) {
3330b57cec5SDimitry Andric     bool is_reexported = false;
3340b57cec5SDimitry Andric 
3350b57cec5SDimitry Andric     if (sc.block && sc.block->GetInlinedFunctionInfo()) {
3360b57cec5SDimitry Andric       if (!sc.block->GetStartAddress(break_addr))
3370b57cec5SDimitry Andric         break_addr.Clear();
3380b57cec5SDimitry Andric     } else if (sc.function) {
3390b57cec5SDimitry Andric       break_addr = sc.function->GetAddressRange().GetBaseAddress();
3400b57cec5SDimitry Andric       if (m_skip_prologue && break_addr.IsValid()) {
3415ffd83dbSDimitry Andric         const uint32_t prologue_byte_size = sc.function->GetPrologueByteSize();
3420b57cec5SDimitry Andric         if (prologue_byte_size)
3430b57cec5SDimitry Andric           break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size);
3440b57cec5SDimitry Andric       }
3450b57cec5SDimitry Andric     } else if (sc.symbol) {
3460b57cec5SDimitry Andric       if (sc.symbol->GetType() == eSymbolTypeReExported) {
3470b57cec5SDimitry Andric         const Symbol *actual_symbol =
3485ffd83dbSDimitry Andric             sc.symbol->ResolveReExportedSymbol(breakpoint.GetTarget());
3490b57cec5SDimitry Andric         if (actual_symbol) {
3500b57cec5SDimitry Andric           is_reexported = true;
3510b57cec5SDimitry Andric           break_addr = actual_symbol->GetAddress();
3520b57cec5SDimitry Andric         }
3530b57cec5SDimitry Andric       } else {
3540b57cec5SDimitry Andric         break_addr = sc.symbol->GetAddress();
3550b57cec5SDimitry Andric       }
3560b57cec5SDimitry Andric 
3570b57cec5SDimitry Andric       if (m_skip_prologue && break_addr.IsValid()) {
3585ffd83dbSDimitry Andric         const uint32_t prologue_byte_size = sc.symbol->GetPrologueByteSize();
3590b57cec5SDimitry Andric         if (prologue_byte_size)
3600b57cec5SDimitry Andric           break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size);
3610b57cec5SDimitry Andric         else {
3620b57cec5SDimitry Andric           const Architecture *arch =
3635ffd83dbSDimitry Andric               breakpoint.GetTarget().GetArchitecturePlugin();
3640b57cec5SDimitry Andric           if (arch)
3650b57cec5SDimitry Andric             arch->AdjustBreakpointAddress(*sc.symbol, break_addr);
3660b57cec5SDimitry Andric         }
3670b57cec5SDimitry Andric       }
3680b57cec5SDimitry Andric     }
3690b57cec5SDimitry Andric 
3705ffd83dbSDimitry Andric     if (!break_addr.IsValid())
3715ffd83dbSDimitry Andric       continue;
3725ffd83dbSDimitry Andric 
3735ffd83dbSDimitry Andric     if (!filter.AddressPasses(break_addr))
3745ffd83dbSDimitry Andric       continue;
3755ffd83dbSDimitry Andric 
3765ffd83dbSDimitry Andric     bool new_location;
3775ffd83dbSDimitry Andric     BreakpointLocationSP bp_loc_sp(AddLocation(break_addr, &new_location));
3780b57cec5SDimitry Andric     bp_loc_sp->SetIsReExported(is_reexported);
3795ffd83dbSDimitry Andric     if (bp_loc_sp && new_location && !breakpoint.IsInternal()) {
3800b57cec5SDimitry Andric       if (log) {
3810b57cec5SDimitry Andric         StreamString s;
3820b57cec5SDimitry Andric         bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
3839dba64beSDimitry Andric         LLDB_LOGF(log, "Added location: %s\n", s.GetData());
3840b57cec5SDimitry Andric       }
3850b57cec5SDimitry Andric     }
3860b57cec5SDimitry Andric   }
3870b57cec5SDimitry Andric 
3880b57cec5SDimitry Andric   return Searcher::eCallbackReturnContinue;
3890b57cec5SDimitry Andric }
3900b57cec5SDimitry Andric 
GetDepth()3910b57cec5SDimitry Andric lldb::SearchDepth BreakpointResolverName::GetDepth() {
3920b57cec5SDimitry Andric   return lldb::eSearchDepthModule;
3930b57cec5SDimitry Andric }
3940b57cec5SDimitry Andric 
GetDescription(Stream * s)3950b57cec5SDimitry Andric void BreakpointResolverName::GetDescription(Stream *s) {
3960b57cec5SDimitry Andric   if (m_match_type == Breakpoint::Regexp)
3970b57cec5SDimitry Andric     s->Printf("regex = '%s'", m_regex.GetText().str().c_str());
3980b57cec5SDimitry Andric   else {
3990b57cec5SDimitry Andric     size_t num_names = m_lookups.size();
4000b57cec5SDimitry Andric     if (num_names == 1)
4010b57cec5SDimitry Andric       s->Printf("name = '%s'", m_lookups[0].GetName().GetCString());
4020b57cec5SDimitry Andric     else {
4030b57cec5SDimitry Andric       s->Printf("names = {");
4040b57cec5SDimitry Andric       for (size_t i = 0; i < num_names; i++) {
4050b57cec5SDimitry Andric         s->Printf("%s'%s'", (i == 0 ? "" : ", "),
4060b57cec5SDimitry Andric                   m_lookups[i].GetName().GetCString());
4070b57cec5SDimitry Andric       }
4080b57cec5SDimitry Andric       s->Printf("}");
4090b57cec5SDimitry Andric     }
4100b57cec5SDimitry Andric   }
4110b57cec5SDimitry Andric   if (m_language != eLanguageTypeUnknown) {
4120b57cec5SDimitry Andric     s->Printf(", language = %s", Language::GetNameForLanguageType(m_language));
4130b57cec5SDimitry Andric   }
4140b57cec5SDimitry Andric }
4150b57cec5SDimitry Andric 
Dump(Stream * s) const4160b57cec5SDimitry Andric void BreakpointResolverName::Dump(Stream *s) const {}
4170b57cec5SDimitry Andric 
4180b57cec5SDimitry Andric lldb::BreakpointResolverSP
CopyForBreakpoint(BreakpointSP & breakpoint)4195ffd83dbSDimitry Andric BreakpointResolverName::CopyForBreakpoint(BreakpointSP &breakpoint) {
4200b57cec5SDimitry Andric   lldb::BreakpointResolverSP ret_sp(new BreakpointResolverName(*this));
4215ffd83dbSDimitry Andric   ret_sp->SetBreakpoint(breakpoint);
4220b57cec5SDimitry Andric   return ret_sp;
4230b57cec5SDimitry Andric }
424