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