1cfca06d7SDimitry Andric //===-- BreakpointResolverName.cpp ----------------------------------------===//
2f034231aSEd Maste //
35f29bb8aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f29bb8aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f29bb8aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f034231aSEd Maste //
7f034231aSEd Maste //===----------------------------------------------------------------------===//
8f034231aSEd Maste
9e81d9d49SDimitry Andric #include "lldb/Breakpoint/BreakpointResolverName.h"
10e81d9d49SDimitry Andric
11f034231aSEd Maste #include "lldb/Breakpoint/BreakpointLocation.h"
12f73363f1SDimitry Andric #include "lldb/Core/Architecture.h"
13f034231aSEd Maste #include "lldb/Core/Module.h"
14f034231aSEd Maste #include "lldb/Symbol/Block.h"
15f034231aSEd Maste #include "lldb/Symbol/Function.h"
16f034231aSEd Maste #include "lldb/Symbol/Symbol.h"
17f034231aSEd Maste #include "lldb/Symbol/SymbolContext.h"
185f29bb8aSDimitry Andric #include "lldb/Target/Language.h"
19145449b1SDimitry Andric #include "lldb/Target/Target.h"
20145449b1SDimitry Andric #include "lldb/Utility/LLDBLog.h"
2174a628f7SDimitry Andric #include "lldb/Utility/Log.h"
2274a628f7SDimitry Andric #include "lldb/Utility/StreamString.h"
23f034231aSEd Maste
24f034231aSEd Maste using namespace lldb;
25f034231aSEd Maste using namespace lldb_private;
26f034231aSEd Maste
BreakpointResolverName(const BreakpointSP & bkpt,const char * name_cstr,FunctionNameType name_type_mask,LanguageType language,Breakpoint::MatchType type,lldb::addr_t offset,bool skip_prologue)27cfca06d7SDimitry Andric BreakpointResolverName::BreakpointResolverName(const BreakpointSP &bkpt,
28cfca06d7SDimitry Andric const char *name_cstr, FunctionNameType name_type_mask,
2914f1b3e8SDimitry Andric LanguageType language, Breakpoint::MatchType type, lldb::addr_t offset,
3014f1b3e8SDimitry Andric bool skip_prologue)
3114f1b3e8SDimitry Andric : BreakpointResolver(bkpt, BreakpointResolver::NameResolver, offset),
32145449b1SDimitry Andric m_match_type(type), m_language(language), m_skip_prologue(skip_prologue) {
3314f1b3e8SDimitry Andric if (m_match_type == Breakpoint::Regexp) {
34344a3780SDimitry Andric m_regex = RegularExpression(name_cstr);
35ead24645SDimitry Andric if (!m_regex.IsValid()) {
36145449b1SDimitry Andric Log *log = GetLog(LLDBLog::Breakpoints);
37f034231aSEd Maste
38f034231aSEd Maste if (log)
3914f1b3e8SDimitry Andric log->Warning("function name regexp: \"%s\" did not compile.",
4014f1b3e8SDimitry Andric name_cstr);
41f034231aSEd Maste }
4214f1b3e8SDimitry Andric } else {
43f034231aSEd Maste AddNameLookup(ConstString(name_cstr), name_type_mask);
44f034231aSEd Maste }
45f034231aSEd Maste }
46f034231aSEd Maste
BreakpointResolverName(const BreakpointSP & bkpt,const char * names[],size_t num_names,FunctionNameType name_type_mask,LanguageType language,lldb::addr_t offset,bool skip_prologue)4714f1b3e8SDimitry Andric BreakpointResolverName::BreakpointResolverName(
48cfca06d7SDimitry Andric const BreakpointSP &bkpt, const char *names[], size_t num_names,
4994994d37SDimitry Andric FunctionNameType name_type_mask, LanguageType language, lldb::addr_t offset,
5014f1b3e8SDimitry Andric bool skip_prologue)
5114f1b3e8SDimitry Andric : BreakpointResolver(bkpt, BreakpointResolver::NameResolver, offset),
5214f1b3e8SDimitry Andric m_match_type(Breakpoint::Exact), m_language(language),
5314f1b3e8SDimitry Andric m_skip_prologue(skip_prologue) {
5414f1b3e8SDimitry Andric for (size_t i = 0; i < num_names; i++) {
55f034231aSEd Maste AddNameLookup(ConstString(names[i]), name_type_mask);
56f034231aSEd Maste }
57f034231aSEd Maste }
58f034231aSEd Maste
BreakpointResolverName(const BreakpointSP & bkpt,const std::vector<std::string> & names,FunctionNameType name_type_mask,LanguageType language,lldb::addr_t offset,bool skip_prologue)59b1c73532SDimitry Andric BreakpointResolverName::BreakpointResolverName(
60b1c73532SDimitry Andric const BreakpointSP &bkpt, const std::vector<std::string> &names,
61b1c73532SDimitry Andric FunctionNameType name_type_mask, LanguageType language, lldb::addr_t offset,
6294994d37SDimitry Andric bool skip_prologue)
6314f1b3e8SDimitry Andric : BreakpointResolver(bkpt, BreakpointResolver::NameResolver, offset),
6414f1b3e8SDimitry Andric m_match_type(Breakpoint::Exact), m_language(language),
6514f1b3e8SDimitry Andric m_skip_prologue(skip_prologue) {
6614f1b3e8SDimitry Andric for (const std::string &name : names) {
67f034231aSEd Maste AddNameLookup(ConstString(name.c_str(), name.size()), name_type_mask);
68f034231aSEd Maste }
69f034231aSEd Maste }
70f034231aSEd Maste
BreakpointResolverName(const BreakpointSP & bkpt,RegularExpression func_regex,lldb::LanguageType language,lldb::addr_t offset,bool skip_prologue)71cfca06d7SDimitry Andric BreakpointResolverName::BreakpointResolverName(const BreakpointSP &bkpt,
72ead24645SDimitry Andric RegularExpression func_regex,
73e81d9d49SDimitry Andric lldb::LanguageType language,
74f3fbd1c0SDimitry Andric lldb::addr_t offset,
7514f1b3e8SDimitry Andric bool skip_prologue)
7614f1b3e8SDimitry Andric : BreakpointResolver(bkpt, BreakpointResolver::NameResolver, offset),
77ead24645SDimitry Andric m_class_name(nullptr), m_regex(std::move(func_regex)),
7814f1b3e8SDimitry Andric m_match_type(Breakpoint::Regexp), m_language(language),
7914f1b3e8SDimitry Andric m_skip_prologue(skip_prologue) {}
80f034231aSEd Maste
BreakpointResolverName(const BreakpointResolverName & rhs)8114f1b3e8SDimitry Andric BreakpointResolverName::BreakpointResolverName(
8214f1b3e8SDimitry Andric const BreakpointResolverName &rhs)
83cfca06d7SDimitry Andric : BreakpointResolver(rhs.GetBreakpoint(), BreakpointResolver::NameResolver,
84cfca06d7SDimitry Andric rhs.GetOffset()),
8514f1b3e8SDimitry Andric m_lookups(rhs.m_lookups), m_class_name(rhs.m_class_name),
8614f1b3e8SDimitry Andric m_regex(rhs.m_regex), m_match_type(rhs.m_match_type),
8714f1b3e8SDimitry Andric m_language(rhs.m_language), m_skip_prologue(rhs.m_skip_prologue) {}
8814f1b3e8SDimitry Andric
CreateFromStructuredData(const StructuredData::Dictionary & options_dict,Status & error)89b1c73532SDimitry Andric BreakpointResolverSP BreakpointResolverName::CreateFromStructuredData(
90312c0ed1SDimitry Andric const StructuredData::Dictionary &options_dict, Status &error) {
9114f1b3e8SDimitry Andric LanguageType language = eLanguageTypeUnknown;
92b76161e4SDimitry Andric llvm::StringRef language_name;
9314f1b3e8SDimitry Andric bool success = options_dict.GetValueForKeyAsString(
9414f1b3e8SDimitry Andric GetKey(OptionNames::LanguageName), language_name);
9514f1b3e8SDimitry Andric if (success) {
9614f1b3e8SDimitry Andric language = Language::GetLanguageTypeFromString(language_name);
9714f1b3e8SDimitry Andric if (language == eLanguageTypeUnknown) {
98b76161e4SDimitry Andric error.SetErrorStringWithFormatv("BRN::CFSD: Unknown language: {0}.",
99b76161e4SDimitry Andric language_name);
10014f1b3e8SDimitry Andric return nullptr;
10114f1b3e8SDimitry Andric }
102205afe67SEd Maste }
103205afe67SEd Maste
1047fa27ce4SDimitry Andric lldb::offset_t offset = 0;
10514f1b3e8SDimitry Andric success =
10614f1b3e8SDimitry Andric options_dict.GetValueForKeyAsInteger(GetKey(OptionNames::Offset), offset);
10714f1b3e8SDimitry Andric if (!success) {
108b60736ecSDimitry Andric error.SetErrorString("BRN::CFSD: Missing offset entry.");
10914f1b3e8SDimitry Andric return nullptr;
11014f1b3e8SDimitry Andric }
11114f1b3e8SDimitry Andric
11214f1b3e8SDimitry Andric bool skip_prologue;
11314f1b3e8SDimitry Andric success = options_dict.GetValueForKeyAsBoolean(
11414f1b3e8SDimitry Andric GetKey(OptionNames::SkipPrologue), skip_prologue);
11514f1b3e8SDimitry Andric if (!success) {
116b60736ecSDimitry Andric error.SetErrorString("BRN::CFSD: Missing Skip prologue entry.");
11714f1b3e8SDimitry Andric return nullptr;
11814f1b3e8SDimitry Andric }
11914f1b3e8SDimitry Andric
120b76161e4SDimitry Andric llvm::StringRef regex_text;
12114f1b3e8SDimitry Andric success = options_dict.GetValueForKeyAsString(
12214f1b3e8SDimitry Andric GetKey(OptionNames::RegexString), regex_text);
12314f1b3e8SDimitry Andric if (success) {
124b1c73532SDimitry Andric return std::make_shared<BreakpointResolverName>(
125312c0ed1SDimitry Andric nullptr, RegularExpression(regex_text), language, offset,
126312c0ed1SDimitry Andric skip_prologue);
12714f1b3e8SDimitry Andric } else {
12814f1b3e8SDimitry Andric StructuredData::Array *names_array;
12914f1b3e8SDimitry Andric success = options_dict.GetValueForKeyAsArray(
13014f1b3e8SDimitry Andric GetKey(OptionNames::SymbolNameArray), names_array);
13114f1b3e8SDimitry Andric if (!success) {
132b60736ecSDimitry Andric error.SetErrorString("BRN::CFSD: Missing symbol names entry.");
13314f1b3e8SDimitry Andric return nullptr;
13414f1b3e8SDimitry Andric }
13514f1b3e8SDimitry Andric StructuredData::Array *names_mask_array;
13614f1b3e8SDimitry Andric success = options_dict.GetValueForKeyAsArray(
13714f1b3e8SDimitry Andric GetKey(OptionNames::NameMaskArray), names_mask_array);
13814f1b3e8SDimitry Andric if (!success) {
139b60736ecSDimitry Andric error.SetErrorString("BRN::CFSD: Missing symbol names mask entry.");
14014f1b3e8SDimitry Andric return nullptr;
14114f1b3e8SDimitry Andric }
14214f1b3e8SDimitry Andric
14314f1b3e8SDimitry Andric size_t num_elem = names_array->GetSize();
14414f1b3e8SDimitry Andric if (num_elem != names_mask_array->GetSize()) {
14514f1b3e8SDimitry Andric error.SetErrorString(
14614f1b3e8SDimitry Andric "BRN::CFSD: names and names mask arrays have different sizes.");
14714f1b3e8SDimitry Andric return nullptr;
14814f1b3e8SDimitry Andric }
14914f1b3e8SDimitry Andric
15014f1b3e8SDimitry Andric if (num_elem == 0) {
15114f1b3e8SDimitry Andric error.SetErrorString(
15214f1b3e8SDimitry Andric "BRN::CFSD: no name entry in a breakpoint by name breakpoint.");
15314f1b3e8SDimitry Andric return nullptr;
15414f1b3e8SDimitry Andric }
15514f1b3e8SDimitry Andric std::vector<std::string> names;
15694994d37SDimitry Andric std::vector<FunctionNameType> name_masks;
15714f1b3e8SDimitry Andric for (size_t i = 0; i < num_elem; i++) {
158b1c73532SDimitry Andric std::optional<llvm::StringRef> maybe_name =
159b1c73532SDimitry Andric names_array->GetItemAtIndexAsString(i);
160b1c73532SDimitry Andric if (!maybe_name) {
16114f1b3e8SDimitry Andric error.SetErrorString("BRN::CFSD: name entry is not a string.");
16214f1b3e8SDimitry Andric return nullptr;
16314f1b3e8SDimitry Andric }
164aca2e42cSDimitry Andric auto maybe_fnt = names_mask_array->GetItemAtIndexAsInteger<
165aca2e42cSDimitry Andric std::underlying_type<FunctionNameType>::type>(i);
166aca2e42cSDimitry Andric if (!maybe_fnt) {
16714f1b3e8SDimitry Andric error.SetErrorString("BRN::CFSD: name mask entry is not an integer.");
16814f1b3e8SDimitry Andric return nullptr;
16914f1b3e8SDimitry Andric }
170b1c73532SDimitry Andric names.push_back(std::string(*maybe_name));
171aca2e42cSDimitry Andric name_masks.push_back(static_cast<FunctionNameType>(*maybe_fnt));
17214f1b3e8SDimitry Andric }
17314f1b3e8SDimitry Andric
174b1c73532SDimitry Andric std::shared_ptr<BreakpointResolverName> resolver_sp =
175b1c73532SDimitry Andric std::make_shared<BreakpointResolverName>(
176312c0ed1SDimitry Andric nullptr, names[0].c_str(), name_masks[0], language,
17714f1b3e8SDimitry Andric Breakpoint::MatchType::Exact, offset, skip_prologue);
17814f1b3e8SDimitry Andric for (size_t i = 1; i < num_elem; i++) {
179b1c73532SDimitry Andric resolver_sp->AddNameLookup(ConstString(names[i]), name_masks[i]);
18014f1b3e8SDimitry Andric }
181b1c73532SDimitry Andric return resolver_sp;
18214f1b3e8SDimitry Andric }
18314f1b3e8SDimitry Andric }
18414f1b3e8SDimitry Andric
SerializeToStructuredData()18514f1b3e8SDimitry Andric StructuredData::ObjectSP BreakpointResolverName::SerializeToStructuredData() {
18614f1b3e8SDimitry Andric StructuredData::DictionarySP options_dict_sp(
18714f1b3e8SDimitry Andric new StructuredData::Dictionary());
18814f1b3e8SDimitry Andric
18914f1b3e8SDimitry Andric if (m_regex.IsValid()) {
19014f1b3e8SDimitry Andric options_dict_sp->AddStringItem(GetKey(OptionNames::RegexString),
19114f1b3e8SDimitry Andric m_regex.GetText());
19214f1b3e8SDimitry Andric } else {
19314f1b3e8SDimitry Andric StructuredData::ArraySP names_sp(new StructuredData::Array());
19414f1b3e8SDimitry Andric StructuredData::ArraySP name_masks_sp(new StructuredData::Array());
19514f1b3e8SDimitry Andric for (auto lookup : m_lookups) {
19614f1b3e8SDimitry Andric names_sp->AddItem(StructuredData::StringSP(
197cfca06d7SDimitry Andric new StructuredData::String(lookup.GetName().GetStringRef())));
1987fa27ce4SDimitry Andric name_masks_sp->AddItem(StructuredData::UnsignedIntegerSP(
1997fa27ce4SDimitry Andric new StructuredData::UnsignedInteger(lookup.GetNameTypeMask())));
20014f1b3e8SDimitry Andric }
20114f1b3e8SDimitry Andric options_dict_sp->AddItem(GetKey(OptionNames::SymbolNameArray), names_sp);
20214f1b3e8SDimitry Andric options_dict_sp->AddItem(GetKey(OptionNames::NameMaskArray), name_masks_sp);
20314f1b3e8SDimitry Andric }
20414f1b3e8SDimitry Andric if (m_language != eLanguageTypeUnknown)
20514f1b3e8SDimitry Andric options_dict_sp->AddStringItem(
20614f1b3e8SDimitry Andric GetKey(OptionNames::LanguageName),
20714f1b3e8SDimitry Andric Language::GetNameForLanguageType(m_language));
20814f1b3e8SDimitry Andric options_dict_sp->AddBooleanItem(GetKey(OptionNames::SkipPrologue),
20914f1b3e8SDimitry Andric m_skip_prologue);
21014f1b3e8SDimitry Andric
21114f1b3e8SDimitry Andric return WrapOptionsDict(options_dict_sp);
21214f1b3e8SDimitry Andric }
21314f1b3e8SDimitry Andric
AddNameLookup(ConstString name,FunctionNameType name_type_mask)2145f29bb8aSDimitry Andric void BreakpointResolverName::AddNameLookup(ConstString name,
21594994d37SDimitry Andric FunctionNameType name_type_mask) {
2165f29bb8aSDimitry Andric
217f3fbd1c0SDimitry Andric Module::LookupInfo lookup(name, name_type_mask, m_language);
2185f29bb8aSDimitry Andric m_lookups.emplace_back(lookup);
2195f29bb8aSDimitry Andric
2205f29bb8aSDimitry Andric auto add_variant_funcs = [&](Language *lang) {
221344a3780SDimitry Andric for (Language::MethodNameVariant variant :
222344a3780SDimitry Andric lang->GetMethodNameVariants(name)) {
223344a3780SDimitry Andric // FIXME: Should we be adding variants that aren't of type Full?
224344a3780SDimitry Andric if (variant.GetType() & lldb::eFunctionNameTypeFull) {
225344a3780SDimitry Andric Module::LookupInfo variant_lookup(name, variant.GetType(),
2265f29bb8aSDimitry Andric lang->GetLanguageType());
227344a3780SDimitry Andric variant_lookup.SetLookupName(variant.GetName());
2285f29bb8aSDimitry Andric m_lookups.emplace_back(variant_lookup);
2295f29bb8aSDimitry Andric }
230344a3780SDimitry Andric }
2315f29bb8aSDimitry Andric return true;
2325f29bb8aSDimitry Andric };
2335f29bb8aSDimitry Andric
2345f29bb8aSDimitry Andric if (Language *lang = Language::FindPlugin(m_language)) {
2355f29bb8aSDimitry Andric add_variant_funcs(lang);
2365f29bb8aSDimitry Andric } else {
2375f29bb8aSDimitry Andric // Most likely m_language is eLanguageTypeUnknown. We check each language for
2385f29bb8aSDimitry Andric // possible variants or more qualified names and create lookups for those as
2395f29bb8aSDimitry Andric // well.
2405f29bb8aSDimitry Andric Language::ForEach(add_variant_funcs);
241f034231aSEd Maste }
242f034231aSEd Maste }
243f034231aSEd Maste
24414f1b3e8SDimitry Andric // FIXME: Right now we look at the module level, and call the module's
24514f1b3e8SDimitry Andric // "FindFunctions".
24614f1b3e8SDimitry Andric // Greg says he will add function tables, maybe at the CompileUnit level to
247f73363f1SDimitry Andric // accelerate function lookup. At that point, we should switch the depth to
248f73363f1SDimitry Andric // CompileUnit, and look in these tables.
249f034231aSEd Maste
250f034231aSEd Maste Searcher::CallbackReturn
SearchCallback(SearchFilter & filter,SymbolContext & context,Address * addr)251e81d9d49SDimitry Andric BreakpointResolverName::SearchCallback(SearchFilter &filter,
252ead24645SDimitry Andric SymbolContext &context, Address *addr) {
253145449b1SDimitry Andric Log *log = GetLog(LLDBLog::Breakpoints);
254f034231aSEd Maste
25514f1b3e8SDimitry Andric if (m_class_name) {
256f034231aSEd Maste if (log)
257f034231aSEd Maste log->Warning("Class/method function specification not supported yet.\n");
258f034231aSEd Maste return Searcher::eCallbackReturnStop;
259f034231aSEd Maste }
260cfca06d7SDimitry Andric
261cfca06d7SDimitry Andric SymbolContextList func_list;
26214f1b3e8SDimitry Andric bool filter_by_cu =
26314f1b3e8SDimitry Andric (filter.GetFilterRequiredItems() & eSymbolContextCompUnit) != 0;
264e81d9d49SDimitry Andric bool filter_by_language = (m_language != eLanguageTypeUnknown);
265c0981da4SDimitry Andric
266c0981da4SDimitry Andric ModuleFunctionSearchOptions function_options;
267c0981da4SDimitry Andric function_options.include_symbols = !filter_by_cu;
268c0981da4SDimitry Andric function_options.include_inlines = true;
269f034231aSEd Maste
27014f1b3e8SDimitry Andric switch (m_match_type) {
271f034231aSEd Maste case Breakpoint::Exact:
27214f1b3e8SDimitry Andric if (context.module_sp) {
27314f1b3e8SDimitry Andric for (const auto &lookup : m_lookups) {
274f034231aSEd Maste const size_t start_func_idx = func_list.GetSize();
275e3b55780SDimitry Andric context.module_sp->FindFunctions(lookup, CompilerDeclContext(),
276e3b55780SDimitry Andric function_options, func_list);
277f3fbd1c0SDimitry Andric
278f034231aSEd Maste const size_t end_func_idx = func_list.GetSize();
279f034231aSEd Maste
280f034231aSEd Maste if (start_func_idx < end_func_idx)
281f034231aSEd Maste lookup.Prune(func_list, start_func_idx);
282f034231aSEd Maste }
283f034231aSEd Maste }
284f034231aSEd Maste break;
285f034231aSEd Maste case Breakpoint::Regexp:
28614f1b3e8SDimitry Andric if (context.module_sp) {
287c0981da4SDimitry Andric context.module_sp->FindFunctions(m_regex, function_options, func_list);
288f034231aSEd Maste }
289f034231aSEd Maste break;
290f034231aSEd Maste case Breakpoint::Glob:
291f034231aSEd Maste if (log)
292f034231aSEd Maste log->Warning("glob is not supported yet.");
293f034231aSEd Maste break;
294f034231aSEd Maste }
295f034231aSEd Maste
296f73363f1SDimitry Andric // If the filter specifies a Compilation Unit, remove the ones that don't
297f73363f1SDimitry Andric // pass at this point.
29814f1b3e8SDimitry Andric if (filter_by_cu || filter_by_language) {
299f034231aSEd Maste uint32_t num_functions = func_list.GetSize();
300f034231aSEd Maste
30114f1b3e8SDimitry Andric for (size_t idx = 0; idx < num_functions; idx++) {
302e81d9d49SDimitry Andric bool remove_it = false;
303f034231aSEd Maste SymbolContext sc;
304f034231aSEd Maste func_list.GetContextAtIndex(idx, sc);
30514f1b3e8SDimitry Andric if (filter_by_cu) {
306f034231aSEd Maste if (!sc.comp_unit || !filter.CompUnitPasses(*sc.comp_unit))
307e81d9d49SDimitry Andric remove_it = true;
308e81d9d49SDimitry Andric }
309e81d9d49SDimitry Andric
31014f1b3e8SDimitry Andric if (filter_by_language) {
311e81d9d49SDimitry Andric LanguageType sym_language = sc.GetLanguage();
312e81d9d49SDimitry Andric if ((Language::GetPrimaryLanguage(sym_language) !=
313e81d9d49SDimitry Andric Language::GetPrimaryLanguage(m_language)) &&
31414f1b3e8SDimitry Andric (sym_language != eLanguageTypeUnknown)) {
315e81d9d49SDimitry Andric remove_it = true;
316e81d9d49SDimitry Andric }
317e81d9d49SDimitry Andric }
318e81d9d49SDimitry Andric
31914f1b3e8SDimitry Andric if (remove_it) {
320f034231aSEd Maste func_list.RemoveContextAtIndex(idx);
321f034231aSEd Maste num_functions--;
322f034231aSEd Maste idx--;
323f034231aSEd Maste }
324f034231aSEd Maste }
325f034231aSEd Maste }
326f034231aSEd Maste
327cfca06d7SDimitry Andric BreakpointSP breakpoint_sp = GetBreakpoint();
328cfca06d7SDimitry Andric Breakpoint &breakpoint = *breakpoint_sp;
329cfca06d7SDimitry Andric Address break_addr;
330cfca06d7SDimitry Andric
3310cac4ca3SEd Maste // Remove any duplicates between the function list and the symbol list
3327fa27ce4SDimitry Andric for (const SymbolContext &sc : func_list) {
333866dcdacSEd Maste bool is_reexported = false;
334866dcdacSEd Maste
33514f1b3e8SDimitry Andric if (sc.block && sc.block->GetInlinedFunctionInfo()) {
336f034231aSEd Maste if (!sc.block->GetStartAddress(break_addr))
337f034231aSEd Maste break_addr.Clear();
33814f1b3e8SDimitry Andric } else if (sc.function) {
339f034231aSEd Maste break_addr = sc.function->GetAddressRange().GetBaseAddress();
34014f1b3e8SDimitry Andric if (m_skip_prologue && break_addr.IsValid()) {
341cfca06d7SDimitry Andric const uint32_t prologue_byte_size = sc.function->GetPrologueByteSize();
342f034231aSEd Maste if (prologue_byte_size)
343f034231aSEd Maste break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size);
344f034231aSEd Maste }
34514f1b3e8SDimitry Andric } else if (sc.symbol) {
34614f1b3e8SDimitry Andric if (sc.symbol->GetType() == eSymbolTypeReExported) {
34714f1b3e8SDimitry Andric const Symbol *actual_symbol =
348cfca06d7SDimitry Andric sc.symbol->ResolveReExportedSymbol(breakpoint.GetTarget());
34914f1b3e8SDimitry Andric if (actual_symbol) {
350866dcdacSEd Maste is_reexported = true;
351f21a844fSEd Maste break_addr = actual_symbol->GetAddress();
352f21a844fSEd Maste }
35314f1b3e8SDimitry Andric } else {
354f034231aSEd Maste break_addr = sc.symbol->GetAddress();
355f21a844fSEd Maste }
356f21a844fSEd Maste
35714f1b3e8SDimitry Andric if (m_skip_prologue && break_addr.IsValid()) {
358cfca06d7SDimitry Andric const uint32_t prologue_byte_size = sc.symbol->GetPrologueByteSize();
359f034231aSEd Maste if (prologue_byte_size)
360f034231aSEd Maste break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size);
361f73363f1SDimitry Andric else {
362f73363f1SDimitry Andric const Architecture *arch =
363cfca06d7SDimitry Andric breakpoint.GetTarget().GetArchitecturePlugin();
364f73363f1SDimitry Andric if (arch)
365f73363f1SDimitry Andric arch->AdjustBreakpointAddress(*sc.symbol, break_addr);
366f73363f1SDimitry Andric }
367f034231aSEd Maste }
368f034231aSEd Maste }
369f034231aSEd Maste
370cfca06d7SDimitry Andric if (!break_addr.IsValid())
371cfca06d7SDimitry Andric continue;
372cfca06d7SDimitry Andric
373cfca06d7SDimitry Andric if (!filter.AddressPasses(break_addr))
374cfca06d7SDimitry Andric continue;
375cfca06d7SDimitry Andric
376cfca06d7SDimitry Andric bool new_location;
377cfca06d7SDimitry Andric BreakpointLocationSP bp_loc_sp(AddLocation(break_addr, &new_location));
378866dcdacSEd Maste bp_loc_sp->SetIsReExported(is_reexported);
379cfca06d7SDimitry Andric if (bp_loc_sp && new_location && !breakpoint.IsInternal()) {
38014f1b3e8SDimitry Andric if (log) {
381f034231aSEd Maste StreamString s;
382f034231aSEd Maste bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
383ead24645SDimitry Andric LLDB_LOGF(log, "Added location: %s\n", s.GetData());
384f034231aSEd Maste }
385f034231aSEd Maste }
386f034231aSEd Maste }
387f034231aSEd Maste
388f034231aSEd Maste return Searcher::eCallbackReturnContinue;
389f034231aSEd Maste }
390f034231aSEd Maste
GetDepth()39194994d37SDimitry Andric lldb::SearchDepth BreakpointResolverName::GetDepth() {
39294994d37SDimitry Andric return lldb::eSearchDepthModule;
393f034231aSEd Maste }
394f034231aSEd Maste
GetDescription(Stream * s)39514f1b3e8SDimitry Andric void BreakpointResolverName::GetDescription(Stream *s) {
396f034231aSEd Maste if (m_match_type == Breakpoint::Regexp)
39714f1b3e8SDimitry Andric s->Printf("regex = '%s'", m_regex.GetText().str().c_str());
39814f1b3e8SDimitry Andric else {
399f034231aSEd Maste size_t num_names = m_lookups.size();
400f034231aSEd Maste if (num_names == 1)
401f3fbd1c0SDimitry Andric s->Printf("name = '%s'", m_lookups[0].GetName().GetCString());
40214f1b3e8SDimitry Andric else {
403f034231aSEd Maste s->Printf("names = {");
40414f1b3e8SDimitry Andric for (size_t i = 0; i < num_names; i++) {
40514f1b3e8SDimitry Andric s->Printf("%s'%s'", (i == 0 ? "" : ", "),
40614f1b3e8SDimitry Andric m_lookups[i].GetName().GetCString());
407f034231aSEd Maste }
408f3fbd1c0SDimitry Andric s->Printf("}");
409f034231aSEd Maste }
410f034231aSEd Maste }
41114f1b3e8SDimitry Andric if (m_language != eLanguageTypeUnknown) {
412e81d9d49SDimitry Andric s->Printf(", language = %s", Language::GetNameForLanguageType(m_language));
413e81d9d49SDimitry Andric }
414f034231aSEd Maste }
415f034231aSEd Maste
Dump(Stream * s) const41614f1b3e8SDimitry Andric void BreakpointResolverName::Dump(Stream *s) const {}
417f034231aSEd Maste
418205afe67SEd Maste lldb::BreakpointResolverSP
CopyForBreakpoint(BreakpointSP & breakpoint)419cfca06d7SDimitry Andric BreakpointResolverName::CopyForBreakpoint(BreakpointSP &breakpoint) {
420205afe67SEd Maste lldb::BreakpointResolverSP ret_sp(new BreakpointResolverName(*this));
421cfca06d7SDimitry Andric ret_sp->SetBreakpoint(breakpoint);
422205afe67SEd Maste return ret_sp;
423205afe67SEd Maste }
424