15ffd83dbSDimitry Andric //===-- Target.cpp --------------------------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "lldb/Target/Target.h" 100b57cec5SDimitry Andric #include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h" 110b57cec5SDimitry Andric #include "lldb/Breakpoint/BreakpointIDList.h" 120b57cec5SDimitry Andric #include "lldb/Breakpoint/BreakpointPrecondition.h" 130b57cec5SDimitry Andric #include "lldb/Breakpoint/BreakpointResolver.h" 140b57cec5SDimitry Andric #include "lldb/Breakpoint/BreakpointResolverAddress.h" 150b57cec5SDimitry Andric #include "lldb/Breakpoint/BreakpointResolverFileLine.h" 160b57cec5SDimitry Andric #include "lldb/Breakpoint/BreakpointResolverFileRegex.h" 170b57cec5SDimitry Andric #include "lldb/Breakpoint/BreakpointResolverName.h" 180b57cec5SDimitry Andric #include "lldb/Breakpoint/BreakpointResolverScripted.h" 190b57cec5SDimitry Andric #include "lldb/Breakpoint/Watchpoint.h" 200b57cec5SDimitry Andric #include "lldb/Core/Debugger.h" 210b57cec5SDimitry Andric #include "lldb/Core/Module.h" 220b57cec5SDimitry Andric #include "lldb/Core/ModuleSpec.h" 230b57cec5SDimitry Andric #include "lldb/Core/PluginManager.h" 240b57cec5SDimitry Andric #include "lldb/Core/SearchFilter.h" 250b57cec5SDimitry Andric #include "lldb/Core/Section.h" 260b57cec5SDimitry Andric #include "lldb/Core/SourceManager.h" 270b57cec5SDimitry Andric #include "lldb/Core/StreamFile.h" 280b57cec5SDimitry Andric #include "lldb/Core/StructuredDataImpl.h" 290b57cec5SDimitry Andric #include "lldb/Core/ValueObject.h" 305ffd83dbSDimitry Andric #include "lldb/Expression/ExpressionVariable.h" 310b57cec5SDimitry Andric #include "lldb/Expression/REPL.h" 320b57cec5SDimitry Andric #include "lldb/Expression/UserExpression.h" 330b57cec5SDimitry Andric #include "lldb/Host/Host.h" 340b57cec5SDimitry Andric #include "lldb/Host/PosixApi.h" 350b57cec5SDimitry Andric #include "lldb/Interpreter/CommandInterpreter.h" 360b57cec5SDimitry Andric #include "lldb/Interpreter/CommandReturnObject.h" 370b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupWatchpoint.h" 380b57cec5SDimitry Andric #include "lldb/Interpreter/OptionValues.h" 390b57cec5SDimitry Andric #include "lldb/Interpreter/Property.h" 400b57cec5SDimitry Andric #include "lldb/Symbol/Function.h" 410b57cec5SDimitry Andric #include "lldb/Symbol/ObjectFile.h" 420b57cec5SDimitry Andric #include "lldb/Symbol/Symbol.h" 430b57cec5SDimitry Andric #include "lldb/Target/Language.h" 440b57cec5SDimitry Andric #include "lldb/Target/LanguageRuntime.h" 450b57cec5SDimitry Andric #include "lldb/Target/Process.h" 460b57cec5SDimitry Andric #include "lldb/Target/SectionLoadList.h" 470b57cec5SDimitry Andric #include "lldb/Target/StackFrame.h" 480b57cec5SDimitry Andric #include "lldb/Target/SystemRuntime.h" 490b57cec5SDimitry Andric #include "lldb/Target/Thread.h" 500b57cec5SDimitry Andric #include "lldb/Target/ThreadSpec.h" 510b57cec5SDimitry Andric #include "lldb/Utility/Event.h" 520b57cec5SDimitry Andric #include "lldb/Utility/FileSpec.h" 530b57cec5SDimitry Andric #include "lldb/Utility/LLDBAssert.h" 540b57cec5SDimitry Andric #include "lldb/Utility/Log.h" 550b57cec5SDimitry Andric #include "lldb/Utility/State.h" 560b57cec5SDimitry Andric #include "lldb/Utility/StreamString.h" 570b57cec5SDimitry Andric #include "lldb/Utility/Timer.h" 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric #include "llvm/ADT/ScopeExit.h" 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric #include <memory> 620b57cec5SDimitry Andric #include <mutex> 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric using namespace lldb; 650b57cec5SDimitry Andric using namespace lldb_private; 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric constexpr std::chrono::milliseconds EvaluateExpressionOptions::default_timeout; 680b57cec5SDimitry Andric 690b57cec5SDimitry Andric Target::Arch::Arch(const ArchSpec &spec) 700b57cec5SDimitry Andric : m_spec(spec), 710b57cec5SDimitry Andric m_plugin_up(PluginManager::CreateArchitectureInstance(spec)) {} 720b57cec5SDimitry Andric 730b57cec5SDimitry Andric const Target::Arch &Target::Arch::operator=(const ArchSpec &spec) { 740b57cec5SDimitry Andric m_spec = spec; 750b57cec5SDimitry Andric m_plugin_up = PluginManager::CreateArchitectureInstance(spec); 760b57cec5SDimitry Andric return *this; 770b57cec5SDimitry Andric } 780b57cec5SDimitry Andric 790b57cec5SDimitry Andric ConstString &Target::GetStaticBroadcasterClass() { 800b57cec5SDimitry Andric static ConstString class_name("lldb.target"); 810b57cec5SDimitry Andric return class_name; 820b57cec5SDimitry Andric } 830b57cec5SDimitry Andric 840b57cec5SDimitry Andric Target::Target(Debugger &debugger, const ArchSpec &target_arch, 850b57cec5SDimitry Andric const lldb::PlatformSP &platform_sp, bool is_dummy_target) 860b57cec5SDimitry Andric : TargetProperties(this), 870b57cec5SDimitry Andric Broadcaster(debugger.GetBroadcasterManager(), 880b57cec5SDimitry Andric Target::GetStaticBroadcasterClass().AsCString()), 890b57cec5SDimitry Andric ExecutionContextScope(), m_debugger(debugger), m_platform_sp(platform_sp), 900b57cec5SDimitry Andric m_mutex(), m_arch(target_arch), m_images(this), m_section_load_history(), 910b57cec5SDimitry Andric m_breakpoint_list(false), m_internal_breakpoint_list(true), 920b57cec5SDimitry Andric m_watchpoint_list(), m_process_sp(), m_search_filter_sp(), 935ffd83dbSDimitry Andric m_image_search_paths(ImageSearchPathsChanged, this), 940b57cec5SDimitry Andric m_source_manager_up(), m_stop_hooks(), m_stop_hook_next_id(0), 950b57cec5SDimitry Andric m_valid(true), m_suppress_stop_hooks(false), 960b57cec5SDimitry Andric m_is_dummy_target(is_dummy_target), 970b57cec5SDimitry Andric m_stats_storage(static_cast<int>(StatisticKind::StatisticMax)) 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric { 1000b57cec5SDimitry Andric SetEventName(eBroadcastBitBreakpointChanged, "breakpoint-changed"); 1010b57cec5SDimitry Andric SetEventName(eBroadcastBitModulesLoaded, "modules-loaded"); 1020b57cec5SDimitry Andric SetEventName(eBroadcastBitModulesUnloaded, "modules-unloaded"); 1030b57cec5SDimitry Andric SetEventName(eBroadcastBitWatchpointChanged, "watchpoint-changed"); 1040b57cec5SDimitry Andric SetEventName(eBroadcastBitSymbolsLoaded, "symbols-loaded"); 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andric CheckInWithManager(); 1070b57cec5SDimitry Andric 1089dba64beSDimitry Andric LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT), 1099dba64beSDimitry Andric "{0} Target::Target()", static_cast<void *>(this)); 1100b57cec5SDimitry Andric if (target_arch.IsValid()) { 1119dba64beSDimitry Andric LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET), 1129dba64beSDimitry Andric "Target::Target created with architecture {0} ({1})", 1130b57cec5SDimitry Andric target_arch.GetArchitectureName(), 1140b57cec5SDimitry Andric target_arch.GetTriple().getTriple().c_str()); 1150b57cec5SDimitry Andric } 1165ffd83dbSDimitry Andric 1175ffd83dbSDimitry Andric UpdateLaunchInfoFromProperties(); 1180b57cec5SDimitry Andric } 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric Target::~Target() { 1210b57cec5SDimitry Andric Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); 1229dba64beSDimitry Andric LLDB_LOG(log, "{0} Target::~Target()", static_cast<void *>(this)); 1230b57cec5SDimitry Andric DeleteCurrentProcess(); 1240b57cec5SDimitry Andric } 1250b57cec5SDimitry Andric 1260b57cec5SDimitry Andric void Target::PrimeFromDummyTarget(Target *target) { 1270b57cec5SDimitry Andric if (!target) 1280b57cec5SDimitry Andric return; 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric m_stop_hooks = target->m_stop_hooks; 1310b57cec5SDimitry Andric 1325ffd83dbSDimitry Andric for (const auto &breakpoint_sp : target->m_breakpoint_list.Breakpoints()) { 1330b57cec5SDimitry Andric if (breakpoint_sp->IsInternal()) 1340b57cec5SDimitry Andric continue; 1350b57cec5SDimitry Andric 1365ffd83dbSDimitry Andric BreakpointSP new_bp( 1375ffd83dbSDimitry Andric Breakpoint::CopyFromBreakpoint(shared_from_this(), *breakpoint_sp)); 1385ffd83dbSDimitry Andric AddBreakpoint(std::move(new_bp), false); 1390b57cec5SDimitry Andric } 1400b57cec5SDimitry Andric 1419dba64beSDimitry Andric for (auto bp_name_entry : target->m_breakpoint_names) { 1420b57cec5SDimitry Andric 1430b57cec5SDimitry Andric BreakpointName *new_bp_name = new BreakpointName(*bp_name_entry.second); 1440b57cec5SDimitry Andric AddBreakpointName(new_bp_name); 1450b57cec5SDimitry Andric } 1460b57cec5SDimitry Andric } 1470b57cec5SDimitry Andric 1480b57cec5SDimitry Andric void Target::Dump(Stream *s, lldb::DescriptionLevel description_level) { 1490b57cec5SDimitry Andric // s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); 1500b57cec5SDimitry Andric if (description_level != lldb::eDescriptionLevelBrief) { 1510b57cec5SDimitry Andric s->Indent(); 1520b57cec5SDimitry Andric s->PutCString("Target\n"); 1530b57cec5SDimitry Andric s->IndentMore(); 1540b57cec5SDimitry Andric m_images.Dump(s); 1550b57cec5SDimitry Andric m_breakpoint_list.Dump(s); 1560b57cec5SDimitry Andric m_internal_breakpoint_list.Dump(s); 1570b57cec5SDimitry Andric s->IndentLess(); 1580b57cec5SDimitry Andric } else { 1590b57cec5SDimitry Andric Module *exe_module = GetExecutableModulePointer(); 1600b57cec5SDimitry Andric if (exe_module) 1610b57cec5SDimitry Andric s->PutCString(exe_module->GetFileSpec().GetFilename().GetCString()); 1620b57cec5SDimitry Andric else 1630b57cec5SDimitry Andric s->PutCString("No executable module."); 1640b57cec5SDimitry Andric } 1650b57cec5SDimitry Andric } 1660b57cec5SDimitry Andric 1670b57cec5SDimitry Andric void Target::CleanupProcess() { 1680b57cec5SDimitry Andric // Do any cleanup of the target we need to do between process instances. 1690b57cec5SDimitry Andric // NB It is better to do this before destroying the process in case the 1700b57cec5SDimitry Andric // clean up needs some help from the process. 1710b57cec5SDimitry Andric m_breakpoint_list.ClearAllBreakpointSites(); 1720b57cec5SDimitry Andric m_internal_breakpoint_list.ClearAllBreakpointSites(); 1730b57cec5SDimitry Andric // Disable watchpoints just on the debugger side. 1740b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 1750b57cec5SDimitry Andric this->GetWatchpointList().GetListMutex(lock); 1760b57cec5SDimitry Andric DisableAllWatchpoints(false); 1770b57cec5SDimitry Andric ClearAllWatchpointHitCounts(); 1780b57cec5SDimitry Andric ClearAllWatchpointHistoricValues(); 1790b57cec5SDimitry Andric } 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric void Target::DeleteCurrentProcess() { 1820b57cec5SDimitry Andric if (m_process_sp) { 1830b57cec5SDimitry Andric m_section_load_history.Clear(); 1840b57cec5SDimitry Andric if (m_process_sp->IsAlive()) 1850b57cec5SDimitry Andric m_process_sp->Destroy(false); 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric m_process_sp->Finalize(); 1880b57cec5SDimitry Andric 1890b57cec5SDimitry Andric CleanupProcess(); 1900b57cec5SDimitry Andric 1910b57cec5SDimitry Andric m_process_sp.reset(); 1920b57cec5SDimitry Andric } 1930b57cec5SDimitry Andric } 1940b57cec5SDimitry Andric 1950b57cec5SDimitry Andric const lldb::ProcessSP &Target::CreateProcess(ListenerSP listener_sp, 1960b57cec5SDimitry Andric llvm::StringRef plugin_name, 1970b57cec5SDimitry Andric const FileSpec *crash_file) { 1980b57cec5SDimitry Andric if (!listener_sp) 1990b57cec5SDimitry Andric listener_sp = GetDebugger().GetListener(); 2000b57cec5SDimitry Andric DeleteCurrentProcess(); 2010b57cec5SDimitry Andric m_process_sp = Process::FindPlugin(shared_from_this(), plugin_name, 2020b57cec5SDimitry Andric listener_sp, crash_file); 2030b57cec5SDimitry Andric return m_process_sp; 2040b57cec5SDimitry Andric } 2050b57cec5SDimitry Andric 2060b57cec5SDimitry Andric const lldb::ProcessSP &Target::GetProcessSP() const { return m_process_sp; } 2070b57cec5SDimitry Andric 2080b57cec5SDimitry Andric lldb::REPLSP Target::GetREPL(Status &err, lldb::LanguageType language, 2090b57cec5SDimitry Andric const char *repl_options, bool can_create) { 2100b57cec5SDimitry Andric if (language == eLanguageTypeUnknown) { 2119dba64beSDimitry Andric LanguageSet repl_languages = Language::GetLanguagesSupportingREPLs(); 2120b57cec5SDimitry Andric 2139dba64beSDimitry Andric if (auto single_lang = repl_languages.GetSingularLanguage()) { 2149dba64beSDimitry Andric language = *single_lang; 2159dba64beSDimitry Andric } else if (repl_languages.Empty()) { 2160b57cec5SDimitry Andric err.SetErrorStringWithFormat( 2170b57cec5SDimitry Andric "LLDB isn't configured with REPL support for any languages."); 2180b57cec5SDimitry Andric return REPLSP(); 2190b57cec5SDimitry Andric } else { 2200b57cec5SDimitry Andric err.SetErrorStringWithFormat( 2210b57cec5SDimitry Andric "Multiple possible REPL languages. Please specify a language."); 2220b57cec5SDimitry Andric return REPLSP(); 2230b57cec5SDimitry Andric } 2240b57cec5SDimitry Andric } 2250b57cec5SDimitry Andric 2260b57cec5SDimitry Andric REPLMap::iterator pos = m_repl_map.find(language); 2270b57cec5SDimitry Andric 2280b57cec5SDimitry Andric if (pos != m_repl_map.end()) { 2290b57cec5SDimitry Andric return pos->second; 2300b57cec5SDimitry Andric } 2310b57cec5SDimitry Andric 2320b57cec5SDimitry Andric if (!can_create) { 2330b57cec5SDimitry Andric err.SetErrorStringWithFormat( 2340b57cec5SDimitry Andric "Couldn't find an existing REPL for %s, and can't create a new one", 2350b57cec5SDimitry Andric Language::GetNameForLanguageType(language)); 2360b57cec5SDimitry Andric return lldb::REPLSP(); 2370b57cec5SDimitry Andric } 2380b57cec5SDimitry Andric 2390b57cec5SDimitry Andric Debugger *const debugger = nullptr; 2400b57cec5SDimitry Andric lldb::REPLSP ret = REPL::Create(err, language, debugger, this, repl_options); 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric if (ret) { 2430b57cec5SDimitry Andric m_repl_map[language] = ret; 2440b57cec5SDimitry Andric return m_repl_map[language]; 2450b57cec5SDimitry Andric } 2460b57cec5SDimitry Andric 2470b57cec5SDimitry Andric if (err.Success()) { 2480b57cec5SDimitry Andric err.SetErrorStringWithFormat("Couldn't create a REPL for %s", 2490b57cec5SDimitry Andric Language::GetNameForLanguageType(language)); 2500b57cec5SDimitry Andric } 2510b57cec5SDimitry Andric 2520b57cec5SDimitry Andric return lldb::REPLSP(); 2530b57cec5SDimitry Andric } 2540b57cec5SDimitry Andric 2550b57cec5SDimitry Andric void Target::SetREPL(lldb::LanguageType language, lldb::REPLSP repl_sp) { 2560b57cec5SDimitry Andric lldbassert(!m_repl_map.count(language)); 2570b57cec5SDimitry Andric 2580b57cec5SDimitry Andric m_repl_map[language] = repl_sp; 2590b57cec5SDimitry Andric } 2600b57cec5SDimitry Andric 2610b57cec5SDimitry Andric void Target::Destroy() { 2620b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(m_mutex); 2630b57cec5SDimitry Andric m_valid = false; 2640b57cec5SDimitry Andric DeleteCurrentProcess(); 2650b57cec5SDimitry Andric m_platform_sp.reset(); 2660b57cec5SDimitry Andric m_arch = ArchSpec(); 2670b57cec5SDimitry Andric ClearModules(true); 2680b57cec5SDimitry Andric m_section_load_history.Clear(); 2690b57cec5SDimitry Andric const bool notify = false; 2700b57cec5SDimitry Andric m_breakpoint_list.RemoveAll(notify); 2710b57cec5SDimitry Andric m_internal_breakpoint_list.RemoveAll(notify); 2720b57cec5SDimitry Andric m_last_created_breakpoint.reset(); 2730b57cec5SDimitry Andric m_last_created_watchpoint.reset(); 2740b57cec5SDimitry Andric m_search_filter_sp.reset(); 2750b57cec5SDimitry Andric m_image_search_paths.Clear(notify); 2760b57cec5SDimitry Andric m_stop_hooks.clear(); 2770b57cec5SDimitry Andric m_stop_hook_next_id = 0; 2780b57cec5SDimitry Andric m_suppress_stop_hooks = false; 2790b57cec5SDimitry Andric } 2800b57cec5SDimitry Andric 2810b57cec5SDimitry Andric BreakpointList &Target::GetBreakpointList(bool internal) { 2820b57cec5SDimitry Andric if (internal) 2830b57cec5SDimitry Andric return m_internal_breakpoint_list; 2840b57cec5SDimitry Andric else 2850b57cec5SDimitry Andric return m_breakpoint_list; 2860b57cec5SDimitry Andric } 2870b57cec5SDimitry Andric 2880b57cec5SDimitry Andric const BreakpointList &Target::GetBreakpointList(bool internal) const { 2890b57cec5SDimitry Andric if (internal) 2900b57cec5SDimitry Andric return m_internal_breakpoint_list; 2910b57cec5SDimitry Andric else 2920b57cec5SDimitry Andric return m_breakpoint_list; 2930b57cec5SDimitry Andric } 2940b57cec5SDimitry Andric 2950b57cec5SDimitry Andric BreakpointSP Target::GetBreakpointByID(break_id_t break_id) { 2960b57cec5SDimitry Andric BreakpointSP bp_sp; 2970b57cec5SDimitry Andric 2980b57cec5SDimitry Andric if (LLDB_BREAK_ID_IS_INTERNAL(break_id)) 2990b57cec5SDimitry Andric bp_sp = m_internal_breakpoint_list.FindBreakpointByID(break_id); 3000b57cec5SDimitry Andric else 3010b57cec5SDimitry Andric bp_sp = m_breakpoint_list.FindBreakpointByID(break_id); 3020b57cec5SDimitry Andric 3030b57cec5SDimitry Andric return bp_sp; 3040b57cec5SDimitry Andric } 3050b57cec5SDimitry Andric 3060b57cec5SDimitry Andric BreakpointSP Target::CreateSourceRegexBreakpoint( 3070b57cec5SDimitry Andric const FileSpecList *containingModules, 3080b57cec5SDimitry Andric const FileSpecList *source_file_spec_list, 3090b57cec5SDimitry Andric const std::unordered_set<std::string> &function_names, 3109dba64beSDimitry Andric RegularExpression source_regex, bool internal, bool hardware, 3110b57cec5SDimitry Andric LazyBool move_to_nearest_code) { 3120b57cec5SDimitry Andric SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList( 3130b57cec5SDimitry Andric containingModules, source_file_spec_list)); 3140b57cec5SDimitry Andric if (move_to_nearest_code == eLazyBoolCalculate) 3150b57cec5SDimitry Andric move_to_nearest_code = GetMoveToNearestCode() ? eLazyBoolYes : eLazyBoolNo; 3160b57cec5SDimitry Andric BreakpointResolverSP resolver_sp(new BreakpointResolverFileRegex( 3179dba64beSDimitry Andric nullptr, std::move(source_regex), function_names, 3180b57cec5SDimitry Andric !static_cast<bool>(move_to_nearest_code))); 3190b57cec5SDimitry Andric 3200b57cec5SDimitry Andric return CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true); 3210b57cec5SDimitry Andric } 3220b57cec5SDimitry Andric 3230b57cec5SDimitry Andric BreakpointSP Target::CreateBreakpoint(const FileSpecList *containingModules, 3240b57cec5SDimitry Andric const FileSpec &file, uint32_t line_no, 3250b57cec5SDimitry Andric uint32_t column, lldb::addr_t offset, 3260b57cec5SDimitry Andric LazyBool check_inlines, 3270b57cec5SDimitry Andric LazyBool skip_prologue, bool internal, 3280b57cec5SDimitry Andric bool hardware, 3290b57cec5SDimitry Andric LazyBool move_to_nearest_code) { 3300b57cec5SDimitry Andric FileSpec remapped_file; 3310b57cec5SDimitry Andric if (!GetSourcePathMap().ReverseRemapPath(file, remapped_file)) 3320b57cec5SDimitry Andric remapped_file = file; 3330b57cec5SDimitry Andric 3340b57cec5SDimitry Andric if (check_inlines == eLazyBoolCalculate) { 3350b57cec5SDimitry Andric const InlineStrategy inline_strategy = GetInlineStrategy(); 3360b57cec5SDimitry Andric switch (inline_strategy) { 3370b57cec5SDimitry Andric case eInlineBreakpointsNever: 3380b57cec5SDimitry Andric check_inlines = eLazyBoolNo; 3390b57cec5SDimitry Andric break; 3400b57cec5SDimitry Andric 3410b57cec5SDimitry Andric case eInlineBreakpointsHeaders: 3420b57cec5SDimitry Andric if (remapped_file.IsSourceImplementationFile()) 3430b57cec5SDimitry Andric check_inlines = eLazyBoolNo; 3440b57cec5SDimitry Andric else 3450b57cec5SDimitry Andric check_inlines = eLazyBoolYes; 3460b57cec5SDimitry Andric break; 3470b57cec5SDimitry Andric 3480b57cec5SDimitry Andric case eInlineBreakpointsAlways: 3490b57cec5SDimitry Andric check_inlines = eLazyBoolYes; 3500b57cec5SDimitry Andric break; 3510b57cec5SDimitry Andric } 3520b57cec5SDimitry Andric } 3530b57cec5SDimitry Andric SearchFilterSP filter_sp; 3540b57cec5SDimitry Andric if (check_inlines == eLazyBoolNo) { 3550b57cec5SDimitry Andric // Not checking for inlines, we are looking only for matching compile units 3560b57cec5SDimitry Andric FileSpecList compile_unit_list; 3570b57cec5SDimitry Andric compile_unit_list.Append(remapped_file); 3580b57cec5SDimitry Andric filter_sp = GetSearchFilterForModuleAndCUList(containingModules, 3590b57cec5SDimitry Andric &compile_unit_list); 3600b57cec5SDimitry Andric } else { 3610b57cec5SDimitry Andric filter_sp = GetSearchFilterForModuleList(containingModules); 3620b57cec5SDimitry Andric } 3630b57cec5SDimitry Andric if (skip_prologue == eLazyBoolCalculate) 3640b57cec5SDimitry Andric skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo; 3650b57cec5SDimitry Andric if (move_to_nearest_code == eLazyBoolCalculate) 3660b57cec5SDimitry Andric move_to_nearest_code = GetMoveToNearestCode() ? eLazyBoolYes : eLazyBoolNo; 3670b57cec5SDimitry Andric 3680b57cec5SDimitry Andric BreakpointResolverSP resolver_sp(new BreakpointResolverFileLine( 3690b57cec5SDimitry Andric nullptr, remapped_file, line_no, column, offset, check_inlines, 3700b57cec5SDimitry Andric skip_prologue, !static_cast<bool>(move_to_nearest_code))); 3710b57cec5SDimitry Andric return CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true); 3720b57cec5SDimitry Andric } 3730b57cec5SDimitry Andric 3740b57cec5SDimitry Andric BreakpointSP Target::CreateBreakpoint(lldb::addr_t addr, bool internal, 3750b57cec5SDimitry Andric bool hardware) { 3760b57cec5SDimitry Andric Address so_addr; 3770b57cec5SDimitry Andric 3780b57cec5SDimitry Andric // Check for any reason we want to move this breakpoint to other address. 3790b57cec5SDimitry Andric addr = GetBreakableLoadAddress(addr); 3800b57cec5SDimitry Andric 3810b57cec5SDimitry Andric // Attempt to resolve our load address if possible, though it is ok if it 3820b57cec5SDimitry Andric // doesn't resolve to section/offset. 3830b57cec5SDimitry Andric 3840b57cec5SDimitry Andric // Try and resolve as a load address if possible 3850b57cec5SDimitry Andric GetSectionLoadList().ResolveLoadAddress(addr, so_addr); 3860b57cec5SDimitry Andric if (!so_addr.IsValid()) { 3870b57cec5SDimitry Andric // The address didn't resolve, so just set this as an absolute address 3880b57cec5SDimitry Andric so_addr.SetOffset(addr); 3890b57cec5SDimitry Andric } 3900b57cec5SDimitry Andric BreakpointSP bp_sp(CreateBreakpoint(so_addr, internal, hardware)); 3910b57cec5SDimitry Andric return bp_sp; 3920b57cec5SDimitry Andric } 3930b57cec5SDimitry Andric 3940b57cec5SDimitry Andric BreakpointSP Target::CreateBreakpoint(const Address &addr, bool internal, 3950b57cec5SDimitry Andric bool hardware) { 3960b57cec5SDimitry Andric SearchFilterSP filter_sp( 3970b57cec5SDimitry Andric new SearchFilterForUnconstrainedSearches(shared_from_this())); 3980b57cec5SDimitry Andric BreakpointResolverSP resolver_sp( 3990b57cec5SDimitry Andric new BreakpointResolverAddress(nullptr, addr)); 4000b57cec5SDimitry Andric return CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, false); 4010b57cec5SDimitry Andric } 4020b57cec5SDimitry Andric 4030b57cec5SDimitry Andric lldb::BreakpointSP 4040b57cec5SDimitry Andric Target::CreateAddressInModuleBreakpoint(lldb::addr_t file_addr, bool internal, 4050b57cec5SDimitry Andric const FileSpec *file_spec, 4060b57cec5SDimitry Andric bool request_hardware) { 4070b57cec5SDimitry Andric SearchFilterSP filter_sp( 4080b57cec5SDimitry Andric new SearchFilterForUnconstrainedSearches(shared_from_this())); 409480093f4SDimitry Andric BreakpointResolverSP resolver_sp(new BreakpointResolverAddress( 410480093f4SDimitry Andric nullptr, file_addr, file_spec ? *file_spec : FileSpec())); 4110b57cec5SDimitry Andric return CreateBreakpoint(filter_sp, resolver_sp, internal, request_hardware, 4120b57cec5SDimitry Andric false); 4130b57cec5SDimitry Andric } 4140b57cec5SDimitry Andric 4150b57cec5SDimitry Andric BreakpointSP Target::CreateBreakpoint( 4160b57cec5SDimitry Andric const FileSpecList *containingModules, 4170b57cec5SDimitry Andric const FileSpecList *containingSourceFiles, const char *func_name, 4180b57cec5SDimitry Andric FunctionNameType func_name_type_mask, LanguageType language, 4190b57cec5SDimitry Andric lldb::addr_t offset, LazyBool skip_prologue, bool internal, bool hardware) { 4200b57cec5SDimitry Andric BreakpointSP bp_sp; 4210b57cec5SDimitry Andric if (func_name) { 4220b57cec5SDimitry Andric SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList( 4230b57cec5SDimitry Andric containingModules, containingSourceFiles)); 4240b57cec5SDimitry Andric 4250b57cec5SDimitry Andric if (skip_prologue == eLazyBoolCalculate) 4260b57cec5SDimitry Andric skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo; 4270b57cec5SDimitry Andric if (language == lldb::eLanguageTypeUnknown) 4280b57cec5SDimitry Andric language = GetLanguage(); 4290b57cec5SDimitry Andric 4300b57cec5SDimitry Andric BreakpointResolverSP resolver_sp(new BreakpointResolverName( 4310b57cec5SDimitry Andric nullptr, func_name, func_name_type_mask, language, Breakpoint::Exact, 4320b57cec5SDimitry Andric offset, skip_prologue)); 4330b57cec5SDimitry Andric bp_sp = CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true); 4340b57cec5SDimitry Andric } 4350b57cec5SDimitry Andric return bp_sp; 4360b57cec5SDimitry Andric } 4370b57cec5SDimitry Andric 4380b57cec5SDimitry Andric lldb::BreakpointSP 4390b57cec5SDimitry Andric Target::CreateBreakpoint(const FileSpecList *containingModules, 4400b57cec5SDimitry Andric const FileSpecList *containingSourceFiles, 4410b57cec5SDimitry Andric const std::vector<std::string> &func_names, 4420b57cec5SDimitry Andric FunctionNameType func_name_type_mask, 4430b57cec5SDimitry Andric LanguageType language, lldb::addr_t offset, 4440b57cec5SDimitry Andric LazyBool skip_prologue, bool internal, bool hardware) { 4450b57cec5SDimitry Andric BreakpointSP bp_sp; 4460b57cec5SDimitry Andric size_t num_names = func_names.size(); 4470b57cec5SDimitry Andric if (num_names > 0) { 4480b57cec5SDimitry Andric SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList( 4490b57cec5SDimitry Andric containingModules, containingSourceFiles)); 4500b57cec5SDimitry Andric 4510b57cec5SDimitry Andric if (skip_prologue == eLazyBoolCalculate) 4520b57cec5SDimitry Andric skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo; 4530b57cec5SDimitry Andric if (language == lldb::eLanguageTypeUnknown) 4540b57cec5SDimitry Andric language = GetLanguage(); 4550b57cec5SDimitry Andric 4560b57cec5SDimitry Andric BreakpointResolverSP resolver_sp( 4570b57cec5SDimitry Andric new BreakpointResolverName(nullptr, func_names, func_name_type_mask, 4580b57cec5SDimitry Andric language, offset, skip_prologue)); 4590b57cec5SDimitry Andric bp_sp = CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true); 4600b57cec5SDimitry Andric } 4610b57cec5SDimitry Andric return bp_sp; 4620b57cec5SDimitry Andric } 4630b57cec5SDimitry Andric 4640b57cec5SDimitry Andric BreakpointSP 4650b57cec5SDimitry Andric Target::CreateBreakpoint(const FileSpecList *containingModules, 4660b57cec5SDimitry Andric const FileSpecList *containingSourceFiles, 4670b57cec5SDimitry Andric const char *func_names[], size_t num_names, 4680b57cec5SDimitry Andric FunctionNameType func_name_type_mask, 4690b57cec5SDimitry Andric LanguageType language, lldb::addr_t offset, 4700b57cec5SDimitry Andric LazyBool skip_prologue, bool internal, bool hardware) { 4710b57cec5SDimitry Andric BreakpointSP bp_sp; 4720b57cec5SDimitry Andric if (num_names > 0) { 4730b57cec5SDimitry Andric SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList( 4740b57cec5SDimitry Andric containingModules, containingSourceFiles)); 4750b57cec5SDimitry Andric 4760b57cec5SDimitry Andric if (skip_prologue == eLazyBoolCalculate) { 4770b57cec5SDimitry Andric if (offset == 0) 4780b57cec5SDimitry Andric skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo; 4790b57cec5SDimitry Andric else 4800b57cec5SDimitry Andric skip_prologue = eLazyBoolNo; 4810b57cec5SDimitry Andric } 4820b57cec5SDimitry Andric if (language == lldb::eLanguageTypeUnknown) 4830b57cec5SDimitry Andric language = GetLanguage(); 4840b57cec5SDimitry Andric 4850b57cec5SDimitry Andric BreakpointResolverSP resolver_sp(new BreakpointResolverName( 4860b57cec5SDimitry Andric nullptr, func_names, num_names, func_name_type_mask, language, offset, 4870b57cec5SDimitry Andric skip_prologue)); 4880b57cec5SDimitry Andric resolver_sp->SetOffset(offset); 4890b57cec5SDimitry Andric bp_sp = CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true); 4900b57cec5SDimitry Andric } 4910b57cec5SDimitry Andric return bp_sp; 4920b57cec5SDimitry Andric } 4930b57cec5SDimitry Andric 4940b57cec5SDimitry Andric SearchFilterSP 4950b57cec5SDimitry Andric Target::GetSearchFilterForModule(const FileSpec *containingModule) { 4960b57cec5SDimitry Andric SearchFilterSP filter_sp; 4970b57cec5SDimitry Andric if (containingModule != nullptr) { 4980b57cec5SDimitry Andric // TODO: We should look into sharing module based search filters 4990b57cec5SDimitry Andric // across many breakpoints like we do for the simple target based one 5000b57cec5SDimitry Andric filter_sp = std::make_shared<SearchFilterByModule>(shared_from_this(), 5010b57cec5SDimitry Andric *containingModule); 5020b57cec5SDimitry Andric } else { 5030b57cec5SDimitry Andric if (!m_search_filter_sp) 5040b57cec5SDimitry Andric m_search_filter_sp = 5050b57cec5SDimitry Andric std::make_shared<SearchFilterForUnconstrainedSearches>( 5060b57cec5SDimitry Andric shared_from_this()); 5070b57cec5SDimitry Andric filter_sp = m_search_filter_sp; 5080b57cec5SDimitry Andric } 5090b57cec5SDimitry Andric return filter_sp; 5100b57cec5SDimitry Andric } 5110b57cec5SDimitry Andric 5120b57cec5SDimitry Andric SearchFilterSP 5130b57cec5SDimitry Andric Target::GetSearchFilterForModuleList(const FileSpecList *containingModules) { 5140b57cec5SDimitry Andric SearchFilterSP filter_sp; 5150b57cec5SDimitry Andric if (containingModules && containingModules->GetSize() != 0) { 5160b57cec5SDimitry Andric // TODO: We should look into sharing module based search filters 5170b57cec5SDimitry Andric // across many breakpoints like we do for the simple target based one 5180b57cec5SDimitry Andric filter_sp = std::make_shared<SearchFilterByModuleList>(shared_from_this(), 5190b57cec5SDimitry Andric *containingModules); 5200b57cec5SDimitry Andric } else { 5210b57cec5SDimitry Andric if (!m_search_filter_sp) 5220b57cec5SDimitry Andric m_search_filter_sp = 5230b57cec5SDimitry Andric std::make_shared<SearchFilterForUnconstrainedSearches>( 5240b57cec5SDimitry Andric shared_from_this()); 5250b57cec5SDimitry Andric filter_sp = m_search_filter_sp; 5260b57cec5SDimitry Andric } 5270b57cec5SDimitry Andric return filter_sp; 5280b57cec5SDimitry Andric } 5290b57cec5SDimitry Andric 5300b57cec5SDimitry Andric SearchFilterSP Target::GetSearchFilterForModuleAndCUList( 5310b57cec5SDimitry Andric const FileSpecList *containingModules, 5320b57cec5SDimitry Andric const FileSpecList *containingSourceFiles) { 5330b57cec5SDimitry Andric if (containingSourceFiles == nullptr || containingSourceFiles->GetSize() == 0) 5340b57cec5SDimitry Andric return GetSearchFilterForModuleList(containingModules); 5350b57cec5SDimitry Andric 5360b57cec5SDimitry Andric SearchFilterSP filter_sp; 5370b57cec5SDimitry Andric if (containingModules == nullptr) { 5380b57cec5SDimitry Andric // We could make a special "CU List only SearchFilter". Better yet was if 5390b57cec5SDimitry Andric // these could be composable, but that will take a little reworking. 5400b57cec5SDimitry Andric 5410b57cec5SDimitry Andric filter_sp = std::make_shared<SearchFilterByModuleListAndCU>( 5420b57cec5SDimitry Andric shared_from_this(), FileSpecList(), *containingSourceFiles); 5430b57cec5SDimitry Andric } else { 5440b57cec5SDimitry Andric filter_sp = std::make_shared<SearchFilterByModuleListAndCU>( 5450b57cec5SDimitry Andric shared_from_this(), *containingModules, *containingSourceFiles); 5460b57cec5SDimitry Andric } 5470b57cec5SDimitry Andric return filter_sp; 5480b57cec5SDimitry Andric } 5490b57cec5SDimitry Andric 5500b57cec5SDimitry Andric BreakpointSP Target::CreateFuncRegexBreakpoint( 5510b57cec5SDimitry Andric const FileSpecList *containingModules, 5529dba64beSDimitry Andric const FileSpecList *containingSourceFiles, RegularExpression func_regex, 5530b57cec5SDimitry Andric lldb::LanguageType requested_language, LazyBool skip_prologue, 5540b57cec5SDimitry Andric bool internal, bool hardware) { 5550b57cec5SDimitry Andric SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList( 5560b57cec5SDimitry Andric containingModules, containingSourceFiles)); 5570b57cec5SDimitry Andric bool skip = (skip_prologue == eLazyBoolCalculate) 5580b57cec5SDimitry Andric ? GetSkipPrologue() 5590b57cec5SDimitry Andric : static_cast<bool>(skip_prologue); 5600b57cec5SDimitry Andric BreakpointResolverSP resolver_sp(new BreakpointResolverName( 5619dba64beSDimitry Andric nullptr, std::move(func_regex), requested_language, 0, skip)); 5620b57cec5SDimitry Andric 5630b57cec5SDimitry Andric return CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true); 5640b57cec5SDimitry Andric } 5650b57cec5SDimitry Andric 5660b57cec5SDimitry Andric lldb::BreakpointSP 5670b57cec5SDimitry Andric Target::CreateExceptionBreakpoint(enum lldb::LanguageType language, 5680b57cec5SDimitry Andric bool catch_bp, bool throw_bp, bool internal, 5690b57cec5SDimitry Andric Args *additional_args, Status *error) { 5700b57cec5SDimitry Andric BreakpointSP exc_bkpt_sp = LanguageRuntime::CreateExceptionBreakpoint( 5710b57cec5SDimitry Andric *this, language, catch_bp, throw_bp, internal); 5720b57cec5SDimitry Andric if (exc_bkpt_sp && additional_args) { 5730b57cec5SDimitry Andric BreakpointPreconditionSP precondition_sp = exc_bkpt_sp->GetPrecondition(); 5740b57cec5SDimitry Andric if (precondition_sp && additional_args) { 5750b57cec5SDimitry Andric if (error) 5760b57cec5SDimitry Andric *error = precondition_sp->ConfigurePrecondition(*additional_args); 5770b57cec5SDimitry Andric else 5780b57cec5SDimitry Andric precondition_sp->ConfigurePrecondition(*additional_args); 5790b57cec5SDimitry Andric } 5800b57cec5SDimitry Andric } 5810b57cec5SDimitry Andric return exc_bkpt_sp; 5820b57cec5SDimitry Andric } 5830b57cec5SDimitry Andric 5849dba64beSDimitry Andric lldb::BreakpointSP Target::CreateScriptedBreakpoint( 5859dba64beSDimitry Andric const llvm::StringRef class_name, const FileSpecList *containingModules, 5869dba64beSDimitry Andric const FileSpecList *containingSourceFiles, bool internal, 5879dba64beSDimitry Andric bool request_hardware, StructuredData::ObjectSP extra_args_sp, 5889dba64beSDimitry Andric Status *creation_error) { 5890b57cec5SDimitry Andric SearchFilterSP filter_sp; 5900b57cec5SDimitry Andric 5910b57cec5SDimitry Andric lldb::SearchDepth depth = lldb::eSearchDepthTarget; 5929dba64beSDimitry Andric bool has_files = 5939dba64beSDimitry Andric containingSourceFiles && containingSourceFiles->GetSize() > 0; 5940b57cec5SDimitry Andric bool has_modules = containingModules && containingModules->GetSize() > 0; 5950b57cec5SDimitry Andric 5960b57cec5SDimitry Andric if (has_files && has_modules) { 5979dba64beSDimitry Andric filter_sp = GetSearchFilterForModuleAndCUList(containingModules, 5989dba64beSDimitry Andric containingSourceFiles); 5990b57cec5SDimitry Andric } else if (has_files) { 6009dba64beSDimitry Andric filter_sp = 6019dba64beSDimitry Andric GetSearchFilterForModuleAndCUList(nullptr, containingSourceFiles); 6020b57cec5SDimitry Andric } else if (has_modules) { 6030b57cec5SDimitry Andric filter_sp = GetSearchFilterForModuleList(containingModules); 6040b57cec5SDimitry Andric } else { 6050b57cec5SDimitry Andric filter_sp = std::make_shared<SearchFilterForUnconstrainedSearches>( 6060b57cec5SDimitry Andric shared_from_this()); 6070b57cec5SDimitry Andric } 6080b57cec5SDimitry Andric 6090b57cec5SDimitry Andric StructuredDataImpl *extra_args_impl = new StructuredDataImpl(); 6100b57cec5SDimitry Andric if (extra_args_sp) 6110b57cec5SDimitry Andric extra_args_impl->SetObjectSP(extra_args_sp); 6120b57cec5SDimitry Andric 6130b57cec5SDimitry Andric BreakpointResolverSP resolver_sp(new BreakpointResolverScripted( 6149dba64beSDimitry Andric nullptr, class_name, depth, extra_args_impl)); 6150b57cec5SDimitry Andric return CreateBreakpoint(filter_sp, resolver_sp, internal, false, true); 6160b57cec5SDimitry Andric } 6170b57cec5SDimitry Andric 6180b57cec5SDimitry Andric BreakpointSP Target::CreateBreakpoint(SearchFilterSP &filter_sp, 6190b57cec5SDimitry Andric BreakpointResolverSP &resolver_sp, 6200b57cec5SDimitry Andric bool internal, bool request_hardware, 6210b57cec5SDimitry Andric bool resolve_indirect_symbols) { 6220b57cec5SDimitry Andric BreakpointSP bp_sp; 6230b57cec5SDimitry Andric if (filter_sp && resolver_sp) { 6240b57cec5SDimitry Andric const bool hardware = request_hardware || GetRequireHardwareBreakpoints(); 6250b57cec5SDimitry Andric bp_sp.reset(new Breakpoint(*this, filter_sp, resolver_sp, hardware, 6260b57cec5SDimitry Andric resolve_indirect_symbols)); 6275ffd83dbSDimitry Andric resolver_sp->SetBreakpoint(bp_sp); 6280b57cec5SDimitry Andric AddBreakpoint(bp_sp, internal); 6290b57cec5SDimitry Andric } 6300b57cec5SDimitry Andric return bp_sp; 6310b57cec5SDimitry Andric } 6320b57cec5SDimitry Andric 6330b57cec5SDimitry Andric void Target::AddBreakpoint(lldb::BreakpointSP bp_sp, bool internal) { 6340b57cec5SDimitry Andric if (!bp_sp) 6350b57cec5SDimitry Andric return; 6360b57cec5SDimitry Andric if (internal) 6370b57cec5SDimitry Andric m_internal_breakpoint_list.Add(bp_sp, false); 6380b57cec5SDimitry Andric else 6390b57cec5SDimitry Andric m_breakpoint_list.Add(bp_sp, true); 6400b57cec5SDimitry Andric 6410b57cec5SDimitry Andric Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); 6420b57cec5SDimitry Andric if (log) { 6430b57cec5SDimitry Andric StreamString s; 6440b57cec5SDimitry Andric bp_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose); 6459dba64beSDimitry Andric LLDB_LOGF(log, "Target::%s (internal = %s) => break_id = %s\n", 6469dba64beSDimitry Andric __FUNCTION__, bp_sp->IsInternal() ? "yes" : "no", s.GetData()); 6470b57cec5SDimitry Andric } 6480b57cec5SDimitry Andric 6490b57cec5SDimitry Andric bp_sp->ResolveBreakpoint(); 6500b57cec5SDimitry Andric 6510b57cec5SDimitry Andric if (!internal) { 6520b57cec5SDimitry Andric m_last_created_breakpoint = bp_sp; 6530b57cec5SDimitry Andric } 6540b57cec5SDimitry Andric } 6550b57cec5SDimitry Andric 6569dba64beSDimitry Andric void Target::AddNameToBreakpoint(BreakpointID &id, const char *name, 6579dba64beSDimitry Andric Status &error) { 6589dba64beSDimitry Andric BreakpointSP bp_sp = 6599dba64beSDimitry Andric m_breakpoint_list.FindBreakpointByID(id.GetBreakpointID()); 6609dba64beSDimitry Andric if (!bp_sp) { 6610b57cec5SDimitry Andric StreamString s; 6620b57cec5SDimitry Andric id.GetDescription(&s, eDescriptionLevelBrief); 6639dba64beSDimitry Andric error.SetErrorStringWithFormat("Could not find breakpoint %s", s.GetData()); 6640b57cec5SDimitry Andric return; 6650b57cec5SDimitry Andric } 6660b57cec5SDimitry Andric AddNameToBreakpoint(bp_sp, name, error); 6670b57cec5SDimitry Andric } 6680b57cec5SDimitry Andric 6699dba64beSDimitry Andric void Target::AddNameToBreakpoint(BreakpointSP &bp_sp, const char *name, 6709dba64beSDimitry Andric Status &error) { 6710b57cec5SDimitry Andric if (!bp_sp) 6720b57cec5SDimitry Andric return; 6730b57cec5SDimitry Andric 6740b57cec5SDimitry Andric BreakpointName *bp_name = FindBreakpointName(ConstString(name), true, error); 6750b57cec5SDimitry Andric if (!bp_name) 6760b57cec5SDimitry Andric return; 6770b57cec5SDimitry Andric 6780b57cec5SDimitry Andric bp_name->ConfigureBreakpoint(bp_sp); 6790b57cec5SDimitry Andric bp_sp->AddName(name); 6800b57cec5SDimitry Andric } 6810b57cec5SDimitry Andric 6820b57cec5SDimitry Andric void Target::AddBreakpointName(BreakpointName *bp_name) { 6830b57cec5SDimitry Andric m_breakpoint_names.insert(std::make_pair(bp_name->GetName(), bp_name)); 6840b57cec5SDimitry Andric } 6850b57cec5SDimitry Andric 6869dba64beSDimitry Andric BreakpointName *Target::FindBreakpointName(ConstString name, bool can_create, 6879dba64beSDimitry Andric Status &error) { 6880b57cec5SDimitry Andric BreakpointID::StringIsBreakpointName(name.GetStringRef(), error); 6890b57cec5SDimitry Andric if (!error.Success()) 6900b57cec5SDimitry Andric return nullptr; 6910b57cec5SDimitry Andric 6920b57cec5SDimitry Andric BreakpointNameList::iterator iter = m_breakpoint_names.find(name); 6930b57cec5SDimitry Andric if (iter == m_breakpoint_names.end()) { 6949dba64beSDimitry Andric if (!can_create) { 6950b57cec5SDimitry Andric error.SetErrorStringWithFormat("Breakpoint name \"%s\" doesn't exist and " 6969dba64beSDimitry Andric "can_create is false.", 6979dba64beSDimitry Andric name.AsCString()); 6980b57cec5SDimitry Andric return nullptr; 6990b57cec5SDimitry Andric } 7000b57cec5SDimitry Andric 7019dba64beSDimitry Andric iter = m_breakpoint_names 7029dba64beSDimitry Andric .insert(std::make_pair(name, new BreakpointName(name))) 7030b57cec5SDimitry Andric .first; 7040b57cec5SDimitry Andric } 7050b57cec5SDimitry Andric return (iter->second); 7060b57cec5SDimitry Andric } 7070b57cec5SDimitry Andric 7089dba64beSDimitry Andric void Target::DeleteBreakpointName(ConstString name) { 7090b57cec5SDimitry Andric BreakpointNameList::iterator iter = m_breakpoint_names.find(name); 7100b57cec5SDimitry Andric 7110b57cec5SDimitry Andric if (iter != m_breakpoint_names.end()) { 7120b57cec5SDimitry Andric const char *name_cstr = name.AsCString(); 7130b57cec5SDimitry Andric m_breakpoint_names.erase(iter); 7140b57cec5SDimitry Andric for (auto bp_sp : m_breakpoint_list.Breakpoints()) 7150b57cec5SDimitry Andric bp_sp->RemoveName(name_cstr); 7160b57cec5SDimitry Andric } 7170b57cec5SDimitry Andric } 7180b57cec5SDimitry Andric 7190b57cec5SDimitry Andric void Target::RemoveNameFromBreakpoint(lldb::BreakpointSP &bp_sp, 7209dba64beSDimitry Andric ConstString name) { 7210b57cec5SDimitry Andric bp_sp->RemoveName(name.AsCString()); 7220b57cec5SDimitry Andric } 7230b57cec5SDimitry Andric 7249dba64beSDimitry Andric void Target::ConfigureBreakpointName( 7259dba64beSDimitry Andric BreakpointName &bp_name, const BreakpointOptions &new_options, 7269dba64beSDimitry Andric const BreakpointName::Permissions &new_permissions) { 7270b57cec5SDimitry Andric bp_name.GetOptions().CopyOverSetOptions(new_options); 7280b57cec5SDimitry Andric bp_name.GetPermissions().MergeInto(new_permissions); 7290b57cec5SDimitry Andric ApplyNameToBreakpoints(bp_name); 7300b57cec5SDimitry Andric } 7310b57cec5SDimitry Andric 7320b57cec5SDimitry Andric void Target::ApplyNameToBreakpoints(BreakpointName &bp_name) { 733480093f4SDimitry Andric llvm::Expected<std::vector<BreakpointSP>> expected_vector = 734480093f4SDimitry Andric m_breakpoint_list.FindBreakpointsByName(bp_name.GetName().AsCString()); 7350b57cec5SDimitry Andric 736480093f4SDimitry Andric if (!expected_vector) { 737480093f4SDimitry Andric LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS), 738480093f4SDimitry Andric "invalid breakpoint name: {}", 739480093f4SDimitry Andric llvm::toString(expected_vector.takeError())); 740480093f4SDimitry Andric return; 741480093f4SDimitry Andric } 742480093f4SDimitry Andric 743480093f4SDimitry Andric for (auto bp_sp : *expected_vector) 7440b57cec5SDimitry Andric bp_name.ConfigureBreakpoint(bp_sp); 7450b57cec5SDimitry Andric } 7460b57cec5SDimitry Andric 7479dba64beSDimitry Andric void Target::GetBreakpointNames(std::vector<std::string> &names) { 7480b57cec5SDimitry Andric names.clear(); 7490b57cec5SDimitry Andric for (auto bp_name : m_breakpoint_names) { 7500b57cec5SDimitry Andric names.push_back(bp_name.first.AsCString()); 7510b57cec5SDimitry Andric } 7520b57cec5SDimitry Andric llvm::sort(names.begin(), names.end()); 7530b57cec5SDimitry Andric } 7540b57cec5SDimitry Andric 7550b57cec5SDimitry Andric bool Target::ProcessIsValid() { 7560b57cec5SDimitry Andric return (m_process_sp && m_process_sp->IsAlive()); 7570b57cec5SDimitry Andric } 7580b57cec5SDimitry Andric 7590b57cec5SDimitry Andric static bool CheckIfWatchpointsSupported(Target *target, Status &error) { 7600b57cec5SDimitry Andric uint32_t num_supported_hardware_watchpoints; 7610b57cec5SDimitry Andric Status rc = target->GetProcessSP()->GetWatchpointSupportInfo( 7620b57cec5SDimitry Andric num_supported_hardware_watchpoints); 7630b57cec5SDimitry Andric 7640b57cec5SDimitry Andric // If unable to determine the # of watchpoints available, 7650b57cec5SDimitry Andric // assume they are supported. 7660b57cec5SDimitry Andric if (rc.Fail()) 7670b57cec5SDimitry Andric return true; 7680b57cec5SDimitry Andric 7690b57cec5SDimitry Andric if (num_supported_hardware_watchpoints == 0) { 7700b57cec5SDimitry Andric error.SetErrorStringWithFormat( 7710b57cec5SDimitry Andric "Target supports (%u) hardware watchpoint slots.\n", 7720b57cec5SDimitry Andric num_supported_hardware_watchpoints); 7730b57cec5SDimitry Andric return false; 7740b57cec5SDimitry Andric } 7750b57cec5SDimitry Andric return true; 7760b57cec5SDimitry Andric } 7770b57cec5SDimitry Andric 7780b57cec5SDimitry Andric // See also Watchpoint::SetWatchpointType(uint32_t type) and the 7790b57cec5SDimitry Andric // OptionGroupWatchpoint::WatchType enum type. 7800b57cec5SDimitry Andric WatchpointSP Target::CreateWatchpoint(lldb::addr_t addr, size_t size, 7810b57cec5SDimitry Andric const CompilerType *type, uint32_t kind, 7820b57cec5SDimitry Andric Status &error) { 7830b57cec5SDimitry Andric Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); 7849dba64beSDimitry Andric LLDB_LOGF(log, 7859dba64beSDimitry Andric "Target::%s (addr = 0x%8.8" PRIx64 " size = %" PRIu64 7860b57cec5SDimitry Andric " type = %u)\n", 7870b57cec5SDimitry Andric __FUNCTION__, addr, (uint64_t)size, kind); 7880b57cec5SDimitry Andric 7890b57cec5SDimitry Andric WatchpointSP wp_sp; 7900b57cec5SDimitry Andric if (!ProcessIsValid()) { 7910b57cec5SDimitry Andric error.SetErrorString("process is not alive"); 7920b57cec5SDimitry Andric return wp_sp; 7930b57cec5SDimitry Andric } 7940b57cec5SDimitry Andric 7950b57cec5SDimitry Andric if (addr == LLDB_INVALID_ADDRESS || size == 0) { 7960b57cec5SDimitry Andric if (size == 0) 7970b57cec5SDimitry Andric error.SetErrorString("cannot set a watchpoint with watch_size of 0"); 7980b57cec5SDimitry Andric else 7990b57cec5SDimitry Andric error.SetErrorStringWithFormat("invalid watch address: %" PRIu64, addr); 8000b57cec5SDimitry Andric return wp_sp; 8010b57cec5SDimitry Andric } 8020b57cec5SDimitry Andric 8030b57cec5SDimitry Andric if (!LLDB_WATCH_TYPE_IS_VALID(kind)) { 8040b57cec5SDimitry Andric error.SetErrorStringWithFormat("invalid watchpoint type: %d", kind); 8050b57cec5SDimitry Andric } 8060b57cec5SDimitry Andric 8070b57cec5SDimitry Andric if (!CheckIfWatchpointsSupported(this, error)) 8080b57cec5SDimitry Andric return wp_sp; 8090b57cec5SDimitry Andric 8100b57cec5SDimitry Andric // Currently we only support one watchpoint per address, with total number of 8110b57cec5SDimitry Andric // watchpoints limited by the hardware which the inferior is running on. 8120b57cec5SDimitry Andric 8130b57cec5SDimitry Andric // Grab the list mutex while doing operations. 8140b57cec5SDimitry Andric const bool notify = false; // Don't notify about all the state changes we do 8150b57cec5SDimitry Andric // on creating the watchpoint. 8160b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 8170b57cec5SDimitry Andric this->GetWatchpointList().GetListMutex(lock); 8180b57cec5SDimitry Andric WatchpointSP matched_sp = m_watchpoint_list.FindByAddress(addr); 8190b57cec5SDimitry Andric if (matched_sp) { 8200b57cec5SDimitry Andric size_t old_size = matched_sp->GetByteSize(); 8210b57cec5SDimitry Andric uint32_t old_type = 8220b57cec5SDimitry Andric (matched_sp->WatchpointRead() ? LLDB_WATCH_TYPE_READ : 0) | 8230b57cec5SDimitry Andric (matched_sp->WatchpointWrite() ? LLDB_WATCH_TYPE_WRITE : 0); 8240b57cec5SDimitry Andric // Return the existing watchpoint if both size and type match. 8250b57cec5SDimitry Andric if (size == old_size && kind == old_type) { 8260b57cec5SDimitry Andric wp_sp = matched_sp; 8270b57cec5SDimitry Andric wp_sp->SetEnabled(false, notify); 8280b57cec5SDimitry Andric } else { 8290b57cec5SDimitry Andric // Nil the matched watchpoint; we will be creating a new one. 8300b57cec5SDimitry Andric m_process_sp->DisableWatchpoint(matched_sp.get(), notify); 8310b57cec5SDimitry Andric m_watchpoint_list.Remove(matched_sp->GetID(), true); 8320b57cec5SDimitry Andric } 8330b57cec5SDimitry Andric } 8340b57cec5SDimitry Andric 8350b57cec5SDimitry Andric if (!wp_sp) { 8360b57cec5SDimitry Andric wp_sp = std::make_shared<Watchpoint>(*this, addr, size, type); 8370b57cec5SDimitry Andric wp_sp->SetWatchpointType(kind, notify); 8380b57cec5SDimitry Andric m_watchpoint_list.Add(wp_sp, true); 8390b57cec5SDimitry Andric } 8400b57cec5SDimitry Andric 8410b57cec5SDimitry Andric error = m_process_sp->EnableWatchpoint(wp_sp.get(), notify); 8429dba64beSDimitry Andric LLDB_LOGF(log, "Target::%s (creation of watchpoint %s with id = %u)\n", 8430b57cec5SDimitry Andric __FUNCTION__, error.Success() ? "succeeded" : "failed", 8440b57cec5SDimitry Andric wp_sp->GetID()); 8450b57cec5SDimitry Andric 8460b57cec5SDimitry Andric if (error.Fail()) { 8470b57cec5SDimitry Andric // Enabling the watchpoint on the device side failed. Remove the said 8480b57cec5SDimitry Andric // watchpoint from the list maintained by the target instance. 8490b57cec5SDimitry Andric m_watchpoint_list.Remove(wp_sp->GetID(), true); 8500b57cec5SDimitry Andric // See if we could provide more helpful error message. 8510b57cec5SDimitry Andric if (!OptionGroupWatchpoint::IsWatchSizeSupported(size)) 8520b57cec5SDimitry Andric error.SetErrorStringWithFormat( 8530b57cec5SDimitry Andric "watch size of %" PRIu64 " is not supported", (uint64_t)size); 8540b57cec5SDimitry Andric 8550b57cec5SDimitry Andric wp_sp.reset(); 8560b57cec5SDimitry Andric } else 8570b57cec5SDimitry Andric m_last_created_watchpoint = wp_sp; 8580b57cec5SDimitry Andric return wp_sp; 8590b57cec5SDimitry Andric } 8600b57cec5SDimitry Andric 8619dba64beSDimitry Andric void Target::RemoveAllowedBreakpoints() { 8620b57cec5SDimitry Andric Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); 8639dba64beSDimitry Andric LLDB_LOGF(log, "Target::%s \n", __FUNCTION__); 8640b57cec5SDimitry Andric 8650b57cec5SDimitry Andric m_breakpoint_list.RemoveAllowed(true); 8660b57cec5SDimitry Andric 8670b57cec5SDimitry Andric m_last_created_breakpoint.reset(); 8680b57cec5SDimitry Andric } 8690b57cec5SDimitry Andric 8700b57cec5SDimitry Andric void Target::RemoveAllBreakpoints(bool internal_also) { 8710b57cec5SDimitry Andric Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); 8729dba64beSDimitry Andric LLDB_LOGF(log, "Target::%s (internal_also = %s)\n", __FUNCTION__, 8730b57cec5SDimitry Andric internal_also ? "yes" : "no"); 8740b57cec5SDimitry Andric 8750b57cec5SDimitry Andric m_breakpoint_list.RemoveAll(true); 8760b57cec5SDimitry Andric if (internal_also) 8770b57cec5SDimitry Andric m_internal_breakpoint_list.RemoveAll(false); 8780b57cec5SDimitry Andric 8790b57cec5SDimitry Andric m_last_created_breakpoint.reset(); 8800b57cec5SDimitry Andric } 8810b57cec5SDimitry Andric 8820b57cec5SDimitry Andric void Target::DisableAllBreakpoints(bool internal_also) { 8830b57cec5SDimitry Andric Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); 8849dba64beSDimitry Andric LLDB_LOGF(log, "Target::%s (internal_also = %s)\n", __FUNCTION__, 8850b57cec5SDimitry Andric internal_also ? "yes" : "no"); 8860b57cec5SDimitry Andric 8870b57cec5SDimitry Andric m_breakpoint_list.SetEnabledAll(false); 8880b57cec5SDimitry Andric if (internal_also) 8890b57cec5SDimitry Andric m_internal_breakpoint_list.SetEnabledAll(false); 8900b57cec5SDimitry Andric } 8910b57cec5SDimitry Andric 8920b57cec5SDimitry Andric void Target::DisableAllowedBreakpoints() { 8930b57cec5SDimitry Andric Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); 8949dba64beSDimitry Andric LLDB_LOGF(log, "Target::%s", __FUNCTION__); 8950b57cec5SDimitry Andric 8960b57cec5SDimitry Andric m_breakpoint_list.SetEnabledAllowed(false); 8970b57cec5SDimitry Andric } 8980b57cec5SDimitry Andric 8990b57cec5SDimitry Andric void Target::EnableAllBreakpoints(bool internal_also) { 9000b57cec5SDimitry Andric Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); 9019dba64beSDimitry Andric LLDB_LOGF(log, "Target::%s (internal_also = %s)\n", __FUNCTION__, 9020b57cec5SDimitry Andric internal_also ? "yes" : "no"); 9030b57cec5SDimitry Andric 9040b57cec5SDimitry Andric m_breakpoint_list.SetEnabledAll(true); 9050b57cec5SDimitry Andric if (internal_also) 9060b57cec5SDimitry Andric m_internal_breakpoint_list.SetEnabledAll(true); 9070b57cec5SDimitry Andric } 9080b57cec5SDimitry Andric 9090b57cec5SDimitry Andric void Target::EnableAllowedBreakpoints() { 9100b57cec5SDimitry Andric Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); 9119dba64beSDimitry Andric LLDB_LOGF(log, "Target::%s", __FUNCTION__); 9120b57cec5SDimitry Andric 9130b57cec5SDimitry Andric m_breakpoint_list.SetEnabledAllowed(true); 9140b57cec5SDimitry Andric } 9150b57cec5SDimitry Andric 9160b57cec5SDimitry Andric bool Target::RemoveBreakpointByID(break_id_t break_id) { 9170b57cec5SDimitry Andric Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); 9189dba64beSDimitry Andric LLDB_LOGF(log, "Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__, 9190b57cec5SDimitry Andric break_id, LLDB_BREAK_ID_IS_INTERNAL(break_id) ? "yes" : "no"); 9200b57cec5SDimitry Andric 9210b57cec5SDimitry Andric if (DisableBreakpointByID(break_id)) { 9220b57cec5SDimitry Andric if (LLDB_BREAK_ID_IS_INTERNAL(break_id)) 9230b57cec5SDimitry Andric m_internal_breakpoint_list.Remove(break_id, false); 9240b57cec5SDimitry Andric else { 9250b57cec5SDimitry Andric if (m_last_created_breakpoint) { 9260b57cec5SDimitry Andric if (m_last_created_breakpoint->GetID() == break_id) 9270b57cec5SDimitry Andric m_last_created_breakpoint.reset(); 9280b57cec5SDimitry Andric } 9290b57cec5SDimitry Andric m_breakpoint_list.Remove(break_id, true); 9300b57cec5SDimitry Andric } 9310b57cec5SDimitry Andric return true; 9320b57cec5SDimitry Andric } 9330b57cec5SDimitry Andric return false; 9340b57cec5SDimitry Andric } 9350b57cec5SDimitry Andric 9360b57cec5SDimitry Andric bool Target::DisableBreakpointByID(break_id_t break_id) { 9370b57cec5SDimitry Andric Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); 9389dba64beSDimitry Andric LLDB_LOGF(log, "Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__, 9390b57cec5SDimitry Andric break_id, LLDB_BREAK_ID_IS_INTERNAL(break_id) ? "yes" : "no"); 9400b57cec5SDimitry Andric 9410b57cec5SDimitry Andric BreakpointSP bp_sp; 9420b57cec5SDimitry Andric 9430b57cec5SDimitry Andric if (LLDB_BREAK_ID_IS_INTERNAL(break_id)) 9440b57cec5SDimitry Andric bp_sp = m_internal_breakpoint_list.FindBreakpointByID(break_id); 9450b57cec5SDimitry Andric else 9460b57cec5SDimitry Andric bp_sp = m_breakpoint_list.FindBreakpointByID(break_id); 9470b57cec5SDimitry Andric if (bp_sp) { 9480b57cec5SDimitry Andric bp_sp->SetEnabled(false); 9490b57cec5SDimitry Andric return true; 9500b57cec5SDimitry Andric } 9510b57cec5SDimitry Andric return false; 9520b57cec5SDimitry Andric } 9530b57cec5SDimitry Andric 9540b57cec5SDimitry Andric bool Target::EnableBreakpointByID(break_id_t break_id) { 9550b57cec5SDimitry Andric Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); 9569dba64beSDimitry Andric LLDB_LOGF(log, "Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__, 9570b57cec5SDimitry Andric break_id, LLDB_BREAK_ID_IS_INTERNAL(break_id) ? "yes" : "no"); 9580b57cec5SDimitry Andric 9590b57cec5SDimitry Andric BreakpointSP bp_sp; 9600b57cec5SDimitry Andric 9610b57cec5SDimitry Andric if (LLDB_BREAK_ID_IS_INTERNAL(break_id)) 9620b57cec5SDimitry Andric bp_sp = m_internal_breakpoint_list.FindBreakpointByID(break_id); 9630b57cec5SDimitry Andric else 9640b57cec5SDimitry Andric bp_sp = m_breakpoint_list.FindBreakpointByID(break_id); 9650b57cec5SDimitry Andric 9660b57cec5SDimitry Andric if (bp_sp) { 9670b57cec5SDimitry Andric bp_sp->SetEnabled(true); 9680b57cec5SDimitry Andric return true; 9690b57cec5SDimitry Andric } 9700b57cec5SDimitry Andric return false; 9710b57cec5SDimitry Andric } 9720b57cec5SDimitry Andric 9730b57cec5SDimitry Andric Status Target::SerializeBreakpointsToFile(const FileSpec &file, 9740b57cec5SDimitry Andric const BreakpointIDList &bp_ids, 9750b57cec5SDimitry Andric bool append) { 9760b57cec5SDimitry Andric Status error; 9770b57cec5SDimitry Andric 9780b57cec5SDimitry Andric if (!file) { 9790b57cec5SDimitry Andric error.SetErrorString("Invalid FileSpec."); 9800b57cec5SDimitry Andric return error; 9810b57cec5SDimitry Andric } 9820b57cec5SDimitry Andric 9830b57cec5SDimitry Andric std::string path(file.GetPath()); 9840b57cec5SDimitry Andric StructuredData::ObjectSP input_data_sp; 9850b57cec5SDimitry Andric 9860b57cec5SDimitry Andric StructuredData::ArraySP break_store_sp; 9870b57cec5SDimitry Andric StructuredData::Array *break_store_ptr = nullptr; 9880b57cec5SDimitry Andric 9890b57cec5SDimitry Andric if (append) { 9900b57cec5SDimitry Andric input_data_sp = StructuredData::ParseJSONFromFile(file, error); 9910b57cec5SDimitry Andric if (error.Success()) { 9920b57cec5SDimitry Andric break_store_ptr = input_data_sp->GetAsArray(); 9930b57cec5SDimitry Andric if (!break_store_ptr) { 9940b57cec5SDimitry Andric error.SetErrorStringWithFormat( 9950b57cec5SDimitry Andric "Tried to append to invalid input file %s", path.c_str()); 9960b57cec5SDimitry Andric return error; 9970b57cec5SDimitry Andric } 9980b57cec5SDimitry Andric } 9990b57cec5SDimitry Andric } 10000b57cec5SDimitry Andric 10010b57cec5SDimitry Andric if (!break_store_ptr) { 10020b57cec5SDimitry Andric break_store_sp = std::make_shared<StructuredData::Array>(); 10030b57cec5SDimitry Andric break_store_ptr = break_store_sp.get(); 10040b57cec5SDimitry Andric } 10050b57cec5SDimitry Andric 10060b57cec5SDimitry Andric StreamFile out_file(path.c_str(), 10079dba64beSDimitry Andric File::eOpenOptionTruncate | File::eOpenOptionWrite | 10089dba64beSDimitry Andric File::eOpenOptionCanCreate | 10099dba64beSDimitry Andric File::eOpenOptionCloseOnExec, 10100b57cec5SDimitry Andric lldb::eFilePermissionsFileDefault); 10110b57cec5SDimitry Andric if (!out_file.GetFile().IsValid()) { 10120b57cec5SDimitry Andric error.SetErrorStringWithFormat("Unable to open output file: %s.", 10130b57cec5SDimitry Andric path.c_str()); 10140b57cec5SDimitry Andric return error; 10150b57cec5SDimitry Andric } 10160b57cec5SDimitry Andric 10170b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 10180b57cec5SDimitry Andric GetBreakpointList().GetListMutex(lock); 10190b57cec5SDimitry Andric 10200b57cec5SDimitry Andric if (bp_ids.GetSize() == 0) { 10210b57cec5SDimitry Andric const BreakpointList &breakpoints = GetBreakpointList(); 10220b57cec5SDimitry Andric 10230b57cec5SDimitry Andric size_t num_breakpoints = breakpoints.GetSize(); 10240b57cec5SDimitry Andric for (size_t i = 0; i < num_breakpoints; i++) { 10250b57cec5SDimitry Andric Breakpoint *bp = breakpoints.GetBreakpointAtIndex(i).get(); 10260b57cec5SDimitry Andric StructuredData::ObjectSP bkpt_save_sp = bp->SerializeToStructuredData(); 10270b57cec5SDimitry Andric // If a breakpoint can't serialize it, just ignore it for now: 10280b57cec5SDimitry Andric if (bkpt_save_sp) 10290b57cec5SDimitry Andric break_store_ptr->AddItem(bkpt_save_sp); 10300b57cec5SDimitry Andric } 10310b57cec5SDimitry Andric } else { 10320b57cec5SDimitry Andric 10330b57cec5SDimitry Andric std::unordered_set<lldb::break_id_t> processed_bkpts; 10340b57cec5SDimitry Andric const size_t count = bp_ids.GetSize(); 10350b57cec5SDimitry Andric for (size_t i = 0; i < count; ++i) { 10360b57cec5SDimitry Andric BreakpointID cur_bp_id = bp_ids.GetBreakpointIDAtIndex(i); 10370b57cec5SDimitry Andric lldb::break_id_t bp_id = cur_bp_id.GetBreakpointID(); 10380b57cec5SDimitry Andric 10390b57cec5SDimitry Andric if (bp_id != LLDB_INVALID_BREAK_ID) { 10400b57cec5SDimitry Andric // Only do each breakpoint once: 10410b57cec5SDimitry Andric std::pair<std::unordered_set<lldb::break_id_t>::iterator, bool> 10420b57cec5SDimitry Andric insert_result = processed_bkpts.insert(bp_id); 10430b57cec5SDimitry Andric if (!insert_result.second) 10440b57cec5SDimitry Andric continue; 10450b57cec5SDimitry Andric 10460b57cec5SDimitry Andric Breakpoint *bp = GetBreakpointByID(bp_id).get(); 10470b57cec5SDimitry Andric StructuredData::ObjectSP bkpt_save_sp = bp->SerializeToStructuredData(); 10480b57cec5SDimitry Andric // If the user explicitly asked to serialize a breakpoint, and we 10490b57cec5SDimitry Andric // can't, then raise an error: 10500b57cec5SDimitry Andric if (!bkpt_save_sp) { 10510b57cec5SDimitry Andric error.SetErrorStringWithFormat("Unable to serialize breakpoint %d", 10520b57cec5SDimitry Andric bp_id); 10530b57cec5SDimitry Andric return error; 10540b57cec5SDimitry Andric } 10550b57cec5SDimitry Andric break_store_ptr->AddItem(bkpt_save_sp); 10560b57cec5SDimitry Andric } 10570b57cec5SDimitry Andric } 10580b57cec5SDimitry Andric } 10590b57cec5SDimitry Andric 10600b57cec5SDimitry Andric break_store_ptr->Dump(out_file, false); 10610b57cec5SDimitry Andric out_file.PutChar('\n'); 10620b57cec5SDimitry Andric return error; 10630b57cec5SDimitry Andric } 10640b57cec5SDimitry Andric 10650b57cec5SDimitry Andric Status Target::CreateBreakpointsFromFile(const FileSpec &file, 10660b57cec5SDimitry Andric BreakpointIDList &new_bps) { 10670b57cec5SDimitry Andric std::vector<std::string> no_names; 10680b57cec5SDimitry Andric return CreateBreakpointsFromFile(file, no_names, new_bps); 10690b57cec5SDimitry Andric } 10700b57cec5SDimitry Andric 10710b57cec5SDimitry Andric Status Target::CreateBreakpointsFromFile(const FileSpec &file, 10720b57cec5SDimitry Andric std::vector<std::string> &names, 10730b57cec5SDimitry Andric BreakpointIDList &new_bps) { 10740b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 10750b57cec5SDimitry Andric GetBreakpointList().GetListMutex(lock); 10760b57cec5SDimitry Andric 10770b57cec5SDimitry Andric Status error; 10780b57cec5SDimitry Andric StructuredData::ObjectSP input_data_sp = 10790b57cec5SDimitry Andric StructuredData::ParseJSONFromFile(file, error); 10800b57cec5SDimitry Andric if (!error.Success()) { 10810b57cec5SDimitry Andric return error; 10820b57cec5SDimitry Andric } else if (!input_data_sp || !input_data_sp->IsValid()) { 10830b57cec5SDimitry Andric error.SetErrorStringWithFormat("Invalid JSON from input file: %s.", 10840b57cec5SDimitry Andric file.GetPath().c_str()); 10850b57cec5SDimitry Andric return error; 10860b57cec5SDimitry Andric } 10870b57cec5SDimitry Andric 10880b57cec5SDimitry Andric StructuredData::Array *bkpt_array = input_data_sp->GetAsArray(); 10890b57cec5SDimitry Andric if (!bkpt_array) { 10900b57cec5SDimitry Andric error.SetErrorStringWithFormat( 10910b57cec5SDimitry Andric "Invalid breakpoint data from input file: %s.", file.GetPath().c_str()); 10920b57cec5SDimitry Andric return error; 10930b57cec5SDimitry Andric } 10940b57cec5SDimitry Andric 10950b57cec5SDimitry Andric size_t num_bkpts = bkpt_array->GetSize(); 10960b57cec5SDimitry Andric size_t num_names = names.size(); 10970b57cec5SDimitry Andric 10980b57cec5SDimitry Andric for (size_t i = 0; i < num_bkpts; i++) { 10990b57cec5SDimitry Andric StructuredData::ObjectSP bkpt_object_sp = bkpt_array->GetItemAtIndex(i); 11000b57cec5SDimitry Andric // Peel off the breakpoint key, and feed the rest to the Breakpoint: 11010b57cec5SDimitry Andric StructuredData::Dictionary *bkpt_dict = bkpt_object_sp->GetAsDictionary(); 11020b57cec5SDimitry Andric if (!bkpt_dict) { 11030b57cec5SDimitry Andric error.SetErrorStringWithFormat( 11040b57cec5SDimitry Andric "Invalid breakpoint data for element %zu from input file: %s.", i, 11050b57cec5SDimitry Andric file.GetPath().c_str()); 11060b57cec5SDimitry Andric return error; 11070b57cec5SDimitry Andric } 11080b57cec5SDimitry Andric StructuredData::ObjectSP bkpt_data_sp = 11090b57cec5SDimitry Andric bkpt_dict->GetValueForKey(Breakpoint::GetSerializationKey()); 11100b57cec5SDimitry Andric if (num_names && 11110b57cec5SDimitry Andric !Breakpoint::SerializedBreakpointMatchesNames(bkpt_data_sp, names)) 11120b57cec5SDimitry Andric continue; 11130b57cec5SDimitry Andric 11145ffd83dbSDimitry Andric BreakpointSP bkpt_sp = Breakpoint::CreateFromStructuredData( 11155ffd83dbSDimitry Andric shared_from_this(), bkpt_data_sp, error); 11160b57cec5SDimitry Andric if (!error.Success()) { 11170b57cec5SDimitry Andric error.SetErrorStringWithFormat( 11180b57cec5SDimitry Andric "Error restoring breakpoint %zu from %s: %s.", i, 11190b57cec5SDimitry Andric file.GetPath().c_str(), error.AsCString()); 11200b57cec5SDimitry Andric return error; 11210b57cec5SDimitry Andric } 11220b57cec5SDimitry Andric new_bps.AddBreakpointID(BreakpointID(bkpt_sp->GetID())); 11230b57cec5SDimitry Andric } 11240b57cec5SDimitry Andric return error; 11250b57cec5SDimitry Andric } 11260b57cec5SDimitry Andric 11270b57cec5SDimitry Andric // The flag 'end_to_end', default to true, signifies that the operation is 11280b57cec5SDimitry Andric // performed end to end, for both the debugger and the debuggee. 11290b57cec5SDimitry Andric 11300b57cec5SDimitry Andric // Assumption: Caller holds the list mutex lock for m_watchpoint_list for end 11310b57cec5SDimitry Andric // to end operations. 11320b57cec5SDimitry Andric bool Target::RemoveAllWatchpoints(bool end_to_end) { 11330b57cec5SDimitry Andric Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); 11349dba64beSDimitry Andric LLDB_LOGF(log, "Target::%s\n", __FUNCTION__); 11350b57cec5SDimitry Andric 11360b57cec5SDimitry Andric if (!end_to_end) { 11370b57cec5SDimitry Andric m_watchpoint_list.RemoveAll(true); 11380b57cec5SDimitry Andric return true; 11390b57cec5SDimitry Andric } 11400b57cec5SDimitry Andric 11410b57cec5SDimitry Andric // Otherwise, it's an end to end operation. 11420b57cec5SDimitry Andric 11430b57cec5SDimitry Andric if (!ProcessIsValid()) 11440b57cec5SDimitry Andric return false; 11450b57cec5SDimitry Andric 11460b57cec5SDimitry Andric size_t num_watchpoints = m_watchpoint_list.GetSize(); 11470b57cec5SDimitry Andric for (size_t i = 0; i < num_watchpoints; ++i) { 11480b57cec5SDimitry Andric WatchpointSP wp_sp = m_watchpoint_list.GetByIndex(i); 11490b57cec5SDimitry Andric if (!wp_sp) 11500b57cec5SDimitry Andric return false; 11510b57cec5SDimitry Andric 11520b57cec5SDimitry Andric Status rc = m_process_sp->DisableWatchpoint(wp_sp.get()); 11530b57cec5SDimitry Andric if (rc.Fail()) 11540b57cec5SDimitry Andric return false; 11550b57cec5SDimitry Andric } 11560b57cec5SDimitry Andric m_watchpoint_list.RemoveAll(true); 11570b57cec5SDimitry Andric m_last_created_watchpoint.reset(); 11580b57cec5SDimitry Andric return true; // Success! 11590b57cec5SDimitry Andric } 11600b57cec5SDimitry Andric 11610b57cec5SDimitry Andric // Assumption: Caller holds the list mutex lock for m_watchpoint_list for end 11620b57cec5SDimitry Andric // to end operations. 11630b57cec5SDimitry Andric bool Target::DisableAllWatchpoints(bool end_to_end) { 11640b57cec5SDimitry Andric Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); 11659dba64beSDimitry Andric LLDB_LOGF(log, "Target::%s\n", __FUNCTION__); 11660b57cec5SDimitry Andric 11670b57cec5SDimitry Andric if (!end_to_end) { 11680b57cec5SDimitry Andric m_watchpoint_list.SetEnabledAll(false); 11690b57cec5SDimitry Andric return true; 11700b57cec5SDimitry Andric } 11710b57cec5SDimitry Andric 11720b57cec5SDimitry Andric // Otherwise, it's an end to end operation. 11730b57cec5SDimitry Andric 11740b57cec5SDimitry Andric if (!ProcessIsValid()) 11750b57cec5SDimitry Andric return false; 11760b57cec5SDimitry Andric 11770b57cec5SDimitry Andric size_t num_watchpoints = m_watchpoint_list.GetSize(); 11780b57cec5SDimitry Andric for (size_t i = 0; i < num_watchpoints; ++i) { 11790b57cec5SDimitry Andric WatchpointSP wp_sp = m_watchpoint_list.GetByIndex(i); 11800b57cec5SDimitry Andric if (!wp_sp) 11810b57cec5SDimitry Andric return false; 11820b57cec5SDimitry Andric 11830b57cec5SDimitry Andric Status rc = m_process_sp->DisableWatchpoint(wp_sp.get()); 11840b57cec5SDimitry Andric if (rc.Fail()) 11850b57cec5SDimitry Andric return false; 11860b57cec5SDimitry Andric } 11870b57cec5SDimitry Andric return true; // Success! 11880b57cec5SDimitry Andric } 11890b57cec5SDimitry Andric 11900b57cec5SDimitry Andric // Assumption: Caller holds the list mutex lock for m_watchpoint_list for end 11910b57cec5SDimitry Andric // to end operations. 11920b57cec5SDimitry Andric bool Target::EnableAllWatchpoints(bool end_to_end) { 11930b57cec5SDimitry Andric Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); 11949dba64beSDimitry Andric LLDB_LOGF(log, "Target::%s\n", __FUNCTION__); 11950b57cec5SDimitry Andric 11960b57cec5SDimitry Andric if (!end_to_end) { 11970b57cec5SDimitry Andric m_watchpoint_list.SetEnabledAll(true); 11980b57cec5SDimitry Andric return true; 11990b57cec5SDimitry Andric } 12000b57cec5SDimitry Andric 12010b57cec5SDimitry Andric // Otherwise, it's an end to end operation. 12020b57cec5SDimitry Andric 12030b57cec5SDimitry Andric if (!ProcessIsValid()) 12040b57cec5SDimitry Andric return false; 12050b57cec5SDimitry Andric 12060b57cec5SDimitry Andric size_t num_watchpoints = m_watchpoint_list.GetSize(); 12070b57cec5SDimitry Andric for (size_t i = 0; i < num_watchpoints; ++i) { 12080b57cec5SDimitry Andric WatchpointSP wp_sp = m_watchpoint_list.GetByIndex(i); 12090b57cec5SDimitry Andric if (!wp_sp) 12100b57cec5SDimitry Andric return false; 12110b57cec5SDimitry Andric 12120b57cec5SDimitry Andric Status rc = m_process_sp->EnableWatchpoint(wp_sp.get()); 12130b57cec5SDimitry Andric if (rc.Fail()) 12140b57cec5SDimitry Andric return false; 12150b57cec5SDimitry Andric } 12160b57cec5SDimitry Andric return true; // Success! 12170b57cec5SDimitry Andric } 12180b57cec5SDimitry Andric 12190b57cec5SDimitry Andric // Assumption: Caller holds the list mutex lock for m_watchpoint_list. 12200b57cec5SDimitry Andric bool Target::ClearAllWatchpointHitCounts() { 12210b57cec5SDimitry Andric Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); 12229dba64beSDimitry Andric LLDB_LOGF(log, "Target::%s\n", __FUNCTION__); 12230b57cec5SDimitry Andric 12240b57cec5SDimitry Andric size_t num_watchpoints = m_watchpoint_list.GetSize(); 12250b57cec5SDimitry Andric for (size_t i = 0; i < num_watchpoints; ++i) { 12260b57cec5SDimitry Andric WatchpointSP wp_sp = m_watchpoint_list.GetByIndex(i); 12270b57cec5SDimitry Andric if (!wp_sp) 12280b57cec5SDimitry Andric return false; 12290b57cec5SDimitry Andric 12300b57cec5SDimitry Andric wp_sp->ResetHitCount(); 12310b57cec5SDimitry Andric } 12320b57cec5SDimitry Andric return true; // Success! 12330b57cec5SDimitry Andric } 12340b57cec5SDimitry Andric 12350b57cec5SDimitry Andric // Assumption: Caller holds the list mutex lock for m_watchpoint_list. 12360b57cec5SDimitry Andric bool Target::ClearAllWatchpointHistoricValues() { 12370b57cec5SDimitry Andric Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); 12389dba64beSDimitry Andric LLDB_LOGF(log, "Target::%s\n", __FUNCTION__); 12390b57cec5SDimitry Andric 12400b57cec5SDimitry Andric size_t num_watchpoints = m_watchpoint_list.GetSize(); 12410b57cec5SDimitry Andric for (size_t i = 0; i < num_watchpoints; ++i) { 12420b57cec5SDimitry Andric WatchpointSP wp_sp = m_watchpoint_list.GetByIndex(i); 12430b57cec5SDimitry Andric if (!wp_sp) 12440b57cec5SDimitry Andric return false; 12450b57cec5SDimitry Andric 12460b57cec5SDimitry Andric wp_sp->ResetHistoricValues(); 12470b57cec5SDimitry Andric } 12480b57cec5SDimitry Andric return true; // Success! 12490b57cec5SDimitry Andric } 12500b57cec5SDimitry Andric 12510b57cec5SDimitry Andric // Assumption: Caller holds the list mutex lock for m_watchpoint_list during 12520b57cec5SDimitry Andric // these operations. 12530b57cec5SDimitry Andric bool Target::IgnoreAllWatchpoints(uint32_t ignore_count) { 12540b57cec5SDimitry Andric Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); 12559dba64beSDimitry Andric LLDB_LOGF(log, "Target::%s\n", __FUNCTION__); 12560b57cec5SDimitry Andric 12570b57cec5SDimitry Andric if (!ProcessIsValid()) 12580b57cec5SDimitry Andric return false; 12590b57cec5SDimitry Andric 12600b57cec5SDimitry Andric size_t num_watchpoints = m_watchpoint_list.GetSize(); 12610b57cec5SDimitry Andric for (size_t i = 0; i < num_watchpoints; ++i) { 12620b57cec5SDimitry Andric WatchpointSP wp_sp = m_watchpoint_list.GetByIndex(i); 12630b57cec5SDimitry Andric if (!wp_sp) 12640b57cec5SDimitry Andric return false; 12650b57cec5SDimitry Andric 12660b57cec5SDimitry Andric wp_sp->SetIgnoreCount(ignore_count); 12670b57cec5SDimitry Andric } 12680b57cec5SDimitry Andric return true; // Success! 12690b57cec5SDimitry Andric } 12700b57cec5SDimitry Andric 12710b57cec5SDimitry Andric // Assumption: Caller holds the list mutex lock for m_watchpoint_list. 12720b57cec5SDimitry Andric bool Target::DisableWatchpointByID(lldb::watch_id_t watch_id) { 12730b57cec5SDimitry Andric Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); 12749dba64beSDimitry Andric LLDB_LOGF(log, "Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id); 12750b57cec5SDimitry Andric 12760b57cec5SDimitry Andric if (!ProcessIsValid()) 12770b57cec5SDimitry Andric return false; 12780b57cec5SDimitry Andric 12790b57cec5SDimitry Andric WatchpointSP wp_sp = m_watchpoint_list.FindByID(watch_id); 12800b57cec5SDimitry Andric if (wp_sp) { 12810b57cec5SDimitry Andric Status rc = m_process_sp->DisableWatchpoint(wp_sp.get()); 12820b57cec5SDimitry Andric if (rc.Success()) 12830b57cec5SDimitry Andric return true; 12840b57cec5SDimitry Andric 12850b57cec5SDimitry Andric // Else, fallthrough. 12860b57cec5SDimitry Andric } 12870b57cec5SDimitry Andric return false; 12880b57cec5SDimitry Andric } 12890b57cec5SDimitry Andric 12900b57cec5SDimitry Andric // Assumption: Caller holds the list mutex lock for m_watchpoint_list. 12910b57cec5SDimitry Andric bool Target::EnableWatchpointByID(lldb::watch_id_t watch_id) { 12920b57cec5SDimitry Andric Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); 12939dba64beSDimitry Andric LLDB_LOGF(log, "Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id); 12940b57cec5SDimitry Andric 12950b57cec5SDimitry Andric if (!ProcessIsValid()) 12960b57cec5SDimitry Andric return false; 12970b57cec5SDimitry Andric 12980b57cec5SDimitry Andric WatchpointSP wp_sp = m_watchpoint_list.FindByID(watch_id); 12990b57cec5SDimitry Andric if (wp_sp) { 13000b57cec5SDimitry Andric Status rc = m_process_sp->EnableWatchpoint(wp_sp.get()); 13010b57cec5SDimitry Andric if (rc.Success()) 13020b57cec5SDimitry Andric return true; 13030b57cec5SDimitry Andric 13040b57cec5SDimitry Andric // Else, fallthrough. 13050b57cec5SDimitry Andric } 13060b57cec5SDimitry Andric return false; 13070b57cec5SDimitry Andric } 13080b57cec5SDimitry Andric 13090b57cec5SDimitry Andric // Assumption: Caller holds the list mutex lock for m_watchpoint_list. 13100b57cec5SDimitry Andric bool Target::RemoveWatchpointByID(lldb::watch_id_t watch_id) { 13110b57cec5SDimitry Andric Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); 13129dba64beSDimitry Andric LLDB_LOGF(log, "Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id); 13130b57cec5SDimitry Andric 13140b57cec5SDimitry Andric WatchpointSP watch_to_remove_sp = m_watchpoint_list.FindByID(watch_id); 13150b57cec5SDimitry Andric if (watch_to_remove_sp == m_last_created_watchpoint) 13160b57cec5SDimitry Andric m_last_created_watchpoint.reset(); 13170b57cec5SDimitry Andric 13180b57cec5SDimitry Andric if (DisableWatchpointByID(watch_id)) { 13190b57cec5SDimitry Andric m_watchpoint_list.Remove(watch_id, true); 13200b57cec5SDimitry Andric return true; 13210b57cec5SDimitry Andric } 13220b57cec5SDimitry Andric return false; 13230b57cec5SDimitry Andric } 13240b57cec5SDimitry Andric 13250b57cec5SDimitry Andric // Assumption: Caller holds the list mutex lock for m_watchpoint_list. 13260b57cec5SDimitry Andric bool Target::IgnoreWatchpointByID(lldb::watch_id_t watch_id, 13270b57cec5SDimitry Andric uint32_t ignore_count) { 13280b57cec5SDimitry Andric Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); 13299dba64beSDimitry Andric LLDB_LOGF(log, "Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id); 13300b57cec5SDimitry Andric 13310b57cec5SDimitry Andric if (!ProcessIsValid()) 13320b57cec5SDimitry Andric return false; 13330b57cec5SDimitry Andric 13340b57cec5SDimitry Andric WatchpointSP wp_sp = m_watchpoint_list.FindByID(watch_id); 13350b57cec5SDimitry Andric if (wp_sp) { 13360b57cec5SDimitry Andric wp_sp->SetIgnoreCount(ignore_count); 13370b57cec5SDimitry Andric return true; 13380b57cec5SDimitry Andric } 13390b57cec5SDimitry Andric return false; 13400b57cec5SDimitry Andric } 13410b57cec5SDimitry Andric 13420b57cec5SDimitry Andric ModuleSP Target::GetExecutableModule() { 13430b57cec5SDimitry Andric // search for the first executable in the module list 13440b57cec5SDimitry Andric for (size_t i = 0; i < m_images.GetSize(); ++i) { 13450b57cec5SDimitry Andric ModuleSP module_sp = m_images.GetModuleAtIndex(i); 13460b57cec5SDimitry Andric lldb_private::ObjectFile *obj = module_sp->GetObjectFile(); 13470b57cec5SDimitry Andric if (obj == nullptr) 13480b57cec5SDimitry Andric continue; 13490b57cec5SDimitry Andric if (obj->GetType() == ObjectFile::Type::eTypeExecutable) 13500b57cec5SDimitry Andric return module_sp; 13510b57cec5SDimitry Andric } 13520b57cec5SDimitry Andric // as fall back return the first module loaded 13530b57cec5SDimitry Andric return m_images.GetModuleAtIndex(0); 13540b57cec5SDimitry Andric } 13550b57cec5SDimitry Andric 13560b57cec5SDimitry Andric Module *Target::GetExecutableModulePointer() { 13570b57cec5SDimitry Andric return GetExecutableModule().get(); 13580b57cec5SDimitry Andric } 13590b57cec5SDimitry Andric 13600b57cec5SDimitry Andric static void LoadScriptingResourceForModule(const ModuleSP &module_sp, 13610b57cec5SDimitry Andric Target *target) { 13620b57cec5SDimitry Andric Status error; 13630b57cec5SDimitry Andric StreamString feedback_stream; 13649dba64beSDimitry Andric if (module_sp && !module_sp->LoadScriptingResourceInTarget( 13659dba64beSDimitry Andric target, error, &feedback_stream)) { 13660b57cec5SDimitry Andric if (error.AsCString()) 13679dba64beSDimitry Andric target->GetDebugger().GetErrorStream().Printf( 13680b57cec5SDimitry Andric "unable to load scripting data for module %s - error reported was " 13690b57cec5SDimitry Andric "%s\n", 13700b57cec5SDimitry Andric module_sp->GetFileSpec().GetFileNameStrippingExtension().GetCString(), 13710b57cec5SDimitry Andric error.AsCString()); 13720b57cec5SDimitry Andric } 13730b57cec5SDimitry Andric if (feedback_stream.GetSize()) 13749dba64beSDimitry Andric target->GetDebugger().GetErrorStream().Printf("%s\n", 13750b57cec5SDimitry Andric feedback_stream.GetData()); 13760b57cec5SDimitry Andric } 13770b57cec5SDimitry Andric 13780b57cec5SDimitry Andric void Target::ClearModules(bool delete_locations) { 13790b57cec5SDimitry Andric ModulesDidUnload(m_images, delete_locations); 13800b57cec5SDimitry Andric m_section_load_history.Clear(); 13810b57cec5SDimitry Andric m_images.Clear(); 13820b57cec5SDimitry Andric m_scratch_type_system_map.Clear(); 13830b57cec5SDimitry Andric } 13840b57cec5SDimitry Andric 13850b57cec5SDimitry Andric void Target::DidExec() { 13860b57cec5SDimitry Andric // When a process exec's we need to know about it so we can do some cleanup. 13870b57cec5SDimitry Andric m_breakpoint_list.RemoveInvalidLocations(m_arch.GetSpec()); 13880b57cec5SDimitry Andric m_internal_breakpoint_list.RemoveInvalidLocations(m_arch.GetSpec()); 13890b57cec5SDimitry Andric } 13900b57cec5SDimitry Andric 13910b57cec5SDimitry Andric void Target::SetExecutableModule(ModuleSP &executable_sp, 13920b57cec5SDimitry Andric LoadDependentFiles load_dependent_files) { 13930b57cec5SDimitry Andric Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET)); 13940b57cec5SDimitry Andric ClearModules(false); 13950b57cec5SDimitry Andric 13960b57cec5SDimitry Andric if (executable_sp) { 13970b57cec5SDimitry Andric static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); 13980b57cec5SDimitry Andric Timer scoped_timer(func_cat, 13990b57cec5SDimitry Andric "Target::SetExecutableModule (executable = '%s')", 14000b57cec5SDimitry Andric executable_sp->GetFileSpec().GetPath().c_str()); 14010b57cec5SDimitry Andric 14020b57cec5SDimitry Andric const bool notify = true; 14039dba64beSDimitry Andric m_images.Append(executable_sp, 14049dba64beSDimitry Andric notify); // The first image is our executable file 14050b57cec5SDimitry Andric 14060b57cec5SDimitry Andric // If we haven't set an architecture yet, reset our architecture based on 14070b57cec5SDimitry Andric // what we found in the executable module. 14080b57cec5SDimitry Andric if (!m_arch.GetSpec().IsValid()) { 14090b57cec5SDimitry Andric m_arch = executable_sp->GetArchitecture(); 14100b57cec5SDimitry Andric LLDB_LOG(log, 14110b57cec5SDimitry Andric "setting architecture to {0} ({1}) based on executable file", 14120b57cec5SDimitry Andric m_arch.GetSpec().GetArchitectureName(), 14130b57cec5SDimitry Andric m_arch.GetSpec().GetTriple().getTriple()); 14140b57cec5SDimitry Andric } 14150b57cec5SDimitry Andric 14160b57cec5SDimitry Andric FileSpecList dependent_files; 14170b57cec5SDimitry Andric ObjectFile *executable_objfile = executable_sp->GetObjectFile(); 14180b57cec5SDimitry Andric bool load_dependents = true; 14190b57cec5SDimitry Andric switch (load_dependent_files) { 14200b57cec5SDimitry Andric case eLoadDependentsDefault: 14210b57cec5SDimitry Andric load_dependents = executable_sp->IsExecutable(); 14220b57cec5SDimitry Andric break; 14230b57cec5SDimitry Andric case eLoadDependentsYes: 14240b57cec5SDimitry Andric load_dependents = true; 14250b57cec5SDimitry Andric break; 14260b57cec5SDimitry Andric case eLoadDependentsNo: 14270b57cec5SDimitry Andric load_dependents = false; 14280b57cec5SDimitry Andric break; 14290b57cec5SDimitry Andric } 14300b57cec5SDimitry Andric 14310b57cec5SDimitry Andric if (executable_objfile && load_dependents) { 14320b57cec5SDimitry Andric ModuleList added_modules; 14330b57cec5SDimitry Andric executable_objfile->GetDependentModules(dependent_files); 14340b57cec5SDimitry Andric for (uint32_t i = 0; i < dependent_files.GetSize(); i++) { 1435480093f4SDimitry Andric FileSpec dependent_file_spec(dependent_files.GetFileSpecAtIndex(i)); 14360b57cec5SDimitry Andric FileSpec platform_dependent_file_spec; 14370b57cec5SDimitry Andric if (m_platform_sp) 14380b57cec5SDimitry Andric m_platform_sp->GetFileWithUUID(dependent_file_spec, nullptr, 14390b57cec5SDimitry Andric platform_dependent_file_spec); 14400b57cec5SDimitry Andric else 14410b57cec5SDimitry Andric platform_dependent_file_spec = dependent_file_spec; 14420b57cec5SDimitry Andric 14430b57cec5SDimitry Andric ModuleSpec module_spec(platform_dependent_file_spec, m_arch.GetSpec()); 14449dba64beSDimitry Andric ModuleSP image_module_sp( 14459dba64beSDimitry Andric GetOrCreateModule(module_spec, false /* notify */)); 14460b57cec5SDimitry Andric if (image_module_sp) { 14470b57cec5SDimitry Andric added_modules.AppendIfNeeded(image_module_sp, false); 14480b57cec5SDimitry Andric ObjectFile *objfile = image_module_sp->GetObjectFile(); 14490b57cec5SDimitry Andric if (objfile) 14500b57cec5SDimitry Andric objfile->GetDependentModules(dependent_files); 14510b57cec5SDimitry Andric } 14520b57cec5SDimitry Andric } 14530b57cec5SDimitry Andric ModulesDidLoad(added_modules); 14540b57cec5SDimitry Andric } 14550b57cec5SDimitry Andric } 14560b57cec5SDimitry Andric } 14570b57cec5SDimitry Andric 14580b57cec5SDimitry Andric bool Target::SetArchitecture(const ArchSpec &arch_spec, bool set_platform) { 14590b57cec5SDimitry Andric Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET)); 14600b57cec5SDimitry Andric bool missing_local_arch = !m_arch.GetSpec().IsValid(); 14610b57cec5SDimitry Andric bool replace_local_arch = true; 14620b57cec5SDimitry Andric bool compatible_local_arch = false; 14630b57cec5SDimitry Andric ArchSpec other(arch_spec); 14640b57cec5SDimitry Andric 14650b57cec5SDimitry Andric // Changing the architecture might mean that the currently selected platform 14660b57cec5SDimitry Andric // isn't compatible. Set the platform correctly if we are asked to do so, 14670b57cec5SDimitry Andric // otherwise assume the user will set the platform manually. 14680b57cec5SDimitry Andric if (set_platform) { 14690b57cec5SDimitry Andric if (other.IsValid()) { 14700b57cec5SDimitry Andric auto platform_sp = GetPlatform(); 14710b57cec5SDimitry Andric if (!platform_sp || 14720b57cec5SDimitry Andric !platform_sp->IsCompatibleArchitecture(other, false, nullptr)) { 14730b57cec5SDimitry Andric ArchSpec platform_arch; 14740b57cec5SDimitry Andric auto arch_platform_sp = 14750b57cec5SDimitry Andric Platform::GetPlatformForArchitecture(other, &platform_arch); 14760b57cec5SDimitry Andric if (arch_platform_sp) { 14770b57cec5SDimitry Andric SetPlatform(arch_platform_sp); 14780b57cec5SDimitry Andric if (platform_arch.IsValid()) 14790b57cec5SDimitry Andric other = platform_arch; 14800b57cec5SDimitry Andric } 14810b57cec5SDimitry Andric } 14820b57cec5SDimitry Andric } 14830b57cec5SDimitry Andric } 14840b57cec5SDimitry Andric 14850b57cec5SDimitry Andric if (!missing_local_arch) { 14860b57cec5SDimitry Andric if (m_arch.GetSpec().IsCompatibleMatch(arch_spec)) { 14870b57cec5SDimitry Andric other.MergeFrom(m_arch.GetSpec()); 14880b57cec5SDimitry Andric 14890b57cec5SDimitry Andric if (m_arch.GetSpec().IsCompatibleMatch(other)) { 14900b57cec5SDimitry Andric compatible_local_arch = true; 14910b57cec5SDimitry Andric bool arch_changed, vendor_changed, os_changed, os_ver_changed, 14920b57cec5SDimitry Andric env_changed; 14930b57cec5SDimitry Andric 14949dba64beSDimitry Andric m_arch.GetSpec().PiecewiseTripleCompare(other, arch_changed, 14959dba64beSDimitry Andric vendor_changed, os_changed, 14969dba64beSDimitry Andric os_ver_changed, env_changed); 14970b57cec5SDimitry Andric 14980b57cec5SDimitry Andric if (!arch_changed && !vendor_changed && !os_changed && !env_changed) 14990b57cec5SDimitry Andric replace_local_arch = false; 15000b57cec5SDimitry Andric } 15010b57cec5SDimitry Andric } 15020b57cec5SDimitry Andric } 15030b57cec5SDimitry Andric 15040b57cec5SDimitry Andric if (compatible_local_arch || missing_local_arch) { 15050b57cec5SDimitry Andric // If we haven't got a valid arch spec, or the architectures are compatible 15060b57cec5SDimitry Andric // update the architecture, unless the one we already have is more 15070b57cec5SDimitry Andric // specified 15080b57cec5SDimitry Andric if (replace_local_arch) 15090b57cec5SDimitry Andric m_arch = other; 15100b57cec5SDimitry Andric LLDB_LOG(log, "set architecture to {0} ({1})", 15110b57cec5SDimitry Andric m_arch.GetSpec().GetArchitectureName(), 15120b57cec5SDimitry Andric m_arch.GetSpec().GetTriple().getTriple()); 15130b57cec5SDimitry Andric return true; 15140b57cec5SDimitry Andric } 15150b57cec5SDimitry Andric 15160b57cec5SDimitry Andric // If we have an executable file, try to reset the executable to the desired 15170b57cec5SDimitry Andric // architecture 15189dba64beSDimitry Andric LLDB_LOGF(log, "Target::SetArchitecture changing architecture to %s (%s)", 15190b57cec5SDimitry Andric arch_spec.GetArchitectureName(), 15200b57cec5SDimitry Andric arch_spec.GetTriple().getTriple().c_str()); 15210b57cec5SDimitry Andric m_arch = other; 15220b57cec5SDimitry Andric ModuleSP executable_sp = GetExecutableModule(); 15230b57cec5SDimitry Andric 15240b57cec5SDimitry Andric ClearModules(true); 15250b57cec5SDimitry Andric // Need to do something about unsetting breakpoints. 15260b57cec5SDimitry Andric 15270b57cec5SDimitry Andric if (executable_sp) { 15289dba64beSDimitry Andric LLDB_LOGF(log, 15299dba64beSDimitry Andric "Target::SetArchitecture Trying to select executable file " 15300b57cec5SDimitry Andric "architecture %s (%s)", 15310b57cec5SDimitry Andric arch_spec.GetArchitectureName(), 15320b57cec5SDimitry Andric arch_spec.GetTriple().getTriple().c_str()); 15330b57cec5SDimitry Andric ModuleSpec module_spec(executable_sp->GetFileSpec(), other); 15340b57cec5SDimitry Andric FileSpecList search_paths = GetExecutableSearchPaths(); 15350b57cec5SDimitry Andric Status error = ModuleList::GetSharedModule(module_spec, executable_sp, 15369dba64beSDimitry Andric &search_paths, nullptr, nullptr); 15370b57cec5SDimitry Andric 15380b57cec5SDimitry Andric if (!error.Fail() && executable_sp) { 15390b57cec5SDimitry Andric SetExecutableModule(executable_sp, eLoadDependentsYes); 15400b57cec5SDimitry Andric return true; 15410b57cec5SDimitry Andric } 15420b57cec5SDimitry Andric } 15430b57cec5SDimitry Andric return false; 15440b57cec5SDimitry Andric } 15450b57cec5SDimitry Andric 15460b57cec5SDimitry Andric bool Target::MergeArchitecture(const ArchSpec &arch_spec) { 15470b57cec5SDimitry Andric Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET)); 15480b57cec5SDimitry Andric if (arch_spec.IsValid()) { 15490b57cec5SDimitry Andric if (m_arch.GetSpec().IsCompatibleMatch(arch_spec)) { 15500b57cec5SDimitry Andric // The current target arch is compatible with "arch_spec", see if we can 15510b57cec5SDimitry Andric // improve our current architecture using bits from "arch_spec" 15520b57cec5SDimitry Andric 15539dba64beSDimitry Andric LLDB_LOGF(log, 15549dba64beSDimitry Andric "Target::MergeArchitecture target has arch %s, merging with " 15550b57cec5SDimitry Andric "arch %s", 15560b57cec5SDimitry Andric m_arch.GetSpec().GetTriple().getTriple().c_str(), 15570b57cec5SDimitry Andric arch_spec.GetTriple().getTriple().c_str()); 15580b57cec5SDimitry Andric 15590b57cec5SDimitry Andric // Merge bits from arch_spec into "merged_arch" and set our architecture 15600b57cec5SDimitry Andric ArchSpec merged_arch(m_arch.GetSpec()); 15610b57cec5SDimitry Andric merged_arch.MergeFrom(arch_spec); 15620b57cec5SDimitry Andric return SetArchitecture(merged_arch); 15630b57cec5SDimitry Andric } else { 15640b57cec5SDimitry Andric // The new architecture is different, we just need to replace it 15650b57cec5SDimitry Andric return SetArchitecture(arch_spec); 15660b57cec5SDimitry Andric } 15670b57cec5SDimitry Andric } 15680b57cec5SDimitry Andric return false; 15690b57cec5SDimitry Andric } 15700b57cec5SDimitry Andric 15710b57cec5SDimitry Andric void Target::NotifyWillClearList(const ModuleList &module_list) {} 15720b57cec5SDimitry Andric 15730b57cec5SDimitry Andric void Target::NotifyModuleAdded(const ModuleList &module_list, 15740b57cec5SDimitry Andric const ModuleSP &module_sp) { 15750b57cec5SDimitry Andric // A module is being added to this target for the first time 15760b57cec5SDimitry Andric if (m_valid) { 15770b57cec5SDimitry Andric ModuleList my_module_list; 15780b57cec5SDimitry Andric my_module_list.Append(module_sp); 15790b57cec5SDimitry Andric ModulesDidLoad(my_module_list); 15800b57cec5SDimitry Andric } 15810b57cec5SDimitry Andric } 15820b57cec5SDimitry Andric 15830b57cec5SDimitry Andric void Target::NotifyModuleRemoved(const ModuleList &module_list, 15840b57cec5SDimitry Andric const ModuleSP &module_sp) { 15850b57cec5SDimitry Andric // A module is being removed from this target. 15860b57cec5SDimitry Andric if (m_valid) { 15870b57cec5SDimitry Andric ModuleList my_module_list; 15880b57cec5SDimitry Andric my_module_list.Append(module_sp); 15890b57cec5SDimitry Andric ModulesDidUnload(my_module_list, false); 15900b57cec5SDimitry Andric } 15910b57cec5SDimitry Andric } 15920b57cec5SDimitry Andric 15930b57cec5SDimitry Andric void Target::NotifyModuleUpdated(const ModuleList &module_list, 15940b57cec5SDimitry Andric const ModuleSP &old_module_sp, 15950b57cec5SDimitry Andric const ModuleSP &new_module_sp) { 15960b57cec5SDimitry Andric // A module is replacing an already added module 15970b57cec5SDimitry Andric if (m_valid) { 15980b57cec5SDimitry Andric m_breakpoint_list.UpdateBreakpointsWhenModuleIsReplaced(old_module_sp, 15990b57cec5SDimitry Andric new_module_sp); 16000b57cec5SDimitry Andric m_internal_breakpoint_list.UpdateBreakpointsWhenModuleIsReplaced( 16010b57cec5SDimitry Andric old_module_sp, new_module_sp); 16020b57cec5SDimitry Andric } 16030b57cec5SDimitry Andric } 16040b57cec5SDimitry Andric 16050b57cec5SDimitry Andric void Target::NotifyModulesRemoved(lldb_private::ModuleList &module_list) { 16060b57cec5SDimitry Andric ModulesDidUnload(module_list, false); 16070b57cec5SDimitry Andric } 16080b57cec5SDimitry Andric 16090b57cec5SDimitry Andric void Target::ModulesDidLoad(ModuleList &module_list) { 16100b57cec5SDimitry Andric const size_t num_images = module_list.GetSize(); 16110b57cec5SDimitry Andric if (m_valid && num_images) { 16120b57cec5SDimitry Andric for (size_t idx = 0; idx < num_images; ++idx) { 16130b57cec5SDimitry Andric ModuleSP module_sp(module_list.GetModuleAtIndex(idx)); 16140b57cec5SDimitry Andric LoadScriptingResourceForModule(module_sp, this); 16150b57cec5SDimitry Andric } 16160b57cec5SDimitry Andric m_breakpoint_list.UpdateBreakpoints(module_list, true, false); 16170b57cec5SDimitry Andric m_internal_breakpoint_list.UpdateBreakpoints(module_list, true, false); 16180b57cec5SDimitry Andric if (m_process_sp) { 16190b57cec5SDimitry Andric m_process_sp->ModulesDidLoad(module_list); 16200b57cec5SDimitry Andric } 16210b57cec5SDimitry Andric BroadcastEvent(eBroadcastBitModulesLoaded, 16220b57cec5SDimitry Andric new TargetEventData(this->shared_from_this(), module_list)); 16230b57cec5SDimitry Andric } 16240b57cec5SDimitry Andric } 16250b57cec5SDimitry Andric 16260b57cec5SDimitry Andric void Target::SymbolsDidLoad(ModuleList &module_list) { 16270b57cec5SDimitry Andric if (m_valid && module_list.GetSize()) { 16280b57cec5SDimitry Andric if (m_process_sp) { 16290b57cec5SDimitry Andric for (LanguageRuntime *runtime : m_process_sp->GetLanguageRuntimes()) { 16300b57cec5SDimitry Andric runtime->SymbolsDidLoad(module_list); 16310b57cec5SDimitry Andric } 16320b57cec5SDimitry Andric } 16330b57cec5SDimitry Andric 16340b57cec5SDimitry Andric m_breakpoint_list.UpdateBreakpoints(module_list, true, false); 16350b57cec5SDimitry Andric m_internal_breakpoint_list.UpdateBreakpoints(module_list, true, false); 16360b57cec5SDimitry Andric BroadcastEvent(eBroadcastBitSymbolsLoaded, 16370b57cec5SDimitry Andric new TargetEventData(this->shared_from_this(), module_list)); 16380b57cec5SDimitry Andric } 16390b57cec5SDimitry Andric } 16400b57cec5SDimitry Andric 16410b57cec5SDimitry Andric void Target::ModulesDidUnload(ModuleList &module_list, bool delete_locations) { 16420b57cec5SDimitry Andric if (m_valid && module_list.GetSize()) { 16430b57cec5SDimitry Andric UnloadModuleSections(module_list); 16440b57cec5SDimitry Andric m_breakpoint_list.UpdateBreakpoints(module_list, false, delete_locations); 16450b57cec5SDimitry Andric m_internal_breakpoint_list.UpdateBreakpoints(module_list, false, 16460b57cec5SDimitry Andric delete_locations); 16470b57cec5SDimitry Andric BroadcastEvent(eBroadcastBitModulesUnloaded, 16480b57cec5SDimitry Andric new TargetEventData(this->shared_from_this(), module_list)); 16490b57cec5SDimitry Andric } 16500b57cec5SDimitry Andric } 16510b57cec5SDimitry Andric 16520b57cec5SDimitry Andric bool Target::ModuleIsExcludedForUnconstrainedSearches( 16530b57cec5SDimitry Andric const FileSpec &module_file_spec) { 16540b57cec5SDimitry Andric if (GetBreakpointsConsultPlatformAvoidList()) { 16550b57cec5SDimitry Andric ModuleList matchingModules; 16560b57cec5SDimitry Andric ModuleSpec module_spec(module_file_spec); 16579dba64beSDimitry Andric GetImages().FindModules(module_spec, matchingModules); 16589dba64beSDimitry Andric size_t num_modules = matchingModules.GetSize(); 16590b57cec5SDimitry Andric 16609dba64beSDimitry Andric // If there is more than one module for this file spec, only 16619dba64beSDimitry Andric // return true if ALL the modules are on the black list. 16620b57cec5SDimitry Andric if (num_modules > 0) { 16630b57cec5SDimitry Andric for (size_t i = 0; i < num_modules; i++) { 16640b57cec5SDimitry Andric if (!ModuleIsExcludedForUnconstrainedSearches( 16650b57cec5SDimitry Andric matchingModules.GetModuleAtIndex(i))) 16660b57cec5SDimitry Andric return false; 16670b57cec5SDimitry Andric } 16680b57cec5SDimitry Andric return true; 16690b57cec5SDimitry Andric } 16700b57cec5SDimitry Andric } 16710b57cec5SDimitry Andric return false; 16720b57cec5SDimitry Andric } 16730b57cec5SDimitry Andric 16740b57cec5SDimitry Andric bool Target::ModuleIsExcludedForUnconstrainedSearches( 16750b57cec5SDimitry Andric const lldb::ModuleSP &module_sp) { 16760b57cec5SDimitry Andric if (GetBreakpointsConsultPlatformAvoidList()) { 16770b57cec5SDimitry Andric if (m_platform_sp) 16780b57cec5SDimitry Andric return m_platform_sp->ModuleIsExcludedForUnconstrainedSearches(*this, 16790b57cec5SDimitry Andric module_sp); 16800b57cec5SDimitry Andric } 16810b57cec5SDimitry Andric return false; 16820b57cec5SDimitry Andric } 16830b57cec5SDimitry Andric 16840b57cec5SDimitry Andric size_t Target::ReadMemoryFromFileCache(const Address &addr, void *dst, 16850b57cec5SDimitry Andric size_t dst_len, Status &error) { 16860b57cec5SDimitry Andric SectionSP section_sp(addr.GetSection()); 16870b57cec5SDimitry Andric if (section_sp) { 16880b57cec5SDimitry Andric // If the contents of this section are encrypted, the on-disk file is 16890b57cec5SDimitry Andric // unusable. Read only from live memory. 16900b57cec5SDimitry Andric if (section_sp->IsEncrypted()) { 16910b57cec5SDimitry Andric error.SetErrorString("section is encrypted"); 16920b57cec5SDimitry Andric return 0; 16930b57cec5SDimitry Andric } 16940b57cec5SDimitry Andric ModuleSP module_sp(section_sp->GetModule()); 16950b57cec5SDimitry Andric if (module_sp) { 16960b57cec5SDimitry Andric ObjectFile *objfile = section_sp->GetModule()->GetObjectFile(); 16970b57cec5SDimitry Andric if (objfile) { 16980b57cec5SDimitry Andric size_t bytes_read = objfile->ReadSectionData( 16990b57cec5SDimitry Andric section_sp.get(), addr.GetOffset(), dst, dst_len); 17000b57cec5SDimitry Andric if (bytes_read > 0) 17010b57cec5SDimitry Andric return bytes_read; 17020b57cec5SDimitry Andric else 17030b57cec5SDimitry Andric error.SetErrorStringWithFormat("error reading data from section %s", 17040b57cec5SDimitry Andric section_sp->GetName().GetCString()); 17050b57cec5SDimitry Andric } else 17060b57cec5SDimitry Andric error.SetErrorString("address isn't from a object file"); 17070b57cec5SDimitry Andric } else 17080b57cec5SDimitry Andric error.SetErrorString("address isn't in a module"); 17090b57cec5SDimitry Andric } else 17100b57cec5SDimitry Andric error.SetErrorString("address doesn't contain a section that points to a " 17110b57cec5SDimitry Andric "section in a object file"); 17120b57cec5SDimitry Andric 17130b57cec5SDimitry Andric return 0; 17140b57cec5SDimitry Andric } 17150b57cec5SDimitry Andric 17160b57cec5SDimitry Andric size_t Target::ReadMemory(const Address &addr, bool prefer_file_cache, 17170b57cec5SDimitry Andric void *dst, size_t dst_len, Status &error, 17180b57cec5SDimitry Andric lldb::addr_t *load_addr_ptr) { 17190b57cec5SDimitry Andric error.Clear(); 17200b57cec5SDimitry Andric 17210b57cec5SDimitry Andric // if we end up reading this from process memory, we will fill this with the 17220b57cec5SDimitry Andric // actual load address 17230b57cec5SDimitry Andric if (load_addr_ptr) 17240b57cec5SDimitry Andric *load_addr_ptr = LLDB_INVALID_ADDRESS; 17250b57cec5SDimitry Andric 17260b57cec5SDimitry Andric size_t bytes_read = 0; 17270b57cec5SDimitry Andric 17280b57cec5SDimitry Andric addr_t load_addr = LLDB_INVALID_ADDRESS; 17290b57cec5SDimitry Andric addr_t file_addr = LLDB_INVALID_ADDRESS; 17300b57cec5SDimitry Andric Address resolved_addr; 17310b57cec5SDimitry Andric if (!addr.IsSectionOffset()) { 17320b57cec5SDimitry Andric SectionLoadList §ion_load_list = GetSectionLoadList(); 17330b57cec5SDimitry Andric if (section_load_list.IsEmpty()) { 17340b57cec5SDimitry Andric // No sections are loaded, so we must assume we are not running yet and 17350b57cec5SDimitry Andric // anything we are given is a file address. 17360b57cec5SDimitry Andric file_addr = addr.GetOffset(); // "addr" doesn't have a section, so its 17370b57cec5SDimitry Andric // offset is the file address 17380b57cec5SDimitry Andric m_images.ResolveFileAddress(file_addr, resolved_addr); 17390b57cec5SDimitry Andric } else { 17400b57cec5SDimitry Andric // We have at least one section loaded. This can be because we have 17410b57cec5SDimitry Andric // manually loaded some sections with "target modules load ..." or 17420b57cec5SDimitry Andric // because we have have a live process that has sections loaded through 17430b57cec5SDimitry Andric // the dynamic loader 17440b57cec5SDimitry Andric load_addr = addr.GetOffset(); // "addr" doesn't have a section, so its 17450b57cec5SDimitry Andric // offset is the load address 17460b57cec5SDimitry Andric section_load_list.ResolveLoadAddress(load_addr, resolved_addr); 17470b57cec5SDimitry Andric } 17480b57cec5SDimitry Andric } 17490b57cec5SDimitry Andric if (!resolved_addr.IsValid()) 17500b57cec5SDimitry Andric resolved_addr = addr; 17510b57cec5SDimitry Andric 17520b57cec5SDimitry Andric if (prefer_file_cache) { 17530b57cec5SDimitry Andric bytes_read = ReadMemoryFromFileCache(resolved_addr, dst, dst_len, error); 17540b57cec5SDimitry Andric if (bytes_read > 0) 17550b57cec5SDimitry Andric return bytes_read; 17560b57cec5SDimitry Andric } 17570b57cec5SDimitry Andric 17580b57cec5SDimitry Andric if (ProcessIsValid()) { 17590b57cec5SDimitry Andric if (load_addr == LLDB_INVALID_ADDRESS) 17600b57cec5SDimitry Andric load_addr = resolved_addr.GetLoadAddress(this); 17610b57cec5SDimitry Andric 17620b57cec5SDimitry Andric if (load_addr == LLDB_INVALID_ADDRESS) { 17630b57cec5SDimitry Andric ModuleSP addr_module_sp(resolved_addr.GetModule()); 17640b57cec5SDimitry Andric if (addr_module_sp && addr_module_sp->GetFileSpec()) 17650b57cec5SDimitry Andric error.SetErrorStringWithFormatv( 17660b57cec5SDimitry Andric "{0:F}[{1:x+}] can't be resolved, {0:F} is not currently loaded", 17670b57cec5SDimitry Andric addr_module_sp->GetFileSpec(), resolved_addr.GetFileAddress()); 17680b57cec5SDimitry Andric else 17690b57cec5SDimitry Andric error.SetErrorStringWithFormat("0x%" PRIx64 " can't be resolved", 17700b57cec5SDimitry Andric resolved_addr.GetFileAddress()); 17710b57cec5SDimitry Andric } else { 17720b57cec5SDimitry Andric bytes_read = m_process_sp->ReadMemory(load_addr, dst, dst_len, error); 17730b57cec5SDimitry Andric if (bytes_read != dst_len) { 17740b57cec5SDimitry Andric if (error.Success()) { 17750b57cec5SDimitry Andric if (bytes_read == 0) 17760b57cec5SDimitry Andric error.SetErrorStringWithFormat( 17770b57cec5SDimitry Andric "read memory from 0x%" PRIx64 " failed", load_addr); 17780b57cec5SDimitry Andric else 17790b57cec5SDimitry Andric error.SetErrorStringWithFormat( 17800b57cec5SDimitry Andric "only %" PRIu64 " of %" PRIu64 17810b57cec5SDimitry Andric " bytes were read from memory at 0x%" PRIx64, 17820b57cec5SDimitry Andric (uint64_t)bytes_read, (uint64_t)dst_len, load_addr); 17830b57cec5SDimitry Andric } 17840b57cec5SDimitry Andric } 17850b57cec5SDimitry Andric if (bytes_read) { 17860b57cec5SDimitry Andric if (load_addr_ptr) 17870b57cec5SDimitry Andric *load_addr_ptr = load_addr; 17880b57cec5SDimitry Andric return bytes_read; 17890b57cec5SDimitry Andric } 17900b57cec5SDimitry Andric // If the address is not section offset we have an address that doesn't 17910b57cec5SDimitry Andric // resolve to any address in any currently loaded shared libraries and we 17920b57cec5SDimitry Andric // failed to read memory so there isn't anything more we can do. If it is 17930b57cec5SDimitry Andric // section offset, we might be able to read cached memory from the object 17940b57cec5SDimitry Andric // file. 17950b57cec5SDimitry Andric if (!resolved_addr.IsSectionOffset()) 17960b57cec5SDimitry Andric return 0; 17970b57cec5SDimitry Andric } 17980b57cec5SDimitry Andric } 17990b57cec5SDimitry Andric 18000b57cec5SDimitry Andric if (!prefer_file_cache && resolved_addr.IsSectionOffset()) { 18010b57cec5SDimitry Andric // If we didn't already try and read from the object file cache, then try 18020b57cec5SDimitry Andric // it after failing to read from the process. 18030b57cec5SDimitry Andric return ReadMemoryFromFileCache(resolved_addr, dst, dst_len, error); 18040b57cec5SDimitry Andric } 18050b57cec5SDimitry Andric return 0; 18060b57cec5SDimitry Andric } 18070b57cec5SDimitry Andric 18080b57cec5SDimitry Andric size_t Target::ReadCStringFromMemory(const Address &addr, std::string &out_str, 18090b57cec5SDimitry Andric Status &error) { 18100b57cec5SDimitry Andric char buf[256]; 18110b57cec5SDimitry Andric out_str.clear(); 18120b57cec5SDimitry Andric addr_t curr_addr = addr.GetLoadAddress(this); 18130b57cec5SDimitry Andric Address address(addr); 18140b57cec5SDimitry Andric while (true) { 18150b57cec5SDimitry Andric size_t length = ReadCStringFromMemory(address, buf, sizeof(buf), error); 18160b57cec5SDimitry Andric if (length == 0) 18170b57cec5SDimitry Andric break; 18180b57cec5SDimitry Andric out_str.append(buf, length); 18190b57cec5SDimitry Andric // If we got "length - 1" bytes, we didn't get the whole C string, we need 18200b57cec5SDimitry Andric // to read some more characters 18210b57cec5SDimitry Andric if (length == sizeof(buf) - 1) 18220b57cec5SDimitry Andric curr_addr += length; 18230b57cec5SDimitry Andric else 18240b57cec5SDimitry Andric break; 18250b57cec5SDimitry Andric address = Address(curr_addr); 18260b57cec5SDimitry Andric } 18270b57cec5SDimitry Andric return out_str.size(); 18280b57cec5SDimitry Andric } 18290b57cec5SDimitry Andric 18300b57cec5SDimitry Andric size_t Target::ReadCStringFromMemory(const Address &addr, char *dst, 18310b57cec5SDimitry Andric size_t dst_max_len, Status &result_error) { 18320b57cec5SDimitry Andric size_t total_cstr_len = 0; 18330b57cec5SDimitry Andric if (dst && dst_max_len) { 18340b57cec5SDimitry Andric result_error.Clear(); 18350b57cec5SDimitry Andric // NULL out everything just to be safe 18360b57cec5SDimitry Andric memset(dst, 0, dst_max_len); 18370b57cec5SDimitry Andric Status error; 18380b57cec5SDimitry Andric addr_t curr_addr = addr.GetLoadAddress(this); 18390b57cec5SDimitry Andric Address address(addr); 18400b57cec5SDimitry Andric 18410b57cec5SDimitry Andric // We could call m_process_sp->GetMemoryCacheLineSize() but I don't think 18420b57cec5SDimitry Andric // this really needs to be tied to the memory cache subsystem's cache line 18430b57cec5SDimitry Andric // size, so leave this as a fixed constant. 18440b57cec5SDimitry Andric const size_t cache_line_size = 512; 18450b57cec5SDimitry Andric 18460b57cec5SDimitry Andric size_t bytes_left = dst_max_len - 1; 18470b57cec5SDimitry Andric char *curr_dst = dst; 18480b57cec5SDimitry Andric 18490b57cec5SDimitry Andric while (bytes_left > 0) { 18500b57cec5SDimitry Andric addr_t cache_line_bytes_left = 18510b57cec5SDimitry Andric cache_line_size - (curr_addr % cache_line_size); 18520b57cec5SDimitry Andric addr_t bytes_to_read = 18530b57cec5SDimitry Andric std::min<addr_t>(bytes_left, cache_line_bytes_left); 18540b57cec5SDimitry Andric size_t bytes_read = 18550b57cec5SDimitry Andric ReadMemory(address, false, curr_dst, bytes_to_read, error); 18560b57cec5SDimitry Andric 18570b57cec5SDimitry Andric if (bytes_read == 0) { 18580b57cec5SDimitry Andric result_error = error; 18590b57cec5SDimitry Andric dst[total_cstr_len] = '\0'; 18600b57cec5SDimitry Andric break; 18610b57cec5SDimitry Andric } 18620b57cec5SDimitry Andric const size_t len = strlen(curr_dst); 18630b57cec5SDimitry Andric 18640b57cec5SDimitry Andric total_cstr_len += len; 18650b57cec5SDimitry Andric 18660b57cec5SDimitry Andric if (len < bytes_to_read) 18670b57cec5SDimitry Andric break; 18680b57cec5SDimitry Andric 18690b57cec5SDimitry Andric curr_dst += bytes_read; 18700b57cec5SDimitry Andric curr_addr += bytes_read; 18710b57cec5SDimitry Andric bytes_left -= bytes_read; 18720b57cec5SDimitry Andric address = Address(curr_addr); 18730b57cec5SDimitry Andric } 18740b57cec5SDimitry Andric } else { 18750b57cec5SDimitry Andric if (dst == nullptr) 18760b57cec5SDimitry Andric result_error.SetErrorString("invalid arguments"); 18770b57cec5SDimitry Andric else 18780b57cec5SDimitry Andric result_error.Clear(); 18790b57cec5SDimitry Andric } 18800b57cec5SDimitry Andric return total_cstr_len; 18810b57cec5SDimitry Andric } 18820b57cec5SDimitry Andric 18830b57cec5SDimitry Andric size_t Target::ReadScalarIntegerFromMemory(const Address &addr, 18840b57cec5SDimitry Andric bool prefer_file_cache, 18850b57cec5SDimitry Andric uint32_t byte_size, bool is_signed, 18860b57cec5SDimitry Andric Scalar &scalar, Status &error) { 18870b57cec5SDimitry Andric uint64_t uval; 18880b57cec5SDimitry Andric 18890b57cec5SDimitry Andric if (byte_size <= sizeof(uval)) { 18900b57cec5SDimitry Andric size_t bytes_read = 18910b57cec5SDimitry Andric ReadMemory(addr, prefer_file_cache, &uval, byte_size, error); 18920b57cec5SDimitry Andric if (bytes_read == byte_size) { 18930b57cec5SDimitry Andric DataExtractor data(&uval, sizeof(uval), m_arch.GetSpec().GetByteOrder(), 18940b57cec5SDimitry Andric m_arch.GetSpec().GetAddressByteSize()); 18950b57cec5SDimitry Andric lldb::offset_t offset = 0; 18960b57cec5SDimitry Andric if (byte_size <= 4) 18970b57cec5SDimitry Andric scalar = data.GetMaxU32(&offset, byte_size); 18980b57cec5SDimitry Andric else 18990b57cec5SDimitry Andric scalar = data.GetMaxU64(&offset, byte_size); 19000b57cec5SDimitry Andric 19010b57cec5SDimitry Andric if (is_signed) 19020b57cec5SDimitry Andric scalar.SignExtend(byte_size * 8); 19030b57cec5SDimitry Andric return bytes_read; 19040b57cec5SDimitry Andric } 19050b57cec5SDimitry Andric } else { 19060b57cec5SDimitry Andric error.SetErrorStringWithFormat( 19070b57cec5SDimitry Andric "byte size of %u is too large for integer scalar type", byte_size); 19080b57cec5SDimitry Andric } 19090b57cec5SDimitry Andric return 0; 19100b57cec5SDimitry Andric } 19110b57cec5SDimitry Andric 19120b57cec5SDimitry Andric uint64_t Target::ReadUnsignedIntegerFromMemory(const Address &addr, 19130b57cec5SDimitry Andric bool prefer_file_cache, 19140b57cec5SDimitry Andric size_t integer_byte_size, 19150b57cec5SDimitry Andric uint64_t fail_value, 19160b57cec5SDimitry Andric Status &error) { 19170b57cec5SDimitry Andric Scalar scalar; 19180b57cec5SDimitry Andric if (ReadScalarIntegerFromMemory(addr, prefer_file_cache, integer_byte_size, 19190b57cec5SDimitry Andric false, scalar, error)) 19200b57cec5SDimitry Andric return scalar.ULongLong(fail_value); 19210b57cec5SDimitry Andric return fail_value; 19220b57cec5SDimitry Andric } 19230b57cec5SDimitry Andric 19240b57cec5SDimitry Andric bool Target::ReadPointerFromMemory(const Address &addr, bool prefer_file_cache, 19250b57cec5SDimitry Andric Status &error, Address &pointer_addr) { 19260b57cec5SDimitry Andric Scalar scalar; 19270b57cec5SDimitry Andric if (ReadScalarIntegerFromMemory(addr, prefer_file_cache, 19289dba64beSDimitry Andric m_arch.GetSpec().GetAddressByteSize(), false, 19299dba64beSDimitry Andric scalar, error)) { 19300b57cec5SDimitry Andric addr_t pointer_vm_addr = scalar.ULongLong(LLDB_INVALID_ADDRESS); 19310b57cec5SDimitry Andric if (pointer_vm_addr != LLDB_INVALID_ADDRESS) { 19320b57cec5SDimitry Andric SectionLoadList §ion_load_list = GetSectionLoadList(); 19330b57cec5SDimitry Andric if (section_load_list.IsEmpty()) { 19340b57cec5SDimitry Andric // No sections are loaded, so we must assume we are not running yet and 19350b57cec5SDimitry Andric // anything we are given is a file address. 19360b57cec5SDimitry Andric m_images.ResolveFileAddress(pointer_vm_addr, pointer_addr); 19370b57cec5SDimitry Andric } else { 19380b57cec5SDimitry Andric // We have at least one section loaded. This can be because we have 19390b57cec5SDimitry Andric // manually loaded some sections with "target modules load ..." or 19400b57cec5SDimitry Andric // because we have have a live process that has sections loaded through 19410b57cec5SDimitry Andric // the dynamic loader 19420b57cec5SDimitry Andric section_load_list.ResolveLoadAddress(pointer_vm_addr, pointer_addr); 19430b57cec5SDimitry Andric } 19440b57cec5SDimitry Andric // We weren't able to resolve the pointer value, so just return an 19450b57cec5SDimitry Andric // address with no section 19460b57cec5SDimitry Andric if (!pointer_addr.IsValid()) 19470b57cec5SDimitry Andric pointer_addr.SetOffset(pointer_vm_addr); 19480b57cec5SDimitry Andric return true; 19490b57cec5SDimitry Andric } 19500b57cec5SDimitry Andric } 19510b57cec5SDimitry Andric return false; 19520b57cec5SDimitry Andric } 19530b57cec5SDimitry Andric 19540b57cec5SDimitry Andric ModuleSP Target::GetOrCreateModule(const ModuleSpec &module_spec, bool notify, 19550b57cec5SDimitry Andric Status *error_ptr) { 19560b57cec5SDimitry Andric ModuleSP module_sp; 19570b57cec5SDimitry Andric 19580b57cec5SDimitry Andric Status error; 19590b57cec5SDimitry Andric 19600b57cec5SDimitry Andric // First see if we already have this module in our module list. If we do, 19610b57cec5SDimitry Andric // then we're done, we don't need to consult the shared modules list. But 19620b57cec5SDimitry Andric // only do this if we are passed a UUID. 19630b57cec5SDimitry Andric 19640b57cec5SDimitry Andric if (module_spec.GetUUID().IsValid()) 19650b57cec5SDimitry Andric module_sp = m_images.FindFirstModule(module_spec); 19660b57cec5SDimitry Andric 19670b57cec5SDimitry Andric if (!module_sp) { 1968eaeb601bSDimitry Andric llvm::SmallVector<ModuleSP, 1> 1969eaeb601bSDimitry Andric old_modules; // This will get filled in if we have a new version 19700b57cec5SDimitry Andric // of the library 19710b57cec5SDimitry Andric bool did_create_module = false; 19720b57cec5SDimitry Andric FileSpecList search_paths = GetExecutableSearchPaths(); 19730b57cec5SDimitry Andric // If there are image search path entries, try to use them first to acquire 19740b57cec5SDimitry Andric // a suitable image. 19750b57cec5SDimitry Andric if (m_image_search_paths.GetSize()) { 19760b57cec5SDimitry Andric ModuleSpec transformed_spec(module_spec); 19770b57cec5SDimitry Andric if (m_image_search_paths.RemapPath( 19780b57cec5SDimitry Andric module_spec.GetFileSpec().GetDirectory(), 19790b57cec5SDimitry Andric transformed_spec.GetFileSpec().GetDirectory())) { 19800b57cec5SDimitry Andric transformed_spec.GetFileSpec().GetFilename() = 19810b57cec5SDimitry Andric module_spec.GetFileSpec().GetFilename(); 19820b57cec5SDimitry Andric error = ModuleList::GetSharedModule(transformed_spec, module_sp, 1983eaeb601bSDimitry Andric &search_paths, &old_modules, 19849dba64beSDimitry Andric &did_create_module); 19850b57cec5SDimitry Andric } 19860b57cec5SDimitry Andric } 19870b57cec5SDimitry Andric 19880b57cec5SDimitry Andric if (!module_sp) { 19890b57cec5SDimitry Andric // If we have a UUID, we can check our global shared module list in case 19900b57cec5SDimitry Andric // we already have it. If we don't have a valid UUID, then we can't since 19910b57cec5SDimitry Andric // the path in "module_spec" will be a platform path, and we will need to 19920b57cec5SDimitry Andric // let the platform find that file. For example, we could be asking for 19930b57cec5SDimitry Andric // "/usr/lib/dyld" and if we do not have a UUID, we don't want to pick 19940b57cec5SDimitry Andric // the local copy of "/usr/lib/dyld" since our platform could be a remote 19950b57cec5SDimitry Andric // platform that has its own "/usr/lib/dyld" in an SDK or in a local file 19960b57cec5SDimitry Andric // cache. 19970b57cec5SDimitry Andric if (module_spec.GetUUID().IsValid()) { 19980b57cec5SDimitry Andric // We have a UUID, it is OK to check the global module list... 19999dba64beSDimitry Andric error = 20009dba64beSDimitry Andric ModuleList::GetSharedModule(module_spec, module_sp, &search_paths, 2001eaeb601bSDimitry Andric &old_modules, &did_create_module); 20020b57cec5SDimitry Andric } 20030b57cec5SDimitry Andric 20040b57cec5SDimitry Andric if (!module_sp) { 20050b57cec5SDimitry Andric // The platform is responsible for finding and caching an appropriate 20060b57cec5SDimitry Andric // module in the shared module cache. 20070b57cec5SDimitry Andric if (m_platform_sp) { 20080b57cec5SDimitry Andric error = m_platform_sp->GetSharedModule( 20099dba64beSDimitry Andric module_spec, m_process_sp.get(), module_sp, &search_paths, 2010eaeb601bSDimitry Andric &old_modules, &did_create_module); 20110b57cec5SDimitry Andric } else { 20120b57cec5SDimitry Andric error.SetErrorString("no platform is currently set"); 20130b57cec5SDimitry Andric } 20140b57cec5SDimitry Andric } 20150b57cec5SDimitry Andric } 20160b57cec5SDimitry Andric 20170b57cec5SDimitry Andric // We found a module that wasn't in our target list. Let's make sure that 20180b57cec5SDimitry Andric // there wasn't an equivalent module in the list already, and if there was, 20190b57cec5SDimitry Andric // let's remove it. 20200b57cec5SDimitry Andric if (module_sp) { 20210b57cec5SDimitry Andric ObjectFile *objfile = module_sp->GetObjectFile(); 20220b57cec5SDimitry Andric if (objfile) { 20230b57cec5SDimitry Andric switch (objfile->GetType()) { 20240b57cec5SDimitry Andric case ObjectFile::eTypeCoreFile: /// A core file that has a checkpoint of 20250b57cec5SDimitry Andric /// a program's execution state 20260b57cec5SDimitry Andric case ObjectFile::eTypeExecutable: /// A normal executable 20270b57cec5SDimitry Andric case ObjectFile::eTypeDynamicLinker: /// The platform's dynamic linker 20280b57cec5SDimitry Andric /// executable 20290b57cec5SDimitry Andric case ObjectFile::eTypeObjectFile: /// An intermediate object file 20300b57cec5SDimitry Andric case ObjectFile::eTypeSharedLibrary: /// A shared library that can be 20310b57cec5SDimitry Andric /// used during execution 20320b57cec5SDimitry Andric break; 20330b57cec5SDimitry Andric case ObjectFile::eTypeDebugInfo: /// An object file that contains only 20340b57cec5SDimitry Andric /// debug information 20350b57cec5SDimitry Andric if (error_ptr) 20360b57cec5SDimitry Andric error_ptr->SetErrorString("debug info files aren't valid target " 20370b57cec5SDimitry Andric "modules, please specify an executable"); 20380b57cec5SDimitry Andric return ModuleSP(); 20390b57cec5SDimitry Andric case ObjectFile::eTypeStubLibrary: /// A library that can be linked 20400b57cec5SDimitry Andric /// against but not used for 20410b57cec5SDimitry Andric /// execution 20420b57cec5SDimitry Andric if (error_ptr) 20430b57cec5SDimitry Andric error_ptr->SetErrorString("stub libraries aren't valid target " 20440b57cec5SDimitry Andric "modules, please specify an executable"); 20450b57cec5SDimitry Andric return ModuleSP(); 20460b57cec5SDimitry Andric default: 20470b57cec5SDimitry Andric if (error_ptr) 20480b57cec5SDimitry Andric error_ptr->SetErrorString( 20490b57cec5SDimitry Andric "unsupported file type, please specify an executable"); 20500b57cec5SDimitry Andric return ModuleSP(); 20510b57cec5SDimitry Andric } 20520b57cec5SDimitry Andric // GetSharedModule is not guaranteed to find the old shared module, for 20530b57cec5SDimitry Andric // instance in the common case where you pass in the UUID, it is only 20540b57cec5SDimitry Andric // going to find the one module matching the UUID. In fact, it has no 20550b57cec5SDimitry Andric // good way to know what the "old module" relevant to this target is, 20560b57cec5SDimitry Andric // since there might be many copies of a module with this file spec in 20570b57cec5SDimitry Andric // various running debug sessions, but only one of them will belong to 20580b57cec5SDimitry Andric // this target. So let's remove the UUID from the module list, and look 20590b57cec5SDimitry Andric // in the target's module list. Only do this if there is SOMETHING else 20600b57cec5SDimitry Andric // in the module spec... 20610b57cec5SDimitry Andric if (module_spec.GetUUID().IsValid() && 20620b57cec5SDimitry Andric !module_spec.GetFileSpec().GetFilename().IsEmpty() && 20630b57cec5SDimitry Andric !module_spec.GetFileSpec().GetDirectory().IsEmpty()) { 20640b57cec5SDimitry Andric ModuleSpec module_spec_copy(module_spec.GetFileSpec()); 20650b57cec5SDimitry Andric module_spec_copy.GetUUID().Clear(); 20660b57cec5SDimitry Andric 20670b57cec5SDimitry Andric ModuleList found_modules; 20680b57cec5SDimitry Andric m_images.FindModules(module_spec_copy, found_modules); 2069eaeb601bSDimitry Andric found_modules.ForEach([&](const ModuleSP &found_module) -> bool { 2070eaeb601bSDimitry Andric old_modules.push_back(found_module); 2071eaeb601bSDimitry Andric return true; 2072eaeb601bSDimitry Andric }); 20730b57cec5SDimitry Andric } 20740b57cec5SDimitry Andric 20750b57cec5SDimitry Andric // Preload symbols outside of any lock, so hopefully we can do this for 20760b57cec5SDimitry Andric // each library in parallel. 20770b57cec5SDimitry Andric if (GetPreloadSymbols()) 20780b57cec5SDimitry Andric module_sp->PreloadSymbols(); 20790b57cec5SDimitry Andric 2080eaeb601bSDimitry Andric llvm::SmallVector<ModuleSP, 1> replaced_modules; 2081eaeb601bSDimitry Andric for (ModuleSP &old_module_sp : old_modules) { 2082eaeb601bSDimitry Andric if (m_images.GetIndexForModule(old_module_sp.get()) != 20830b57cec5SDimitry Andric LLDB_INVALID_INDEX32) { 2084eaeb601bSDimitry Andric if (replaced_modules.empty()) 20850b57cec5SDimitry Andric m_images.ReplaceModule(old_module_sp, module_sp); 2086eaeb601bSDimitry Andric else 2087eaeb601bSDimitry Andric m_images.Remove(old_module_sp); 2088eaeb601bSDimitry Andric 2089eaeb601bSDimitry Andric replaced_modules.push_back(std::move(old_module_sp)); 2090eaeb601bSDimitry Andric } 2091eaeb601bSDimitry Andric } 2092eaeb601bSDimitry Andric 2093eaeb601bSDimitry Andric if (replaced_modules.size() > 1) { 2094eaeb601bSDimitry Andric // The same new module replaced multiple old modules 2095eaeb601bSDimitry Andric // simultaneously. It's not clear this should ever 2096eaeb601bSDimitry Andric // happen (if we always replace old modules as we add 2097eaeb601bSDimitry Andric // new ones, presumably we should never have more than 2098eaeb601bSDimitry Andric // one old one). If there are legitimate cases where 2099eaeb601bSDimitry Andric // this happens, then the ModuleList::Notifier interface 2100eaeb601bSDimitry Andric // may need to be adjusted to allow reporting this. 2101eaeb601bSDimitry Andric // In the meantime, just log that this has happened; just 2102eaeb601bSDimitry Andric // above we called ReplaceModule on the first one, and Remove 2103eaeb601bSDimitry Andric // on the rest. 2104eaeb601bSDimitry Andric if (Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET | 2105eaeb601bSDimitry Andric LIBLLDB_LOG_MODULES)) { 2106eaeb601bSDimitry Andric StreamString message; 2107eaeb601bSDimitry Andric auto dump = [&message](Module &dump_module) -> void { 2108eaeb601bSDimitry Andric UUID dump_uuid = dump_module.GetUUID(); 2109eaeb601bSDimitry Andric 2110eaeb601bSDimitry Andric message << '['; 2111eaeb601bSDimitry Andric dump_module.GetDescription(message.AsRawOstream()); 2112eaeb601bSDimitry Andric message << " (uuid "; 2113eaeb601bSDimitry Andric 2114eaeb601bSDimitry Andric if (dump_uuid.IsValid()) 2115eaeb601bSDimitry Andric dump_uuid.Dump(&message); 2116eaeb601bSDimitry Andric else 2117eaeb601bSDimitry Andric message << "not specified"; 2118eaeb601bSDimitry Andric 2119eaeb601bSDimitry Andric message << ")]"; 2120eaeb601bSDimitry Andric }; 2121eaeb601bSDimitry Andric 2122eaeb601bSDimitry Andric message << "New module "; 2123eaeb601bSDimitry Andric dump(*module_sp); 2124eaeb601bSDimitry Andric message.AsRawOstream() 2125eaeb601bSDimitry Andric << llvm::formatv(" simultaneously replaced {0} old modules: ", 2126eaeb601bSDimitry Andric replaced_modules.size()); 2127eaeb601bSDimitry Andric for (ModuleSP &replaced_module_sp : replaced_modules) 2128eaeb601bSDimitry Andric dump(*replaced_module_sp); 2129eaeb601bSDimitry Andric 2130eaeb601bSDimitry Andric log->PutString(message.GetString()); 2131eaeb601bSDimitry Andric } 2132eaeb601bSDimitry Andric } 2133eaeb601bSDimitry Andric 2134eaeb601bSDimitry Andric if (replaced_modules.empty()) 2135eaeb601bSDimitry Andric m_images.Append(module_sp, notify); 2136eaeb601bSDimitry Andric 2137eaeb601bSDimitry Andric for (ModuleSP &old_module_sp : replaced_modules) { 21380b57cec5SDimitry Andric Module *old_module_ptr = old_module_sp.get(); 21390b57cec5SDimitry Andric old_module_sp.reset(); 21400b57cec5SDimitry Andric ModuleList::RemoveSharedModuleIfOrphaned(old_module_ptr); 21410b57cec5SDimitry Andric } 21420b57cec5SDimitry Andric } else 21430b57cec5SDimitry Andric module_sp.reset(); 21440b57cec5SDimitry Andric } 21450b57cec5SDimitry Andric } 21460b57cec5SDimitry Andric if (error_ptr) 21470b57cec5SDimitry Andric *error_ptr = error; 21480b57cec5SDimitry Andric return module_sp; 21490b57cec5SDimitry Andric } 21500b57cec5SDimitry Andric 21510b57cec5SDimitry Andric TargetSP Target::CalculateTarget() { return shared_from_this(); } 21520b57cec5SDimitry Andric 21530b57cec5SDimitry Andric ProcessSP Target::CalculateProcess() { return m_process_sp; } 21540b57cec5SDimitry Andric 21550b57cec5SDimitry Andric ThreadSP Target::CalculateThread() { return ThreadSP(); } 21560b57cec5SDimitry Andric 21570b57cec5SDimitry Andric StackFrameSP Target::CalculateStackFrame() { return StackFrameSP(); } 21580b57cec5SDimitry Andric 21590b57cec5SDimitry Andric void Target::CalculateExecutionContext(ExecutionContext &exe_ctx) { 21600b57cec5SDimitry Andric exe_ctx.Clear(); 21610b57cec5SDimitry Andric exe_ctx.SetTargetPtr(this); 21620b57cec5SDimitry Andric } 21630b57cec5SDimitry Andric 21640b57cec5SDimitry Andric PathMappingList &Target::GetImageSearchPathList() { 21650b57cec5SDimitry Andric return m_image_search_paths; 21660b57cec5SDimitry Andric } 21670b57cec5SDimitry Andric 21680b57cec5SDimitry Andric void Target::ImageSearchPathsChanged(const PathMappingList &path_list, 21690b57cec5SDimitry Andric void *baton) { 21700b57cec5SDimitry Andric Target *target = (Target *)baton; 21710b57cec5SDimitry Andric ModuleSP exe_module_sp(target->GetExecutableModule()); 21720b57cec5SDimitry Andric if (exe_module_sp) 21730b57cec5SDimitry Andric target->SetExecutableModule(exe_module_sp, eLoadDependentsYes); 21740b57cec5SDimitry Andric } 21750b57cec5SDimitry Andric 21769dba64beSDimitry Andric llvm::Expected<TypeSystem &> 21779dba64beSDimitry Andric Target::GetScratchTypeSystemForLanguage(lldb::LanguageType language, 21780b57cec5SDimitry Andric bool create_on_demand) { 21790b57cec5SDimitry Andric if (!m_valid) 21809dba64beSDimitry Andric return llvm::make_error<llvm::StringError>("Invalid Target", 21819dba64beSDimitry Andric llvm::inconvertibleErrorCode()); 21820b57cec5SDimitry Andric 21830b57cec5SDimitry Andric if (language == eLanguageTypeMipsAssembler // GNU AS and LLVM use it for all 21840b57cec5SDimitry Andric // assembly code 21850b57cec5SDimitry Andric || language == eLanguageTypeUnknown) { 21869dba64beSDimitry Andric LanguageSet languages_for_expressions = 21879dba64beSDimitry Andric Language::GetLanguagesSupportingTypeSystemsForExpressions(); 21880b57cec5SDimitry Andric 21899dba64beSDimitry Andric if (languages_for_expressions[eLanguageTypeC]) { 21900b57cec5SDimitry Andric language = eLanguageTypeC; // LLDB's default. Override by setting the 21910b57cec5SDimitry Andric // target language. 21920b57cec5SDimitry Andric } else { 21939dba64beSDimitry Andric if (languages_for_expressions.Empty()) 21949dba64beSDimitry Andric return llvm::make_error<llvm::StringError>( 21959dba64beSDimitry Andric "No expression support for any languages", 21969dba64beSDimitry Andric llvm::inconvertibleErrorCode()); 21979dba64beSDimitry Andric language = (LanguageType)languages_for_expressions.bitvector.find_first(); 21980b57cec5SDimitry Andric } 21990b57cec5SDimitry Andric } 22000b57cec5SDimitry Andric 22010b57cec5SDimitry Andric return m_scratch_type_system_map.GetTypeSystemForLanguage(language, this, 22020b57cec5SDimitry Andric create_on_demand); 22030b57cec5SDimitry Andric } 22040b57cec5SDimitry Andric 22059dba64beSDimitry Andric std::vector<TypeSystem *> Target::GetScratchTypeSystems(bool create_on_demand) { 22069dba64beSDimitry Andric if (!m_valid) 22079dba64beSDimitry Andric return {}; 22089dba64beSDimitry Andric 22099dba64beSDimitry Andric std::vector<TypeSystem *> scratch_type_systems; 22109dba64beSDimitry Andric 22119dba64beSDimitry Andric LanguageSet languages_for_expressions = 22129dba64beSDimitry Andric Language::GetLanguagesSupportingTypeSystemsForExpressions(); 22139dba64beSDimitry Andric 22149dba64beSDimitry Andric for (auto bit : languages_for_expressions.bitvector.set_bits()) { 22159dba64beSDimitry Andric auto language = (LanguageType)bit; 22169dba64beSDimitry Andric auto type_system_or_err = 22179dba64beSDimitry Andric GetScratchTypeSystemForLanguage(language, create_on_demand); 22189dba64beSDimitry Andric if (!type_system_or_err) 22199dba64beSDimitry Andric LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET), 22209dba64beSDimitry Andric type_system_or_err.takeError(), 22219dba64beSDimitry Andric "Language '{}' has expression support but no scratch type " 22229dba64beSDimitry Andric "system available", 22239dba64beSDimitry Andric Language::GetNameForLanguageType(language)); 22249dba64beSDimitry Andric else 22259dba64beSDimitry Andric scratch_type_systems.emplace_back(&type_system_or_err.get()); 22269dba64beSDimitry Andric } 22279dba64beSDimitry Andric 22289dba64beSDimitry Andric return scratch_type_systems; 22299dba64beSDimitry Andric } 22309dba64beSDimitry Andric 22310b57cec5SDimitry Andric PersistentExpressionState * 22320b57cec5SDimitry Andric Target::GetPersistentExpressionStateForLanguage(lldb::LanguageType language) { 22339dba64beSDimitry Andric auto type_system_or_err = GetScratchTypeSystemForLanguage(language, true); 22340b57cec5SDimitry Andric 22359dba64beSDimitry Andric if (auto err = type_system_or_err.takeError()) { 22369dba64beSDimitry Andric LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET), 22379dba64beSDimitry Andric std::move(err), 22389dba64beSDimitry Andric "Unable to get persistent expression state for language {}", 22399dba64beSDimitry Andric Language::GetNameForLanguageType(language)); 22400b57cec5SDimitry Andric return nullptr; 22410b57cec5SDimitry Andric } 22429dba64beSDimitry Andric 22439dba64beSDimitry Andric return type_system_or_err->GetPersistentExpressionState(); 22440b57cec5SDimitry Andric } 22450b57cec5SDimitry Andric 22460b57cec5SDimitry Andric UserExpression *Target::GetUserExpressionForLanguage( 22470b57cec5SDimitry Andric llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language, 22480b57cec5SDimitry Andric Expression::ResultType desired_type, 22499dba64beSDimitry Andric const EvaluateExpressionOptions &options, ValueObject *ctx_obj, 22509dba64beSDimitry Andric Status &error) { 22519dba64beSDimitry Andric auto type_system_or_err = GetScratchTypeSystemForLanguage(language); 22529dba64beSDimitry Andric if (auto err = type_system_or_err.takeError()) { 22530b57cec5SDimitry Andric error.SetErrorStringWithFormat( 22540b57cec5SDimitry Andric "Could not find type system for language %s: %s", 22550b57cec5SDimitry Andric Language::GetNameForLanguageType(language), 22569dba64beSDimitry Andric llvm::toString(std::move(err)).c_str()); 22570b57cec5SDimitry Andric return nullptr; 22580b57cec5SDimitry Andric } 22590b57cec5SDimitry Andric 22609dba64beSDimitry Andric auto *user_expr = type_system_or_err->GetUserExpression( 22619dba64beSDimitry Andric expr, prefix, language, desired_type, options, ctx_obj); 22620b57cec5SDimitry Andric if (!user_expr) 22630b57cec5SDimitry Andric error.SetErrorStringWithFormat( 22640b57cec5SDimitry Andric "Could not create an expression for language %s", 22650b57cec5SDimitry Andric Language::GetNameForLanguageType(language)); 22660b57cec5SDimitry Andric 22670b57cec5SDimitry Andric return user_expr; 22680b57cec5SDimitry Andric } 22690b57cec5SDimitry Andric 22700b57cec5SDimitry Andric FunctionCaller *Target::GetFunctionCallerForLanguage( 22710b57cec5SDimitry Andric lldb::LanguageType language, const CompilerType &return_type, 22720b57cec5SDimitry Andric const Address &function_address, const ValueList &arg_value_list, 22730b57cec5SDimitry Andric const char *name, Status &error) { 22749dba64beSDimitry Andric auto type_system_or_err = GetScratchTypeSystemForLanguage(language); 22759dba64beSDimitry Andric if (auto err = type_system_or_err.takeError()) { 22760b57cec5SDimitry Andric error.SetErrorStringWithFormat( 22770b57cec5SDimitry Andric "Could not find type system for language %s: %s", 22780b57cec5SDimitry Andric Language::GetNameForLanguageType(language), 22799dba64beSDimitry Andric llvm::toString(std::move(err)).c_str()); 22809dba64beSDimitry Andric return nullptr; 22810b57cec5SDimitry Andric } 22820b57cec5SDimitry Andric 22839dba64beSDimitry Andric auto *persistent_fn = type_system_or_err->GetFunctionCaller( 22849dba64beSDimitry Andric return_type, function_address, arg_value_list, name); 22850b57cec5SDimitry Andric if (!persistent_fn) 22860b57cec5SDimitry Andric error.SetErrorStringWithFormat( 22870b57cec5SDimitry Andric "Could not create an expression for language %s", 22880b57cec5SDimitry Andric Language::GetNameForLanguageType(language)); 22890b57cec5SDimitry Andric 22900b57cec5SDimitry Andric return persistent_fn; 22910b57cec5SDimitry Andric } 22920b57cec5SDimitry Andric 22930b57cec5SDimitry Andric UtilityFunction * 22940b57cec5SDimitry Andric Target::GetUtilityFunctionForLanguage(const char *text, 22950b57cec5SDimitry Andric lldb::LanguageType language, 22960b57cec5SDimitry Andric const char *name, Status &error) { 22979dba64beSDimitry Andric auto type_system_or_err = GetScratchTypeSystemForLanguage(language); 22980b57cec5SDimitry Andric 22999dba64beSDimitry Andric if (auto err = type_system_or_err.takeError()) { 23000b57cec5SDimitry Andric error.SetErrorStringWithFormat( 23010b57cec5SDimitry Andric "Could not find type system for language %s: %s", 23020b57cec5SDimitry Andric Language::GetNameForLanguageType(language), 23039dba64beSDimitry Andric llvm::toString(std::move(err)).c_str()); 23049dba64beSDimitry Andric return nullptr; 23050b57cec5SDimitry Andric } 23060b57cec5SDimitry Andric 23079dba64beSDimitry Andric auto *utility_fn = type_system_or_err->GetUtilityFunction(text, name); 23080b57cec5SDimitry Andric if (!utility_fn) 23090b57cec5SDimitry Andric error.SetErrorStringWithFormat( 23100b57cec5SDimitry Andric "Could not create an expression for language %s", 23110b57cec5SDimitry Andric Language::GetNameForLanguageType(language)); 23120b57cec5SDimitry Andric 23130b57cec5SDimitry Andric return utility_fn; 23140b57cec5SDimitry Andric } 23150b57cec5SDimitry Andric 23160b57cec5SDimitry Andric void Target::SettingsInitialize() { Process::SettingsInitialize(); } 23170b57cec5SDimitry Andric 23180b57cec5SDimitry Andric void Target::SettingsTerminate() { Process::SettingsTerminate(); } 23190b57cec5SDimitry Andric 23200b57cec5SDimitry Andric FileSpecList Target::GetDefaultExecutableSearchPaths() { 23210b57cec5SDimitry Andric TargetPropertiesSP properties_sp(Target::GetGlobalProperties()); 23220b57cec5SDimitry Andric if (properties_sp) 23230b57cec5SDimitry Andric return properties_sp->GetExecutableSearchPaths(); 23240b57cec5SDimitry Andric return FileSpecList(); 23250b57cec5SDimitry Andric } 23260b57cec5SDimitry Andric 23270b57cec5SDimitry Andric FileSpecList Target::GetDefaultDebugFileSearchPaths() { 23280b57cec5SDimitry Andric TargetPropertiesSP properties_sp(Target::GetGlobalProperties()); 23290b57cec5SDimitry Andric if (properties_sp) 23300b57cec5SDimitry Andric return properties_sp->GetDebugFileSearchPaths(); 23310b57cec5SDimitry Andric return FileSpecList(); 23320b57cec5SDimitry Andric } 23330b57cec5SDimitry Andric 23340b57cec5SDimitry Andric ArchSpec Target::GetDefaultArchitecture() { 23350b57cec5SDimitry Andric TargetPropertiesSP properties_sp(Target::GetGlobalProperties()); 23360b57cec5SDimitry Andric if (properties_sp) 23370b57cec5SDimitry Andric return properties_sp->GetDefaultArchitecture(); 23380b57cec5SDimitry Andric return ArchSpec(); 23390b57cec5SDimitry Andric } 23400b57cec5SDimitry Andric 23410b57cec5SDimitry Andric void Target::SetDefaultArchitecture(const ArchSpec &arch) { 23420b57cec5SDimitry Andric TargetPropertiesSP properties_sp(Target::GetGlobalProperties()); 23430b57cec5SDimitry Andric if (properties_sp) { 23449dba64beSDimitry Andric LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET), 23459dba64beSDimitry Andric "Target::SetDefaultArchitecture setting target's " 23469dba64beSDimitry Andric "default architecture to {0} ({1})", 23479dba64beSDimitry Andric arch.GetArchitectureName(), arch.GetTriple().getTriple()); 23480b57cec5SDimitry Andric return properties_sp->SetDefaultArchitecture(arch); 23490b57cec5SDimitry Andric } 23500b57cec5SDimitry Andric } 23510b57cec5SDimitry Andric 23520b57cec5SDimitry Andric Target *Target::GetTargetFromContexts(const ExecutionContext *exe_ctx_ptr, 23530b57cec5SDimitry Andric const SymbolContext *sc_ptr) { 23540b57cec5SDimitry Andric // The target can either exist in the "process" of ExecutionContext, or in 23550b57cec5SDimitry Andric // the "target_sp" member of SymbolContext. This accessor helper function 23560b57cec5SDimitry Andric // will get the target from one of these locations. 23570b57cec5SDimitry Andric 23580b57cec5SDimitry Andric Target *target = nullptr; 23590b57cec5SDimitry Andric if (sc_ptr != nullptr) 23600b57cec5SDimitry Andric target = sc_ptr->target_sp.get(); 23610b57cec5SDimitry Andric if (target == nullptr && exe_ctx_ptr) 23620b57cec5SDimitry Andric target = exe_ctx_ptr->GetTargetPtr(); 23630b57cec5SDimitry Andric return target; 23640b57cec5SDimitry Andric } 23650b57cec5SDimitry Andric 23660b57cec5SDimitry Andric ExpressionResults Target::EvaluateExpression( 23670b57cec5SDimitry Andric llvm::StringRef expr, ExecutionContextScope *exe_scope, 23680b57cec5SDimitry Andric lldb::ValueObjectSP &result_valobj_sp, 23690b57cec5SDimitry Andric const EvaluateExpressionOptions &options, std::string *fixed_expression, 23700b57cec5SDimitry Andric ValueObject *ctx_obj) { 23710b57cec5SDimitry Andric result_valobj_sp.reset(); 23720b57cec5SDimitry Andric 23730b57cec5SDimitry Andric ExpressionResults execution_results = eExpressionSetupError; 23740b57cec5SDimitry Andric 23750b57cec5SDimitry Andric if (expr.empty()) 23760b57cec5SDimitry Andric return execution_results; 23770b57cec5SDimitry Andric 23780b57cec5SDimitry Andric // We shouldn't run stop hooks in expressions. 23790b57cec5SDimitry Andric bool old_suppress_value = m_suppress_stop_hooks; 23800b57cec5SDimitry Andric m_suppress_stop_hooks = true; 23810b57cec5SDimitry Andric auto on_exit = llvm::make_scope_exit([this, old_suppress_value]() { 23829dba64beSDimitry Andric m_suppress_stop_hooks = old_suppress_value; 23839dba64beSDimitry Andric }); 23840b57cec5SDimitry Andric 23850b57cec5SDimitry Andric ExecutionContext exe_ctx; 23860b57cec5SDimitry Andric 23870b57cec5SDimitry Andric if (exe_scope) { 23880b57cec5SDimitry Andric exe_scope->CalculateExecutionContext(exe_ctx); 23890b57cec5SDimitry Andric } else if (m_process_sp) { 23900b57cec5SDimitry Andric m_process_sp->CalculateExecutionContext(exe_ctx); 23910b57cec5SDimitry Andric } else { 23920b57cec5SDimitry Andric CalculateExecutionContext(exe_ctx); 23930b57cec5SDimitry Andric } 23940b57cec5SDimitry Andric 23950b57cec5SDimitry Andric // Make sure we aren't just trying to see the value of a persistent variable 23960b57cec5SDimitry Andric // (something like "$0") 23970b57cec5SDimitry Andric // Only check for persistent variables the expression starts with a '$' 23989dba64beSDimitry Andric lldb::ExpressionVariableSP persistent_var_sp; 23999dba64beSDimitry Andric if (expr[0] == '$') { 24009dba64beSDimitry Andric auto type_system_or_err = 24019dba64beSDimitry Andric GetScratchTypeSystemForLanguage(eLanguageTypeC); 24029dba64beSDimitry Andric if (auto err = type_system_or_err.takeError()) { 24039dba64beSDimitry Andric LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET), 24049dba64beSDimitry Andric std::move(err), "Unable to get scratch type system"); 24059dba64beSDimitry Andric } else { 24069dba64beSDimitry Andric persistent_var_sp = 24079dba64beSDimitry Andric type_system_or_err->GetPersistentExpressionState()->GetVariable(expr); 24089dba64beSDimitry Andric } 24099dba64beSDimitry Andric } 24100b57cec5SDimitry Andric if (persistent_var_sp) { 24110b57cec5SDimitry Andric result_valobj_sp = persistent_var_sp->GetValueObject(); 24120b57cec5SDimitry Andric execution_results = eExpressionCompleted; 24130b57cec5SDimitry Andric } else { 24140b57cec5SDimitry Andric llvm::StringRef prefix = GetExpressionPrefixContents(); 24150b57cec5SDimitry Andric Status error; 24165ffd83dbSDimitry Andric execution_results = UserExpression::Evaluate(exe_ctx, options, expr, prefix, 24175ffd83dbSDimitry Andric result_valobj_sp, error, 24185ffd83dbSDimitry Andric fixed_expression, ctx_obj); 24190b57cec5SDimitry Andric } 24200b57cec5SDimitry Andric 24210b57cec5SDimitry Andric return execution_results; 24220b57cec5SDimitry Andric } 24230b57cec5SDimitry Andric 24249dba64beSDimitry Andric lldb::ExpressionVariableSP Target::GetPersistentVariable(ConstString name) { 24250b57cec5SDimitry Andric lldb::ExpressionVariableSP variable_sp; 24260b57cec5SDimitry Andric m_scratch_type_system_map.ForEach( 24270b57cec5SDimitry Andric [name, &variable_sp](TypeSystem *type_system) -> bool { 24280b57cec5SDimitry Andric if (PersistentExpressionState *persistent_state = 24290b57cec5SDimitry Andric type_system->GetPersistentExpressionState()) { 24300b57cec5SDimitry Andric variable_sp = persistent_state->GetVariable(name); 24310b57cec5SDimitry Andric 24320b57cec5SDimitry Andric if (variable_sp) 24330b57cec5SDimitry Andric return false; // Stop iterating the ForEach 24340b57cec5SDimitry Andric } 24350b57cec5SDimitry Andric return true; // Keep iterating the ForEach 24360b57cec5SDimitry Andric }); 24370b57cec5SDimitry Andric return variable_sp; 24380b57cec5SDimitry Andric } 24390b57cec5SDimitry Andric 24400b57cec5SDimitry Andric lldb::addr_t Target::GetPersistentSymbol(ConstString name) { 24410b57cec5SDimitry Andric lldb::addr_t address = LLDB_INVALID_ADDRESS; 24420b57cec5SDimitry Andric 24430b57cec5SDimitry Andric m_scratch_type_system_map.ForEach( 24440b57cec5SDimitry Andric [name, &address](TypeSystem *type_system) -> bool { 24450b57cec5SDimitry Andric if (PersistentExpressionState *persistent_state = 24460b57cec5SDimitry Andric type_system->GetPersistentExpressionState()) { 24470b57cec5SDimitry Andric address = persistent_state->LookupSymbol(name); 24480b57cec5SDimitry Andric if (address != LLDB_INVALID_ADDRESS) 24490b57cec5SDimitry Andric return false; // Stop iterating the ForEach 24500b57cec5SDimitry Andric } 24510b57cec5SDimitry Andric return true; // Keep iterating the ForEach 24520b57cec5SDimitry Andric }); 24530b57cec5SDimitry Andric return address; 24540b57cec5SDimitry Andric } 24550b57cec5SDimitry Andric 24569dba64beSDimitry Andric llvm::Expected<lldb_private::Address> Target::GetEntryPointAddress() { 24579dba64beSDimitry Andric Module *exe_module = GetExecutableModulePointer(); 24589dba64beSDimitry Andric 2459*1e991466SDimitry Andric // Try to find the entry point address in the primary executable. 2460*1e991466SDimitry Andric const bool has_primary_executable = exe_module && exe_module->GetObjectFile(); 2461*1e991466SDimitry Andric if (has_primary_executable) { 24629dba64beSDimitry Andric Address entry_addr = exe_module->GetObjectFile()->GetEntryPointAddress(); 24639dba64beSDimitry Andric if (entry_addr.IsValid()) 24649dba64beSDimitry Andric return entry_addr; 24659dba64beSDimitry Andric } 24669dba64beSDimitry Andric 24679dba64beSDimitry Andric const ModuleList &modules = GetImages(); 24689dba64beSDimitry Andric const size_t num_images = modules.GetSize(); 24699dba64beSDimitry Andric for (size_t idx = 0; idx < num_images; ++idx) { 24709dba64beSDimitry Andric ModuleSP module_sp(modules.GetModuleAtIndex(idx)); 24719dba64beSDimitry Andric if (!module_sp || !module_sp->GetObjectFile()) 24729dba64beSDimitry Andric continue; 24739dba64beSDimitry Andric 24749dba64beSDimitry Andric Address entry_addr = module_sp->GetObjectFile()->GetEntryPointAddress(); 2475*1e991466SDimitry Andric if (entry_addr.IsValid()) 24769dba64beSDimitry Andric return entry_addr; 24779dba64beSDimitry Andric } 24789dba64beSDimitry Andric 2479*1e991466SDimitry Andric // We haven't found the entry point address. Return an appropriate error. 2480*1e991466SDimitry Andric if (!has_primary_executable) 2481*1e991466SDimitry Andric return llvm::make_error<llvm::StringError>( 2482*1e991466SDimitry Andric "No primary executable found and could not find entry point address in " 2483*1e991466SDimitry Andric "any executable module", 2484*1e991466SDimitry Andric llvm::inconvertibleErrorCode()); 2485*1e991466SDimitry Andric 2486*1e991466SDimitry Andric return llvm::make_error<llvm::StringError>( 2487*1e991466SDimitry Andric "Could not find entry point address for primary executable module \"" + 2488*1e991466SDimitry Andric exe_module->GetFileSpec().GetFilename().GetStringRef() + "\"", 2489*1e991466SDimitry Andric llvm::inconvertibleErrorCode()); 24909dba64beSDimitry Andric } 24919dba64beSDimitry Andric 24920b57cec5SDimitry Andric lldb::addr_t Target::GetCallableLoadAddress(lldb::addr_t load_addr, 24930b57cec5SDimitry Andric AddressClass addr_class) const { 24940b57cec5SDimitry Andric auto arch_plugin = GetArchitecturePlugin(); 24959dba64beSDimitry Andric return arch_plugin 24969dba64beSDimitry Andric ? arch_plugin->GetCallableLoadAddress(load_addr, addr_class) 24979dba64beSDimitry Andric : load_addr; 24980b57cec5SDimitry Andric } 24990b57cec5SDimitry Andric 25000b57cec5SDimitry Andric lldb::addr_t Target::GetOpcodeLoadAddress(lldb::addr_t load_addr, 25010b57cec5SDimitry Andric AddressClass addr_class) const { 25020b57cec5SDimitry Andric auto arch_plugin = GetArchitecturePlugin(); 25039dba64beSDimitry Andric return arch_plugin ? arch_plugin->GetOpcodeLoadAddress(load_addr, addr_class) 25049dba64beSDimitry Andric : load_addr; 25050b57cec5SDimitry Andric } 25060b57cec5SDimitry Andric 25070b57cec5SDimitry Andric lldb::addr_t Target::GetBreakableLoadAddress(lldb::addr_t addr) { 25080b57cec5SDimitry Andric auto arch_plugin = GetArchitecturePlugin(); 25099dba64beSDimitry Andric return arch_plugin ? arch_plugin->GetBreakableLoadAddress(addr, *this) : addr; 25100b57cec5SDimitry Andric } 25110b57cec5SDimitry Andric 25120b57cec5SDimitry Andric SourceManager &Target::GetSourceManager() { 25130b57cec5SDimitry Andric if (!m_source_manager_up) 25145ffd83dbSDimitry Andric m_source_manager_up = std::make_unique<SourceManager>(shared_from_this()); 25150b57cec5SDimitry Andric return *m_source_manager_up; 25160b57cec5SDimitry Andric } 25170b57cec5SDimitry Andric 25180b57cec5SDimitry Andric ClangModulesDeclVendor *Target::GetClangModulesDeclVendor() { 25190b57cec5SDimitry Andric static std::mutex s_clang_modules_decl_vendor_mutex; // If this is contended 25200b57cec5SDimitry Andric // we can make it 25210b57cec5SDimitry Andric // per-target 25220b57cec5SDimitry Andric 25230b57cec5SDimitry Andric { 25240b57cec5SDimitry Andric std::lock_guard<std::mutex> guard(s_clang_modules_decl_vendor_mutex); 25250b57cec5SDimitry Andric 25260b57cec5SDimitry Andric if (!m_clang_modules_decl_vendor_up) { 25270b57cec5SDimitry Andric m_clang_modules_decl_vendor_up.reset( 25280b57cec5SDimitry Andric ClangModulesDeclVendor::Create(*this)); 25290b57cec5SDimitry Andric } 25300b57cec5SDimitry Andric } 25310b57cec5SDimitry Andric 25320b57cec5SDimitry Andric return m_clang_modules_decl_vendor_up.get(); 25330b57cec5SDimitry Andric } 25340b57cec5SDimitry Andric 25350b57cec5SDimitry Andric Target::StopHookSP Target::CreateStopHook() { 25360b57cec5SDimitry Andric lldb::user_id_t new_uid = ++m_stop_hook_next_id; 25370b57cec5SDimitry Andric Target::StopHookSP stop_hook_sp(new StopHook(shared_from_this(), new_uid)); 25380b57cec5SDimitry Andric m_stop_hooks[new_uid] = stop_hook_sp; 25390b57cec5SDimitry Andric return stop_hook_sp; 25400b57cec5SDimitry Andric } 25410b57cec5SDimitry Andric 25420b57cec5SDimitry Andric bool Target::RemoveStopHookByID(lldb::user_id_t user_id) { 25430b57cec5SDimitry Andric size_t num_removed = m_stop_hooks.erase(user_id); 25440b57cec5SDimitry Andric return (num_removed != 0); 25450b57cec5SDimitry Andric } 25460b57cec5SDimitry Andric 25470b57cec5SDimitry Andric void Target::RemoveAllStopHooks() { m_stop_hooks.clear(); } 25480b57cec5SDimitry Andric 25490b57cec5SDimitry Andric Target::StopHookSP Target::GetStopHookByID(lldb::user_id_t user_id) { 25500b57cec5SDimitry Andric StopHookSP found_hook; 25510b57cec5SDimitry Andric 25520b57cec5SDimitry Andric StopHookCollection::iterator specified_hook_iter; 25530b57cec5SDimitry Andric specified_hook_iter = m_stop_hooks.find(user_id); 25540b57cec5SDimitry Andric if (specified_hook_iter != m_stop_hooks.end()) 25550b57cec5SDimitry Andric found_hook = (*specified_hook_iter).second; 25560b57cec5SDimitry Andric return found_hook; 25570b57cec5SDimitry Andric } 25580b57cec5SDimitry Andric 25590b57cec5SDimitry Andric bool Target::SetStopHookActiveStateByID(lldb::user_id_t user_id, 25600b57cec5SDimitry Andric bool active_state) { 25610b57cec5SDimitry Andric StopHookCollection::iterator specified_hook_iter; 25620b57cec5SDimitry Andric specified_hook_iter = m_stop_hooks.find(user_id); 25630b57cec5SDimitry Andric if (specified_hook_iter == m_stop_hooks.end()) 25640b57cec5SDimitry Andric return false; 25650b57cec5SDimitry Andric 25660b57cec5SDimitry Andric (*specified_hook_iter).second->SetIsActive(active_state); 25670b57cec5SDimitry Andric return true; 25680b57cec5SDimitry Andric } 25690b57cec5SDimitry Andric 25700b57cec5SDimitry Andric void Target::SetAllStopHooksActiveState(bool active_state) { 25710b57cec5SDimitry Andric StopHookCollection::iterator pos, end = m_stop_hooks.end(); 25720b57cec5SDimitry Andric for (pos = m_stop_hooks.begin(); pos != end; pos++) { 25730b57cec5SDimitry Andric (*pos).second->SetIsActive(active_state); 25740b57cec5SDimitry Andric } 25750b57cec5SDimitry Andric } 25760b57cec5SDimitry Andric 25770b57cec5SDimitry Andric void Target::RunStopHooks() { 25780b57cec5SDimitry Andric if (m_suppress_stop_hooks) 25790b57cec5SDimitry Andric return; 25800b57cec5SDimitry Andric 25810b57cec5SDimitry Andric if (!m_process_sp) 25820b57cec5SDimitry Andric return; 25830b57cec5SDimitry Andric 25840b57cec5SDimitry Andric // Somebody might have restarted the process: 25850b57cec5SDimitry Andric if (m_process_sp->GetState() != eStateStopped) 25860b57cec5SDimitry Andric return; 25870b57cec5SDimitry Andric 25880b57cec5SDimitry Andric // <rdar://problem/12027563> make sure we check that we are not stopped 25890b57cec5SDimitry Andric // because of us running a user expression since in that case we do not want 25900b57cec5SDimitry Andric // to run the stop-hooks 25910b57cec5SDimitry Andric if (m_process_sp->GetModIDRef().IsLastResumeForUserExpression()) 25920b57cec5SDimitry Andric return; 25930b57cec5SDimitry Andric 25940b57cec5SDimitry Andric if (m_stop_hooks.empty()) 25950b57cec5SDimitry Andric return; 25960b57cec5SDimitry Andric 25970b57cec5SDimitry Andric StopHookCollection::iterator pos, end = m_stop_hooks.end(); 25980b57cec5SDimitry Andric 25990b57cec5SDimitry Andric // If there aren't any active stop hooks, don't bother either. 26000b57cec5SDimitry Andric // Also see if any of the active hooks want to auto-continue. 26010b57cec5SDimitry Andric bool any_active_hooks = false; 26020b57cec5SDimitry Andric bool auto_continue = false; 26030b57cec5SDimitry Andric for (auto hook : m_stop_hooks) { 26040b57cec5SDimitry Andric if (hook.second->IsActive()) { 26050b57cec5SDimitry Andric any_active_hooks = true; 26060b57cec5SDimitry Andric auto_continue |= hook.second->GetAutoContinue(); 26070b57cec5SDimitry Andric } 26080b57cec5SDimitry Andric } 26090b57cec5SDimitry Andric if (!any_active_hooks) 26100b57cec5SDimitry Andric return; 26110b57cec5SDimitry Andric 26125ffd83dbSDimitry Andric CommandReturnObject result(m_debugger.GetUseColor()); 26130b57cec5SDimitry Andric 26140b57cec5SDimitry Andric std::vector<ExecutionContext> exc_ctx_with_reasons; 26150b57cec5SDimitry Andric std::vector<SymbolContext> sym_ctx_with_reasons; 26160b57cec5SDimitry Andric 26170b57cec5SDimitry Andric ThreadList &cur_threadlist = m_process_sp->GetThreadList(); 26180b57cec5SDimitry Andric size_t num_threads = cur_threadlist.GetSize(); 26190b57cec5SDimitry Andric for (size_t i = 0; i < num_threads; i++) { 26200b57cec5SDimitry Andric lldb::ThreadSP cur_thread_sp = cur_threadlist.GetThreadAtIndex(i); 26210b57cec5SDimitry Andric if (cur_thread_sp->ThreadStoppedForAReason()) { 26220b57cec5SDimitry Andric lldb::StackFrameSP cur_frame_sp = cur_thread_sp->GetStackFrameAtIndex(0); 26230b57cec5SDimitry Andric exc_ctx_with_reasons.push_back(ExecutionContext( 26240b57cec5SDimitry Andric m_process_sp.get(), cur_thread_sp.get(), cur_frame_sp.get())); 26250b57cec5SDimitry Andric sym_ctx_with_reasons.push_back( 26260b57cec5SDimitry Andric cur_frame_sp->GetSymbolContext(eSymbolContextEverything)); 26270b57cec5SDimitry Andric } 26280b57cec5SDimitry Andric } 26290b57cec5SDimitry Andric 26300b57cec5SDimitry Andric // If no threads stopped for a reason, don't run the stop-hooks. 26310b57cec5SDimitry Andric size_t num_exe_ctx = exc_ctx_with_reasons.size(); 26320b57cec5SDimitry Andric if (num_exe_ctx == 0) 26330b57cec5SDimitry Andric return; 26340b57cec5SDimitry Andric 26350b57cec5SDimitry Andric result.SetImmediateOutputStream(m_debugger.GetAsyncOutputStream()); 26360b57cec5SDimitry Andric result.SetImmediateErrorStream(m_debugger.GetAsyncErrorStream()); 26370b57cec5SDimitry Andric 26380b57cec5SDimitry Andric bool keep_going = true; 26390b57cec5SDimitry Andric bool hooks_ran = false; 26400b57cec5SDimitry Andric bool print_hook_header = (m_stop_hooks.size() != 1); 26410b57cec5SDimitry Andric bool print_thread_header = (num_exe_ctx != 1); 26420b57cec5SDimitry Andric bool did_restart = false; 26430b57cec5SDimitry Andric 26440b57cec5SDimitry Andric for (pos = m_stop_hooks.begin(); keep_going && pos != end; pos++) { 26450b57cec5SDimitry Andric // result.Clear(); 26460b57cec5SDimitry Andric StopHookSP cur_hook_sp = (*pos).second; 26470b57cec5SDimitry Andric if (!cur_hook_sp->IsActive()) 26480b57cec5SDimitry Andric continue; 26490b57cec5SDimitry Andric 26500b57cec5SDimitry Andric bool any_thread_matched = false; 26510b57cec5SDimitry Andric for (size_t i = 0; keep_going && i < num_exe_ctx; i++) { 26520b57cec5SDimitry Andric if ((cur_hook_sp->GetSpecifier() == nullptr || 26530b57cec5SDimitry Andric cur_hook_sp->GetSpecifier()->SymbolContextMatches( 26540b57cec5SDimitry Andric sym_ctx_with_reasons[i])) && 26550b57cec5SDimitry Andric (cur_hook_sp->GetThreadSpecifier() == nullptr || 26560b57cec5SDimitry Andric cur_hook_sp->GetThreadSpecifier()->ThreadPassesBasicTests( 26570b57cec5SDimitry Andric exc_ctx_with_reasons[i].GetThreadRef()))) { 26580b57cec5SDimitry Andric if (!hooks_ran) { 26590b57cec5SDimitry Andric hooks_ran = true; 26600b57cec5SDimitry Andric } 26610b57cec5SDimitry Andric if (print_hook_header && !any_thread_matched) { 26620b57cec5SDimitry Andric const char *cmd = 26630b57cec5SDimitry Andric (cur_hook_sp->GetCommands().GetSize() == 1 26640b57cec5SDimitry Andric ? cur_hook_sp->GetCommands().GetStringAtIndex(0) 26650b57cec5SDimitry Andric : nullptr); 26660b57cec5SDimitry Andric if (cmd) 26670b57cec5SDimitry Andric result.AppendMessageWithFormat("\n- Hook %" PRIu64 " (%s)\n", 26680b57cec5SDimitry Andric cur_hook_sp->GetID(), cmd); 26690b57cec5SDimitry Andric else 26700b57cec5SDimitry Andric result.AppendMessageWithFormat("\n- Hook %" PRIu64 "\n", 26710b57cec5SDimitry Andric cur_hook_sp->GetID()); 26720b57cec5SDimitry Andric any_thread_matched = true; 26730b57cec5SDimitry Andric } 26740b57cec5SDimitry Andric 26750b57cec5SDimitry Andric if (print_thread_header) 26760b57cec5SDimitry Andric result.AppendMessageWithFormat( 26770b57cec5SDimitry Andric "-- Thread %d\n", 26780b57cec5SDimitry Andric exc_ctx_with_reasons[i].GetThreadPtr()->GetIndexID()); 26790b57cec5SDimitry Andric 26800b57cec5SDimitry Andric CommandInterpreterRunOptions options; 26810b57cec5SDimitry Andric options.SetStopOnContinue(true); 26820b57cec5SDimitry Andric options.SetStopOnError(true); 26830b57cec5SDimitry Andric options.SetEchoCommands(false); 26840b57cec5SDimitry Andric options.SetPrintResults(true); 26850b57cec5SDimitry Andric options.SetPrintErrors(true); 26860b57cec5SDimitry Andric options.SetAddToHistory(false); 26870b57cec5SDimitry Andric 26880b57cec5SDimitry Andric // Force Async: 26890b57cec5SDimitry Andric bool old_async = GetDebugger().GetAsyncExecution(); 26900b57cec5SDimitry Andric GetDebugger().SetAsyncExecution(true); 26910b57cec5SDimitry Andric GetDebugger().GetCommandInterpreter().HandleCommands( 26920b57cec5SDimitry Andric cur_hook_sp->GetCommands(), &exc_ctx_with_reasons[i], options, 26930b57cec5SDimitry Andric result); 26940b57cec5SDimitry Andric GetDebugger().SetAsyncExecution(old_async); 26950b57cec5SDimitry Andric // If the command started the target going again, we should bag out of 26960b57cec5SDimitry Andric // running the stop hooks. 26970b57cec5SDimitry Andric if ((result.GetStatus() == eReturnStatusSuccessContinuingNoResult) || 26980b57cec5SDimitry Andric (result.GetStatus() == eReturnStatusSuccessContinuingResult)) { 26990b57cec5SDimitry Andric // But only complain if there were more stop hooks to do: 27000b57cec5SDimitry Andric StopHookCollection::iterator tmp = pos; 27010b57cec5SDimitry Andric if (++tmp != end) 27029dba64beSDimitry Andric result.AppendMessageWithFormat( 27039dba64beSDimitry Andric "\nAborting stop hooks, hook %" PRIu64 27040b57cec5SDimitry Andric " set the program running.\n" 27050b57cec5SDimitry Andric " Consider using '-G true' to make " 27060b57cec5SDimitry Andric "stop hooks auto-continue.\n", 27070b57cec5SDimitry Andric cur_hook_sp->GetID()); 27080b57cec5SDimitry Andric keep_going = false; 27090b57cec5SDimitry Andric did_restart = true; 27100b57cec5SDimitry Andric } 27110b57cec5SDimitry Andric } 27120b57cec5SDimitry Andric } 27130b57cec5SDimitry Andric } 27140b57cec5SDimitry Andric // Finally, if auto-continue was requested, do it now: 27150b57cec5SDimitry Andric if (!did_restart && auto_continue) 27160b57cec5SDimitry Andric m_process_sp->PrivateResume(); 27170b57cec5SDimitry Andric 27180b57cec5SDimitry Andric result.GetImmediateOutputStream()->Flush(); 27190b57cec5SDimitry Andric result.GetImmediateErrorStream()->Flush(); 27200b57cec5SDimitry Andric } 27210b57cec5SDimitry Andric 27220b57cec5SDimitry Andric const TargetPropertiesSP &Target::GetGlobalProperties() { 27230b57cec5SDimitry Andric // NOTE: intentional leak so we don't crash if global destructor chain gets 27240b57cec5SDimitry Andric // called as other threads still use the result of this function 27250b57cec5SDimitry Andric static TargetPropertiesSP *g_settings_sp_ptr = 27260b57cec5SDimitry Andric new TargetPropertiesSP(new TargetProperties(nullptr)); 27270b57cec5SDimitry Andric return *g_settings_sp_ptr; 27280b57cec5SDimitry Andric } 27290b57cec5SDimitry Andric 27300b57cec5SDimitry Andric Status Target::Install(ProcessLaunchInfo *launch_info) { 27310b57cec5SDimitry Andric Status error; 27320b57cec5SDimitry Andric PlatformSP platform_sp(GetPlatform()); 27330b57cec5SDimitry Andric if (platform_sp) { 27340b57cec5SDimitry Andric if (platform_sp->IsRemote()) { 27350b57cec5SDimitry Andric if (platform_sp->IsConnected()) { 27365ffd83dbSDimitry Andric // Install all files that have an install path when connected to a 27375ffd83dbSDimitry Andric // remote platform. If target.auto-install-main-executable is set then 27385ffd83dbSDimitry Andric // also install the main executable even if it does not have an explicit 27395ffd83dbSDimitry Andric // install path specified. 27400b57cec5SDimitry Andric const ModuleList &modules = GetImages(); 27410b57cec5SDimitry Andric const size_t num_images = modules.GetSize(); 27420b57cec5SDimitry Andric for (size_t idx = 0; idx < num_images; ++idx) { 27430b57cec5SDimitry Andric ModuleSP module_sp(modules.GetModuleAtIndex(idx)); 27440b57cec5SDimitry Andric if (module_sp) { 27450b57cec5SDimitry Andric const bool is_main_executable = module_sp == GetExecutableModule(); 27460b57cec5SDimitry Andric FileSpec local_file(module_sp->GetFileSpec()); 27470b57cec5SDimitry Andric if (local_file) { 27480b57cec5SDimitry Andric FileSpec remote_file(module_sp->GetRemoteInstallFileSpec()); 27490b57cec5SDimitry Andric if (!remote_file) { 27505ffd83dbSDimitry Andric if (is_main_executable && GetAutoInstallMainExecutable()) { 27515ffd83dbSDimitry Andric // Automatically install the main executable. 27520b57cec5SDimitry Andric remote_file = platform_sp->GetRemoteWorkingDirectory(); 27530b57cec5SDimitry Andric remote_file.AppendPathComponent( 27540b57cec5SDimitry Andric module_sp->GetFileSpec().GetFilename().GetCString()); 27550b57cec5SDimitry Andric } 27560b57cec5SDimitry Andric } 27570b57cec5SDimitry Andric if (remote_file) { 27580b57cec5SDimitry Andric error = platform_sp->Install(local_file, remote_file); 27590b57cec5SDimitry Andric if (error.Success()) { 27600b57cec5SDimitry Andric module_sp->SetPlatformFileSpec(remote_file); 27610b57cec5SDimitry Andric if (is_main_executable) { 27620b57cec5SDimitry Andric platform_sp->SetFilePermissions(remote_file, 0700); 27630b57cec5SDimitry Andric if (launch_info) 27640b57cec5SDimitry Andric launch_info->SetExecutableFile(remote_file, false); 27650b57cec5SDimitry Andric } 27660b57cec5SDimitry Andric } else 27670b57cec5SDimitry Andric break; 27680b57cec5SDimitry Andric } 27690b57cec5SDimitry Andric } 27700b57cec5SDimitry Andric } 27710b57cec5SDimitry Andric } 27720b57cec5SDimitry Andric } 27730b57cec5SDimitry Andric } 27740b57cec5SDimitry Andric } 27750b57cec5SDimitry Andric return error; 27760b57cec5SDimitry Andric } 27770b57cec5SDimitry Andric 27780b57cec5SDimitry Andric bool Target::ResolveLoadAddress(addr_t load_addr, Address &so_addr, 27790b57cec5SDimitry Andric uint32_t stop_id) { 27800b57cec5SDimitry Andric return m_section_load_history.ResolveLoadAddress(stop_id, load_addr, so_addr); 27810b57cec5SDimitry Andric } 27820b57cec5SDimitry Andric 27830b57cec5SDimitry Andric bool Target::ResolveFileAddress(lldb::addr_t file_addr, 27840b57cec5SDimitry Andric Address &resolved_addr) { 27850b57cec5SDimitry Andric return m_images.ResolveFileAddress(file_addr, resolved_addr); 27860b57cec5SDimitry Andric } 27870b57cec5SDimitry Andric 27880b57cec5SDimitry Andric bool Target::SetSectionLoadAddress(const SectionSP §ion_sp, 27890b57cec5SDimitry Andric addr_t new_section_load_addr, 27900b57cec5SDimitry Andric bool warn_multiple) { 27910b57cec5SDimitry Andric const addr_t old_section_load_addr = 27920b57cec5SDimitry Andric m_section_load_history.GetSectionLoadAddress( 27930b57cec5SDimitry Andric SectionLoadHistory::eStopIDNow, section_sp); 27940b57cec5SDimitry Andric if (old_section_load_addr != new_section_load_addr) { 27950b57cec5SDimitry Andric uint32_t stop_id = 0; 27960b57cec5SDimitry Andric ProcessSP process_sp(GetProcessSP()); 27970b57cec5SDimitry Andric if (process_sp) 27980b57cec5SDimitry Andric stop_id = process_sp->GetStopID(); 27990b57cec5SDimitry Andric else 28000b57cec5SDimitry Andric stop_id = m_section_load_history.GetLastStopID(); 28010b57cec5SDimitry Andric if (m_section_load_history.SetSectionLoadAddress( 28020b57cec5SDimitry Andric stop_id, section_sp, new_section_load_addr, warn_multiple)) 28030b57cec5SDimitry Andric return true; // Return true if the section load address was changed... 28040b57cec5SDimitry Andric } 28050b57cec5SDimitry Andric return false; // Return false to indicate nothing changed 28060b57cec5SDimitry Andric } 28070b57cec5SDimitry Andric 28080b57cec5SDimitry Andric size_t Target::UnloadModuleSections(const ModuleList &module_list) { 28090b57cec5SDimitry Andric size_t section_unload_count = 0; 28100b57cec5SDimitry Andric size_t num_modules = module_list.GetSize(); 28110b57cec5SDimitry Andric for (size_t i = 0; i < num_modules; ++i) { 28120b57cec5SDimitry Andric section_unload_count += 28130b57cec5SDimitry Andric UnloadModuleSections(module_list.GetModuleAtIndex(i)); 28140b57cec5SDimitry Andric } 28150b57cec5SDimitry Andric return section_unload_count; 28160b57cec5SDimitry Andric } 28170b57cec5SDimitry Andric 28180b57cec5SDimitry Andric size_t Target::UnloadModuleSections(const lldb::ModuleSP &module_sp) { 28190b57cec5SDimitry Andric uint32_t stop_id = 0; 28200b57cec5SDimitry Andric ProcessSP process_sp(GetProcessSP()); 28210b57cec5SDimitry Andric if (process_sp) 28220b57cec5SDimitry Andric stop_id = process_sp->GetStopID(); 28230b57cec5SDimitry Andric else 28240b57cec5SDimitry Andric stop_id = m_section_load_history.GetLastStopID(); 28250b57cec5SDimitry Andric SectionList *sections = module_sp->GetSectionList(); 28260b57cec5SDimitry Andric size_t section_unload_count = 0; 28270b57cec5SDimitry Andric if (sections) { 28280b57cec5SDimitry Andric const uint32_t num_sections = sections->GetNumSections(0); 28290b57cec5SDimitry Andric for (uint32_t i = 0; i < num_sections; ++i) { 28300b57cec5SDimitry Andric section_unload_count += m_section_load_history.SetSectionUnloaded( 28310b57cec5SDimitry Andric stop_id, sections->GetSectionAtIndex(i)); 28320b57cec5SDimitry Andric } 28330b57cec5SDimitry Andric } 28340b57cec5SDimitry Andric return section_unload_count; 28350b57cec5SDimitry Andric } 28360b57cec5SDimitry Andric 28370b57cec5SDimitry Andric bool Target::SetSectionUnloaded(const lldb::SectionSP §ion_sp) { 28380b57cec5SDimitry Andric uint32_t stop_id = 0; 28390b57cec5SDimitry Andric ProcessSP process_sp(GetProcessSP()); 28400b57cec5SDimitry Andric if (process_sp) 28410b57cec5SDimitry Andric stop_id = process_sp->GetStopID(); 28420b57cec5SDimitry Andric else 28430b57cec5SDimitry Andric stop_id = m_section_load_history.GetLastStopID(); 28440b57cec5SDimitry Andric return m_section_load_history.SetSectionUnloaded(stop_id, section_sp); 28450b57cec5SDimitry Andric } 28460b57cec5SDimitry Andric 28470b57cec5SDimitry Andric bool Target::SetSectionUnloaded(const lldb::SectionSP §ion_sp, 28480b57cec5SDimitry Andric addr_t load_addr) { 28490b57cec5SDimitry Andric uint32_t stop_id = 0; 28500b57cec5SDimitry Andric ProcessSP process_sp(GetProcessSP()); 28510b57cec5SDimitry Andric if (process_sp) 28520b57cec5SDimitry Andric stop_id = process_sp->GetStopID(); 28530b57cec5SDimitry Andric else 28540b57cec5SDimitry Andric stop_id = m_section_load_history.GetLastStopID(); 28550b57cec5SDimitry Andric return m_section_load_history.SetSectionUnloaded(stop_id, section_sp, 28560b57cec5SDimitry Andric load_addr); 28570b57cec5SDimitry Andric } 28580b57cec5SDimitry Andric 28590b57cec5SDimitry Andric void Target::ClearAllLoadedSections() { m_section_load_history.Clear(); } 28600b57cec5SDimitry Andric 28610b57cec5SDimitry Andric Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) { 28620b57cec5SDimitry Andric Status error; 28630b57cec5SDimitry Andric Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET)); 28640b57cec5SDimitry Andric 28659dba64beSDimitry Andric LLDB_LOGF(log, "Target::%s() called for %s", __FUNCTION__, 28660b57cec5SDimitry Andric launch_info.GetExecutableFile().GetPath().c_str()); 28670b57cec5SDimitry Andric 28680b57cec5SDimitry Andric StateType state = eStateInvalid; 28690b57cec5SDimitry Andric 28700b57cec5SDimitry Andric // Scope to temporarily get the process state in case someone has manually 28710b57cec5SDimitry Andric // remotely connected already to a process and we can skip the platform 28720b57cec5SDimitry Andric // launching. 28730b57cec5SDimitry Andric { 28740b57cec5SDimitry Andric ProcessSP process_sp(GetProcessSP()); 28750b57cec5SDimitry Andric 28760b57cec5SDimitry Andric if (process_sp) { 28770b57cec5SDimitry Andric state = process_sp->GetState(); 28789dba64beSDimitry Andric LLDB_LOGF(log, 28790b57cec5SDimitry Andric "Target::%s the process exists, and its current state is %s", 28800b57cec5SDimitry Andric __FUNCTION__, StateAsCString(state)); 28810b57cec5SDimitry Andric } else { 28829dba64beSDimitry Andric LLDB_LOGF(log, "Target::%s the process instance doesn't currently exist.", 28830b57cec5SDimitry Andric __FUNCTION__); 28840b57cec5SDimitry Andric } 28850b57cec5SDimitry Andric } 28860b57cec5SDimitry Andric 28870b57cec5SDimitry Andric launch_info.GetFlags().Set(eLaunchFlagDebug); 28880b57cec5SDimitry Andric 28890b57cec5SDimitry Andric // Get the value of synchronous execution here. If you wait till after you 28900b57cec5SDimitry Andric // have started to run, then you could have hit a breakpoint, whose command 28910b57cec5SDimitry Andric // might switch the value, and then you'll pick up that incorrect value. 28920b57cec5SDimitry Andric Debugger &debugger = GetDebugger(); 28930b57cec5SDimitry Andric const bool synchronous_execution = 28940b57cec5SDimitry Andric debugger.GetCommandInterpreter().GetSynchronous(); 28950b57cec5SDimitry Andric 28960b57cec5SDimitry Andric PlatformSP platform_sp(GetPlatform()); 28970b57cec5SDimitry Andric 28980b57cec5SDimitry Andric FinalizeFileActions(launch_info); 28990b57cec5SDimitry Andric 29000b57cec5SDimitry Andric if (state == eStateConnected) { 29010b57cec5SDimitry Andric if (launch_info.GetFlags().Test(eLaunchFlagLaunchInTTY)) { 29020b57cec5SDimitry Andric error.SetErrorString( 29030b57cec5SDimitry Andric "can't launch in tty when launching through a remote connection"); 29040b57cec5SDimitry Andric return error; 29050b57cec5SDimitry Andric } 29060b57cec5SDimitry Andric } 29070b57cec5SDimitry Andric 29080b57cec5SDimitry Andric if (!launch_info.GetArchitecture().IsValid()) 29090b57cec5SDimitry Andric launch_info.GetArchitecture() = GetArchitecture(); 29100b57cec5SDimitry Andric 29110b57cec5SDimitry Andric // If we're not already connected to the process, and if we have a platform 29120b57cec5SDimitry Andric // that can launch a process for debugging, go ahead and do that here. 29130b57cec5SDimitry Andric if (state != eStateConnected && platform_sp && 29140b57cec5SDimitry Andric platform_sp->CanDebugProcess()) { 29159dba64beSDimitry Andric LLDB_LOGF(log, "Target::%s asking the platform to debug the process", 29160b57cec5SDimitry Andric __FUNCTION__); 29170b57cec5SDimitry Andric 29180b57cec5SDimitry Andric // If there was a previous process, delete it before we make the new one. 29190b57cec5SDimitry Andric // One subtle point, we delete the process before we release the reference 29200b57cec5SDimitry Andric // to m_process_sp. That way even if we are the last owner, the process 29210b57cec5SDimitry Andric // will get Finalized before it gets destroyed. 29220b57cec5SDimitry Andric DeleteCurrentProcess(); 29230b57cec5SDimitry Andric 29240b57cec5SDimitry Andric m_process_sp = 29250b57cec5SDimitry Andric GetPlatform()->DebugProcess(launch_info, debugger, this, error); 29260b57cec5SDimitry Andric 29270b57cec5SDimitry Andric } else { 29289dba64beSDimitry Andric LLDB_LOGF(log, 29299dba64beSDimitry Andric "Target::%s the platform doesn't know how to debug a " 29300b57cec5SDimitry Andric "process, getting a process plugin to do this for us.", 29310b57cec5SDimitry Andric __FUNCTION__); 29320b57cec5SDimitry Andric 29330b57cec5SDimitry Andric if (state == eStateConnected) { 29340b57cec5SDimitry Andric assert(m_process_sp); 29350b57cec5SDimitry Andric } else { 29360b57cec5SDimitry Andric // Use a Process plugin to construct the process. 29370b57cec5SDimitry Andric const char *plugin_name = launch_info.GetProcessPluginName(); 29380b57cec5SDimitry Andric CreateProcess(launch_info.GetListener(), plugin_name, nullptr); 29390b57cec5SDimitry Andric } 29400b57cec5SDimitry Andric 29410b57cec5SDimitry Andric // Since we didn't have a platform launch the process, launch it here. 29420b57cec5SDimitry Andric if (m_process_sp) 29430b57cec5SDimitry Andric error = m_process_sp->Launch(launch_info); 29440b57cec5SDimitry Andric } 29450b57cec5SDimitry Andric 29460b57cec5SDimitry Andric if (!m_process_sp) { 29470b57cec5SDimitry Andric if (error.Success()) 29480b57cec5SDimitry Andric error.SetErrorString("failed to launch or debug process"); 29490b57cec5SDimitry Andric return error; 29500b57cec5SDimitry Andric } 29510b57cec5SDimitry Andric 29520b57cec5SDimitry Andric if (error.Success()) { 29530b57cec5SDimitry Andric if (synchronous_execution || 29540b57cec5SDimitry Andric !launch_info.GetFlags().Test(eLaunchFlagStopAtEntry)) { 29550b57cec5SDimitry Andric ListenerSP hijack_listener_sp(launch_info.GetHijackListener()); 29560b57cec5SDimitry Andric if (!hijack_listener_sp) { 29570b57cec5SDimitry Andric hijack_listener_sp = 29580b57cec5SDimitry Andric Listener::MakeListener("lldb.Target.Launch.hijack"); 29590b57cec5SDimitry Andric launch_info.SetHijackListener(hijack_listener_sp); 29600b57cec5SDimitry Andric m_process_sp->HijackProcessEvents(hijack_listener_sp); 29610b57cec5SDimitry Andric } 29620b57cec5SDimitry Andric 29630b57cec5SDimitry Andric StateType state = m_process_sp->WaitForProcessToStop( 29640b57cec5SDimitry Andric llvm::None, nullptr, false, hijack_listener_sp, nullptr); 29650b57cec5SDimitry Andric 29660b57cec5SDimitry Andric if (state == eStateStopped) { 29670b57cec5SDimitry Andric if (!launch_info.GetFlags().Test(eLaunchFlagStopAtEntry)) { 29680b57cec5SDimitry Andric if (synchronous_execution) { 29699dba64beSDimitry Andric // Now we have handled the stop-from-attach, and we are just 29709dba64beSDimitry Andric // switching to a synchronous resume. So we should switch to the 29719dba64beSDimitry Andric // SyncResume hijacker. 29720b57cec5SDimitry Andric m_process_sp->RestoreProcessEvents(); 29730b57cec5SDimitry Andric m_process_sp->ResumeSynchronous(stream); 29740b57cec5SDimitry Andric } else { 29750b57cec5SDimitry Andric m_process_sp->RestoreProcessEvents(); 29760b57cec5SDimitry Andric error = m_process_sp->PrivateResume(); 29770b57cec5SDimitry Andric } 29780b57cec5SDimitry Andric if (!error.Success()) { 29790b57cec5SDimitry Andric Status error2; 29800b57cec5SDimitry Andric error2.SetErrorStringWithFormat( 29810b57cec5SDimitry Andric "process resume at entry point failed: %s", error.AsCString()); 29820b57cec5SDimitry Andric error = error2; 29830b57cec5SDimitry Andric } 29840b57cec5SDimitry Andric } 29850b57cec5SDimitry Andric } else if (state == eStateExited) { 29860b57cec5SDimitry Andric bool with_shell = !!launch_info.GetShell(); 29870b57cec5SDimitry Andric const int exit_status = m_process_sp->GetExitStatus(); 29880b57cec5SDimitry Andric const char *exit_desc = m_process_sp->GetExitDescription(); 29890b57cec5SDimitry Andric #define LAUNCH_SHELL_MESSAGE \ 29900b57cec5SDimitry Andric "\n'r' and 'run' are aliases that default to launching through a " \ 29910b57cec5SDimitry Andric "shell.\nTry launching without going through a shell by using 'process " \ 29920b57cec5SDimitry Andric "launch'." 29930b57cec5SDimitry Andric if (exit_desc && exit_desc[0]) { 29940b57cec5SDimitry Andric if (with_shell) 29950b57cec5SDimitry Andric error.SetErrorStringWithFormat( 29960b57cec5SDimitry Andric "process exited with status %i (%s)" LAUNCH_SHELL_MESSAGE, 29970b57cec5SDimitry Andric exit_status, exit_desc); 29980b57cec5SDimitry Andric else 29990b57cec5SDimitry Andric error.SetErrorStringWithFormat("process exited with status %i (%s)", 30000b57cec5SDimitry Andric exit_status, exit_desc); 30010b57cec5SDimitry Andric } else { 30020b57cec5SDimitry Andric if (with_shell) 30030b57cec5SDimitry Andric error.SetErrorStringWithFormat( 30040b57cec5SDimitry Andric "process exited with status %i" LAUNCH_SHELL_MESSAGE, 30050b57cec5SDimitry Andric exit_status); 30060b57cec5SDimitry Andric else 30070b57cec5SDimitry Andric error.SetErrorStringWithFormat("process exited with status %i", 30080b57cec5SDimitry Andric exit_status); 30090b57cec5SDimitry Andric } 30100b57cec5SDimitry Andric } else { 30110b57cec5SDimitry Andric error.SetErrorStringWithFormat( 30120b57cec5SDimitry Andric "initial process state wasn't stopped: %s", StateAsCString(state)); 30130b57cec5SDimitry Andric } 30140b57cec5SDimitry Andric } 30150b57cec5SDimitry Andric m_process_sp->RestoreProcessEvents(); 30160b57cec5SDimitry Andric } 30170b57cec5SDimitry Andric return error; 30180b57cec5SDimitry Andric } 30190b57cec5SDimitry Andric 30200b57cec5SDimitry Andric Status Target::Attach(ProcessAttachInfo &attach_info, Stream *stream) { 30210b57cec5SDimitry Andric auto state = eStateInvalid; 30220b57cec5SDimitry Andric auto process_sp = GetProcessSP(); 30230b57cec5SDimitry Andric if (process_sp) { 30240b57cec5SDimitry Andric state = process_sp->GetState(); 30250b57cec5SDimitry Andric if (process_sp->IsAlive() && state != eStateConnected) { 30260b57cec5SDimitry Andric if (state == eStateAttaching) 30270b57cec5SDimitry Andric return Status("process attach is in progress"); 30280b57cec5SDimitry Andric return Status("a process is already being debugged"); 30290b57cec5SDimitry Andric } 30300b57cec5SDimitry Andric } 30310b57cec5SDimitry Andric 30320b57cec5SDimitry Andric const ModuleSP old_exec_module_sp = GetExecutableModule(); 30330b57cec5SDimitry Andric 30340b57cec5SDimitry Andric // If no process info was specified, then use the target executable name as 30350b57cec5SDimitry Andric // the process to attach to by default 30360b57cec5SDimitry Andric if (!attach_info.ProcessInfoSpecified()) { 30370b57cec5SDimitry Andric if (old_exec_module_sp) 30380b57cec5SDimitry Andric attach_info.GetExecutableFile().GetFilename() = 30390b57cec5SDimitry Andric old_exec_module_sp->GetPlatformFileSpec().GetFilename(); 30400b57cec5SDimitry Andric 30410b57cec5SDimitry Andric if (!attach_info.ProcessInfoSpecified()) { 30420b57cec5SDimitry Andric return Status("no process specified, create a target with a file, or " 30430b57cec5SDimitry Andric "specify the --pid or --name"); 30440b57cec5SDimitry Andric } 30450b57cec5SDimitry Andric } 30460b57cec5SDimitry Andric 30470b57cec5SDimitry Andric const auto platform_sp = 30480b57cec5SDimitry Andric GetDebugger().GetPlatformList().GetSelectedPlatform(); 30490b57cec5SDimitry Andric ListenerSP hijack_listener_sp; 30500b57cec5SDimitry Andric const bool async = attach_info.GetAsync(); 30510b57cec5SDimitry Andric if (!async) { 30520b57cec5SDimitry Andric hijack_listener_sp = 30530b57cec5SDimitry Andric Listener::MakeListener("lldb.Target.Attach.attach.hijack"); 30540b57cec5SDimitry Andric attach_info.SetHijackListener(hijack_listener_sp); 30550b57cec5SDimitry Andric } 30560b57cec5SDimitry Andric 30570b57cec5SDimitry Andric Status error; 30580b57cec5SDimitry Andric if (state != eStateConnected && platform_sp != nullptr && 30590b57cec5SDimitry Andric platform_sp->CanDebugProcess()) { 30600b57cec5SDimitry Andric SetPlatform(platform_sp); 30610b57cec5SDimitry Andric process_sp = platform_sp->Attach(attach_info, GetDebugger(), this, error); 30620b57cec5SDimitry Andric } else { 30630b57cec5SDimitry Andric if (state != eStateConnected) { 30640b57cec5SDimitry Andric const char *plugin_name = attach_info.GetProcessPluginName(); 30650b57cec5SDimitry Andric process_sp = 30660b57cec5SDimitry Andric CreateProcess(attach_info.GetListenerForProcess(GetDebugger()), 30670b57cec5SDimitry Andric plugin_name, nullptr); 30680b57cec5SDimitry Andric if (process_sp == nullptr) { 30690b57cec5SDimitry Andric error.SetErrorStringWithFormat( 30700b57cec5SDimitry Andric "failed to create process using plugin %s", 30710b57cec5SDimitry Andric (plugin_name) ? plugin_name : "null"); 30720b57cec5SDimitry Andric return error; 30730b57cec5SDimitry Andric } 30740b57cec5SDimitry Andric } 30750b57cec5SDimitry Andric if (hijack_listener_sp) 30760b57cec5SDimitry Andric process_sp->HijackProcessEvents(hijack_listener_sp); 30770b57cec5SDimitry Andric error = process_sp->Attach(attach_info); 30780b57cec5SDimitry Andric } 30790b57cec5SDimitry Andric 30800b57cec5SDimitry Andric if (error.Success() && process_sp) { 30810b57cec5SDimitry Andric if (async) { 30820b57cec5SDimitry Andric process_sp->RestoreProcessEvents(); 30830b57cec5SDimitry Andric } else { 30840b57cec5SDimitry Andric state = process_sp->WaitForProcessToStop( 30850b57cec5SDimitry Andric llvm::None, nullptr, false, attach_info.GetHijackListener(), stream); 30860b57cec5SDimitry Andric process_sp->RestoreProcessEvents(); 30870b57cec5SDimitry Andric 30880b57cec5SDimitry Andric if (state != eStateStopped) { 30890b57cec5SDimitry Andric const char *exit_desc = process_sp->GetExitDescription(); 30900b57cec5SDimitry Andric if (exit_desc) 30910b57cec5SDimitry Andric error.SetErrorStringWithFormat("%s", exit_desc); 30920b57cec5SDimitry Andric else 30930b57cec5SDimitry Andric error.SetErrorString( 30940b57cec5SDimitry Andric "process did not stop (no such process or permission problem?)"); 30950b57cec5SDimitry Andric process_sp->Destroy(false); 30960b57cec5SDimitry Andric } 30970b57cec5SDimitry Andric } 30980b57cec5SDimitry Andric } 30990b57cec5SDimitry Andric return error; 31000b57cec5SDimitry Andric } 31010b57cec5SDimitry Andric 31020b57cec5SDimitry Andric void Target::FinalizeFileActions(ProcessLaunchInfo &info) { 31030b57cec5SDimitry Andric Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); 31040b57cec5SDimitry Andric 31050b57cec5SDimitry Andric // Finalize the file actions, and if none were given, default to opening up a 31060b57cec5SDimitry Andric // pseudo terminal 31070b57cec5SDimitry Andric PlatformSP platform_sp = GetPlatform(); 31080b57cec5SDimitry Andric const bool default_to_use_pty = 31090b57cec5SDimitry Andric m_platform_sp ? m_platform_sp->IsHost() : false; 31100b57cec5SDimitry Andric LLDB_LOG( 31110b57cec5SDimitry Andric log, 31120b57cec5SDimitry Andric "have platform={0}, platform_sp->IsHost()={1}, default_to_use_pty={2}", 31130b57cec5SDimitry Andric bool(platform_sp), 31140b57cec5SDimitry Andric platform_sp ? (platform_sp->IsHost() ? "true" : "false") : "n/a", 31150b57cec5SDimitry Andric default_to_use_pty); 31160b57cec5SDimitry Andric 31170b57cec5SDimitry Andric // If nothing for stdin or stdout or stderr was specified, then check the 31180b57cec5SDimitry Andric // process for any default settings that were set with "settings set" 31190b57cec5SDimitry Andric if (info.GetFileActionForFD(STDIN_FILENO) == nullptr || 31200b57cec5SDimitry Andric info.GetFileActionForFD(STDOUT_FILENO) == nullptr || 31210b57cec5SDimitry Andric info.GetFileActionForFD(STDERR_FILENO) == nullptr) { 31220b57cec5SDimitry Andric LLDB_LOG(log, "at least one of stdin/stdout/stderr was not set, evaluating " 31230b57cec5SDimitry Andric "default handling"); 31240b57cec5SDimitry Andric 31250b57cec5SDimitry Andric if (info.GetFlags().Test(eLaunchFlagLaunchInTTY)) { 31260b57cec5SDimitry Andric // Do nothing, if we are launching in a remote terminal no file actions 31270b57cec5SDimitry Andric // should be done at all. 31280b57cec5SDimitry Andric return; 31290b57cec5SDimitry Andric } 31300b57cec5SDimitry Andric 31310b57cec5SDimitry Andric if (info.GetFlags().Test(eLaunchFlagDisableSTDIO)) { 31320b57cec5SDimitry Andric LLDB_LOG(log, "eLaunchFlagDisableSTDIO set, adding suppression action " 31330b57cec5SDimitry Andric "for stdin, stdout and stderr"); 31340b57cec5SDimitry Andric info.AppendSuppressFileAction(STDIN_FILENO, true, false); 31350b57cec5SDimitry Andric info.AppendSuppressFileAction(STDOUT_FILENO, false, true); 31360b57cec5SDimitry Andric info.AppendSuppressFileAction(STDERR_FILENO, false, true); 31370b57cec5SDimitry Andric } else { 31380b57cec5SDimitry Andric // Check for any values that might have gotten set with any of: (lldb) 31390b57cec5SDimitry Andric // settings set target.input-path (lldb) settings set target.output-path 31400b57cec5SDimitry Andric // (lldb) settings set target.error-path 31410b57cec5SDimitry Andric FileSpec in_file_spec; 31420b57cec5SDimitry Andric FileSpec out_file_spec; 31430b57cec5SDimitry Andric FileSpec err_file_spec; 31440b57cec5SDimitry Andric // Only override with the target settings if we don't already have an 31450b57cec5SDimitry Andric // action for in, out or error 31460b57cec5SDimitry Andric if (info.GetFileActionForFD(STDIN_FILENO) == nullptr) 31470b57cec5SDimitry Andric in_file_spec = GetStandardInputPath(); 31480b57cec5SDimitry Andric if (info.GetFileActionForFD(STDOUT_FILENO) == nullptr) 31490b57cec5SDimitry Andric out_file_spec = GetStandardOutputPath(); 31500b57cec5SDimitry Andric if (info.GetFileActionForFD(STDERR_FILENO) == nullptr) 31510b57cec5SDimitry Andric err_file_spec = GetStandardErrorPath(); 31520b57cec5SDimitry Andric 31530b57cec5SDimitry Andric LLDB_LOG(log, "target stdin='{0}', target stdout='{1}', stderr='{1}'", 31540b57cec5SDimitry Andric in_file_spec, out_file_spec, err_file_spec); 31550b57cec5SDimitry Andric 31560b57cec5SDimitry Andric if (in_file_spec) { 31570b57cec5SDimitry Andric info.AppendOpenFileAction(STDIN_FILENO, in_file_spec, true, false); 31580b57cec5SDimitry Andric LLDB_LOG(log, "appended stdin open file action for {0}", in_file_spec); 31590b57cec5SDimitry Andric } 31600b57cec5SDimitry Andric 31610b57cec5SDimitry Andric if (out_file_spec) { 31620b57cec5SDimitry Andric info.AppendOpenFileAction(STDOUT_FILENO, out_file_spec, false, true); 31630b57cec5SDimitry Andric LLDB_LOG(log, "appended stdout open file action for {0}", 31640b57cec5SDimitry Andric out_file_spec); 31650b57cec5SDimitry Andric } 31660b57cec5SDimitry Andric 31670b57cec5SDimitry Andric if (err_file_spec) { 31680b57cec5SDimitry Andric info.AppendOpenFileAction(STDERR_FILENO, err_file_spec, false, true); 31690b57cec5SDimitry Andric LLDB_LOG(log, "appended stderr open file action for {0}", 31700b57cec5SDimitry Andric err_file_spec); 31710b57cec5SDimitry Andric } 31720b57cec5SDimitry Andric 31730b57cec5SDimitry Andric if (default_to_use_pty && 31740b57cec5SDimitry Andric (!in_file_spec || !out_file_spec || !err_file_spec)) { 31750b57cec5SDimitry Andric llvm::Error Err = info.SetUpPtyRedirection(); 31760b57cec5SDimitry Andric LLDB_LOG_ERROR(log, std::move(Err), "SetUpPtyRedirection failed: {0}"); 31770b57cec5SDimitry Andric } 31780b57cec5SDimitry Andric } 31790b57cec5SDimitry Andric } 31800b57cec5SDimitry Andric } 31810b57cec5SDimitry Andric 31820b57cec5SDimitry Andric // Target::StopHook 31830b57cec5SDimitry Andric Target::StopHook::StopHook(lldb::TargetSP target_sp, lldb::user_id_t uid) 31840b57cec5SDimitry Andric : UserID(uid), m_target_sp(target_sp), m_commands(), m_specifier_sp(), 31850b57cec5SDimitry Andric m_thread_spec_up() {} 31860b57cec5SDimitry Andric 31870b57cec5SDimitry Andric Target::StopHook::StopHook(const StopHook &rhs) 31880b57cec5SDimitry Andric : UserID(rhs.GetID()), m_target_sp(rhs.m_target_sp), 31890b57cec5SDimitry Andric m_commands(rhs.m_commands), m_specifier_sp(rhs.m_specifier_sp), 31900b57cec5SDimitry Andric m_thread_spec_up(), m_active(rhs.m_active), 31910b57cec5SDimitry Andric m_auto_continue(rhs.m_auto_continue) { 31920b57cec5SDimitry Andric if (rhs.m_thread_spec_up) 31935ffd83dbSDimitry Andric m_thread_spec_up = std::make_unique<ThreadSpec>(*rhs.m_thread_spec_up); 31940b57cec5SDimitry Andric } 31950b57cec5SDimitry Andric 31960b57cec5SDimitry Andric Target::StopHook::~StopHook() = default; 31970b57cec5SDimitry Andric 31980b57cec5SDimitry Andric void Target::StopHook::SetSpecifier(SymbolContextSpecifier *specifier) { 31990b57cec5SDimitry Andric m_specifier_sp.reset(specifier); 32000b57cec5SDimitry Andric } 32010b57cec5SDimitry Andric 32020b57cec5SDimitry Andric void Target::StopHook::SetThreadSpecifier(ThreadSpec *specifier) { 32030b57cec5SDimitry Andric m_thread_spec_up.reset(specifier); 32040b57cec5SDimitry Andric } 32050b57cec5SDimitry Andric 32060b57cec5SDimitry Andric void Target::StopHook::GetDescription(Stream *s, 32070b57cec5SDimitry Andric lldb::DescriptionLevel level) const { 3208480093f4SDimitry Andric unsigned indent_level = s->GetIndentLevel(); 32090b57cec5SDimitry Andric 32100b57cec5SDimitry Andric s->SetIndentLevel(indent_level + 2); 32110b57cec5SDimitry Andric 32120b57cec5SDimitry Andric s->Printf("Hook: %" PRIu64 "\n", GetID()); 32130b57cec5SDimitry Andric if (m_active) 32140b57cec5SDimitry Andric s->Indent("State: enabled\n"); 32150b57cec5SDimitry Andric else 32160b57cec5SDimitry Andric s->Indent("State: disabled\n"); 32170b57cec5SDimitry Andric 32180b57cec5SDimitry Andric if (m_auto_continue) 32190b57cec5SDimitry Andric s->Indent("AutoContinue on\n"); 32200b57cec5SDimitry Andric 32210b57cec5SDimitry Andric if (m_specifier_sp) { 32220b57cec5SDimitry Andric s->Indent(); 32230b57cec5SDimitry Andric s->PutCString("Specifier:\n"); 32240b57cec5SDimitry Andric s->SetIndentLevel(indent_level + 4); 32250b57cec5SDimitry Andric m_specifier_sp->GetDescription(s, level); 32260b57cec5SDimitry Andric s->SetIndentLevel(indent_level + 2); 32270b57cec5SDimitry Andric } 32280b57cec5SDimitry Andric 32290b57cec5SDimitry Andric if (m_thread_spec_up) { 32300b57cec5SDimitry Andric StreamString tmp; 32310b57cec5SDimitry Andric s->Indent("Thread:\n"); 32320b57cec5SDimitry Andric m_thread_spec_up->GetDescription(&tmp, level); 32330b57cec5SDimitry Andric s->SetIndentLevel(indent_level + 4); 32340b57cec5SDimitry Andric s->Indent(tmp.GetString()); 32350b57cec5SDimitry Andric s->PutCString("\n"); 32360b57cec5SDimitry Andric s->SetIndentLevel(indent_level + 2); 32370b57cec5SDimitry Andric } 32380b57cec5SDimitry Andric 32390b57cec5SDimitry Andric s->Indent("Commands: \n"); 32400b57cec5SDimitry Andric s->SetIndentLevel(indent_level + 4); 32410b57cec5SDimitry Andric uint32_t num_commands = m_commands.GetSize(); 32420b57cec5SDimitry Andric for (uint32_t i = 0; i < num_commands; i++) { 32430b57cec5SDimitry Andric s->Indent(m_commands.GetStringAtIndex(i)); 32440b57cec5SDimitry Andric s->PutCString("\n"); 32450b57cec5SDimitry Andric } 32460b57cec5SDimitry Andric s->SetIndentLevel(indent_level); 32470b57cec5SDimitry Andric } 32480b57cec5SDimitry Andric 32490b57cec5SDimitry Andric static constexpr OptionEnumValueElement g_dynamic_value_types[] = { 32509dba64beSDimitry Andric { 32519dba64beSDimitry Andric eNoDynamicValues, 32529dba64beSDimitry Andric "no-dynamic-values", 32539dba64beSDimitry Andric "Don't calculate the dynamic type of values", 32549dba64beSDimitry Andric }, 32559dba64beSDimitry Andric { 32569dba64beSDimitry Andric eDynamicCanRunTarget, 32579dba64beSDimitry Andric "run-target", 32589dba64beSDimitry Andric "Calculate the dynamic type of values " 32599dba64beSDimitry Andric "even if you have to run the target.", 32609dba64beSDimitry Andric }, 32619dba64beSDimitry Andric { 32629dba64beSDimitry Andric eDynamicDontRunTarget, 32639dba64beSDimitry Andric "no-run-target", 32649dba64beSDimitry Andric "Calculate the dynamic type of values, but don't run the target.", 32659dba64beSDimitry Andric }, 32669dba64beSDimitry Andric }; 32670b57cec5SDimitry Andric 32680b57cec5SDimitry Andric OptionEnumValues lldb_private::GetDynamicValueTypes() { 32690b57cec5SDimitry Andric return OptionEnumValues(g_dynamic_value_types); 32700b57cec5SDimitry Andric } 32710b57cec5SDimitry Andric 32720b57cec5SDimitry Andric static constexpr OptionEnumValueElement g_inline_breakpoint_enums[] = { 32739dba64beSDimitry Andric { 32749dba64beSDimitry Andric eInlineBreakpointsNever, 32759dba64beSDimitry Andric "never", 32769dba64beSDimitry Andric "Never look for inline breakpoint locations (fastest). This setting " 32779dba64beSDimitry Andric "should only be used if you know that no inlining occurs in your" 32789dba64beSDimitry Andric "programs.", 32799dba64beSDimitry Andric }, 32809dba64beSDimitry Andric { 32819dba64beSDimitry Andric eInlineBreakpointsHeaders, 32829dba64beSDimitry Andric "headers", 32839dba64beSDimitry Andric "Only check for inline breakpoint locations when setting breakpoints " 32849dba64beSDimitry Andric "in header files, but not when setting breakpoint in implementation " 32859dba64beSDimitry Andric "source files (default).", 32869dba64beSDimitry Andric }, 32879dba64beSDimitry Andric { 32889dba64beSDimitry Andric eInlineBreakpointsAlways, 32899dba64beSDimitry Andric "always", 32909dba64beSDimitry Andric "Always look for inline breakpoint locations when setting file and " 32919dba64beSDimitry Andric "line breakpoints (slower but most accurate).", 32929dba64beSDimitry Andric }, 32939dba64beSDimitry Andric }; 32940b57cec5SDimitry Andric 32950b57cec5SDimitry Andric enum x86DisassemblyFlavor { 32960b57cec5SDimitry Andric eX86DisFlavorDefault, 32970b57cec5SDimitry Andric eX86DisFlavorIntel, 32980b57cec5SDimitry Andric eX86DisFlavorATT 32990b57cec5SDimitry Andric }; 33000b57cec5SDimitry Andric 33010b57cec5SDimitry Andric static constexpr OptionEnumValueElement g_x86_dis_flavor_value_types[] = { 33029dba64beSDimitry Andric { 33039dba64beSDimitry Andric eX86DisFlavorDefault, 33049dba64beSDimitry Andric "default", 33059dba64beSDimitry Andric "Disassembler default (currently att).", 33069dba64beSDimitry Andric }, 33079dba64beSDimitry Andric { 33089dba64beSDimitry Andric eX86DisFlavorIntel, 33099dba64beSDimitry Andric "intel", 33109dba64beSDimitry Andric "Intel disassembler flavor.", 33119dba64beSDimitry Andric }, 33129dba64beSDimitry Andric { 33139dba64beSDimitry Andric eX86DisFlavorATT, 33149dba64beSDimitry Andric "att", 33159dba64beSDimitry Andric "AT&T disassembler flavor.", 33169dba64beSDimitry Andric }, 33179dba64beSDimitry Andric }; 33180b57cec5SDimitry Andric 33190b57cec5SDimitry Andric static constexpr OptionEnumValueElement g_hex_immediate_style_values[] = { 33209dba64beSDimitry Andric { 33219dba64beSDimitry Andric Disassembler::eHexStyleC, 33229dba64beSDimitry Andric "c", 33239dba64beSDimitry Andric "C-style (0xffff).", 33249dba64beSDimitry Andric }, 33259dba64beSDimitry Andric { 33269dba64beSDimitry Andric Disassembler::eHexStyleAsm, 33279dba64beSDimitry Andric "asm", 33289dba64beSDimitry Andric "Asm-style (0ffffh).", 33299dba64beSDimitry Andric }, 33309dba64beSDimitry Andric }; 33310b57cec5SDimitry Andric 33320b57cec5SDimitry Andric static constexpr OptionEnumValueElement g_load_script_from_sym_file_values[] = { 33339dba64beSDimitry Andric { 33349dba64beSDimitry Andric eLoadScriptFromSymFileTrue, 33359dba64beSDimitry Andric "true", 33369dba64beSDimitry Andric "Load debug scripts inside symbol files", 33379dba64beSDimitry Andric }, 33389dba64beSDimitry Andric { 33399dba64beSDimitry Andric eLoadScriptFromSymFileFalse, 33409dba64beSDimitry Andric "false", 33419dba64beSDimitry Andric "Do not load debug scripts inside symbol files.", 33429dba64beSDimitry Andric }, 33439dba64beSDimitry Andric { 33449dba64beSDimitry Andric eLoadScriptFromSymFileWarn, 33459dba64beSDimitry Andric "warn", 33469dba64beSDimitry Andric "Warn about debug scripts inside symbol files but do not load them.", 33479dba64beSDimitry Andric }, 33489dba64beSDimitry Andric }; 33490b57cec5SDimitry Andric 33509dba64beSDimitry Andric static constexpr OptionEnumValueElement g_load_cwd_lldbinit_values[] = { 33519dba64beSDimitry Andric { 33529dba64beSDimitry Andric eLoadCWDlldbinitTrue, 33539dba64beSDimitry Andric "true", 33549dba64beSDimitry Andric "Load .lldbinit files from current directory", 33559dba64beSDimitry Andric }, 33569dba64beSDimitry Andric { 33579dba64beSDimitry Andric eLoadCWDlldbinitFalse, 33589dba64beSDimitry Andric "false", 33599dba64beSDimitry Andric "Do not load .lldbinit files from current directory", 33609dba64beSDimitry Andric }, 33619dba64beSDimitry Andric { 33629dba64beSDimitry Andric eLoadCWDlldbinitWarn, 33639dba64beSDimitry Andric "warn", 33649dba64beSDimitry Andric "Warn about loading .lldbinit files from current directory", 33659dba64beSDimitry Andric }, 33669dba64beSDimitry Andric }; 33670b57cec5SDimitry Andric 33680b57cec5SDimitry Andric static constexpr OptionEnumValueElement g_memory_module_load_level_values[] = { 33699dba64beSDimitry Andric { 33709dba64beSDimitry Andric eMemoryModuleLoadLevelMinimal, 33719dba64beSDimitry Andric "minimal", 33720b57cec5SDimitry Andric "Load minimal information when loading modules from memory. Currently " 33739dba64beSDimitry Andric "this setting loads sections only.", 33749dba64beSDimitry Andric }, 33759dba64beSDimitry Andric { 33769dba64beSDimitry Andric eMemoryModuleLoadLevelPartial, 33779dba64beSDimitry Andric "partial", 33780b57cec5SDimitry Andric "Load partial information when loading modules from memory. Currently " 33799dba64beSDimitry Andric "this setting loads sections and function bounds.", 33809dba64beSDimitry Andric }, 33819dba64beSDimitry Andric { 33829dba64beSDimitry Andric eMemoryModuleLoadLevelComplete, 33839dba64beSDimitry Andric "complete", 33840b57cec5SDimitry Andric "Load complete information when loading modules from memory. Currently " 33859dba64beSDimitry Andric "this setting loads sections and all symbols.", 33869dba64beSDimitry Andric }, 33879dba64beSDimitry Andric }; 33880b57cec5SDimitry Andric 33899dba64beSDimitry Andric #define LLDB_PROPERTIES_target 33909dba64beSDimitry Andric #include "TargetProperties.inc" 33910b57cec5SDimitry Andric 33920b57cec5SDimitry Andric enum { 33939dba64beSDimitry Andric #define LLDB_PROPERTIES_target 33949dba64beSDimitry Andric #include "TargetPropertiesEnum.inc" 33950b57cec5SDimitry Andric ePropertyExperimental, 33960b57cec5SDimitry Andric }; 33970b57cec5SDimitry Andric 33980b57cec5SDimitry Andric class TargetOptionValueProperties : public OptionValueProperties { 33990b57cec5SDimitry Andric public: 34005ffd83dbSDimitry Andric TargetOptionValueProperties(ConstString name) : OptionValueProperties(name) {} 34010b57cec5SDimitry Andric 34020b57cec5SDimitry Andric // This constructor is used when creating TargetOptionValueProperties when it 34030b57cec5SDimitry Andric // is part of a new lldb_private::Target instance. It will copy all current 34040b57cec5SDimitry Andric // global property values as needed 34055ffd83dbSDimitry Andric TargetOptionValueProperties(const TargetPropertiesSP &target_properties_sp) 34065ffd83dbSDimitry Andric : OptionValueProperties(*target_properties_sp->GetValueProperties()) {} 34070b57cec5SDimitry Andric 34080b57cec5SDimitry Andric const Property *GetPropertyAtIndex(const ExecutionContext *exe_ctx, 34090b57cec5SDimitry Andric bool will_modify, 34100b57cec5SDimitry Andric uint32_t idx) const override { 34110b57cec5SDimitry Andric // When getting the value for a key from the target options, we will always 34120b57cec5SDimitry Andric // try and grab the setting from the current target if there is one. Else 34130b57cec5SDimitry Andric // we just use the one from this instance. 34140b57cec5SDimitry Andric if (exe_ctx) { 34150b57cec5SDimitry Andric Target *target = exe_ctx->GetTargetPtr(); 34160b57cec5SDimitry Andric if (target) { 34170b57cec5SDimitry Andric TargetOptionValueProperties *target_properties = 34180b57cec5SDimitry Andric static_cast<TargetOptionValueProperties *>( 34190b57cec5SDimitry Andric target->GetValueProperties().get()); 34200b57cec5SDimitry Andric if (this != target_properties) 34210b57cec5SDimitry Andric return target_properties->ProtectedGetPropertyAtIndex(idx); 34220b57cec5SDimitry Andric } 34230b57cec5SDimitry Andric } 34240b57cec5SDimitry Andric return ProtectedGetPropertyAtIndex(idx); 34250b57cec5SDimitry Andric } 34260b57cec5SDimitry Andric }; 34270b57cec5SDimitry Andric 34280b57cec5SDimitry Andric // TargetProperties 34295ffd83dbSDimitry Andric #define LLDB_PROPERTIES_target_experimental 34309dba64beSDimitry Andric #include "TargetProperties.inc" 34310b57cec5SDimitry Andric 34329dba64beSDimitry Andric enum { 34335ffd83dbSDimitry Andric #define LLDB_PROPERTIES_target_experimental 34349dba64beSDimitry Andric #include "TargetPropertiesEnum.inc" 34359dba64beSDimitry Andric }; 34360b57cec5SDimitry Andric 34370b57cec5SDimitry Andric class TargetExperimentalOptionValueProperties : public OptionValueProperties { 34380b57cec5SDimitry Andric public: 34390b57cec5SDimitry Andric TargetExperimentalOptionValueProperties() 34400b57cec5SDimitry Andric : OptionValueProperties( 34410b57cec5SDimitry Andric ConstString(Properties::GetExperimentalSettingsName())) {} 34420b57cec5SDimitry Andric }; 34430b57cec5SDimitry Andric 34440b57cec5SDimitry Andric TargetExperimentalProperties::TargetExperimentalProperties() 34450b57cec5SDimitry Andric : Properties(OptionValuePropertiesSP( 34460b57cec5SDimitry Andric new TargetExperimentalOptionValueProperties())) { 34475ffd83dbSDimitry Andric m_collection_sp->Initialize(g_target_experimental_properties); 34480b57cec5SDimitry Andric } 34490b57cec5SDimitry Andric 34500b57cec5SDimitry Andric // TargetProperties 34510b57cec5SDimitry Andric TargetProperties::TargetProperties(Target *target) 34525ffd83dbSDimitry Andric : Properties(), m_launch_info(), m_target(target) { 34530b57cec5SDimitry Andric if (target) { 34540b57cec5SDimitry Andric m_collection_sp = std::make_shared<TargetOptionValueProperties>( 34555ffd83dbSDimitry Andric Target::GetGlobalProperties()); 34560b57cec5SDimitry Andric 34570b57cec5SDimitry Andric // Set callbacks to update launch_info whenever "settins set" updated any 34580b57cec5SDimitry Andric // of these properties 34590b57cec5SDimitry Andric m_collection_sp->SetValueChangedCallback( 3460480093f4SDimitry Andric ePropertyArg0, [this] { Arg0ValueChangedCallback(); }); 34610b57cec5SDimitry Andric m_collection_sp->SetValueChangedCallback( 3462480093f4SDimitry Andric ePropertyRunArgs, [this] { RunArgsValueChangedCallback(); }); 34630b57cec5SDimitry Andric m_collection_sp->SetValueChangedCallback( 3464480093f4SDimitry Andric ePropertyEnvVars, [this] { EnvVarsValueChangedCallback(); }); 34650b57cec5SDimitry Andric m_collection_sp->SetValueChangedCallback( 34665ffd83dbSDimitry Andric ePropertyUnsetEnvVars, [this] { EnvVarsValueChangedCallback(); }); 34675ffd83dbSDimitry Andric m_collection_sp->SetValueChangedCallback( 34685ffd83dbSDimitry Andric ePropertyInheritEnv, [this] { EnvVarsValueChangedCallback(); }); 34695ffd83dbSDimitry Andric m_collection_sp->SetValueChangedCallback( 3470480093f4SDimitry Andric ePropertyInputPath, [this] { InputPathValueChangedCallback(); }); 34710b57cec5SDimitry Andric m_collection_sp->SetValueChangedCallback( 3472480093f4SDimitry Andric ePropertyOutputPath, [this] { OutputPathValueChangedCallback(); }); 34730b57cec5SDimitry Andric m_collection_sp->SetValueChangedCallback( 3474480093f4SDimitry Andric ePropertyErrorPath, [this] { ErrorPathValueChangedCallback(); }); 3475480093f4SDimitry Andric m_collection_sp->SetValueChangedCallback(ePropertyDetachOnError, [this] { 3476480093f4SDimitry Andric DetachOnErrorValueChangedCallback(); 3477480093f4SDimitry Andric }); 34780b57cec5SDimitry Andric m_collection_sp->SetValueChangedCallback( 3479480093f4SDimitry Andric ePropertyDisableASLR, [this] { DisableASLRValueChangedCallback(); }); 34800b57cec5SDimitry Andric m_collection_sp->SetValueChangedCallback( 3481480093f4SDimitry Andric ePropertyDisableSTDIO, [this] { DisableSTDIOValueChangedCallback(); }); 34820b57cec5SDimitry Andric 34835ffd83dbSDimitry Andric m_experimental_properties_up = 34845ffd83dbSDimitry Andric std::make_unique<TargetExperimentalProperties>(); 34850b57cec5SDimitry Andric m_collection_sp->AppendProperty( 34860b57cec5SDimitry Andric ConstString(Properties::GetExperimentalSettingsName()), 34870b57cec5SDimitry Andric ConstString("Experimental settings - setting these won't produce " 34880b57cec5SDimitry Andric "errors if the setting is not present."), 34890b57cec5SDimitry Andric true, m_experimental_properties_up->GetValueProperties()); 34900b57cec5SDimitry Andric } else { 34910b57cec5SDimitry Andric m_collection_sp = 34920b57cec5SDimitry Andric std::make_shared<TargetOptionValueProperties>(ConstString("target")); 34939dba64beSDimitry Andric m_collection_sp->Initialize(g_target_properties); 34945ffd83dbSDimitry Andric m_experimental_properties_up = 34955ffd83dbSDimitry Andric std::make_unique<TargetExperimentalProperties>(); 34960b57cec5SDimitry Andric m_collection_sp->AppendProperty( 34970b57cec5SDimitry Andric ConstString(Properties::GetExperimentalSettingsName()), 34980b57cec5SDimitry Andric ConstString("Experimental settings - setting these won't produce " 34990b57cec5SDimitry Andric "errors if the setting is not present."), 35000b57cec5SDimitry Andric true, m_experimental_properties_up->GetValueProperties()); 35010b57cec5SDimitry Andric m_collection_sp->AppendProperty( 35020b57cec5SDimitry Andric ConstString("process"), ConstString("Settings specific to processes."), 35030b57cec5SDimitry Andric true, Process::GetGlobalProperties()->GetValueProperties()); 35040b57cec5SDimitry Andric } 35050b57cec5SDimitry Andric } 35060b57cec5SDimitry Andric 35070b57cec5SDimitry Andric TargetProperties::~TargetProperties() = default; 35080b57cec5SDimitry Andric 35095ffd83dbSDimitry Andric void TargetProperties::UpdateLaunchInfoFromProperties() { 35105ffd83dbSDimitry Andric Arg0ValueChangedCallback(); 35115ffd83dbSDimitry Andric RunArgsValueChangedCallback(); 35125ffd83dbSDimitry Andric EnvVarsValueChangedCallback(); 35135ffd83dbSDimitry Andric InputPathValueChangedCallback(); 35145ffd83dbSDimitry Andric OutputPathValueChangedCallback(); 35155ffd83dbSDimitry Andric ErrorPathValueChangedCallback(); 35165ffd83dbSDimitry Andric DetachOnErrorValueChangedCallback(); 35175ffd83dbSDimitry Andric DisableASLRValueChangedCallback(); 35185ffd83dbSDimitry Andric DisableSTDIOValueChangedCallback(); 35195ffd83dbSDimitry Andric } 35205ffd83dbSDimitry Andric 35210b57cec5SDimitry Andric bool TargetProperties::GetInjectLocalVariables( 35220b57cec5SDimitry Andric ExecutionContext *exe_ctx) const { 35230b57cec5SDimitry Andric const Property *exp_property = m_collection_sp->GetPropertyAtIndex( 35240b57cec5SDimitry Andric exe_ctx, false, ePropertyExperimental); 35250b57cec5SDimitry Andric OptionValueProperties *exp_values = 35260b57cec5SDimitry Andric exp_property->GetValue()->GetAsProperties(); 35270b57cec5SDimitry Andric if (exp_values) 35280b57cec5SDimitry Andric return exp_values->GetPropertyAtIndexAsBoolean( 35290b57cec5SDimitry Andric exe_ctx, ePropertyInjectLocalVars, true); 35300b57cec5SDimitry Andric else 35310b57cec5SDimitry Andric return true; 35320b57cec5SDimitry Andric } 35330b57cec5SDimitry Andric 35340b57cec5SDimitry Andric void TargetProperties::SetInjectLocalVariables(ExecutionContext *exe_ctx, 35350b57cec5SDimitry Andric bool b) { 35360b57cec5SDimitry Andric const Property *exp_property = 35370b57cec5SDimitry Andric m_collection_sp->GetPropertyAtIndex(exe_ctx, true, ePropertyExperimental); 35380b57cec5SDimitry Andric OptionValueProperties *exp_values = 35390b57cec5SDimitry Andric exp_property->GetValue()->GetAsProperties(); 35400b57cec5SDimitry Andric if (exp_values) 35410b57cec5SDimitry Andric exp_values->SetPropertyAtIndexAsBoolean(exe_ctx, ePropertyInjectLocalVars, 35420b57cec5SDimitry Andric true); 35430b57cec5SDimitry Andric } 35440b57cec5SDimitry Andric 35450b57cec5SDimitry Andric ArchSpec TargetProperties::GetDefaultArchitecture() const { 35460b57cec5SDimitry Andric OptionValueArch *value = m_collection_sp->GetPropertyAtIndexAsOptionValueArch( 35470b57cec5SDimitry Andric nullptr, ePropertyDefaultArch); 35480b57cec5SDimitry Andric if (value) 35490b57cec5SDimitry Andric return value->GetCurrentValue(); 35500b57cec5SDimitry Andric return ArchSpec(); 35510b57cec5SDimitry Andric } 35520b57cec5SDimitry Andric 35530b57cec5SDimitry Andric void TargetProperties::SetDefaultArchitecture(const ArchSpec &arch) { 35540b57cec5SDimitry Andric OptionValueArch *value = m_collection_sp->GetPropertyAtIndexAsOptionValueArch( 35550b57cec5SDimitry Andric nullptr, ePropertyDefaultArch); 35560b57cec5SDimitry Andric if (value) 35570b57cec5SDimitry Andric return value->SetCurrentValue(arch, true); 35580b57cec5SDimitry Andric } 35590b57cec5SDimitry Andric 35600b57cec5SDimitry Andric bool TargetProperties::GetMoveToNearestCode() const { 35610b57cec5SDimitry Andric const uint32_t idx = ePropertyMoveToNearestCode; 35620b57cec5SDimitry Andric return m_collection_sp->GetPropertyAtIndexAsBoolean( 35639dba64beSDimitry Andric nullptr, idx, g_target_properties[idx].default_uint_value != 0); 35640b57cec5SDimitry Andric } 35650b57cec5SDimitry Andric 35660b57cec5SDimitry Andric lldb::DynamicValueType TargetProperties::GetPreferDynamicValue() const { 35670b57cec5SDimitry Andric const uint32_t idx = ePropertyPreferDynamic; 35680b57cec5SDimitry Andric return (lldb::DynamicValueType) 35690b57cec5SDimitry Andric m_collection_sp->GetPropertyAtIndexAsEnumeration( 35709dba64beSDimitry Andric nullptr, idx, g_target_properties[idx].default_uint_value); 35710b57cec5SDimitry Andric } 35720b57cec5SDimitry Andric 35730b57cec5SDimitry Andric bool TargetProperties::SetPreferDynamicValue(lldb::DynamicValueType d) { 35740b57cec5SDimitry Andric const uint32_t idx = ePropertyPreferDynamic; 35750b57cec5SDimitry Andric return m_collection_sp->SetPropertyAtIndexAsEnumeration(nullptr, idx, d); 35760b57cec5SDimitry Andric } 35770b57cec5SDimitry Andric 35780b57cec5SDimitry Andric bool TargetProperties::GetPreloadSymbols() const { 35790b57cec5SDimitry Andric const uint32_t idx = ePropertyPreloadSymbols; 35800b57cec5SDimitry Andric return m_collection_sp->GetPropertyAtIndexAsBoolean( 35819dba64beSDimitry Andric nullptr, idx, g_target_properties[idx].default_uint_value != 0); 35820b57cec5SDimitry Andric } 35830b57cec5SDimitry Andric 35840b57cec5SDimitry Andric void TargetProperties::SetPreloadSymbols(bool b) { 35850b57cec5SDimitry Andric const uint32_t idx = ePropertyPreloadSymbols; 35860b57cec5SDimitry Andric m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); 35870b57cec5SDimitry Andric } 35880b57cec5SDimitry Andric 35890b57cec5SDimitry Andric bool TargetProperties::GetDisableASLR() const { 35900b57cec5SDimitry Andric const uint32_t idx = ePropertyDisableASLR; 35910b57cec5SDimitry Andric return m_collection_sp->GetPropertyAtIndexAsBoolean( 35929dba64beSDimitry Andric nullptr, idx, g_target_properties[idx].default_uint_value != 0); 35930b57cec5SDimitry Andric } 35940b57cec5SDimitry Andric 35950b57cec5SDimitry Andric void TargetProperties::SetDisableASLR(bool b) { 35960b57cec5SDimitry Andric const uint32_t idx = ePropertyDisableASLR; 35970b57cec5SDimitry Andric m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); 35980b57cec5SDimitry Andric } 35990b57cec5SDimitry Andric 36000b57cec5SDimitry Andric bool TargetProperties::GetDetachOnError() const { 36010b57cec5SDimitry Andric const uint32_t idx = ePropertyDetachOnError; 36020b57cec5SDimitry Andric return m_collection_sp->GetPropertyAtIndexAsBoolean( 36039dba64beSDimitry Andric nullptr, idx, g_target_properties[idx].default_uint_value != 0); 36040b57cec5SDimitry Andric } 36050b57cec5SDimitry Andric 36060b57cec5SDimitry Andric void TargetProperties::SetDetachOnError(bool b) { 36070b57cec5SDimitry Andric const uint32_t idx = ePropertyDetachOnError; 36080b57cec5SDimitry Andric m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); 36090b57cec5SDimitry Andric } 36100b57cec5SDimitry Andric 36110b57cec5SDimitry Andric bool TargetProperties::GetDisableSTDIO() const { 36120b57cec5SDimitry Andric const uint32_t idx = ePropertyDisableSTDIO; 36130b57cec5SDimitry Andric return m_collection_sp->GetPropertyAtIndexAsBoolean( 36149dba64beSDimitry Andric nullptr, idx, g_target_properties[idx].default_uint_value != 0); 36150b57cec5SDimitry Andric } 36160b57cec5SDimitry Andric 36170b57cec5SDimitry Andric void TargetProperties::SetDisableSTDIO(bool b) { 36180b57cec5SDimitry Andric const uint32_t idx = ePropertyDisableSTDIO; 36190b57cec5SDimitry Andric m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); 36200b57cec5SDimitry Andric } 36210b57cec5SDimitry Andric 36220b57cec5SDimitry Andric const char *TargetProperties::GetDisassemblyFlavor() const { 36230b57cec5SDimitry Andric const uint32_t idx = ePropertyDisassemblyFlavor; 36240b57cec5SDimitry Andric const char *return_value; 36250b57cec5SDimitry Andric 36260b57cec5SDimitry Andric x86DisassemblyFlavor flavor_value = 36270b57cec5SDimitry Andric (x86DisassemblyFlavor)m_collection_sp->GetPropertyAtIndexAsEnumeration( 36289dba64beSDimitry Andric nullptr, idx, g_target_properties[idx].default_uint_value); 36290b57cec5SDimitry Andric return_value = g_x86_dis_flavor_value_types[flavor_value].string_value; 36300b57cec5SDimitry Andric return return_value; 36310b57cec5SDimitry Andric } 36320b57cec5SDimitry Andric 36330b57cec5SDimitry Andric InlineStrategy TargetProperties::GetInlineStrategy() const { 36340b57cec5SDimitry Andric const uint32_t idx = ePropertyInlineStrategy; 36350b57cec5SDimitry Andric return (InlineStrategy)m_collection_sp->GetPropertyAtIndexAsEnumeration( 36369dba64beSDimitry Andric nullptr, idx, g_target_properties[idx].default_uint_value); 36370b57cec5SDimitry Andric } 36380b57cec5SDimitry Andric 36390b57cec5SDimitry Andric llvm::StringRef TargetProperties::GetArg0() const { 36400b57cec5SDimitry Andric const uint32_t idx = ePropertyArg0; 36419dba64beSDimitry Andric return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, 36429dba64beSDimitry Andric llvm::StringRef()); 36430b57cec5SDimitry Andric } 36440b57cec5SDimitry Andric 36450b57cec5SDimitry Andric void TargetProperties::SetArg0(llvm::StringRef arg) { 36460b57cec5SDimitry Andric const uint32_t idx = ePropertyArg0; 36479dba64beSDimitry Andric m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, arg); 36480b57cec5SDimitry Andric m_launch_info.SetArg0(arg); 36490b57cec5SDimitry Andric } 36500b57cec5SDimitry Andric 36510b57cec5SDimitry Andric bool TargetProperties::GetRunArguments(Args &args) const { 36520b57cec5SDimitry Andric const uint32_t idx = ePropertyRunArgs; 36530b57cec5SDimitry Andric return m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, idx, args); 36540b57cec5SDimitry Andric } 36550b57cec5SDimitry Andric 36560b57cec5SDimitry Andric void TargetProperties::SetRunArguments(const Args &args) { 36570b57cec5SDimitry Andric const uint32_t idx = ePropertyRunArgs; 36580b57cec5SDimitry Andric m_collection_sp->SetPropertyAtIndexFromArgs(nullptr, idx, args); 36590b57cec5SDimitry Andric m_launch_info.GetArguments() = args; 36600b57cec5SDimitry Andric } 36610b57cec5SDimitry Andric 36625ffd83dbSDimitry Andric Environment TargetProperties::ComputeEnvironment() const { 36635ffd83dbSDimitry Andric Environment env; 36645ffd83dbSDimitry Andric 36655ffd83dbSDimitry Andric if (m_target && 36665ffd83dbSDimitry Andric m_collection_sp->GetPropertyAtIndexAsBoolean( 36675ffd83dbSDimitry Andric nullptr, ePropertyInheritEnv, 36685ffd83dbSDimitry Andric g_target_properties[ePropertyInheritEnv].default_uint_value != 0)) { 36695ffd83dbSDimitry Andric if (auto platform_sp = m_target->GetPlatform()) { 36705ffd83dbSDimitry Andric Environment platform_env = platform_sp->GetEnvironment(); 36715ffd83dbSDimitry Andric for (const auto &KV : platform_env) 36725ffd83dbSDimitry Andric env[KV.first()] = KV.second; 36735ffd83dbSDimitry Andric } 36745ffd83dbSDimitry Andric } 36755ffd83dbSDimitry Andric 36765ffd83dbSDimitry Andric Args property_unset_env; 36775ffd83dbSDimitry Andric m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, ePropertyUnsetEnvVars, 36785ffd83dbSDimitry Andric property_unset_env); 36795ffd83dbSDimitry Andric for (const auto &var : property_unset_env) 36805ffd83dbSDimitry Andric env.erase(var.ref()); 36815ffd83dbSDimitry Andric 36825ffd83dbSDimitry Andric Args property_env; 36835ffd83dbSDimitry Andric m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, ePropertyEnvVars, 36845ffd83dbSDimitry Andric property_env); 36855ffd83dbSDimitry Andric for (const auto &KV : Environment(property_env)) 36865ffd83dbSDimitry Andric env[KV.first()] = KV.second; 36875ffd83dbSDimitry Andric 36885ffd83dbSDimitry Andric return env; 36895ffd83dbSDimitry Andric } 36905ffd83dbSDimitry Andric 36910b57cec5SDimitry Andric Environment TargetProperties::GetEnvironment() const { 36925ffd83dbSDimitry Andric return ComputeEnvironment(); 36930b57cec5SDimitry Andric } 36940b57cec5SDimitry Andric 36950b57cec5SDimitry Andric void TargetProperties::SetEnvironment(Environment env) { 36960b57cec5SDimitry Andric // TODO: Get rid of the Args intermediate step 36970b57cec5SDimitry Andric const uint32_t idx = ePropertyEnvVars; 36980b57cec5SDimitry Andric m_collection_sp->SetPropertyAtIndexFromArgs(nullptr, idx, Args(env)); 36990b57cec5SDimitry Andric } 37000b57cec5SDimitry Andric 37010b57cec5SDimitry Andric bool TargetProperties::GetSkipPrologue() const { 37020b57cec5SDimitry Andric const uint32_t idx = ePropertySkipPrologue; 37030b57cec5SDimitry Andric return m_collection_sp->GetPropertyAtIndexAsBoolean( 37049dba64beSDimitry Andric nullptr, idx, g_target_properties[idx].default_uint_value != 0); 37050b57cec5SDimitry Andric } 37060b57cec5SDimitry Andric 37070b57cec5SDimitry Andric PathMappingList &TargetProperties::GetSourcePathMap() const { 37080b57cec5SDimitry Andric const uint32_t idx = ePropertySourceMap; 37090b57cec5SDimitry Andric OptionValuePathMappings *option_value = 37100b57cec5SDimitry Andric m_collection_sp->GetPropertyAtIndexAsOptionValuePathMappings(nullptr, 37110b57cec5SDimitry Andric false, idx); 37120b57cec5SDimitry Andric assert(option_value); 37130b57cec5SDimitry Andric return option_value->GetCurrentValue(); 37140b57cec5SDimitry Andric } 37150b57cec5SDimitry Andric 37160b57cec5SDimitry Andric void TargetProperties::AppendExecutableSearchPaths(const FileSpec &dir) { 37170b57cec5SDimitry Andric const uint32_t idx = ePropertyExecutableSearchPaths; 37180b57cec5SDimitry Andric OptionValueFileSpecList *option_value = 37190b57cec5SDimitry Andric m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(nullptr, 37200b57cec5SDimitry Andric false, idx); 37210b57cec5SDimitry Andric assert(option_value); 37220b57cec5SDimitry Andric option_value->AppendCurrentValue(dir); 37230b57cec5SDimitry Andric } 37240b57cec5SDimitry Andric 37250b57cec5SDimitry Andric FileSpecList TargetProperties::GetExecutableSearchPaths() { 37260b57cec5SDimitry Andric const uint32_t idx = ePropertyExecutableSearchPaths; 37270b57cec5SDimitry Andric const OptionValueFileSpecList *option_value = 37280b57cec5SDimitry Andric m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(nullptr, 37290b57cec5SDimitry Andric false, idx); 37300b57cec5SDimitry Andric assert(option_value); 37310b57cec5SDimitry Andric return option_value->GetCurrentValue(); 37320b57cec5SDimitry Andric } 37330b57cec5SDimitry Andric 37340b57cec5SDimitry Andric FileSpecList TargetProperties::GetDebugFileSearchPaths() { 37350b57cec5SDimitry Andric const uint32_t idx = ePropertyDebugFileSearchPaths; 37360b57cec5SDimitry Andric const OptionValueFileSpecList *option_value = 37370b57cec5SDimitry Andric m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(nullptr, 37380b57cec5SDimitry Andric false, idx); 37390b57cec5SDimitry Andric assert(option_value); 37400b57cec5SDimitry Andric return option_value->GetCurrentValue(); 37410b57cec5SDimitry Andric } 37420b57cec5SDimitry Andric 37430b57cec5SDimitry Andric FileSpecList TargetProperties::GetClangModuleSearchPaths() { 37440b57cec5SDimitry Andric const uint32_t idx = ePropertyClangModuleSearchPaths; 37450b57cec5SDimitry Andric const OptionValueFileSpecList *option_value = 37460b57cec5SDimitry Andric m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(nullptr, 37470b57cec5SDimitry Andric false, idx); 37480b57cec5SDimitry Andric assert(option_value); 37490b57cec5SDimitry Andric return option_value->GetCurrentValue(); 37500b57cec5SDimitry Andric } 37510b57cec5SDimitry Andric 37520b57cec5SDimitry Andric bool TargetProperties::GetEnableAutoImportClangModules() const { 37530b57cec5SDimitry Andric const uint32_t idx = ePropertyAutoImportClangModules; 37540b57cec5SDimitry Andric return m_collection_sp->GetPropertyAtIndexAsBoolean( 37559dba64beSDimitry Andric nullptr, idx, g_target_properties[idx].default_uint_value != 0); 37560b57cec5SDimitry Andric } 37570b57cec5SDimitry Andric 37580b57cec5SDimitry Andric bool TargetProperties::GetEnableImportStdModule() const { 37590b57cec5SDimitry Andric const uint32_t idx = ePropertyImportStdModule; 37600b57cec5SDimitry Andric return m_collection_sp->GetPropertyAtIndexAsBoolean( 37619dba64beSDimitry Andric nullptr, idx, g_target_properties[idx].default_uint_value != 0); 37620b57cec5SDimitry Andric } 37630b57cec5SDimitry Andric 37640b57cec5SDimitry Andric bool TargetProperties::GetEnableAutoApplyFixIts() const { 37650b57cec5SDimitry Andric const uint32_t idx = ePropertyAutoApplyFixIts; 37660b57cec5SDimitry Andric return m_collection_sp->GetPropertyAtIndexAsBoolean( 37679dba64beSDimitry Andric nullptr, idx, g_target_properties[idx].default_uint_value != 0); 37680b57cec5SDimitry Andric } 37690b57cec5SDimitry Andric 37705ffd83dbSDimitry Andric uint64_t TargetProperties::GetNumberOfRetriesWithFixits() const { 37715ffd83dbSDimitry Andric const uint32_t idx = ePropertyRetriesWithFixIts; 37725ffd83dbSDimitry Andric return m_collection_sp->GetPropertyAtIndexAsUInt64( 37735ffd83dbSDimitry Andric nullptr, idx, g_target_properties[idx].default_uint_value); 37745ffd83dbSDimitry Andric } 37755ffd83dbSDimitry Andric 37760b57cec5SDimitry Andric bool TargetProperties::GetEnableNotifyAboutFixIts() const { 37770b57cec5SDimitry Andric const uint32_t idx = ePropertyNotifyAboutFixIts; 37780b57cec5SDimitry Andric return m_collection_sp->GetPropertyAtIndexAsBoolean( 37799dba64beSDimitry Andric nullptr, idx, g_target_properties[idx].default_uint_value != 0); 37800b57cec5SDimitry Andric } 37810b57cec5SDimitry Andric 37820b57cec5SDimitry Andric bool TargetProperties::GetEnableSaveObjects() const { 37830b57cec5SDimitry Andric const uint32_t idx = ePropertySaveObjects; 37840b57cec5SDimitry Andric return m_collection_sp->GetPropertyAtIndexAsBoolean( 37859dba64beSDimitry Andric nullptr, idx, g_target_properties[idx].default_uint_value != 0); 37860b57cec5SDimitry Andric } 37870b57cec5SDimitry Andric 37880b57cec5SDimitry Andric bool TargetProperties::GetEnableSyntheticValue() const { 37890b57cec5SDimitry Andric const uint32_t idx = ePropertyEnableSynthetic; 37900b57cec5SDimitry Andric return m_collection_sp->GetPropertyAtIndexAsBoolean( 37919dba64beSDimitry Andric nullptr, idx, g_target_properties[idx].default_uint_value != 0); 37929dba64beSDimitry Andric } 37939dba64beSDimitry Andric 37949dba64beSDimitry Andric uint32_t TargetProperties::GetMaxZeroPaddingInFloatFormat() const { 37959dba64beSDimitry Andric const uint32_t idx = ePropertyMaxZeroPaddingInFloatFormat; 37969dba64beSDimitry Andric return m_collection_sp->GetPropertyAtIndexAsUInt64( 37979dba64beSDimitry Andric nullptr, idx, g_target_properties[idx].default_uint_value); 37980b57cec5SDimitry Andric } 37990b57cec5SDimitry Andric 38000b57cec5SDimitry Andric uint32_t TargetProperties::GetMaximumNumberOfChildrenToDisplay() const { 38010b57cec5SDimitry Andric const uint32_t idx = ePropertyMaxChildrenCount; 38020b57cec5SDimitry Andric return m_collection_sp->GetPropertyAtIndexAsSInt64( 38039dba64beSDimitry Andric nullptr, idx, g_target_properties[idx].default_uint_value); 38040b57cec5SDimitry Andric } 38050b57cec5SDimitry Andric 38060b57cec5SDimitry Andric uint32_t TargetProperties::GetMaximumSizeOfStringSummary() const { 38070b57cec5SDimitry Andric const uint32_t idx = ePropertyMaxSummaryLength; 38080b57cec5SDimitry Andric return m_collection_sp->GetPropertyAtIndexAsSInt64( 38099dba64beSDimitry Andric nullptr, idx, g_target_properties[idx].default_uint_value); 38100b57cec5SDimitry Andric } 38110b57cec5SDimitry Andric 38120b57cec5SDimitry Andric uint32_t TargetProperties::GetMaximumMemReadSize() const { 38130b57cec5SDimitry Andric const uint32_t idx = ePropertyMaxMemReadSize; 38140b57cec5SDimitry Andric return m_collection_sp->GetPropertyAtIndexAsSInt64( 38159dba64beSDimitry Andric nullptr, idx, g_target_properties[idx].default_uint_value); 38160b57cec5SDimitry Andric } 38170b57cec5SDimitry Andric 38180b57cec5SDimitry Andric FileSpec TargetProperties::GetStandardInputPath() const { 38190b57cec5SDimitry Andric const uint32_t idx = ePropertyInputPath; 38200b57cec5SDimitry Andric return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr, idx); 38210b57cec5SDimitry Andric } 38220b57cec5SDimitry Andric 38230b57cec5SDimitry Andric void TargetProperties::SetStandardInputPath(llvm::StringRef path) { 38240b57cec5SDimitry Andric const uint32_t idx = ePropertyInputPath; 38250b57cec5SDimitry Andric m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, path); 38260b57cec5SDimitry Andric } 38270b57cec5SDimitry Andric 38280b57cec5SDimitry Andric FileSpec TargetProperties::GetStandardOutputPath() const { 38290b57cec5SDimitry Andric const uint32_t idx = ePropertyOutputPath; 38300b57cec5SDimitry Andric return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr, idx); 38310b57cec5SDimitry Andric } 38320b57cec5SDimitry Andric 38330b57cec5SDimitry Andric void TargetProperties::SetStandardOutputPath(llvm::StringRef path) { 38340b57cec5SDimitry Andric const uint32_t idx = ePropertyOutputPath; 38350b57cec5SDimitry Andric m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, path); 38360b57cec5SDimitry Andric } 38370b57cec5SDimitry Andric 38380b57cec5SDimitry Andric FileSpec TargetProperties::GetStandardErrorPath() const { 38390b57cec5SDimitry Andric const uint32_t idx = ePropertyErrorPath; 38400b57cec5SDimitry Andric return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr, idx); 38410b57cec5SDimitry Andric } 38420b57cec5SDimitry Andric 38430b57cec5SDimitry Andric void TargetProperties::SetStandardErrorPath(llvm::StringRef path) { 38440b57cec5SDimitry Andric const uint32_t idx = ePropertyErrorPath; 38450b57cec5SDimitry Andric m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, path); 38460b57cec5SDimitry Andric } 38470b57cec5SDimitry Andric 38480b57cec5SDimitry Andric LanguageType TargetProperties::GetLanguage() const { 38490b57cec5SDimitry Andric OptionValueLanguage *value = 38500b57cec5SDimitry Andric m_collection_sp->GetPropertyAtIndexAsOptionValueLanguage( 38510b57cec5SDimitry Andric nullptr, ePropertyLanguage); 38520b57cec5SDimitry Andric if (value) 38530b57cec5SDimitry Andric return value->GetCurrentValue(); 38540b57cec5SDimitry Andric return LanguageType(); 38550b57cec5SDimitry Andric } 38560b57cec5SDimitry Andric 38570b57cec5SDimitry Andric llvm::StringRef TargetProperties::GetExpressionPrefixContents() { 38580b57cec5SDimitry Andric const uint32_t idx = ePropertyExprPrefix; 38590b57cec5SDimitry Andric OptionValueFileSpec *file = 38600b57cec5SDimitry Andric m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpec(nullptr, false, 38610b57cec5SDimitry Andric idx); 38620b57cec5SDimitry Andric if (file) { 38630b57cec5SDimitry Andric DataBufferSP data_sp(file->GetFileContents()); 38640b57cec5SDimitry Andric if (data_sp) 38650b57cec5SDimitry Andric return llvm::StringRef( 38660b57cec5SDimitry Andric reinterpret_cast<const char *>(data_sp->GetBytes()), 38670b57cec5SDimitry Andric data_sp->GetByteSize()); 38680b57cec5SDimitry Andric } 38690b57cec5SDimitry Andric return ""; 38700b57cec5SDimitry Andric } 38710b57cec5SDimitry Andric 38720b57cec5SDimitry Andric bool TargetProperties::GetBreakpointsConsultPlatformAvoidList() { 38730b57cec5SDimitry Andric const uint32_t idx = ePropertyBreakpointUseAvoidList; 38740b57cec5SDimitry Andric return m_collection_sp->GetPropertyAtIndexAsBoolean( 38759dba64beSDimitry Andric nullptr, idx, g_target_properties[idx].default_uint_value != 0); 38760b57cec5SDimitry Andric } 38770b57cec5SDimitry Andric 38780b57cec5SDimitry Andric bool TargetProperties::GetUseHexImmediates() const { 38790b57cec5SDimitry Andric const uint32_t idx = ePropertyUseHexImmediates; 38800b57cec5SDimitry Andric return m_collection_sp->GetPropertyAtIndexAsBoolean( 38819dba64beSDimitry Andric nullptr, idx, g_target_properties[idx].default_uint_value != 0); 38820b57cec5SDimitry Andric } 38830b57cec5SDimitry Andric 38840b57cec5SDimitry Andric bool TargetProperties::GetUseFastStepping() const { 38850b57cec5SDimitry Andric const uint32_t idx = ePropertyUseFastStepping; 38860b57cec5SDimitry Andric return m_collection_sp->GetPropertyAtIndexAsBoolean( 38879dba64beSDimitry Andric nullptr, idx, g_target_properties[idx].default_uint_value != 0); 38880b57cec5SDimitry Andric } 38890b57cec5SDimitry Andric 38900b57cec5SDimitry Andric bool TargetProperties::GetDisplayExpressionsInCrashlogs() const { 38910b57cec5SDimitry Andric const uint32_t idx = ePropertyDisplayExpressionsInCrashlogs; 38920b57cec5SDimitry Andric return m_collection_sp->GetPropertyAtIndexAsBoolean( 38939dba64beSDimitry Andric nullptr, idx, g_target_properties[idx].default_uint_value != 0); 38940b57cec5SDimitry Andric } 38950b57cec5SDimitry Andric 38960b57cec5SDimitry Andric LoadScriptFromSymFile TargetProperties::GetLoadScriptFromSymbolFile() const { 38970b57cec5SDimitry Andric const uint32_t idx = ePropertyLoadScriptFromSymbolFile; 38980b57cec5SDimitry Andric return (LoadScriptFromSymFile) 38990b57cec5SDimitry Andric m_collection_sp->GetPropertyAtIndexAsEnumeration( 39009dba64beSDimitry Andric nullptr, idx, g_target_properties[idx].default_uint_value); 39010b57cec5SDimitry Andric } 39020b57cec5SDimitry Andric 39030b57cec5SDimitry Andric LoadCWDlldbinitFile TargetProperties::GetLoadCWDlldbinitFile() const { 39040b57cec5SDimitry Andric const uint32_t idx = ePropertyLoadCWDlldbinitFile; 39050b57cec5SDimitry Andric return (LoadCWDlldbinitFile)m_collection_sp->GetPropertyAtIndexAsEnumeration( 39069dba64beSDimitry Andric nullptr, idx, g_target_properties[idx].default_uint_value); 39070b57cec5SDimitry Andric } 39080b57cec5SDimitry Andric 39090b57cec5SDimitry Andric Disassembler::HexImmediateStyle TargetProperties::GetHexImmediateStyle() const { 39100b57cec5SDimitry Andric const uint32_t idx = ePropertyHexImmediateStyle; 39110b57cec5SDimitry Andric return (Disassembler::HexImmediateStyle) 39120b57cec5SDimitry Andric m_collection_sp->GetPropertyAtIndexAsEnumeration( 39139dba64beSDimitry Andric nullptr, idx, g_target_properties[idx].default_uint_value); 39140b57cec5SDimitry Andric } 39150b57cec5SDimitry Andric 39160b57cec5SDimitry Andric MemoryModuleLoadLevel TargetProperties::GetMemoryModuleLoadLevel() const { 39170b57cec5SDimitry Andric const uint32_t idx = ePropertyMemoryModuleLoadLevel; 39180b57cec5SDimitry Andric return (MemoryModuleLoadLevel) 39190b57cec5SDimitry Andric m_collection_sp->GetPropertyAtIndexAsEnumeration( 39209dba64beSDimitry Andric nullptr, idx, g_target_properties[idx].default_uint_value); 39210b57cec5SDimitry Andric } 39220b57cec5SDimitry Andric 39230b57cec5SDimitry Andric bool TargetProperties::GetUserSpecifiedTrapHandlerNames(Args &args) const { 39240b57cec5SDimitry Andric const uint32_t idx = ePropertyTrapHandlerNames; 39250b57cec5SDimitry Andric return m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, idx, args); 39260b57cec5SDimitry Andric } 39270b57cec5SDimitry Andric 39280b57cec5SDimitry Andric void TargetProperties::SetUserSpecifiedTrapHandlerNames(const Args &args) { 39290b57cec5SDimitry Andric const uint32_t idx = ePropertyTrapHandlerNames; 39300b57cec5SDimitry Andric m_collection_sp->SetPropertyAtIndexFromArgs(nullptr, idx, args); 39310b57cec5SDimitry Andric } 39320b57cec5SDimitry Andric 39330b57cec5SDimitry Andric bool TargetProperties::GetDisplayRuntimeSupportValues() const { 39340b57cec5SDimitry Andric const uint32_t idx = ePropertyDisplayRuntimeSupportValues; 39350b57cec5SDimitry Andric return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, false); 39360b57cec5SDimitry Andric } 39370b57cec5SDimitry Andric 39380b57cec5SDimitry Andric void TargetProperties::SetDisplayRuntimeSupportValues(bool b) { 39390b57cec5SDimitry Andric const uint32_t idx = ePropertyDisplayRuntimeSupportValues; 39400b57cec5SDimitry Andric m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); 39410b57cec5SDimitry Andric } 39420b57cec5SDimitry Andric 39430b57cec5SDimitry Andric bool TargetProperties::GetDisplayRecognizedArguments() const { 39440b57cec5SDimitry Andric const uint32_t idx = ePropertyDisplayRecognizedArguments; 39450b57cec5SDimitry Andric return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, false); 39460b57cec5SDimitry Andric } 39470b57cec5SDimitry Andric 39480b57cec5SDimitry Andric void TargetProperties::SetDisplayRecognizedArguments(bool b) { 39490b57cec5SDimitry Andric const uint32_t idx = ePropertyDisplayRecognizedArguments; 39500b57cec5SDimitry Andric m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); 39510b57cec5SDimitry Andric } 39520b57cec5SDimitry Andric 39530b57cec5SDimitry Andric bool TargetProperties::GetNonStopModeEnabled() const { 39540b57cec5SDimitry Andric const uint32_t idx = ePropertyNonStopModeEnabled; 39550b57cec5SDimitry Andric return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, false); 39560b57cec5SDimitry Andric } 39570b57cec5SDimitry Andric 39580b57cec5SDimitry Andric void TargetProperties::SetNonStopModeEnabled(bool b) { 39590b57cec5SDimitry Andric const uint32_t idx = ePropertyNonStopModeEnabled; 39600b57cec5SDimitry Andric m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); 39610b57cec5SDimitry Andric } 39620b57cec5SDimitry Andric 39630b57cec5SDimitry Andric const ProcessLaunchInfo &TargetProperties::GetProcessLaunchInfo() { 39640b57cec5SDimitry Andric m_launch_info.SetArg0(GetArg0()); // FIXME: Arg0 callback doesn't work 39650b57cec5SDimitry Andric return m_launch_info; 39660b57cec5SDimitry Andric } 39670b57cec5SDimitry Andric 39680b57cec5SDimitry Andric void TargetProperties::SetProcessLaunchInfo( 39690b57cec5SDimitry Andric const ProcessLaunchInfo &launch_info) { 39700b57cec5SDimitry Andric m_launch_info = launch_info; 39710b57cec5SDimitry Andric SetArg0(launch_info.GetArg0()); 39720b57cec5SDimitry Andric SetRunArguments(launch_info.GetArguments()); 39730b57cec5SDimitry Andric SetEnvironment(launch_info.GetEnvironment()); 39740b57cec5SDimitry Andric const FileAction *input_file_action = 39750b57cec5SDimitry Andric launch_info.GetFileActionForFD(STDIN_FILENO); 39760b57cec5SDimitry Andric if (input_file_action) { 39770b57cec5SDimitry Andric SetStandardInputPath(input_file_action->GetPath()); 39780b57cec5SDimitry Andric } 39790b57cec5SDimitry Andric const FileAction *output_file_action = 39800b57cec5SDimitry Andric launch_info.GetFileActionForFD(STDOUT_FILENO); 39810b57cec5SDimitry Andric if (output_file_action) { 39820b57cec5SDimitry Andric SetStandardOutputPath(output_file_action->GetPath()); 39830b57cec5SDimitry Andric } 39840b57cec5SDimitry Andric const FileAction *error_file_action = 39850b57cec5SDimitry Andric launch_info.GetFileActionForFD(STDERR_FILENO); 39860b57cec5SDimitry Andric if (error_file_action) { 39870b57cec5SDimitry Andric SetStandardErrorPath(error_file_action->GetPath()); 39880b57cec5SDimitry Andric } 39890b57cec5SDimitry Andric SetDetachOnError(launch_info.GetFlags().Test(lldb::eLaunchFlagDetachOnError)); 39900b57cec5SDimitry Andric SetDisableASLR(launch_info.GetFlags().Test(lldb::eLaunchFlagDisableASLR)); 39910b57cec5SDimitry Andric SetDisableSTDIO(launch_info.GetFlags().Test(lldb::eLaunchFlagDisableSTDIO)); 39920b57cec5SDimitry Andric } 39930b57cec5SDimitry Andric 39940b57cec5SDimitry Andric bool TargetProperties::GetRequireHardwareBreakpoints() const { 39950b57cec5SDimitry Andric const uint32_t idx = ePropertyRequireHardwareBreakpoints; 39960b57cec5SDimitry Andric return m_collection_sp->GetPropertyAtIndexAsBoolean( 39979dba64beSDimitry Andric nullptr, idx, g_target_properties[idx].default_uint_value != 0); 39980b57cec5SDimitry Andric } 39990b57cec5SDimitry Andric 40000b57cec5SDimitry Andric void TargetProperties::SetRequireHardwareBreakpoints(bool b) { 40010b57cec5SDimitry Andric const uint32_t idx = ePropertyRequireHardwareBreakpoints; 40020b57cec5SDimitry Andric m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); 40030b57cec5SDimitry Andric } 40040b57cec5SDimitry Andric 40055ffd83dbSDimitry Andric bool TargetProperties::GetAutoInstallMainExecutable() const { 40065ffd83dbSDimitry Andric const uint32_t idx = ePropertyAutoInstallMainExecutable; 40075ffd83dbSDimitry Andric return m_collection_sp->GetPropertyAtIndexAsBoolean( 40085ffd83dbSDimitry Andric nullptr, idx, g_target_properties[idx].default_uint_value != 0); 40095ffd83dbSDimitry Andric } 40105ffd83dbSDimitry Andric 4011480093f4SDimitry Andric void TargetProperties::Arg0ValueChangedCallback() { 4012480093f4SDimitry Andric m_launch_info.SetArg0(GetArg0()); 40130b57cec5SDimitry Andric } 40140b57cec5SDimitry Andric 4015480093f4SDimitry Andric void TargetProperties::RunArgsValueChangedCallback() { 40160b57cec5SDimitry Andric Args args; 4017480093f4SDimitry Andric if (GetRunArguments(args)) 4018480093f4SDimitry Andric m_launch_info.GetArguments() = args; 40190b57cec5SDimitry Andric } 40200b57cec5SDimitry Andric 4021480093f4SDimitry Andric void TargetProperties::EnvVarsValueChangedCallback() { 40225ffd83dbSDimitry Andric m_launch_info.GetEnvironment() = ComputeEnvironment(); 40230b57cec5SDimitry Andric } 40240b57cec5SDimitry Andric 4025480093f4SDimitry Andric void TargetProperties::InputPathValueChangedCallback() { 4026480093f4SDimitry Andric m_launch_info.AppendOpenFileAction(STDIN_FILENO, GetStandardInputPath(), true, 4027480093f4SDimitry Andric false); 40280b57cec5SDimitry Andric } 40290b57cec5SDimitry Andric 4030480093f4SDimitry Andric void TargetProperties::OutputPathValueChangedCallback() { 4031480093f4SDimitry Andric m_launch_info.AppendOpenFileAction(STDOUT_FILENO, GetStandardOutputPath(), 4032480093f4SDimitry Andric false, true); 40330b57cec5SDimitry Andric } 40340b57cec5SDimitry Andric 4035480093f4SDimitry Andric void TargetProperties::ErrorPathValueChangedCallback() { 4036480093f4SDimitry Andric m_launch_info.AppendOpenFileAction(STDERR_FILENO, GetStandardErrorPath(), 4037480093f4SDimitry Andric false, true); 40380b57cec5SDimitry Andric } 40390b57cec5SDimitry Andric 4040480093f4SDimitry Andric void TargetProperties::DetachOnErrorValueChangedCallback() { 4041480093f4SDimitry Andric if (GetDetachOnError()) 4042480093f4SDimitry Andric m_launch_info.GetFlags().Set(lldb::eLaunchFlagDetachOnError); 40430b57cec5SDimitry Andric else 4044480093f4SDimitry Andric m_launch_info.GetFlags().Clear(lldb::eLaunchFlagDetachOnError); 40450b57cec5SDimitry Andric } 40460b57cec5SDimitry Andric 4047480093f4SDimitry Andric void TargetProperties::DisableASLRValueChangedCallback() { 4048480093f4SDimitry Andric if (GetDisableASLR()) 4049480093f4SDimitry Andric m_launch_info.GetFlags().Set(lldb::eLaunchFlagDisableASLR); 40500b57cec5SDimitry Andric else 4051480093f4SDimitry Andric m_launch_info.GetFlags().Clear(lldb::eLaunchFlagDisableASLR); 40520b57cec5SDimitry Andric } 40530b57cec5SDimitry Andric 4054480093f4SDimitry Andric void TargetProperties::DisableSTDIOValueChangedCallback() { 4055480093f4SDimitry Andric if (GetDisableSTDIO()) 4056480093f4SDimitry Andric m_launch_info.GetFlags().Set(lldb::eLaunchFlagDisableSTDIO); 40570b57cec5SDimitry Andric else 4058480093f4SDimitry Andric m_launch_info.GetFlags().Clear(lldb::eLaunchFlagDisableSTDIO); 40590b57cec5SDimitry Andric } 40600b57cec5SDimitry Andric 40610b57cec5SDimitry Andric // Target::TargetEventData 40620b57cec5SDimitry Andric 40630b57cec5SDimitry Andric Target::TargetEventData::TargetEventData(const lldb::TargetSP &target_sp) 40640b57cec5SDimitry Andric : EventData(), m_target_sp(target_sp), m_module_list() {} 40650b57cec5SDimitry Andric 40660b57cec5SDimitry Andric Target::TargetEventData::TargetEventData(const lldb::TargetSP &target_sp, 40670b57cec5SDimitry Andric const ModuleList &module_list) 40680b57cec5SDimitry Andric : EventData(), m_target_sp(target_sp), m_module_list(module_list) {} 40690b57cec5SDimitry Andric 40700b57cec5SDimitry Andric Target::TargetEventData::~TargetEventData() = default; 40710b57cec5SDimitry Andric 40720b57cec5SDimitry Andric ConstString Target::TargetEventData::GetFlavorString() { 40730b57cec5SDimitry Andric static ConstString g_flavor("Target::TargetEventData"); 40740b57cec5SDimitry Andric return g_flavor; 40750b57cec5SDimitry Andric } 40760b57cec5SDimitry Andric 40770b57cec5SDimitry Andric void Target::TargetEventData::Dump(Stream *s) const { 40780b57cec5SDimitry Andric for (size_t i = 0; i < m_module_list.GetSize(); ++i) { 40790b57cec5SDimitry Andric if (i != 0) 40800b57cec5SDimitry Andric *s << ", "; 40810b57cec5SDimitry Andric m_module_list.GetModuleAtIndex(i)->GetDescription( 4082480093f4SDimitry Andric s->AsRawOstream(), lldb::eDescriptionLevelBrief); 40830b57cec5SDimitry Andric } 40840b57cec5SDimitry Andric } 40850b57cec5SDimitry Andric 40860b57cec5SDimitry Andric const Target::TargetEventData * 40870b57cec5SDimitry Andric Target::TargetEventData::GetEventDataFromEvent(const Event *event_ptr) { 40880b57cec5SDimitry Andric if (event_ptr) { 40890b57cec5SDimitry Andric const EventData *event_data = event_ptr->GetData(); 40900b57cec5SDimitry Andric if (event_data && 40910b57cec5SDimitry Andric event_data->GetFlavor() == TargetEventData::GetFlavorString()) 40920b57cec5SDimitry Andric return static_cast<const TargetEventData *>(event_ptr->GetData()); 40930b57cec5SDimitry Andric } 40940b57cec5SDimitry Andric return nullptr; 40950b57cec5SDimitry Andric } 40960b57cec5SDimitry Andric 40970b57cec5SDimitry Andric TargetSP Target::TargetEventData::GetTargetFromEvent(const Event *event_ptr) { 40980b57cec5SDimitry Andric TargetSP target_sp; 40990b57cec5SDimitry Andric const TargetEventData *event_data = GetEventDataFromEvent(event_ptr); 41000b57cec5SDimitry Andric if (event_data) 41010b57cec5SDimitry Andric target_sp = event_data->m_target_sp; 41020b57cec5SDimitry Andric return target_sp; 41030b57cec5SDimitry Andric } 41040b57cec5SDimitry Andric 41050b57cec5SDimitry Andric ModuleList 41060b57cec5SDimitry Andric Target::TargetEventData::GetModuleListFromEvent(const Event *event_ptr) { 41070b57cec5SDimitry Andric ModuleList module_list; 41080b57cec5SDimitry Andric const TargetEventData *event_data = GetEventDataFromEvent(event_ptr); 41090b57cec5SDimitry Andric if (event_data) 41100b57cec5SDimitry Andric module_list = event_data->m_module_list; 41110b57cec5SDimitry Andric return module_list; 41120b57cec5SDimitry Andric } 41139dba64beSDimitry Andric 41149dba64beSDimitry Andric std::recursive_mutex &Target::GetAPIMutex() { 41159dba64beSDimitry Andric if (GetProcessSP() && GetProcessSP()->CurrentThreadIsPrivateStateThread()) 41169dba64beSDimitry Andric return m_private_mutex; 41179dba64beSDimitry Andric else 41189dba64beSDimitry Andric return m_mutex; 41199dba64beSDimitry Andric } 4120