1ac7ddfbfSEd Maste //===-- Target.cpp ----------------------------------------------*- C++ -*-===//
2ac7ddfbfSEd Maste //
3ac7ddfbfSEd Maste //                     The LLVM Compiler Infrastructure
4ac7ddfbfSEd Maste //
5ac7ddfbfSEd Maste // This file is distributed under the University of Illinois Open Source
6ac7ddfbfSEd Maste // License. See LICENSE.TXT for details.
7ac7ddfbfSEd Maste //
8ac7ddfbfSEd Maste //===----------------------------------------------------------------------===//
9ac7ddfbfSEd Maste 
10*b5893f02SDimitry Andric #include "lldb/Target/Target.h"
11435933ddSDimitry Andric #include "Plugins/ExpressionParser/Clang/ClangASTSource.h"
12435933ddSDimitry Andric #include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h"
13435933ddSDimitry Andric #include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
14435933ddSDimitry Andric #include "lldb/Breakpoint/BreakpointIDList.h"
15ac7ddfbfSEd Maste #include "lldb/Breakpoint/BreakpointResolver.h"
16ac7ddfbfSEd Maste #include "lldb/Breakpoint/BreakpointResolverAddress.h"
17ac7ddfbfSEd Maste #include "lldb/Breakpoint/BreakpointResolverFileLine.h"
18ac7ddfbfSEd Maste #include "lldb/Breakpoint/BreakpointResolverFileRegex.h"
19ac7ddfbfSEd Maste #include "lldb/Breakpoint/BreakpointResolverName.h"
20*b5893f02SDimitry Andric #include "lldb/Breakpoint/BreakpointResolverScripted.h"
21ac7ddfbfSEd Maste #include "lldb/Breakpoint/Watchpoint.h"
22ac7ddfbfSEd Maste #include "lldb/Core/Debugger.h"
23ac7ddfbfSEd Maste #include "lldb/Core/Module.h"
24ac7ddfbfSEd Maste #include "lldb/Core/ModuleSpec.h"
25acac075bSDimitry Andric #include "lldb/Core/PluginManager.h"
26*b5893f02SDimitry Andric #include "lldb/Core/SearchFilter.h"
27ac7ddfbfSEd Maste #include "lldb/Core/Section.h"
28ac7ddfbfSEd Maste #include "lldb/Core/SourceManager.h"
2912b93ac6SEd Maste #include "lldb/Core/StreamFile.h"
30*b5893f02SDimitry Andric #include "lldb/Core/StructuredDataImpl.h"
31ac7ddfbfSEd Maste #include "lldb/Core/ValueObject.h"
329f2f44ceSEd Maste #include "lldb/Expression/REPL.h"
339f2f44ceSEd Maste #include "lldb/Expression/UserExpression.h"
34ac7ddfbfSEd Maste #include "lldb/Host/Host.h"
35b40b48b8SDimitry Andric #include "lldb/Host/PosixApi.h"
36ac7ddfbfSEd Maste #include "lldb/Interpreter/CommandInterpreter.h"
37ac7ddfbfSEd Maste #include "lldb/Interpreter/CommandReturnObject.h"
38ac7ddfbfSEd Maste #include "lldb/Interpreter/OptionGroupWatchpoint.h"
39ac7ddfbfSEd Maste #include "lldb/Interpreter/OptionValues.h"
40ac7ddfbfSEd Maste #include "lldb/Interpreter/Property.h"
411c3bbb01SEd Maste #include "lldb/Symbol/ClangASTContext.h"
429f2f44ceSEd Maste #include "lldb/Symbol/Function.h"
43435933ddSDimitry Andric #include "lldb/Symbol/ObjectFile.h"
449f2f44ceSEd Maste #include "lldb/Symbol/Symbol.h"
459f2f44ceSEd Maste #include "lldb/Target/Language.h"
461c3bbb01SEd Maste #include "lldb/Target/LanguageRuntime.h"
471c3bbb01SEd Maste #include "lldb/Target/ObjCLanguageRuntime.h"
48ac7ddfbfSEd Maste #include "lldb/Target/Process.h"
4912b93ac6SEd Maste #include "lldb/Target/SectionLoadList.h"
50ac7ddfbfSEd Maste #include "lldb/Target/StackFrame.h"
5135617911SEd Maste #include "lldb/Target/SystemRuntime.h"
52ac7ddfbfSEd Maste #include "lldb/Target/Thread.h"
53ac7ddfbfSEd Maste #include "lldb/Target/ThreadSpec.h"
54*b5893f02SDimitry Andric #include "lldb/Utility/Event.h"
55f678e45dSDimitry Andric #include "lldb/Utility/FileSpec.h"
569f2f44ceSEd Maste #include "lldb/Utility/LLDBAssert.h"
57f678e45dSDimitry Andric #include "lldb/Utility/Log.h"
58*b5893f02SDimitry Andric #include "lldb/Utility/State.h"
59f678e45dSDimitry Andric #include "lldb/Utility/StreamString.h"
60a580b014SDimitry Andric #include "lldb/Utility/Timer.h"
61*b5893f02SDimitry Andric #include <mutex>
62ac7ddfbfSEd Maste 
63ac7ddfbfSEd Maste using namespace lldb;
64ac7ddfbfSEd Maste using namespace lldb_private;
65ac7ddfbfSEd Maste 
66435933ddSDimitry Andric constexpr std::chrono::milliseconds EvaluateExpressionOptions::default_timeout;
67435933ddSDimitry Andric 
Arch(const ArchSpec & spec)68acac075bSDimitry Andric Target::Arch::Arch(const ArchSpec &spec)
69acac075bSDimitry Andric     : m_spec(spec),
70acac075bSDimitry Andric       m_plugin_up(PluginManager::CreateArchitectureInstance(spec)) {}
71acac075bSDimitry Andric 
operator =(const ArchSpec & spec)72acac075bSDimitry Andric const Target::Arch& Target::Arch::operator=(const ArchSpec &spec) {
73acac075bSDimitry Andric   m_spec = spec;
74acac075bSDimitry Andric   m_plugin_up = PluginManager::CreateArchitectureInstance(spec);
75acac075bSDimitry Andric   return *this;
76acac075bSDimitry Andric }
77acac075bSDimitry Andric 
GetStaticBroadcasterClass()78435933ddSDimitry Andric ConstString &Target::GetStaticBroadcasterClass() {
79ac7ddfbfSEd Maste   static ConstString class_name("lldb.target");
80ac7ddfbfSEd Maste   return class_name;
81ac7ddfbfSEd Maste }
82ac7ddfbfSEd Maste 
Target(Debugger & debugger,const ArchSpec & target_arch,const lldb::PlatformSP & platform_sp,bool is_dummy_target)83435933ddSDimitry Andric Target::Target(Debugger &debugger, const ArchSpec &target_arch,
84435933ddSDimitry Andric                const lldb::PlatformSP &platform_sp, bool is_dummy_target)
854bb0738eSEd Maste     : TargetProperties(this),
86435933ddSDimitry Andric       Broadcaster(debugger.GetBroadcasterManager(),
87435933ddSDimitry Andric                   Target::GetStaticBroadcasterClass().AsCString()),
88435933ddSDimitry Andric       ExecutionContextScope(), m_debugger(debugger), m_platform_sp(platform_sp),
894ba319b5SDimitry Andric       m_mutex(), m_arch(target_arch), m_images(this), m_section_load_history(),
904ba319b5SDimitry Andric       m_breakpoint_list(false), m_internal_breakpoint_list(true),
914ba319b5SDimitry Andric       m_watchpoint_list(), m_process_sp(), m_search_filter_sp(),
924ba319b5SDimitry Andric       m_image_search_paths(ImageSearchPathsChanged, this), m_ast_importer_sp(),
934ba319b5SDimitry Andric       m_source_manager_ap(), m_stop_hooks(), m_stop_hook_next_id(0),
944ba319b5SDimitry Andric       m_valid(true), m_suppress_stop_hooks(false),
954ba319b5SDimitry Andric       m_is_dummy_target(is_dummy_target),
964ba319b5SDimitry Andric       m_stats_storage(static_cast<int>(StatisticKind::StatisticMax))
977aa51b79SEd Maste 
98ac7ddfbfSEd Maste {
99ac7ddfbfSEd Maste   SetEventName(eBroadcastBitBreakpointChanged, "breakpoint-changed");
100ac7ddfbfSEd Maste   SetEventName(eBroadcastBitModulesLoaded, "modules-loaded");
101ac7ddfbfSEd Maste   SetEventName(eBroadcastBitModulesUnloaded, "modules-unloaded");
102ac7ddfbfSEd Maste   SetEventName(eBroadcastBitWatchpointChanged, "watchpoint-changed");
103ac7ddfbfSEd Maste   SetEventName(eBroadcastBitSymbolsLoaded, "symbols-loaded");
104ac7ddfbfSEd Maste 
105ac7ddfbfSEd Maste   CheckInWithManager();
106ac7ddfbfSEd Maste 
107ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
108ac7ddfbfSEd Maste   if (log)
1090127ef0fSEd Maste     log->Printf("%p Target::Target()", static_cast<void *>(this));
110acac075bSDimitry Andric   if (target_arch.IsValid()) {
111acac075bSDimitry Andric     LogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET,
112acac075bSDimitry Andric                           "Target::Target created with architecture %s (%s)",
113acac075bSDimitry Andric                           target_arch.GetArchitectureName(),
114acac075bSDimitry Andric                           target_arch.GetTriple().getTriple().c_str());
115ac7ddfbfSEd Maste   }
116ac7ddfbfSEd Maste }
117ac7ddfbfSEd Maste 
~Target()118435933ddSDimitry Andric Target::~Target() {
1199f2f44ceSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
1209f2f44ceSEd Maste   if (log)
1219f2f44ceSEd Maste     log->Printf("%p Target::~Target()", static_cast<void *>(this));
1229f2f44ceSEd Maste   DeleteCurrentProcess();
1239f2f44ceSEd Maste }
1249f2f44ceSEd Maste 
PrimeFromDummyTarget(Target * target)125435933ddSDimitry Andric void Target::PrimeFromDummyTarget(Target *target) {
1267aa51b79SEd Maste   if (!target)
1277aa51b79SEd Maste     return;
1287aa51b79SEd Maste 
1297aa51b79SEd Maste   m_stop_hooks = target->m_stop_hooks;
1307aa51b79SEd Maste 
131435933ddSDimitry Andric   for (BreakpointSP breakpoint_sp : target->m_breakpoint_list.Breakpoints()) {
1327aa51b79SEd Maste     if (breakpoint_sp->IsInternal())
1337aa51b79SEd Maste       continue;
1347aa51b79SEd Maste 
1357aa51b79SEd Maste     BreakpointSP new_bp(new Breakpoint(*this, *breakpoint_sp.get()));
1367aa51b79SEd Maste     AddBreakpoint(new_bp, false);
1377aa51b79SEd Maste   }
138acac075bSDimitry Andric 
139acac075bSDimitry Andric   for (auto bp_name_entry : target->m_breakpoint_names)
140acac075bSDimitry Andric   {
141acac075bSDimitry Andric 
142acac075bSDimitry Andric     BreakpointName *new_bp_name = new BreakpointName(*bp_name_entry.second);
143acac075bSDimitry Andric     AddBreakpointName(new_bp_name);
144acac075bSDimitry Andric   }
1457aa51b79SEd Maste }
1467aa51b79SEd Maste 
Dump(Stream * s,lldb::DescriptionLevel description_level)147435933ddSDimitry Andric void Target::Dump(Stream *s, lldb::DescriptionLevel description_level) {
148ac7ddfbfSEd Maste   //    s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
149435933ddSDimitry Andric   if (description_level != lldb::eDescriptionLevelBrief) {
150ac7ddfbfSEd Maste     s->Indent();
151ac7ddfbfSEd Maste     s->PutCString("Target\n");
152ac7ddfbfSEd Maste     s->IndentMore();
153ac7ddfbfSEd Maste     m_images.Dump(s);
154ac7ddfbfSEd Maste     m_breakpoint_list.Dump(s);
155ac7ddfbfSEd Maste     m_internal_breakpoint_list.Dump(s);
156ac7ddfbfSEd Maste     s->IndentLess();
157435933ddSDimitry Andric   } else {
158ac7ddfbfSEd Maste     Module *exe_module = GetExecutableModulePointer();
159ac7ddfbfSEd Maste     if (exe_module)
160ac7ddfbfSEd Maste       s->PutCString(exe_module->GetFileSpec().GetFilename().GetCString());
161ac7ddfbfSEd Maste     else
162ac7ddfbfSEd Maste       s->PutCString("No executable module.");
163ac7ddfbfSEd Maste   }
164ac7ddfbfSEd Maste }
165ac7ddfbfSEd Maste 
CleanupProcess()166435933ddSDimitry Andric void Target::CleanupProcess() {
167ac7ddfbfSEd Maste   // Do any cleanup of the target we need to do between process instances.
168ac7ddfbfSEd Maste   // NB It is better to do this before destroying the process in case the
169ac7ddfbfSEd Maste   // clean up needs some help from the process.
170ac7ddfbfSEd Maste   m_breakpoint_list.ClearAllBreakpointSites();
171ac7ddfbfSEd Maste   m_internal_breakpoint_list.ClearAllBreakpointSites();
172ac7ddfbfSEd Maste   // Disable watchpoints just on the debugger side.
1734bb0738eSEd Maste   std::unique_lock<std::recursive_mutex> lock;
1744bb0738eSEd Maste   this->GetWatchpointList().GetListMutex(lock);
175ac7ddfbfSEd Maste   DisableAllWatchpoints(false);
176ac7ddfbfSEd Maste   ClearAllWatchpointHitCounts();
1771c3bbb01SEd Maste   ClearAllWatchpointHistoricValues();
178ac7ddfbfSEd Maste }
179ac7ddfbfSEd Maste 
DeleteCurrentProcess()180435933ddSDimitry Andric void Target::DeleteCurrentProcess() {
181435933ddSDimitry Andric   if (m_process_sp) {
18212b93ac6SEd Maste     m_section_load_history.Clear();
183ac7ddfbfSEd Maste     if (m_process_sp->IsAlive())
1841c3bbb01SEd Maste       m_process_sp->Destroy(false);
185ac7ddfbfSEd Maste 
186ac7ddfbfSEd Maste     m_process_sp->Finalize();
187ac7ddfbfSEd Maste 
188ac7ddfbfSEd Maste     CleanupProcess();
189ac7ddfbfSEd Maste 
190ac7ddfbfSEd Maste     m_process_sp.reset();
191ac7ddfbfSEd Maste   }
192ac7ddfbfSEd Maste }
193ac7ddfbfSEd Maste 
CreateProcess(ListenerSP listener_sp,llvm::StringRef plugin_name,const FileSpec * crash_file)194435933ddSDimitry Andric const lldb::ProcessSP &Target::CreateProcess(ListenerSP listener_sp,
195435933ddSDimitry Andric                                              llvm::StringRef plugin_name,
196435933ddSDimitry Andric                                              const FileSpec *crash_file) {
197*b5893f02SDimitry Andric   if (!listener_sp)
198*b5893f02SDimitry Andric     listener_sp = GetDebugger().GetListener();
199ac7ddfbfSEd Maste   DeleteCurrentProcess();
200435933ddSDimitry Andric   m_process_sp = Process::FindPlugin(shared_from_this(), plugin_name,
201435933ddSDimitry Andric                                      listener_sp, crash_file);
202ac7ddfbfSEd Maste   return m_process_sp;
203ac7ddfbfSEd Maste }
204ac7ddfbfSEd Maste 
GetProcessSP() const205435933ddSDimitry Andric const lldb::ProcessSP &Target::GetProcessSP() const { return m_process_sp; }
206ac7ddfbfSEd Maste 
GetREPL(Status & err,lldb::LanguageType language,const char * repl_options,bool can_create)2075517e702SDimitry Andric lldb::REPLSP Target::GetREPL(Status &err, lldb::LanguageType language,
208435933ddSDimitry Andric                              const char *repl_options, bool can_create) {
209435933ddSDimitry Andric   if (language == eLanguageTypeUnknown) {
2109f2f44ceSEd Maste     std::set<LanguageType> repl_languages;
2119f2f44ceSEd Maste 
2129f2f44ceSEd Maste     Language::GetLanguagesSupportingREPLs(repl_languages);
2139f2f44ceSEd Maste 
214435933ddSDimitry Andric     if (repl_languages.size() == 1) {
2159f2f44ceSEd Maste       language = *repl_languages.begin();
216435933ddSDimitry Andric     } else if (repl_languages.size() == 0) {
217435933ddSDimitry Andric       err.SetErrorStringWithFormat(
218435933ddSDimitry Andric           "LLDB isn't configured with REPL support for any languages.");
2199f2f44ceSEd Maste       return REPLSP();
220435933ddSDimitry Andric     } else {
221435933ddSDimitry Andric       err.SetErrorStringWithFormat(
222435933ddSDimitry Andric           "Multiple possible REPL languages.  Please specify a language.");
2239f2f44ceSEd Maste       return REPLSP();
2249f2f44ceSEd Maste     }
2259f2f44ceSEd Maste   }
2269f2f44ceSEd Maste 
2279f2f44ceSEd Maste   REPLMap::iterator pos = m_repl_map.find(language);
2289f2f44ceSEd Maste 
229435933ddSDimitry Andric   if (pos != m_repl_map.end()) {
2309f2f44ceSEd Maste     return pos->second;
2319f2f44ceSEd Maste   }
2329f2f44ceSEd Maste 
233435933ddSDimitry Andric   if (!can_create) {
234435933ddSDimitry Andric     err.SetErrorStringWithFormat(
235435933ddSDimitry Andric         "Couldn't find an existing REPL for %s, and can't create a new one",
236435933ddSDimitry Andric         Language::GetNameForLanguageType(language));
2379f2f44ceSEd Maste     return lldb::REPLSP();
2389f2f44ceSEd Maste   }
2399f2f44ceSEd Maste 
2409f2f44ceSEd Maste   Debugger *const debugger = nullptr;
2419f2f44ceSEd Maste   lldb::REPLSP ret = REPL::Create(err, language, debugger, this, repl_options);
2429f2f44ceSEd Maste 
243435933ddSDimitry Andric   if (ret) {
2449f2f44ceSEd Maste     m_repl_map[language] = ret;
2459f2f44ceSEd Maste     return m_repl_map[language];
2469f2f44ceSEd Maste   }
2479f2f44ceSEd Maste 
248435933ddSDimitry Andric   if (err.Success()) {
249435933ddSDimitry Andric     err.SetErrorStringWithFormat("Couldn't create a REPL for %s",
250435933ddSDimitry Andric                                  Language::GetNameForLanguageType(language));
2519f2f44ceSEd Maste   }
2529f2f44ceSEd Maste 
2539f2f44ceSEd Maste   return lldb::REPLSP();
2549f2f44ceSEd Maste }
2559f2f44ceSEd Maste 
SetREPL(lldb::LanguageType language,lldb::REPLSP repl_sp)256435933ddSDimitry Andric void Target::SetREPL(lldb::LanguageType language, lldb::REPLSP repl_sp) {
2579f2f44ceSEd Maste   lldbassert(!m_repl_map.count(language));
2589f2f44ceSEd Maste 
2599f2f44ceSEd Maste   m_repl_map[language] = repl_sp;
2609f2f44ceSEd Maste }
2619f2f44ceSEd Maste 
Destroy()262435933ddSDimitry Andric void Target::Destroy() {
2634bb0738eSEd Maste   std::lock_guard<std::recursive_mutex> guard(m_mutex);
264ac7ddfbfSEd Maste   m_valid = false;
265ac7ddfbfSEd Maste   DeleteCurrentProcess();
266ac7ddfbfSEd Maste   m_platform_sp.reset();
267acac075bSDimitry Andric   m_arch = ArchSpec();
268b952cd58SEd Maste   ClearModules(true);
26912b93ac6SEd Maste   m_section_load_history.Clear();
270ac7ddfbfSEd Maste   const bool notify = false;
271ac7ddfbfSEd Maste   m_breakpoint_list.RemoveAll(notify);
272ac7ddfbfSEd Maste   m_internal_breakpoint_list.RemoveAll(notify);
273ac7ddfbfSEd Maste   m_last_created_breakpoint.reset();
274ac7ddfbfSEd Maste   m_last_created_watchpoint.reset();
275ac7ddfbfSEd Maste   m_search_filter_sp.reset();
276ac7ddfbfSEd Maste   m_image_search_paths.Clear(notify);
277ac7ddfbfSEd Maste   m_stop_hooks.clear();
278ac7ddfbfSEd Maste   m_stop_hook_next_id = 0;
279ac7ddfbfSEd Maste   m_suppress_stop_hooks = false;
280ac7ddfbfSEd Maste }
281ac7ddfbfSEd Maste 
GetBreakpointList(bool internal)282435933ddSDimitry Andric BreakpointList &Target::GetBreakpointList(bool internal) {
283ac7ddfbfSEd Maste   if (internal)
284ac7ddfbfSEd Maste     return m_internal_breakpoint_list;
285ac7ddfbfSEd Maste   else
286ac7ddfbfSEd Maste     return m_breakpoint_list;
287ac7ddfbfSEd Maste }
288ac7ddfbfSEd Maste 
GetBreakpointList(bool internal) const289435933ddSDimitry Andric const BreakpointList &Target::GetBreakpointList(bool internal) const {
290ac7ddfbfSEd Maste   if (internal)
291ac7ddfbfSEd Maste     return m_internal_breakpoint_list;
292ac7ddfbfSEd Maste   else
293ac7ddfbfSEd Maste     return m_breakpoint_list;
294ac7ddfbfSEd Maste }
295ac7ddfbfSEd Maste 
GetBreakpointByID(break_id_t break_id)296435933ddSDimitry Andric BreakpointSP Target::GetBreakpointByID(break_id_t break_id) {
297ac7ddfbfSEd Maste   BreakpointSP bp_sp;
298ac7ddfbfSEd Maste 
299ac7ddfbfSEd Maste   if (LLDB_BREAK_ID_IS_INTERNAL(break_id))
300ac7ddfbfSEd Maste     bp_sp = m_internal_breakpoint_list.FindBreakpointByID(break_id);
301ac7ddfbfSEd Maste   else
302ac7ddfbfSEd Maste     bp_sp = m_breakpoint_list.FindBreakpointByID(break_id);
303ac7ddfbfSEd Maste 
304ac7ddfbfSEd Maste   return bp_sp;
305ac7ddfbfSEd Maste }
306ac7ddfbfSEd Maste 
CreateSourceRegexBreakpoint(const FileSpecList * containingModules,const FileSpecList * source_file_spec_list,const std::unordered_set<std::string> & function_names,RegularExpression & source_regex,bool internal,bool hardware,LazyBool move_to_nearest_code)307435933ddSDimitry Andric BreakpointSP Target::CreateSourceRegexBreakpoint(
308435933ddSDimitry Andric     const FileSpecList *containingModules,
309ac7ddfbfSEd Maste     const FileSpecList *source_file_spec_list,
3104bb0738eSEd Maste     const std::unordered_set<std::string> &function_names,
311435933ddSDimitry Andric     RegularExpression &source_regex, bool internal, bool hardware,
312435933ddSDimitry Andric     LazyBool move_to_nearest_code) {
313435933ddSDimitry Andric   SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList(
314435933ddSDimitry Andric       containingModules, source_file_spec_list));
3151c3bbb01SEd Maste   if (move_to_nearest_code == eLazyBoolCalculate)
3161c3bbb01SEd Maste     move_to_nearest_code = GetMoveToNearestCode() ? eLazyBoolYes : eLazyBoolNo;
317435933ddSDimitry Andric   BreakpointResolverSP resolver_sp(new BreakpointResolverFileRegex(
318435933ddSDimitry Andric       nullptr, source_regex, function_names,
3194bb0738eSEd Maste       !static_cast<bool>(move_to_nearest_code)));
3204bb0738eSEd Maste 
32112b93ac6SEd Maste   return CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true);
322ac7ddfbfSEd Maste }
323ac7ddfbfSEd Maste 
CreateBreakpoint(const FileSpecList * containingModules,const FileSpec & file,uint32_t line_no,uint32_t column,lldb::addr_t offset,LazyBool check_inlines,LazyBool skip_prologue,bool internal,bool hardware,LazyBool move_to_nearest_code)324435933ddSDimitry Andric BreakpointSP Target::CreateBreakpoint(const FileSpecList *containingModules,
325435933ddSDimitry Andric                                       const FileSpec &file, uint32_t line_no,
326*b5893f02SDimitry Andric                                       uint32_t column, lldb::addr_t offset,
327ac7ddfbfSEd Maste                                       LazyBool check_inlines,
328435933ddSDimitry Andric                                       LazyBool skip_prologue, bool internal,
3291c3bbb01SEd Maste                                       bool hardware,
330435933ddSDimitry Andric                                       LazyBool move_to_nearest_code) {
3314bb0738eSEd Maste   FileSpec remapped_file;
3324ba319b5SDimitry Andric   if (!GetSourcePathMap().ReverseRemapPath(file, remapped_file))
3334bb0738eSEd Maste     remapped_file = file;
3344bb0738eSEd Maste 
335435933ddSDimitry Andric   if (check_inlines == eLazyBoolCalculate) {
336ac7ddfbfSEd Maste     const InlineStrategy inline_strategy = GetInlineStrategy();
337435933ddSDimitry Andric     switch (inline_strategy) {
338ac7ddfbfSEd Maste     case eInlineBreakpointsNever:
339ac7ddfbfSEd Maste       check_inlines = eLazyBoolNo;
340ac7ddfbfSEd Maste       break;
341ac7ddfbfSEd Maste 
342ac7ddfbfSEd Maste     case eInlineBreakpointsHeaders:
3434bb0738eSEd Maste       if (remapped_file.IsSourceImplementationFile())
344ac7ddfbfSEd Maste         check_inlines = eLazyBoolNo;
345ac7ddfbfSEd Maste       else
346ac7ddfbfSEd Maste         check_inlines = eLazyBoolYes;
347ac7ddfbfSEd Maste       break;
348ac7ddfbfSEd Maste 
349ac7ddfbfSEd Maste     case eInlineBreakpointsAlways:
350ac7ddfbfSEd Maste       check_inlines = eLazyBoolYes;
351ac7ddfbfSEd Maste       break;
352ac7ddfbfSEd Maste     }
353ac7ddfbfSEd Maste   }
354ac7ddfbfSEd Maste   SearchFilterSP filter_sp;
355435933ddSDimitry Andric   if (check_inlines == eLazyBoolNo) {
356ac7ddfbfSEd Maste     // Not checking for inlines, we are looking only for matching compile units
357ac7ddfbfSEd Maste     FileSpecList compile_unit_list;
3584bb0738eSEd Maste     compile_unit_list.Append(remapped_file);
359435933ddSDimitry Andric     filter_sp = GetSearchFilterForModuleAndCUList(containingModules,
360435933ddSDimitry Andric                                                   &compile_unit_list);
361435933ddSDimitry Andric   } else {
362ac7ddfbfSEd Maste     filter_sp = GetSearchFilterForModuleList(containingModules);
363ac7ddfbfSEd Maste   }
364ac7ddfbfSEd Maste   if (skip_prologue == eLazyBoolCalculate)
365ac7ddfbfSEd Maste     skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;
3661c3bbb01SEd Maste   if (move_to_nearest_code == eLazyBoolCalculate)
3671c3bbb01SEd Maste     move_to_nearest_code = GetMoveToNearestCode() ? eLazyBoolYes : eLazyBoolNo;
368ac7ddfbfSEd Maste 
369435933ddSDimitry Andric   BreakpointResolverSP resolver_sp(new BreakpointResolverFileLine(
370*b5893f02SDimitry Andric       nullptr, remapped_file, line_no, column, offset, check_inlines,
371*b5893f02SDimitry Andric       skip_prologue, !static_cast<bool>(move_to_nearest_code)));
37212b93ac6SEd Maste   return CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true);
373ac7ddfbfSEd Maste }
374ac7ddfbfSEd Maste 
CreateBreakpoint(lldb::addr_t addr,bool internal,bool hardware)375435933ddSDimitry Andric BreakpointSP Target::CreateBreakpoint(lldb::addr_t addr, bool internal,
376435933ddSDimitry Andric                                       bool hardware) {
377ac7ddfbfSEd Maste   Address so_addr;
3789f2f44ceSEd Maste 
3799f2f44ceSEd Maste   // Check for any reason we want to move this breakpoint to other address.
3809f2f44ceSEd Maste   addr = GetBreakableLoadAddress(addr);
3819f2f44ceSEd Maste 
3824ba319b5SDimitry Andric   // Attempt to resolve our load address if possible, though it is ok if it
3834ba319b5SDimitry Andric   // doesn't resolve to section/offset.
384ac7ddfbfSEd Maste 
385ac7ddfbfSEd Maste   // Try and resolve as a load address if possible
38612b93ac6SEd Maste   GetSectionLoadList().ResolveLoadAddress(addr, so_addr);
387435933ddSDimitry Andric   if (!so_addr.IsValid()) {
388ac7ddfbfSEd Maste     // The address didn't resolve, so just set this as an absolute address
389ac7ddfbfSEd Maste     so_addr.SetOffset(addr);
390ac7ddfbfSEd Maste   }
39135617911SEd Maste   BreakpointSP bp_sp(CreateBreakpoint(so_addr, internal, hardware));
392ac7ddfbfSEd Maste   return bp_sp;
393ac7ddfbfSEd Maste }
394ac7ddfbfSEd Maste 
CreateBreakpoint(const Address & addr,bool internal,bool hardware)395435933ddSDimitry Andric BreakpointSP Target::CreateBreakpoint(const Address &addr, bool internal,
396435933ddSDimitry Andric                                       bool hardware) {
397435933ddSDimitry Andric   SearchFilterSP filter_sp(
398435933ddSDimitry Andric       new SearchFilterForUnconstrainedSearches(shared_from_this()));
399435933ddSDimitry Andric   BreakpointResolverSP resolver_sp(
400435933ddSDimitry Andric       new BreakpointResolverAddress(nullptr, addr));
40112b93ac6SEd Maste   return CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, false);
402ac7ddfbfSEd Maste }
403ac7ddfbfSEd Maste 
4049f2f44ceSEd Maste lldb::BreakpointSP
CreateAddressInModuleBreakpoint(lldb::addr_t file_addr,bool internal,const FileSpec * file_spec,bool request_hardware)405435933ddSDimitry Andric Target::CreateAddressInModuleBreakpoint(lldb::addr_t file_addr, bool internal,
4069f2f44ceSEd Maste                                         const FileSpec *file_spec,
407435933ddSDimitry Andric                                         bool request_hardware) {
408435933ddSDimitry Andric   SearchFilterSP filter_sp(
409435933ddSDimitry Andric       new SearchFilterForUnconstrainedSearches(shared_from_this()));
410435933ddSDimitry Andric   BreakpointResolverSP resolver_sp(
411435933ddSDimitry Andric       new BreakpointResolverAddress(nullptr, file_addr, file_spec));
412435933ddSDimitry Andric   return CreateBreakpoint(filter_sp, resolver_sp, internal, request_hardware,
413435933ddSDimitry Andric                           false);
4149f2f44ceSEd Maste }
4159f2f44ceSEd Maste 
CreateBreakpoint(const FileSpecList * containingModules,const FileSpecList * containingSourceFiles,const char * func_name,FunctionNameType func_name_type_mask,LanguageType language,lldb::addr_t offset,LazyBool skip_prologue,bool internal,bool hardware)416*b5893f02SDimitry Andric BreakpointSP Target::CreateBreakpoint(
417*b5893f02SDimitry Andric     const FileSpecList *containingModules,
418*b5893f02SDimitry Andric     const FileSpecList *containingSourceFiles, const char *func_name,
419*b5893f02SDimitry Andric     FunctionNameType func_name_type_mask, LanguageType language,
420*b5893f02SDimitry Andric     lldb::addr_t offset, LazyBool skip_prologue, bool internal, bool hardware) {
421ac7ddfbfSEd Maste   BreakpointSP bp_sp;
422435933ddSDimitry Andric   if (func_name) {
423435933ddSDimitry Andric     SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList(
424435933ddSDimitry Andric         containingModules, containingSourceFiles));
425ac7ddfbfSEd Maste 
426ac7ddfbfSEd Maste     if (skip_prologue == eLazyBoolCalculate)
427ac7ddfbfSEd Maste       skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;
4289f2f44ceSEd Maste     if (language == lldb::eLanguageTypeUnknown)
4299f2f44ceSEd Maste       language = GetLanguage();
430ac7ddfbfSEd Maste 
431435933ddSDimitry Andric     BreakpointResolverSP resolver_sp(new BreakpointResolverName(
432435933ddSDimitry Andric         nullptr, func_name, func_name_type_mask, language, Breakpoint::Exact,
433435933ddSDimitry Andric         offset, skip_prologue));
43412b93ac6SEd Maste     bp_sp = CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true);
435ac7ddfbfSEd Maste   }
436ac7ddfbfSEd Maste   return bp_sp;
437ac7ddfbfSEd Maste }
438ac7ddfbfSEd Maste 
439ac7ddfbfSEd Maste lldb::BreakpointSP
CreateBreakpoint(const FileSpecList * containingModules,const FileSpecList * containingSourceFiles,const std::vector<std::string> & func_names,FunctionNameType func_name_type_mask,LanguageType language,lldb::addr_t offset,LazyBool skip_prologue,bool internal,bool hardware)440ac7ddfbfSEd Maste Target::CreateBreakpoint(const FileSpecList *containingModules,
441ac7ddfbfSEd Maste                          const FileSpecList *containingSourceFiles,
442ac7ddfbfSEd Maste                          const std::vector<std::string> &func_names,
443*b5893f02SDimitry Andric                          FunctionNameType func_name_type_mask,
444*b5893f02SDimitry Andric                          LanguageType language, lldb::addr_t offset,
445*b5893f02SDimitry Andric                          LazyBool skip_prologue, bool internal, bool hardware) {
446ac7ddfbfSEd Maste   BreakpointSP bp_sp;
447ac7ddfbfSEd Maste   size_t num_names = func_names.size();
448435933ddSDimitry Andric   if (num_names > 0) {
449435933ddSDimitry Andric     SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList(
450435933ddSDimitry Andric         containingModules, containingSourceFiles));
451ac7ddfbfSEd Maste 
452ac7ddfbfSEd Maste     if (skip_prologue == eLazyBoolCalculate)
453ac7ddfbfSEd Maste       skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;
4549f2f44ceSEd Maste     if (language == lldb::eLanguageTypeUnknown)
4559f2f44ceSEd Maste       language = GetLanguage();
456ac7ddfbfSEd Maste 
457435933ddSDimitry Andric     BreakpointResolverSP resolver_sp(
458435933ddSDimitry Andric         new BreakpointResolverName(nullptr, func_names, func_name_type_mask,
459435933ddSDimitry Andric                                    language, offset, skip_prologue));
46012b93ac6SEd Maste     bp_sp = CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true);
461ac7ddfbfSEd Maste   }
462ac7ddfbfSEd Maste   return bp_sp;
463ac7ddfbfSEd Maste }
464ac7ddfbfSEd Maste 
465*b5893f02SDimitry Andric BreakpointSP
CreateBreakpoint(const FileSpecList * containingModules,const FileSpecList * containingSourceFiles,const char * func_names[],size_t num_names,FunctionNameType func_name_type_mask,LanguageType language,lldb::addr_t offset,LazyBool skip_prologue,bool internal,bool hardware)466*b5893f02SDimitry Andric Target::CreateBreakpoint(const FileSpecList *containingModules,
467*b5893f02SDimitry Andric                          const FileSpecList *containingSourceFiles,
468*b5893f02SDimitry Andric                          const char *func_names[], size_t num_names,
469*b5893f02SDimitry Andric                          FunctionNameType func_name_type_mask,
470*b5893f02SDimitry Andric                          LanguageType language, lldb::addr_t offset,
471*b5893f02SDimitry Andric                          LazyBool skip_prologue, bool internal, bool hardware) {
472ac7ddfbfSEd Maste   BreakpointSP bp_sp;
473435933ddSDimitry Andric   if (num_names > 0) {
474435933ddSDimitry Andric     SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList(
475435933ddSDimitry Andric         containingModules, containingSourceFiles));
476ac7ddfbfSEd Maste 
477435933ddSDimitry Andric     if (skip_prologue == eLazyBoolCalculate) {
4784bb0738eSEd Maste       if (offset == 0)
479ac7ddfbfSEd Maste         skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;
4804bb0738eSEd Maste       else
4814bb0738eSEd Maste         skip_prologue = eLazyBoolNo;
4824bb0738eSEd Maste     }
4839f2f44ceSEd Maste     if (language == lldb::eLanguageTypeUnknown)
4849f2f44ceSEd Maste       language = GetLanguage();
485ac7ddfbfSEd Maste 
486435933ddSDimitry Andric     BreakpointResolverSP resolver_sp(new BreakpointResolverName(
487435933ddSDimitry Andric         nullptr, func_names, num_names, func_name_type_mask, language, offset,
488ac7ddfbfSEd Maste         skip_prologue));
4894bb0738eSEd Maste     resolver_sp->SetOffset(offset);
49012b93ac6SEd Maste     bp_sp = CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true);
491ac7ddfbfSEd Maste   }
492ac7ddfbfSEd Maste   return bp_sp;
493ac7ddfbfSEd Maste }
494ac7ddfbfSEd Maste 
495ac7ddfbfSEd Maste SearchFilterSP
GetSearchFilterForModule(const FileSpec * containingModule)496435933ddSDimitry Andric Target::GetSearchFilterForModule(const FileSpec *containingModule) {
497ac7ddfbfSEd Maste   SearchFilterSP filter_sp;
498435933ddSDimitry Andric   if (containingModule != nullptr) {
499ac7ddfbfSEd Maste     // TODO: We should look into sharing module based search filters
500ac7ddfbfSEd Maste     // across many breakpoints like we do for the simple target based one
501435933ddSDimitry Andric     filter_sp.reset(
502435933ddSDimitry Andric         new SearchFilterByModule(shared_from_this(), *containingModule));
503435933ddSDimitry Andric   } else {
5049f2f44ceSEd Maste     if (!m_search_filter_sp)
505435933ddSDimitry Andric       m_search_filter_sp.reset(
506435933ddSDimitry Andric           new SearchFilterForUnconstrainedSearches(shared_from_this()));
507ac7ddfbfSEd Maste     filter_sp = m_search_filter_sp;
508ac7ddfbfSEd Maste   }
509ac7ddfbfSEd Maste   return filter_sp;
510ac7ddfbfSEd Maste }
511ac7ddfbfSEd Maste 
512ac7ddfbfSEd Maste SearchFilterSP
GetSearchFilterForModuleList(const FileSpecList * containingModules)513435933ddSDimitry Andric Target::GetSearchFilterForModuleList(const FileSpecList *containingModules) {
514ac7ddfbfSEd Maste   SearchFilterSP filter_sp;
515435933ddSDimitry Andric   if (containingModules && containingModules->GetSize() != 0) {
516ac7ddfbfSEd Maste     // TODO: We should look into sharing module based search filters
517ac7ddfbfSEd Maste     // across many breakpoints like we do for the simple target based one
518435933ddSDimitry Andric     filter_sp.reset(
519435933ddSDimitry Andric         new SearchFilterByModuleList(shared_from_this(), *containingModules));
520435933ddSDimitry Andric   } else {
5219f2f44ceSEd Maste     if (!m_search_filter_sp)
522435933ddSDimitry Andric       m_search_filter_sp.reset(
523435933ddSDimitry Andric           new SearchFilterForUnconstrainedSearches(shared_from_this()));
524ac7ddfbfSEd Maste     filter_sp = m_search_filter_sp;
525ac7ddfbfSEd Maste   }
526ac7ddfbfSEd Maste   return filter_sp;
527ac7ddfbfSEd Maste }
528ac7ddfbfSEd Maste 
GetSearchFilterForModuleAndCUList(const FileSpecList * containingModules,const FileSpecList * containingSourceFiles)529435933ddSDimitry Andric SearchFilterSP Target::GetSearchFilterForModuleAndCUList(
530435933ddSDimitry Andric     const FileSpecList *containingModules,
531435933ddSDimitry Andric     const FileSpecList *containingSourceFiles) {
5329f2f44ceSEd Maste   if (containingSourceFiles == nullptr || containingSourceFiles->GetSize() == 0)
533ac7ddfbfSEd Maste     return GetSearchFilterForModuleList(containingModules);
534ac7ddfbfSEd Maste 
535ac7ddfbfSEd Maste   SearchFilterSP filter_sp;
536435933ddSDimitry Andric   if (containingModules == nullptr) {
537435933ddSDimitry Andric     // We could make a special "CU List only SearchFilter".  Better yet was if
5384ba319b5SDimitry Andric     // these could be composable, but that will take a little reworking.
539ac7ddfbfSEd Maste 
540435933ddSDimitry Andric     filter_sp.reset(new SearchFilterByModuleListAndCU(
541435933ddSDimitry Andric         shared_from_this(), FileSpecList(), *containingSourceFiles));
542435933ddSDimitry Andric   } else {
543435933ddSDimitry Andric     filter_sp.reset(new SearchFilterByModuleListAndCU(
544435933ddSDimitry Andric         shared_from_this(), *containingModules, *containingSourceFiles));
545ac7ddfbfSEd Maste   }
546ac7ddfbfSEd Maste   return filter_sp;
547ac7ddfbfSEd Maste }
548ac7ddfbfSEd Maste 
CreateFuncRegexBreakpoint(const FileSpecList * containingModules,const FileSpecList * containingSourceFiles,RegularExpression & func_regex,lldb::LanguageType requested_language,LazyBool skip_prologue,bool internal,bool hardware)549435933ddSDimitry Andric BreakpointSP Target::CreateFuncRegexBreakpoint(
550435933ddSDimitry Andric     const FileSpecList *containingModules,
551435933ddSDimitry Andric     const FileSpecList *containingSourceFiles, RegularExpression &func_regex,
552435933ddSDimitry Andric     lldb::LanguageType requested_language, LazyBool skip_prologue,
553435933ddSDimitry Andric     bool internal, bool hardware) {
554435933ddSDimitry Andric   SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList(
555435933ddSDimitry Andric       containingModules, containingSourceFiles));
556435933ddSDimitry Andric   bool skip = (skip_prologue == eLazyBoolCalculate)
557435933ddSDimitry Andric                   ? GetSkipPrologue()
5580127ef0fSEd Maste                   : static_cast<bool>(skip_prologue);
559435933ddSDimitry Andric   BreakpointResolverSP resolver_sp(new BreakpointResolverName(
560435933ddSDimitry Andric       nullptr, func_regex, requested_language, 0, skip));
561ac7ddfbfSEd Maste 
56212b93ac6SEd Maste   return CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true);
563ac7ddfbfSEd Maste }
564ac7ddfbfSEd Maste 
565ac7ddfbfSEd Maste lldb::BreakpointSP
CreateExceptionBreakpoint(enum lldb::LanguageType language,bool catch_bp,bool throw_bp,bool internal,Args * additional_args,Status * error)566435933ddSDimitry Andric Target::CreateExceptionBreakpoint(enum lldb::LanguageType language,
567435933ddSDimitry Andric                                   bool catch_bp, bool throw_bp, bool internal,
5685517e702SDimitry Andric                                   Args *additional_args, Status *error) {
569435933ddSDimitry Andric   BreakpointSP exc_bkpt_sp = LanguageRuntime::CreateExceptionBreakpoint(
570435933ddSDimitry Andric       *this, language, catch_bp, throw_bp, internal);
571435933ddSDimitry Andric   if (exc_bkpt_sp && additional_args) {
572435933ddSDimitry Andric     Breakpoint::BreakpointPreconditionSP precondition_sp =
573435933ddSDimitry Andric         exc_bkpt_sp->GetPrecondition();
574435933ddSDimitry Andric     if (precondition_sp && additional_args) {
5751c3bbb01SEd Maste       if (error)
5761c3bbb01SEd Maste         *error = precondition_sp->ConfigurePrecondition(*additional_args);
5771c3bbb01SEd Maste       else
5781c3bbb01SEd Maste         precondition_sp->ConfigurePrecondition(*additional_args);
5791c3bbb01SEd Maste     }
5801c3bbb01SEd Maste   }
5811c3bbb01SEd Maste   return exc_bkpt_sp;
582ac7ddfbfSEd Maste }
583ac7ddfbfSEd Maste 
584*b5893f02SDimitry Andric lldb::BreakpointSP
CreateScriptedBreakpoint(const llvm::StringRef class_name,const FileSpecList * containingModules,const FileSpecList * containingSourceFiles,bool internal,bool request_hardware,StructuredData::ObjectSP extra_args_sp,Status * creation_error)585*b5893f02SDimitry Andric Target::CreateScriptedBreakpoint(const llvm::StringRef class_name,
586*b5893f02SDimitry Andric                                  const FileSpecList *containingModules,
587*b5893f02SDimitry Andric                                  const FileSpecList *containingSourceFiles,
588*b5893f02SDimitry Andric                                  bool internal,
589*b5893f02SDimitry Andric                                  bool request_hardware,
590*b5893f02SDimitry Andric                                  StructuredData::ObjectSP extra_args_sp,
591*b5893f02SDimitry Andric                                  Status *creation_error)
592*b5893f02SDimitry Andric {
593*b5893f02SDimitry Andric   SearchFilterSP filter_sp;
594*b5893f02SDimitry Andric 
595*b5893f02SDimitry Andric   lldb::SearchDepth depth = lldb::eSearchDepthTarget;
596*b5893f02SDimitry Andric   bool has_files = containingSourceFiles && containingSourceFiles->GetSize() > 0;
597*b5893f02SDimitry Andric   bool has_modules = containingModules && containingModules->GetSize() > 0;
598*b5893f02SDimitry Andric 
599*b5893f02SDimitry Andric   if (has_files && has_modules) {
600*b5893f02SDimitry Andric     filter_sp = GetSearchFilterForModuleAndCUList(
601*b5893f02SDimitry Andric       containingModules, containingSourceFiles);
602*b5893f02SDimitry Andric   } else if (has_files) {
603*b5893f02SDimitry Andric     filter_sp = GetSearchFilterForModuleAndCUList(
604*b5893f02SDimitry Andric       nullptr, containingSourceFiles);
605*b5893f02SDimitry Andric   } else if (has_modules) {
606*b5893f02SDimitry Andric     filter_sp = GetSearchFilterForModuleList(containingModules);
607*b5893f02SDimitry Andric   } else {
608*b5893f02SDimitry Andric     filter_sp.reset(new SearchFilterForUnconstrainedSearches(shared_from_this()));
609*b5893f02SDimitry Andric   }
610*b5893f02SDimitry Andric 
611*b5893f02SDimitry Andric   StructuredDataImpl *extra_args_impl = new StructuredDataImpl();
612*b5893f02SDimitry Andric   if (extra_args_sp)
613*b5893f02SDimitry Andric     extra_args_impl->SetObjectSP(extra_args_sp);
614*b5893f02SDimitry Andric 
615*b5893f02SDimitry Andric   BreakpointResolverSP resolver_sp(new
616*b5893f02SDimitry Andric                                    BreakpointResolverScripted(nullptr, class_name,
617*b5893f02SDimitry Andric                                    depth,
618*b5893f02SDimitry Andric                                    extra_args_impl,
619*b5893f02SDimitry Andric                                    *GetDebugger().GetCommandInterpreter()
620*b5893f02SDimitry Andric                                        .GetScriptInterpreter()));
621*b5893f02SDimitry Andric   return CreateBreakpoint(filter_sp, resolver_sp, internal, false, true);
622*b5893f02SDimitry Andric 
623*b5893f02SDimitry Andric }
624*b5893f02SDimitry Andric 
625*b5893f02SDimitry Andric 
CreateBreakpoint(SearchFilterSP & filter_sp,BreakpointResolverSP & resolver_sp,bool internal,bool request_hardware,bool resolve_indirect_symbols)626435933ddSDimitry Andric BreakpointSP Target::CreateBreakpoint(SearchFilterSP &filter_sp,
627435933ddSDimitry Andric                                       BreakpointResolverSP &resolver_sp,
628435933ddSDimitry Andric                                       bool internal, bool request_hardware,
629435933ddSDimitry Andric                                       bool resolve_indirect_symbols) {
630ac7ddfbfSEd Maste   BreakpointSP bp_sp;
631435933ddSDimitry Andric   if (filter_sp && resolver_sp) {
632*b5893f02SDimitry Andric     const bool hardware = request_hardware || GetRequireHardwareBreakpoints();
633*b5893f02SDimitry Andric     bp_sp.reset(new Breakpoint(*this, filter_sp, resolver_sp, hardware,
634435933ddSDimitry Andric                                resolve_indirect_symbols));
635ac7ddfbfSEd Maste     resolver_sp->SetBreakpoint(bp_sp.get());
6367aa51b79SEd Maste     AddBreakpoint(bp_sp, internal);
6377aa51b79SEd Maste   }
6387aa51b79SEd Maste   return bp_sp;
6397aa51b79SEd Maste }
640ac7ddfbfSEd Maste 
AddBreakpoint(lldb::BreakpointSP bp_sp,bool internal)641435933ddSDimitry Andric void Target::AddBreakpoint(lldb::BreakpointSP bp_sp, bool internal) {
6427aa51b79SEd Maste   if (!bp_sp)
6437aa51b79SEd Maste     return;
644ac7ddfbfSEd Maste   if (internal)
645ac7ddfbfSEd Maste     m_internal_breakpoint_list.Add(bp_sp, false);
646ac7ddfbfSEd Maste   else
647ac7ddfbfSEd Maste     m_breakpoint_list.Add(bp_sp, true);
648ac7ddfbfSEd Maste 
649ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
650435933ddSDimitry Andric   if (log) {
651ac7ddfbfSEd Maste     StreamString s;
652ac7ddfbfSEd Maste     bp_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
653435933ddSDimitry Andric     log->Printf("Target::%s (internal = %s) => break_id = %s\n", __FUNCTION__,
654435933ddSDimitry Andric                 bp_sp->IsInternal() ? "yes" : "no", s.GetData());
655ac7ddfbfSEd Maste   }
656ac7ddfbfSEd Maste 
657ac7ddfbfSEd Maste   bp_sp->ResolveBreakpoint();
658ac7ddfbfSEd Maste 
659435933ddSDimitry Andric   if (!internal) {
660ac7ddfbfSEd Maste     m_last_created_breakpoint = bp_sp;
661ac7ddfbfSEd Maste   }
662ac7ddfbfSEd Maste }
663ac7ddfbfSEd Maste 
AddNameToBreakpoint(BreakpointID & id,const char * name,Status & error)664acac075bSDimitry Andric void Target::AddNameToBreakpoint(BreakpointID &id,
665acac075bSDimitry Andric                                  const char *name,
666acac075bSDimitry Andric                                  Status &error)
667acac075bSDimitry Andric  {
668acac075bSDimitry Andric    BreakpointSP bp_sp
669acac075bSDimitry Andric        = m_breakpoint_list.FindBreakpointByID(id.GetBreakpointID());
670acac075bSDimitry Andric    if (!bp_sp)
671acac075bSDimitry Andric    {
672acac075bSDimitry Andric      StreamString s;
673acac075bSDimitry Andric      id.GetDescription(&s, eDescriptionLevelBrief);
674acac075bSDimitry Andric      error.SetErrorStringWithFormat("Could not find breakpoint %s",
675acac075bSDimitry Andric                                     s.GetData());
676acac075bSDimitry Andric      return;
677acac075bSDimitry Andric    }
678acac075bSDimitry Andric    AddNameToBreakpoint(bp_sp, name, error);
679acac075bSDimitry Andric  }
680acac075bSDimitry Andric 
AddNameToBreakpoint(BreakpointSP & bp_sp,const char * name,Status & error)681acac075bSDimitry Andric void Target::AddNameToBreakpoint(BreakpointSP &bp_sp,
682acac075bSDimitry Andric                                  const char *name,
683acac075bSDimitry Andric                                  Status &error)
684acac075bSDimitry Andric  {
685acac075bSDimitry Andric    if (!bp_sp)
686acac075bSDimitry Andric      return;
687acac075bSDimitry Andric 
688acac075bSDimitry Andric    BreakpointName *bp_name = FindBreakpointName(ConstString(name), true, error);
689acac075bSDimitry Andric    if (!bp_name)
690acac075bSDimitry Andric      return;
691acac075bSDimitry Andric 
692acac075bSDimitry Andric    bp_name->ConfigureBreakpoint(bp_sp);
693acac075bSDimitry Andric    bp_sp->AddName(name);
694acac075bSDimitry Andric  }
695acac075bSDimitry Andric 
AddBreakpointName(BreakpointName * bp_name)696acac075bSDimitry Andric void Target::AddBreakpointName(BreakpointName *bp_name) {
697acac075bSDimitry Andric   m_breakpoint_names.insert(std::make_pair(bp_name->GetName(), bp_name));
698acac075bSDimitry Andric }
699acac075bSDimitry Andric 
FindBreakpointName(const ConstString & name,bool can_create,Status & error)700acac075bSDimitry Andric BreakpointName *Target::FindBreakpointName(const ConstString &name,
701acac075bSDimitry Andric                                            bool can_create,
702acac075bSDimitry Andric                                            Status &error)
703acac075bSDimitry Andric {
704acac075bSDimitry Andric   BreakpointID::StringIsBreakpointName(name.GetStringRef(), error);
705acac075bSDimitry Andric   if (!error.Success())
706acac075bSDimitry Andric     return nullptr;
707acac075bSDimitry Andric 
708acac075bSDimitry Andric   BreakpointNameList::iterator iter = m_breakpoint_names.find(name);
709acac075bSDimitry Andric   if (iter == m_breakpoint_names.end()) {
710acac075bSDimitry Andric     if (!can_create)
711acac075bSDimitry Andric     {
712acac075bSDimitry Andric       error.SetErrorStringWithFormat("Breakpoint name \"%s\" doesn't exist and "
713acac075bSDimitry Andric                                      "can_create is false.", name.AsCString());
714acac075bSDimitry Andric       return nullptr;
715acac075bSDimitry Andric     }
716acac075bSDimitry Andric 
717acac075bSDimitry Andric     iter = m_breakpoint_names.insert(std::make_pair(name,
718acac075bSDimitry Andric                                                     new BreakpointName(name)))
719acac075bSDimitry Andric                                                         .first;
720acac075bSDimitry Andric   }
721acac075bSDimitry Andric   return (iter->second);
722acac075bSDimitry Andric }
723acac075bSDimitry Andric 
724acac075bSDimitry Andric void
DeleteBreakpointName(const ConstString & name)725acac075bSDimitry Andric Target::DeleteBreakpointName(const ConstString &name)
726acac075bSDimitry Andric {
727acac075bSDimitry Andric   BreakpointNameList::iterator iter = m_breakpoint_names.find(name);
728acac075bSDimitry Andric 
729acac075bSDimitry Andric   if (iter != m_breakpoint_names.end()) {
730acac075bSDimitry Andric     const char *name_cstr = name.AsCString();
731acac075bSDimitry Andric     m_breakpoint_names.erase(iter);
732acac075bSDimitry Andric     for (auto bp_sp : m_breakpoint_list.Breakpoints())
733acac075bSDimitry Andric       bp_sp->RemoveName(name_cstr);
734acac075bSDimitry Andric   }
735acac075bSDimitry Andric }
736acac075bSDimitry Andric 
RemoveNameFromBreakpoint(lldb::BreakpointSP & bp_sp,const ConstString & name)737acac075bSDimitry Andric void Target::RemoveNameFromBreakpoint(lldb::BreakpointSP &bp_sp,
738acac075bSDimitry Andric                                 const ConstString &name)
739acac075bSDimitry Andric {
740acac075bSDimitry Andric   bp_sp->RemoveName(name.AsCString());
741acac075bSDimitry Andric }
742acac075bSDimitry Andric 
ConfigureBreakpointName(BreakpointName & bp_name,const BreakpointOptions & new_options,const BreakpointName::Permissions & new_permissions)743acac075bSDimitry Andric void Target::ConfigureBreakpointName(BreakpointName &bp_name,
744acac075bSDimitry Andric                                const BreakpointOptions &new_options,
745acac075bSDimitry Andric                                const BreakpointName::Permissions &new_permissions)
746acac075bSDimitry Andric {
747acac075bSDimitry Andric   bp_name.GetOptions().CopyOverSetOptions(new_options);
748acac075bSDimitry Andric   bp_name.GetPermissions().MergeInto(new_permissions);
749acac075bSDimitry Andric   ApplyNameToBreakpoints(bp_name);
750acac075bSDimitry Andric }
751acac075bSDimitry Andric 
ApplyNameToBreakpoints(BreakpointName & bp_name)752acac075bSDimitry Andric void Target::ApplyNameToBreakpoints(BreakpointName &bp_name) {
753acac075bSDimitry Andric   BreakpointList bkpts_with_name(false);
754acac075bSDimitry Andric   m_breakpoint_list.FindBreakpointsByName(bp_name.GetName().AsCString(),
755acac075bSDimitry Andric                                           bkpts_with_name);
756acac075bSDimitry Andric 
757acac075bSDimitry Andric   for (auto bp_sp : bkpts_with_name.Breakpoints())
758acac075bSDimitry Andric     bp_name.ConfigureBreakpoint(bp_sp);
759acac075bSDimitry Andric }
760acac075bSDimitry Andric 
GetBreakpointNames(std::vector<std::string> & names)761acac075bSDimitry Andric void Target::GetBreakpointNames(std::vector<std::string> &names)
762acac075bSDimitry Andric {
763acac075bSDimitry Andric   names.clear();
764acac075bSDimitry Andric   for (auto bp_name : m_breakpoint_names) {
765acac075bSDimitry Andric     names.push_back(bp_name.first.AsCString());
766acac075bSDimitry Andric   }
767*b5893f02SDimitry Andric   llvm::sort(names.begin(), names.end());
768acac075bSDimitry Andric }
769acac075bSDimitry Andric 
ProcessIsValid()770435933ddSDimitry Andric bool Target::ProcessIsValid() {
771ac7ddfbfSEd Maste   return (m_process_sp && m_process_sp->IsAlive());
772ac7ddfbfSEd Maste }
773ac7ddfbfSEd Maste 
CheckIfWatchpointsSupported(Target * target,Status & error)774*b5893f02SDimitry Andric static bool CheckIfWatchpointsSupported(Target *target, Status &error) {
775ac7ddfbfSEd Maste   uint32_t num_supported_hardware_watchpoints;
7765517e702SDimitry Andric   Status rc = target->GetProcessSP()->GetWatchpointSupportInfo(
777435933ddSDimitry Andric       num_supported_hardware_watchpoints);
778*b5893f02SDimitry Andric 
779*b5893f02SDimitry Andric   // If unable to determine the # of watchpoints available,
780*b5893f02SDimitry Andric   // assume they are supported.
781*b5893f02SDimitry Andric   if (rc.Fail())
782*b5893f02SDimitry Andric     return true;
783*b5893f02SDimitry Andric 
784435933ddSDimitry Andric   if (num_supported_hardware_watchpoints == 0) {
785435933ddSDimitry Andric     error.SetErrorStringWithFormat(
786435933ddSDimitry Andric         "Target supports (%u) hardware watchpoint slots.\n",
787ac7ddfbfSEd Maste         num_supported_hardware_watchpoints);
788ac7ddfbfSEd Maste     return false;
789ac7ddfbfSEd Maste   }
7904bb0738eSEd Maste   return true;
7914bb0738eSEd Maste }
792ac7ddfbfSEd Maste 
7934ba319b5SDimitry Andric // See also Watchpoint::SetWatchpointType(uint32_t type) and the
7944ba319b5SDimitry Andric // OptionGroupWatchpoint::WatchType enum type.
CreateWatchpoint(lldb::addr_t addr,size_t size,const CompilerType * type,uint32_t kind,Status & error)795435933ddSDimitry Andric WatchpointSP Target::CreateWatchpoint(lldb::addr_t addr, size_t size,
796435933ddSDimitry Andric                                       const CompilerType *type, uint32_t kind,
7975517e702SDimitry Andric                                       Status &error) {
798ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
799ac7ddfbfSEd Maste   if (log)
800435933ddSDimitry Andric     log->Printf("Target::%s (addr = 0x%8.8" PRIx64 " size = %" PRIu64
801435933ddSDimitry Andric                 " type = %u)\n",
802ac7ddfbfSEd Maste                 __FUNCTION__, addr, (uint64_t)size, kind);
803ac7ddfbfSEd Maste 
804ac7ddfbfSEd Maste   WatchpointSP wp_sp;
805435933ddSDimitry Andric   if (!ProcessIsValid()) {
806ac7ddfbfSEd Maste     error.SetErrorString("process is not alive");
807ac7ddfbfSEd Maste     return wp_sp;
808ac7ddfbfSEd Maste   }
809ac7ddfbfSEd Maste 
810435933ddSDimitry Andric   if (addr == LLDB_INVALID_ADDRESS || size == 0) {
811ac7ddfbfSEd Maste     if (size == 0)
812ac7ddfbfSEd Maste       error.SetErrorString("cannot set a watchpoint with watch_size of 0");
813ac7ddfbfSEd Maste     else
814ac7ddfbfSEd Maste       error.SetErrorStringWithFormat("invalid watch address: %" PRIu64, addr);
815ac7ddfbfSEd Maste     return wp_sp;
816ac7ddfbfSEd Maste   }
817ac7ddfbfSEd Maste 
818435933ddSDimitry Andric   if (!LLDB_WATCH_TYPE_IS_VALID(kind)) {
819ac7ddfbfSEd Maste     error.SetErrorStringWithFormat("invalid watchpoint type: %d", kind);
820ac7ddfbfSEd Maste   }
821ac7ddfbfSEd Maste 
822*b5893f02SDimitry Andric   if (!CheckIfWatchpointsSupported(this, error))
8234bb0738eSEd Maste     return wp_sp;
8244bb0738eSEd Maste 
8254ba319b5SDimitry Andric   // Currently we only support one watchpoint per address, with total number of
8264ba319b5SDimitry Andric   // watchpoints limited by the hardware which the inferior is running on.
827ac7ddfbfSEd Maste 
828ac7ddfbfSEd Maste   // Grab the list mutex while doing operations.
829435933ddSDimitry Andric   const bool notify = false; // Don't notify about all the state changes we do
830435933ddSDimitry Andric                              // on creating the watchpoint.
8314bb0738eSEd Maste   std::unique_lock<std::recursive_mutex> lock;
8324bb0738eSEd Maste   this->GetWatchpointList().GetListMutex(lock);
833ac7ddfbfSEd Maste   WatchpointSP matched_sp = m_watchpoint_list.FindByAddress(addr);
834435933ddSDimitry Andric   if (matched_sp) {
835ac7ddfbfSEd Maste     size_t old_size = matched_sp->GetByteSize();
836ac7ddfbfSEd Maste     uint32_t old_type =
837ac7ddfbfSEd Maste         (matched_sp->WatchpointRead() ? LLDB_WATCH_TYPE_READ : 0) |
838ac7ddfbfSEd Maste         (matched_sp->WatchpointWrite() ? LLDB_WATCH_TYPE_WRITE : 0);
839ac7ddfbfSEd Maste     // Return the existing watchpoint if both size and type match.
840435933ddSDimitry Andric     if (size == old_size && kind == old_type) {
841ac7ddfbfSEd Maste       wp_sp = matched_sp;
842ac7ddfbfSEd Maste       wp_sp->SetEnabled(false, notify);
843435933ddSDimitry Andric     } else {
844ac7ddfbfSEd Maste       // Nil the matched watchpoint; we will be creating a new one.
845ac7ddfbfSEd Maste       m_process_sp->DisableWatchpoint(matched_sp.get(), notify);
846ac7ddfbfSEd Maste       m_watchpoint_list.Remove(matched_sp->GetID(), true);
847ac7ddfbfSEd Maste     }
848ac7ddfbfSEd Maste   }
849ac7ddfbfSEd Maste 
850435933ddSDimitry Andric   if (!wp_sp) {
851ac7ddfbfSEd Maste     wp_sp.reset(new Watchpoint(*this, addr, size, type));
852ac7ddfbfSEd Maste     wp_sp->SetWatchpointType(kind, notify);
853ac7ddfbfSEd Maste     m_watchpoint_list.Add(wp_sp, true);
854ac7ddfbfSEd Maste   }
855ac7ddfbfSEd Maste 
856ac7ddfbfSEd Maste   error = m_process_sp->EnableWatchpoint(wp_sp.get(), notify);
857ac7ddfbfSEd Maste   if (log)
858ac7ddfbfSEd Maste     log->Printf("Target::%s (creation of watchpoint %s with id = %u)\n",
859435933ddSDimitry Andric                 __FUNCTION__, error.Success() ? "succeeded" : "failed",
860ac7ddfbfSEd Maste                 wp_sp->GetID());
861ac7ddfbfSEd Maste 
862435933ddSDimitry Andric   if (error.Fail()) {
8634ba319b5SDimitry Andric     // Enabling the watchpoint on the device side failed. Remove the said
8644ba319b5SDimitry Andric     // watchpoint from the list maintained by the target instance.
865ac7ddfbfSEd Maste     m_watchpoint_list.Remove(wp_sp->GetID(), true);
866ac7ddfbfSEd Maste     // See if we could provide more helpful error message.
867ac7ddfbfSEd Maste     if (!OptionGroupWatchpoint::IsWatchSizeSupported(size))
868435933ddSDimitry Andric       error.SetErrorStringWithFormat(
869435933ddSDimitry Andric           "watch size of %" PRIu64 " is not supported", (uint64_t)size);
8704bb0738eSEd Maste 
871ac7ddfbfSEd Maste     wp_sp.reset();
872435933ddSDimitry Andric   } else
873ac7ddfbfSEd Maste     m_last_created_watchpoint = wp_sp;
874ac7ddfbfSEd Maste   return wp_sp;
875ac7ddfbfSEd Maste }
876ac7ddfbfSEd Maste 
RemoveAllowedBreakpoints()877acac075bSDimitry Andric void Target::RemoveAllowedBreakpoints ()
878acac075bSDimitry Andric {
879acac075bSDimitry Andric   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
880acac075bSDimitry Andric   if (log)
881acac075bSDimitry Andric     log->Printf("Target::%s \n", __FUNCTION__);
882acac075bSDimitry Andric 
883acac075bSDimitry Andric   m_breakpoint_list.RemoveAllowed(true);
884acac075bSDimitry Andric 
885acac075bSDimitry Andric   m_last_created_breakpoint.reset();
886acac075bSDimitry Andric }
887acac075bSDimitry Andric 
RemoveAllBreakpoints(bool internal_also)888435933ddSDimitry Andric void Target::RemoveAllBreakpoints(bool internal_also) {
889ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
890ac7ddfbfSEd Maste   if (log)
891435933ddSDimitry Andric     log->Printf("Target::%s (internal_also = %s)\n", __FUNCTION__,
892435933ddSDimitry Andric                 internal_also ? "yes" : "no");
893ac7ddfbfSEd Maste 
894ac7ddfbfSEd Maste   m_breakpoint_list.RemoveAll(true);
895ac7ddfbfSEd Maste   if (internal_also)
896ac7ddfbfSEd Maste     m_internal_breakpoint_list.RemoveAll(false);
897ac7ddfbfSEd Maste 
898ac7ddfbfSEd Maste   m_last_created_breakpoint.reset();
899ac7ddfbfSEd Maste }
900ac7ddfbfSEd Maste 
DisableAllBreakpoints(bool internal_also)901435933ddSDimitry Andric void Target::DisableAllBreakpoints(bool internal_also) {
902ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
903ac7ddfbfSEd Maste   if (log)
904435933ddSDimitry Andric     log->Printf("Target::%s (internal_also = %s)\n", __FUNCTION__,
905435933ddSDimitry Andric                 internal_also ? "yes" : "no");
906ac7ddfbfSEd Maste 
907ac7ddfbfSEd Maste   m_breakpoint_list.SetEnabledAll(false);
908ac7ddfbfSEd Maste   if (internal_also)
909ac7ddfbfSEd Maste     m_internal_breakpoint_list.SetEnabledAll(false);
910ac7ddfbfSEd Maste }
911ac7ddfbfSEd Maste 
DisableAllowedBreakpoints()912acac075bSDimitry Andric void Target::DisableAllowedBreakpoints() {
913acac075bSDimitry Andric   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
914acac075bSDimitry Andric   if (log)
915acac075bSDimitry Andric     log->Printf("Target::%s", __FUNCTION__);
916acac075bSDimitry Andric 
917acac075bSDimitry Andric   m_breakpoint_list.SetEnabledAllowed(false);
918acac075bSDimitry Andric }
919acac075bSDimitry Andric 
EnableAllBreakpoints(bool internal_also)920435933ddSDimitry Andric void Target::EnableAllBreakpoints(bool internal_also) {
921ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
922ac7ddfbfSEd Maste   if (log)
923435933ddSDimitry Andric     log->Printf("Target::%s (internal_also = %s)\n", __FUNCTION__,
924435933ddSDimitry Andric                 internal_also ? "yes" : "no");
925ac7ddfbfSEd Maste 
926ac7ddfbfSEd Maste   m_breakpoint_list.SetEnabledAll(true);
927ac7ddfbfSEd Maste   if (internal_also)
928ac7ddfbfSEd Maste     m_internal_breakpoint_list.SetEnabledAll(true);
929ac7ddfbfSEd Maste }
930ac7ddfbfSEd Maste 
EnableAllowedBreakpoints()931acac075bSDimitry Andric void Target::EnableAllowedBreakpoints() {
932acac075bSDimitry Andric   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
933acac075bSDimitry Andric   if (log)
934acac075bSDimitry Andric     log->Printf("Target::%s", __FUNCTION__);
935acac075bSDimitry Andric 
936acac075bSDimitry Andric   m_breakpoint_list.SetEnabledAllowed(true);
937acac075bSDimitry Andric }
938acac075bSDimitry Andric 
RemoveBreakpointByID(break_id_t break_id)939435933ddSDimitry Andric bool Target::RemoveBreakpointByID(break_id_t break_id) {
940ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
941ac7ddfbfSEd Maste   if (log)
942435933ddSDimitry Andric     log->Printf("Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__,
943435933ddSDimitry Andric                 break_id, LLDB_BREAK_ID_IS_INTERNAL(break_id) ? "yes" : "no");
944ac7ddfbfSEd Maste 
945435933ddSDimitry Andric   if (DisableBreakpointByID(break_id)) {
946ac7ddfbfSEd Maste     if (LLDB_BREAK_ID_IS_INTERNAL(break_id))
947ac7ddfbfSEd Maste       m_internal_breakpoint_list.Remove(break_id, false);
948435933ddSDimitry Andric     else {
949435933ddSDimitry Andric       if (m_last_created_breakpoint) {
950ac7ddfbfSEd Maste         if (m_last_created_breakpoint->GetID() == break_id)
951ac7ddfbfSEd Maste           m_last_created_breakpoint.reset();
952ac7ddfbfSEd Maste       }
953ac7ddfbfSEd Maste       m_breakpoint_list.Remove(break_id, true);
954ac7ddfbfSEd Maste     }
955ac7ddfbfSEd Maste     return true;
956ac7ddfbfSEd Maste   }
957ac7ddfbfSEd Maste   return false;
958ac7ddfbfSEd Maste }
959ac7ddfbfSEd Maste 
DisableBreakpointByID(break_id_t break_id)960435933ddSDimitry Andric bool Target::DisableBreakpointByID(break_id_t break_id) {
961ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
962ac7ddfbfSEd Maste   if (log)
963435933ddSDimitry Andric     log->Printf("Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__,
964435933ddSDimitry Andric                 break_id, LLDB_BREAK_ID_IS_INTERNAL(break_id) ? "yes" : "no");
965ac7ddfbfSEd Maste 
966ac7ddfbfSEd Maste   BreakpointSP bp_sp;
967ac7ddfbfSEd Maste 
968ac7ddfbfSEd Maste   if (LLDB_BREAK_ID_IS_INTERNAL(break_id))
969ac7ddfbfSEd Maste     bp_sp = m_internal_breakpoint_list.FindBreakpointByID(break_id);
970ac7ddfbfSEd Maste   else
971ac7ddfbfSEd Maste     bp_sp = m_breakpoint_list.FindBreakpointByID(break_id);
972435933ddSDimitry Andric   if (bp_sp) {
973ac7ddfbfSEd Maste     bp_sp->SetEnabled(false);
974ac7ddfbfSEd Maste     return true;
975ac7ddfbfSEd Maste   }
976ac7ddfbfSEd Maste   return false;
977ac7ddfbfSEd Maste }
978ac7ddfbfSEd Maste 
EnableBreakpointByID(break_id_t break_id)979435933ddSDimitry Andric bool Target::EnableBreakpointByID(break_id_t break_id) {
980ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
981ac7ddfbfSEd Maste   if (log)
982435933ddSDimitry Andric     log->Printf("Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__,
983435933ddSDimitry Andric                 break_id, LLDB_BREAK_ID_IS_INTERNAL(break_id) ? "yes" : "no");
984ac7ddfbfSEd Maste 
985ac7ddfbfSEd Maste   BreakpointSP bp_sp;
986ac7ddfbfSEd Maste 
987ac7ddfbfSEd Maste   if (LLDB_BREAK_ID_IS_INTERNAL(break_id))
988ac7ddfbfSEd Maste     bp_sp = m_internal_breakpoint_list.FindBreakpointByID(break_id);
989ac7ddfbfSEd Maste   else
990ac7ddfbfSEd Maste     bp_sp = m_breakpoint_list.FindBreakpointByID(break_id);
991ac7ddfbfSEd Maste 
992435933ddSDimitry Andric   if (bp_sp) {
993ac7ddfbfSEd Maste     bp_sp->SetEnabled(true);
994ac7ddfbfSEd Maste     return true;
995ac7ddfbfSEd Maste   }
996ac7ddfbfSEd Maste   return false;
997ac7ddfbfSEd Maste }
998ac7ddfbfSEd Maste 
SerializeBreakpointsToFile(const FileSpec & file,const BreakpointIDList & bp_ids,bool append)9995517e702SDimitry Andric Status Target::SerializeBreakpointsToFile(const FileSpec &file,
1000435933ddSDimitry Andric                                           const BreakpointIDList &bp_ids,
1001435933ddSDimitry Andric                                           bool append) {
10025517e702SDimitry Andric   Status error;
1003435933ddSDimitry Andric 
1004435933ddSDimitry Andric   if (!file) {
1005435933ddSDimitry Andric     error.SetErrorString("Invalid FileSpec.");
1006435933ddSDimitry Andric     return error;
1007435933ddSDimitry Andric   }
1008435933ddSDimitry Andric 
1009435933ddSDimitry Andric   std::string path(file.GetPath());
1010435933ddSDimitry Andric   StructuredData::ObjectSP input_data_sp;
1011435933ddSDimitry Andric 
1012435933ddSDimitry Andric   StructuredData::ArraySP break_store_sp;
1013435933ddSDimitry Andric   StructuredData::Array *break_store_ptr = nullptr;
1014435933ddSDimitry Andric 
1015435933ddSDimitry Andric   if (append) {
1016435933ddSDimitry Andric     input_data_sp = StructuredData::ParseJSONFromFile(file, error);
1017435933ddSDimitry Andric     if (error.Success()) {
1018435933ddSDimitry Andric       break_store_ptr = input_data_sp->GetAsArray();
1019435933ddSDimitry Andric       if (!break_store_ptr) {
1020435933ddSDimitry Andric         error.SetErrorStringWithFormat(
1021435933ddSDimitry Andric             "Tried to append to invalid input file %s", path.c_str());
1022435933ddSDimitry Andric         return error;
1023435933ddSDimitry Andric       }
1024435933ddSDimitry Andric     }
1025435933ddSDimitry Andric   }
1026435933ddSDimitry Andric 
1027435933ddSDimitry Andric   if (!break_store_ptr) {
1028435933ddSDimitry Andric     break_store_sp.reset(new StructuredData::Array());
1029435933ddSDimitry Andric     break_store_ptr = break_store_sp.get();
1030435933ddSDimitry Andric   }
1031435933ddSDimitry Andric 
1032435933ddSDimitry Andric   StreamFile out_file(path.c_str(),
1033435933ddSDimitry Andric                       File::OpenOptions::eOpenOptionTruncate |
1034435933ddSDimitry Andric                           File::OpenOptions::eOpenOptionWrite |
1035435933ddSDimitry Andric                           File::OpenOptions::eOpenOptionCanCreate |
1036435933ddSDimitry Andric                           File::OpenOptions::eOpenOptionCloseOnExec,
1037435933ddSDimitry Andric                       lldb::eFilePermissionsFileDefault);
1038435933ddSDimitry Andric   if (!out_file.GetFile().IsValid()) {
1039435933ddSDimitry Andric     error.SetErrorStringWithFormat("Unable to open output file: %s.",
1040435933ddSDimitry Andric                                    path.c_str());
1041435933ddSDimitry Andric     return error;
1042435933ddSDimitry Andric   }
1043435933ddSDimitry Andric 
1044435933ddSDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
1045435933ddSDimitry Andric   GetBreakpointList().GetListMutex(lock);
1046435933ddSDimitry Andric 
1047435933ddSDimitry Andric   if (bp_ids.GetSize() == 0) {
1048435933ddSDimitry Andric     const BreakpointList &breakpoints = GetBreakpointList();
1049435933ddSDimitry Andric 
1050435933ddSDimitry Andric     size_t num_breakpoints = breakpoints.GetSize();
1051435933ddSDimitry Andric     for (size_t i = 0; i < num_breakpoints; i++) {
1052435933ddSDimitry Andric       Breakpoint *bp = breakpoints.GetBreakpointAtIndex(i).get();
1053435933ddSDimitry Andric       StructuredData::ObjectSP bkpt_save_sp = bp->SerializeToStructuredData();
1054435933ddSDimitry Andric       // If a breakpoint can't serialize it, just ignore it for now:
1055435933ddSDimitry Andric       if (bkpt_save_sp)
1056435933ddSDimitry Andric         break_store_ptr->AddItem(bkpt_save_sp);
1057435933ddSDimitry Andric     }
1058435933ddSDimitry Andric   } else {
1059435933ddSDimitry Andric 
1060435933ddSDimitry Andric     std::unordered_set<lldb::break_id_t> processed_bkpts;
1061435933ddSDimitry Andric     const size_t count = bp_ids.GetSize();
1062435933ddSDimitry Andric     for (size_t i = 0; i < count; ++i) {
1063435933ddSDimitry Andric       BreakpointID cur_bp_id = bp_ids.GetBreakpointIDAtIndex(i);
1064435933ddSDimitry Andric       lldb::break_id_t bp_id = cur_bp_id.GetBreakpointID();
1065435933ddSDimitry Andric 
1066435933ddSDimitry Andric       if (bp_id != LLDB_INVALID_BREAK_ID) {
1067435933ddSDimitry Andric         // Only do each breakpoint once:
1068435933ddSDimitry Andric         std::pair<std::unordered_set<lldb::break_id_t>::iterator, bool>
1069435933ddSDimitry Andric             insert_result = processed_bkpts.insert(bp_id);
1070435933ddSDimitry Andric         if (!insert_result.second)
1071435933ddSDimitry Andric           continue;
1072435933ddSDimitry Andric 
1073435933ddSDimitry Andric         Breakpoint *bp = GetBreakpointByID(bp_id).get();
1074435933ddSDimitry Andric         StructuredData::ObjectSP bkpt_save_sp = bp->SerializeToStructuredData();
1075435933ddSDimitry Andric         // If the user explicitly asked to serialize a breakpoint, and we
10764ba319b5SDimitry Andric         // can't, then raise an error:
1077435933ddSDimitry Andric         if (!bkpt_save_sp) {
1078435933ddSDimitry Andric           error.SetErrorStringWithFormat("Unable to serialize breakpoint %d",
1079435933ddSDimitry Andric                                          bp_id);
1080435933ddSDimitry Andric           return error;
1081435933ddSDimitry Andric         }
1082435933ddSDimitry Andric         break_store_ptr->AddItem(bkpt_save_sp);
1083435933ddSDimitry Andric       }
1084435933ddSDimitry Andric     }
1085435933ddSDimitry Andric   }
1086435933ddSDimitry Andric 
1087435933ddSDimitry Andric   break_store_ptr->Dump(out_file, false);
1088435933ddSDimitry Andric   out_file.PutChar('\n');
1089435933ddSDimitry Andric   return error;
1090435933ddSDimitry Andric }
1091435933ddSDimitry Andric 
CreateBreakpointsFromFile(const FileSpec & file,BreakpointIDList & new_bps)10925517e702SDimitry Andric Status Target::CreateBreakpointsFromFile(const FileSpec &file,
1093435933ddSDimitry Andric                                          BreakpointIDList &new_bps) {
1094435933ddSDimitry Andric   std::vector<std::string> no_names;
1095435933ddSDimitry Andric   return CreateBreakpointsFromFile(file, no_names, new_bps);
1096435933ddSDimitry Andric }
1097435933ddSDimitry Andric 
CreateBreakpointsFromFile(const FileSpec & file,std::vector<std::string> & names,BreakpointIDList & new_bps)10985517e702SDimitry Andric Status Target::CreateBreakpointsFromFile(const FileSpec &file,
1099435933ddSDimitry Andric                                          std::vector<std::string> &names,
1100435933ddSDimitry Andric                                          BreakpointIDList &new_bps) {
1101435933ddSDimitry Andric   std::unique_lock<std::recursive_mutex> lock;
1102435933ddSDimitry Andric   GetBreakpointList().GetListMutex(lock);
1103435933ddSDimitry Andric 
11045517e702SDimitry Andric   Status error;
1105435933ddSDimitry Andric   StructuredData::ObjectSP input_data_sp =
1106435933ddSDimitry Andric       StructuredData::ParseJSONFromFile(file, error);
1107435933ddSDimitry Andric   if (!error.Success()) {
1108435933ddSDimitry Andric     return error;
1109435933ddSDimitry Andric   } else if (!input_data_sp || !input_data_sp->IsValid()) {
1110435933ddSDimitry Andric     error.SetErrorStringWithFormat("Invalid JSON from input file: %s.",
1111435933ddSDimitry Andric                                    file.GetPath().c_str());
1112435933ddSDimitry Andric     return error;
1113435933ddSDimitry Andric   }
1114435933ddSDimitry Andric 
1115435933ddSDimitry Andric   StructuredData::Array *bkpt_array = input_data_sp->GetAsArray();
1116435933ddSDimitry Andric   if (!bkpt_array) {
1117435933ddSDimitry Andric     error.SetErrorStringWithFormat(
1118435933ddSDimitry Andric         "Invalid breakpoint data from input file: %s.", file.GetPath().c_str());
1119435933ddSDimitry Andric     return error;
1120435933ddSDimitry Andric   }
1121435933ddSDimitry Andric 
1122435933ddSDimitry Andric   size_t num_bkpts = bkpt_array->GetSize();
1123435933ddSDimitry Andric   size_t num_names = names.size();
1124435933ddSDimitry Andric 
1125435933ddSDimitry Andric   for (size_t i = 0; i < num_bkpts; i++) {
1126435933ddSDimitry Andric     StructuredData::ObjectSP bkpt_object_sp = bkpt_array->GetItemAtIndex(i);
1127435933ddSDimitry Andric     // Peel off the breakpoint key, and feed the rest to the Breakpoint:
1128435933ddSDimitry Andric     StructuredData::Dictionary *bkpt_dict = bkpt_object_sp->GetAsDictionary();
1129435933ddSDimitry Andric     if (!bkpt_dict) {
1130435933ddSDimitry Andric       error.SetErrorStringWithFormat(
1131435933ddSDimitry Andric           "Invalid breakpoint data for element %zu from input file: %s.", i,
1132435933ddSDimitry Andric           file.GetPath().c_str());
1133435933ddSDimitry Andric       return error;
1134435933ddSDimitry Andric     }
1135435933ddSDimitry Andric     StructuredData::ObjectSP bkpt_data_sp =
1136435933ddSDimitry Andric         bkpt_dict->GetValueForKey(Breakpoint::GetSerializationKey());
1137435933ddSDimitry Andric     if (num_names &&
1138435933ddSDimitry Andric         !Breakpoint::SerializedBreakpointMatchesNames(bkpt_data_sp, names))
1139435933ddSDimitry Andric       continue;
1140435933ddSDimitry Andric 
1141435933ddSDimitry Andric     BreakpointSP bkpt_sp =
1142435933ddSDimitry Andric         Breakpoint::CreateFromStructuredData(*this, bkpt_data_sp, error);
1143435933ddSDimitry Andric     if (!error.Success()) {
1144435933ddSDimitry Andric       error.SetErrorStringWithFormat(
1145435933ddSDimitry Andric           "Error restoring breakpoint %zu from %s: %s.", i,
1146435933ddSDimitry Andric           file.GetPath().c_str(), error.AsCString());
1147435933ddSDimitry Andric       return error;
1148435933ddSDimitry Andric     }
1149435933ddSDimitry Andric     new_bps.AddBreakpointID(BreakpointID(bkpt_sp->GetID()));
1150435933ddSDimitry Andric   }
1151435933ddSDimitry Andric   return error;
1152435933ddSDimitry Andric }
1153435933ddSDimitry Andric 
1154ac7ddfbfSEd Maste // The flag 'end_to_end', default to true, signifies that the operation is
1155ac7ddfbfSEd Maste // performed end to end, for both the debugger and the debuggee.
1156ac7ddfbfSEd Maste 
1157ac7ddfbfSEd Maste // Assumption: Caller holds the list mutex lock for m_watchpoint_list for end
1158ac7ddfbfSEd Maste // to end operations.
RemoveAllWatchpoints(bool end_to_end)1159435933ddSDimitry Andric bool Target::RemoveAllWatchpoints(bool end_to_end) {
1160ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
1161ac7ddfbfSEd Maste   if (log)
1162ac7ddfbfSEd Maste     log->Printf("Target::%s\n", __FUNCTION__);
1163ac7ddfbfSEd Maste 
1164ac7ddfbfSEd Maste   if (!end_to_end) {
1165ac7ddfbfSEd Maste     m_watchpoint_list.RemoveAll(true);
1166ac7ddfbfSEd Maste     return true;
1167ac7ddfbfSEd Maste   }
1168ac7ddfbfSEd Maste 
1169ac7ddfbfSEd Maste   // Otherwise, it's an end to end operation.
1170ac7ddfbfSEd Maste 
1171ac7ddfbfSEd Maste   if (!ProcessIsValid())
1172ac7ddfbfSEd Maste     return false;
1173ac7ddfbfSEd Maste 
1174ac7ddfbfSEd Maste   size_t num_watchpoints = m_watchpoint_list.GetSize();
1175435933ddSDimitry Andric   for (size_t i = 0; i < num_watchpoints; ++i) {
1176ac7ddfbfSEd Maste     WatchpointSP wp_sp = m_watchpoint_list.GetByIndex(i);
1177ac7ddfbfSEd Maste     if (!wp_sp)
1178ac7ddfbfSEd Maste       return false;
1179ac7ddfbfSEd Maste 
11805517e702SDimitry Andric     Status rc = m_process_sp->DisableWatchpoint(wp_sp.get());
1181ac7ddfbfSEd Maste     if (rc.Fail())
1182ac7ddfbfSEd Maste       return false;
1183ac7ddfbfSEd Maste   }
1184ac7ddfbfSEd Maste   m_watchpoint_list.RemoveAll(true);
1185ac7ddfbfSEd Maste   m_last_created_watchpoint.reset();
1186ac7ddfbfSEd Maste   return true; // Success!
1187ac7ddfbfSEd Maste }
1188ac7ddfbfSEd Maste 
11894ba319b5SDimitry Andric // Assumption: Caller holds the list mutex lock for m_watchpoint_list for end
11904ba319b5SDimitry Andric // to end operations.
DisableAllWatchpoints(bool end_to_end)1191435933ddSDimitry Andric bool Target::DisableAllWatchpoints(bool end_to_end) {
1192ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
1193ac7ddfbfSEd Maste   if (log)
1194ac7ddfbfSEd Maste     log->Printf("Target::%s\n", __FUNCTION__);
1195ac7ddfbfSEd Maste 
1196ac7ddfbfSEd Maste   if (!end_to_end) {
1197ac7ddfbfSEd Maste     m_watchpoint_list.SetEnabledAll(false);
1198ac7ddfbfSEd Maste     return true;
1199ac7ddfbfSEd Maste   }
1200ac7ddfbfSEd Maste 
1201ac7ddfbfSEd Maste   // Otherwise, it's an end to end operation.
1202ac7ddfbfSEd Maste 
1203ac7ddfbfSEd Maste   if (!ProcessIsValid())
1204ac7ddfbfSEd Maste     return false;
1205ac7ddfbfSEd Maste 
1206ac7ddfbfSEd Maste   size_t num_watchpoints = m_watchpoint_list.GetSize();
1207435933ddSDimitry Andric   for (size_t i = 0; i < num_watchpoints; ++i) {
1208ac7ddfbfSEd Maste     WatchpointSP wp_sp = m_watchpoint_list.GetByIndex(i);
1209ac7ddfbfSEd Maste     if (!wp_sp)
1210ac7ddfbfSEd Maste       return false;
1211ac7ddfbfSEd Maste 
12125517e702SDimitry Andric     Status rc = m_process_sp->DisableWatchpoint(wp_sp.get());
1213ac7ddfbfSEd Maste     if (rc.Fail())
1214ac7ddfbfSEd Maste       return false;
1215ac7ddfbfSEd Maste   }
1216ac7ddfbfSEd Maste   return true; // Success!
1217ac7ddfbfSEd Maste }
1218ac7ddfbfSEd Maste 
12194ba319b5SDimitry Andric // Assumption: Caller holds the list mutex lock for m_watchpoint_list for end
12204ba319b5SDimitry Andric // to end operations.
EnableAllWatchpoints(bool end_to_end)1221435933ddSDimitry Andric bool Target::EnableAllWatchpoints(bool end_to_end) {
1222ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
1223ac7ddfbfSEd Maste   if (log)
1224ac7ddfbfSEd Maste     log->Printf("Target::%s\n", __FUNCTION__);
1225ac7ddfbfSEd Maste 
1226ac7ddfbfSEd Maste   if (!end_to_end) {
1227ac7ddfbfSEd Maste     m_watchpoint_list.SetEnabledAll(true);
1228ac7ddfbfSEd Maste     return true;
1229ac7ddfbfSEd Maste   }
1230ac7ddfbfSEd Maste 
1231ac7ddfbfSEd Maste   // Otherwise, it's an end to end operation.
1232ac7ddfbfSEd Maste 
1233ac7ddfbfSEd Maste   if (!ProcessIsValid())
1234ac7ddfbfSEd Maste     return false;
1235ac7ddfbfSEd Maste 
1236ac7ddfbfSEd Maste   size_t num_watchpoints = m_watchpoint_list.GetSize();
1237435933ddSDimitry Andric   for (size_t i = 0; i < num_watchpoints; ++i) {
1238ac7ddfbfSEd Maste     WatchpointSP wp_sp = m_watchpoint_list.GetByIndex(i);
1239ac7ddfbfSEd Maste     if (!wp_sp)
1240ac7ddfbfSEd Maste       return false;
1241ac7ddfbfSEd Maste 
12425517e702SDimitry Andric     Status rc = m_process_sp->EnableWatchpoint(wp_sp.get());
1243ac7ddfbfSEd Maste     if (rc.Fail())
1244ac7ddfbfSEd Maste       return false;
1245ac7ddfbfSEd Maste   }
1246ac7ddfbfSEd Maste   return true; // Success!
1247ac7ddfbfSEd Maste }
1248ac7ddfbfSEd Maste 
1249ac7ddfbfSEd Maste // Assumption: Caller holds the list mutex lock for m_watchpoint_list.
ClearAllWatchpointHitCounts()1250435933ddSDimitry Andric bool Target::ClearAllWatchpointHitCounts() {
1251ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
1252ac7ddfbfSEd Maste   if (log)
1253ac7ddfbfSEd Maste     log->Printf("Target::%s\n", __FUNCTION__);
1254ac7ddfbfSEd Maste 
1255ac7ddfbfSEd Maste   size_t num_watchpoints = m_watchpoint_list.GetSize();
1256435933ddSDimitry Andric   for (size_t i = 0; i < num_watchpoints; ++i) {
1257ac7ddfbfSEd Maste     WatchpointSP wp_sp = m_watchpoint_list.GetByIndex(i);
1258ac7ddfbfSEd Maste     if (!wp_sp)
1259ac7ddfbfSEd Maste       return false;
1260ac7ddfbfSEd Maste 
1261ac7ddfbfSEd Maste     wp_sp->ResetHitCount();
1262ac7ddfbfSEd Maste   }
1263ac7ddfbfSEd Maste   return true; // Success!
1264ac7ddfbfSEd Maste }
1265ac7ddfbfSEd Maste 
12661c3bbb01SEd Maste // Assumption: Caller holds the list mutex lock for m_watchpoint_list.
ClearAllWatchpointHistoricValues()1267435933ddSDimitry Andric bool Target::ClearAllWatchpointHistoricValues() {
12681c3bbb01SEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
12691c3bbb01SEd Maste   if (log)
12701c3bbb01SEd Maste     log->Printf("Target::%s\n", __FUNCTION__);
12711c3bbb01SEd Maste 
12721c3bbb01SEd Maste   size_t num_watchpoints = m_watchpoint_list.GetSize();
1273435933ddSDimitry Andric   for (size_t i = 0; i < num_watchpoints; ++i) {
12741c3bbb01SEd Maste     WatchpointSP wp_sp = m_watchpoint_list.GetByIndex(i);
12751c3bbb01SEd Maste     if (!wp_sp)
12761c3bbb01SEd Maste       return false;
12771c3bbb01SEd Maste 
12781c3bbb01SEd Maste     wp_sp->ResetHistoricValues();
12791c3bbb01SEd Maste   }
12801c3bbb01SEd Maste   return true; // Success!
12811c3bbb01SEd Maste }
12821c3bbb01SEd Maste 
12834ba319b5SDimitry Andric // Assumption: Caller holds the list mutex lock for m_watchpoint_list during
12844ba319b5SDimitry Andric // these operations.
IgnoreAllWatchpoints(uint32_t ignore_count)1285435933ddSDimitry Andric bool Target::IgnoreAllWatchpoints(uint32_t ignore_count) {
1286ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
1287ac7ddfbfSEd Maste   if (log)
1288ac7ddfbfSEd Maste     log->Printf("Target::%s\n", __FUNCTION__);
1289ac7ddfbfSEd Maste 
1290ac7ddfbfSEd Maste   if (!ProcessIsValid())
1291ac7ddfbfSEd Maste     return false;
1292ac7ddfbfSEd Maste 
1293ac7ddfbfSEd Maste   size_t num_watchpoints = m_watchpoint_list.GetSize();
1294435933ddSDimitry Andric   for (size_t i = 0; i < num_watchpoints; ++i) {
1295ac7ddfbfSEd Maste     WatchpointSP wp_sp = m_watchpoint_list.GetByIndex(i);
1296ac7ddfbfSEd Maste     if (!wp_sp)
1297ac7ddfbfSEd Maste       return false;
1298ac7ddfbfSEd Maste 
1299ac7ddfbfSEd Maste     wp_sp->SetIgnoreCount(ignore_count);
1300ac7ddfbfSEd Maste   }
1301ac7ddfbfSEd Maste   return true; // Success!
1302ac7ddfbfSEd Maste }
1303ac7ddfbfSEd Maste 
1304ac7ddfbfSEd Maste // Assumption: Caller holds the list mutex lock for m_watchpoint_list.
DisableWatchpointByID(lldb::watch_id_t watch_id)1305435933ddSDimitry Andric bool Target::DisableWatchpointByID(lldb::watch_id_t watch_id) {
1306ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
1307ac7ddfbfSEd Maste   if (log)
1308ac7ddfbfSEd Maste     log->Printf("Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);
1309ac7ddfbfSEd Maste 
1310ac7ddfbfSEd Maste   if (!ProcessIsValid())
1311ac7ddfbfSEd Maste     return false;
1312ac7ddfbfSEd Maste 
1313ac7ddfbfSEd Maste   WatchpointSP wp_sp = m_watchpoint_list.FindByID(watch_id);
1314435933ddSDimitry Andric   if (wp_sp) {
13155517e702SDimitry Andric     Status rc = m_process_sp->DisableWatchpoint(wp_sp.get());
1316ac7ddfbfSEd Maste     if (rc.Success())
1317ac7ddfbfSEd Maste       return true;
1318ac7ddfbfSEd Maste 
1319ac7ddfbfSEd Maste     // Else, fallthrough.
1320ac7ddfbfSEd Maste   }
1321ac7ddfbfSEd Maste   return false;
1322ac7ddfbfSEd Maste }
1323ac7ddfbfSEd Maste 
1324ac7ddfbfSEd Maste // Assumption: Caller holds the list mutex lock for m_watchpoint_list.
EnableWatchpointByID(lldb::watch_id_t watch_id)1325435933ddSDimitry Andric bool Target::EnableWatchpointByID(lldb::watch_id_t watch_id) {
1326ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
1327ac7ddfbfSEd Maste   if (log)
1328ac7ddfbfSEd Maste     log->Printf("Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);
1329ac7ddfbfSEd Maste 
1330ac7ddfbfSEd Maste   if (!ProcessIsValid())
1331ac7ddfbfSEd Maste     return false;
1332ac7ddfbfSEd Maste 
1333ac7ddfbfSEd Maste   WatchpointSP wp_sp = m_watchpoint_list.FindByID(watch_id);
1334435933ddSDimitry Andric   if (wp_sp) {
13355517e702SDimitry Andric     Status rc = m_process_sp->EnableWatchpoint(wp_sp.get());
1336ac7ddfbfSEd Maste     if (rc.Success())
1337ac7ddfbfSEd Maste       return true;
1338ac7ddfbfSEd Maste 
1339ac7ddfbfSEd Maste     // Else, fallthrough.
1340ac7ddfbfSEd Maste   }
1341ac7ddfbfSEd Maste   return false;
1342ac7ddfbfSEd Maste }
1343ac7ddfbfSEd Maste 
1344ac7ddfbfSEd Maste // Assumption: Caller holds the list mutex lock for m_watchpoint_list.
RemoveWatchpointByID(lldb::watch_id_t watch_id)1345435933ddSDimitry Andric bool Target::RemoveWatchpointByID(lldb::watch_id_t watch_id) {
1346ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
1347ac7ddfbfSEd Maste   if (log)
1348ac7ddfbfSEd Maste     log->Printf("Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);
1349ac7ddfbfSEd Maste 
1350ac7ddfbfSEd Maste   WatchpointSP watch_to_remove_sp = m_watchpoint_list.FindByID(watch_id);
1351ac7ddfbfSEd Maste   if (watch_to_remove_sp == m_last_created_watchpoint)
1352ac7ddfbfSEd Maste     m_last_created_watchpoint.reset();
1353ac7ddfbfSEd Maste 
1354435933ddSDimitry Andric   if (DisableWatchpointByID(watch_id)) {
1355ac7ddfbfSEd Maste     m_watchpoint_list.Remove(watch_id, true);
1356ac7ddfbfSEd Maste     return true;
1357ac7ddfbfSEd Maste   }
1358ac7ddfbfSEd Maste   return false;
1359ac7ddfbfSEd Maste }
1360ac7ddfbfSEd Maste 
1361ac7ddfbfSEd Maste // Assumption: Caller holds the list mutex lock for m_watchpoint_list.
IgnoreWatchpointByID(lldb::watch_id_t watch_id,uint32_t ignore_count)1362435933ddSDimitry Andric bool Target::IgnoreWatchpointByID(lldb::watch_id_t watch_id,
1363435933ddSDimitry Andric                                   uint32_t ignore_count) {
1364ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS));
1365ac7ddfbfSEd Maste   if (log)
1366ac7ddfbfSEd Maste     log->Printf("Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);
1367ac7ddfbfSEd Maste 
1368ac7ddfbfSEd Maste   if (!ProcessIsValid())
1369ac7ddfbfSEd Maste     return false;
1370ac7ddfbfSEd Maste 
1371ac7ddfbfSEd Maste   WatchpointSP wp_sp = m_watchpoint_list.FindByID(watch_id);
1372435933ddSDimitry Andric   if (wp_sp) {
1373ac7ddfbfSEd Maste     wp_sp->SetIgnoreCount(ignore_count);
1374ac7ddfbfSEd Maste     return true;
1375ac7ddfbfSEd Maste   }
1376ac7ddfbfSEd Maste   return false;
1377ac7ddfbfSEd Maste }
1378ac7ddfbfSEd Maste 
GetExecutableModule()1379435933ddSDimitry Andric ModuleSP Target::GetExecutableModule() {
13801c3bbb01SEd Maste   // search for the first executable in the module list
1381435933ddSDimitry Andric   for (size_t i = 0; i < m_images.GetSize(); ++i) {
13821c3bbb01SEd Maste     ModuleSP module_sp = m_images.GetModuleAtIndex(i);
13831c3bbb01SEd Maste     lldb_private::ObjectFile *obj = module_sp->GetObjectFile();
13841c3bbb01SEd Maste     if (obj == nullptr)
13851c3bbb01SEd Maste       continue;
13861c3bbb01SEd Maste     if (obj->GetType() == ObjectFile::Type::eTypeExecutable)
13871c3bbb01SEd Maste       return module_sp;
13881c3bbb01SEd Maste   }
13891c3bbb01SEd Maste   // as fall back return the first module loaded
1390ac7ddfbfSEd Maste   return m_images.GetModuleAtIndex(0);
1391ac7ddfbfSEd Maste }
1392ac7ddfbfSEd Maste 
GetExecutableModulePointer()1393435933ddSDimitry Andric Module *Target::GetExecutableModulePointer() {
13941c3bbb01SEd Maste   return GetExecutableModule().get();
1395ac7ddfbfSEd Maste }
1396ac7ddfbfSEd Maste 
LoadScriptingResourceForModule(const ModuleSP & module_sp,Target * target)1397435933ddSDimitry Andric static void LoadScriptingResourceForModule(const ModuleSP &module_sp,
1398435933ddSDimitry Andric                                            Target *target) {
13995517e702SDimitry Andric   Status error;
1400ac7ddfbfSEd Maste   StreamString feedback_stream;
1401435933ddSDimitry Andric   if (module_sp &&
1402435933ddSDimitry Andric       !module_sp->LoadScriptingResourceInTarget(target, error,
1403435933ddSDimitry Andric                                                 &feedback_stream)) {
1404ac7ddfbfSEd Maste     if (error.AsCString())
1405435933ddSDimitry Andric       target->GetDebugger().GetErrorFile()->Printf(
1406435933ddSDimitry Andric           "unable to load scripting data for module %s - error reported was "
1407435933ddSDimitry Andric           "%s\n",
1408ac7ddfbfSEd Maste           module_sp->GetFileSpec().GetFileNameStrippingExtension().GetCString(),
1409ac7ddfbfSEd Maste           error.AsCString());
14100127ef0fSEd Maste   }
1411ac7ddfbfSEd Maste   if (feedback_stream.GetSize())
141212b93ac6SEd Maste     target->GetDebugger().GetErrorFile()->Printf("%s\n",
1413ac7ddfbfSEd Maste                                                  feedback_stream.GetData());
1414ac7ddfbfSEd Maste }
1415ac7ddfbfSEd Maste 
ClearModules(bool delete_locations)1416435933ddSDimitry Andric void Target::ClearModules(bool delete_locations) {
1417b952cd58SEd Maste   ModulesDidUnload(m_images, delete_locations);
141812b93ac6SEd Maste   m_section_load_history.Clear();
1419ac7ddfbfSEd Maste   m_images.Clear();
14209f2f44ceSEd Maste   m_scratch_type_system_map.Clear();
14219f2f44ceSEd Maste   m_ast_importer_sp.reset();
142235617911SEd Maste }
142335617911SEd Maste 
DidExec()1424435933ddSDimitry Andric void Target::DidExec() {
1425b952cd58SEd Maste   // When a process exec's we need to know about it so we can do some cleanup.
1426acac075bSDimitry Andric   m_breakpoint_list.RemoveInvalidLocations(m_arch.GetSpec());
1427acac075bSDimitry Andric   m_internal_breakpoint_list.RemoveInvalidLocations(m_arch.GetSpec());
1428b952cd58SEd Maste }
1429b952cd58SEd Maste 
SetExecutableModule(ModuleSP & executable_sp,LoadDependentFiles load_dependent_files)1430435933ddSDimitry Andric void Target::SetExecutableModule(ModuleSP &executable_sp,
1431*b5893f02SDimitry Andric                                  LoadDependentFiles load_dependent_files) {
143235617911SEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET));
1433b952cd58SEd Maste   ClearModules(false);
1434ac7ddfbfSEd Maste 
1435435933ddSDimitry Andric   if (executable_sp) {
14365517e702SDimitry Andric     static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
14375517e702SDimitry Andric     Timer scoped_timer(func_cat,
1438ac7ddfbfSEd Maste                        "Target::SetExecutableModule (executable = '%s')",
1439ac7ddfbfSEd Maste                        executable_sp->GetFileSpec().GetPath().c_str());
1440ac7ddfbfSEd Maste 
14410127ef0fSEd Maste     m_images.Append(executable_sp); // The first image is our executable file
1442ac7ddfbfSEd Maste 
1443435933ddSDimitry Andric     // If we haven't set an architecture yet, reset our architecture based on
1444435933ddSDimitry Andric     // what we found in the executable module.
1445acac075bSDimitry Andric     if (!m_arch.GetSpec().IsValid()) {
1446ac7ddfbfSEd Maste       m_arch = executable_sp->GetArchitecture();
1447acac075bSDimitry Andric       LLDB_LOG(log,
1448acac075bSDimitry Andric                "setting architecture to {0} ({1}) based on executable file",
1449acac075bSDimitry Andric                m_arch.GetSpec().GetArchitectureName(),
1450acac075bSDimitry Andric                m_arch.GetSpec().GetTriple().getTriple());
1451ac7ddfbfSEd Maste     }
1452ac7ddfbfSEd Maste 
1453ac7ddfbfSEd Maste     FileSpecList dependent_files;
1454ac7ddfbfSEd Maste     ObjectFile *executable_objfile = executable_sp->GetObjectFile();
1455*b5893f02SDimitry Andric     bool load_dependents = true;
1456*b5893f02SDimitry Andric     switch (load_dependent_files) {
1457*b5893f02SDimitry Andric     case eLoadDependentsDefault:
1458*b5893f02SDimitry Andric       load_dependents = executable_sp->IsExecutable();
1459*b5893f02SDimitry Andric       break;
1460*b5893f02SDimitry Andric     case eLoadDependentsYes:
1461*b5893f02SDimitry Andric       load_dependents = true;
1462*b5893f02SDimitry Andric       break;
1463*b5893f02SDimitry Andric     case eLoadDependentsNo:
1464*b5893f02SDimitry Andric       load_dependents = false;
1465*b5893f02SDimitry Andric       break;
1466*b5893f02SDimitry Andric     }
1467ac7ddfbfSEd Maste 
1468*b5893f02SDimitry Andric     if (executable_objfile && load_dependents) {
1469ac7ddfbfSEd Maste       executable_objfile->GetDependentModules(dependent_files);
1470435933ddSDimitry Andric       for (uint32_t i = 0; i < dependent_files.GetSize(); i++) {
1471435933ddSDimitry Andric         FileSpec dependent_file_spec(
1472435933ddSDimitry Andric             dependent_files.GetFileSpecPointerAtIndex(i));
1473ac7ddfbfSEd Maste         FileSpec platform_dependent_file_spec;
1474ac7ddfbfSEd Maste         if (m_platform_sp)
1475435933ddSDimitry Andric           m_platform_sp->GetFileWithUUID(dependent_file_spec, nullptr,
1476435933ddSDimitry Andric                                          platform_dependent_file_spec);
1477ac7ddfbfSEd Maste         else
1478ac7ddfbfSEd Maste           platform_dependent_file_spec = dependent_file_spec;
1479ac7ddfbfSEd Maste 
1480acac075bSDimitry Andric         ModuleSpec module_spec(platform_dependent_file_spec, m_arch.GetSpec());
1481ac7ddfbfSEd Maste         ModuleSP image_module_sp(GetSharedModule(module_spec));
1482435933ddSDimitry Andric         if (image_module_sp) {
1483ac7ddfbfSEd Maste           ObjectFile *objfile = image_module_sp->GetObjectFile();
1484ac7ddfbfSEd Maste           if (objfile)
1485ac7ddfbfSEd Maste             objfile->GetDependentModules(dependent_files);
1486ac7ddfbfSEd Maste         }
1487ac7ddfbfSEd Maste       }
1488ac7ddfbfSEd Maste     }
1489ac7ddfbfSEd Maste   }
1490ac7ddfbfSEd Maste }
1491ac7ddfbfSEd Maste 
SetArchitecture(const ArchSpec & arch_spec,bool set_platform)1492*b5893f02SDimitry Andric bool Target::SetArchitecture(const ArchSpec &arch_spec, bool set_platform) {
1493ac7ddfbfSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET));
1494acac075bSDimitry Andric   bool missing_local_arch = !m_arch.GetSpec().IsValid();
14959f2f44ceSEd Maste   bool replace_local_arch = true;
14969f2f44ceSEd Maste   bool compatible_local_arch = false;
14979f2f44ceSEd Maste   ArchSpec other(arch_spec);
14989f2f44ceSEd Maste 
1499*b5893f02SDimitry Andric   // Changing the architecture might mean that the currently selected platform
1500*b5893f02SDimitry Andric   // isn't compatible. Set the platform correctly if we are asked to do so,
1501*b5893f02SDimitry Andric   // otherwise assume the user will set the platform manually.
1502*b5893f02SDimitry Andric   if (set_platform) {
1503*b5893f02SDimitry Andric     if (other.IsValid()) {
1504*b5893f02SDimitry Andric       auto platform_sp = GetPlatform();
1505*b5893f02SDimitry Andric       if (!platform_sp ||
1506*b5893f02SDimitry Andric           !platform_sp->IsCompatibleArchitecture(other, false, nullptr)) {
1507*b5893f02SDimitry Andric         ArchSpec platform_arch;
1508*b5893f02SDimitry Andric         auto arch_platform_sp =
1509*b5893f02SDimitry Andric             Platform::GetPlatformForArchitecture(other, &platform_arch);
1510*b5893f02SDimitry Andric         if (arch_platform_sp) {
1511*b5893f02SDimitry Andric           SetPlatform(arch_platform_sp);
1512*b5893f02SDimitry Andric           if (platform_arch.IsValid())
1513*b5893f02SDimitry Andric             other = platform_arch;
1514*b5893f02SDimitry Andric         }
1515*b5893f02SDimitry Andric       }
1516*b5893f02SDimitry Andric     }
1517*b5893f02SDimitry Andric   }
1518*b5893f02SDimitry Andric 
1519435933ddSDimitry Andric   if (!missing_local_arch) {
1520acac075bSDimitry Andric     if (m_arch.GetSpec().IsCompatibleMatch(arch_spec)) {
1521acac075bSDimitry Andric       other.MergeFrom(m_arch.GetSpec());
15229f2f44ceSEd Maste 
1523acac075bSDimitry Andric       if (m_arch.GetSpec().IsCompatibleMatch(other)) {
15249f2f44ceSEd Maste         compatible_local_arch = true;
1525435933ddSDimitry Andric         bool arch_changed, vendor_changed, os_changed, os_ver_changed,
1526435933ddSDimitry Andric             env_changed;
15279f2f44ceSEd Maste 
1528acac075bSDimitry Andric         m_arch.GetSpec().PiecewiseTripleCompare(other, arch_changed, vendor_changed,
1529435933ddSDimitry Andric                                       os_changed, os_ver_changed, env_changed);
15309f2f44ceSEd Maste 
15314bb0738eSEd Maste         if (!arch_changed && !vendor_changed && !os_changed && !env_changed)
15329f2f44ceSEd Maste           replace_local_arch = false;
15339f2f44ceSEd Maste       }
15349f2f44ceSEd Maste     }
15359f2f44ceSEd Maste   }
15369f2f44ceSEd Maste 
1537435933ddSDimitry Andric   if (compatible_local_arch || missing_local_arch) {
15389f2f44ceSEd Maste     // If we haven't got a valid arch spec, or the architectures are compatible
15394ba319b5SDimitry Andric     // update the architecture, unless the one we already have is more
15404ba319b5SDimitry Andric     // specified
15419f2f44ceSEd Maste     if (replace_local_arch)
15429f2f44ceSEd Maste       m_arch = other;
1543acac075bSDimitry Andric     LLDB_LOG(log, "set architecture to {0} ({1})",
1544acac075bSDimitry Andric              m_arch.GetSpec().GetArchitectureName(),
1545acac075bSDimitry Andric              m_arch.GetSpec().GetTriple().getTriple());
1546ac7ddfbfSEd Maste     return true;
1547ac7ddfbfSEd Maste   }
15489f2f44ceSEd Maste 
1549435933ddSDimitry Andric   // If we have an executable file, try to reset the executable to the desired
1550435933ddSDimitry Andric   // architecture
1551ac7ddfbfSEd Maste   if (log)
1552435933ddSDimitry Andric     log->Printf("Target::SetArchitecture changing architecture to %s (%s)",
1553435933ddSDimitry Andric                 arch_spec.GetArchitectureName(),
1554435933ddSDimitry Andric                 arch_spec.GetTriple().getTriple().c_str());
15559f2f44ceSEd Maste   m_arch = other;
1556ac7ddfbfSEd Maste   ModuleSP executable_sp = GetExecutableModule();
155735617911SEd Maste 
1558b952cd58SEd Maste   ClearModules(true);
1559ac7ddfbfSEd Maste   // Need to do something about unsetting breakpoints.
1560ac7ddfbfSEd Maste 
1561435933ddSDimitry Andric   if (executable_sp) {
1562ac7ddfbfSEd Maste     if (log)
1563435933ddSDimitry Andric       log->Printf("Target::SetArchitecture Trying to select executable file "
1564435933ddSDimitry Andric                   "architecture %s (%s)",
1565435933ddSDimitry Andric                   arch_spec.GetArchitectureName(),
1566435933ddSDimitry Andric                   arch_spec.GetTriple().getTriple().c_str());
15679f2f44ceSEd Maste     ModuleSpec module_spec(executable_sp->GetFileSpec(), other);
15685517e702SDimitry Andric     Status error = ModuleList::GetSharedModule(module_spec, executable_sp,
1569ac7ddfbfSEd Maste                                                &GetExecutableSearchPaths(),
1570435933ddSDimitry Andric                                                nullptr, nullptr);
1571ac7ddfbfSEd Maste 
1572435933ddSDimitry Andric     if (!error.Fail() && executable_sp) {
1573*b5893f02SDimitry Andric       SetExecutableModule(executable_sp, eLoadDependentsYes);
1574ac7ddfbfSEd Maste       return true;
1575ac7ddfbfSEd Maste     }
1576ac7ddfbfSEd Maste   }
1577ac7ddfbfSEd Maste   return false;
1578ac7ddfbfSEd Maste }
1579ac7ddfbfSEd Maste 
MergeArchitecture(const ArchSpec & arch_spec)1580435933ddSDimitry Andric bool Target::MergeArchitecture(const ArchSpec &arch_spec) {
1581*b5893f02SDimitry Andric   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET));
1582435933ddSDimitry Andric   if (arch_spec.IsValid()) {
1583acac075bSDimitry Andric     if (m_arch.GetSpec().IsCompatibleMatch(arch_spec)) {
15844ba319b5SDimitry Andric       // The current target arch is compatible with "arch_spec", see if we can
15854ba319b5SDimitry Andric       // improve our current architecture using bits from "arch_spec"
15861c3bbb01SEd Maste 
1587*b5893f02SDimitry Andric       if (log)
1588*b5893f02SDimitry Andric         log->Printf("Target::MergeArchitecture target has arch %s, merging with "
1589*b5893f02SDimitry Andric                     "arch %s",
1590*b5893f02SDimitry Andric                     m_arch.GetSpec().GetTriple().getTriple().c_str(),
1591*b5893f02SDimitry Andric                     arch_spec.GetTriple().getTriple().c_str());
1592*b5893f02SDimitry Andric 
15931c3bbb01SEd Maste       // Merge bits from arch_spec into "merged_arch" and set our architecture
1594acac075bSDimitry Andric       ArchSpec merged_arch(m_arch.GetSpec());
15951c3bbb01SEd Maste       merged_arch.MergeFrom(arch_spec);
15961c3bbb01SEd Maste       return SetArchitecture(merged_arch);
1597435933ddSDimitry Andric     } else {
15981c3bbb01SEd Maste       // The new architecture is different, we just need to replace it
15991c3bbb01SEd Maste       return SetArchitecture(arch_spec);
16001c3bbb01SEd Maste     }
16011c3bbb01SEd Maste   }
16021c3bbb01SEd Maste   return false;
16031c3bbb01SEd Maste }
16041c3bbb01SEd Maste 
WillClearList(const ModuleList & module_list)1605435933ddSDimitry Andric void Target::WillClearList(const ModuleList &module_list) {}
1606ac7ddfbfSEd Maste 
ModuleAdded(const ModuleList & module_list,const ModuleSP & module_sp)1607435933ddSDimitry Andric void Target::ModuleAdded(const ModuleList &module_list,
1608435933ddSDimitry Andric                          const ModuleSP &module_sp) {
1609ac7ddfbfSEd Maste   // A module is being added to this target for the first time
1610435933ddSDimitry Andric   if (m_valid) {
1611ac7ddfbfSEd Maste     ModuleList my_module_list;
1612ac7ddfbfSEd Maste     my_module_list.Append(module_sp);
1613ac7ddfbfSEd Maste     LoadScriptingResourceForModule(module_sp, this);
1614ac7ddfbfSEd Maste     ModulesDidLoad(my_module_list);
1615ac7ddfbfSEd Maste   }
16160127ef0fSEd Maste }
1617ac7ddfbfSEd Maste 
ModuleRemoved(const ModuleList & module_list,const ModuleSP & module_sp)1618435933ddSDimitry Andric void Target::ModuleRemoved(const ModuleList &module_list,
1619435933ddSDimitry Andric                            const ModuleSP &module_sp) {
16209f2f44ceSEd Maste   // A module is being removed from this target.
1621435933ddSDimitry Andric   if (m_valid) {
1622ac7ddfbfSEd Maste     ModuleList my_module_list;
1623ac7ddfbfSEd Maste     my_module_list.Append(module_sp);
162435617911SEd Maste     ModulesDidUnload(my_module_list, false);
1625ac7ddfbfSEd Maste   }
16260127ef0fSEd Maste }
1627ac7ddfbfSEd Maste 
ModuleUpdated(const ModuleList & module_list,const ModuleSP & old_module_sp,const ModuleSP & new_module_sp)1628435933ddSDimitry Andric void Target::ModuleUpdated(const ModuleList &module_list,
1629435933ddSDimitry Andric                            const ModuleSP &old_module_sp,
1630435933ddSDimitry Andric                            const ModuleSP &new_module_sp) {
1631ac7ddfbfSEd Maste   // A module is replacing an already added module
1632435933ddSDimitry Andric   if (m_valid) {
1633435933ddSDimitry Andric     m_breakpoint_list.UpdateBreakpointsWhenModuleIsReplaced(old_module_sp,
1634435933ddSDimitry Andric                                                             new_module_sp);
1635435933ddSDimitry Andric     m_internal_breakpoint_list.UpdateBreakpointsWhenModuleIsReplaced(
1636435933ddSDimitry Andric         old_module_sp, new_module_sp);
16379f2f44ceSEd Maste   }
1638ac7ddfbfSEd Maste }
1639ac7ddfbfSEd Maste 
ModulesDidLoad(ModuleList & module_list)1640435933ddSDimitry Andric void Target::ModulesDidLoad(ModuleList &module_list) {
1641435933ddSDimitry Andric   if (m_valid && module_list.GetSize()) {
164235617911SEd Maste     m_breakpoint_list.UpdateBreakpoints(module_list, true, false);
16439f2f44ceSEd Maste     m_internal_breakpoint_list.UpdateBreakpoints(module_list, true, false);
1644435933ddSDimitry Andric     if (m_process_sp) {
16450127ef0fSEd Maste       m_process_sp->ModulesDidLoad(module_list);
164635617911SEd Maste     }
1647435933ddSDimitry Andric     BroadcastEvent(eBroadcastBitModulesLoaded,
1648435933ddSDimitry Andric                    new TargetEventData(this->shared_from_this(), module_list));
1649ac7ddfbfSEd Maste   }
1650ac7ddfbfSEd Maste }
1651ac7ddfbfSEd Maste 
SymbolsDidLoad(ModuleList & module_list)1652435933ddSDimitry Andric void Target::SymbolsDidLoad(ModuleList &module_list) {
1653435933ddSDimitry Andric   if (m_valid && module_list.GetSize()) {
1654435933ddSDimitry Andric     if (m_process_sp) {
1655435933ddSDimitry Andric       LanguageRuntime *runtime =
1656435933ddSDimitry Andric           m_process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
1657435933ddSDimitry Andric       if (runtime) {
1658ac7ddfbfSEd Maste         ObjCLanguageRuntime *objc_runtime = (ObjCLanguageRuntime *)runtime;
1659ac7ddfbfSEd Maste         objc_runtime->SymbolsDidLoad(module_list);
1660ac7ddfbfSEd Maste       }
1661ac7ddfbfSEd Maste     }
1662ac7ddfbfSEd Maste 
166335617911SEd Maste     m_breakpoint_list.UpdateBreakpoints(module_list, true, false);
16649f2f44ceSEd Maste     m_internal_breakpoint_list.UpdateBreakpoints(module_list, true, false);
1665435933ddSDimitry Andric     BroadcastEvent(eBroadcastBitSymbolsLoaded,
1666435933ddSDimitry Andric                    new TargetEventData(this->shared_from_this(), module_list));
1667ac7ddfbfSEd Maste   }
1668ac7ddfbfSEd Maste }
1669ac7ddfbfSEd Maste 
ModulesDidUnload(ModuleList & module_list,bool delete_locations)1670435933ddSDimitry Andric void Target::ModulesDidUnload(ModuleList &module_list, bool delete_locations) {
1671435933ddSDimitry Andric   if (m_valid && module_list.GetSize()) {
16727aa51b79SEd Maste     UnloadModuleSections(module_list);
167335617911SEd Maste     m_breakpoint_list.UpdateBreakpoints(module_list, false, delete_locations);
1674435933ddSDimitry Andric     m_internal_breakpoint_list.UpdateBreakpoints(module_list, false,
1675435933ddSDimitry Andric                                                  delete_locations);
1676435933ddSDimitry Andric     BroadcastEvent(eBroadcastBitModulesUnloaded,
1677435933ddSDimitry Andric                    new TargetEventData(this->shared_from_this(), module_list));
1678ac7ddfbfSEd Maste   }
1679ac7ddfbfSEd Maste }
1680ac7ddfbfSEd Maste 
ModuleIsExcludedForUnconstrainedSearches(const FileSpec & module_file_spec)1681435933ddSDimitry Andric bool Target::ModuleIsExcludedForUnconstrainedSearches(
1682435933ddSDimitry Andric     const FileSpec &module_file_spec) {
1683435933ddSDimitry Andric   if (GetBreakpointsConsultPlatformAvoidList()) {
1684ac7ddfbfSEd Maste     ModuleList matchingModules;
1685ac7ddfbfSEd Maste     ModuleSpec module_spec(module_file_spec);
1686ac7ddfbfSEd Maste     size_t num_modules = GetImages().FindModules(module_spec, matchingModules);
1687ac7ddfbfSEd Maste 
1688435933ddSDimitry Andric     // If there is more than one module for this file spec, only return true if
1689435933ddSDimitry Andric     // ALL the modules are on the
1690ac7ddfbfSEd Maste     // black list.
1691435933ddSDimitry Andric     if (num_modules > 0) {
1692435933ddSDimitry Andric       for (size_t i = 0; i < num_modules; i++) {
1693435933ddSDimitry Andric         if (!ModuleIsExcludedForUnconstrainedSearches(
1694435933ddSDimitry Andric                 matchingModules.GetModuleAtIndex(i)))
1695ac7ddfbfSEd Maste           return false;
1696ac7ddfbfSEd Maste       }
1697ac7ddfbfSEd Maste       return true;
1698ac7ddfbfSEd Maste     }
1699ac7ddfbfSEd Maste   }
1700ac7ddfbfSEd Maste   return false;
1701ac7ddfbfSEd Maste }
1702ac7ddfbfSEd Maste 
ModuleIsExcludedForUnconstrainedSearches(const lldb::ModuleSP & module_sp)1703435933ddSDimitry Andric bool Target::ModuleIsExcludedForUnconstrainedSearches(
1704435933ddSDimitry Andric     const lldb::ModuleSP &module_sp) {
1705435933ddSDimitry Andric   if (GetBreakpointsConsultPlatformAvoidList()) {
1706ac7ddfbfSEd Maste     if (m_platform_sp)
1707435933ddSDimitry Andric       return m_platform_sp->ModuleIsExcludedForUnconstrainedSearches(*this,
1708435933ddSDimitry Andric                                                                      module_sp);
1709ac7ddfbfSEd Maste   }
1710ac7ddfbfSEd Maste   return false;
1711ac7ddfbfSEd Maste }
1712ac7ddfbfSEd Maste 
ReadMemoryFromFileCache(const Address & addr,void * dst,size_t dst_len,Status & error)1713435933ddSDimitry Andric size_t Target::ReadMemoryFromFileCache(const Address &addr, void *dst,
17145517e702SDimitry Andric                                        size_t dst_len, Status &error) {
1715ac7ddfbfSEd Maste   SectionSP section_sp(addr.GetSection());
1716435933ddSDimitry Andric   if (section_sp) {
1717435933ddSDimitry Andric     // If the contents of this section are encrypted, the on-disk file is
1718435933ddSDimitry Andric     // unusable.  Read only from live memory.
1719435933ddSDimitry Andric     if (section_sp->IsEncrypted()) {
1720ac7ddfbfSEd Maste       error.SetErrorString("section is encrypted");
1721ac7ddfbfSEd Maste       return 0;
1722ac7ddfbfSEd Maste     }
1723ac7ddfbfSEd Maste     ModuleSP module_sp(section_sp->GetModule());
1724435933ddSDimitry Andric     if (module_sp) {
1725ac7ddfbfSEd Maste       ObjectFile *objfile = section_sp->GetModule()->GetObjectFile();
1726435933ddSDimitry Andric       if (objfile) {
1727435933ddSDimitry Andric         size_t bytes_read = objfile->ReadSectionData(
1728435933ddSDimitry Andric             section_sp.get(), addr.GetOffset(), dst, dst_len);
1729ac7ddfbfSEd Maste         if (bytes_read > 0)
1730ac7ddfbfSEd Maste           return bytes_read;
1731ac7ddfbfSEd Maste         else
1732435933ddSDimitry Andric           error.SetErrorStringWithFormat("error reading data from section %s",
1733435933ddSDimitry Andric                                          section_sp->GetName().GetCString());
1734435933ddSDimitry Andric       } else
1735ac7ddfbfSEd Maste         error.SetErrorString("address isn't from a object file");
1736435933ddSDimitry Andric     } else
1737ac7ddfbfSEd Maste       error.SetErrorString("address isn't in a module");
1738435933ddSDimitry Andric   } else
1739435933ddSDimitry Andric     error.SetErrorString("address doesn't contain a section that points to a "
1740435933ddSDimitry Andric                          "section in a object file");
1741ac7ddfbfSEd Maste 
1742ac7ddfbfSEd Maste   return 0;
1743ac7ddfbfSEd Maste }
1744ac7ddfbfSEd Maste 
ReadMemory(const Address & addr,bool prefer_file_cache,void * dst,size_t dst_len,Status & error,lldb::addr_t * load_addr_ptr)1745435933ddSDimitry Andric size_t Target::ReadMemory(const Address &addr, bool prefer_file_cache,
17465517e702SDimitry Andric                           void *dst, size_t dst_len, Status &error,
1747435933ddSDimitry Andric                           lldb::addr_t *load_addr_ptr) {
1748ac7ddfbfSEd Maste   error.Clear();
1749ac7ddfbfSEd Maste 
17504ba319b5SDimitry Andric   // if we end up reading this from process memory, we will fill this with the
17514ba319b5SDimitry Andric   // actual load address
1752ac7ddfbfSEd Maste   if (load_addr_ptr)
1753ac7ddfbfSEd Maste     *load_addr_ptr = LLDB_INVALID_ADDRESS;
1754ac7ddfbfSEd Maste 
1755ac7ddfbfSEd Maste   size_t bytes_read = 0;
1756ac7ddfbfSEd Maste 
1757ac7ddfbfSEd Maste   addr_t load_addr = LLDB_INVALID_ADDRESS;
1758ac7ddfbfSEd Maste   addr_t file_addr = LLDB_INVALID_ADDRESS;
1759ac7ddfbfSEd Maste   Address resolved_addr;
1760435933ddSDimitry Andric   if (!addr.IsSectionOffset()) {
176112b93ac6SEd Maste     SectionLoadList &section_load_list = GetSectionLoadList();
1762435933ddSDimitry Andric     if (section_load_list.IsEmpty()) {
17634ba319b5SDimitry Andric       // No sections are loaded, so we must assume we are not running yet and
17644ba319b5SDimitry Andric       // anything we are given is a file address.
1765435933ddSDimitry Andric       file_addr = addr.GetOffset(); // "addr" doesn't have a section, so its
1766435933ddSDimitry Andric                                     // offset is the file address
1767ac7ddfbfSEd Maste       m_images.ResolveFileAddress(file_addr, resolved_addr);
1768435933ddSDimitry Andric     } else {
17694ba319b5SDimitry Andric       // We have at least one section loaded. This can be because we have
17704ba319b5SDimitry Andric       // manually loaded some sections with "target modules load ..." or
17714ba319b5SDimitry Andric       // because we have have a live process that has sections loaded through
17724ba319b5SDimitry Andric       // the dynamic loader
1773435933ddSDimitry Andric       load_addr = addr.GetOffset(); // "addr" doesn't have a section, so its
1774435933ddSDimitry Andric                                     // offset is the load address
177512b93ac6SEd Maste       section_load_list.ResolveLoadAddress(load_addr, resolved_addr);
1776ac7ddfbfSEd Maste     }
1777ac7ddfbfSEd Maste   }
1778ac7ddfbfSEd Maste   if (!resolved_addr.IsValid())
1779ac7ddfbfSEd Maste     resolved_addr = addr;
1780ac7ddfbfSEd Maste 
1781435933ddSDimitry Andric   if (prefer_file_cache) {
1782ac7ddfbfSEd Maste     bytes_read = ReadMemoryFromFileCache(resolved_addr, dst, dst_len, error);
1783ac7ddfbfSEd Maste     if (bytes_read > 0)
1784ac7ddfbfSEd Maste       return bytes_read;
1785ac7ddfbfSEd Maste   }
1786ac7ddfbfSEd Maste 
1787435933ddSDimitry Andric   if (ProcessIsValid()) {
1788ac7ddfbfSEd Maste     if (load_addr == LLDB_INVALID_ADDRESS)
1789ac7ddfbfSEd Maste       load_addr = resolved_addr.GetLoadAddress(this);
1790ac7ddfbfSEd Maste 
1791435933ddSDimitry Andric     if (load_addr == LLDB_INVALID_ADDRESS) {
1792ac7ddfbfSEd Maste       ModuleSP addr_module_sp(resolved_addr.GetModule());
1793ac7ddfbfSEd Maste       if (addr_module_sp && addr_module_sp->GetFileSpec())
1794435933ddSDimitry Andric         error.SetErrorStringWithFormatv(
1795435933ddSDimitry Andric             "{0:F}[{1:x+}] can't be resolved, {0:F} is not currently loaded",
1796435933ddSDimitry Andric             addr_module_sp->GetFileSpec(), resolved_addr.GetFileAddress());
1797ac7ddfbfSEd Maste       else
1798435933ddSDimitry Andric         error.SetErrorStringWithFormat("0x%" PRIx64 " can't be resolved",
1799435933ddSDimitry Andric                                        resolved_addr.GetFileAddress());
1800435933ddSDimitry Andric     } else {
1801ac7ddfbfSEd Maste       bytes_read = m_process_sp->ReadMemory(load_addr, dst, dst_len, error);
1802435933ddSDimitry Andric       if (bytes_read != dst_len) {
1803435933ddSDimitry Andric         if (error.Success()) {
1804ac7ddfbfSEd Maste           if (bytes_read == 0)
1805435933ddSDimitry Andric             error.SetErrorStringWithFormat(
1806435933ddSDimitry Andric                 "read memory from 0x%" PRIx64 " failed", load_addr);
1807ac7ddfbfSEd Maste           else
1808435933ddSDimitry Andric             error.SetErrorStringWithFormat(
1809435933ddSDimitry Andric                 "only %" PRIu64 " of %" PRIu64
1810435933ddSDimitry Andric                 " bytes were read from memory at 0x%" PRIx64,
1811435933ddSDimitry Andric                 (uint64_t)bytes_read, (uint64_t)dst_len, load_addr);
1812ac7ddfbfSEd Maste         }
1813ac7ddfbfSEd Maste       }
1814435933ddSDimitry Andric       if (bytes_read) {
1815ac7ddfbfSEd Maste         if (load_addr_ptr)
1816ac7ddfbfSEd Maste           *load_addr_ptr = load_addr;
1817ac7ddfbfSEd Maste         return bytes_read;
1818ac7ddfbfSEd Maste       }
18194ba319b5SDimitry Andric       // If the address is not section offset we have an address that doesn't
18204ba319b5SDimitry Andric       // resolve to any address in any currently loaded shared libraries and we
18214ba319b5SDimitry Andric       // failed to read memory so there isn't anything more we can do. If it is
18224ba319b5SDimitry Andric       // section offset, we might be able to read cached memory from the object
18234ba319b5SDimitry Andric       // file.
1824ac7ddfbfSEd Maste       if (!resolved_addr.IsSectionOffset())
1825ac7ddfbfSEd Maste         return 0;
1826ac7ddfbfSEd Maste     }
1827ac7ddfbfSEd Maste   }
1828ac7ddfbfSEd Maste 
1829435933ddSDimitry Andric   if (!prefer_file_cache && resolved_addr.IsSectionOffset()) {
18304ba319b5SDimitry Andric     // If we didn't already try and read from the object file cache, then try
18314ba319b5SDimitry Andric     // it after failing to read from the process.
1832ac7ddfbfSEd Maste     return ReadMemoryFromFileCache(resolved_addr, dst, dst_len, error);
1833ac7ddfbfSEd Maste   }
1834ac7ddfbfSEd Maste   return 0;
1835ac7ddfbfSEd Maste }
1836ac7ddfbfSEd Maste 
ReadCStringFromMemory(const Address & addr,std::string & out_str,Status & error)1837435933ddSDimitry Andric size_t Target::ReadCStringFromMemory(const Address &addr, std::string &out_str,
18385517e702SDimitry Andric                                      Status &error) {
1839ac7ddfbfSEd Maste   char buf[256];
1840ac7ddfbfSEd Maste   out_str.clear();
1841ac7ddfbfSEd Maste   addr_t curr_addr = addr.GetLoadAddress(this);
1842ac7ddfbfSEd Maste   Address address(addr);
1843435933ddSDimitry Andric   while (1) {
1844ac7ddfbfSEd Maste     size_t length = ReadCStringFromMemory(address, buf, sizeof(buf), error);
1845ac7ddfbfSEd Maste     if (length == 0)
1846ac7ddfbfSEd Maste       break;
1847ac7ddfbfSEd Maste     out_str.append(buf, length);
18484ba319b5SDimitry Andric     // If we got "length - 1" bytes, we didn't get the whole C string, we need
18494ba319b5SDimitry Andric     // to read some more characters
1850ac7ddfbfSEd Maste     if (length == sizeof(buf) - 1)
1851ac7ddfbfSEd Maste       curr_addr += length;
1852ac7ddfbfSEd Maste     else
1853ac7ddfbfSEd Maste       break;
1854ac7ddfbfSEd Maste     address = Address(curr_addr);
1855ac7ddfbfSEd Maste   }
1856ac7ddfbfSEd Maste   return out_str.size();
1857ac7ddfbfSEd Maste }
1858ac7ddfbfSEd Maste 
ReadCStringFromMemory(const Address & addr,char * dst,size_t dst_max_len,Status & result_error)1859435933ddSDimitry Andric size_t Target::ReadCStringFromMemory(const Address &addr, char *dst,
18605517e702SDimitry Andric                                      size_t dst_max_len, Status &result_error) {
1861ac7ddfbfSEd Maste   size_t total_cstr_len = 0;
1862435933ddSDimitry Andric   if (dst && dst_max_len) {
1863ac7ddfbfSEd Maste     result_error.Clear();
1864ac7ddfbfSEd Maste     // NULL out everything just to be safe
1865ac7ddfbfSEd Maste     memset(dst, 0, dst_max_len);
18665517e702SDimitry Andric     Status error;
1867ac7ddfbfSEd Maste     addr_t curr_addr = addr.GetLoadAddress(this);
1868ac7ddfbfSEd Maste     Address address(addr);
18697aa51b79SEd Maste 
18704ba319b5SDimitry Andric     // We could call m_process_sp->GetMemoryCacheLineSize() but I don't think
18714ba319b5SDimitry Andric     // this really needs to be tied to the memory cache subsystem's cache line
18724ba319b5SDimitry Andric     // size, so leave this as a fixed constant.
1873ac7ddfbfSEd Maste     const size_t cache_line_size = 512;
18747aa51b79SEd Maste 
1875ac7ddfbfSEd Maste     size_t bytes_left = dst_max_len - 1;
1876ac7ddfbfSEd Maste     char *curr_dst = dst;
1877ac7ddfbfSEd Maste 
1878435933ddSDimitry Andric     while (bytes_left > 0) {
1879435933ddSDimitry Andric       addr_t cache_line_bytes_left =
1880435933ddSDimitry Andric           cache_line_size - (curr_addr % cache_line_size);
1881435933ddSDimitry Andric       addr_t bytes_to_read =
1882435933ddSDimitry Andric           std::min<addr_t>(bytes_left, cache_line_bytes_left);
1883435933ddSDimitry Andric       size_t bytes_read =
1884435933ddSDimitry Andric           ReadMemory(address, false, curr_dst, bytes_to_read, error);
1885ac7ddfbfSEd Maste 
1886435933ddSDimitry Andric       if (bytes_read == 0) {
1887ac7ddfbfSEd Maste         result_error = error;
1888ac7ddfbfSEd Maste         dst[total_cstr_len] = '\0';
1889ac7ddfbfSEd Maste         break;
1890ac7ddfbfSEd Maste       }
1891ac7ddfbfSEd Maste       const size_t len = strlen(curr_dst);
1892ac7ddfbfSEd Maste 
1893ac7ddfbfSEd Maste       total_cstr_len += len;
1894ac7ddfbfSEd Maste 
1895ac7ddfbfSEd Maste       if (len < bytes_to_read)
1896ac7ddfbfSEd Maste         break;
1897ac7ddfbfSEd Maste 
1898ac7ddfbfSEd Maste       curr_dst += bytes_read;
1899ac7ddfbfSEd Maste       curr_addr += bytes_read;
1900ac7ddfbfSEd Maste       bytes_left -= bytes_read;
1901ac7ddfbfSEd Maste       address = Address(curr_addr);
1902ac7ddfbfSEd Maste     }
1903435933ddSDimitry Andric   } else {
19049f2f44ceSEd Maste     if (dst == nullptr)
1905ac7ddfbfSEd Maste       result_error.SetErrorString("invalid arguments");
1906ac7ddfbfSEd Maste     else
1907ac7ddfbfSEd Maste       result_error.Clear();
1908ac7ddfbfSEd Maste   }
1909ac7ddfbfSEd Maste   return total_cstr_len;
1910ac7ddfbfSEd Maste }
1911ac7ddfbfSEd Maste 
ReadScalarIntegerFromMemory(const Address & addr,bool prefer_file_cache,uint32_t byte_size,bool is_signed,Scalar & scalar,Status & error)1912435933ddSDimitry Andric size_t Target::ReadScalarIntegerFromMemory(const Address &addr,
1913ac7ddfbfSEd Maste                                            bool prefer_file_cache,
1914435933ddSDimitry Andric                                            uint32_t byte_size, bool is_signed,
19155517e702SDimitry Andric                                            Scalar &scalar, Status &error) {
1916ac7ddfbfSEd Maste   uint64_t uval;
1917ac7ddfbfSEd Maste 
1918435933ddSDimitry Andric   if (byte_size <= sizeof(uval)) {
1919435933ddSDimitry Andric     size_t bytes_read =
1920435933ddSDimitry Andric         ReadMemory(addr, prefer_file_cache, &uval, byte_size, error);
1921435933ddSDimitry Andric     if (bytes_read == byte_size) {
1922acac075bSDimitry Andric       DataExtractor data(&uval, sizeof(uval), m_arch.GetSpec().GetByteOrder(),
1923acac075bSDimitry Andric                          m_arch.GetSpec().GetAddressByteSize());
1924ac7ddfbfSEd Maste       lldb::offset_t offset = 0;
1925ac7ddfbfSEd Maste       if (byte_size <= 4)
1926ac7ddfbfSEd Maste         scalar = data.GetMaxU32(&offset, byte_size);
1927ac7ddfbfSEd Maste       else
1928ac7ddfbfSEd Maste         scalar = data.GetMaxU64(&offset, byte_size);
1929ac7ddfbfSEd Maste 
1930ac7ddfbfSEd Maste       if (is_signed)
1931ac7ddfbfSEd Maste         scalar.SignExtend(byte_size * 8);
1932ac7ddfbfSEd Maste       return bytes_read;
1933ac7ddfbfSEd Maste     }
1934435933ddSDimitry Andric   } else {
1935435933ddSDimitry Andric     error.SetErrorStringWithFormat(
1936435933ddSDimitry Andric         "byte size of %u is too large for integer scalar type", byte_size);
1937ac7ddfbfSEd Maste   }
1938ac7ddfbfSEd Maste   return 0;
1939ac7ddfbfSEd Maste }
1940ac7ddfbfSEd Maste 
ReadUnsignedIntegerFromMemory(const Address & addr,bool prefer_file_cache,size_t integer_byte_size,uint64_t fail_value,Status & error)1941435933ddSDimitry Andric uint64_t Target::ReadUnsignedIntegerFromMemory(const Address &addr,
1942ac7ddfbfSEd Maste                                                bool prefer_file_cache,
1943ac7ddfbfSEd Maste                                                size_t integer_byte_size,
1944ac7ddfbfSEd Maste                                                uint64_t fail_value,
19455517e702SDimitry Andric                                                Status &error) {
1946ac7ddfbfSEd Maste   Scalar scalar;
1947435933ddSDimitry Andric   if (ReadScalarIntegerFromMemory(addr, prefer_file_cache, integer_byte_size,
1948435933ddSDimitry Andric                                   false, scalar, error))
1949ac7ddfbfSEd Maste     return scalar.ULongLong(fail_value);
1950ac7ddfbfSEd Maste   return fail_value;
1951ac7ddfbfSEd Maste }
1952ac7ddfbfSEd Maste 
ReadPointerFromMemory(const Address & addr,bool prefer_file_cache,Status & error,Address & pointer_addr)1953435933ddSDimitry Andric bool Target::ReadPointerFromMemory(const Address &addr, bool prefer_file_cache,
19545517e702SDimitry Andric                                    Status &error, Address &pointer_addr) {
1955ac7ddfbfSEd Maste   Scalar scalar;
1956435933ddSDimitry Andric   if (ReadScalarIntegerFromMemory(addr, prefer_file_cache,
1957acac075bSDimitry Andric                                   m_arch.GetSpec().GetAddressByteSize(), false, scalar,
1958435933ddSDimitry Andric                                   error)) {
1959ac7ddfbfSEd Maste     addr_t pointer_vm_addr = scalar.ULongLong(LLDB_INVALID_ADDRESS);
1960435933ddSDimitry Andric     if (pointer_vm_addr != LLDB_INVALID_ADDRESS) {
196112b93ac6SEd Maste       SectionLoadList &section_load_list = GetSectionLoadList();
1962435933ddSDimitry Andric       if (section_load_list.IsEmpty()) {
19634ba319b5SDimitry Andric         // No sections are loaded, so we must assume we are not running yet and
19644ba319b5SDimitry Andric         // anything we are given is a file address.
1965ac7ddfbfSEd Maste         m_images.ResolveFileAddress(pointer_vm_addr, pointer_addr);
1966435933ddSDimitry Andric       } else {
19674ba319b5SDimitry Andric         // We have at least one section loaded. This can be because we have
19684ba319b5SDimitry Andric         // manually loaded some sections with "target modules load ..." or
19694ba319b5SDimitry Andric         // because we have have a live process that has sections loaded through
19704ba319b5SDimitry Andric         // the dynamic loader
197112b93ac6SEd Maste         section_load_list.ResolveLoadAddress(pointer_vm_addr, pointer_addr);
1972ac7ddfbfSEd Maste       }
19734ba319b5SDimitry Andric       // We weren't able to resolve the pointer value, so just return an
19744ba319b5SDimitry Andric       // address with no section
1975ac7ddfbfSEd Maste       if (!pointer_addr.IsValid())
1976ac7ddfbfSEd Maste         pointer_addr.SetOffset(pointer_vm_addr);
1977ac7ddfbfSEd Maste       return true;
1978ac7ddfbfSEd Maste     }
1979ac7ddfbfSEd Maste   }
1980ac7ddfbfSEd Maste   return false;
1981ac7ddfbfSEd Maste }
1982ac7ddfbfSEd Maste 
GetSharedModule(const ModuleSpec & module_spec,Status * error_ptr)1983435933ddSDimitry Andric ModuleSP Target::GetSharedModule(const ModuleSpec &module_spec,
19845517e702SDimitry Andric                                  Status *error_ptr) {
1985ac7ddfbfSEd Maste   ModuleSP module_sp;
1986ac7ddfbfSEd Maste 
19875517e702SDimitry Andric   Status error;
1988ac7ddfbfSEd Maste 
1989435933ddSDimitry Andric   // First see if we already have this module in our module list.  If we do,
19904ba319b5SDimitry Andric   // then we're done, we don't need to consult the shared modules list.  But
19914ba319b5SDimitry Andric   // only do this if we are passed a UUID.
1992ac7ddfbfSEd Maste 
1993ac7ddfbfSEd Maste   if (module_spec.GetUUID().IsValid())
1994ac7ddfbfSEd Maste     module_sp = m_images.FindFirstModule(module_spec);
1995ac7ddfbfSEd Maste 
1996435933ddSDimitry Andric   if (!module_sp) {
1997435933ddSDimitry Andric     ModuleSP old_module_sp; // This will get filled in if we have a new version
1998435933ddSDimitry Andric                             // of the library
1999ac7ddfbfSEd Maste     bool did_create_module = false;
2000ac7ddfbfSEd Maste 
2001435933ddSDimitry Andric     // If there are image search path entries, try to use them first to acquire
2002435933ddSDimitry Andric     // a suitable image.
2003435933ddSDimitry Andric     if (m_image_search_paths.GetSize()) {
2004ac7ddfbfSEd Maste       ModuleSpec transformed_spec(module_spec);
2005435933ddSDimitry Andric       if (m_image_search_paths.RemapPath(
2006435933ddSDimitry Andric               module_spec.GetFileSpec().GetDirectory(),
2007435933ddSDimitry Andric               transformed_spec.GetFileSpec().GetDirectory())) {
2008435933ddSDimitry Andric         transformed_spec.GetFileSpec().GetFilename() =
2009435933ddSDimitry Andric             module_spec.GetFileSpec().GetFilename();
2010435933ddSDimitry Andric         error = ModuleList::GetSharedModule(transformed_spec, module_sp,
2011ac7ddfbfSEd Maste                                             &GetExecutableSearchPaths(),
2012435933ddSDimitry Andric                                             &old_module_sp, &did_create_module);
2013ac7ddfbfSEd Maste       }
2014ac7ddfbfSEd Maste     }
2015ac7ddfbfSEd Maste 
2016435933ddSDimitry Andric     if (!module_sp) {
2017ac7ddfbfSEd Maste       // If we have a UUID, we can check our global shared module list in case
2018ac7ddfbfSEd Maste       // we already have it. If we don't have a valid UUID, then we can't since
2019ac7ddfbfSEd Maste       // the path in "module_spec" will be a platform path, and we will need to
2020ac7ddfbfSEd Maste       // let the platform find that file. For example, we could be asking for
2021ac7ddfbfSEd Maste       // "/usr/lib/dyld" and if we do not have a UUID, we don't want to pick
2022ac7ddfbfSEd Maste       // the local copy of "/usr/lib/dyld" since our platform could be a remote
2023ac7ddfbfSEd Maste       // platform that has its own "/usr/lib/dyld" in an SDK or in a local file
2024ac7ddfbfSEd Maste       // cache.
2025435933ddSDimitry Andric       if (module_spec.GetUUID().IsValid()) {
2026ac7ddfbfSEd Maste         // We have a UUID, it is OK to check the global module list...
2027435933ddSDimitry Andric         error = ModuleList::GetSharedModule(module_spec, module_sp,
2028ac7ddfbfSEd Maste                                             &GetExecutableSearchPaths(),
2029435933ddSDimitry Andric                                             &old_module_sp, &did_create_module);
2030ac7ddfbfSEd Maste       }
2031ac7ddfbfSEd Maste 
2032435933ddSDimitry Andric       if (!module_sp) {
2033ac7ddfbfSEd Maste         // The platform is responsible for finding and caching an appropriate
2034ac7ddfbfSEd Maste         // module in the shared module cache.
2035435933ddSDimitry Andric         if (m_platform_sp) {
2036435933ddSDimitry Andric           error = m_platform_sp->GetSharedModule(
2037435933ddSDimitry Andric               module_spec, m_process_sp.get(), module_sp,
2038435933ddSDimitry Andric               &GetExecutableSearchPaths(), &old_module_sp, &did_create_module);
2039435933ddSDimitry Andric         } else {
2040ac7ddfbfSEd Maste           error.SetErrorString("no platform is currently set");
2041ac7ddfbfSEd Maste         }
2042ac7ddfbfSEd Maste       }
2043ac7ddfbfSEd Maste     }
2044ac7ddfbfSEd Maste 
2045435933ddSDimitry Andric     // We found a module that wasn't in our target list.  Let's make sure that
20464ba319b5SDimitry Andric     // there wasn't an equivalent module in the list already, and if there was,
20474ba319b5SDimitry Andric     // let's remove it.
2048435933ddSDimitry Andric     if (module_sp) {
2049ac7ddfbfSEd Maste       ObjectFile *objfile = module_sp->GetObjectFile();
2050435933ddSDimitry Andric       if (objfile) {
2051435933ddSDimitry Andric         switch (objfile->GetType()) {
2052435933ddSDimitry Andric         case ObjectFile::eTypeCoreFile: /// A core file that has a checkpoint of
2053435933ddSDimitry Andric                                         /// a program's execution state
2054ac7ddfbfSEd Maste         case ObjectFile::eTypeExecutable:    /// A normal executable
2055435933ddSDimitry Andric         case ObjectFile::eTypeDynamicLinker: /// The platform's dynamic linker
2056435933ddSDimitry Andric                                              /// executable
2057ac7ddfbfSEd Maste         case ObjectFile::eTypeObjectFile:    /// An intermediate object file
2058435933ddSDimitry Andric         case ObjectFile::eTypeSharedLibrary: /// A shared library that can be
2059435933ddSDimitry Andric                                              /// used during execution
2060ac7ddfbfSEd Maste           break;
2061435933ddSDimitry Andric         case ObjectFile::eTypeDebugInfo: /// An object file that contains only
2062435933ddSDimitry Andric                                          /// debug information
2063ac7ddfbfSEd Maste           if (error_ptr)
2064435933ddSDimitry Andric             error_ptr->SetErrorString("debug info files aren't valid target "
2065435933ddSDimitry Andric                                       "modules, please specify an executable");
2066ac7ddfbfSEd Maste           return ModuleSP();
2067435933ddSDimitry Andric         case ObjectFile::eTypeStubLibrary: /// A library that can be linked
2068435933ddSDimitry Andric                                            /// against but not used for
2069435933ddSDimitry Andric                                            /// execution
2070ac7ddfbfSEd Maste           if (error_ptr)
2071435933ddSDimitry Andric             error_ptr->SetErrorString("stub libraries aren't valid target "
2072435933ddSDimitry Andric                                       "modules, please specify an executable");
2073ac7ddfbfSEd Maste           return ModuleSP();
2074ac7ddfbfSEd Maste         default:
2075ac7ddfbfSEd Maste           if (error_ptr)
2076435933ddSDimitry Andric             error_ptr->SetErrorString(
2077435933ddSDimitry Andric                 "unsupported file type, please specify an executable");
2078ac7ddfbfSEd Maste           return ModuleSP();
2079ac7ddfbfSEd Maste         }
2080435933ddSDimitry Andric         // GetSharedModule is not guaranteed to find the old shared module, for
20814ba319b5SDimitry Andric         // instance in the common case where you pass in the UUID, it is only
20824ba319b5SDimitry Andric         // going to find the one module matching the UUID.  In fact, it has no
20834ba319b5SDimitry Andric         // good way to know what the "old module" relevant to this target is,
20844ba319b5SDimitry Andric         // since there might be many copies of a module with this file spec in
20854ba319b5SDimitry Andric         // various running debug sessions, but only one of them will belong to
20864ba319b5SDimitry Andric         // this target. So let's remove the UUID from the module list, and look
20874ba319b5SDimitry Andric         // in the target's module list. Only do this if there is SOMETHING else
20884ba319b5SDimitry Andric         // in the module spec...
2089435933ddSDimitry Andric         if (!old_module_sp) {
2090435933ddSDimitry Andric           if (module_spec.GetUUID().IsValid() &&
2091435933ddSDimitry Andric               !module_spec.GetFileSpec().GetFilename().IsEmpty() &&
2092435933ddSDimitry Andric               !module_spec.GetFileSpec().GetDirectory().IsEmpty()) {
2093ac7ddfbfSEd Maste             ModuleSpec module_spec_copy(module_spec.GetFileSpec());
2094ac7ddfbfSEd Maste             module_spec_copy.GetUUID().Clear();
2095ac7ddfbfSEd Maste 
2096ac7ddfbfSEd Maste             ModuleList found_modules;
2097435933ddSDimitry Andric             size_t num_found =
2098435933ddSDimitry Andric                 m_images.FindModules(module_spec_copy, found_modules);
2099435933ddSDimitry Andric             if (num_found == 1) {
2100ac7ddfbfSEd Maste               old_module_sp = found_modules.GetModuleAtIndex(0);
2101ac7ddfbfSEd Maste             }
2102ac7ddfbfSEd Maste           }
2103ac7ddfbfSEd Maste         }
2104ac7ddfbfSEd Maste 
2105f37b6182SDimitry Andric         // Preload symbols outside of any lock, so hopefully we can do this for
2106f37b6182SDimitry Andric         // each library in parallel.
2107f37b6182SDimitry Andric         if (GetPreloadSymbols())
2108f37b6182SDimitry Andric           module_sp->PreloadSymbols();
2109f37b6182SDimitry Andric 
2110435933ddSDimitry Andric         if (old_module_sp &&
2111435933ddSDimitry Andric             m_images.GetIndexForModule(old_module_sp.get()) !=
2112435933ddSDimitry Andric                 LLDB_INVALID_INDEX32) {
2113ac7ddfbfSEd Maste           m_images.ReplaceModule(old_module_sp, module_sp);
2114ac7ddfbfSEd Maste           Module *old_module_ptr = old_module_sp.get();
2115ac7ddfbfSEd Maste           old_module_sp.reset();
2116ac7ddfbfSEd Maste           ModuleList::RemoveSharedModuleIfOrphaned(old_module_ptr);
2117435933ddSDimitry Andric         } else
2118ac7ddfbfSEd Maste           m_images.Append(module_sp);
2119435933ddSDimitry Andric       } else
21200127ef0fSEd Maste         module_sp.reset();
2121ac7ddfbfSEd Maste     }
2122ac7ddfbfSEd Maste   }
2123ac7ddfbfSEd Maste   if (error_ptr)
2124ac7ddfbfSEd Maste     *error_ptr = error;
2125ac7ddfbfSEd Maste   return module_sp;
2126ac7ddfbfSEd Maste }
2127ac7ddfbfSEd Maste 
CalculateTarget()2128435933ddSDimitry Andric TargetSP Target::CalculateTarget() { return shared_from_this(); }
2129ac7ddfbfSEd Maste 
CalculateProcess()2130435933ddSDimitry Andric ProcessSP Target::CalculateProcess() { return m_process_sp; }
2131ac7ddfbfSEd Maste 
CalculateThread()2132435933ddSDimitry Andric ThreadSP Target::CalculateThread() { return ThreadSP(); }
2133ac7ddfbfSEd Maste 
CalculateStackFrame()2134435933ddSDimitry Andric StackFrameSP Target::CalculateStackFrame() { return StackFrameSP(); }
2135ac7ddfbfSEd Maste 
CalculateExecutionContext(ExecutionContext & exe_ctx)2136435933ddSDimitry Andric void Target::CalculateExecutionContext(ExecutionContext &exe_ctx) {
2137ac7ddfbfSEd Maste   exe_ctx.Clear();
2138ac7ddfbfSEd Maste   exe_ctx.SetTargetPtr(this);
2139ac7ddfbfSEd Maste }
2140ac7ddfbfSEd Maste 
GetImageSearchPathList()2141435933ddSDimitry Andric PathMappingList &Target::GetImageSearchPathList() {
2142ac7ddfbfSEd Maste   return m_image_search_paths;
2143ac7ddfbfSEd Maste }
2144ac7ddfbfSEd Maste 
ImageSearchPathsChanged(const PathMappingList & path_list,void * baton)2145435933ddSDimitry Andric void Target::ImageSearchPathsChanged(const PathMappingList &path_list,
2146435933ddSDimitry Andric                                      void *baton) {
2147ac7ddfbfSEd Maste   Target *target = (Target *)baton;
2148ac7ddfbfSEd Maste   ModuleSP exe_module_sp(target->GetExecutableModule());
2149ac7ddfbfSEd Maste   if (exe_module_sp)
2150*b5893f02SDimitry Andric     target->SetExecutableModule(exe_module_sp, eLoadDependentsYes);
2151ac7ddfbfSEd Maste }
2152ac7ddfbfSEd Maste 
GetScratchTypeSystemForLanguage(Status * error,lldb::LanguageType language,bool create_on_demand)21535517e702SDimitry Andric TypeSystem *Target::GetScratchTypeSystemForLanguage(Status *error,
2154435933ddSDimitry Andric                                                     lldb::LanguageType language,
2155435933ddSDimitry Andric                                                     bool create_on_demand) {
21569f2f44ceSEd Maste   if (!m_valid)
21579f2f44ceSEd Maste     return nullptr;
21589f2f44ceSEd Maste 
2159435933ddSDimitry Andric   if (error) {
21609f2f44ceSEd Maste     error->Clear();
21619f2f44ceSEd Maste   }
21629f2f44ceSEd Maste 
2163435933ddSDimitry Andric   if (language == eLanguageTypeMipsAssembler // GNU AS and LLVM use it for all
2164435933ddSDimitry Andric                                              // assembly code
2165435933ddSDimitry Andric       || language == eLanguageTypeUnknown) {
21669f2f44ceSEd Maste     std::set<lldb::LanguageType> languages_for_types;
21679f2f44ceSEd Maste     std::set<lldb::LanguageType> languages_for_expressions;
21689f2f44ceSEd Maste 
2169435933ddSDimitry Andric     Language::GetLanguagesSupportingTypeSystems(languages_for_types,
2170435933ddSDimitry Andric                                                 languages_for_expressions);
21719f2f44ceSEd Maste 
2172435933ddSDimitry Andric     if (languages_for_expressions.count(eLanguageTypeC)) {
2173435933ddSDimitry Andric       language = eLanguageTypeC; // LLDB's default.  Override by setting the
2174435933ddSDimitry Andric                                  // target language.
2175435933ddSDimitry Andric     } else {
2176435933ddSDimitry Andric       if (languages_for_expressions.empty()) {
21779f2f44ceSEd Maste         return nullptr;
2178435933ddSDimitry Andric       } else {
21799f2f44ceSEd Maste         language = *languages_for_expressions.begin();
21809f2f44ceSEd Maste       }
21819f2f44ceSEd Maste     }
21829f2f44ceSEd Maste   }
21839f2f44ceSEd Maste 
2184435933ddSDimitry Andric   return m_scratch_type_system_map.GetTypeSystemForLanguage(language, this,
2185435933ddSDimitry Andric                                                             create_on_demand);
21869f2f44ceSEd Maste }
21879f2f44ceSEd Maste 
21889f2f44ceSEd Maste PersistentExpressionState *
GetPersistentExpressionStateForLanguage(lldb::LanguageType language)2189435933ddSDimitry Andric Target::GetPersistentExpressionStateForLanguage(lldb::LanguageType language) {
2190435933ddSDimitry Andric   TypeSystem *type_system =
2191435933ddSDimitry Andric       GetScratchTypeSystemForLanguage(nullptr, language, true);
21929f2f44ceSEd Maste 
2193435933ddSDimitry Andric   if (type_system) {
21949f2f44ceSEd Maste     return type_system->GetPersistentExpressionState();
2195435933ddSDimitry Andric   } else {
21969f2f44ceSEd Maste     return nullptr;
21979f2f44ceSEd Maste   }
21989f2f44ceSEd Maste }
21999f2f44ceSEd Maste 
GetUserExpressionForLanguage(llvm::StringRef expr,llvm::StringRef prefix,lldb::LanguageType language,Expression::ResultType desired_type,const EvaluateExpressionOptions & options,Status & error)2200435933ddSDimitry Andric UserExpression *Target::GetUserExpressionForLanguage(
2201435933ddSDimitry Andric     llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language,
22029f2f44ceSEd Maste     Expression::ResultType desired_type,
22035517e702SDimitry Andric     const EvaluateExpressionOptions &options, Status &error) {
22045517e702SDimitry Andric   Status type_system_error;
22059f2f44ceSEd Maste 
2206435933ddSDimitry Andric   TypeSystem *type_system =
2207435933ddSDimitry Andric       GetScratchTypeSystemForLanguage(&type_system_error, language);
22089f2f44ceSEd Maste   UserExpression *user_expr = nullptr;
22099f2f44ceSEd Maste 
2210435933ddSDimitry Andric   if (!type_system) {
2211435933ddSDimitry Andric     error.SetErrorStringWithFormat(
2212435933ddSDimitry Andric         "Could not find type system for language %s: %s",
2213435933ddSDimitry Andric         Language::GetNameForLanguageType(language),
2214435933ddSDimitry Andric         type_system_error.AsCString());
22159f2f44ceSEd Maste     return nullptr;
22169f2f44ceSEd Maste   }
22179f2f44ceSEd Maste 
2218435933ddSDimitry Andric   user_expr = type_system->GetUserExpression(expr, prefix, language,
2219435933ddSDimitry Andric                                              desired_type, options);
22209f2f44ceSEd Maste   if (!user_expr)
2221435933ddSDimitry Andric     error.SetErrorStringWithFormat(
2222435933ddSDimitry Andric         "Could not create an expression for language %s",
2223435933ddSDimitry Andric         Language::GetNameForLanguageType(language));
22249f2f44ceSEd Maste 
22259f2f44ceSEd Maste   return user_expr;
22269f2f44ceSEd Maste }
22279f2f44ceSEd Maste 
GetFunctionCallerForLanguage(lldb::LanguageType language,const CompilerType & return_type,const Address & function_address,const ValueList & arg_value_list,const char * name,Status & error)2228435933ddSDimitry Andric FunctionCaller *Target::GetFunctionCallerForLanguage(
2229435933ddSDimitry Andric     lldb::LanguageType language, const CompilerType &return_type,
2230435933ddSDimitry Andric     const Address &function_address, const ValueList &arg_value_list,
22315517e702SDimitry Andric     const char *name, Status &error) {
22325517e702SDimitry Andric   Status type_system_error;
2233435933ddSDimitry Andric   TypeSystem *type_system =
2234435933ddSDimitry Andric       GetScratchTypeSystemForLanguage(&type_system_error, language);
22359f2f44ceSEd Maste   FunctionCaller *persistent_fn = nullptr;
22369f2f44ceSEd Maste 
2237435933ddSDimitry Andric   if (!type_system) {
2238435933ddSDimitry Andric     error.SetErrorStringWithFormat(
2239435933ddSDimitry Andric         "Could not find type system for language %s: %s",
2240435933ddSDimitry Andric         Language::GetNameForLanguageType(language),
2241435933ddSDimitry Andric         type_system_error.AsCString());
22429f2f44ceSEd Maste     return persistent_fn;
22439f2f44ceSEd Maste   }
22449f2f44ceSEd Maste 
2245435933ddSDimitry Andric   persistent_fn = type_system->GetFunctionCaller(return_type, function_address,
2246435933ddSDimitry Andric                                                  arg_value_list, name);
22479f2f44ceSEd Maste   if (!persistent_fn)
2248435933ddSDimitry Andric     error.SetErrorStringWithFormat(
2249435933ddSDimitry Andric         "Could not create an expression for language %s",
2250435933ddSDimitry Andric         Language::GetNameForLanguageType(language));
22519f2f44ceSEd Maste 
22529f2f44ceSEd Maste   return persistent_fn;
22539f2f44ceSEd Maste }
22549f2f44ceSEd Maste 
22559f2f44ceSEd Maste UtilityFunction *
GetUtilityFunctionForLanguage(const char * text,lldb::LanguageType language,const char * name,Status & error)22569f2f44ceSEd Maste Target::GetUtilityFunctionForLanguage(const char *text,
22579f2f44ceSEd Maste                                       lldb::LanguageType language,
22585517e702SDimitry Andric                                       const char *name, Status &error) {
22595517e702SDimitry Andric   Status type_system_error;
2260435933ddSDimitry Andric   TypeSystem *type_system =
2261435933ddSDimitry Andric       GetScratchTypeSystemForLanguage(&type_system_error, language);
22629f2f44ceSEd Maste   UtilityFunction *utility_fn = nullptr;
22639f2f44ceSEd Maste 
2264435933ddSDimitry Andric   if (!type_system) {
2265435933ddSDimitry Andric     error.SetErrorStringWithFormat(
2266435933ddSDimitry Andric         "Could not find type system for language %s: %s",
2267435933ddSDimitry Andric         Language::GetNameForLanguageType(language),
2268435933ddSDimitry Andric         type_system_error.AsCString());
22699f2f44ceSEd Maste     return utility_fn;
22709f2f44ceSEd Maste   }
22719f2f44ceSEd Maste 
22729f2f44ceSEd Maste   utility_fn = type_system->GetUtilityFunction(text, name);
22739f2f44ceSEd Maste   if (!utility_fn)
2274435933ddSDimitry Andric     error.SetErrorStringWithFormat(
2275435933ddSDimitry Andric         "Could not create an expression for language %s",
2276435933ddSDimitry Andric         Language::GetNameForLanguageType(language));
22779f2f44ceSEd Maste 
22789f2f44ceSEd Maste   return utility_fn;
22799f2f44ceSEd Maste }
22809f2f44ceSEd Maste 
GetScratchClangASTContext(bool create_on_demand)2281435933ddSDimitry Andric ClangASTContext *Target::GetScratchClangASTContext(bool create_on_demand) {
2282435933ddSDimitry Andric   if (m_valid) {
2283435933ddSDimitry Andric     if (TypeSystem *type_system = GetScratchTypeSystemForLanguage(
2284435933ddSDimitry Andric             nullptr, eLanguageTypeC, create_on_demand))
22859f2f44ceSEd Maste       return llvm::dyn_cast<ClangASTContext>(type_system);
2286ac7ddfbfSEd Maste   }
22879f2f44ceSEd Maste   return nullptr;
2288ac7ddfbfSEd Maste }
2289ac7ddfbfSEd Maste 
GetClangASTImporter()2290435933ddSDimitry Andric ClangASTImporterSP Target::GetClangASTImporter() {
2291435933ddSDimitry Andric   if (m_valid) {
2292435933ddSDimitry Andric     if (!m_ast_importer_sp) {
22939f2f44ceSEd Maste       m_ast_importer_sp.reset(new ClangASTImporter());
2294ac7ddfbfSEd Maste     }
22959f2f44ceSEd Maste     return m_ast_importer_sp;
22969f2f44ceSEd Maste   }
22979f2f44ceSEd Maste   return ClangASTImporterSP();
2298ac7ddfbfSEd Maste }
2299ac7ddfbfSEd Maste 
SettingsInitialize()2300435933ddSDimitry Andric void Target::SettingsInitialize() { Process::SettingsInitialize(); }
2301ac7ddfbfSEd Maste 
SettingsTerminate()2302435933ddSDimitry Andric void Target::SettingsTerminate() { Process::SettingsTerminate(); }
2303ac7ddfbfSEd Maste 
GetDefaultExecutableSearchPaths()2304435933ddSDimitry Andric FileSpecList Target::GetDefaultExecutableSearchPaths() {
2305ac7ddfbfSEd Maste   TargetPropertiesSP properties_sp(Target::GetGlobalProperties());
2306ac7ddfbfSEd Maste   if (properties_sp)
2307ac7ddfbfSEd Maste     return properties_sp->GetExecutableSearchPaths();
2308ac7ddfbfSEd Maste   return FileSpecList();
2309ac7ddfbfSEd Maste }
2310ac7ddfbfSEd Maste 
GetDefaultDebugFileSearchPaths()2311435933ddSDimitry Andric FileSpecList Target::GetDefaultDebugFileSearchPaths() {
2312ac7ddfbfSEd Maste   TargetPropertiesSP properties_sp(Target::GetGlobalProperties());
2313ac7ddfbfSEd Maste   if (properties_sp)
2314ac7ddfbfSEd Maste     return properties_sp->GetDebugFileSearchPaths();
2315ac7ddfbfSEd Maste   return FileSpecList();
2316ac7ddfbfSEd Maste }
2317ac7ddfbfSEd Maste 
GetDefaultClangModuleSearchPaths()2318435933ddSDimitry Andric FileSpecList Target::GetDefaultClangModuleSearchPaths() {
23191c3bbb01SEd Maste   TargetPropertiesSP properties_sp(Target::GetGlobalProperties());
23201c3bbb01SEd Maste   if (properties_sp)
23211c3bbb01SEd Maste     return properties_sp->GetClangModuleSearchPaths();
23221c3bbb01SEd Maste   return FileSpecList();
23231c3bbb01SEd Maste }
23241c3bbb01SEd Maste 
GetDefaultArchitecture()2325435933ddSDimitry Andric ArchSpec Target::GetDefaultArchitecture() {
2326ac7ddfbfSEd Maste   TargetPropertiesSP properties_sp(Target::GetGlobalProperties());
2327ac7ddfbfSEd Maste   if (properties_sp)
2328ac7ddfbfSEd Maste     return properties_sp->GetDefaultArchitecture();
2329ac7ddfbfSEd Maste   return ArchSpec();
2330ac7ddfbfSEd Maste }
2331ac7ddfbfSEd Maste 
SetDefaultArchitecture(const ArchSpec & arch)2332435933ddSDimitry Andric void Target::SetDefaultArchitecture(const ArchSpec &arch) {
2333ac7ddfbfSEd Maste   TargetPropertiesSP properties_sp(Target::GetGlobalProperties());
2334435933ddSDimitry Andric   if (properties_sp) {
2335435933ddSDimitry Andric     LogIfAnyCategoriesSet(
2336435933ddSDimitry Andric         LIBLLDB_LOG_TARGET, "Target::SetDefaultArchitecture setting target's "
2337435933ddSDimitry Andric                             "default architecture to  %s (%s)",
2338435933ddSDimitry Andric         arch.GetArchitectureName(), arch.GetTriple().getTriple().c_str());
2339ac7ddfbfSEd Maste     return properties_sp->SetDefaultArchitecture(arch);
2340ac7ddfbfSEd Maste   }
2341ac7ddfbfSEd Maste }
2342ac7ddfbfSEd Maste 
GetTargetFromContexts(const ExecutionContext * exe_ctx_ptr,const SymbolContext * sc_ptr)2343435933ddSDimitry Andric Target *Target::GetTargetFromContexts(const ExecutionContext *exe_ctx_ptr,
2344435933ddSDimitry Andric                                       const SymbolContext *sc_ptr) {
2345ac7ddfbfSEd Maste   // The target can either exist in the "process" of ExecutionContext, or in
2346ac7ddfbfSEd Maste   // the "target_sp" member of SymbolContext. This accessor helper function
2347ac7ddfbfSEd Maste   // will get the target from one of these locations.
2348ac7ddfbfSEd Maste 
23499f2f44ceSEd Maste   Target *target = nullptr;
23509f2f44ceSEd Maste   if (sc_ptr != nullptr)
2351ac7ddfbfSEd Maste     target = sc_ptr->target_sp.get();
23529f2f44ceSEd Maste   if (target == nullptr && exe_ctx_ptr)
2353ac7ddfbfSEd Maste     target = exe_ctx_ptr->GetTargetPtr();
2354ac7ddfbfSEd Maste   return target;
2355ac7ddfbfSEd Maste }
2356ac7ddfbfSEd Maste 
EvaluateExpression(llvm::StringRef expr,ExecutionContextScope * exe_scope,lldb::ValueObjectSP & result_valobj_sp,const EvaluateExpressionOptions & options,std::string * fixed_expression)2357435933ddSDimitry Andric ExpressionResults Target::EvaluateExpression(
2358435933ddSDimitry Andric     llvm::StringRef expr, ExecutionContextScope *exe_scope,
2359ac7ddfbfSEd Maste     lldb::ValueObjectSP &result_valobj_sp,
2360435933ddSDimitry Andric     const EvaluateExpressionOptions &options, std::string *fixed_expression) {
2361ac7ddfbfSEd Maste   result_valobj_sp.reset();
2362ac7ddfbfSEd Maste 
23630127ef0fSEd Maste   ExpressionResults execution_results = eExpressionSetupError;
2364ac7ddfbfSEd Maste 
2365435933ddSDimitry Andric   if (expr.empty())
2366ac7ddfbfSEd Maste     return execution_results;
2367ac7ddfbfSEd Maste 
23684ba319b5SDimitry Andric   // We shouldn't run stop hooks in expressions. Be sure to reset this if you
23694ba319b5SDimitry Andric   // return anywhere within this function.
2370ac7ddfbfSEd Maste   bool old_suppress_value = m_suppress_stop_hooks;
2371ac7ddfbfSEd Maste   m_suppress_stop_hooks = true;
2372ac7ddfbfSEd Maste 
2373ac7ddfbfSEd Maste   ExecutionContext exe_ctx;
2374ac7ddfbfSEd Maste 
2375435933ddSDimitry Andric   if (exe_scope) {
23769f2f44ceSEd Maste     exe_scope->CalculateExecutionContext(exe_ctx);
2377435933ddSDimitry Andric   } else if (m_process_sp) {
2378ac7ddfbfSEd Maste     m_process_sp->CalculateExecutionContext(exe_ctx);
2379435933ddSDimitry Andric   } else {
2380ac7ddfbfSEd Maste     CalculateExecutionContext(exe_ctx);
2381ac7ddfbfSEd Maste   }
2382ac7ddfbfSEd Maste 
23834ba319b5SDimitry Andric   // Make sure we aren't just trying to see the value of a persistent variable
23844ba319b5SDimitry Andric   // (something like "$0")
23859f2f44ceSEd Maste   lldb::ExpressionVariableSP persistent_var_sp;
2386ac7ddfbfSEd Maste   // Only check for persistent variables the expression starts with a '$'
2387435933ddSDimitry Andric   if (expr[0] == '$')
2388435933ddSDimitry Andric     persistent_var_sp = GetScratchTypeSystemForLanguage(nullptr, eLanguageTypeC)
2389435933ddSDimitry Andric                             ->GetPersistentExpressionState()
2390435933ddSDimitry Andric                             ->GetVariable(expr);
2391ac7ddfbfSEd Maste 
2392435933ddSDimitry Andric   if (persistent_var_sp) {
2393ac7ddfbfSEd Maste     result_valobj_sp = persistent_var_sp->GetValueObject();
23940127ef0fSEd Maste     execution_results = eExpressionCompleted;
2395435933ddSDimitry Andric   } else {
239638638513SDimitry Andric     llvm::StringRef prefix = GetExpressionPrefixContents();
23975517e702SDimitry Andric     Status error;
2398435933ddSDimitry Andric     execution_results = UserExpression::Evaluate(exe_ctx, options, expr, prefix,
2399435933ddSDimitry Andric                                                  result_valobj_sp, error,
24004bb0738eSEd Maste                                                  0, // Line Number
24014bb0738eSEd Maste                                                  fixed_expression);
2402ac7ddfbfSEd Maste   }
2403ac7ddfbfSEd Maste 
2404ac7ddfbfSEd Maste   m_suppress_stop_hooks = old_suppress_value;
2405ac7ddfbfSEd Maste 
2406ac7ddfbfSEd Maste   return execution_results;
2407ac7ddfbfSEd Maste }
2408ac7ddfbfSEd Maste 
24099f2f44ceSEd Maste lldb::ExpressionVariableSP
GetPersistentVariable(const ConstString & name)2410435933ddSDimitry Andric Target::GetPersistentVariable(const ConstString &name) {
24119f2f44ceSEd Maste   lldb::ExpressionVariableSP variable_sp;
2412435933ddSDimitry Andric   m_scratch_type_system_map.ForEach(
2413f678e45dSDimitry Andric       [name, &variable_sp](TypeSystem *type_system) -> bool {
2414435933ddSDimitry Andric         if (PersistentExpressionState *persistent_state =
2415435933ddSDimitry Andric                 type_system->GetPersistentExpressionState()) {
24169f2f44ceSEd Maste           variable_sp = persistent_state->GetVariable(name);
24179f2f44ceSEd Maste 
24189f2f44ceSEd Maste           if (variable_sp)
24199f2f44ceSEd Maste             return false; // Stop iterating the ForEach
24209f2f44ceSEd Maste         }
24219f2f44ceSEd Maste         return true; // Keep iterating the ForEach
24229f2f44ceSEd Maste       });
24239f2f44ceSEd Maste   return variable_sp;
24249f2f44ceSEd Maste }
24259f2f44ceSEd Maste 
GetPersistentSymbol(const ConstString & name)2426435933ddSDimitry Andric lldb::addr_t Target::GetPersistentSymbol(const ConstString &name) {
24279f2f44ceSEd Maste   lldb::addr_t address = LLDB_INVALID_ADDRESS;
24289f2f44ceSEd Maste 
2429435933ddSDimitry Andric   m_scratch_type_system_map.ForEach(
2430f678e45dSDimitry Andric       [name, &address](TypeSystem *type_system) -> bool {
2431435933ddSDimitry Andric         if (PersistentExpressionState *persistent_state =
2432435933ddSDimitry Andric                 type_system->GetPersistentExpressionState()) {
24339f2f44ceSEd Maste           address = persistent_state->LookupSymbol(name);
24349f2f44ceSEd Maste           if (address != LLDB_INVALID_ADDRESS)
24359f2f44ceSEd Maste             return false; // Stop iterating the ForEach
24369f2f44ceSEd Maste         }
24379f2f44ceSEd Maste         return true; // Keep iterating the ForEach
24389f2f44ceSEd Maste       });
24399f2f44ceSEd Maste   return address;
24401c3bbb01SEd Maste }
24411c3bbb01SEd Maste 
GetCallableLoadAddress(lldb::addr_t load_addr,AddressClass addr_class) const2442435933ddSDimitry Andric lldb::addr_t Target::GetCallableLoadAddress(lldb::addr_t load_addr,
2443435933ddSDimitry Andric                                             AddressClass addr_class) const {
2444*b5893f02SDimitry Andric   auto arch_plugin = GetArchitecturePlugin();
2445*b5893f02SDimitry Andric   return arch_plugin ?
2446*b5893f02SDimitry Andric       arch_plugin->GetCallableLoadAddress(load_addr, addr_class) : load_addr;
2447ac7ddfbfSEd Maste }
2448ac7ddfbfSEd Maste 
GetOpcodeLoadAddress(lldb::addr_t load_addr,AddressClass addr_class) const2449435933ddSDimitry Andric lldb::addr_t Target::GetOpcodeLoadAddress(lldb::addr_t load_addr,
2450435933ddSDimitry Andric                                           AddressClass addr_class) const {
2451*b5893f02SDimitry Andric   auto arch_plugin = GetArchitecturePlugin();
2452*b5893f02SDimitry Andric   return arch_plugin ?
2453*b5893f02SDimitry Andric       arch_plugin->GetOpcodeLoadAddress(load_addr, addr_class) : load_addr;
2454ac7ddfbfSEd Maste }
2455ac7ddfbfSEd Maste 
GetBreakableLoadAddress(lldb::addr_t addr)2456435933ddSDimitry Andric lldb::addr_t Target::GetBreakableLoadAddress(lldb::addr_t addr) {
2457*b5893f02SDimitry Andric   auto arch_plugin = GetArchitecturePlugin();
2458*b5893f02SDimitry Andric   return arch_plugin ?
2459*b5893f02SDimitry Andric       arch_plugin->GetBreakableLoadAddress(addr, *this) : addr;
24609f2f44ceSEd Maste }
24619f2f44ceSEd Maste 
GetSourceManager()2462435933ddSDimitry Andric SourceManager &Target::GetSourceManager() {
24639f2f44ceSEd Maste   if (!m_source_manager_ap)
2464ac7ddfbfSEd Maste     m_source_manager_ap.reset(new SourceManager(shared_from_this()));
2465ac7ddfbfSEd Maste   return *m_source_manager_ap;
2466ac7ddfbfSEd Maste }
2467ac7ddfbfSEd Maste 
GetClangModulesDeclVendor()2468435933ddSDimitry Andric ClangModulesDeclVendor *Target::GetClangModulesDeclVendor() {
2469435933ddSDimitry Andric   static std::mutex s_clang_modules_decl_vendor_mutex; // If this is contended
2470435933ddSDimitry Andric                                                        // we can make it
2471435933ddSDimitry Andric                                                        // per-target
24727aa51b79SEd Maste 
24737aa51b79SEd Maste   {
24744bb0738eSEd Maste     std::lock_guard<std::mutex> guard(s_clang_modules_decl_vendor_mutex);
24757aa51b79SEd Maste 
2476435933ddSDimitry Andric     if (!m_clang_modules_decl_vendor_ap) {
2477435933ddSDimitry Andric       m_clang_modules_decl_vendor_ap.reset(
2478435933ddSDimitry Andric           ClangModulesDeclVendor::Create(*this));
24797aa51b79SEd Maste     }
24807aa51b79SEd Maste   }
24817aa51b79SEd Maste 
24827aa51b79SEd Maste   return m_clang_modules_decl_vendor_ap.get();
24837aa51b79SEd Maste }
2484ac7ddfbfSEd Maste 
CreateStopHook()2485435933ddSDimitry Andric Target::StopHookSP Target::CreateStopHook() {
2486ac7ddfbfSEd Maste   lldb::user_id_t new_uid = ++m_stop_hook_next_id;
248712b93ac6SEd Maste   Target::StopHookSP stop_hook_sp(new StopHook(shared_from_this(), new_uid));
248812b93ac6SEd Maste   m_stop_hooks[new_uid] = stop_hook_sp;
248912b93ac6SEd Maste   return stop_hook_sp;
2490ac7ddfbfSEd Maste }
2491ac7ddfbfSEd Maste 
RemoveStopHookByID(lldb::user_id_t user_id)2492435933ddSDimitry Andric bool Target::RemoveStopHookByID(lldb::user_id_t user_id) {
24939f2f44ceSEd Maste   size_t num_removed = m_stop_hooks.erase(user_id);
24949f2f44ceSEd Maste   return (num_removed != 0);
2495ac7ddfbfSEd Maste }
2496ac7ddfbfSEd Maste 
RemoveAllStopHooks()2497435933ddSDimitry Andric void Target::RemoveAllStopHooks() { m_stop_hooks.clear(); }
2498ac7ddfbfSEd Maste 
GetStopHookByID(lldb::user_id_t user_id)2499435933ddSDimitry Andric Target::StopHookSP Target::GetStopHookByID(lldb::user_id_t user_id) {
2500ac7ddfbfSEd Maste   StopHookSP found_hook;
2501ac7ddfbfSEd Maste 
2502ac7ddfbfSEd Maste   StopHookCollection::iterator specified_hook_iter;
2503ac7ddfbfSEd Maste   specified_hook_iter = m_stop_hooks.find(user_id);
2504ac7ddfbfSEd Maste   if (specified_hook_iter != m_stop_hooks.end())
2505ac7ddfbfSEd Maste     found_hook = (*specified_hook_iter).second;
2506ac7ddfbfSEd Maste   return found_hook;
2507ac7ddfbfSEd Maste }
2508ac7ddfbfSEd Maste 
SetStopHookActiveStateByID(lldb::user_id_t user_id,bool active_state)2509435933ddSDimitry Andric bool Target::SetStopHookActiveStateByID(lldb::user_id_t user_id,
2510435933ddSDimitry Andric                                         bool active_state) {
2511ac7ddfbfSEd Maste   StopHookCollection::iterator specified_hook_iter;
2512ac7ddfbfSEd Maste   specified_hook_iter = m_stop_hooks.find(user_id);
2513ac7ddfbfSEd Maste   if (specified_hook_iter == m_stop_hooks.end())
2514ac7ddfbfSEd Maste     return false;
2515ac7ddfbfSEd Maste 
2516ac7ddfbfSEd Maste   (*specified_hook_iter).second->SetIsActive(active_state);
2517ac7ddfbfSEd Maste   return true;
2518ac7ddfbfSEd Maste }
2519ac7ddfbfSEd Maste 
SetAllStopHooksActiveState(bool active_state)2520435933ddSDimitry Andric void Target::SetAllStopHooksActiveState(bool active_state) {
2521ac7ddfbfSEd Maste   StopHookCollection::iterator pos, end = m_stop_hooks.end();
2522435933ddSDimitry Andric   for (pos = m_stop_hooks.begin(); pos != end; pos++) {
2523ac7ddfbfSEd Maste     (*pos).second->SetIsActive(active_state);
2524ac7ddfbfSEd Maste   }
2525ac7ddfbfSEd Maste }
2526ac7ddfbfSEd Maste 
RunStopHooks()2527435933ddSDimitry Andric void Target::RunStopHooks() {
2528ac7ddfbfSEd Maste   if (m_suppress_stop_hooks)
2529ac7ddfbfSEd Maste     return;
2530ac7ddfbfSEd Maste 
2531ac7ddfbfSEd Maste   if (!m_process_sp)
2532ac7ddfbfSEd Maste     return;
2533ac7ddfbfSEd Maste 
2534acac075bSDimitry Andric   // Somebody might have restarted the process:
2535acac075bSDimitry Andric   if (m_process_sp->GetState() != eStateStopped)
2536acac075bSDimitry Andric     return;
2537acac075bSDimitry Andric 
2538435933ddSDimitry Andric   // <rdar://problem/12027563> make sure we check that we are not stopped
25394ba319b5SDimitry Andric   // because of us running a user expression since in that case we do not want
25404ba319b5SDimitry Andric   // to run the stop-hooks
2541ac7ddfbfSEd Maste   if (m_process_sp->GetModIDRef().IsLastResumeForUserExpression())
2542ac7ddfbfSEd Maste     return;
2543ac7ddfbfSEd Maste 
2544ac7ddfbfSEd Maste   if (m_stop_hooks.empty())
2545ac7ddfbfSEd Maste     return;
2546ac7ddfbfSEd Maste 
2547ac7ddfbfSEd Maste   StopHookCollection::iterator pos, end = m_stop_hooks.end();
2548ac7ddfbfSEd Maste 
2549ac7ddfbfSEd Maste   // If there aren't any active stop hooks, don't bother either:
2550ac7ddfbfSEd Maste   bool any_active_hooks = false;
2551435933ddSDimitry Andric   for (pos = m_stop_hooks.begin(); pos != end; pos++) {
2552435933ddSDimitry Andric     if ((*pos).second->IsActive()) {
2553ac7ddfbfSEd Maste       any_active_hooks = true;
2554ac7ddfbfSEd Maste       break;
2555ac7ddfbfSEd Maste     }
2556ac7ddfbfSEd Maste   }
2557ac7ddfbfSEd Maste   if (!any_active_hooks)
2558ac7ddfbfSEd Maste     return;
2559ac7ddfbfSEd Maste 
2560ac7ddfbfSEd Maste   CommandReturnObject result;
2561ac7ddfbfSEd Maste 
2562ac7ddfbfSEd Maste   std::vector<ExecutionContext> exc_ctx_with_reasons;
2563ac7ddfbfSEd Maste   std::vector<SymbolContext> sym_ctx_with_reasons;
2564ac7ddfbfSEd Maste 
2565ac7ddfbfSEd Maste   ThreadList &cur_threadlist = m_process_sp->GetThreadList();
2566ac7ddfbfSEd Maste   size_t num_threads = cur_threadlist.GetSize();
2567435933ddSDimitry Andric   for (size_t i = 0; i < num_threads; i++) {
2568ac7ddfbfSEd Maste     lldb::ThreadSP cur_thread_sp = cur_threadlist.GetThreadAtIndex(i);
2569435933ddSDimitry Andric     if (cur_thread_sp->ThreadStoppedForAReason()) {
2570ac7ddfbfSEd Maste       lldb::StackFrameSP cur_frame_sp = cur_thread_sp->GetStackFrameAtIndex(0);
2571435933ddSDimitry Andric       exc_ctx_with_reasons.push_back(ExecutionContext(
2572435933ddSDimitry Andric           m_process_sp.get(), cur_thread_sp.get(), cur_frame_sp.get()));
2573435933ddSDimitry Andric       sym_ctx_with_reasons.push_back(
2574435933ddSDimitry Andric           cur_frame_sp->GetSymbolContext(eSymbolContextEverything));
2575ac7ddfbfSEd Maste     }
2576ac7ddfbfSEd Maste   }
2577ac7ddfbfSEd Maste 
2578ac7ddfbfSEd Maste   // If no threads stopped for a reason, don't run the stop-hooks.
2579ac7ddfbfSEd Maste   size_t num_exe_ctx = exc_ctx_with_reasons.size();
2580ac7ddfbfSEd Maste   if (num_exe_ctx == 0)
2581ac7ddfbfSEd Maste     return;
2582ac7ddfbfSEd Maste 
2583ac7ddfbfSEd Maste   result.SetImmediateOutputStream(m_debugger.GetAsyncOutputStream());
2584ac7ddfbfSEd Maste   result.SetImmediateErrorStream(m_debugger.GetAsyncErrorStream());
2585ac7ddfbfSEd Maste 
2586ac7ddfbfSEd Maste   bool keep_going = true;
2587ac7ddfbfSEd Maste   bool hooks_ran = false;
25889f2f44ceSEd Maste   bool print_hook_header = (m_stop_hooks.size() != 1);
25899f2f44ceSEd Maste   bool print_thread_header = (num_exe_ctx != 1);
2590ac7ddfbfSEd Maste 
2591435933ddSDimitry Andric   for (pos = m_stop_hooks.begin(); keep_going && pos != end; pos++) {
2592ac7ddfbfSEd Maste     // result.Clear();
2593ac7ddfbfSEd Maste     StopHookSP cur_hook_sp = (*pos).second;
2594ac7ddfbfSEd Maste     if (!cur_hook_sp->IsActive())
2595ac7ddfbfSEd Maste       continue;
2596ac7ddfbfSEd Maste 
2597ac7ddfbfSEd Maste     bool any_thread_matched = false;
2598435933ddSDimitry Andric     for (size_t i = 0; keep_going && i < num_exe_ctx; i++) {
2599435933ddSDimitry Andric       if ((cur_hook_sp->GetSpecifier() == nullptr ||
2600435933ddSDimitry Andric            cur_hook_sp->GetSpecifier()->SymbolContextMatches(
2601435933ddSDimitry Andric                sym_ctx_with_reasons[i])) &&
2602435933ddSDimitry Andric           (cur_hook_sp->GetThreadSpecifier() == nullptr ||
2603435933ddSDimitry Andric            cur_hook_sp->GetThreadSpecifier()->ThreadPassesBasicTests(
2604435933ddSDimitry Andric                exc_ctx_with_reasons[i].GetThreadRef()))) {
2605435933ddSDimitry Andric         if (!hooks_ran) {
2606ac7ddfbfSEd Maste           hooks_ran = true;
2607ac7ddfbfSEd Maste         }
2608435933ddSDimitry Andric         if (print_hook_header && !any_thread_matched) {
2609435933ddSDimitry Andric           const char *cmd =
2610435933ddSDimitry Andric               (cur_hook_sp->GetCommands().GetSize() == 1
2611435933ddSDimitry Andric                    ? cur_hook_sp->GetCommands().GetStringAtIndex(0)
2612435933ddSDimitry Andric                    : nullptr);
2613ac7ddfbfSEd Maste           if (cmd)
2614435933ddSDimitry Andric             result.AppendMessageWithFormat("\n- Hook %" PRIu64 " (%s)\n",
2615435933ddSDimitry Andric                                            cur_hook_sp->GetID(), cmd);
2616ac7ddfbfSEd Maste           else
2617435933ddSDimitry Andric             result.AppendMessageWithFormat("\n- Hook %" PRIu64 "\n",
2618435933ddSDimitry Andric                                            cur_hook_sp->GetID());
2619ac7ddfbfSEd Maste           any_thread_matched = true;
2620ac7ddfbfSEd Maste         }
2621ac7ddfbfSEd Maste 
2622ac7ddfbfSEd Maste         if (print_thread_header)
2623435933ddSDimitry Andric           result.AppendMessageWithFormat(
2624435933ddSDimitry Andric               "-- Thread %d\n",
2625435933ddSDimitry Andric               exc_ctx_with_reasons[i].GetThreadPtr()->GetIndexID());
2626ac7ddfbfSEd Maste 
26277aa51b79SEd Maste         CommandInterpreterRunOptions options;
26287aa51b79SEd Maste         options.SetStopOnContinue(true);
26297aa51b79SEd Maste         options.SetStopOnError(true);
26307aa51b79SEd Maste         options.SetEchoCommands(false);
26317aa51b79SEd Maste         options.SetPrintResults(true);
26327aa51b79SEd Maste         options.SetAddToHistory(false);
26337aa51b79SEd Maste 
2634435933ddSDimitry Andric         GetDebugger().GetCommandInterpreter().HandleCommands(
2635435933ddSDimitry Andric             cur_hook_sp->GetCommands(), &exc_ctx_with_reasons[i], options,
2636ac7ddfbfSEd Maste             result);
2637ac7ddfbfSEd Maste 
2638ac7ddfbfSEd Maste         // If the command started the target going again, we should bag out of
2639ac7ddfbfSEd Maste         // running the stop hooks.
2640ac7ddfbfSEd Maste         if ((result.GetStatus() == eReturnStatusSuccessContinuingNoResult) ||
2641435933ddSDimitry Andric             (result.GetStatus() == eReturnStatusSuccessContinuingResult)) {
2642acac075bSDimitry Andric           // But only complain if there were more stop hooks to do:
2643acac075bSDimitry Andric           StopHookCollection::iterator tmp = pos;
2644acac075bSDimitry Andric           if (++tmp != end)
2645acac075bSDimitry Andric             result.AppendMessageWithFormat("\nAborting stop hooks, hook %" PRIu64
2646acac075bSDimitry Andric                                            " set the program running.\n",
2647435933ddSDimitry Andric                                            cur_hook_sp->GetID());
2648ac7ddfbfSEd Maste           keep_going = false;
2649ac7ddfbfSEd Maste         }
2650ac7ddfbfSEd Maste       }
2651ac7ddfbfSEd Maste     }
2652ac7ddfbfSEd Maste   }
2653ac7ddfbfSEd Maste 
2654ac7ddfbfSEd Maste   result.GetImmediateOutputStream()->Flush();
2655ac7ddfbfSEd Maste   result.GetImmediateErrorStream()->Flush();
2656ac7ddfbfSEd Maste }
2657ac7ddfbfSEd Maste 
GetGlobalProperties()2658435933ddSDimitry Andric const TargetPropertiesSP &Target::GetGlobalProperties() {
26594bb0738eSEd Maste   // NOTE: intentional leak so we don't crash if global destructor chain gets
26604bb0738eSEd Maste   // called as other threads still use the result of this function
2661435933ddSDimitry Andric   static TargetPropertiesSP *g_settings_sp_ptr =
2662435933ddSDimitry Andric       new TargetPropertiesSP(new TargetProperties(nullptr));
26634bb0738eSEd Maste   return *g_settings_sp_ptr;
2664b952cd58SEd Maste }
2665b952cd58SEd Maste 
Install(ProcessLaunchInfo * launch_info)26665517e702SDimitry Andric Status Target::Install(ProcessLaunchInfo *launch_info) {
26675517e702SDimitry Andric   Status error;
2668b952cd58SEd Maste   PlatformSP platform_sp(GetPlatform());
2669435933ddSDimitry Andric   if (platform_sp) {
2670435933ddSDimitry Andric     if (platform_sp->IsRemote()) {
2671435933ddSDimitry Andric       if (platform_sp->IsConnected()) {
2672b952cd58SEd Maste         // Install all files that have an install path, and always install the
2673b952cd58SEd Maste         // main executable when connected to a remote platform
2674b952cd58SEd Maste         const ModuleList &modules = GetImages();
2675b952cd58SEd Maste         const size_t num_images = modules.GetSize();
2676435933ddSDimitry Andric         for (size_t idx = 0; idx < num_images; ++idx) {
2677b952cd58SEd Maste           ModuleSP module_sp(modules.GetModuleAtIndex(idx));
2678435933ddSDimitry Andric           if (module_sp) {
26794bb0738eSEd Maste             const bool is_main_executable = module_sp == GetExecutableModule();
2680b952cd58SEd Maste             FileSpec local_file(module_sp->GetFileSpec());
2681435933ddSDimitry Andric             if (local_file) {
2682b952cd58SEd Maste               FileSpec remote_file(module_sp->GetRemoteInstallFileSpec());
2683435933ddSDimitry Andric               if (!remote_file) {
2684435933ddSDimitry Andric                 if (is_main_executable) // TODO: add setting for always
2685435933ddSDimitry Andric                                         // installing main executable???
2686b952cd58SEd Maste                 {
2687b952cd58SEd Maste                   // Always install the main executable
26881c3bbb01SEd Maste                   remote_file = platform_sp->GetRemoteWorkingDirectory();
2689435933ddSDimitry Andric                   remote_file.AppendPathComponent(
2690435933ddSDimitry Andric                       module_sp->GetFileSpec().GetFilename().GetCString());
2691b952cd58SEd Maste                 }
2692b952cd58SEd Maste               }
2693435933ddSDimitry Andric               if (remote_file) {
2694b952cd58SEd Maste                 error = platform_sp->Install(local_file, remote_file);
2695435933ddSDimitry Andric                 if (error.Success()) {
2696b952cd58SEd Maste                   module_sp->SetPlatformFileSpec(remote_file);
2697435933ddSDimitry Andric                   if (is_main_executable) {
26981c3bbb01SEd Maste                     platform_sp->SetFilePermissions(remote_file, 0700);
2699b952cd58SEd Maste                     if (launch_info)
2700b952cd58SEd Maste                       launch_info->SetExecutableFile(remote_file, false);
2701b952cd58SEd Maste                   }
2702435933ddSDimitry Andric                 } else
2703b952cd58SEd Maste                   break;
2704b952cd58SEd Maste               }
2705b952cd58SEd Maste             }
2706b952cd58SEd Maste           }
2707b952cd58SEd Maste         }
2708b952cd58SEd Maste       }
2709b952cd58SEd Maste     }
2710b952cd58SEd Maste   }
2711b952cd58SEd Maste   return error;
2712b952cd58SEd Maste }
2713ac7ddfbfSEd Maste 
ResolveLoadAddress(addr_t load_addr,Address & so_addr,uint32_t stop_id)2714435933ddSDimitry Andric bool Target::ResolveLoadAddress(addr_t load_addr, Address &so_addr,
2715435933ddSDimitry Andric                                 uint32_t stop_id) {
271612b93ac6SEd Maste   return m_section_load_history.ResolveLoadAddress(stop_id, load_addr, so_addr);
271712b93ac6SEd Maste }
271812b93ac6SEd Maste 
ResolveFileAddress(lldb::addr_t file_addr,Address & resolved_addr)2719435933ddSDimitry Andric bool Target::ResolveFileAddress(lldb::addr_t file_addr,
2720435933ddSDimitry Andric                                 Address &resolved_addr) {
27217aa51b79SEd Maste   return m_images.ResolveFileAddress(file_addr, resolved_addr);
27227aa51b79SEd Maste }
27237aa51b79SEd Maste 
SetSectionLoadAddress(const SectionSP & section_sp,addr_t new_section_load_addr,bool warn_multiple)2724435933ddSDimitry Andric bool Target::SetSectionLoadAddress(const SectionSP &section_sp,
2725435933ddSDimitry Andric                                    addr_t new_section_load_addr,
2726435933ddSDimitry Andric                                    bool warn_multiple) {
2727435933ddSDimitry Andric   const addr_t old_section_load_addr =
2728435933ddSDimitry Andric       m_section_load_history.GetSectionLoadAddress(
2729435933ddSDimitry Andric           SectionLoadHistory::eStopIDNow, section_sp);
2730435933ddSDimitry Andric   if (old_section_load_addr != new_section_load_addr) {
273112b93ac6SEd Maste     uint32_t stop_id = 0;
273212b93ac6SEd Maste     ProcessSP process_sp(GetProcessSP());
273312b93ac6SEd Maste     if (process_sp)
273412b93ac6SEd Maste       stop_id = process_sp->GetStopID();
273512b93ac6SEd Maste     else
273612b93ac6SEd Maste       stop_id = m_section_load_history.GetLastStopID();
2737435933ddSDimitry Andric     if (m_section_load_history.SetSectionLoadAddress(
2738435933ddSDimitry Andric             stop_id, section_sp, new_section_load_addr, warn_multiple))
273912b93ac6SEd Maste       return true; // Return true if the section load address was changed...
274012b93ac6SEd Maste   }
274112b93ac6SEd Maste   return false; // Return false to indicate nothing changed
274212b93ac6SEd Maste }
274312b93ac6SEd Maste 
UnloadModuleSections(const ModuleList & module_list)2744435933ddSDimitry Andric size_t Target::UnloadModuleSections(const ModuleList &module_list) {
27457aa51b79SEd Maste   size_t section_unload_count = 0;
27467aa51b79SEd Maste   size_t num_modules = module_list.GetSize();
2747435933ddSDimitry Andric   for (size_t i = 0; i < num_modules; ++i) {
2748435933ddSDimitry Andric     section_unload_count +=
2749435933ddSDimitry Andric         UnloadModuleSections(module_list.GetModuleAtIndex(i));
27507aa51b79SEd Maste   }
27517aa51b79SEd Maste   return section_unload_count;
27527aa51b79SEd Maste }
27537aa51b79SEd Maste 
UnloadModuleSections(const lldb::ModuleSP & module_sp)2754435933ddSDimitry Andric size_t Target::UnloadModuleSections(const lldb::ModuleSP &module_sp) {
27557aa51b79SEd Maste   uint32_t stop_id = 0;
27567aa51b79SEd Maste   ProcessSP process_sp(GetProcessSP());
27577aa51b79SEd Maste   if (process_sp)
27587aa51b79SEd Maste     stop_id = process_sp->GetStopID();
27597aa51b79SEd Maste   else
27607aa51b79SEd Maste     stop_id = m_section_load_history.GetLastStopID();
27617aa51b79SEd Maste   SectionList *sections = module_sp->GetSectionList();
27627aa51b79SEd Maste   size_t section_unload_count = 0;
2763435933ddSDimitry Andric   if (sections) {
27647aa51b79SEd Maste     const uint32_t num_sections = sections->GetNumSections(0);
2765435933ddSDimitry Andric     for (uint32_t i = 0; i < num_sections; ++i) {
2766435933ddSDimitry Andric       section_unload_count += m_section_load_history.SetSectionUnloaded(
2767435933ddSDimitry Andric           stop_id, sections->GetSectionAtIndex(i));
27687aa51b79SEd Maste     }
27697aa51b79SEd Maste   }
27707aa51b79SEd Maste   return section_unload_count;
27717aa51b79SEd Maste }
27727aa51b79SEd Maste 
SetSectionUnloaded(const lldb::SectionSP & section_sp)2773435933ddSDimitry Andric bool Target::SetSectionUnloaded(const lldb::SectionSP &section_sp) {
277412b93ac6SEd Maste   uint32_t stop_id = 0;
277512b93ac6SEd Maste   ProcessSP process_sp(GetProcessSP());
277612b93ac6SEd Maste   if (process_sp)
277712b93ac6SEd Maste     stop_id = process_sp->GetStopID();
277812b93ac6SEd Maste   else
277912b93ac6SEd Maste     stop_id = m_section_load_history.GetLastStopID();
278012b93ac6SEd Maste   return m_section_load_history.SetSectionUnloaded(stop_id, section_sp);
278112b93ac6SEd Maste }
278212b93ac6SEd Maste 
SetSectionUnloaded(const lldb::SectionSP & section_sp,addr_t load_addr)2783435933ddSDimitry Andric bool Target::SetSectionUnloaded(const lldb::SectionSP &section_sp,
2784435933ddSDimitry Andric                                 addr_t load_addr) {
278512b93ac6SEd Maste   uint32_t stop_id = 0;
278612b93ac6SEd Maste   ProcessSP process_sp(GetProcessSP());
278712b93ac6SEd Maste   if (process_sp)
278812b93ac6SEd Maste     stop_id = process_sp->GetStopID();
278912b93ac6SEd Maste   else
279012b93ac6SEd Maste     stop_id = m_section_load_history.GetLastStopID();
2791435933ddSDimitry Andric   return m_section_load_history.SetSectionUnloaded(stop_id, section_sp,
2792435933ddSDimitry Andric                                                    load_addr);
279312b93ac6SEd Maste }
279412b93ac6SEd Maste 
ClearAllLoadedSections()2795435933ddSDimitry Andric void Target::ClearAllLoadedSections() { m_section_load_history.Clear(); }
279612b93ac6SEd Maste 
Launch(ProcessLaunchInfo & launch_info,Stream * stream)27975517e702SDimitry Andric Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) {
27985517e702SDimitry Andric   Status error;
27997aa51b79SEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET));
28007aa51b79SEd Maste 
28017aa51b79SEd Maste   if (log)
2802435933ddSDimitry Andric     log->Printf("Target::%s() called for %s", __FUNCTION__,
2803435933ddSDimitry Andric                 launch_info.GetExecutableFile().GetPath().c_str());
280412b93ac6SEd Maste 
280512b93ac6SEd Maste   StateType state = eStateInvalid;
280612b93ac6SEd Maste 
280712b93ac6SEd Maste   // Scope to temporarily get the process state in case someone has manually
280812b93ac6SEd Maste   // remotely connected already to a process and we can skip the platform
280912b93ac6SEd Maste   // launching.
281012b93ac6SEd Maste   {
281112b93ac6SEd Maste     ProcessSP process_sp(GetProcessSP());
281212b93ac6SEd Maste 
2813435933ddSDimitry Andric     if (process_sp) {
281412b93ac6SEd Maste       state = process_sp->GetState();
28157aa51b79SEd Maste       if (log)
2816435933ddSDimitry Andric         log->Printf(
2817435933ddSDimitry Andric             "Target::%s the process exists, and its current state is %s",
2818435933ddSDimitry Andric             __FUNCTION__, StateAsCString(state));
2819435933ddSDimitry Andric     } else {
28207aa51b79SEd Maste       if (log)
2821435933ddSDimitry Andric         log->Printf("Target::%s the process instance doesn't currently exist.",
2822435933ddSDimitry Andric                     __FUNCTION__);
28237aa51b79SEd Maste     }
282412b93ac6SEd Maste   }
282512b93ac6SEd Maste 
282612b93ac6SEd Maste   launch_info.GetFlags().Set(eLaunchFlagDebug);
282712b93ac6SEd Maste 
2828435933ddSDimitry Andric   // Get the value of synchronous execution here.  If you wait till after you
28294ba319b5SDimitry Andric   // have started to run, then you could have hit a breakpoint, whose command
28304ba319b5SDimitry Andric   // might switch the value, and then you'll pick up that incorrect value.
283112b93ac6SEd Maste   Debugger &debugger = GetDebugger();
2832435933ddSDimitry Andric   const bool synchronous_execution =
2833435933ddSDimitry Andric       debugger.GetCommandInterpreter().GetSynchronous();
283412b93ac6SEd Maste 
283512b93ac6SEd Maste   PlatformSP platform_sp(GetPlatform());
283612b93ac6SEd Maste 
2837*b5893f02SDimitry Andric   FinalizeFileActions(launch_info);
283812b93ac6SEd Maste 
2839435933ddSDimitry Andric   if (state == eStateConnected) {
2840435933ddSDimitry Andric     if (launch_info.GetFlags().Test(eLaunchFlagLaunchInTTY)) {
2841435933ddSDimitry Andric       error.SetErrorString(
2842435933ddSDimitry Andric           "can't launch in tty when launching through a remote connection");
284312b93ac6SEd Maste       return error;
284412b93ac6SEd Maste     }
284512b93ac6SEd Maste   }
284612b93ac6SEd Maste 
284712b93ac6SEd Maste   if (!launch_info.GetArchitecture().IsValid())
284812b93ac6SEd Maste     launch_info.GetArchitecture() = GetArchitecture();
284912b93ac6SEd Maste 
2850435933ddSDimitry Andric   // If we're not already connected to the process, and if we have a platform
2851435933ddSDimitry Andric   // that can launch a process for debugging, go ahead and do that here.
2852435933ddSDimitry Andric   if (state != eStateConnected && platform_sp &&
2853435933ddSDimitry Andric       platform_sp->CanDebugProcess()) {
28547aa51b79SEd Maste     if (log)
2855435933ddSDimitry Andric       log->Printf("Target::%s asking the platform to debug the process",
2856435933ddSDimitry Andric                   __FUNCTION__);
28577aa51b79SEd Maste 
2858*b5893f02SDimitry Andric     // If there was a previous process, delete it before we make the new one.
2859*b5893f02SDimitry Andric     // One subtle point, we delete the process before we release the reference
2860*b5893f02SDimitry Andric     // to m_process_sp.  That way even if we are the last owner, the process
2861*b5893f02SDimitry Andric     // will get Finalized before it gets destroyed.
2862*b5893f02SDimitry Andric     DeleteCurrentProcess();
2863*b5893f02SDimitry Andric 
2864435933ddSDimitry Andric     m_process_sp =
2865435933ddSDimitry Andric         GetPlatform()->DebugProcess(launch_info, debugger, this, error);
28661c3bbb01SEd Maste 
2867435933ddSDimitry Andric   } else {
28687aa51b79SEd Maste     if (log)
2869435933ddSDimitry Andric       log->Printf("Target::%s the platform doesn't know how to debug a "
2870435933ddSDimitry Andric                   "process, getting a process plugin to do this for us.",
2871435933ddSDimitry Andric                   __FUNCTION__);
28727aa51b79SEd Maste 
2873435933ddSDimitry Andric     if (state == eStateConnected) {
287412b93ac6SEd Maste       assert(m_process_sp);
2875435933ddSDimitry Andric     } else {
28760127ef0fSEd Maste       // Use a Process plugin to construct the process.
287712b93ac6SEd Maste       const char *plugin_name = launch_info.GetProcessPluginName();
2878*b5893f02SDimitry Andric       CreateProcess(launch_info.GetListener(), plugin_name, nullptr);
287912b93ac6SEd Maste     }
288012b93ac6SEd Maste 
28810127ef0fSEd Maste     // Since we didn't have a platform launch the process, launch it here.
288212b93ac6SEd Maste     if (m_process_sp)
288312b93ac6SEd Maste       error = m_process_sp->Launch(launch_info);
288412b93ac6SEd Maste   }
288512b93ac6SEd Maste 
2886435933ddSDimitry Andric   if (!m_process_sp) {
288712b93ac6SEd Maste     if (error.Success())
288812b93ac6SEd Maste       error.SetErrorString("failed to launch or debug process");
288912b93ac6SEd Maste     return error;
289012b93ac6SEd Maste   }
289112b93ac6SEd Maste 
2892435933ddSDimitry Andric   if (error.Success()) {
2893435933ddSDimitry Andric     if (synchronous_execution ||
2894435933ddSDimitry Andric         !launch_info.GetFlags().Test(eLaunchFlagStopAtEntry)) {
289512b93ac6SEd Maste       ListenerSP hijack_listener_sp(launch_info.GetHijackListener());
2896435933ddSDimitry Andric       if (!hijack_listener_sp) {
2897435933ddSDimitry Andric         hijack_listener_sp =
2898435933ddSDimitry Andric             Listener::MakeListener("lldb.Target.Launch.hijack");
28991c3bbb01SEd Maste         launch_info.SetHijackListener(hijack_listener_sp);
29004bb0738eSEd Maste         m_process_sp->HijackProcessEvents(hijack_listener_sp);
29011c3bbb01SEd Maste       }
290212b93ac6SEd Maste 
2903435933ddSDimitry Andric       StateType state = m_process_sp->WaitForProcessToStop(
2904435933ddSDimitry Andric           llvm::None, nullptr, false, hijack_listener_sp, nullptr);
290512b93ac6SEd Maste 
2906435933ddSDimitry Andric       if (state == eStateStopped) {
2907435933ddSDimitry Andric         if (!launch_info.GetFlags().Test(eLaunchFlagStopAtEntry)) {
2908435933ddSDimitry Andric           if (synchronous_execution) {
29091c3bbb01SEd Maste             error = m_process_sp->PrivateResume();
2910435933ddSDimitry Andric             if (error.Success()) {
2911435933ddSDimitry Andric               state = m_process_sp->WaitForProcessToStop(
2912435933ddSDimitry Andric                   llvm::None, nullptr, true, hijack_listener_sp, stream);
2913435933ddSDimitry Andric               const bool must_be_alive =
2914435933ddSDimitry Andric                   false; // eStateExited is ok, so this must be false
2915435933ddSDimitry Andric               if (!StateIsStoppedState(state, must_be_alive)) {
2916435933ddSDimitry Andric                 error.SetErrorStringWithFormat("process isn't stopped: %s",
2917435933ddSDimitry Andric                                                StateAsCString(state));
291812b93ac6SEd Maste               }
291912b93ac6SEd Maste             }
2920435933ddSDimitry Andric           } else {
29211c3bbb01SEd Maste             m_process_sp->RestoreProcessEvents();
29221c3bbb01SEd Maste             error = m_process_sp->PrivateResume();
29231c3bbb01SEd Maste           }
2924435933ddSDimitry Andric           if (!error.Success()) {
29255517e702SDimitry Andric             Status error2;
2926435933ddSDimitry Andric             error2.SetErrorStringWithFormat(
2927435933ddSDimitry Andric                 "process resume at entry point failed: %s", error.AsCString());
292812b93ac6SEd Maste             error = error2;
292912b93ac6SEd Maste           }
293012b93ac6SEd Maste         }
2931435933ddSDimitry Andric       } else if (state == eStateExited) {
29327aa51b79SEd Maste         bool with_shell = !!launch_info.GetShell();
29330127ef0fSEd Maste         const int exit_status = m_process_sp->GetExitStatus();
29340127ef0fSEd Maste         const char *exit_desc = m_process_sp->GetExitDescription();
2935435933ddSDimitry Andric #define LAUNCH_SHELL_MESSAGE                                                   \
2936435933ddSDimitry Andric   "\n'r' and 'run' are aliases that default to launching through a "           \
2937435933ddSDimitry Andric   "shell.\nTry launching without going through a shell by using 'process "     \
2938435933ddSDimitry Andric   "launch'."
2939435933ddSDimitry Andric         if (exit_desc && exit_desc[0]) {
29400127ef0fSEd Maste           if (with_shell)
2941435933ddSDimitry Andric             error.SetErrorStringWithFormat(
2942435933ddSDimitry Andric                 "process exited with status %i (%s)" LAUNCH_SHELL_MESSAGE,
2943435933ddSDimitry Andric                 exit_status, exit_desc);
29440127ef0fSEd Maste           else
2945435933ddSDimitry Andric             error.SetErrorStringWithFormat("process exited with status %i (%s)",
2946435933ddSDimitry Andric                                            exit_status, exit_desc);
2947435933ddSDimitry Andric         } else {
29480127ef0fSEd Maste           if (with_shell)
2949435933ddSDimitry Andric             error.SetErrorStringWithFormat(
2950435933ddSDimitry Andric                 "process exited with status %i" LAUNCH_SHELL_MESSAGE,
2951435933ddSDimitry Andric                 exit_status);
29520127ef0fSEd Maste           else
2953435933ddSDimitry Andric             error.SetErrorStringWithFormat("process exited with status %i",
2954435933ddSDimitry Andric                                            exit_status);
29550127ef0fSEd Maste         }
2956435933ddSDimitry Andric       } else {
2957435933ddSDimitry Andric         error.SetErrorStringWithFormat(
2958435933ddSDimitry Andric             "initial process state wasn't stopped: %s", StateAsCString(state));
295912b93ac6SEd Maste       }
296012b93ac6SEd Maste     }
296112b93ac6SEd Maste     m_process_sp->RestoreProcessEvents();
2962435933ddSDimitry Andric   } else {
29635517e702SDimitry Andric     Status error2;
2964435933ddSDimitry Andric     error2.SetErrorStringWithFormat("process launch failed: %s",
2965435933ddSDimitry Andric                                     error.AsCString());
296612b93ac6SEd Maste     error = error2;
296712b93ac6SEd Maste   }
296812b93ac6SEd Maste   return error;
296912b93ac6SEd Maste }
29701c3bbb01SEd Maste 
Attach(ProcessAttachInfo & attach_info,Stream * stream)29715517e702SDimitry Andric Status Target::Attach(ProcessAttachInfo &attach_info, Stream *stream) {
29721c3bbb01SEd Maste   auto state = eStateInvalid;
29731c3bbb01SEd Maste   auto process_sp = GetProcessSP();
2974435933ddSDimitry Andric   if (process_sp) {
29751c3bbb01SEd Maste     state = process_sp->GetState();
2976435933ddSDimitry Andric     if (process_sp->IsAlive() && state != eStateConnected) {
29771c3bbb01SEd Maste       if (state == eStateAttaching)
29785517e702SDimitry Andric         return Status("process attach is in progress");
29795517e702SDimitry Andric       return Status("a process is already being debugged");
29801c3bbb01SEd Maste     }
29811c3bbb01SEd Maste   }
29821c3bbb01SEd Maste 
29831c3bbb01SEd Maste   const ModuleSP old_exec_module_sp = GetExecutableModule();
29841c3bbb01SEd Maste 
29854ba319b5SDimitry Andric   // If no process info was specified, then use the target executable name as
29864ba319b5SDimitry Andric   // the process to attach to by default
2987435933ddSDimitry Andric   if (!attach_info.ProcessInfoSpecified()) {
29881c3bbb01SEd Maste     if (old_exec_module_sp)
2989435933ddSDimitry Andric       attach_info.GetExecutableFile().GetFilename() =
2990435933ddSDimitry Andric           old_exec_module_sp->GetPlatformFileSpec().GetFilename();
29911c3bbb01SEd Maste 
2992435933ddSDimitry Andric     if (!attach_info.ProcessInfoSpecified()) {
29935517e702SDimitry Andric       return Status("no process specified, create a target with a file, or "
2994435933ddSDimitry Andric                     "specify the --pid or --name");
29951c3bbb01SEd Maste     }
29961c3bbb01SEd Maste   }
29971c3bbb01SEd Maste 
2998435933ddSDimitry Andric   const auto platform_sp =
2999435933ddSDimitry Andric       GetDebugger().GetPlatformList().GetSelectedPlatform();
30009f2f44ceSEd Maste   ListenerSP hijack_listener_sp;
30019f2f44ceSEd Maste   const bool async = attach_info.GetAsync();
3002435933ddSDimitry Andric   if (!async) {
3003435933ddSDimitry Andric     hijack_listener_sp =
3004435933ddSDimitry Andric         Listener::MakeListener("lldb.Target.Attach.attach.hijack");
30059f2f44ceSEd Maste     attach_info.SetHijackListener(hijack_listener_sp);
30069f2f44ceSEd Maste   }
30071c3bbb01SEd Maste 
30085517e702SDimitry Andric   Status error;
3009435933ddSDimitry Andric   if (state != eStateConnected && platform_sp != nullptr &&
3010435933ddSDimitry Andric       platform_sp->CanDebugProcess()) {
30111c3bbb01SEd Maste     SetPlatform(platform_sp);
30121c3bbb01SEd Maste     process_sp = platform_sp->Attach(attach_info, GetDebugger(), this, error);
3013435933ddSDimitry Andric   } else {
3014435933ddSDimitry Andric     if (state != eStateConnected) {
30151c3bbb01SEd Maste       const char *plugin_name = attach_info.GetProcessPluginName();
3016435933ddSDimitry Andric       process_sp =
3017435933ddSDimitry Andric           CreateProcess(attach_info.GetListenerForProcess(GetDebugger()),
3018435933ddSDimitry Andric                         plugin_name, nullptr);
3019435933ddSDimitry Andric       if (process_sp == nullptr) {
3020435933ddSDimitry Andric         error.SetErrorStringWithFormat(
3021435933ddSDimitry Andric             "failed to create process using plugin %s",
3022435933ddSDimitry Andric             (plugin_name) ? plugin_name : "null");
30231c3bbb01SEd Maste         return error;
30241c3bbb01SEd Maste       }
30251c3bbb01SEd Maste     }
30269f2f44ceSEd Maste     if (hijack_listener_sp)
30274bb0738eSEd Maste       process_sp->HijackProcessEvents(hijack_listener_sp);
30281c3bbb01SEd Maste     error = process_sp->Attach(attach_info);
30291c3bbb01SEd Maste   }
30301c3bbb01SEd Maste 
3031435933ddSDimitry Andric   if (error.Success() && process_sp) {
3032435933ddSDimitry Andric     if (async) {
30339f2f44ceSEd Maste       process_sp->RestoreProcessEvents();
3034435933ddSDimitry Andric     } else {
3035435933ddSDimitry Andric       state = process_sp->WaitForProcessToStop(
3036435933ddSDimitry Andric           llvm::None, nullptr, false, attach_info.GetHijackListener(), stream);
30371c3bbb01SEd Maste       process_sp->RestoreProcessEvents();
30381c3bbb01SEd Maste 
3039435933ddSDimitry Andric       if (state != eStateStopped) {
30401c3bbb01SEd Maste         const char *exit_desc = process_sp->GetExitDescription();
30411c3bbb01SEd Maste         if (exit_desc)
30429f2f44ceSEd Maste           error.SetErrorStringWithFormat("%s", exit_desc);
30431c3bbb01SEd Maste         else
3044435933ddSDimitry Andric           error.SetErrorString(
3045435933ddSDimitry Andric               "process did not stop (no such process or permission problem?)");
30461c3bbb01SEd Maste         process_sp->Destroy(false);
30471c3bbb01SEd Maste       }
30481c3bbb01SEd Maste     }
30499f2f44ceSEd Maste   }
30501c3bbb01SEd Maste   return error;
30511c3bbb01SEd Maste }
30521c3bbb01SEd Maste 
FinalizeFileActions(ProcessLaunchInfo & info)3053*b5893f02SDimitry Andric void Target::FinalizeFileActions(ProcessLaunchInfo &info) {
3054*b5893f02SDimitry Andric   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
3055*b5893f02SDimitry Andric 
3056*b5893f02SDimitry Andric   // Finalize the file actions, and if none were given, default to opening up a
3057*b5893f02SDimitry Andric   // pseudo terminal
3058*b5893f02SDimitry Andric   PlatformSP platform_sp = GetPlatform();
3059*b5893f02SDimitry Andric   const bool default_to_use_pty =
3060*b5893f02SDimitry Andric       m_platform_sp ? m_platform_sp->IsHost() : false;
3061*b5893f02SDimitry Andric   LLDB_LOG(
3062*b5893f02SDimitry Andric       log,
3063*b5893f02SDimitry Andric       "have platform={0}, platform_sp->IsHost()={1}, default_to_use_pty={2}",
3064*b5893f02SDimitry Andric       bool(platform_sp),
3065*b5893f02SDimitry Andric       platform_sp ? (platform_sp->IsHost() ? "true" : "false") : "n/a",
3066*b5893f02SDimitry Andric       default_to_use_pty);
3067*b5893f02SDimitry Andric 
3068*b5893f02SDimitry Andric   // If nothing for stdin or stdout or stderr was specified, then check the
3069*b5893f02SDimitry Andric   // process for any default settings that were set with "settings set"
3070*b5893f02SDimitry Andric   if (info.GetFileActionForFD(STDIN_FILENO) == nullptr ||
3071*b5893f02SDimitry Andric       info.GetFileActionForFD(STDOUT_FILENO) == nullptr ||
3072*b5893f02SDimitry Andric       info.GetFileActionForFD(STDERR_FILENO) == nullptr) {
3073*b5893f02SDimitry Andric     LLDB_LOG(log, "at least one of stdin/stdout/stderr was not set, evaluating "
3074*b5893f02SDimitry Andric                   "default handling");
3075*b5893f02SDimitry Andric 
3076*b5893f02SDimitry Andric     if (info.GetFlags().Test(eLaunchFlagLaunchInTTY)) {
3077*b5893f02SDimitry Andric       // Do nothing, if we are launching in a remote terminal no file actions
3078*b5893f02SDimitry Andric       // should be done at all.
3079*b5893f02SDimitry Andric       return;
3080*b5893f02SDimitry Andric     }
3081*b5893f02SDimitry Andric 
3082*b5893f02SDimitry Andric     if (info.GetFlags().Test(eLaunchFlagDisableSTDIO)) {
3083*b5893f02SDimitry Andric       LLDB_LOG(log, "eLaunchFlagDisableSTDIO set, adding suppression action "
3084*b5893f02SDimitry Andric                     "for stdin, stdout and stderr");
3085*b5893f02SDimitry Andric       info.AppendSuppressFileAction(STDIN_FILENO, true, false);
3086*b5893f02SDimitry Andric       info.AppendSuppressFileAction(STDOUT_FILENO, false, true);
3087*b5893f02SDimitry Andric       info.AppendSuppressFileAction(STDERR_FILENO, false, true);
3088*b5893f02SDimitry Andric     } else {
3089*b5893f02SDimitry Andric       // Check for any values that might have gotten set with any of: (lldb)
3090*b5893f02SDimitry Andric       // settings set target.input-path (lldb) settings set target.output-path
3091*b5893f02SDimitry Andric       // (lldb) settings set target.error-path
3092*b5893f02SDimitry Andric       FileSpec in_file_spec;
3093*b5893f02SDimitry Andric       FileSpec out_file_spec;
3094*b5893f02SDimitry Andric       FileSpec err_file_spec;
3095*b5893f02SDimitry Andric       // Only override with the target settings if we don't already have an
3096*b5893f02SDimitry Andric       // action for in, out or error
3097*b5893f02SDimitry Andric       if (info.GetFileActionForFD(STDIN_FILENO) == nullptr)
3098*b5893f02SDimitry Andric         in_file_spec = GetStandardInputPath();
3099*b5893f02SDimitry Andric       if (info.GetFileActionForFD(STDOUT_FILENO) == nullptr)
3100*b5893f02SDimitry Andric         out_file_spec = GetStandardOutputPath();
3101*b5893f02SDimitry Andric       if (info.GetFileActionForFD(STDERR_FILENO) == nullptr)
3102*b5893f02SDimitry Andric         err_file_spec = GetStandardErrorPath();
3103*b5893f02SDimitry Andric 
3104*b5893f02SDimitry Andric       LLDB_LOG(log, "target stdin='{0}', target stdout='{1}', stderr='{1}'",
3105*b5893f02SDimitry Andric                in_file_spec, out_file_spec, err_file_spec);
3106*b5893f02SDimitry Andric 
3107*b5893f02SDimitry Andric       if (in_file_spec) {
3108*b5893f02SDimitry Andric         info.AppendOpenFileAction(STDIN_FILENO, in_file_spec, true, false);
3109*b5893f02SDimitry Andric         LLDB_LOG(log, "appended stdin open file action for {0}", in_file_spec);
3110*b5893f02SDimitry Andric       }
3111*b5893f02SDimitry Andric 
3112*b5893f02SDimitry Andric       if (out_file_spec) {
3113*b5893f02SDimitry Andric         info.AppendOpenFileAction(STDOUT_FILENO, out_file_spec, false, true);
3114*b5893f02SDimitry Andric         LLDB_LOG(log, "appended stdout open file action for {0}",
3115*b5893f02SDimitry Andric                  out_file_spec);
3116*b5893f02SDimitry Andric       }
3117*b5893f02SDimitry Andric 
3118*b5893f02SDimitry Andric       if (err_file_spec) {
3119*b5893f02SDimitry Andric         info.AppendOpenFileAction(STDERR_FILENO, err_file_spec, false, true);
3120*b5893f02SDimitry Andric         LLDB_LOG(log, "appended stderr open file action for {0}",
3121*b5893f02SDimitry Andric                  err_file_spec);
3122*b5893f02SDimitry Andric       }
3123*b5893f02SDimitry Andric 
3124*b5893f02SDimitry Andric       if (default_to_use_pty &&
3125*b5893f02SDimitry Andric           (!in_file_spec || !out_file_spec || !err_file_spec)) {
3126*b5893f02SDimitry Andric         llvm::Error Err = info.SetUpPtyRedirection();
3127*b5893f02SDimitry Andric         LLDB_LOG_ERROR(log, std::move(Err), "SetUpPtyRedirection failed: {0}");
3128*b5893f02SDimitry Andric       }
3129*b5893f02SDimitry Andric     }
3130*b5893f02SDimitry Andric   }
3131*b5893f02SDimitry Andric }
3132*b5893f02SDimitry Andric 
3133ac7ddfbfSEd Maste //--------------------------------------------------------------
3134b952cd58SEd Maste // Target::StopHook
3135ac7ddfbfSEd Maste //--------------------------------------------------------------
StopHook(lldb::TargetSP target_sp,lldb::user_id_t uid)3136435933ddSDimitry Andric Target::StopHook::StopHook(lldb::TargetSP target_sp, lldb::user_id_t uid)
3137435933ddSDimitry Andric     : UserID(uid), m_target_sp(target_sp), m_commands(), m_specifier_sp(),
3138435933ddSDimitry Andric       m_thread_spec_ap(), m_active(true) {}
3139ac7ddfbfSEd Maste 
StopHook(const StopHook & rhs)3140435933ddSDimitry Andric Target::StopHook::StopHook(const StopHook &rhs)
3141435933ddSDimitry Andric     : UserID(rhs.GetID()), m_target_sp(rhs.m_target_sp),
3142435933ddSDimitry Andric       m_commands(rhs.m_commands), m_specifier_sp(rhs.m_specifier_sp),
3143435933ddSDimitry Andric       m_thread_spec_ap(), m_active(rhs.m_active) {
31449f2f44ceSEd Maste   if (rhs.m_thread_spec_ap)
3145ac7ddfbfSEd Maste     m_thread_spec_ap.reset(new ThreadSpec(*rhs.m_thread_spec_ap.get()));
3146ac7ddfbfSEd Maste }
3147ac7ddfbfSEd Maste 
31489f2f44ceSEd Maste Target::StopHook::~StopHook() = default;
3149ac7ddfbfSEd Maste 
SetSpecifier(SymbolContextSpecifier * specifier)3150435933ddSDimitry Andric void Target::StopHook::SetSpecifier(SymbolContextSpecifier *specifier) {
31511c3bbb01SEd Maste   m_specifier_sp.reset(specifier);
31521c3bbb01SEd Maste }
31531c3bbb01SEd Maste 
SetThreadSpecifier(ThreadSpec * specifier)3154435933ddSDimitry Andric void Target::StopHook::SetThreadSpecifier(ThreadSpec *specifier) {
3155ac7ddfbfSEd Maste   m_thread_spec_ap.reset(specifier);
3156ac7ddfbfSEd Maste }
3157ac7ddfbfSEd Maste 
GetDescription(Stream * s,lldb::DescriptionLevel level) const3158435933ddSDimitry Andric void Target::StopHook::GetDescription(Stream *s,
3159435933ddSDimitry Andric                                       lldb::DescriptionLevel level) const {
3160ac7ddfbfSEd Maste   int indent_level = s->GetIndentLevel();
3161ac7ddfbfSEd Maste 
3162ac7ddfbfSEd Maste   s->SetIndentLevel(indent_level + 2);
3163ac7ddfbfSEd Maste 
3164ac7ddfbfSEd Maste   s->Printf("Hook: %" PRIu64 "\n", GetID());
3165ac7ddfbfSEd Maste   if (m_active)
3166ac7ddfbfSEd Maste     s->Indent("State: enabled\n");
3167ac7ddfbfSEd Maste   else
3168ac7ddfbfSEd Maste     s->Indent("State: disabled\n");
3169ac7ddfbfSEd Maste 
3170435933ddSDimitry Andric   if (m_specifier_sp) {
3171ac7ddfbfSEd Maste     s->Indent();
3172ac7ddfbfSEd Maste     s->PutCString("Specifier:\n");
3173ac7ddfbfSEd Maste     s->SetIndentLevel(indent_level + 4);
3174ac7ddfbfSEd Maste     m_specifier_sp->GetDescription(s, level);
3175ac7ddfbfSEd Maste     s->SetIndentLevel(indent_level + 2);
3176ac7ddfbfSEd Maste   }
3177ac7ddfbfSEd Maste 
3178435933ddSDimitry Andric   if (m_thread_spec_ap) {
3179ac7ddfbfSEd Maste     StreamString tmp;
3180ac7ddfbfSEd Maste     s->Indent("Thread:\n");
3181ac7ddfbfSEd Maste     m_thread_spec_ap->GetDescription(&tmp, level);
3182ac7ddfbfSEd Maste     s->SetIndentLevel(indent_level + 4);
3183435933ddSDimitry Andric     s->Indent(tmp.GetString());
3184ac7ddfbfSEd Maste     s->PutCString("\n");
3185ac7ddfbfSEd Maste     s->SetIndentLevel(indent_level + 2);
3186ac7ddfbfSEd Maste   }
3187ac7ddfbfSEd Maste 
3188ac7ddfbfSEd Maste   s->Indent("Commands: \n");
3189ac7ddfbfSEd Maste   s->SetIndentLevel(indent_level + 4);
3190ac7ddfbfSEd Maste   uint32_t num_commands = m_commands.GetSize();
3191435933ddSDimitry Andric   for (uint32_t i = 0; i < num_commands; i++) {
3192ac7ddfbfSEd Maste     s->Indent(m_commands.GetStringAtIndex(i));
3193ac7ddfbfSEd Maste     s->PutCString("\n");
3194ac7ddfbfSEd Maste   }
3195ac7ddfbfSEd Maste   s->SetIndentLevel(indent_level);
3196ac7ddfbfSEd Maste }
3197ac7ddfbfSEd Maste 
3198ac7ddfbfSEd Maste //--------------------------------------------------------------
3199ac7ddfbfSEd Maste // class TargetProperties
3200ac7ddfbfSEd Maste //--------------------------------------------------------------
3201ac7ddfbfSEd Maste 
3202*b5893f02SDimitry Andric // clang-format off
3203*b5893f02SDimitry Andric static constexpr OptionEnumValueElement g_dynamic_value_types[] = {
3204435933ddSDimitry Andric     {eNoDynamicValues, "no-dynamic-values",
3205435933ddSDimitry Andric      "Don't calculate the dynamic type of values"},
3206435933ddSDimitry Andric     {eDynamicCanRunTarget, "run-target", "Calculate the dynamic type of values "
3207435933ddSDimitry Andric                                          "even if you have to run the target."},
3208435933ddSDimitry Andric     {eDynamicDontRunTarget, "no-run-target",
3209*b5893f02SDimitry Andric      "Calculate the dynamic type of values, but don't run the target."} };
3210ac7ddfbfSEd Maste 
GetDynamicValueTypes()3211*b5893f02SDimitry Andric OptionEnumValues lldb_private::GetDynamicValueTypes() {
3212*b5893f02SDimitry Andric   return OptionEnumValues(g_dynamic_value_types);
3213*b5893f02SDimitry Andric }
3214*b5893f02SDimitry Andric 
3215*b5893f02SDimitry Andric static constexpr OptionEnumValueElement g_inline_breakpoint_enums[] = {
3216435933ddSDimitry Andric     {eInlineBreakpointsNever, "never", "Never look for inline breakpoint "
3217435933ddSDimitry Andric                                        "locations (fastest). This setting "
3218435933ddSDimitry Andric                                        "should only be used if you know that "
3219435933ddSDimitry Andric                                        "no inlining occurs in your programs."},
3220435933ddSDimitry Andric     {eInlineBreakpointsHeaders, "headers",
3221435933ddSDimitry Andric      "Only check for inline breakpoint locations when setting breakpoints in "
3222435933ddSDimitry Andric      "header files, but not when setting breakpoint in implementation source "
3223435933ddSDimitry Andric      "files (default)."},
3224435933ddSDimitry Andric     {eInlineBreakpointsAlways, "always",
3225435933ddSDimitry Andric      "Always look for inline breakpoint locations when setting file and line "
3226*b5893f02SDimitry Andric      "breakpoints (slower but most accurate)."} };
3227ac7ddfbfSEd Maste 
3228435933ddSDimitry Andric typedef enum x86DisassemblyFlavor {
3229ac7ddfbfSEd Maste   eX86DisFlavorDefault,
3230ac7ddfbfSEd Maste   eX86DisFlavorIntel,
3231ac7ddfbfSEd Maste   eX86DisFlavorATT
3232ac7ddfbfSEd Maste } x86DisassemblyFlavor;
3233ac7ddfbfSEd Maste 
3234*b5893f02SDimitry Andric static constexpr OptionEnumValueElement g_x86_dis_flavor_value_types[] = {
3235ac7ddfbfSEd Maste     {eX86DisFlavorDefault, "default", "Disassembler default (currently att)."},
3236ac7ddfbfSEd Maste     {eX86DisFlavorIntel, "intel", "Intel disassembler flavor."},
3237*b5893f02SDimitry Andric     {eX86DisFlavorATT, "att", "AT&T disassembler flavor."} };
3238ac7ddfbfSEd Maste 
3239*b5893f02SDimitry Andric static constexpr OptionEnumValueElement g_hex_immediate_style_values[] = {
3240ac7ddfbfSEd Maste     {Disassembler::eHexStyleC, "c", "C-style (0xffff)."},
3241*b5893f02SDimitry Andric     {Disassembler::eHexStyleAsm, "asm", "Asm-style (0ffffh)."} };
3242ac7ddfbfSEd Maste 
3243*b5893f02SDimitry Andric static constexpr OptionEnumValueElement g_load_script_from_sym_file_values[] = {
3244435933ddSDimitry Andric     {eLoadScriptFromSymFileTrue, "true",
3245435933ddSDimitry Andric      "Load debug scripts inside symbol files"},
3246435933ddSDimitry Andric     {eLoadScriptFromSymFileFalse, "false",
3247435933ddSDimitry Andric      "Do not load debug scripts inside symbol files."},
3248435933ddSDimitry Andric     {eLoadScriptFromSymFileWarn, "warn",
3249*b5893f02SDimitry Andric      "Warn about debug scripts inside symbol files but do not load them."} };
3250ac7ddfbfSEd Maste 
3251*b5893f02SDimitry Andric static constexpr
3252*b5893f02SDimitry Andric OptionEnumValueElement g_load_current_working_dir_lldbinit_values[] = {
3253435933ddSDimitry Andric     {eLoadCWDlldbinitTrue, "true",
3254435933ddSDimitry Andric      "Load .lldbinit files from current directory"},
3255435933ddSDimitry Andric     {eLoadCWDlldbinitFalse, "false",
3256435933ddSDimitry Andric      "Do not load .lldbinit files from current directory"},
3257435933ddSDimitry Andric     {eLoadCWDlldbinitWarn, "warn",
3258*b5893f02SDimitry Andric      "Warn about loading .lldbinit files from current directory"} };
32594bb0738eSEd Maste 
3260*b5893f02SDimitry Andric static constexpr OptionEnumValueElement g_memory_module_load_level_values[] = {
3261435933ddSDimitry Andric     {eMemoryModuleLoadLevelMinimal, "minimal",
3262435933ddSDimitry Andric      "Load minimal information when loading modules from memory. Currently "
3263435933ddSDimitry Andric      "this setting loads sections only."},
3264435933ddSDimitry Andric     {eMemoryModuleLoadLevelPartial, "partial",
3265435933ddSDimitry Andric      "Load partial information when loading modules from memory. Currently "
3266435933ddSDimitry Andric      "this setting loads sections and function bounds."},
3267435933ddSDimitry Andric     {eMemoryModuleLoadLevelComplete, "complete",
3268435933ddSDimitry Andric      "Load complete information when loading modules from memory. Currently "
3269*b5893f02SDimitry Andric      "this setting loads sections and all symbols."} };
3270ac7ddfbfSEd Maste 
3271*b5893f02SDimitry Andric static constexpr PropertyDefinition g_properties[] = {
3272*b5893f02SDimitry Andric     {"default-arch", OptionValue::eTypeArch, true, 0, nullptr, {},
3273435933ddSDimitry Andric      "Default architecture to choose, when there's a choice."},
3274435933ddSDimitry Andric     {"move-to-nearest-code", OptionValue::eTypeBoolean, false, true, nullptr,
3275*b5893f02SDimitry Andric      {}, "Move breakpoints to nearest code."},
3276435933ddSDimitry Andric     {"language", OptionValue::eTypeLanguage, false, eLanguageTypeUnknown,
3277*b5893f02SDimitry Andric      nullptr, {},
3278435933ddSDimitry Andric      "The language to use when interpreting expressions entered in commands."},
3279*b5893f02SDimitry Andric     {"expr-prefix", OptionValue::eTypeFileSpec, false, 0, nullptr, {},
3280435933ddSDimitry Andric      "Path to a file containing expressions to be prepended to all "
3281435933ddSDimitry Andric      "expressions."},
3282435933ddSDimitry Andric     {"prefer-dynamic-value", OptionValue::eTypeEnum, false,
3283*b5893f02SDimitry Andric      eDynamicDontRunTarget, nullptr, OptionEnumValues(g_dynamic_value_types),
3284435933ddSDimitry Andric      "Should printed values be shown as their dynamic value."},
3285435933ddSDimitry Andric     {"enable-synthetic-value", OptionValue::eTypeBoolean, false, true, nullptr,
3286*b5893f02SDimitry Andric      {}, "Should synthetic values be used by default whenever available."},
3287*b5893f02SDimitry Andric     {"skip-prologue", OptionValue::eTypeBoolean, false, true, nullptr, {},
3288435933ddSDimitry Andric      "Skip function prologues when setting breakpoints by name."},
3289*b5893f02SDimitry Andric     {"source-map", OptionValue::eTypePathMap, false, 0, nullptr, {},
3290435933ddSDimitry Andric      "Source path remappings are used to track the change of location between "
3291435933ddSDimitry Andric      "a source file when built, and "
3292435933ddSDimitry Andric      "where it exists on the current system.  It consists of an array of "
3293435933ddSDimitry Andric      "duples, the first element of each duple is "
3294435933ddSDimitry Andric      "some part (starting at the root) of the path to the file when it was "
3295435933ddSDimitry Andric      "built, "
3296435933ddSDimitry Andric      "and the second is where the remainder of the original build hierarchy is "
3297435933ddSDimitry Andric      "rooted on the local system.  "
3298435933ddSDimitry Andric      "Each element of the array is checked in order and the first one that "
3299435933ddSDimitry Andric      "results in a match wins."},
3300435933ddSDimitry Andric     {"exec-search-paths", OptionValue::eTypeFileSpecList, false, 0, nullptr,
3301*b5893f02SDimitry Andric      {}, "Executable search paths to use when locating executable files "
3302435933ddSDimitry Andric          "whose paths don't match the local file system."},
3303435933ddSDimitry Andric     {"debug-file-search-paths", OptionValue::eTypeFileSpecList, false, 0,
3304*b5893f02SDimitry Andric      nullptr, {},
3305*b5893f02SDimitry Andric      "List of directories to be searched when locating debug symbol files. "
3306*b5893f02SDimitry Andric      "See also symbols.enable-external-lookup."},
3307435933ddSDimitry Andric     {"clang-module-search-paths", OptionValue::eTypeFileSpecList, false, 0,
3308*b5893f02SDimitry Andric      nullptr, {},
3309435933ddSDimitry Andric      "List of directories to be searched when locating modules for Clang."},
3310435933ddSDimitry Andric     {"auto-import-clang-modules", OptionValue::eTypeBoolean, false, true,
3311*b5893f02SDimitry Andric      nullptr, {},
3312435933ddSDimitry Andric      "Automatically load Clang modules referred to by the program."},
3313435933ddSDimitry Andric     {"auto-apply-fixits", OptionValue::eTypeBoolean, false, true, nullptr,
3314*b5893f02SDimitry Andric      {}, "Automatically apply fix-it hints to expressions."},
3315435933ddSDimitry Andric     {"notify-about-fixits", OptionValue::eTypeBoolean, false, true, nullptr,
3316*b5893f02SDimitry Andric      {}, "Print the fixed expression text."},
3317435933ddSDimitry Andric     {"save-jit-objects", OptionValue::eTypeBoolean, false, false, nullptr,
3318*b5893f02SDimitry Andric      {}, "Save intermediate object files generated by the LLVM JIT"},
3319435933ddSDimitry Andric     {"max-children-count", OptionValue::eTypeSInt64, false, 256, nullptr,
3320*b5893f02SDimitry Andric      {}, "Maximum number of children to expand in any level of depth."},
3321435933ddSDimitry Andric     {"max-string-summary-length", OptionValue::eTypeSInt64, false, 1024,
3322*b5893f02SDimitry Andric      nullptr, {},
3323435933ddSDimitry Andric      "Maximum number of characters to show when using %s in summary strings."},
3324435933ddSDimitry Andric     {"max-memory-read-size", OptionValue::eTypeSInt64, false, 1024, nullptr,
3325*b5893f02SDimitry Andric      {}, "Maximum number of bytes that 'memory read' will fetch before "
3326435933ddSDimitry Andric          "--force must be specified."},
3327435933ddSDimitry Andric     {"breakpoints-use-platform-avoid-list", OptionValue::eTypeBoolean, false,
3328*b5893f02SDimitry Andric      true, nullptr, {}, "Consult the platform module avoid list when "
3329435933ddSDimitry Andric                         "setting non-module specific breakpoints."},
3330*b5893f02SDimitry Andric     {"arg0", OptionValue::eTypeString, false, 0, nullptr, {},
3331435933ddSDimitry Andric      "The first argument passed to the program in the argument array which can "
3332435933ddSDimitry Andric      "be different from the executable itself."},
3333*b5893f02SDimitry Andric     {"run-args", OptionValue::eTypeArgs, false, 0, nullptr, {},
3334435933ddSDimitry Andric      "A list containing all the arguments to be passed to the executable when "
3335435933ddSDimitry Andric      "it is run. Note that this does NOT include the argv[0] which is in "
3336435933ddSDimitry Andric      "target.arg0."},
3337435933ddSDimitry Andric     {"env-vars", OptionValue::eTypeDictionary, false, OptionValue::eTypeString,
3338*b5893f02SDimitry Andric      nullptr, {}, "A list of all the environment variables to be passed "
3339435933ddSDimitry Andric                   "to the executable's environment, and their values."},
3340*b5893f02SDimitry Andric     {"inherit-env", OptionValue::eTypeBoolean, false, true, nullptr, {},
3341435933ddSDimitry Andric      "Inherit the environment from the process that is running LLDB."},
3342*b5893f02SDimitry Andric     {"input-path", OptionValue::eTypeFileSpec, false, 0, nullptr, {},
3343435933ddSDimitry Andric      "The file/path to be used by the executable program for reading its "
3344435933ddSDimitry Andric      "standard input."},
3345*b5893f02SDimitry Andric     {"output-path", OptionValue::eTypeFileSpec, false, 0, nullptr, {},
3346435933ddSDimitry Andric      "The file/path to be used by the executable program for writing its "
3347435933ddSDimitry Andric      "standard output."},
3348*b5893f02SDimitry Andric     {"error-path", OptionValue::eTypeFileSpec, false, 0, nullptr, {},
3349435933ddSDimitry Andric      "The file/path to be used by the executable program for writing its "
3350435933ddSDimitry Andric      "standard error."},
3351435933ddSDimitry Andric     {"detach-on-error", OptionValue::eTypeBoolean, false, true, nullptr,
3352*b5893f02SDimitry Andric      {}, "debugserver will detach (rather than killing) a process if it "
3353435933ddSDimitry Andric               "loses connection with lldb."},
3354*b5893f02SDimitry Andric     {"preload-symbols", OptionValue::eTypeBoolean, false, true, nullptr, {},
3355f37b6182SDimitry Andric      "Enable loading of symbol tables before they are needed."},
3356*b5893f02SDimitry Andric     {"disable-aslr", OptionValue::eTypeBoolean, false, true, nullptr, {},
3357435933ddSDimitry Andric      "Disable Address Space Layout Randomization (ASLR)"},
3358*b5893f02SDimitry Andric     {"disable-stdio", OptionValue::eTypeBoolean, false, false, nullptr, {},
3359435933ddSDimitry Andric      "Disable stdin/stdout for process (e.g. for a GUI application)"},
3360435933ddSDimitry Andric     {"inline-breakpoint-strategy", OptionValue::eTypeEnum, false,
3361*b5893f02SDimitry Andric      eInlineBreakpointsAlways, nullptr,
3362*b5893f02SDimitry Andric      OptionEnumValues(g_inline_breakpoint_enums),
3363435933ddSDimitry Andric      "The strategy to use when settings breakpoints by file and line. "
3364435933ddSDimitry Andric      "Breakpoint locations can end up being inlined by the compiler, so that a "
3365435933ddSDimitry Andric      "compile unit 'a.c' might contain an inlined function from another source "
3366435933ddSDimitry Andric      "file. "
3367435933ddSDimitry Andric      "Usually this is limited to breakpoint locations from inlined functions "
3368435933ddSDimitry Andric      "from header or other include files, or more accurately "
3369435933ddSDimitry Andric      "non-implementation source files. "
3370435933ddSDimitry Andric      "Sometimes code might #include implementation files and cause inlined "
3371435933ddSDimitry Andric      "breakpoint locations in inlined implementation files. "
3372435933ddSDimitry Andric      "Always checking for inlined breakpoint locations can be expensive "
3373435933ddSDimitry Andric      "(memory and time), so if you have a project with many headers "
3374435933ddSDimitry Andric      "and find that setting breakpoints is slow, then you can change this "
3375435933ddSDimitry Andric      "setting to headers. "
3376435933ddSDimitry Andric      "This setting allows you to control exactly which strategy is used when "
3377435933ddSDimitry Andric      "setting "
3378ac7ddfbfSEd Maste      "file and line breakpoints."},
3379435933ddSDimitry Andric     // FIXME: This is the wrong way to do per-architecture settings, but we
3380435933ddSDimitry Andric     // don't have a general per architecture settings system in place yet.
3381435933ddSDimitry Andric     {"x86-disassembly-flavor", OptionValue::eTypeEnum, false,
3382*b5893f02SDimitry Andric      eX86DisFlavorDefault, nullptr,
3383*b5893f02SDimitry Andric      OptionEnumValues(g_x86_dis_flavor_value_types),
3384435933ddSDimitry Andric      "The default disassembly flavor to use for x86 or x86-64 targets."},
3385435933ddSDimitry Andric     {"use-hex-immediates", OptionValue::eTypeBoolean, false, true, nullptr,
3386*b5893f02SDimitry Andric      {}, "Show immediates in disassembly as hexadecimal."},
3387435933ddSDimitry Andric     {"hex-immediate-style", OptionValue::eTypeEnum, false,
3388*b5893f02SDimitry Andric      Disassembler::eHexStyleC, nullptr,
3389*b5893f02SDimitry Andric      OptionEnumValues(g_hex_immediate_style_values),
3390435933ddSDimitry Andric      "Which style to use for printing hexadecimal disassembly values."},
3391435933ddSDimitry Andric     {"use-fast-stepping", OptionValue::eTypeBoolean, false, true, nullptr,
3392*b5893f02SDimitry Andric      {}, "Use a fast stepping algorithm based on running from branch to "
3393435933ddSDimitry Andric          "branch rather than instruction single-stepping."},
3394435933ddSDimitry Andric     {"load-script-from-symbol-file", OptionValue::eTypeEnum, false,
3395*b5893f02SDimitry Andric      eLoadScriptFromSymFileWarn, nullptr,
3396*b5893f02SDimitry Andric      OptionEnumValues(g_load_script_from_sym_file_values),
3397435933ddSDimitry Andric      "Allow LLDB to load scripting resources embedded in symbol files when "
3398435933ddSDimitry Andric      "available."},
3399435933ddSDimitry Andric     {"load-cwd-lldbinit", OptionValue::eTypeEnum, false, eLoadCWDlldbinitWarn,
3400*b5893f02SDimitry Andric      nullptr, OptionEnumValues(g_load_current_working_dir_lldbinit_values),
3401435933ddSDimitry Andric      "Allow LLDB to .lldbinit files from the current directory automatically."},
3402435933ddSDimitry Andric     {"memory-module-load-level", OptionValue::eTypeEnum, false,
3403*b5893f02SDimitry Andric      eMemoryModuleLoadLevelComplete, nullptr,
3404*b5893f02SDimitry Andric      OptionEnumValues(g_memory_module_load_level_values),
3405435933ddSDimitry Andric      "Loading modules from memory can be slow as reading the symbol tables and "
3406435933ddSDimitry Andric      "other data can take a long time depending on your connection to the "
3407435933ddSDimitry Andric      "debug target. "
3408435933ddSDimitry Andric      "This setting helps users control how much information gets loaded when "
3409435933ddSDimitry Andric      "loading modules from memory."
3410435933ddSDimitry Andric      "'complete' is the default value for this setting which will load all "
3411435933ddSDimitry Andric      "sections and symbols by reading them from memory (slowest, most "
3412435933ddSDimitry Andric      "accurate). "
3413435933ddSDimitry Andric      "'partial' will load sections and attempt to find function bounds without "
3414435933ddSDimitry Andric      "downloading the symbol table (faster, still accurate, missing symbol "
3415435933ddSDimitry Andric      "names). "
3416435933ddSDimitry Andric      "'minimal' is the fastest setting and will load section data with no "
3417435933ddSDimitry Andric      "symbols, but should rarely be used as stack frames in these memory "
3418435933ddSDimitry Andric      "regions will be inaccurate and not provide any context (fastest). "},
3419435933ddSDimitry Andric     {"display-expression-in-crashlogs", OptionValue::eTypeBoolean, false, false,
3420*b5893f02SDimitry Andric      nullptr, {}, "Expressions that crash will show up in crash logs if "
3421435933ddSDimitry Andric                   "the host system supports executable specific crash log "
3422435933ddSDimitry Andric                   "strings and this setting is set to true."},
3423435933ddSDimitry Andric     {"trap-handler-names", OptionValue::eTypeArray, true,
3424*b5893f02SDimitry Andric      OptionValue::eTypeString, nullptr, {},
3425435933ddSDimitry Andric      "A list of trap handler function names, e.g. a common Unix user process "
3426435933ddSDimitry Andric      "one is _sigtramp."},
3427435933ddSDimitry Andric     {"display-runtime-support-values", OptionValue::eTypeBoolean, false, false,
3428*b5893f02SDimitry Andric      nullptr, {}, "If true, LLDB will show variables that are meant to "
3429*b5893f02SDimitry Andric                   "support the operation of a language's runtime support."},
3430*b5893f02SDimitry Andric     {"display-recognized-arguments", OptionValue::eTypeBoolean, false, false,
3431*b5893f02SDimitry Andric      nullptr, {}, "Show recognized arguments in variable listings by default."},
3432*b5893f02SDimitry Andric     {"non-stop-mode", OptionValue::eTypeBoolean, false, 0, nullptr, {},
3433435933ddSDimitry Andric      "Disable lock-step debugging, instead control threads independently."},
3434*b5893f02SDimitry Andric     {"require-hardware-breakpoint", OptionValue::eTypeBoolean, false, 0,
3435*b5893f02SDimitry Andric      nullptr, {}, "Require all breakpoints to be hardware breakpoints."}};
3436*b5893f02SDimitry Andric // clang-format on
34371c3bbb01SEd Maste 
3438435933ddSDimitry Andric enum {
3439ac7ddfbfSEd Maste   ePropertyDefaultArch,
34401c3bbb01SEd Maste   ePropertyMoveToNearestCode,
34419f2f44ceSEd Maste   ePropertyLanguage,
3442ac7ddfbfSEd Maste   ePropertyExprPrefix,
3443ac7ddfbfSEd Maste   ePropertyPreferDynamic,
3444ac7ddfbfSEd Maste   ePropertyEnableSynthetic,
3445ac7ddfbfSEd Maste   ePropertySkipPrologue,
3446ac7ddfbfSEd Maste   ePropertySourceMap,
3447ac7ddfbfSEd Maste   ePropertyExecutableSearchPaths,
3448ac7ddfbfSEd Maste   ePropertyDebugFileSearchPaths,
34491c3bbb01SEd Maste   ePropertyClangModuleSearchPaths,
34501c3bbb01SEd Maste   ePropertyAutoImportClangModules,
34514bb0738eSEd Maste   ePropertyAutoApplyFixIts,
34524bb0738eSEd Maste   ePropertyNotifyAboutFixIts,
3453435933ddSDimitry Andric   ePropertySaveObjects,
3454ac7ddfbfSEd Maste   ePropertyMaxChildrenCount,
3455ac7ddfbfSEd Maste   ePropertyMaxSummaryLength,
3456ac7ddfbfSEd Maste   ePropertyMaxMemReadSize,
3457ac7ddfbfSEd Maste   ePropertyBreakpointUseAvoidList,
3458ac7ddfbfSEd Maste   ePropertyArg0,
3459ac7ddfbfSEd Maste   ePropertyRunArgs,
3460ac7ddfbfSEd Maste   ePropertyEnvVars,
3461ac7ddfbfSEd Maste   ePropertyInheritEnv,
3462ac7ddfbfSEd Maste   ePropertyInputPath,
3463ac7ddfbfSEd Maste   ePropertyOutputPath,
3464ac7ddfbfSEd Maste   ePropertyErrorPath,
34650127ef0fSEd Maste   ePropertyDetachOnError,
3466f37b6182SDimitry Andric   ePropertyPreloadSymbols,
3467ac7ddfbfSEd Maste   ePropertyDisableASLR,
3468ac7ddfbfSEd Maste   ePropertyDisableSTDIO,
3469ac7ddfbfSEd Maste   ePropertyInlineStrategy,
3470ac7ddfbfSEd Maste   ePropertyDisassemblyFlavor,
3471ac7ddfbfSEd Maste   ePropertyUseHexImmediates,
3472ac7ddfbfSEd Maste   ePropertyHexImmediateStyle,
3473ac7ddfbfSEd Maste   ePropertyUseFastStepping,
3474ac7ddfbfSEd Maste   ePropertyLoadScriptFromSymbolFile,
34754bb0738eSEd Maste   ePropertyLoadCWDlldbinitFile,
347612b93ac6SEd Maste   ePropertyMemoryModuleLoadLevel,
347712b93ac6SEd Maste   ePropertyDisplayExpressionsInCrashlogs,
34781c3bbb01SEd Maste   ePropertyTrapHandlerNames,
34791c3bbb01SEd Maste   ePropertyDisplayRuntimeSupportValues,
3480*b5893f02SDimitry Andric   ePropertyDisplayRecognizedArguments,
34814bb0738eSEd Maste   ePropertyNonStopModeEnabled,
3482*b5893f02SDimitry Andric   ePropertyRequireHardwareBreakpoints,
3483*b5893f02SDimitry Andric   ePropertyExperimental,
3484ac7ddfbfSEd Maste };
3485ac7ddfbfSEd Maste 
3486435933ddSDimitry Andric class TargetOptionValueProperties : public OptionValueProperties {
3487ac7ddfbfSEd Maste public:
TargetOptionValueProperties(const ConstString & name)3488435933ddSDimitry Andric   TargetOptionValueProperties(const ConstString &name)
3489435933ddSDimitry Andric       : OptionValueProperties(name), m_target(nullptr), m_got_host_env(false) {}
3490ac7ddfbfSEd Maste 
3491ac7ddfbfSEd Maste   // This constructor is used when creating TargetOptionValueProperties when it
3492ac7ddfbfSEd Maste   // is part of a new lldb_private::Target instance. It will copy all current
3493ac7ddfbfSEd Maste   // global property values as needed
TargetOptionValueProperties(Target * target,const TargetPropertiesSP & target_properties_sp)3494435933ddSDimitry Andric   TargetOptionValueProperties(Target *target,
3495435933ddSDimitry Andric                               const TargetPropertiesSP &target_properties_sp)
3496435933ddSDimitry Andric       : OptionValueProperties(*target_properties_sp->GetValueProperties()),
3497435933ddSDimitry Andric         m_target(target), m_got_host_env(false) {}
3498ac7ddfbfSEd Maste 
GetPropertyAtIndex(const ExecutionContext * exe_ctx,bool will_modify,uint32_t idx) const3499435933ddSDimitry Andric   const Property *GetPropertyAtIndex(const ExecutionContext *exe_ctx,
3500435933ddSDimitry Andric                                      bool will_modify,
3501435933ddSDimitry Andric                                      uint32_t idx) const override {
35020127ef0fSEd Maste     // When getting the value for a key from the target options, we will always
35034ba319b5SDimitry Andric     // try and grab the setting from the current target if there is one. Else
35044ba319b5SDimitry Andric     // we just use the one from this instance.
3505ac7ddfbfSEd Maste     if (idx == ePropertyEnvVars)
3506ac7ddfbfSEd Maste       GetHostEnvironmentIfNeeded();
3507ac7ddfbfSEd Maste 
3508435933ddSDimitry Andric     if (exe_ctx) {
3509ac7ddfbfSEd Maste       Target *target = exe_ctx->GetTargetPtr();
3510435933ddSDimitry Andric       if (target) {
3511435933ddSDimitry Andric         TargetOptionValueProperties *target_properties =
3512435933ddSDimitry Andric             static_cast<TargetOptionValueProperties *>(
3513435933ddSDimitry Andric                 target->GetValueProperties().get());
3514ac7ddfbfSEd Maste         if (this != target_properties)
3515ac7ddfbfSEd Maste           return target_properties->ProtectedGetPropertyAtIndex(idx);
3516ac7ddfbfSEd Maste       }
3517ac7ddfbfSEd Maste     }
3518ac7ddfbfSEd Maste     return ProtectedGetPropertyAtIndex(idx);
3519ac7ddfbfSEd Maste   }
3520ac7ddfbfSEd Maste 
GetTargetSP()3521435933ddSDimitry Andric   lldb::TargetSP GetTargetSP() { return m_target->shared_from_this(); }
3522ac7ddfbfSEd Maste 
3523ac7ddfbfSEd Maste protected:
GetHostEnvironmentIfNeeded() const3524435933ddSDimitry Andric   void GetHostEnvironmentIfNeeded() const {
3525435933ddSDimitry Andric     if (!m_got_host_env) {
3526435933ddSDimitry Andric       if (m_target) {
3527ac7ddfbfSEd Maste         m_got_host_env = true;
3528ac7ddfbfSEd Maste         const uint32_t idx = ePropertyInheritEnv;
3529435933ddSDimitry Andric         if (GetPropertyAtIndexAsBoolean(
3530435933ddSDimitry Andric                 nullptr, idx, g_properties[idx].default_uint_value != 0)) {
3531ac7ddfbfSEd Maste           PlatformSP platform_sp(m_target->GetPlatform());
3532435933ddSDimitry Andric           if (platform_sp) {
35334ba319b5SDimitry Andric             Environment env = platform_sp->GetEnvironment();
3534435933ddSDimitry Andric             OptionValueDictionary *env_dict =
3535435933ddSDimitry Andric                 GetPropertyAtIndexAsOptionValueDictionary(nullptr,
3536435933ddSDimitry Andric                                                           ePropertyEnvVars);
3537435933ddSDimitry Andric             if (env_dict) {
3538ac7ddfbfSEd Maste               const bool can_replace = false;
35394ba319b5SDimitry Andric               for (const auto &KV : env) {
3540435933ddSDimitry Andric                 // Don't allow existing keys to be replaced with ones we get
3541435933ddSDimitry Andric                 // from the platform environment
3542435933ddSDimitry Andric                 env_dict->SetValueForKey(
35434ba319b5SDimitry Andric                     ConstString(KV.first()),
35444ba319b5SDimitry Andric                     OptionValueSP(new OptionValueString(KV.second.c_str())),
3545435933ddSDimitry Andric                     can_replace);
3546ac7ddfbfSEd Maste               }
3547ac7ddfbfSEd Maste             }
3548ac7ddfbfSEd Maste           }
3549ac7ddfbfSEd Maste         }
3550ac7ddfbfSEd Maste       }
3551ac7ddfbfSEd Maste     }
3552ac7ddfbfSEd Maste   }
3553ac7ddfbfSEd Maste   Target *m_target;
3554ac7ddfbfSEd Maste   mutable bool m_got_host_env;
3555ac7ddfbfSEd Maste };
3556ac7ddfbfSEd Maste 
3557b952cd58SEd Maste //----------------------------------------------------------------------
3558b952cd58SEd Maste // TargetProperties
3559b952cd58SEd Maste //----------------------------------------------------------------------
3560*b5893f02SDimitry Andric static constexpr PropertyDefinition g_experimental_properties[]{
3561435933ddSDimitry Andric     {"inject-local-vars", OptionValue::eTypeBoolean, true, true, nullptr,
3562*b5893f02SDimitry Andric      {},
3563435933ddSDimitry Andric      "If true, inject local variables explicitly into the expression text.  "
3564435933ddSDimitry Andric      "This will fix symbol resolution when there are name collisions between "
3565435933ddSDimitry Andric      "ivars and local variables.  "
35664bb0738eSEd Maste      "But it can make expressions run much more slowly."},
3567acac075bSDimitry Andric     {"use-modern-type-lookup", OptionValue::eTypeBoolean, true, false, nullptr,
3568*b5893f02SDimitry Andric      {}, "If true, use Clang's modern type lookup infrastructure."}};
35694bb0738eSEd Maste 
3570acac075bSDimitry Andric enum { ePropertyInjectLocalVars = 0, ePropertyUseModernTypeLookup };
35714bb0738eSEd Maste 
3572435933ddSDimitry Andric class TargetExperimentalOptionValueProperties : public OptionValueProperties {
35734bb0738eSEd Maste public:
TargetExperimentalOptionValueProperties()3574435933ddSDimitry Andric   TargetExperimentalOptionValueProperties()
3575435933ddSDimitry Andric       : OptionValueProperties(
3576435933ddSDimitry Andric             ConstString(Properties::GetExperimentalSettingsName())) {}
35774bb0738eSEd Maste };
35784bb0738eSEd Maste 
TargetExperimentalProperties()3579435933ddSDimitry Andric TargetExperimentalProperties::TargetExperimentalProperties()
3580435933ddSDimitry Andric     : Properties(OptionValuePropertiesSP(
3581435933ddSDimitry Andric           new TargetExperimentalOptionValueProperties())) {
35824bb0738eSEd Maste   m_collection_sp->Initialize(g_experimental_properties);
35834bb0738eSEd Maste }
35844bb0738eSEd Maste 
35854bb0738eSEd Maste //----------------------------------------------------------------------
35864bb0738eSEd Maste // TargetProperties
35874bb0738eSEd Maste //----------------------------------------------------------------------
TargetProperties(Target * target)3588435933ddSDimitry Andric TargetProperties::TargetProperties(Target *target)
3589435933ddSDimitry Andric     : Properties(), m_launch_info() {
3590435933ddSDimitry Andric   if (target) {
3591435933ddSDimitry Andric     m_collection_sp.reset(
3592435933ddSDimitry Andric         new TargetOptionValueProperties(target, Target::GetGlobalProperties()));
35931c3bbb01SEd Maste 
35944ba319b5SDimitry Andric     // Set callbacks to update launch_info whenever "settins set" updated any
35954ba319b5SDimitry Andric     // of these properties
3596435933ddSDimitry Andric     m_collection_sp->SetValueChangedCallback(
3597435933ddSDimitry Andric         ePropertyArg0, TargetProperties::Arg0ValueChangedCallback, this);
3598435933ddSDimitry Andric     m_collection_sp->SetValueChangedCallback(
3599435933ddSDimitry Andric         ePropertyRunArgs, TargetProperties::RunArgsValueChangedCallback, this);
3600435933ddSDimitry Andric     m_collection_sp->SetValueChangedCallback(
3601435933ddSDimitry Andric         ePropertyEnvVars, TargetProperties::EnvVarsValueChangedCallback, this);
3602435933ddSDimitry Andric     m_collection_sp->SetValueChangedCallback(
3603435933ddSDimitry Andric         ePropertyInputPath, TargetProperties::InputPathValueChangedCallback,
3604435933ddSDimitry Andric         this);
3605435933ddSDimitry Andric     m_collection_sp->SetValueChangedCallback(
3606435933ddSDimitry Andric         ePropertyOutputPath, TargetProperties::OutputPathValueChangedCallback,
3607435933ddSDimitry Andric         this);
3608435933ddSDimitry Andric     m_collection_sp->SetValueChangedCallback(
3609435933ddSDimitry Andric         ePropertyErrorPath, TargetProperties::ErrorPathValueChangedCallback,
3610435933ddSDimitry Andric         this);
3611435933ddSDimitry Andric     m_collection_sp->SetValueChangedCallback(
3612435933ddSDimitry Andric         ePropertyDetachOnError,
3613435933ddSDimitry Andric         TargetProperties::DetachOnErrorValueChangedCallback, this);
3614435933ddSDimitry Andric     m_collection_sp->SetValueChangedCallback(
3615435933ddSDimitry Andric         ePropertyDisableASLR, TargetProperties::DisableASLRValueChangedCallback,
3616435933ddSDimitry Andric         this);
3617435933ddSDimitry Andric     m_collection_sp->SetValueChangedCallback(
3618435933ddSDimitry Andric         ePropertyDisableSTDIO,
3619435933ddSDimitry Andric         TargetProperties::DisableSTDIOValueChangedCallback, this);
36201c3bbb01SEd Maste 
36214bb0738eSEd Maste     m_experimental_properties_up.reset(new TargetExperimentalProperties());
3622435933ddSDimitry Andric     m_collection_sp->AppendProperty(
3623435933ddSDimitry Andric         ConstString(Properties::GetExperimentalSettingsName()),
3624435933ddSDimitry Andric         ConstString("Experimental settings - setting these won't produce "
3625435933ddSDimitry Andric                     "errors if the setting is not present."),
3626435933ddSDimitry Andric         true, m_experimental_properties_up->GetValueProperties());
36274bb0738eSEd Maste 
36281c3bbb01SEd Maste     // Update m_launch_info once it was created
36299f2f44ceSEd Maste     Arg0ValueChangedCallback(this, nullptr);
36309f2f44ceSEd Maste     RunArgsValueChangedCallback(this, nullptr);
3631435933ddSDimitry Andric     // EnvVarsValueChangedCallback(this, nullptr); // FIXME: cause segfault in
3632435933ddSDimitry Andric     // Target::GetPlatform()
36339f2f44ceSEd Maste     InputPathValueChangedCallback(this, nullptr);
36349f2f44ceSEd Maste     OutputPathValueChangedCallback(this, nullptr);
36359f2f44ceSEd Maste     ErrorPathValueChangedCallback(this, nullptr);
36369f2f44ceSEd Maste     DetachOnErrorValueChangedCallback(this, nullptr);
36379f2f44ceSEd Maste     DisableASLRValueChangedCallback(this, nullptr);
36389f2f44ceSEd Maste     DisableSTDIOValueChangedCallback(this, nullptr);
3639435933ddSDimitry Andric   } else {
3640435933ddSDimitry Andric     m_collection_sp.reset(
3641435933ddSDimitry Andric         new TargetOptionValueProperties(ConstString("target")));
3642ac7ddfbfSEd Maste     m_collection_sp->Initialize(g_properties);
36434bb0738eSEd Maste     m_experimental_properties_up.reset(new TargetExperimentalProperties());
3644435933ddSDimitry Andric     m_collection_sp->AppendProperty(
3645435933ddSDimitry Andric         ConstString(Properties::GetExperimentalSettingsName()),
3646435933ddSDimitry Andric         ConstString("Experimental settings - setting these won't produce "
3647435933ddSDimitry Andric                     "errors if the setting is not present."),
3648435933ddSDimitry Andric         true, m_experimental_properties_up->GetValueProperties());
3649435933ddSDimitry Andric     m_collection_sp->AppendProperty(
3650435933ddSDimitry Andric         ConstString("process"), ConstString("Settings specific to processes."),
3651435933ddSDimitry Andric         true, Process::GetGlobalProperties()->GetValueProperties());
3652ac7ddfbfSEd Maste   }
3653ac7ddfbfSEd Maste }
3654ac7ddfbfSEd Maste 
36559f2f44ceSEd Maste TargetProperties::~TargetProperties() = default;
36569f2f44ceSEd Maste 
GetInjectLocalVariables(ExecutionContext * exe_ctx) const3657435933ddSDimitry Andric bool TargetProperties::GetInjectLocalVariables(
3658435933ddSDimitry Andric     ExecutionContext *exe_ctx) const {
3659435933ddSDimitry Andric   const Property *exp_property = m_collection_sp->GetPropertyAtIndex(
3660435933ddSDimitry Andric       exe_ctx, false, ePropertyExperimental);
3661435933ddSDimitry Andric   OptionValueProperties *exp_values =
3662435933ddSDimitry Andric       exp_property->GetValue()->GetAsProperties();
36634bb0738eSEd Maste   if (exp_values)
3664435933ddSDimitry Andric     return exp_values->GetPropertyAtIndexAsBoolean(
3665435933ddSDimitry Andric         exe_ctx, ePropertyInjectLocalVars, true);
36664bb0738eSEd Maste   else
36674bb0738eSEd Maste     return true;
36684bb0738eSEd Maste }
36694bb0738eSEd Maste 
SetInjectLocalVariables(ExecutionContext * exe_ctx,bool b)3670435933ddSDimitry Andric void TargetProperties::SetInjectLocalVariables(ExecutionContext *exe_ctx,
3671435933ddSDimitry Andric                                                bool b) {
3672435933ddSDimitry Andric   const Property *exp_property =
3673435933ddSDimitry Andric       m_collection_sp->GetPropertyAtIndex(exe_ctx, true, ePropertyExperimental);
3674435933ddSDimitry Andric   OptionValueProperties *exp_values =
3675435933ddSDimitry Andric       exp_property->GetValue()->GetAsProperties();
36764bb0738eSEd Maste   if (exp_values)
3677435933ddSDimitry Andric     exp_values->SetPropertyAtIndexAsBoolean(exe_ctx, ePropertyInjectLocalVars,
3678435933ddSDimitry Andric                                             true);
36794bb0738eSEd Maste }
36804bb0738eSEd Maste 
GetUseModernTypeLookup() const3681acac075bSDimitry Andric bool TargetProperties::GetUseModernTypeLookup() const {
3682acac075bSDimitry Andric   const Property *exp_property = m_collection_sp->GetPropertyAtIndex(
3683acac075bSDimitry Andric       nullptr, false, ePropertyExperimental);
3684acac075bSDimitry Andric   OptionValueProperties *exp_values =
3685acac075bSDimitry Andric       exp_property->GetValue()->GetAsProperties();
3686acac075bSDimitry Andric   if (exp_values)
3687acac075bSDimitry Andric     return exp_values->GetPropertyAtIndexAsBoolean(
3688acac075bSDimitry Andric         nullptr, ePropertyUseModernTypeLookup, true);
3689acac075bSDimitry Andric   else
3690acac075bSDimitry Andric     return true;
3691acac075bSDimitry Andric }
3692acac075bSDimitry Andric 
GetDefaultArchitecture() const3693435933ddSDimitry Andric ArchSpec TargetProperties::GetDefaultArchitecture() const {
3694435933ddSDimitry Andric   OptionValueArch *value = m_collection_sp->GetPropertyAtIndexAsOptionValueArch(
3695435933ddSDimitry Andric       nullptr, ePropertyDefaultArch);
3696ac7ddfbfSEd Maste   if (value)
3697ac7ddfbfSEd Maste     return value->GetCurrentValue();
3698ac7ddfbfSEd Maste   return ArchSpec();
3699ac7ddfbfSEd Maste }
3700ac7ddfbfSEd Maste 
SetDefaultArchitecture(const ArchSpec & arch)3701435933ddSDimitry Andric void TargetProperties::SetDefaultArchitecture(const ArchSpec &arch) {
3702435933ddSDimitry Andric   OptionValueArch *value = m_collection_sp->GetPropertyAtIndexAsOptionValueArch(
3703435933ddSDimitry Andric       nullptr, ePropertyDefaultArch);
3704ac7ddfbfSEd Maste   if (value)
3705ac7ddfbfSEd Maste     return value->SetCurrentValue(arch, true);
3706ac7ddfbfSEd Maste }
3707ac7ddfbfSEd Maste 
GetMoveToNearestCode() const3708435933ddSDimitry Andric bool TargetProperties::GetMoveToNearestCode() const {
37091c3bbb01SEd Maste   const uint32_t idx = ePropertyMoveToNearestCode;
3710435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsBoolean(
3711435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value != 0);
37121c3bbb01SEd Maste }
37131c3bbb01SEd Maste 
GetPreferDynamicValue() const3714435933ddSDimitry Andric lldb::DynamicValueType TargetProperties::GetPreferDynamicValue() const {
3715ac7ddfbfSEd Maste   const uint32_t idx = ePropertyPreferDynamic;
3716435933ddSDimitry Andric   return (lldb::DynamicValueType)
3717435933ddSDimitry Andric       m_collection_sp->GetPropertyAtIndexAsEnumeration(
3718435933ddSDimitry Andric           nullptr, idx, g_properties[idx].default_uint_value);
3719ac7ddfbfSEd Maste }
3720ac7ddfbfSEd Maste 
SetPreferDynamicValue(lldb::DynamicValueType d)3721435933ddSDimitry Andric bool TargetProperties::SetPreferDynamicValue(lldb::DynamicValueType d) {
37221c3bbb01SEd Maste   const uint32_t idx = ePropertyPreferDynamic;
37239f2f44ceSEd Maste   return m_collection_sp->SetPropertyAtIndexAsEnumeration(nullptr, idx, d);
37241c3bbb01SEd Maste }
37251c3bbb01SEd Maste 
GetPreloadSymbols() const3726f37b6182SDimitry Andric bool TargetProperties::GetPreloadSymbols() const {
3727f37b6182SDimitry Andric   const uint32_t idx = ePropertyPreloadSymbols;
3728f37b6182SDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsBoolean(
3729f37b6182SDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value != 0);
3730f37b6182SDimitry Andric }
3731f37b6182SDimitry Andric 
SetPreloadSymbols(bool b)3732f37b6182SDimitry Andric void TargetProperties::SetPreloadSymbols(bool b) {
3733f37b6182SDimitry Andric   const uint32_t idx = ePropertyPreloadSymbols;
3734f37b6182SDimitry Andric   m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
3735f37b6182SDimitry Andric }
3736f37b6182SDimitry Andric 
GetDisableASLR() const3737435933ddSDimitry Andric bool TargetProperties::GetDisableASLR() const {
3738ac7ddfbfSEd Maste   const uint32_t idx = ePropertyDisableASLR;
3739435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsBoolean(
3740435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value != 0);
3741ac7ddfbfSEd Maste }
3742ac7ddfbfSEd Maste 
SetDisableASLR(bool b)3743435933ddSDimitry Andric void TargetProperties::SetDisableASLR(bool b) {
3744ac7ddfbfSEd Maste   const uint32_t idx = ePropertyDisableASLR;
37459f2f44ceSEd Maste   m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
3746ac7ddfbfSEd Maste }
3747ac7ddfbfSEd Maste 
GetDetachOnError() const3748435933ddSDimitry Andric bool TargetProperties::GetDetachOnError() const {
37490127ef0fSEd Maste   const uint32_t idx = ePropertyDetachOnError;
3750435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsBoolean(
3751435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value != 0);
37520127ef0fSEd Maste }
37530127ef0fSEd Maste 
SetDetachOnError(bool b)3754435933ddSDimitry Andric void TargetProperties::SetDetachOnError(bool b) {
37550127ef0fSEd Maste   const uint32_t idx = ePropertyDetachOnError;
37569f2f44ceSEd Maste   m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
37570127ef0fSEd Maste }
37580127ef0fSEd Maste 
GetDisableSTDIO() const3759435933ddSDimitry Andric bool TargetProperties::GetDisableSTDIO() const {
3760ac7ddfbfSEd Maste   const uint32_t idx = ePropertyDisableSTDIO;
3761435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsBoolean(
3762435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value != 0);
3763ac7ddfbfSEd Maste }
3764ac7ddfbfSEd Maste 
SetDisableSTDIO(bool b)3765435933ddSDimitry Andric void TargetProperties::SetDisableSTDIO(bool b) {
3766ac7ddfbfSEd Maste   const uint32_t idx = ePropertyDisableSTDIO;
37679f2f44ceSEd Maste   m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
3768ac7ddfbfSEd Maste }
3769ac7ddfbfSEd Maste 
GetDisassemblyFlavor() const3770435933ddSDimitry Andric const char *TargetProperties::GetDisassemblyFlavor() const {
3771ac7ddfbfSEd Maste   const uint32_t idx = ePropertyDisassemblyFlavor;
3772ac7ddfbfSEd Maste   const char *return_value;
3773ac7ddfbfSEd Maste 
3774435933ddSDimitry Andric   x86DisassemblyFlavor flavor_value =
3775435933ddSDimitry Andric       (x86DisassemblyFlavor)m_collection_sp->GetPropertyAtIndexAsEnumeration(
3776435933ddSDimitry Andric           nullptr, idx, g_properties[idx].default_uint_value);
3777ac7ddfbfSEd Maste   return_value = g_x86_dis_flavor_value_types[flavor_value].string_value;
3778ac7ddfbfSEd Maste   return return_value;
3779ac7ddfbfSEd Maste }
3780ac7ddfbfSEd Maste 
GetInlineStrategy() const3781435933ddSDimitry Andric InlineStrategy TargetProperties::GetInlineStrategy() const {
3782ac7ddfbfSEd Maste   const uint32_t idx = ePropertyInlineStrategy;
3783435933ddSDimitry Andric   return (InlineStrategy)m_collection_sp->GetPropertyAtIndexAsEnumeration(
3784435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value);
3785ac7ddfbfSEd Maste }
3786ac7ddfbfSEd Maste 
GetArg0() const3787435933ddSDimitry Andric llvm::StringRef TargetProperties::GetArg0() const {
3788ac7ddfbfSEd Maste   const uint32_t idx = ePropertyArg0;
3789435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, llvm::StringRef());
3790ac7ddfbfSEd Maste }
3791ac7ddfbfSEd Maste 
SetArg0(llvm::StringRef arg)3792435933ddSDimitry Andric void TargetProperties::SetArg0(llvm::StringRef arg) {
3793ac7ddfbfSEd Maste   const uint32_t idx = ePropertyArg0;
3794435933ddSDimitry Andric   m_collection_sp->SetPropertyAtIndexAsString(
3795435933ddSDimitry Andric       nullptr, idx, arg);
37961c3bbb01SEd Maste   m_launch_info.SetArg0(arg);
3797ac7ddfbfSEd Maste }
3798ac7ddfbfSEd Maste 
GetRunArguments(Args & args) const3799435933ddSDimitry Andric bool TargetProperties::GetRunArguments(Args &args) const {
3800ac7ddfbfSEd Maste   const uint32_t idx = ePropertyRunArgs;
38019f2f44ceSEd Maste   return m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, idx, args);
3802ac7ddfbfSEd Maste }
3803ac7ddfbfSEd Maste 
SetRunArguments(const Args & args)3804435933ddSDimitry Andric void TargetProperties::SetRunArguments(const Args &args) {
3805ac7ddfbfSEd Maste   const uint32_t idx = ePropertyRunArgs;
38069f2f44ceSEd Maste   m_collection_sp->SetPropertyAtIndexFromArgs(nullptr, idx, args);
38071c3bbb01SEd Maste   m_launch_info.GetArguments() = args;
3808ac7ddfbfSEd Maste }
3809ac7ddfbfSEd Maste 
GetEnvironment() const38104ba319b5SDimitry Andric Environment TargetProperties::GetEnvironment() const {
38114ba319b5SDimitry Andric   // TODO: Get rid of the Args intermediate step
38124ba319b5SDimitry Andric   Args env;
3813ac7ddfbfSEd Maste   const uint32_t idx = ePropertyEnvVars;
38144ba319b5SDimitry Andric   m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, idx, env);
38154ba319b5SDimitry Andric   return Environment(env);
3816ac7ddfbfSEd Maste }
3817ac7ddfbfSEd Maste 
SetEnvironment(Environment env)38184ba319b5SDimitry Andric void TargetProperties::SetEnvironment(Environment env) {
38194ba319b5SDimitry Andric   // TODO: Get rid of the Args intermediate step
38201c3bbb01SEd Maste   const uint32_t idx = ePropertyEnvVars;
38214ba319b5SDimitry Andric   m_collection_sp->SetPropertyAtIndexFromArgs(nullptr, idx, Args(env));
38224ba319b5SDimitry Andric   m_launch_info.GetEnvironment() = std::move(env);
38231c3bbb01SEd Maste }
38241c3bbb01SEd Maste 
GetSkipPrologue() const3825435933ddSDimitry Andric bool TargetProperties::GetSkipPrologue() const {
3826ac7ddfbfSEd Maste   const uint32_t idx = ePropertySkipPrologue;
3827435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsBoolean(
3828435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value != 0);
3829ac7ddfbfSEd Maste }
3830ac7ddfbfSEd Maste 
GetSourcePathMap() const3831435933ddSDimitry Andric PathMappingList &TargetProperties::GetSourcePathMap() const {
3832ac7ddfbfSEd Maste   const uint32_t idx = ePropertySourceMap;
3833435933ddSDimitry Andric   OptionValuePathMappings *option_value =
3834435933ddSDimitry Andric       m_collection_sp->GetPropertyAtIndexAsOptionValuePathMappings(nullptr,
3835435933ddSDimitry Andric                                                                    false, idx);
3836ac7ddfbfSEd Maste   assert(option_value);
3837ac7ddfbfSEd Maste   return option_value->GetCurrentValue();
3838ac7ddfbfSEd Maste }
3839ac7ddfbfSEd Maste 
GetExecutableSearchPaths()3840435933ddSDimitry Andric FileSpecList &TargetProperties::GetExecutableSearchPaths() {
3841ac7ddfbfSEd Maste   const uint32_t idx = ePropertyExecutableSearchPaths;
3842435933ddSDimitry Andric   OptionValueFileSpecList *option_value =
3843435933ddSDimitry Andric       m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(nullptr,
3844435933ddSDimitry Andric                                                                    false, idx);
3845ac7ddfbfSEd Maste   assert(option_value);
3846ac7ddfbfSEd Maste   return option_value->GetCurrentValue();
3847ac7ddfbfSEd Maste }
3848ac7ddfbfSEd Maste 
GetDebugFileSearchPaths()3849435933ddSDimitry Andric FileSpecList &TargetProperties::GetDebugFileSearchPaths() {
3850ac7ddfbfSEd Maste   const uint32_t idx = ePropertyDebugFileSearchPaths;
3851435933ddSDimitry Andric   OptionValueFileSpecList *option_value =
3852435933ddSDimitry Andric       m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(nullptr,
3853435933ddSDimitry Andric                                                                    false, idx);
3854ac7ddfbfSEd Maste   assert(option_value);
3855ac7ddfbfSEd Maste   return option_value->GetCurrentValue();
3856ac7ddfbfSEd Maste }
3857ac7ddfbfSEd Maste 
GetClangModuleSearchPaths()3858435933ddSDimitry Andric FileSpecList &TargetProperties::GetClangModuleSearchPaths() {
38591c3bbb01SEd Maste   const uint32_t idx = ePropertyClangModuleSearchPaths;
3860435933ddSDimitry Andric   OptionValueFileSpecList *option_value =
3861435933ddSDimitry Andric       m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(nullptr,
3862435933ddSDimitry Andric                                                                    false, idx);
38631c3bbb01SEd Maste   assert(option_value);
38641c3bbb01SEd Maste   return option_value->GetCurrentValue();
38651c3bbb01SEd Maste }
38661c3bbb01SEd Maste 
GetEnableAutoImportClangModules() const3867435933ddSDimitry Andric bool TargetProperties::GetEnableAutoImportClangModules() const {
38681c3bbb01SEd Maste   const uint32_t idx = ePropertyAutoImportClangModules;
3869435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsBoolean(
3870435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value != 0);
38711c3bbb01SEd Maste }
38721c3bbb01SEd Maste 
GetEnableAutoApplyFixIts() const3873435933ddSDimitry Andric bool TargetProperties::GetEnableAutoApplyFixIts() const {
38744bb0738eSEd Maste   const uint32_t idx = ePropertyAutoApplyFixIts;
3875435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsBoolean(
3876435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value != 0);
38774bb0738eSEd Maste }
38784bb0738eSEd Maste 
GetEnableNotifyAboutFixIts() const3879435933ddSDimitry Andric bool TargetProperties::GetEnableNotifyAboutFixIts() const {
38804bb0738eSEd Maste   const uint32_t idx = ePropertyNotifyAboutFixIts;
3881435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsBoolean(
3882435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value != 0);
38834bb0738eSEd Maste }
38844bb0738eSEd Maste 
GetEnableSaveObjects() const3885435933ddSDimitry Andric bool TargetProperties::GetEnableSaveObjects() const {
3886435933ddSDimitry Andric   const uint32_t idx = ePropertySaveObjects;
3887435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsBoolean(
3888435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value != 0);
3889435933ddSDimitry Andric }
3890435933ddSDimitry Andric 
GetEnableSyntheticValue() const3891435933ddSDimitry Andric bool TargetProperties::GetEnableSyntheticValue() const {
3892ac7ddfbfSEd Maste   const uint32_t idx = ePropertyEnableSynthetic;
3893435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsBoolean(
3894435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value != 0);
3895ac7ddfbfSEd Maste }
3896ac7ddfbfSEd Maste 
GetMaximumNumberOfChildrenToDisplay() const3897435933ddSDimitry Andric uint32_t TargetProperties::GetMaximumNumberOfChildrenToDisplay() const {
3898ac7ddfbfSEd Maste   const uint32_t idx = ePropertyMaxChildrenCount;
3899435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsSInt64(
3900435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value);
3901ac7ddfbfSEd Maste }
3902ac7ddfbfSEd Maste 
GetMaximumSizeOfStringSummary() const3903435933ddSDimitry Andric uint32_t TargetProperties::GetMaximumSizeOfStringSummary() const {
3904ac7ddfbfSEd Maste   const uint32_t idx = ePropertyMaxSummaryLength;
3905435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsSInt64(
3906435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value);
3907ac7ddfbfSEd Maste }
3908ac7ddfbfSEd Maste 
GetMaximumMemReadSize() const3909435933ddSDimitry Andric uint32_t TargetProperties::GetMaximumMemReadSize() const {
3910ac7ddfbfSEd Maste   const uint32_t idx = ePropertyMaxMemReadSize;
3911435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsSInt64(
3912435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value);
3913ac7ddfbfSEd Maste }
3914ac7ddfbfSEd Maste 
GetStandardInputPath() const3915435933ddSDimitry Andric FileSpec TargetProperties::GetStandardInputPath() const {
3916ac7ddfbfSEd Maste   const uint32_t idx = ePropertyInputPath;
39179f2f44ceSEd Maste   return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr, idx);
3918ac7ddfbfSEd Maste }
3919ac7ddfbfSEd Maste 
SetStandardInputPath(llvm::StringRef path)3920435933ddSDimitry Andric void TargetProperties::SetStandardInputPath(llvm::StringRef path) {
3921ac7ddfbfSEd Maste   const uint32_t idx = ePropertyInputPath;
3922435933ddSDimitry Andric   m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, path);
3923ac7ddfbfSEd Maste }
3924ac7ddfbfSEd Maste 
GetStandardOutputPath() const3925435933ddSDimitry Andric FileSpec TargetProperties::GetStandardOutputPath() const {
3926ac7ddfbfSEd Maste   const uint32_t idx = ePropertyOutputPath;
39279f2f44ceSEd Maste   return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr, idx);
3928ac7ddfbfSEd Maste }
3929ac7ddfbfSEd Maste 
SetStandardOutputPath(llvm::StringRef path)3930435933ddSDimitry Andric void TargetProperties::SetStandardOutputPath(llvm::StringRef path) {
3931ac7ddfbfSEd Maste   const uint32_t idx = ePropertyOutputPath;
3932435933ddSDimitry Andric   m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, path);
3933ac7ddfbfSEd Maste }
3934ac7ddfbfSEd Maste 
GetStandardErrorPath() const3935435933ddSDimitry Andric FileSpec TargetProperties::GetStandardErrorPath() const {
3936ac7ddfbfSEd Maste   const uint32_t idx = ePropertyErrorPath;
39379f2f44ceSEd Maste   return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr, idx);
39389f2f44ceSEd Maste }
39399f2f44ceSEd Maste 
SetStandardErrorPath(llvm::StringRef path)3940435933ddSDimitry Andric void TargetProperties::SetStandardErrorPath(llvm::StringRef path) {
3941435933ddSDimitry Andric   const uint32_t idx = ePropertyErrorPath;
3942435933ddSDimitry Andric   m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, path);
3943435933ddSDimitry Andric }
3944435933ddSDimitry Andric 
GetLanguage() const3945435933ddSDimitry Andric LanguageType TargetProperties::GetLanguage() const {
3946435933ddSDimitry Andric   OptionValueLanguage *value =
3947435933ddSDimitry Andric       m_collection_sp->GetPropertyAtIndexAsOptionValueLanguage(
3948435933ddSDimitry Andric           nullptr, ePropertyLanguage);
39499f2f44ceSEd Maste   if (value)
39509f2f44ceSEd Maste     return value->GetCurrentValue();
39519f2f44ceSEd Maste   return LanguageType();
3952ac7ddfbfSEd Maste }
3953ac7ddfbfSEd Maste 
GetExpressionPrefixContents()395438638513SDimitry Andric llvm::StringRef TargetProperties::GetExpressionPrefixContents() {
3955ac7ddfbfSEd Maste   const uint32_t idx = ePropertyExprPrefix;
3956435933ddSDimitry Andric   OptionValueFileSpec *file =
3957435933ddSDimitry Andric       m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpec(nullptr, false,
3958435933ddSDimitry Andric                                                                idx);
3959435933ddSDimitry Andric   if (file) {
396038638513SDimitry Andric     DataBufferSP data_sp(file->GetFileContents());
3961ac7ddfbfSEd Maste     if (data_sp)
396238638513SDimitry Andric       return llvm::StringRef(
396338638513SDimitry Andric           reinterpret_cast<const char *>(data_sp->GetBytes()),
396438638513SDimitry Andric           data_sp->GetByteSize());
3965ac7ddfbfSEd Maste   }
396638638513SDimitry Andric   return "";
3967ac7ddfbfSEd Maste }
3968ac7ddfbfSEd Maste 
GetBreakpointsConsultPlatformAvoidList()3969435933ddSDimitry Andric bool TargetProperties::GetBreakpointsConsultPlatformAvoidList() {
3970ac7ddfbfSEd Maste   const uint32_t idx = ePropertyBreakpointUseAvoidList;
3971435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsBoolean(
3972435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value != 0);
3973ac7ddfbfSEd Maste }
3974ac7ddfbfSEd Maste 
GetUseHexImmediates() const3975435933ddSDimitry Andric bool TargetProperties::GetUseHexImmediates() const {
3976ac7ddfbfSEd Maste   const uint32_t idx = ePropertyUseHexImmediates;
3977435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsBoolean(
3978435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value != 0);
3979ac7ddfbfSEd Maste }
3980ac7ddfbfSEd Maste 
GetUseFastStepping() const3981435933ddSDimitry Andric bool TargetProperties::GetUseFastStepping() const {
3982ac7ddfbfSEd Maste   const uint32_t idx = ePropertyUseFastStepping;
3983435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsBoolean(
3984435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value != 0);
3985ac7ddfbfSEd Maste }
3986ac7ddfbfSEd Maste 
GetDisplayExpressionsInCrashlogs() const3987435933ddSDimitry Andric bool TargetProperties::GetDisplayExpressionsInCrashlogs() const {
398812b93ac6SEd Maste   const uint32_t idx = ePropertyDisplayExpressionsInCrashlogs;
3989435933ddSDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsBoolean(
3990435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value != 0);
399112b93ac6SEd Maste }
399212b93ac6SEd Maste 
GetLoadScriptFromSymbolFile() const3993435933ddSDimitry Andric LoadScriptFromSymFile TargetProperties::GetLoadScriptFromSymbolFile() const {
3994ac7ddfbfSEd Maste   const uint32_t idx = ePropertyLoadScriptFromSymbolFile;
3995435933ddSDimitry Andric   return (LoadScriptFromSymFile)
3996435933ddSDimitry Andric       m_collection_sp->GetPropertyAtIndexAsEnumeration(
3997435933ddSDimitry Andric           nullptr, idx, g_properties[idx].default_uint_value);
3998ac7ddfbfSEd Maste }
3999ac7ddfbfSEd Maste 
GetLoadCWDlldbinitFile() const4000435933ddSDimitry Andric LoadCWDlldbinitFile TargetProperties::GetLoadCWDlldbinitFile() const {
40014bb0738eSEd Maste   const uint32_t idx = ePropertyLoadCWDlldbinitFile;
4002435933ddSDimitry Andric   return (LoadCWDlldbinitFile)m_collection_sp->GetPropertyAtIndexAsEnumeration(
4003435933ddSDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value);
40044bb0738eSEd Maste }
40054bb0738eSEd Maste 
GetHexImmediateStyle() const4006435933ddSDimitry Andric Disassembler::HexImmediateStyle TargetProperties::GetHexImmediateStyle() const {
4007ac7ddfbfSEd Maste   const uint32_t idx = ePropertyHexImmediateStyle;
4008435933ddSDimitry Andric   return (Disassembler::HexImmediateStyle)
4009435933ddSDimitry Andric       m_collection_sp->GetPropertyAtIndexAsEnumeration(
4010435933ddSDimitry Andric           nullptr, idx, g_properties[idx].default_uint_value);
4011ac7ddfbfSEd Maste }
4012ac7ddfbfSEd Maste 
GetMemoryModuleLoadLevel() const4013435933ddSDimitry Andric MemoryModuleLoadLevel TargetProperties::GetMemoryModuleLoadLevel() const {
4014ac7ddfbfSEd Maste   const uint32_t idx = ePropertyMemoryModuleLoadLevel;
4015435933ddSDimitry Andric   return (MemoryModuleLoadLevel)
4016435933ddSDimitry Andric       m_collection_sp->GetPropertyAtIndexAsEnumeration(
4017435933ddSDimitry Andric           nullptr, idx, g_properties[idx].default_uint_value);
4018ac7ddfbfSEd Maste }
4019ac7ddfbfSEd Maste 
GetUserSpecifiedTrapHandlerNames(Args & args) const4020435933ddSDimitry Andric bool TargetProperties::GetUserSpecifiedTrapHandlerNames(Args &args) const {
402112b93ac6SEd Maste   const uint32_t idx = ePropertyTrapHandlerNames;
40229f2f44ceSEd Maste   return m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, idx, args);
402312b93ac6SEd Maste }
4024ac7ddfbfSEd Maste 
SetUserSpecifiedTrapHandlerNames(const Args & args)4025435933ddSDimitry Andric void TargetProperties::SetUserSpecifiedTrapHandlerNames(const Args &args) {
402612b93ac6SEd Maste   const uint32_t idx = ePropertyTrapHandlerNames;
40279f2f44ceSEd Maste   m_collection_sp->SetPropertyAtIndexFromArgs(nullptr, idx, args);
402812b93ac6SEd Maste }
4029ac7ddfbfSEd Maste 
GetDisplayRuntimeSupportValues() const4030435933ddSDimitry Andric bool TargetProperties::GetDisplayRuntimeSupportValues() const {
40311c3bbb01SEd Maste   const uint32_t idx = ePropertyDisplayRuntimeSupportValues;
40329f2f44ceSEd Maste   return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, false);
40331c3bbb01SEd Maste }
40341c3bbb01SEd Maste 
SetDisplayRuntimeSupportValues(bool b)4035435933ddSDimitry Andric void TargetProperties::SetDisplayRuntimeSupportValues(bool b) {
40361c3bbb01SEd Maste   const uint32_t idx = ePropertyDisplayRuntimeSupportValues;
40379f2f44ceSEd Maste   m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
40381c3bbb01SEd Maste }
40391c3bbb01SEd Maste 
GetDisplayRecognizedArguments() const4040*b5893f02SDimitry Andric bool TargetProperties::GetDisplayRecognizedArguments() const {
4041*b5893f02SDimitry Andric   const uint32_t idx = ePropertyDisplayRecognizedArguments;
4042*b5893f02SDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, false);
4043*b5893f02SDimitry Andric }
4044*b5893f02SDimitry Andric 
SetDisplayRecognizedArguments(bool b)4045*b5893f02SDimitry Andric void TargetProperties::SetDisplayRecognizedArguments(bool b) {
4046*b5893f02SDimitry Andric   const uint32_t idx = ePropertyDisplayRecognizedArguments;
4047*b5893f02SDimitry Andric   m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
4048*b5893f02SDimitry Andric }
4049*b5893f02SDimitry Andric 
GetNonStopModeEnabled() const4050435933ddSDimitry Andric bool TargetProperties::GetNonStopModeEnabled() const {
40511c3bbb01SEd Maste   const uint32_t idx = ePropertyNonStopModeEnabled;
40529f2f44ceSEd Maste   return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, false);
40531c3bbb01SEd Maste }
40541c3bbb01SEd Maste 
SetNonStopModeEnabled(bool b)4055435933ddSDimitry Andric void TargetProperties::SetNonStopModeEnabled(bool b) {
40561c3bbb01SEd Maste   const uint32_t idx = ePropertyNonStopModeEnabled;
40579f2f44ceSEd Maste   m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
40581c3bbb01SEd Maste }
40591c3bbb01SEd Maste 
GetProcessLaunchInfo()4060435933ddSDimitry Andric const ProcessLaunchInfo &TargetProperties::GetProcessLaunchInfo() {
40611c3bbb01SEd Maste   m_launch_info.SetArg0(GetArg0()); // FIXME: Arg0 callback doesn't work
40621c3bbb01SEd Maste   return m_launch_info;
40631c3bbb01SEd Maste }
40641c3bbb01SEd Maste 
SetProcessLaunchInfo(const ProcessLaunchInfo & launch_info)4065435933ddSDimitry Andric void TargetProperties::SetProcessLaunchInfo(
4066435933ddSDimitry Andric     const ProcessLaunchInfo &launch_info) {
40671c3bbb01SEd Maste   m_launch_info = launch_info;
40681c3bbb01SEd Maste   SetArg0(launch_info.GetArg0());
40691c3bbb01SEd Maste   SetRunArguments(launch_info.GetArguments());
40704ba319b5SDimitry Andric   SetEnvironment(launch_info.GetEnvironment());
4071435933ddSDimitry Andric   const FileAction *input_file_action =
4072435933ddSDimitry Andric       launch_info.GetFileActionForFD(STDIN_FILENO);
4073435933ddSDimitry Andric   if (input_file_action) {
4074435933ddSDimitry Andric     SetStandardInputPath(input_file_action->GetPath());
40751c3bbb01SEd Maste   }
4076435933ddSDimitry Andric   const FileAction *output_file_action =
4077435933ddSDimitry Andric       launch_info.GetFileActionForFD(STDOUT_FILENO);
4078435933ddSDimitry Andric   if (output_file_action) {
4079435933ddSDimitry Andric     SetStandardOutputPath(output_file_action->GetPath());
40801c3bbb01SEd Maste   }
4081435933ddSDimitry Andric   const FileAction *error_file_action =
4082435933ddSDimitry Andric       launch_info.GetFileActionForFD(STDERR_FILENO);
4083435933ddSDimitry Andric   if (error_file_action) {
4084435933ddSDimitry Andric     SetStandardErrorPath(error_file_action->GetPath());
40851c3bbb01SEd Maste   }
40861c3bbb01SEd Maste   SetDetachOnError(launch_info.GetFlags().Test(lldb::eLaunchFlagDetachOnError));
40871c3bbb01SEd Maste   SetDisableASLR(launch_info.GetFlags().Test(lldb::eLaunchFlagDisableASLR));
40881c3bbb01SEd Maste   SetDisableSTDIO(launch_info.GetFlags().Test(lldb::eLaunchFlagDisableSTDIO));
40891c3bbb01SEd Maste }
40901c3bbb01SEd Maste 
GetRequireHardwareBreakpoints() const4091*b5893f02SDimitry Andric bool TargetProperties::GetRequireHardwareBreakpoints() const {
4092*b5893f02SDimitry Andric   const uint32_t idx = ePropertyRequireHardwareBreakpoints;
4093*b5893f02SDimitry Andric   return m_collection_sp->GetPropertyAtIndexAsBoolean(
4094*b5893f02SDimitry Andric       nullptr, idx, g_properties[idx].default_uint_value != 0);
4095*b5893f02SDimitry Andric }
4096*b5893f02SDimitry Andric 
SetRequireHardwareBreakpoints(bool b)4097*b5893f02SDimitry Andric void TargetProperties::SetRequireHardwareBreakpoints(bool b) {
4098*b5893f02SDimitry Andric   const uint32_t idx = ePropertyRequireHardwareBreakpoints;
4099*b5893f02SDimitry Andric   m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
4100*b5893f02SDimitry Andric }
4101*b5893f02SDimitry Andric 
Arg0ValueChangedCallback(void * target_property_ptr,OptionValue *)4102435933ddSDimitry Andric void TargetProperties::Arg0ValueChangedCallback(void *target_property_ptr,
4103435933ddSDimitry Andric                                                 OptionValue *) {
4104435933ddSDimitry Andric   TargetProperties *this_ =
4105435933ddSDimitry Andric       reinterpret_cast<TargetProperties *>(target_property_ptr);
41061c3bbb01SEd Maste   this_->m_launch_info.SetArg0(this_->GetArg0());
41071c3bbb01SEd Maste }
41081c3bbb01SEd Maste 
RunArgsValueChangedCallback(void * target_property_ptr,OptionValue *)4109435933ddSDimitry Andric void TargetProperties::RunArgsValueChangedCallback(void *target_property_ptr,
4110435933ddSDimitry Andric                                                    OptionValue *) {
4111435933ddSDimitry Andric   TargetProperties *this_ =
4112435933ddSDimitry Andric       reinterpret_cast<TargetProperties *>(target_property_ptr);
41131c3bbb01SEd Maste   Args args;
41141c3bbb01SEd Maste   if (this_->GetRunArguments(args))
41151c3bbb01SEd Maste     this_->m_launch_info.GetArguments() = args;
41161c3bbb01SEd Maste }
41171c3bbb01SEd Maste 
EnvVarsValueChangedCallback(void * target_property_ptr,OptionValue *)4118435933ddSDimitry Andric void TargetProperties::EnvVarsValueChangedCallback(void *target_property_ptr,
4119435933ddSDimitry Andric                                                    OptionValue *) {
4120435933ddSDimitry Andric   TargetProperties *this_ =
4121435933ddSDimitry Andric       reinterpret_cast<TargetProperties *>(target_property_ptr);
41224ba319b5SDimitry Andric   this_->m_launch_info.GetEnvironment() = this_->GetEnvironment();
41231c3bbb01SEd Maste }
41241c3bbb01SEd Maste 
InputPathValueChangedCallback(void * target_property_ptr,OptionValue *)4125435933ddSDimitry Andric void TargetProperties::InputPathValueChangedCallback(void *target_property_ptr,
4126435933ddSDimitry Andric                                                      OptionValue *) {
4127435933ddSDimitry Andric   TargetProperties *this_ =
4128435933ddSDimitry Andric       reinterpret_cast<TargetProperties *>(target_property_ptr);
4129435933ddSDimitry Andric   this_->m_launch_info.AppendOpenFileAction(
4130435933ddSDimitry Andric       STDIN_FILENO, this_->GetStandardInputPath(), true, false);
41311c3bbb01SEd Maste }
41321c3bbb01SEd Maste 
OutputPathValueChangedCallback(void * target_property_ptr,OptionValue *)4133435933ddSDimitry Andric void TargetProperties::OutputPathValueChangedCallback(void *target_property_ptr,
4134435933ddSDimitry Andric                                                       OptionValue *) {
4135435933ddSDimitry Andric   TargetProperties *this_ =
4136435933ddSDimitry Andric       reinterpret_cast<TargetProperties *>(target_property_ptr);
4137435933ddSDimitry Andric   this_->m_launch_info.AppendOpenFileAction(
4138435933ddSDimitry Andric       STDOUT_FILENO, this_->GetStandardOutputPath(), false, true);
41391c3bbb01SEd Maste }
41401c3bbb01SEd Maste 
ErrorPathValueChangedCallback(void * target_property_ptr,OptionValue *)4141435933ddSDimitry Andric void TargetProperties::ErrorPathValueChangedCallback(void *target_property_ptr,
4142435933ddSDimitry Andric                                                      OptionValue *) {
4143435933ddSDimitry Andric   TargetProperties *this_ =
4144435933ddSDimitry Andric       reinterpret_cast<TargetProperties *>(target_property_ptr);
4145435933ddSDimitry Andric   this_->m_launch_info.AppendOpenFileAction(
4146435933ddSDimitry Andric       STDERR_FILENO, this_->GetStandardErrorPath(), false, true);
41471c3bbb01SEd Maste }
41481c3bbb01SEd Maste 
DetachOnErrorValueChangedCallback(void * target_property_ptr,OptionValue *)4149435933ddSDimitry Andric void TargetProperties::DetachOnErrorValueChangedCallback(
4150435933ddSDimitry Andric     void *target_property_ptr, OptionValue *) {
4151435933ddSDimitry Andric   TargetProperties *this_ =
4152435933ddSDimitry Andric       reinterpret_cast<TargetProperties *>(target_property_ptr);
41531c3bbb01SEd Maste   if (this_->GetDetachOnError())
41541c3bbb01SEd Maste     this_->m_launch_info.GetFlags().Set(lldb::eLaunchFlagDetachOnError);
41551c3bbb01SEd Maste   else
41561c3bbb01SEd Maste     this_->m_launch_info.GetFlags().Clear(lldb::eLaunchFlagDetachOnError);
41571c3bbb01SEd Maste }
41581c3bbb01SEd Maste 
DisableASLRValueChangedCallback(void * target_property_ptr,OptionValue *)4159435933ddSDimitry Andric void TargetProperties::DisableASLRValueChangedCallback(
4160435933ddSDimitry Andric     void *target_property_ptr, OptionValue *) {
4161435933ddSDimitry Andric   TargetProperties *this_ =
4162435933ddSDimitry Andric       reinterpret_cast<TargetProperties *>(target_property_ptr);
41631c3bbb01SEd Maste   if (this_->GetDisableASLR())
41641c3bbb01SEd Maste     this_->m_launch_info.GetFlags().Set(lldb::eLaunchFlagDisableASLR);
41651c3bbb01SEd Maste   else
41661c3bbb01SEd Maste     this_->m_launch_info.GetFlags().Clear(lldb::eLaunchFlagDisableASLR);
41671c3bbb01SEd Maste }
41681c3bbb01SEd Maste 
DisableSTDIOValueChangedCallback(void * target_property_ptr,OptionValue *)4169435933ddSDimitry Andric void TargetProperties::DisableSTDIOValueChangedCallback(
4170435933ddSDimitry Andric     void *target_property_ptr, OptionValue *) {
4171435933ddSDimitry Andric   TargetProperties *this_ =
4172435933ddSDimitry Andric       reinterpret_cast<TargetProperties *>(target_property_ptr);
41731c3bbb01SEd Maste   if (this_->GetDisableSTDIO())
41741c3bbb01SEd Maste     this_->m_launch_info.GetFlags().Set(lldb::eLaunchFlagDisableSTDIO);
41751c3bbb01SEd Maste   else
41761c3bbb01SEd Maste     this_->m_launch_info.GetFlags().Clear(lldb::eLaunchFlagDisableSTDIO);
41771c3bbb01SEd Maste }
41781c3bbb01SEd Maste 
4179b952cd58SEd Maste //----------------------------------------------------------------------
4180b952cd58SEd Maste // Target::TargetEventData
4181b952cd58SEd Maste //----------------------------------------------------------------------
41821c3bbb01SEd Maste 
TargetEventData(const lldb::TargetSP & target_sp)4183435933ddSDimitry Andric Target::TargetEventData::TargetEventData(const lldb::TargetSP &target_sp)
4184435933ddSDimitry Andric     : EventData(), m_target_sp(target_sp), m_module_list() {}
41851c3bbb01SEd Maste 
TargetEventData(const lldb::TargetSP & target_sp,const ModuleList & module_list)4186435933ddSDimitry Andric Target::TargetEventData::TargetEventData(const lldb::TargetSP &target_sp,
4187435933ddSDimitry Andric                                          const ModuleList &module_list)
4188435933ddSDimitry Andric     : EventData(), m_target_sp(target_sp), m_module_list(module_list) {}
41891c3bbb01SEd Maste 
41909f2f44ceSEd Maste Target::TargetEventData::~TargetEventData() = default;
41911c3bbb01SEd Maste 
GetFlavorString()4192435933ddSDimitry Andric const ConstString &Target::TargetEventData::GetFlavorString() {
4193ac7ddfbfSEd Maste   static ConstString g_flavor("Target::TargetEventData");
4194ac7ddfbfSEd Maste   return g_flavor;
4195ac7ddfbfSEd Maste }
4196ac7ddfbfSEd Maste 
Dump(Stream * s) const4197435933ddSDimitry Andric void Target::TargetEventData::Dump(Stream *s) const {
4198435933ddSDimitry Andric   for (size_t i = 0; i < m_module_list.GetSize(); ++i) {
41994bb0738eSEd Maste     if (i != 0)
42004bb0738eSEd Maste       *s << ", ";
4201435933ddSDimitry Andric     m_module_list.GetModuleAtIndex(i)->GetDescription(
4202435933ddSDimitry Andric         s, lldb::eDescriptionLevelBrief);
42034bb0738eSEd Maste   }
4204ac7ddfbfSEd Maste }
4205ac7ddfbfSEd Maste 
4206ac7ddfbfSEd Maste const Target::TargetEventData *
GetEventDataFromEvent(const Event * event_ptr)4207435933ddSDimitry Andric Target::TargetEventData::GetEventDataFromEvent(const Event *event_ptr) {
4208435933ddSDimitry Andric   if (event_ptr) {
4209ac7ddfbfSEd Maste     const EventData *event_data = event_ptr->GetData();
4210435933ddSDimitry Andric     if (event_data &&
4211435933ddSDimitry Andric         event_data->GetFlavor() == TargetEventData::GetFlavorString())
4212ac7ddfbfSEd Maste       return static_cast<const TargetEventData *>(event_ptr->GetData());
4213ac7ddfbfSEd Maste   }
42149f2f44ceSEd Maste   return nullptr;
4215ac7ddfbfSEd Maste }
4216ac7ddfbfSEd Maste 
GetTargetFromEvent(const Event * event_ptr)4217435933ddSDimitry Andric TargetSP Target::TargetEventData::GetTargetFromEvent(const Event *event_ptr) {
42181c3bbb01SEd Maste   TargetSP target_sp;
42191c3bbb01SEd Maste   const TargetEventData *event_data = GetEventDataFromEvent(event_ptr);
42201c3bbb01SEd Maste   if (event_data)
42211c3bbb01SEd Maste     target_sp = event_data->m_target_sp;
42221c3bbb01SEd Maste   return target_sp;
42231c3bbb01SEd Maste }
42241c3bbb01SEd Maste 
42251c3bbb01SEd Maste ModuleList
GetModuleListFromEvent(const Event * event_ptr)4226435933ddSDimitry Andric Target::TargetEventData::GetModuleListFromEvent(const Event *event_ptr) {
42271c3bbb01SEd Maste   ModuleList module_list;
42281c3bbb01SEd Maste   const TargetEventData *event_data = GetEventDataFromEvent(event_ptr);
42291c3bbb01SEd Maste   if (event_data)
42301c3bbb01SEd Maste     module_list = event_data->m_module_list;
42311c3bbb01SEd Maste   return module_list;
42321c3bbb01SEd Maste }
4233