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 §ion_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 §ion_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 §ion_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 §ion_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 §ion_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