180814287SRaphael Isemann //===-- BreakpointResolverName.cpp ----------------------------------------===//
230fdc8d8SChris Lattner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
630fdc8d8SChris Lattner //
730fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
830fdc8d8SChris Lattner 
916fd7511SEugene Zelenko #include "lldb/Breakpoint/BreakpointResolverName.h"
1016fd7511SEugene Zelenko 
1130fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointLocation.h"
1208581263SJim Ingham #include "lldb/Core/Architecture.h"
131f746071SGreg Clayton #include "lldb/Core/Module.h"
141f746071SGreg Clayton #include "lldb/Symbol/Block.h"
151f746071SGreg Clayton #include "lldb/Symbol/Function.h"
161f746071SGreg Clayton #include "lldb/Symbol/Symbol.h"
171f746071SGreg Clayton #include "lldb/Symbol/SymbolContext.h"
1858a638b7SAlex Langford #include "lldb/Target/Language.h"
19c34698a8SPavel Labath #include "lldb/Target/Target.h"
20c34698a8SPavel Labath #include "lldb/Utility/LLDBLog.h"
216f9e6901SZachary Turner #include "lldb/Utility/Log.h"
22bf9a7730SZachary Turner #include "lldb/Utility/StreamString.h"
2330fdc8d8SChris Lattner 
2430fdc8d8SChris Lattner using namespace lldb;
2530fdc8d8SChris Lattner using namespace lldb_private;
2630fdc8d8SChris Lattner 
BreakpointResolverName(const BreakpointSP & bkpt,const char * name_cstr,FunctionNameType name_type_mask,LanguageType language,Breakpoint::MatchType type,lldb::addr_t offset,bool skip_prologue)276c17cc53STatyana Krasnukha BreakpointResolverName::BreakpointResolverName(const BreakpointSP &bkpt,
286c17cc53STatyana Krasnukha     const char *name_cstr, FunctionNameType name_type_mask,
29b9c1b51eSKate Stone     LanguageType language, Breakpoint::MatchType type, lldb::addr_t offset,
30b9c1b51eSKate Stone     bool skip_prologue)
31b9c1b51eSKate Stone     : BreakpointResolver(bkpt, BreakpointResolver::NameResolver, offset),
32*ee4b6cf5SKazu Hirata       m_match_type(type), m_language(language), m_skip_prologue(skip_prologue) {
33b9c1b51eSKate Stone   if (m_match_type == Breakpoint::Regexp) {
34bbea3610SRaphael Isemann     m_regex = RegularExpression(name_cstr);
35f9d90bc5SJan Kratochvil     if (!m_regex.IsValid()) {
36a007a6d8SPavel Labath       Log *log = GetLog(LLDBLog::Breakpoints);
3730fdc8d8SChris Lattner 
3830fdc8d8SChris Lattner       if (log)
39b9c1b51eSKate Stone         log->Warning("function name regexp: \"%s\" did not compile.",
40b9c1b51eSKate Stone                      name_cstr);
4130fdc8d8SChris Lattner     }
42b9c1b51eSKate Stone   } else {
4343fe217bSGreg Clayton     AddNameLookup(ConstString(name_cstr), name_type_mask);
44133e0fb3SJim Ingham   }
45133e0fb3SJim Ingham }
46133e0fb3SJim Ingham 
BreakpointResolverName(const BreakpointSP & bkpt,const char * names[],size_t num_names,FunctionNameType name_type_mask,LanguageType language,lldb::addr_t offset,bool skip_prologue)47b9c1b51eSKate Stone BreakpointResolverName::BreakpointResolverName(
486c17cc53STatyana Krasnukha     const BreakpointSP &bkpt, const char *names[], size_t num_names,
49117b1fa1SZachary Turner     FunctionNameType name_type_mask, LanguageType language, lldb::addr_t offset,
50b9c1b51eSKate Stone     bool skip_prologue)
51b9c1b51eSKate Stone     : BreakpointResolver(bkpt, BreakpointResolver::NameResolver, offset),
52b9c1b51eSKate Stone       m_match_type(Breakpoint::Exact), m_language(language),
53b9c1b51eSKate Stone       m_skip_prologue(skip_prologue) {
54b9c1b51eSKate Stone   for (size_t i = 0; i < num_names; i++) {
5543fe217bSGreg Clayton     AddNameLookup(ConstString(names[i]), name_type_mask);
56133e0fb3SJim Ingham   }
5730fdc8d8SChris Lattner }
5830fdc8d8SChris Lattner 
BreakpointResolverName(const BreakpointSP & bkpt,std::vector<std::string> names,FunctionNameType name_type_mask,LanguageType language,lldb::addr_t offset,bool skip_prologue)596c17cc53STatyana Krasnukha BreakpointResolverName::BreakpointResolverName(const BreakpointSP &bkpt,
60117b1fa1SZachary Turner                                                std::vector<std::string> names,
61117b1fa1SZachary Turner                                                FunctionNameType name_type_mask,
62117b1fa1SZachary Turner                                                LanguageType language,
63117b1fa1SZachary Turner                                                lldb::addr_t offset,
64117b1fa1SZachary Turner                                                bool skip_prologue)
65b9c1b51eSKate Stone     : BreakpointResolver(bkpt, BreakpointResolver::NameResolver, offset),
66b9c1b51eSKate Stone       m_match_type(Breakpoint::Exact), m_language(language),
67b9c1b51eSKate Stone       m_skip_prologue(skip_prologue) {
68b9c1b51eSKate Stone   for (const std::string &name : names) {
6943fe217bSGreg Clayton     AddNameLookup(ConstString(name.c_str(), name.size()), name_type_mask);
70fab10e89SJim Ingham   }
71fab10e89SJim Ingham }
72fab10e89SJim Ingham 
BreakpointResolverName(const BreakpointSP & bkpt,RegularExpression func_regex,lldb::LanguageType language,lldb::addr_t offset,bool skip_prologue)736c17cc53STatyana Krasnukha BreakpointResolverName::BreakpointResolverName(const BreakpointSP &bkpt,
743af3f1e8SJonas Devlieghere                                                RegularExpression func_regex,
750fcdac36SJim Ingham                                                lldb::LanguageType language,
762411167fSJim Ingham                                                lldb::addr_t offset,
77b9c1b51eSKate Stone                                                bool skip_prologue)
78b9c1b51eSKate Stone     : BreakpointResolver(bkpt, BreakpointResolver::NameResolver, offset),
793af3f1e8SJonas Devlieghere       m_class_name(nullptr), m_regex(std::move(func_regex)),
80b9c1b51eSKate Stone       m_match_type(Breakpoint::Regexp), m_language(language),
81b9c1b51eSKate Stone       m_skip_prologue(skip_prologue) {}
8230fdc8d8SChris Lattner 
BreakpointResolverName(const BreakpointResolverName & rhs)83b9c1b51eSKate Stone BreakpointResolverName::BreakpointResolverName(
84b9c1b51eSKate Stone     const BreakpointResolverName &rhs)
856c17cc53STatyana Krasnukha     : BreakpointResolver(rhs.GetBreakpoint(), BreakpointResolver::NameResolver,
866c17cc53STatyana Krasnukha                          rhs.GetOffset()),
87b9c1b51eSKate Stone       m_lookups(rhs.m_lookups), m_class_name(rhs.m_class_name),
88b9c1b51eSKate Stone       m_regex(rhs.m_regex), m_match_type(rhs.m_match_type),
89b9c1b51eSKate Stone       m_language(rhs.m_language), m_skip_prologue(rhs.m_skip_prologue) {}
9033df7cd3SJim Ingham 
CreateFromStructuredData(const BreakpointSP & bkpt,const StructuredData::Dictionary & options_dict,Status & error)91e14dc268SJim Ingham BreakpointResolver *BreakpointResolverName::CreateFromStructuredData(
926c17cc53STatyana Krasnukha     const BreakpointSP &bkpt, const StructuredData::Dictionary &options_dict,
9397206d57SZachary Turner     Status &error) {
94e14dc268SJim Ingham   LanguageType language = eLanguageTypeUnknown;
952833321fSZachary Turner   llvm::StringRef language_name;
96e14dc268SJim Ingham   bool success = options_dict.GetValueForKeyAsString(
97e14dc268SJim Ingham       GetKey(OptionNames::LanguageName), language_name);
98e14dc268SJim Ingham   if (success) {
996fa7681bSZachary Turner     language = Language::GetLanguageTypeFromString(language_name);
100e14dc268SJim Ingham     if (language == eLanguageTypeUnknown) {
1012833321fSZachary Turner       error.SetErrorStringWithFormatv("BRN::CFSD: Unknown language: {0}.",
1022833321fSZachary Turner                                       language_name);
103e14dc268SJim Ingham       return nullptr;
104e14dc268SJim Ingham     }
105e14dc268SJim Ingham   }
106e14dc268SJim Ingham 
107e14dc268SJim Ingham   lldb::addr_t offset = 0;
108e14dc268SJim Ingham   success =
109e14dc268SJim Ingham       options_dict.GetValueForKeyAsInteger(GetKey(OptionNames::Offset), offset);
110e14dc268SJim Ingham   if (!success) {
11189533764SJonas Devlieghere     error.SetErrorString("BRN::CFSD: Missing offset entry.");
112e14dc268SJim Ingham     return nullptr;
113e14dc268SJim Ingham   }
114e14dc268SJim Ingham 
115e14dc268SJim Ingham   bool skip_prologue;
116e14dc268SJim Ingham   success = options_dict.GetValueForKeyAsBoolean(
117e14dc268SJim Ingham       GetKey(OptionNames::SkipPrologue), skip_prologue);
118e14dc268SJim Ingham   if (!success) {
11989533764SJonas Devlieghere     error.SetErrorString("BRN::CFSD: Missing Skip prologue entry.");
120e14dc268SJim Ingham     return nullptr;
121e14dc268SJim Ingham   }
122e14dc268SJim Ingham 
1232833321fSZachary Turner   llvm::StringRef regex_text;
124e14dc268SJim Ingham   success = options_dict.GetValueForKeyAsString(
125e14dc268SJim Ingham       GetKey(OptionNames::RegexString), regex_text);
126e14dc268SJim Ingham   if (success) {
1275aa1d819SJan Kratochvil     return new BreakpointResolverName(bkpt, RegularExpression(regex_text),
1285aa1d819SJan Kratochvil                                       language, offset, skip_prologue);
129e14dc268SJim Ingham   } else {
130e14dc268SJim Ingham     StructuredData::Array *names_array;
131e14dc268SJim Ingham     success = options_dict.GetValueForKeyAsArray(
132e14dc268SJim Ingham         GetKey(OptionNames::SymbolNameArray), names_array);
133e14dc268SJim Ingham     if (!success) {
13489533764SJonas Devlieghere       error.SetErrorString("BRN::CFSD: Missing symbol names entry.");
135e14dc268SJim Ingham       return nullptr;
136e14dc268SJim Ingham     }
137e14dc268SJim Ingham     StructuredData::Array *names_mask_array;
138e14dc268SJim Ingham     success = options_dict.GetValueForKeyAsArray(
139e14dc268SJim Ingham         GetKey(OptionNames::NameMaskArray), names_mask_array);
140e14dc268SJim Ingham     if (!success) {
14189533764SJonas Devlieghere       error.SetErrorString("BRN::CFSD: Missing symbol names mask entry.");
142e14dc268SJim Ingham       return nullptr;
143e14dc268SJim Ingham     }
144e14dc268SJim Ingham 
145e14dc268SJim Ingham     size_t num_elem = names_array->GetSize();
146e14dc268SJim Ingham     if (num_elem != names_mask_array->GetSize()) {
147e14dc268SJim Ingham       error.SetErrorString(
148e14dc268SJim Ingham           "BRN::CFSD: names and names mask arrays have different sizes.");
149e14dc268SJim Ingham       return nullptr;
150e14dc268SJim Ingham     }
151e14dc268SJim Ingham 
152e14dc268SJim Ingham     if (num_elem == 0) {
153e14dc268SJim Ingham       error.SetErrorString(
154e14dc268SJim Ingham           "BRN::CFSD: no name entry in a breakpoint by name breakpoint.");
155e14dc268SJim Ingham       return nullptr;
156e14dc268SJim Ingham     }
157e14dc268SJim Ingham     std::vector<std::string> names;
158117b1fa1SZachary Turner     std::vector<FunctionNameType> name_masks;
159e14dc268SJim Ingham     for (size_t i = 0; i < num_elem; i++) {
1602833321fSZachary Turner       llvm::StringRef name;
161e14dc268SJim Ingham 
162e14dc268SJim Ingham       success = names_array->GetItemAtIndexAsString(i, name);
163e14dc268SJim Ingham       if (!success) {
164e14dc268SJim Ingham         error.SetErrorString("BRN::CFSD: name entry is not a string.");
165e14dc268SJim Ingham         return nullptr;
166e14dc268SJim Ingham       }
167117b1fa1SZachary Turner       std::underlying_type<FunctionNameType>::type fnt;
168117b1fa1SZachary Turner       success = names_mask_array->GetItemAtIndexAsInteger(i, fnt);
169e14dc268SJim Ingham       if (!success) {
170e14dc268SJim Ingham         error.SetErrorString("BRN::CFSD: name mask entry is not an integer.");
171e14dc268SJim Ingham         return nullptr;
172e14dc268SJim Ingham       }
173adcd0268SBenjamin Kramer       names.push_back(std::string(name));
174117b1fa1SZachary Turner       name_masks.push_back(static_cast<FunctionNameType>(fnt));
175e14dc268SJim Ingham     }
176e14dc268SJim Ingham 
177e14dc268SJim Ingham     BreakpointResolverName *resolver = new BreakpointResolverName(
178e14dc268SJim Ingham         bkpt, names[0].c_str(), name_masks[0], language,
179e14dc268SJim Ingham         Breakpoint::MatchType::Exact, offset, skip_prologue);
180e14dc268SJim Ingham     for (size_t i = 1; i < num_elem; i++) {
181e14dc268SJim Ingham       resolver->AddNameLookup(ConstString(names[i]), name_masks[i]);
182e14dc268SJim Ingham     }
183e14dc268SJim Ingham     return resolver;
184e14dc268SJim Ingham   }
185e14dc268SJim Ingham }
186e14dc268SJim Ingham 
SerializeToStructuredData()187e14dc268SJim Ingham StructuredData::ObjectSP BreakpointResolverName::SerializeToStructuredData() {
188e14dc268SJim Ingham   StructuredData::DictionarySP options_dict_sp(
189e14dc268SJim Ingham       new StructuredData::Dictionary());
190e14dc268SJim Ingham 
191e14dc268SJim Ingham   if (m_regex.IsValid()) {
192e14dc268SJim Ingham     options_dict_sp->AddStringItem(GetKey(OptionNames::RegexString),
193e14dc268SJim Ingham                                    m_regex.GetText());
194e14dc268SJim Ingham   } else {
195e14dc268SJim Ingham     StructuredData::ArraySP names_sp(new StructuredData::Array());
196e14dc268SJim Ingham     StructuredData::ArraySP name_masks_sp(new StructuredData::Array());
197e14dc268SJim Ingham     for (auto lookup : m_lookups) {
198e14dc268SJim Ingham       names_sp->AddItem(StructuredData::StringSP(
199642bc15dSRaphael Isemann           new StructuredData::String(lookup.GetName().GetStringRef())));
200e14dc268SJim Ingham       name_masks_sp->AddItem(StructuredData::IntegerSP(
201e14dc268SJim Ingham           new StructuredData::Integer(lookup.GetNameTypeMask())));
202e14dc268SJim Ingham     }
203e14dc268SJim Ingham     options_dict_sp->AddItem(GetKey(OptionNames::SymbolNameArray), names_sp);
204e14dc268SJim Ingham     options_dict_sp->AddItem(GetKey(OptionNames::NameMaskArray), name_masks_sp);
205e14dc268SJim Ingham   }
206e14dc268SJim Ingham   if (m_language != eLanguageTypeUnknown)
207e14dc268SJim Ingham     options_dict_sp->AddStringItem(
208e14dc268SJim Ingham         GetKey(OptionNames::LanguageName),
209e14dc268SJim Ingham         Language::GetNameForLanguageType(m_language));
210e14dc268SJim Ingham   options_dict_sp->AddBooleanItem(GetKey(OptionNames::SkipPrologue),
211e14dc268SJim Ingham                                   m_skip_prologue);
212e14dc268SJim Ingham 
213e14dc268SJim Ingham   return WrapOptionsDict(options_dict_sp);
214e14dc268SJim Ingham }
215e14dc268SJim Ingham 
AddNameLookup(ConstString name,FunctionNameType name_type_mask)2160e4c4821SAdrian Prantl void BreakpointResolverName::AddNameLookup(ConstString name,
217117b1fa1SZachary Turner                                            FunctionNameType name_type_mask) {
21858a638b7SAlex Langford 
2196234a5c8SGreg Clayton   Module::LookupInfo lookup(name, name_type_mask, m_language);
22058a638b7SAlex Langford   m_lookups.emplace_back(lookup);
22158a638b7SAlex Langford 
22258a638b7SAlex Langford   auto add_variant_funcs = [&](Language *lang) {
2235bebc0b1SAlex Langford     for (Language::MethodNameVariant variant :
2245bebc0b1SAlex Langford          lang->GetMethodNameVariants(name)) {
2255bebc0b1SAlex Langford       // FIXME: Should we be adding variants that aren't of type Full?
2265bebc0b1SAlex Langford       if (variant.GetType() & lldb::eFunctionNameTypeFull) {
2275bebc0b1SAlex Langford         Module::LookupInfo variant_lookup(name, variant.GetType(),
22858a638b7SAlex Langford                                           lang->GetLanguageType());
2295bebc0b1SAlex Langford         variant_lookup.SetLookupName(variant.GetName());
23058a638b7SAlex Langford         m_lookups.emplace_back(variant_lookup);
23158a638b7SAlex Langford       }
2325bebc0b1SAlex Langford     }
23358a638b7SAlex Langford     return true;
23458a638b7SAlex Langford   };
23558a638b7SAlex Langford 
23658a638b7SAlex Langford   if (Language *lang = Language::FindPlugin(m_language)) {
23758a638b7SAlex Langford     add_variant_funcs(lang);
23858a638b7SAlex Langford   } else {
23958a638b7SAlex Langford     // Most likely m_language is eLanguageTypeUnknown. We check each language for
24058a638b7SAlex Langford     // possible variants or more qualified names and create lookups for those as
24158a638b7SAlex Langford     // well.
24258a638b7SAlex Langford     Language::ForEach(add_variant_funcs);
24343fe217bSGreg Clayton   }
24443fe217bSGreg Clayton }
24543fe217bSGreg Clayton 
246b9c1b51eSKate Stone // FIXME: Right now we look at the module level, and call the module's
247b9c1b51eSKate Stone // "FindFunctions".
248b9c1b51eSKate Stone // Greg says he will add function tables, maybe at the CompileUnit level to
24905097246SAdrian Prantl // accelerate function lookup.  At that point, we should switch the depth to
25005097246SAdrian Prantl // CompileUnit, and look in these tables.
25130fdc8d8SChris Lattner 
25230fdc8d8SChris Lattner Searcher::CallbackReturn
SearchCallback(SearchFilter & filter,SymbolContext & context,Address * addr)25316fd7511SEugene Zelenko BreakpointResolverName::SearchCallback(SearchFilter &filter,
25495e264fcSRaphael Isemann                                        SymbolContext &context, Address *addr) {
255a007a6d8SPavel Labath   Log *log = GetLog(LLDBLog::Breakpoints);
25630fdc8d8SChris Lattner 
257b9c1b51eSKate Stone   if (m_class_name) {
25830fdc8d8SChris Lattner     if (log)
25930fdc8d8SChris Lattner       log->Warning("Class/method function specification not supported yet.\n");
26030fdc8d8SChris Lattner     return Searcher::eCallbackReturnStop;
26130fdc8d8SChris Lattner   }
2626c17cc53STatyana Krasnukha 
263b1324e74STatyana Krasnukha   SymbolContextList func_list;
264b9c1b51eSKate Stone   bool filter_by_cu =
265b9c1b51eSKate Stone       (filter.GetFilterRequiredItems() & eSymbolContextCompUnit) != 0;
2660fcdac36SJim Ingham   bool filter_by_language = (m_language != eLanguageTypeUnknown);
267c020be17SJonas Devlieghere 
268c020be17SJonas Devlieghere   ModuleFunctionSearchOptions function_options;
269c020be17SJonas Devlieghere   function_options.include_symbols = !filter_by_cu;
270c020be17SJonas Devlieghere   function_options.include_inlines = true;
27187df91b8SJim Ingham 
272b9c1b51eSKate Stone   switch (m_match_type) {
27330fdc8d8SChris Lattner   case Breakpoint::Exact:
274b9c1b51eSKate Stone     if (context.module_sp) {
275b9c1b51eSKate Stone       for (const auto &lookup : m_lookups) {
27643fe217bSGreg Clayton         const size_t start_func_idx = func_list.GetSize();
277b9c1b51eSKate Stone         context.module_sp->FindFunctions(
278f9568a95SRaphael Isemann             lookup.GetLookupName(), CompilerDeclContext(),
279c020be17SJonas Devlieghere             lookup.GetNameTypeMask(), function_options, func_list);
2806234a5c8SGreg Clayton 
28143fe217bSGreg Clayton         const size_t end_func_idx = func_list.GetSize();
28243fe217bSGreg Clayton 
28343fe217bSGreg Clayton         if (start_func_idx < end_func_idx)
28443fe217bSGreg Clayton           lookup.Prune(func_list, start_func_idx);
2859e315589SGreg Clayton       }
28630fdc8d8SChris Lattner     }
28730fdc8d8SChris Lattner     break;
28830fdc8d8SChris Lattner   case Breakpoint::Regexp:
289b9c1b51eSKate Stone     if (context.module_sp) {
290c020be17SJonas Devlieghere       context.module_sp->FindFunctions(m_regex, function_options, func_list);
29130fdc8d8SChris Lattner     }
29230fdc8d8SChris Lattner     break;
29330fdc8d8SChris Lattner   case Breakpoint::Glob:
29430fdc8d8SChris Lattner     if (log)
29530fdc8d8SChris Lattner       log->Warning("glob is not supported yet.");
29630fdc8d8SChris Lattner     break;
29730fdc8d8SChris Lattner   }
29830fdc8d8SChris Lattner 
29905097246SAdrian Prantl   // If the filter specifies a Compilation Unit, remove the ones that don't
30005097246SAdrian Prantl   // pass at this point.
301b9c1b51eSKate Stone   if (filter_by_cu || filter_by_language) {
30287df91b8SJim Ingham     uint32_t num_functions = func_list.GetSize();
30387df91b8SJim Ingham 
304b9c1b51eSKate Stone     for (size_t idx = 0; idx < num_functions; idx++) {
3050fcdac36SJim Ingham       bool remove_it = false;
30687df91b8SJim Ingham       SymbolContext sc;
30787df91b8SJim Ingham       func_list.GetContextAtIndex(idx, sc);
308b9c1b51eSKate Stone       if (filter_by_cu) {
30987df91b8SJim Ingham         if (!sc.comp_unit || !filter.CompUnitPasses(*sc.comp_unit))
3100fcdac36SJim Ingham           remove_it = true;
3110fcdac36SJim Ingham       }
3120fcdac36SJim Ingham 
313b9c1b51eSKate Stone       if (filter_by_language) {
314bfd96183SDawn Perchik         LanguageType sym_language = sc.GetLanguage();
315bfd96183SDawn Perchik         if ((Language::GetPrimaryLanguage(sym_language) !=
316bfd96183SDawn Perchik              Language::GetPrimaryLanguage(m_language)) &&
317b9c1b51eSKate Stone             (sym_language != eLanguageTypeUnknown)) {
3180fcdac36SJim Ingham           remove_it = true;
3190fcdac36SJim Ingham         }
3200fcdac36SJim Ingham       }
3210fcdac36SJim Ingham 
322b9c1b51eSKate Stone       if (remove_it) {
32387df91b8SJim Ingham         func_list.RemoveContextAtIndex(idx);
32487df91b8SJim Ingham         num_functions--;
32587df91b8SJim Ingham         idx--;
32687df91b8SJim Ingham       }
32787df91b8SJim Ingham     }
32887df91b8SJim Ingham   }
32987df91b8SJim Ingham 
3306c17cc53STatyana Krasnukha   BreakpointSP breakpoint_sp = GetBreakpoint();
3316c17cc53STatyana Krasnukha   Breakpoint &breakpoint = *breakpoint_sp;
332b1324e74STatyana Krasnukha   Address break_addr;
3336c17cc53STatyana Krasnukha 
334d93c4a33SBruce Mitchener   // Remove any duplicates between the function list and the symbol list
33543fe217bSGreg Clayton   SymbolContext sc;
336107200aeSKonrad Kleine   if (!func_list.GetSize())
337107200aeSKonrad Kleine     return Searcher::eCallbackReturnContinue;
338107200aeSKonrad Kleine 
339b1324e74STatyana Krasnukha   for (uint32_t i = 0; i < func_list.GetSize(); i++) {
340107200aeSKonrad Kleine     if (!func_list.GetContextAtIndex(i, sc))
341107200aeSKonrad Kleine       continue;
342107200aeSKonrad Kleine 
3431460e4bfSJim Ingham     bool is_reexported = false;
3441460e4bfSJim Ingham 
345b9c1b51eSKate Stone     if (sc.block && sc.block->GetInlinedFunctionInfo()) {
346d7e05469SGreg Clayton       if (!sc.block->GetStartAddress(break_addr))
347d7e05469SGreg Clayton         break_addr.Clear();
348b9c1b51eSKate Stone     } else if (sc.function) {
34930fdc8d8SChris Lattner       break_addr = sc.function->GetAddressRange().GetBaseAddress();
350b9c1b51eSKate Stone       if (m_skip_prologue && break_addr.IsValid()) {
351107200aeSKonrad Kleine         const uint32_t prologue_byte_size = sc.function->GetPrologueByteSize();
35230fdc8d8SChris Lattner         if (prologue_byte_size)
35330fdc8d8SChris Lattner           break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size);
35430fdc8d8SChris Lattner       }
355b9c1b51eSKate Stone     } else if (sc.symbol) {
356b9c1b51eSKate Stone       if (sc.symbol->GetType() == eSymbolTypeReExported) {
357b9c1b51eSKate Stone         const Symbol *actual_symbol =
3586c17cc53STatyana Krasnukha             sc.symbol->ResolveReExportedSymbol(breakpoint.GetTarget());
359b9c1b51eSKate Stone         if (actual_symbol) {
3601460e4bfSJim Ingham           is_reexported = true;
361d65ef14dSGreg Clayton           break_addr = actual_symbol->GetAddress();
362d65ef14dSGreg Clayton         }
363b9c1b51eSKate Stone       } else {
364d8cf1a11SGreg Clayton         break_addr = sc.symbol->GetAddress();
365d65ef14dSGreg Clayton       }
366d65ef14dSGreg Clayton 
367b9c1b51eSKate Stone       if (m_skip_prologue && break_addr.IsValid()) {
368107200aeSKonrad Kleine         const uint32_t prologue_byte_size = sc.symbol->GetPrologueByteSize();
369d8cf1a11SGreg Clayton         if (prologue_byte_size)
370d8cf1a11SGreg Clayton           break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size);
37108581263SJim Ingham         else {
3723da0f218STatyana Krasnukha           const Architecture *arch =
3736c17cc53STatyana Krasnukha               breakpoint.GetTarget().GetArchitecturePlugin();
37408581263SJim Ingham           if (arch)
37508581263SJim Ingham             arch->AdjustBreakpointAddress(*sc.symbol, break_addr);
37608581263SJim Ingham         }
377d8cf1a11SGreg Clayton       }
378d7e05469SGreg Clayton     }
37930fdc8d8SChris Lattner 
380107200aeSKonrad Kleine     if (!break_addr.IsValid())
381107200aeSKonrad Kleine       continue;
382107200aeSKonrad Kleine 
383107200aeSKonrad Kleine     if (!filter.AddressPasses(break_addr))
384107200aeSKonrad Kleine       continue;
385107200aeSKonrad Kleine 
386b1324e74STatyana Krasnukha     bool new_location;
387107200aeSKonrad Kleine     BreakpointLocationSP bp_loc_sp(AddLocation(break_addr, &new_location));
3881460e4bfSJim Ingham     bp_loc_sp->SetIsReExported(is_reexported);
3896c17cc53STatyana Krasnukha     if (bp_loc_sp && new_location && !breakpoint.IsInternal()) {
390b9c1b51eSKate Stone       if (log) {
39130fdc8d8SChris Lattner         StreamString s;
39230fdc8d8SChris Lattner         bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
39363e5fb76SJonas Devlieghere         LLDB_LOGF(log, "Added location: %s\n", s.GetData());
39430fdc8d8SChris Lattner       }
39530fdc8d8SChris Lattner     }
39630fdc8d8SChris Lattner   }
39730fdc8d8SChris Lattner 
39830fdc8d8SChris Lattner   return Searcher::eCallbackReturnContinue;
39930fdc8d8SChris Lattner }
40030fdc8d8SChris Lattner 
GetDepth()4014911d36aSJim Ingham lldb::SearchDepth BreakpointResolverName::GetDepth() {
4024911d36aSJim Ingham   return lldb::eSearchDepthModule;
40330fdc8d8SChris Lattner }
40430fdc8d8SChris Lattner 
GetDescription(Stream * s)405b9c1b51eSKate Stone void BreakpointResolverName::GetDescription(Stream *s) {
40630fdc8d8SChris Lattner   if (m_match_type == Breakpoint::Regexp)
40795eae423SZachary Turner     s->Printf("regex = '%s'", m_regex.GetText().str().c_str());
408b9c1b51eSKate Stone   else {
40943fe217bSGreg Clayton     size_t num_names = m_lookups.size();
410133e0fb3SJim Ingham     if (num_names == 1)
4116234a5c8SGreg Clayton       s->Printf("name = '%s'", m_lookups[0].GetName().GetCString());
412b9c1b51eSKate Stone     else {
413133e0fb3SJim Ingham       s->Printf("names = {");
414b9c1b51eSKate Stone       for (size_t i = 0; i < num_names; i++) {
415b9c1b51eSKate Stone         s->Printf("%s'%s'", (i == 0 ? "" : ", "),
416b9c1b51eSKate Stone                   m_lookups[i].GetName().GetCString());
417133e0fb3SJim Ingham       }
4186234a5c8SGreg Clayton       s->Printf("}");
419133e0fb3SJim Ingham     }
420133e0fb3SJim Ingham   }
421b9c1b51eSKate Stone   if (m_language != eLanguageTypeUnknown) {
4220fcdac36SJim Ingham     s->Printf(", language = %s", Language::GetNameForLanguageType(m_language));
4230fcdac36SJim Ingham   }
42430fdc8d8SChris Lattner }
42530fdc8d8SChris Lattner 
Dump(Stream * s) const426b9c1b51eSKate Stone void BreakpointResolverName::Dump(Stream *s) const {}
42730fdc8d8SChris Lattner 
42833df7cd3SJim Ingham lldb::BreakpointResolverSP
CopyForBreakpoint(BreakpointSP & breakpoint)4296c17cc53STatyana Krasnukha BreakpointResolverName::CopyForBreakpoint(BreakpointSP &breakpoint) {
43033df7cd3SJim Ingham   lldb::BreakpointResolverSP ret_sp(new BreakpointResolverName(*this));
4316c17cc53STatyana Krasnukha   ret_sp->SetBreakpoint(breakpoint);
43233df7cd3SJim Ingham   return ret_sp;
43333df7cd3SJim Ingham }
434