Path: blob/main/contrib/llvm-project/lldb/source/Target/Target.cpp
39587 views
//===-- Target.cpp --------------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "lldb/Target/Target.h"9#include "lldb/Breakpoint/BreakpointIDList.h"10#include "lldb/Breakpoint/BreakpointPrecondition.h"11#include "lldb/Breakpoint/BreakpointResolver.h"12#include "lldb/Breakpoint/BreakpointResolverAddress.h"13#include "lldb/Breakpoint/BreakpointResolverFileLine.h"14#include "lldb/Breakpoint/BreakpointResolverFileRegex.h"15#include "lldb/Breakpoint/BreakpointResolverName.h"16#include "lldb/Breakpoint/BreakpointResolverScripted.h"17#include "lldb/Breakpoint/Watchpoint.h"18#include "lldb/Core/Debugger.h"19#include "lldb/Core/Module.h"20#include "lldb/Core/ModuleSpec.h"21#include "lldb/Core/PluginManager.h"22#include "lldb/Core/SearchFilter.h"23#include "lldb/Core/Section.h"24#include "lldb/Core/SourceManager.h"25#include "lldb/Core/StructuredDataImpl.h"26#include "lldb/Core/ValueObject.h"27#include "lldb/Core/ValueObjectConstResult.h"28#include "lldb/Expression/DiagnosticManager.h"29#include "lldb/Expression/ExpressionVariable.h"30#include "lldb/Expression/REPL.h"31#include "lldb/Expression/UserExpression.h"32#include "lldb/Expression/UtilityFunction.h"33#include "lldb/Host/Host.h"34#include "lldb/Host/PosixApi.h"35#include "lldb/Host/StreamFile.h"36#include "lldb/Interpreter/CommandInterpreter.h"37#include "lldb/Interpreter/CommandReturnObject.h"38#include "lldb/Interpreter/OptionGroupWatchpoint.h"39#include "lldb/Interpreter/OptionValues.h"40#include "lldb/Interpreter/Property.h"41#include "lldb/Symbol/Function.h"42#include "lldb/Symbol/ObjectFile.h"43#include "lldb/Symbol/Symbol.h"44#include "lldb/Target/ABI.h"45#include "lldb/Target/ExecutionContext.h"46#include "lldb/Target/Language.h"47#include "lldb/Target/LanguageRuntime.h"48#include "lldb/Target/Process.h"49#include "lldb/Target/RegisterTypeBuilder.h"50#include "lldb/Target/SectionLoadList.h"51#include "lldb/Target/StackFrame.h"52#include "lldb/Target/StackFrameRecognizer.h"53#include "lldb/Target/SystemRuntime.h"54#include "lldb/Target/Thread.h"55#include "lldb/Target/ThreadSpec.h"56#include "lldb/Target/UnixSignals.h"57#include "lldb/Utility/Event.h"58#include "lldb/Utility/FileSpec.h"59#include "lldb/Utility/LLDBAssert.h"60#include "lldb/Utility/LLDBLog.h"61#include "lldb/Utility/Log.h"62#include "lldb/Utility/State.h"63#include "lldb/Utility/StreamString.h"64#include "lldb/Utility/Timer.h"6566#include "llvm/ADT/ScopeExit.h"67#include "llvm/ADT/SetVector.h"6869#include <memory>70#include <mutex>71#include <optional>72#include <sstream>7374using namespace lldb;75using namespace lldb_private;7677constexpr std::chrono::milliseconds EvaluateExpressionOptions::default_timeout;7879Target::Arch::Arch(const ArchSpec &spec)80: m_spec(spec),81m_plugin_up(PluginManager::CreateArchitectureInstance(spec)) {}8283const Target::Arch &Target::Arch::operator=(const ArchSpec &spec) {84m_spec = spec;85m_plugin_up = PluginManager::CreateArchitectureInstance(spec);86return *this;87}8889llvm::StringRef Target::GetStaticBroadcasterClass() {90static constexpr llvm::StringLiteral class_name("lldb.target");91return class_name;92}9394Target::Target(Debugger &debugger, const ArchSpec &target_arch,95const lldb::PlatformSP &platform_sp, bool is_dummy_target)96: TargetProperties(this),97Broadcaster(debugger.GetBroadcasterManager(),98Target::GetStaticBroadcasterClass().str()),99ExecutionContextScope(), m_debugger(debugger), m_platform_sp(platform_sp),100m_mutex(), m_arch(target_arch), m_images(this), m_section_load_history(),101m_breakpoint_list(false), m_internal_breakpoint_list(true),102m_watchpoint_list(), m_process_sp(), m_search_filter_sp(),103m_image_search_paths(ImageSearchPathsChanged, this),104m_source_manager_up(), m_stop_hooks(), m_stop_hook_next_id(0),105m_latest_stop_hook_id(0), m_valid(true), m_suppress_stop_hooks(false),106m_is_dummy_target(is_dummy_target),107m_frame_recognizer_manager_up(108std::make_unique<StackFrameRecognizerManager>()) {109SetEventName(eBroadcastBitBreakpointChanged, "breakpoint-changed");110SetEventName(eBroadcastBitModulesLoaded, "modules-loaded");111SetEventName(eBroadcastBitModulesUnloaded, "modules-unloaded");112SetEventName(eBroadcastBitWatchpointChanged, "watchpoint-changed");113SetEventName(eBroadcastBitSymbolsLoaded, "symbols-loaded");114115CheckInWithManager();116117LLDB_LOG(GetLog(LLDBLog::Object), "{0} Target::Target()",118static_cast<void *>(this));119if (target_arch.IsValid()) {120LLDB_LOG(GetLog(LLDBLog::Target),121"Target::Target created with architecture {0} ({1})",122target_arch.GetArchitectureName(),123target_arch.GetTriple().getTriple().c_str());124}125126UpdateLaunchInfoFromProperties();127}128129Target::~Target() {130Log *log = GetLog(LLDBLog::Object);131LLDB_LOG(log, "{0} Target::~Target()", static_cast<void *>(this));132DeleteCurrentProcess();133}134135void Target::PrimeFromDummyTarget(Target &target) {136m_stop_hooks = target.m_stop_hooks;137138for (const auto &breakpoint_sp : target.m_breakpoint_list.Breakpoints()) {139if (breakpoint_sp->IsInternal())140continue;141142BreakpointSP new_bp(143Breakpoint::CopyFromBreakpoint(shared_from_this(), *breakpoint_sp));144AddBreakpoint(std::move(new_bp), false);145}146147for (const auto &bp_name_entry : target.m_breakpoint_names) {148AddBreakpointName(std::make_unique<BreakpointName>(*bp_name_entry.second));149}150151m_frame_recognizer_manager_up = std::make_unique<StackFrameRecognizerManager>(152*target.m_frame_recognizer_manager_up);153154m_dummy_signals = target.m_dummy_signals;155}156157void Target::Dump(Stream *s, lldb::DescriptionLevel description_level) {158// s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);159if (description_level != lldb::eDescriptionLevelBrief) {160s->Indent();161s->PutCString("Target\n");162s->IndentMore();163m_images.Dump(s);164m_breakpoint_list.Dump(s);165m_internal_breakpoint_list.Dump(s);166s->IndentLess();167} else {168Module *exe_module = GetExecutableModulePointer();169if (exe_module)170s->PutCString(exe_module->GetFileSpec().GetFilename().GetCString());171else172s->PutCString("No executable module.");173}174}175176void Target::CleanupProcess() {177// Do any cleanup of the target we need to do between process instances.178// NB It is better to do this before destroying the process in case the179// clean up needs some help from the process.180m_breakpoint_list.ClearAllBreakpointSites();181m_internal_breakpoint_list.ClearAllBreakpointSites();182ResetBreakpointHitCounts();183// Disable watchpoints just on the debugger side.184std::unique_lock<std::recursive_mutex> lock;185this->GetWatchpointList().GetListMutex(lock);186DisableAllWatchpoints(false);187ClearAllWatchpointHitCounts();188ClearAllWatchpointHistoricValues();189m_latest_stop_hook_id = 0;190}191192void Target::DeleteCurrentProcess() {193if (m_process_sp) {194// We dispose any active tracing sessions on the current process195m_trace_sp.reset();196m_section_load_history.Clear();197if (m_process_sp->IsAlive())198m_process_sp->Destroy(false);199200m_process_sp->Finalize(false /* not destructing */);201202CleanupProcess();203204m_process_sp.reset();205}206}207208const lldb::ProcessSP &Target::CreateProcess(ListenerSP listener_sp,209llvm::StringRef plugin_name,210const FileSpec *crash_file,211bool can_connect) {212if (!listener_sp)213listener_sp = GetDebugger().GetListener();214DeleteCurrentProcess();215m_process_sp = Process::FindPlugin(shared_from_this(), plugin_name,216listener_sp, crash_file, can_connect);217return m_process_sp;218}219220const lldb::ProcessSP &Target::GetProcessSP() const { return m_process_sp; }221222lldb::REPLSP Target::GetREPL(Status &err, lldb::LanguageType language,223const char *repl_options, bool can_create) {224if (language == eLanguageTypeUnknown)225language = m_debugger.GetREPLLanguage();226227if (language == eLanguageTypeUnknown) {228LanguageSet repl_languages = Language::GetLanguagesSupportingREPLs();229230if (auto single_lang = repl_languages.GetSingularLanguage()) {231language = *single_lang;232} else if (repl_languages.Empty()) {233err.SetErrorString(234"LLDB isn't configured with REPL support for any languages.");235return REPLSP();236} else {237err.SetErrorString(238"Multiple possible REPL languages. Please specify a language.");239return REPLSP();240}241}242243REPLMap::iterator pos = m_repl_map.find(language);244245if (pos != m_repl_map.end()) {246return pos->second;247}248249if (!can_create) {250err.SetErrorStringWithFormat(251"Couldn't find an existing REPL for %s, and can't create a new one",252Language::GetNameForLanguageType(language));253return lldb::REPLSP();254}255256Debugger *const debugger = nullptr;257lldb::REPLSP ret = REPL::Create(err, language, debugger, this, repl_options);258259if (ret) {260m_repl_map[language] = ret;261return m_repl_map[language];262}263264if (err.Success()) {265err.SetErrorStringWithFormat("Couldn't create a REPL for %s",266Language::GetNameForLanguageType(language));267}268269return lldb::REPLSP();270}271272void Target::SetREPL(lldb::LanguageType language, lldb::REPLSP repl_sp) {273lldbassert(!m_repl_map.count(language));274275m_repl_map[language] = repl_sp;276}277278void Target::Destroy() {279std::lock_guard<std::recursive_mutex> guard(m_mutex);280m_valid = false;281DeleteCurrentProcess();282m_platform_sp.reset();283m_arch = ArchSpec();284ClearModules(true);285m_section_load_history.Clear();286const bool notify = false;287m_breakpoint_list.RemoveAll(notify);288m_internal_breakpoint_list.RemoveAll(notify);289m_last_created_breakpoint.reset();290m_watchpoint_list.RemoveAll(notify);291m_last_created_watchpoint.reset();292m_search_filter_sp.reset();293m_image_search_paths.Clear(notify);294m_stop_hooks.clear();295m_stop_hook_next_id = 0;296m_suppress_stop_hooks = false;297m_repl_map.clear();298Args signal_args;299ClearDummySignals(signal_args);300}301302llvm::StringRef Target::GetABIName() const {303lldb::ABISP abi_sp;304if (m_process_sp)305abi_sp = m_process_sp->GetABI();306if (!abi_sp)307abi_sp = ABI::FindPlugin(ProcessSP(), GetArchitecture());308if (abi_sp)309return abi_sp->GetPluginName();310return {};311}312313BreakpointList &Target::GetBreakpointList(bool internal) {314if (internal)315return m_internal_breakpoint_list;316else317return m_breakpoint_list;318}319320const BreakpointList &Target::GetBreakpointList(bool internal) const {321if (internal)322return m_internal_breakpoint_list;323else324return m_breakpoint_list;325}326327BreakpointSP Target::GetBreakpointByID(break_id_t break_id) {328BreakpointSP bp_sp;329330if (LLDB_BREAK_ID_IS_INTERNAL(break_id))331bp_sp = m_internal_breakpoint_list.FindBreakpointByID(break_id);332else333bp_sp = m_breakpoint_list.FindBreakpointByID(break_id);334335return bp_sp;336}337338lldb::BreakpointSP339lldb_private::Target::CreateBreakpointAtUserEntry(Status &error) {340ModuleSP main_module_sp = GetExecutableModule();341FileSpecList shared_lib_filter;342shared_lib_filter.Append(main_module_sp->GetFileSpec());343llvm::SetVector<std::string, std::vector<std::string>,344std::unordered_set<std::string>>345entryPointNamesSet;346for (LanguageType lang_type : Language::GetSupportedLanguages()) {347Language *lang = Language::FindPlugin(lang_type);348if (!lang) {349error.SetErrorString("Language not found\n");350return lldb::BreakpointSP();351}352std::string entryPointName = lang->GetUserEntryPointName().str();353if (!entryPointName.empty())354entryPointNamesSet.insert(entryPointName);355}356if (entryPointNamesSet.empty()) {357error.SetErrorString("No entry point name found\n");358return lldb::BreakpointSP();359}360BreakpointSP bp_sp = CreateBreakpoint(361&shared_lib_filter,362/*containingSourceFiles=*/nullptr, entryPointNamesSet.takeVector(),363/*func_name_type_mask=*/eFunctionNameTypeFull,364/*language=*/eLanguageTypeUnknown,365/*offset=*/0,366/*skip_prologue=*/eLazyBoolNo,367/*internal=*/false,368/*hardware=*/false);369if (!bp_sp) {370error.SetErrorString("Breakpoint creation failed.\n");371return lldb::BreakpointSP();372}373bp_sp->SetOneShot(true);374return bp_sp;375}376377BreakpointSP Target::CreateSourceRegexBreakpoint(378const FileSpecList *containingModules,379const FileSpecList *source_file_spec_list,380const std::unordered_set<std::string> &function_names,381RegularExpression source_regex, bool internal, bool hardware,382LazyBool move_to_nearest_code) {383SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList(384containingModules, source_file_spec_list));385if (move_to_nearest_code == eLazyBoolCalculate)386move_to_nearest_code = GetMoveToNearestCode() ? eLazyBoolYes : eLazyBoolNo;387BreakpointResolverSP resolver_sp(new BreakpointResolverFileRegex(388nullptr, std::move(source_regex), function_names,389!static_cast<bool>(move_to_nearest_code)));390391return CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true);392}393394BreakpointSP Target::CreateBreakpoint(const FileSpecList *containingModules,395const FileSpec &file, uint32_t line_no,396uint32_t column, lldb::addr_t offset,397LazyBool check_inlines,398LazyBool skip_prologue, bool internal,399bool hardware,400LazyBool move_to_nearest_code) {401FileSpec remapped_file;402std::optional<llvm::StringRef> removed_prefix_opt =403GetSourcePathMap().ReverseRemapPath(file, remapped_file);404if (!removed_prefix_opt)405remapped_file = file;406407if (check_inlines == eLazyBoolCalculate) {408const InlineStrategy inline_strategy = GetInlineStrategy();409switch (inline_strategy) {410case eInlineBreakpointsNever:411check_inlines = eLazyBoolNo;412break;413414case eInlineBreakpointsHeaders:415if (remapped_file.IsSourceImplementationFile())416check_inlines = eLazyBoolNo;417else418check_inlines = eLazyBoolYes;419break;420421case eInlineBreakpointsAlways:422check_inlines = eLazyBoolYes;423break;424}425}426SearchFilterSP filter_sp;427if (check_inlines == eLazyBoolNo) {428// Not checking for inlines, we are looking only for matching compile units429FileSpecList compile_unit_list;430compile_unit_list.Append(remapped_file);431filter_sp = GetSearchFilterForModuleAndCUList(containingModules,432&compile_unit_list);433} else {434filter_sp = GetSearchFilterForModuleList(containingModules);435}436if (skip_prologue == eLazyBoolCalculate)437skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;438if (move_to_nearest_code == eLazyBoolCalculate)439move_to_nearest_code = GetMoveToNearestCode() ? eLazyBoolYes : eLazyBoolNo;440441SourceLocationSpec location_spec(remapped_file, line_no, column,442check_inlines,443!static_cast<bool>(move_to_nearest_code));444if (!location_spec)445return nullptr;446447BreakpointResolverSP resolver_sp(new BreakpointResolverFileLine(448nullptr, offset, skip_prologue, location_spec, removed_prefix_opt));449return CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true);450}451452BreakpointSP Target::CreateBreakpoint(lldb::addr_t addr, bool internal,453bool hardware) {454Address so_addr;455456// Check for any reason we want to move this breakpoint to other address.457addr = GetBreakableLoadAddress(addr);458459// Attempt to resolve our load address if possible, though it is ok if it460// doesn't resolve to section/offset.461462// Try and resolve as a load address if possible463GetSectionLoadList().ResolveLoadAddress(addr, so_addr);464if (!so_addr.IsValid()) {465// The address didn't resolve, so just set this as an absolute address466so_addr.SetOffset(addr);467}468BreakpointSP bp_sp(CreateBreakpoint(so_addr, internal, hardware));469return bp_sp;470}471472BreakpointSP Target::CreateBreakpoint(const Address &addr, bool internal,473bool hardware) {474SearchFilterSP filter_sp(475new SearchFilterForUnconstrainedSearches(shared_from_this()));476BreakpointResolverSP resolver_sp(477new BreakpointResolverAddress(nullptr, addr));478return CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, false);479}480481lldb::BreakpointSP482Target::CreateAddressInModuleBreakpoint(lldb::addr_t file_addr, bool internal,483const FileSpec &file_spec,484bool request_hardware) {485SearchFilterSP filter_sp(486new SearchFilterForUnconstrainedSearches(shared_from_this()));487BreakpointResolverSP resolver_sp(new BreakpointResolverAddress(488nullptr, file_addr, file_spec));489return CreateBreakpoint(filter_sp, resolver_sp, internal, request_hardware,490false);491}492493BreakpointSP Target::CreateBreakpoint(494const FileSpecList *containingModules,495const FileSpecList *containingSourceFiles, const char *func_name,496FunctionNameType func_name_type_mask, LanguageType language,497lldb::addr_t offset, LazyBool skip_prologue, bool internal, bool hardware) {498BreakpointSP bp_sp;499if (func_name) {500SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList(501containingModules, containingSourceFiles));502503if (skip_prologue == eLazyBoolCalculate)504skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;505if (language == lldb::eLanguageTypeUnknown)506language = GetLanguage().AsLanguageType();507508BreakpointResolverSP resolver_sp(new BreakpointResolverName(509nullptr, func_name, func_name_type_mask, language, Breakpoint::Exact,510offset, skip_prologue));511bp_sp = CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true);512}513return bp_sp;514}515516lldb::BreakpointSP517Target::CreateBreakpoint(const FileSpecList *containingModules,518const FileSpecList *containingSourceFiles,519const std::vector<std::string> &func_names,520FunctionNameType func_name_type_mask,521LanguageType language, lldb::addr_t offset,522LazyBool skip_prologue, bool internal, bool hardware) {523BreakpointSP bp_sp;524size_t num_names = func_names.size();525if (num_names > 0) {526SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList(527containingModules, containingSourceFiles));528529if (skip_prologue == eLazyBoolCalculate)530skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;531if (language == lldb::eLanguageTypeUnknown)532language = GetLanguage().AsLanguageType();533534BreakpointResolverSP resolver_sp(535new BreakpointResolverName(nullptr, func_names, func_name_type_mask,536language, offset, skip_prologue));537bp_sp = CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true);538}539return bp_sp;540}541542BreakpointSP543Target::CreateBreakpoint(const FileSpecList *containingModules,544const FileSpecList *containingSourceFiles,545const char *func_names[], size_t num_names,546FunctionNameType func_name_type_mask,547LanguageType language, lldb::addr_t offset,548LazyBool skip_prologue, bool internal, bool hardware) {549BreakpointSP bp_sp;550if (num_names > 0) {551SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList(552containingModules, containingSourceFiles));553554if (skip_prologue == eLazyBoolCalculate) {555if (offset == 0)556skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;557else558skip_prologue = eLazyBoolNo;559}560if (language == lldb::eLanguageTypeUnknown)561language = GetLanguage().AsLanguageType();562563BreakpointResolverSP resolver_sp(new BreakpointResolverName(564nullptr, func_names, num_names, func_name_type_mask, language, offset,565skip_prologue));566resolver_sp->SetOffset(offset);567bp_sp = CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true);568}569return bp_sp;570}571572SearchFilterSP573Target::GetSearchFilterForModule(const FileSpec *containingModule) {574SearchFilterSP filter_sp;575if (containingModule != nullptr) {576// TODO: We should look into sharing module based search filters577// across many breakpoints like we do for the simple target based one578filter_sp = std::make_shared<SearchFilterByModule>(shared_from_this(),579*containingModule);580} else {581if (!m_search_filter_sp)582m_search_filter_sp =583std::make_shared<SearchFilterForUnconstrainedSearches>(584shared_from_this());585filter_sp = m_search_filter_sp;586}587return filter_sp;588}589590SearchFilterSP591Target::GetSearchFilterForModuleList(const FileSpecList *containingModules) {592SearchFilterSP filter_sp;593if (containingModules && containingModules->GetSize() != 0) {594// TODO: We should look into sharing module based search filters595// across many breakpoints like we do for the simple target based one596filter_sp = std::make_shared<SearchFilterByModuleList>(shared_from_this(),597*containingModules);598} else {599if (!m_search_filter_sp)600m_search_filter_sp =601std::make_shared<SearchFilterForUnconstrainedSearches>(602shared_from_this());603filter_sp = m_search_filter_sp;604}605return filter_sp;606}607608SearchFilterSP Target::GetSearchFilterForModuleAndCUList(609const FileSpecList *containingModules,610const FileSpecList *containingSourceFiles) {611if (containingSourceFiles == nullptr || containingSourceFiles->GetSize() == 0)612return GetSearchFilterForModuleList(containingModules);613614SearchFilterSP filter_sp;615if (containingModules == nullptr) {616// We could make a special "CU List only SearchFilter". Better yet was if617// these could be composable, but that will take a little reworking.618619filter_sp = std::make_shared<SearchFilterByModuleListAndCU>(620shared_from_this(), FileSpecList(), *containingSourceFiles);621} else {622filter_sp = std::make_shared<SearchFilterByModuleListAndCU>(623shared_from_this(), *containingModules, *containingSourceFiles);624}625return filter_sp;626}627628BreakpointSP Target::CreateFuncRegexBreakpoint(629const FileSpecList *containingModules,630const FileSpecList *containingSourceFiles, RegularExpression func_regex,631lldb::LanguageType requested_language, LazyBool skip_prologue,632bool internal, bool hardware) {633SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList(634containingModules, containingSourceFiles));635bool skip = (skip_prologue == eLazyBoolCalculate)636? GetSkipPrologue()637: static_cast<bool>(skip_prologue);638BreakpointResolverSP resolver_sp(new BreakpointResolverName(639nullptr, std::move(func_regex), requested_language, 0, skip));640641return CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true);642}643644lldb::BreakpointSP645Target::CreateExceptionBreakpoint(enum lldb::LanguageType language,646bool catch_bp, bool throw_bp, bool internal,647Args *additional_args, Status *error) {648BreakpointSP exc_bkpt_sp = LanguageRuntime::CreateExceptionBreakpoint(649*this, language, catch_bp, throw_bp, internal);650if (exc_bkpt_sp && additional_args) {651BreakpointPreconditionSP precondition_sp = exc_bkpt_sp->GetPrecondition();652if (precondition_sp && additional_args) {653if (error)654*error = precondition_sp->ConfigurePrecondition(*additional_args);655else656precondition_sp->ConfigurePrecondition(*additional_args);657}658}659return exc_bkpt_sp;660}661662lldb::BreakpointSP Target::CreateScriptedBreakpoint(663const llvm::StringRef class_name, const FileSpecList *containingModules,664const FileSpecList *containingSourceFiles, bool internal,665bool request_hardware, StructuredData::ObjectSP extra_args_sp,666Status *creation_error) {667SearchFilterSP filter_sp;668669lldb::SearchDepth depth = lldb::eSearchDepthTarget;670bool has_files =671containingSourceFiles && containingSourceFiles->GetSize() > 0;672bool has_modules = containingModules && containingModules->GetSize() > 0;673674if (has_files && has_modules) {675filter_sp = GetSearchFilterForModuleAndCUList(containingModules,676containingSourceFiles);677} else if (has_files) {678filter_sp =679GetSearchFilterForModuleAndCUList(nullptr, containingSourceFiles);680} else if (has_modules) {681filter_sp = GetSearchFilterForModuleList(containingModules);682} else {683filter_sp = std::make_shared<SearchFilterForUnconstrainedSearches>(684shared_from_this());685}686687BreakpointResolverSP resolver_sp(new BreakpointResolverScripted(688nullptr, class_name, depth, StructuredDataImpl(extra_args_sp)));689return CreateBreakpoint(filter_sp, resolver_sp, internal, false, true);690}691692BreakpointSP Target::CreateBreakpoint(SearchFilterSP &filter_sp,693BreakpointResolverSP &resolver_sp,694bool internal, bool request_hardware,695bool resolve_indirect_symbols) {696BreakpointSP bp_sp;697if (filter_sp && resolver_sp) {698const bool hardware = request_hardware || GetRequireHardwareBreakpoints();699bp_sp.reset(new Breakpoint(*this, filter_sp, resolver_sp, hardware,700resolve_indirect_symbols));701resolver_sp->SetBreakpoint(bp_sp);702AddBreakpoint(bp_sp, internal);703}704return bp_sp;705}706707void Target::AddBreakpoint(lldb::BreakpointSP bp_sp, bool internal) {708if (!bp_sp)709return;710if (internal)711m_internal_breakpoint_list.Add(bp_sp, false);712else713m_breakpoint_list.Add(bp_sp, true);714715Log *log = GetLog(LLDBLog::Breakpoints);716if (log) {717StreamString s;718bp_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);719LLDB_LOGF(log, "Target::%s (internal = %s) => break_id = %s\n",720__FUNCTION__, bp_sp->IsInternal() ? "yes" : "no", s.GetData());721}722723bp_sp->ResolveBreakpoint();724725if (!internal) {726m_last_created_breakpoint = bp_sp;727}728}729730void Target::AddNameToBreakpoint(BreakpointID &id, llvm::StringRef name,731Status &error) {732BreakpointSP bp_sp =733m_breakpoint_list.FindBreakpointByID(id.GetBreakpointID());734if (!bp_sp) {735StreamString s;736id.GetDescription(&s, eDescriptionLevelBrief);737error.SetErrorStringWithFormat("Could not find breakpoint %s", s.GetData());738return;739}740AddNameToBreakpoint(bp_sp, name, error);741}742743void Target::AddNameToBreakpoint(BreakpointSP &bp_sp, llvm::StringRef name,744Status &error) {745if (!bp_sp)746return;747748BreakpointName *bp_name = FindBreakpointName(ConstString(name), true, error);749if (!bp_name)750return;751752bp_name->ConfigureBreakpoint(bp_sp);753bp_sp->AddName(name);754}755756void Target::AddBreakpointName(std::unique_ptr<BreakpointName> bp_name) {757m_breakpoint_names.insert(758std::make_pair(bp_name->GetName(), std::move(bp_name)));759}760761BreakpointName *Target::FindBreakpointName(ConstString name, bool can_create,762Status &error) {763BreakpointID::StringIsBreakpointName(name.GetStringRef(), error);764if (!error.Success())765return nullptr;766767BreakpointNameList::iterator iter = m_breakpoint_names.find(name);768if (iter != m_breakpoint_names.end()) {769return iter->second.get();770}771772if (!can_create) {773error.SetErrorStringWithFormat("Breakpoint name \"%s\" doesn't exist and "774"can_create is false.",775name.AsCString());776return nullptr;777}778779return m_breakpoint_names780.insert(std::make_pair(name, std::make_unique<BreakpointName>(name)))781.first->second.get();782}783784void Target::DeleteBreakpointName(ConstString name) {785BreakpointNameList::iterator iter = m_breakpoint_names.find(name);786787if (iter != m_breakpoint_names.end()) {788const char *name_cstr = name.AsCString();789m_breakpoint_names.erase(iter);790for (auto bp_sp : m_breakpoint_list.Breakpoints())791bp_sp->RemoveName(name_cstr);792}793}794795void Target::RemoveNameFromBreakpoint(lldb::BreakpointSP &bp_sp,796ConstString name) {797bp_sp->RemoveName(name.AsCString());798}799800void Target::ConfigureBreakpointName(801BreakpointName &bp_name, const BreakpointOptions &new_options,802const BreakpointName::Permissions &new_permissions) {803bp_name.GetOptions().CopyOverSetOptions(new_options);804bp_name.GetPermissions().MergeInto(new_permissions);805ApplyNameToBreakpoints(bp_name);806}807808void Target::ApplyNameToBreakpoints(BreakpointName &bp_name) {809llvm::Expected<std::vector<BreakpointSP>> expected_vector =810m_breakpoint_list.FindBreakpointsByName(bp_name.GetName().AsCString());811812if (!expected_vector) {813LLDB_LOG(GetLog(LLDBLog::Breakpoints), "invalid breakpoint name: {}",814llvm::toString(expected_vector.takeError()));815return;816}817818for (auto bp_sp : *expected_vector)819bp_name.ConfigureBreakpoint(bp_sp);820}821822void Target::GetBreakpointNames(std::vector<std::string> &names) {823names.clear();824for (const auto& bp_name_entry : m_breakpoint_names) {825names.push_back(bp_name_entry.first.AsCString());826}827llvm::sort(names);828}829830bool Target::ProcessIsValid() {831return (m_process_sp && m_process_sp->IsAlive());832}833834static bool CheckIfWatchpointsSupported(Target *target, Status &error) {835std::optional<uint32_t> num_supported_hardware_watchpoints =836target->GetProcessSP()->GetWatchpointSlotCount();837838// If unable to determine the # of watchpoints available,839// assume they are supported.840if (!num_supported_hardware_watchpoints)841return true;842843if (*num_supported_hardware_watchpoints == 0) {844error.SetErrorStringWithFormat(845"Target supports (%u) hardware watchpoint slots.\n",846*num_supported_hardware_watchpoints);847return false;848}849return true;850}851852// See also Watchpoint::SetWatchpointType(uint32_t type) and the853// OptionGroupWatchpoint::WatchType enum type.854WatchpointSP Target::CreateWatchpoint(lldb::addr_t addr, size_t size,855const CompilerType *type, uint32_t kind,856Status &error) {857Log *log = GetLog(LLDBLog::Watchpoints);858LLDB_LOGF(log,859"Target::%s (addr = 0x%8.8" PRIx64 " size = %" PRIu64860" type = %u)\n",861__FUNCTION__, addr, (uint64_t)size, kind);862863WatchpointSP wp_sp;864if (!ProcessIsValid()) {865error.SetErrorString("process is not alive");866return wp_sp;867}868869if (addr == LLDB_INVALID_ADDRESS || size == 0) {870if (size == 0)871error.SetErrorString("cannot set a watchpoint with watch_size of 0");872else873error.SetErrorStringWithFormat("invalid watch address: %" PRIu64, addr);874return wp_sp;875}876877if (!LLDB_WATCH_TYPE_IS_VALID(kind)) {878error.SetErrorStringWithFormat("invalid watchpoint type: %d", kind);879}880881if (!CheckIfWatchpointsSupported(this, error))882return wp_sp;883884// Currently we only support one watchpoint per address, with total number of885// watchpoints limited by the hardware which the inferior is running on.886887// Grab the list mutex while doing operations.888const bool notify = false; // Don't notify about all the state changes we do889// on creating the watchpoint.890891// Mask off ignored bits from watchpoint address.892if (ABISP abi = m_process_sp->GetABI())893addr = abi->FixDataAddress(addr);894895// LWP_TODO this sequence is looking for an existing watchpoint896// at the exact same user-specified address, disables the new one897// if addr/size/type match. If type/size differ, disable old one.898// This isn't correct, we need both watchpoints to use a shared899// WatchpointResource in the target, and expand the WatchpointResource900// to handle the needs of both Watchpoints.901// Also, even if the addresses don't match, they may need to be902// supported by the same WatchpointResource, e.g. a watchpoint903// watching 1 byte at 0x102 and a watchpoint watching 1 byte at 0x103.904// They're in the same word and must be watched by a single hardware905// watchpoint register.906907std::unique_lock<std::recursive_mutex> lock;908this->GetWatchpointList().GetListMutex(lock);909WatchpointSP matched_sp = m_watchpoint_list.FindByAddress(addr);910if (matched_sp) {911size_t old_size = matched_sp->GetByteSize();912uint32_t old_type =913(matched_sp->WatchpointRead() ? LLDB_WATCH_TYPE_READ : 0) |914(matched_sp->WatchpointWrite() ? LLDB_WATCH_TYPE_WRITE : 0) |915(matched_sp->WatchpointModify() ? LLDB_WATCH_TYPE_MODIFY : 0);916// Return the existing watchpoint if both size and type match.917if (size == old_size && kind == old_type) {918wp_sp = matched_sp;919wp_sp->SetEnabled(false, notify);920} else {921// Nil the matched watchpoint; we will be creating a new one.922m_process_sp->DisableWatchpoint(matched_sp, notify);923m_watchpoint_list.Remove(matched_sp->GetID(), true);924}925}926927if (!wp_sp) {928wp_sp = std::make_shared<Watchpoint>(*this, addr, size, type);929wp_sp->SetWatchpointType(kind, notify);930m_watchpoint_list.Add(wp_sp, true);931}932933error = m_process_sp->EnableWatchpoint(wp_sp, notify);934LLDB_LOGF(log, "Target::%s (creation of watchpoint %s with id = %u)\n",935__FUNCTION__, error.Success() ? "succeeded" : "failed",936wp_sp->GetID());937938if (error.Fail()) {939// Enabling the watchpoint on the device side failed. Remove the said940// watchpoint from the list maintained by the target instance.941m_watchpoint_list.Remove(wp_sp->GetID(), true);942wp_sp.reset();943} else944m_last_created_watchpoint = wp_sp;945return wp_sp;946}947948void Target::RemoveAllowedBreakpoints() {949Log *log = GetLog(LLDBLog::Breakpoints);950LLDB_LOGF(log, "Target::%s \n", __FUNCTION__);951952m_breakpoint_list.RemoveAllowed(true);953954m_last_created_breakpoint.reset();955}956957void Target::RemoveAllBreakpoints(bool internal_also) {958Log *log = GetLog(LLDBLog::Breakpoints);959LLDB_LOGF(log, "Target::%s (internal_also = %s)\n", __FUNCTION__,960internal_also ? "yes" : "no");961962m_breakpoint_list.RemoveAll(true);963if (internal_also)964m_internal_breakpoint_list.RemoveAll(false);965966m_last_created_breakpoint.reset();967}968969void Target::DisableAllBreakpoints(bool internal_also) {970Log *log = GetLog(LLDBLog::Breakpoints);971LLDB_LOGF(log, "Target::%s (internal_also = %s)\n", __FUNCTION__,972internal_also ? "yes" : "no");973974m_breakpoint_list.SetEnabledAll(false);975if (internal_also)976m_internal_breakpoint_list.SetEnabledAll(false);977}978979void Target::DisableAllowedBreakpoints() {980Log *log = GetLog(LLDBLog::Breakpoints);981LLDB_LOGF(log, "Target::%s", __FUNCTION__);982983m_breakpoint_list.SetEnabledAllowed(false);984}985986void Target::EnableAllBreakpoints(bool internal_also) {987Log *log = GetLog(LLDBLog::Breakpoints);988LLDB_LOGF(log, "Target::%s (internal_also = %s)\n", __FUNCTION__,989internal_also ? "yes" : "no");990991m_breakpoint_list.SetEnabledAll(true);992if (internal_also)993m_internal_breakpoint_list.SetEnabledAll(true);994}995996void Target::EnableAllowedBreakpoints() {997Log *log = GetLog(LLDBLog::Breakpoints);998LLDB_LOGF(log, "Target::%s", __FUNCTION__);9991000m_breakpoint_list.SetEnabledAllowed(true);1001}10021003bool Target::RemoveBreakpointByID(break_id_t break_id) {1004Log *log = GetLog(LLDBLog::Breakpoints);1005LLDB_LOGF(log, "Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__,1006break_id, LLDB_BREAK_ID_IS_INTERNAL(break_id) ? "yes" : "no");10071008if (DisableBreakpointByID(break_id)) {1009if (LLDB_BREAK_ID_IS_INTERNAL(break_id))1010m_internal_breakpoint_list.Remove(break_id, false);1011else {1012if (m_last_created_breakpoint) {1013if (m_last_created_breakpoint->GetID() == break_id)1014m_last_created_breakpoint.reset();1015}1016m_breakpoint_list.Remove(break_id, true);1017}1018return true;1019}1020return false;1021}10221023bool Target::DisableBreakpointByID(break_id_t break_id) {1024Log *log = GetLog(LLDBLog::Breakpoints);1025LLDB_LOGF(log, "Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__,1026break_id, LLDB_BREAK_ID_IS_INTERNAL(break_id) ? "yes" : "no");10271028BreakpointSP bp_sp;10291030if (LLDB_BREAK_ID_IS_INTERNAL(break_id))1031bp_sp = m_internal_breakpoint_list.FindBreakpointByID(break_id);1032else1033bp_sp = m_breakpoint_list.FindBreakpointByID(break_id);1034if (bp_sp) {1035bp_sp->SetEnabled(false);1036return true;1037}1038return false;1039}10401041bool Target::EnableBreakpointByID(break_id_t break_id) {1042Log *log = GetLog(LLDBLog::Breakpoints);1043LLDB_LOGF(log, "Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__,1044break_id, LLDB_BREAK_ID_IS_INTERNAL(break_id) ? "yes" : "no");10451046BreakpointSP bp_sp;10471048if (LLDB_BREAK_ID_IS_INTERNAL(break_id))1049bp_sp = m_internal_breakpoint_list.FindBreakpointByID(break_id);1050else1051bp_sp = m_breakpoint_list.FindBreakpointByID(break_id);10521053if (bp_sp) {1054bp_sp->SetEnabled(true);1055return true;1056}1057return false;1058}10591060void Target::ResetBreakpointHitCounts() {1061GetBreakpointList().ResetHitCounts();1062}10631064Status Target::SerializeBreakpointsToFile(const FileSpec &file,1065const BreakpointIDList &bp_ids,1066bool append) {1067Status error;10681069if (!file) {1070error.SetErrorString("Invalid FileSpec.");1071return error;1072}10731074std::string path(file.GetPath());1075StructuredData::ObjectSP input_data_sp;10761077StructuredData::ArraySP break_store_sp;1078StructuredData::Array *break_store_ptr = nullptr;10791080if (append) {1081input_data_sp = StructuredData::ParseJSONFromFile(file, error);1082if (error.Success()) {1083break_store_ptr = input_data_sp->GetAsArray();1084if (!break_store_ptr) {1085error.SetErrorStringWithFormat(1086"Tried to append to invalid input file %s", path.c_str());1087return error;1088}1089}1090}10911092if (!break_store_ptr) {1093break_store_sp = std::make_shared<StructuredData::Array>();1094break_store_ptr = break_store_sp.get();1095}10961097StreamFile out_file(path.c_str(),1098File::eOpenOptionTruncate | File::eOpenOptionWriteOnly |1099File::eOpenOptionCanCreate |1100File::eOpenOptionCloseOnExec,1101lldb::eFilePermissionsFileDefault);1102if (!out_file.GetFile().IsValid()) {1103error.SetErrorStringWithFormat("Unable to open output file: %s.",1104path.c_str());1105return error;1106}11071108std::unique_lock<std::recursive_mutex> lock;1109GetBreakpointList().GetListMutex(lock);11101111if (bp_ids.GetSize() == 0) {1112const BreakpointList &breakpoints = GetBreakpointList();11131114size_t num_breakpoints = breakpoints.GetSize();1115for (size_t i = 0; i < num_breakpoints; i++) {1116Breakpoint *bp = breakpoints.GetBreakpointAtIndex(i).get();1117StructuredData::ObjectSP bkpt_save_sp = bp->SerializeToStructuredData();1118// If a breakpoint can't serialize it, just ignore it for now:1119if (bkpt_save_sp)1120break_store_ptr->AddItem(bkpt_save_sp);1121}1122} else {11231124std::unordered_set<lldb::break_id_t> processed_bkpts;1125const size_t count = bp_ids.GetSize();1126for (size_t i = 0; i < count; ++i) {1127BreakpointID cur_bp_id = bp_ids.GetBreakpointIDAtIndex(i);1128lldb::break_id_t bp_id = cur_bp_id.GetBreakpointID();11291130if (bp_id != LLDB_INVALID_BREAK_ID) {1131// Only do each breakpoint once:1132std::pair<std::unordered_set<lldb::break_id_t>::iterator, bool>1133insert_result = processed_bkpts.insert(bp_id);1134if (!insert_result.second)1135continue;11361137Breakpoint *bp = GetBreakpointByID(bp_id).get();1138StructuredData::ObjectSP bkpt_save_sp = bp->SerializeToStructuredData();1139// If the user explicitly asked to serialize a breakpoint, and we1140// can't, then raise an error:1141if (!bkpt_save_sp) {1142error.SetErrorStringWithFormat("Unable to serialize breakpoint %d",1143bp_id);1144return error;1145}1146break_store_ptr->AddItem(bkpt_save_sp);1147}1148}1149}11501151break_store_ptr->Dump(out_file, false);1152out_file.PutChar('\n');1153return error;1154}11551156Status Target::CreateBreakpointsFromFile(const FileSpec &file,1157BreakpointIDList &new_bps) {1158std::vector<std::string> no_names;1159return CreateBreakpointsFromFile(file, no_names, new_bps);1160}11611162Status Target::CreateBreakpointsFromFile(const FileSpec &file,1163std::vector<std::string> &names,1164BreakpointIDList &new_bps) {1165std::unique_lock<std::recursive_mutex> lock;1166GetBreakpointList().GetListMutex(lock);11671168Status error;1169StructuredData::ObjectSP input_data_sp =1170StructuredData::ParseJSONFromFile(file, error);1171if (!error.Success()) {1172return error;1173} else if (!input_data_sp || !input_data_sp->IsValid()) {1174error.SetErrorStringWithFormat("Invalid JSON from input file: %s.",1175file.GetPath().c_str());1176return error;1177}11781179StructuredData::Array *bkpt_array = input_data_sp->GetAsArray();1180if (!bkpt_array) {1181error.SetErrorStringWithFormat(1182"Invalid breakpoint data from input file: %s.", file.GetPath().c_str());1183return error;1184}11851186size_t num_bkpts = bkpt_array->GetSize();1187size_t num_names = names.size();11881189for (size_t i = 0; i < num_bkpts; i++) {1190StructuredData::ObjectSP bkpt_object_sp = bkpt_array->GetItemAtIndex(i);1191// Peel off the breakpoint key, and feed the rest to the Breakpoint:1192StructuredData::Dictionary *bkpt_dict = bkpt_object_sp->GetAsDictionary();1193if (!bkpt_dict) {1194error.SetErrorStringWithFormat(1195"Invalid breakpoint data for element %zu from input file: %s.", i,1196file.GetPath().c_str());1197return error;1198}1199StructuredData::ObjectSP bkpt_data_sp =1200bkpt_dict->GetValueForKey(Breakpoint::GetSerializationKey());1201if (num_names &&1202!Breakpoint::SerializedBreakpointMatchesNames(bkpt_data_sp, names))1203continue;12041205BreakpointSP bkpt_sp = Breakpoint::CreateFromStructuredData(1206shared_from_this(), bkpt_data_sp, error);1207if (!error.Success()) {1208error.SetErrorStringWithFormat(1209"Error restoring breakpoint %zu from %s: %s.", i,1210file.GetPath().c_str(), error.AsCString());1211return error;1212}1213new_bps.AddBreakpointID(BreakpointID(bkpt_sp->GetID()));1214}1215return error;1216}12171218// The flag 'end_to_end', default to true, signifies that the operation is1219// performed end to end, for both the debugger and the debuggee.12201221// Assumption: Caller holds the list mutex lock for m_watchpoint_list for end1222// to end operations.1223bool Target::RemoveAllWatchpoints(bool end_to_end) {1224Log *log = GetLog(LLDBLog::Watchpoints);1225LLDB_LOGF(log, "Target::%s\n", __FUNCTION__);12261227if (!end_to_end) {1228m_watchpoint_list.RemoveAll(true);1229return true;1230}12311232// Otherwise, it's an end to end operation.12331234if (!ProcessIsValid())1235return false;12361237for (WatchpointSP wp_sp : m_watchpoint_list.Watchpoints()) {1238if (!wp_sp)1239return false;12401241Status rc = m_process_sp->DisableWatchpoint(wp_sp);1242if (rc.Fail())1243return false;1244}1245m_watchpoint_list.RemoveAll(true);1246m_last_created_watchpoint.reset();1247return true; // Success!1248}12491250// Assumption: Caller holds the list mutex lock for m_watchpoint_list for end1251// to end operations.1252bool Target::DisableAllWatchpoints(bool end_to_end) {1253Log *log = GetLog(LLDBLog::Watchpoints);1254LLDB_LOGF(log, "Target::%s\n", __FUNCTION__);12551256if (!end_to_end) {1257m_watchpoint_list.SetEnabledAll(false);1258return true;1259}12601261// Otherwise, it's an end to end operation.12621263if (!ProcessIsValid())1264return false;12651266for (WatchpointSP wp_sp : m_watchpoint_list.Watchpoints()) {1267if (!wp_sp)1268return false;12691270Status rc = m_process_sp->DisableWatchpoint(wp_sp);1271if (rc.Fail())1272return false;1273}1274return true; // Success!1275}12761277// Assumption: Caller holds the list mutex lock for m_watchpoint_list for end1278// to end operations.1279bool Target::EnableAllWatchpoints(bool end_to_end) {1280Log *log = GetLog(LLDBLog::Watchpoints);1281LLDB_LOGF(log, "Target::%s\n", __FUNCTION__);12821283if (!end_to_end) {1284m_watchpoint_list.SetEnabledAll(true);1285return true;1286}12871288// Otherwise, it's an end to end operation.12891290if (!ProcessIsValid())1291return false;12921293for (WatchpointSP wp_sp : m_watchpoint_list.Watchpoints()) {1294if (!wp_sp)1295return false;12961297Status rc = m_process_sp->EnableWatchpoint(wp_sp);1298if (rc.Fail())1299return false;1300}1301return true; // Success!1302}13031304// Assumption: Caller holds the list mutex lock for m_watchpoint_list.1305bool Target::ClearAllWatchpointHitCounts() {1306Log *log = GetLog(LLDBLog::Watchpoints);1307LLDB_LOGF(log, "Target::%s\n", __FUNCTION__);13081309for (WatchpointSP wp_sp : m_watchpoint_list.Watchpoints()) {1310if (!wp_sp)1311return false;13121313wp_sp->ResetHitCount();1314}1315return true; // Success!1316}13171318// Assumption: Caller holds the list mutex lock for m_watchpoint_list.1319bool Target::ClearAllWatchpointHistoricValues() {1320Log *log = GetLog(LLDBLog::Watchpoints);1321LLDB_LOGF(log, "Target::%s\n", __FUNCTION__);13221323for (WatchpointSP wp_sp : m_watchpoint_list.Watchpoints()) {1324if (!wp_sp)1325return false;13261327wp_sp->ResetHistoricValues();1328}1329return true; // Success!1330}13311332// Assumption: Caller holds the list mutex lock for m_watchpoint_list during1333// these operations.1334bool Target::IgnoreAllWatchpoints(uint32_t ignore_count) {1335Log *log = GetLog(LLDBLog::Watchpoints);1336LLDB_LOGF(log, "Target::%s\n", __FUNCTION__);13371338if (!ProcessIsValid())1339return false;13401341for (WatchpointSP wp_sp : m_watchpoint_list.Watchpoints()) {1342if (!wp_sp)1343return false;13441345wp_sp->SetIgnoreCount(ignore_count);1346}1347return true; // Success!1348}13491350// Assumption: Caller holds the list mutex lock for m_watchpoint_list.1351bool Target::DisableWatchpointByID(lldb::watch_id_t watch_id) {1352Log *log = GetLog(LLDBLog::Watchpoints);1353LLDB_LOGF(log, "Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);13541355if (!ProcessIsValid())1356return false;13571358WatchpointSP wp_sp = m_watchpoint_list.FindByID(watch_id);1359if (wp_sp) {1360Status rc = m_process_sp->DisableWatchpoint(wp_sp);1361if (rc.Success())1362return true;13631364// Else, fallthrough.1365}1366return false;1367}13681369// Assumption: Caller holds the list mutex lock for m_watchpoint_list.1370bool Target::EnableWatchpointByID(lldb::watch_id_t watch_id) {1371Log *log = GetLog(LLDBLog::Watchpoints);1372LLDB_LOGF(log, "Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);13731374if (!ProcessIsValid())1375return false;13761377WatchpointSP wp_sp = m_watchpoint_list.FindByID(watch_id);1378if (wp_sp) {1379Status rc = m_process_sp->EnableWatchpoint(wp_sp);1380if (rc.Success())1381return true;13821383// Else, fallthrough.1384}1385return false;1386}13871388// Assumption: Caller holds the list mutex lock for m_watchpoint_list.1389bool Target::RemoveWatchpointByID(lldb::watch_id_t watch_id) {1390Log *log = GetLog(LLDBLog::Watchpoints);1391LLDB_LOGF(log, "Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);13921393WatchpointSP watch_to_remove_sp = m_watchpoint_list.FindByID(watch_id);1394if (watch_to_remove_sp == m_last_created_watchpoint)1395m_last_created_watchpoint.reset();13961397if (DisableWatchpointByID(watch_id)) {1398m_watchpoint_list.Remove(watch_id, true);1399return true;1400}1401return false;1402}14031404// Assumption: Caller holds the list mutex lock for m_watchpoint_list.1405bool Target::IgnoreWatchpointByID(lldb::watch_id_t watch_id,1406uint32_t ignore_count) {1407Log *log = GetLog(LLDBLog::Watchpoints);1408LLDB_LOGF(log, "Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);14091410if (!ProcessIsValid())1411return false;14121413WatchpointSP wp_sp = m_watchpoint_list.FindByID(watch_id);1414if (wp_sp) {1415wp_sp->SetIgnoreCount(ignore_count);1416return true;1417}1418return false;1419}14201421ModuleSP Target::GetExecutableModule() {1422// search for the first executable in the module list1423for (size_t i = 0; i < m_images.GetSize(); ++i) {1424ModuleSP module_sp = m_images.GetModuleAtIndex(i);1425lldb_private::ObjectFile *obj = module_sp->GetObjectFile();1426if (obj == nullptr)1427continue;1428if (obj->GetType() == ObjectFile::Type::eTypeExecutable)1429return module_sp;1430}1431// as fall back return the first module loaded1432return m_images.GetModuleAtIndex(0);1433}14341435Module *Target::GetExecutableModulePointer() {1436return GetExecutableModule().get();1437}14381439static void LoadScriptingResourceForModule(const ModuleSP &module_sp,1440Target *target) {1441Status error;1442StreamString feedback_stream;1443if (module_sp && !module_sp->LoadScriptingResourceInTarget(target, error,1444feedback_stream)) {1445if (error.AsCString())1446target->GetDebugger().GetErrorStream().Printf(1447"unable to load scripting data for module %s - error reported was "1448"%s\n",1449module_sp->GetFileSpec().GetFileNameStrippingExtension().GetCString(),1450error.AsCString());1451}1452if (feedback_stream.GetSize())1453target->GetDebugger().GetErrorStream().Printf("%s\n",1454feedback_stream.GetData());1455}14561457void Target::ClearModules(bool delete_locations) {1458ModulesDidUnload(m_images, delete_locations);1459m_section_load_history.Clear();1460m_images.Clear();1461m_scratch_type_system_map.Clear();1462}14631464void Target::DidExec() {1465// When a process exec's we need to know about it so we can do some cleanup.1466m_breakpoint_list.RemoveInvalidLocations(m_arch.GetSpec());1467m_internal_breakpoint_list.RemoveInvalidLocations(m_arch.GetSpec());1468}14691470void Target::SetExecutableModule(ModuleSP &executable_sp,1471LoadDependentFiles load_dependent_files) {1472Log *log = GetLog(LLDBLog::Target);1473ClearModules(false);14741475if (executable_sp) {1476ElapsedTime elapsed(m_stats.GetCreateTime());1477LLDB_SCOPED_TIMERF("Target::SetExecutableModule (executable = '%s')",1478executable_sp->GetFileSpec().GetPath().c_str());14791480const bool notify = true;1481m_images.Append(executable_sp,1482notify); // The first image is our executable file14831484// If we haven't set an architecture yet, reset our architecture based on1485// what we found in the executable module.1486if (!m_arch.GetSpec().IsValid()) {1487m_arch = executable_sp->GetArchitecture();1488LLDB_LOG(log,1489"Target::SetExecutableModule setting architecture to {0} ({1}) "1490"based on executable file",1491m_arch.GetSpec().GetArchitectureName(),1492m_arch.GetSpec().GetTriple().getTriple());1493}14941495FileSpecList dependent_files;1496ObjectFile *executable_objfile = executable_sp->GetObjectFile();1497bool load_dependents = true;1498switch (load_dependent_files) {1499case eLoadDependentsDefault:1500load_dependents = executable_sp->IsExecutable();1501break;1502case eLoadDependentsYes:1503load_dependents = true;1504break;1505case eLoadDependentsNo:1506load_dependents = false;1507break;1508}15091510if (executable_objfile && load_dependents) {1511ModuleList added_modules;1512executable_objfile->GetDependentModules(dependent_files);1513for (uint32_t i = 0; i < dependent_files.GetSize(); i++) {1514FileSpec dependent_file_spec(dependent_files.GetFileSpecAtIndex(i));1515FileSpec platform_dependent_file_spec;1516if (m_platform_sp)1517m_platform_sp->GetFileWithUUID(dependent_file_spec, nullptr,1518platform_dependent_file_spec);1519else1520platform_dependent_file_spec = dependent_file_spec;15211522ModuleSpec module_spec(platform_dependent_file_spec, m_arch.GetSpec());1523ModuleSP image_module_sp(1524GetOrCreateModule(module_spec, false /* notify */));1525if (image_module_sp) {1526added_modules.AppendIfNeeded(image_module_sp, false);1527ObjectFile *objfile = image_module_sp->GetObjectFile();1528if (objfile)1529objfile->GetDependentModules(dependent_files);1530}1531}1532ModulesDidLoad(added_modules);1533}1534}1535}15361537bool Target::SetArchitecture(const ArchSpec &arch_spec, bool set_platform,1538bool merge) {1539Log *log = GetLog(LLDBLog::Target);1540bool missing_local_arch = !m_arch.GetSpec().IsValid();1541bool replace_local_arch = true;1542bool compatible_local_arch = false;1543ArchSpec other(arch_spec);15441545// Changing the architecture might mean that the currently selected platform1546// isn't compatible. Set the platform correctly if we are asked to do so,1547// otherwise assume the user will set the platform manually.1548if (set_platform) {1549if (other.IsValid()) {1550auto platform_sp = GetPlatform();1551if (!platform_sp || !platform_sp->IsCompatibleArchitecture(1552other, {}, ArchSpec::CompatibleMatch, nullptr)) {1553ArchSpec platform_arch;1554if (PlatformSP arch_platform_sp =1555GetDebugger().GetPlatformList().GetOrCreate(other, {},1556&platform_arch)) {1557SetPlatform(arch_platform_sp);1558if (platform_arch.IsValid())1559other = platform_arch;1560}1561}1562}1563}15641565if (!missing_local_arch) {1566if (merge && m_arch.GetSpec().IsCompatibleMatch(arch_spec)) {1567other.MergeFrom(m_arch.GetSpec());15681569if (m_arch.GetSpec().IsCompatibleMatch(other)) {1570compatible_local_arch = true;15711572if (m_arch.GetSpec().GetTriple() == other.GetTriple())1573replace_local_arch = false;1574}1575}1576}15771578if (compatible_local_arch || missing_local_arch) {1579// If we haven't got a valid arch spec, or the architectures are compatible1580// update the architecture, unless the one we already have is more1581// specified1582if (replace_local_arch)1583m_arch = other;1584LLDB_LOG(log,1585"Target::SetArchitecture merging compatible arch; arch "1586"is now {0} ({1})",1587m_arch.GetSpec().GetArchitectureName(),1588m_arch.GetSpec().GetTriple().getTriple());1589return true;1590}15911592// If we have an executable file, try to reset the executable to the desired1593// architecture1594LLDB_LOGF(1595log,1596"Target::SetArchitecture changing architecture to %s (%s) from %s (%s)",1597arch_spec.GetArchitectureName(),1598arch_spec.GetTriple().getTriple().c_str(),1599m_arch.GetSpec().GetArchitectureName(),1600m_arch.GetSpec().GetTriple().getTriple().c_str());1601m_arch = other;1602ModuleSP executable_sp = GetExecutableModule();16031604ClearModules(true);1605// Need to do something about unsetting breakpoints.16061607if (executable_sp) {1608LLDB_LOGF(log,1609"Target::SetArchitecture Trying to select executable file "1610"architecture %s (%s)",1611arch_spec.GetArchitectureName(),1612arch_spec.GetTriple().getTriple().c_str());1613ModuleSpec module_spec(executable_sp->GetFileSpec(), other);1614FileSpecList search_paths = GetExecutableSearchPaths();1615Status error = ModuleList::GetSharedModule(module_spec, executable_sp,1616&search_paths, nullptr, nullptr);16171618if (!error.Fail() && executable_sp) {1619SetExecutableModule(executable_sp, eLoadDependentsYes);1620return true;1621}1622}1623return false;1624}16251626bool Target::MergeArchitecture(const ArchSpec &arch_spec) {1627Log *log = GetLog(LLDBLog::Target);1628if (arch_spec.IsValid()) {1629if (m_arch.GetSpec().IsCompatibleMatch(arch_spec)) {1630// The current target arch is compatible with "arch_spec", see if we can1631// improve our current architecture using bits from "arch_spec"16321633LLDB_LOGF(log,1634"Target::MergeArchitecture target has arch %s, merging with "1635"arch %s",1636m_arch.GetSpec().GetTriple().getTriple().c_str(),1637arch_spec.GetTriple().getTriple().c_str());16381639// Merge bits from arch_spec into "merged_arch" and set our architecture1640ArchSpec merged_arch(m_arch.GetSpec());1641merged_arch.MergeFrom(arch_spec);1642return SetArchitecture(merged_arch);1643} else {1644// The new architecture is different, we just need to replace it1645return SetArchitecture(arch_spec);1646}1647}1648return false;1649}16501651void Target::NotifyWillClearList(const ModuleList &module_list) {}16521653void Target::NotifyModuleAdded(const ModuleList &module_list,1654const ModuleSP &module_sp) {1655// A module is being added to this target for the first time1656if (m_valid) {1657ModuleList my_module_list;1658my_module_list.Append(module_sp);1659ModulesDidLoad(my_module_list);1660}1661}16621663void Target::NotifyModuleRemoved(const ModuleList &module_list,1664const ModuleSP &module_sp) {1665// A module is being removed from this target.1666if (m_valid) {1667ModuleList my_module_list;1668my_module_list.Append(module_sp);1669ModulesDidUnload(my_module_list, false);1670}1671}16721673void Target::NotifyModuleUpdated(const ModuleList &module_list,1674const ModuleSP &old_module_sp,1675const ModuleSP &new_module_sp) {1676// A module is replacing an already added module1677if (m_valid) {1678m_breakpoint_list.UpdateBreakpointsWhenModuleIsReplaced(old_module_sp,1679new_module_sp);1680m_internal_breakpoint_list.UpdateBreakpointsWhenModuleIsReplaced(1681old_module_sp, new_module_sp);1682}1683}16841685void Target::NotifyModulesRemoved(lldb_private::ModuleList &module_list) {1686ModulesDidUnload(module_list, false);1687}16881689void Target::ModulesDidLoad(ModuleList &module_list) {1690const size_t num_images = module_list.GetSize();1691if (m_valid && num_images) {1692for (size_t idx = 0; idx < num_images; ++idx) {1693ModuleSP module_sp(module_list.GetModuleAtIndex(idx));1694LoadScriptingResourceForModule(module_sp, this);1695}1696m_breakpoint_list.UpdateBreakpoints(module_list, true, false);1697m_internal_breakpoint_list.UpdateBreakpoints(module_list, true, false);1698if (m_process_sp) {1699m_process_sp->ModulesDidLoad(module_list);1700}1701auto data_sp =1702std::make_shared<TargetEventData>(shared_from_this(), module_list);1703BroadcastEvent(eBroadcastBitModulesLoaded, data_sp);1704}1705}17061707void Target::SymbolsDidLoad(ModuleList &module_list) {1708if (m_valid && module_list.GetSize()) {1709if (m_process_sp) {1710for (LanguageRuntime *runtime : m_process_sp->GetLanguageRuntimes()) {1711runtime->SymbolsDidLoad(module_list);1712}1713}17141715m_breakpoint_list.UpdateBreakpoints(module_list, true, false);1716m_internal_breakpoint_list.UpdateBreakpoints(module_list, true, false);1717auto data_sp =1718std::make_shared<TargetEventData>(shared_from_this(), module_list);1719BroadcastEvent(eBroadcastBitSymbolsLoaded, data_sp);1720}1721}17221723void Target::ModulesDidUnload(ModuleList &module_list, bool delete_locations) {1724if (m_valid && module_list.GetSize()) {1725UnloadModuleSections(module_list);1726auto data_sp =1727std::make_shared<TargetEventData>(shared_from_this(), module_list);1728BroadcastEvent(eBroadcastBitModulesUnloaded, data_sp);1729m_breakpoint_list.UpdateBreakpoints(module_list, false, delete_locations);1730m_internal_breakpoint_list.UpdateBreakpoints(module_list, false,1731delete_locations);17321733// If a module was torn down it will have torn down the 'TypeSystemClang's1734// that we used as source 'ASTContext's for the persistent variables in1735// the current target. Those would now be unsafe to access because the1736// 'DeclOrigin' are now possibly stale. Thus clear all persistent1737// variables. We only want to flush 'TypeSystem's if the module being1738// unloaded was capable of describing a source type. JITted module unloads1739// happen frequently for Objective-C utility functions or the REPL and rely1740// on the persistent variables to stick around.1741const bool should_flush_type_systems =1742module_list.AnyOf([](lldb_private::Module &module) {1743auto *object_file = module.GetObjectFile();17441745if (!object_file)1746return false;17471748auto type = object_file->GetType();17491750// eTypeExecutable: when debugged binary was rebuilt1751// eTypeSharedLibrary: if dylib was re-loaded1752return module.FileHasChanged() &&1753(type == ObjectFile::eTypeObjectFile ||1754type == ObjectFile::eTypeExecutable ||1755type == ObjectFile::eTypeSharedLibrary);1756});17571758if (should_flush_type_systems)1759m_scratch_type_system_map.Clear();1760}1761}17621763bool Target::ModuleIsExcludedForUnconstrainedSearches(1764const FileSpec &module_file_spec) {1765if (GetBreakpointsConsultPlatformAvoidList()) {1766ModuleList matchingModules;1767ModuleSpec module_spec(module_file_spec);1768GetImages().FindModules(module_spec, matchingModules);1769size_t num_modules = matchingModules.GetSize();17701771// If there is more than one module for this file spec, only1772// return true if ALL the modules are on the black list.1773if (num_modules > 0) {1774for (size_t i = 0; i < num_modules; i++) {1775if (!ModuleIsExcludedForUnconstrainedSearches(1776matchingModules.GetModuleAtIndex(i)))1777return false;1778}1779return true;1780}1781}1782return false;1783}17841785bool Target::ModuleIsExcludedForUnconstrainedSearches(1786const lldb::ModuleSP &module_sp) {1787if (GetBreakpointsConsultPlatformAvoidList()) {1788if (m_platform_sp)1789return m_platform_sp->ModuleIsExcludedForUnconstrainedSearches(*this,1790module_sp);1791}1792return false;1793}17941795size_t Target::ReadMemoryFromFileCache(const Address &addr, void *dst,1796size_t dst_len, Status &error) {1797SectionSP section_sp(addr.GetSection());1798if (section_sp) {1799// If the contents of this section are encrypted, the on-disk file is1800// unusable. Read only from live memory.1801if (section_sp->IsEncrypted()) {1802error.SetErrorString("section is encrypted");1803return 0;1804}1805ModuleSP module_sp(section_sp->GetModule());1806if (module_sp) {1807ObjectFile *objfile = section_sp->GetModule()->GetObjectFile();1808if (objfile) {1809size_t bytes_read = objfile->ReadSectionData(1810section_sp.get(), addr.GetOffset(), dst, dst_len);1811if (bytes_read > 0)1812return bytes_read;1813else1814error.SetErrorStringWithFormat("error reading data from section %s",1815section_sp->GetName().GetCString());1816} else1817error.SetErrorString("address isn't from a object file");1818} else1819error.SetErrorString("address isn't in a module");1820} else1821error.SetErrorString("address doesn't contain a section that points to a "1822"section in a object file");18231824return 0;1825}18261827size_t Target::ReadMemory(const Address &addr, void *dst, size_t dst_len,1828Status &error, bool force_live_memory,1829lldb::addr_t *load_addr_ptr) {1830error.Clear();18311832Address fixed_addr = addr;1833if (ProcessIsValid())1834if (const ABISP &abi = m_process_sp->GetABI())1835fixed_addr.SetLoadAddress(abi->FixAnyAddress(addr.GetLoadAddress(this)),1836this);18371838// if we end up reading this from process memory, we will fill this with the1839// actual load address1840if (load_addr_ptr)1841*load_addr_ptr = LLDB_INVALID_ADDRESS;18421843size_t bytes_read = 0;18441845addr_t load_addr = LLDB_INVALID_ADDRESS;1846addr_t file_addr = LLDB_INVALID_ADDRESS;1847Address resolved_addr;1848if (!fixed_addr.IsSectionOffset()) {1849SectionLoadList §ion_load_list = GetSectionLoadList();1850if (section_load_list.IsEmpty()) {1851// No sections are loaded, so we must assume we are not running yet and1852// anything we are given is a file address.1853file_addr =1854fixed_addr.GetOffset(); // "fixed_addr" doesn't have a section, so1855// its offset is the file address1856m_images.ResolveFileAddress(file_addr, resolved_addr);1857} else {1858// We have at least one section loaded. This can be because we have1859// manually loaded some sections with "target modules load ..." or1860// because we have a live process that has sections loaded through1861// the dynamic loader1862load_addr =1863fixed_addr.GetOffset(); // "fixed_addr" doesn't have a section, so1864// its offset is the load address1865section_load_list.ResolveLoadAddress(load_addr, resolved_addr);1866}1867}1868if (!resolved_addr.IsValid())1869resolved_addr = fixed_addr;18701871// If we read from the file cache but can't get as many bytes as requested,1872// we keep the result around in this buffer, in case this result is the1873// best we can do.1874std::unique_ptr<uint8_t[]> file_cache_read_buffer;1875size_t file_cache_bytes_read = 0;18761877// Read from file cache if read-only section.1878if (!force_live_memory && resolved_addr.IsSectionOffset()) {1879SectionSP section_sp(resolved_addr.GetSection());1880if (section_sp) {1881auto permissions = Flags(section_sp->GetPermissions());1882bool is_readonly = !permissions.Test(ePermissionsWritable) &&1883permissions.Test(ePermissionsReadable);1884if (is_readonly) {1885file_cache_bytes_read =1886ReadMemoryFromFileCache(resolved_addr, dst, dst_len, error);1887if (file_cache_bytes_read == dst_len)1888return file_cache_bytes_read;1889else if (file_cache_bytes_read > 0) {1890file_cache_read_buffer =1891std::make_unique<uint8_t[]>(file_cache_bytes_read);1892std::memcpy(file_cache_read_buffer.get(), dst, file_cache_bytes_read);1893}1894}1895}1896}18971898if (ProcessIsValid()) {1899if (load_addr == LLDB_INVALID_ADDRESS)1900load_addr = resolved_addr.GetLoadAddress(this);19011902if (load_addr == LLDB_INVALID_ADDRESS) {1903ModuleSP addr_module_sp(resolved_addr.GetModule());1904if (addr_module_sp && addr_module_sp->GetFileSpec())1905error.SetErrorStringWithFormatv(1906"{0:F}[{1:x+}] can't be resolved, {0:F} is not currently loaded",1907addr_module_sp->GetFileSpec(), resolved_addr.GetFileAddress());1908else1909error.SetErrorStringWithFormat("0x%" PRIx64 " can't be resolved",1910resolved_addr.GetFileAddress());1911} else {1912bytes_read = m_process_sp->ReadMemory(load_addr, dst, dst_len, error);1913if (bytes_read != dst_len) {1914if (error.Success()) {1915if (bytes_read == 0)1916error.SetErrorStringWithFormat(1917"read memory from 0x%" PRIx64 " failed", load_addr);1918else1919error.SetErrorStringWithFormat(1920"only %" PRIu64 " of %" PRIu641921" bytes were read from memory at 0x%" PRIx64,1922(uint64_t)bytes_read, (uint64_t)dst_len, load_addr);1923}1924}1925if (bytes_read) {1926if (load_addr_ptr)1927*load_addr_ptr = load_addr;1928return bytes_read;1929}1930}1931}19321933if (file_cache_read_buffer && file_cache_bytes_read > 0) {1934// Reading from the process failed. If we've previously succeeded in reading1935// something from the file cache, then copy that over and return that.1936std::memcpy(dst, file_cache_read_buffer.get(), file_cache_bytes_read);1937return file_cache_bytes_read;1938}19391940if (!file_cache_read_buffer && resolved_addr.IsSectionOffset()) {1941// If we didn't already try and read from the object file cache, then try1942// it after failing to read from the process.1943return ReadMemoryFromFileCache(resolved_addr, dst, dst_len, error);1944}1945return 0;1946}19471948size_t Target::ReadCStringFromMemory(const Address &addr, std::string &out_str,1949Status &error, bool force_live_memory) {1950char buf[256];1951out_str.clear();1952addr_t curr_addr = addr.GetLoadAddress(this);1953Address address(addr);1954while (true) {1955size_t length = ReadCStringFromMemory(address, buf, sizeof(buf), error,1956force_live_memory);1957if (length == 0)1958break;1959out_str.append(buf, length);1960// If we got "length - 1" bytes, we didn't get the whole C string, we need1961// to read some more characters1962if (length == sizeof(buf) - 1)1963curr_addr += length;1964else1965break;1966address = Address(curr_addr);1967}1968return out_str.size();1969}19701971size_t Target::ReadCStringFromMemory(const Address &addr, char *dst,1972size_t dst_max_len, Status &result_error,1973bool force_live_memory) {1974size_t total_cstr_len = 0;1975if (dst && dst_max_len) {1976result_error.Clear();1977// NULL out everything just to be safe1978memset(dst, 0, dst_max_len);1979Status error;1980addr_t curr_addr = addr.GetLoadAddress(this);1981Address address(addr);19821983// We could call m_process_sp->GetMemoryCacheLineSize() but I don't think1984// this really needs to be tied to the memory cache subsystem's cache line1985// size, so leave this as a fixed constant.1986const size_t cache_line_size = 512;19871988size_t bytes_left = dst_max_len - 1;1989char *curr_dst = dst;19901991while (bytes_left > 0) {1992addr_t cache_line_bytes_left =1993cache_line_size - (curr_addr % cache_line_size);1994addr_t bytes_to_read =1995std::min<addr_t>(bytes_left, cache_line_bytes_left);1996size_t bytes_read = ReadMemory(address, curr_dst, bytes_to_read, error,1997force_live_memory);19981999if (bytes_read == 0) {2000result_error = error;2001dst[total_cstr_len] = '\0';2002break;2003}2004const size_t len = strlen(curr_dst);20052006total_cstr_len += len;20072008if (len < bytes_to_read)2009break;20102011curr_dst += bytes_read;2012curr_addr += bytes_read;2013bytes_left -= bytes_read;2014address = Address(curr_addr);2015}2016} else {2017if (dst == nullptr)2018result_error.SetErrorString("invalid arguments");2019else2020result_error.Clear();2021}2022return total_cstr_len;2023}20242025addr_t Target::GetReasonableReadSize(const Address &addr) {2026addr_t load_addr = addr.GetLoadAddress(this);2027if (load_addr != LLDB_INVALID_ADDRESS && m_process_sp) {2028// Avoid crossing cache line boundaries.2029addr_t cache_line_size = m_process_sp->GetMemoryCacheLineSize();2030return cache_line_size - (load_addr % cache_line_size);2031}20322033// The read is going to go to the file cache, so we can just pick a largish2034// value.2035return 0x1000;2036}20372038size_t Target::ReadStringFromMemory(const Address &addr, char *dst,2039size_t max_bytes, Status &error,2040size_t type_width, bool force_live_memory) {2041if (!dst || !max_bytes || !type_width || max_bytes < type_width)2042return 0;20432044size_t total_bytes_read = 0;20452046// Ensure a null terminator independent of the number of bytes that is2047// read.2048memset(dst, 0, max_bytes);2049size_t bytes_left = max_bytes - type_width;20502051const char terminator[4] = {'\0', '\0', '\0', '\0'};2052assert(sizeof(terminator) >= type_width && "Attempting to validate a "2053"string with more than 4 bytes "2054"per character!");20552056Address address = addr;2057char *curr_dst = dst;20582059error.Clear();2060while (bytes_left > 0 && error.Success()) {2061addr_t bytes_to_read =2062std::min<addr_t>(bytes_left, GetReasonableReadSize(address));2063size_t bytes_read =2064ReadMemory(address, curr_dst, bytes_to_read, error, force_live_memory);20652066if (bytes_read == 0)2067break;20682069// Search for a null terminator of correct size and alignment in2070// bytes_read2071size_t aligned_start = total_bytes_read - total_bytes_read % type_width;2072for (size_t i = aligned_start;2073i + type_width <= total_bytes_read + bytes_read; i += type_width)2074if (::memcmp(&dst[i], terminator, type_width) == 0) {2075error.Clear();2076return i;2077}20782079total_bytes_read += bytes_read;2080curr_dst += bytes_read;2081address.Slide(bytes_read);2082bytes_left -= bytes_read;2083}2084return total_bytes_read;2085}20862087size_t Target::ReadScalarIntegerFromMemory(const Address &addr, uint32_t byte_size,2088bool is_signed, Scalar &scalar,2089Status &error,2090bool force_live_memory) {2091uint64_t uval;20922093if (byte_size <= sizeof(uval)) {2094size_t bytes_read =2095ReadMemory(addr, &uval, byte_size, error, force_live_memory);2096if (bytes_read == byte_size) {2097DataExtractor data(&uval, sizeof(uval), m_arch.GetSpec().GetByteOrder(),2098m_arch.GetSpec().GetAddressByteSize());2099lldb::offset_t offset = 0;2100if (byte_size <= 4)2101scalar = data.GetMaxU32(&offset, byte_size);2102else2103scalar = data.GetMaxU64(&offset, byte_size);21042105if (is_signed)2106scalar.SignExtend(byte_size * 8);2107return bytes_read;2108}2109} else {2110error.SetErrorStringWithFormat(2111"byte size of %u is too large for integer scalar type", byte_size);2112}2113return 0;2114}21152116uint64_t Target::ReadUnsignedIntegerFromMemory(const Address &addr,2117size_t integer_byte_size,2118uint64_t fail_value, Status &error,2119bool force_live_memory) {2120Scalar scalar;2121if (ReadScalarIntegerFromMemory(addr, integer_byte_size, false, scalar, error,2122force_live_memory))2123return scalar.ULongLong(fail_value);2124return fail_value;2125}21262127bool Target::ReadPointerFromMemory(const Address &addr, Status &error,2128Address &pointer_addr,2129bool force_live_memory) {2130Scalar scalar;2131if (ReadScalarIntegerFromMemory(addr, m_arch.GetSpec().GetAddressByteSize(),2132false, scalar, error, force_live_memory)) {2133addr_t pointer_vm_addr = scalar.ULongLong(LLDB_INVALID_ADDRESS);2134if (pointer_vm_addr != LLDB_INVALID_ADDRESS) {2135SectionLoadList §ion_load_list = GetSectionLoadList();2136if (section_load_list.IsEmpty()) {2137// No sections are loaded, so we must assume we are not running yet and2138// anything we are given is a file address.2139m_images.ResolveFileAddress(pointer_vm_addr, pointer_addr);2140} else {2141// We have at least one section loaded. This can be because we have2142// manually loaded some sections with "target modules load ..." or2143// because we have a live process that has sections loaded through2144// the dynamic loader2145section_load_list.ResolveLoadAddress(pointer_vm_addr, pointer_addr);2146}2147// We weren't able to resolve the pointer value, so just return an2148// address with no section2149if (!pointer_addr.IsValid())2150pointer_addr.SetOffset(pointer_vm_addr);2151return true;2152}2153}2154return false;2155}21562157ModuleSP Target::GetOrCreateModule(const ModuleSpec &module_spec, bool notify,2158Status *error_ptr) {2159ModuleSP module_sp;21602161Status error;21622163// First see if we already have this module in our module list. If we do,2164// then we're done, we don't need to consult the shared modules list. But2165// only do this if we are passed a UUID.21662167if (module_spec.GetUUID().IsValid())2168module_sp = m_images.FindFirstModule(module_spec);21692170if (!module_sp) {2171llvm::SmallVector<ModuleSP, 1>2172old_modules; // This will get filled in if we have a new version2173// of the library2174bool did_create_module = false;2175FileSpecList search_paths = GetExecutableSearchPaths();2176FileSpec symbol_file_spec;21772178// Call locate module callback if set. This allows users to implement their2179// own module cache system. For example, to leverage build system artifacts,2180// to bypass pulling files from remote platform, or to search symbol files2181// from symbol servers.2182if (m_platform_sp)2183m_platform_sp->CallLocateModuleCallbackIfSet(2184module_spec, module_sp, symbol_file_spec, &did_create_module);21852186// The result of this CallLocateModuleCallbackIfSet is one of the following.2187// 1. module_sp:loaded, symbol_file_spec:set2188// The callback found a module file and a symbol file for the2189// module_spec. We will call module_sp->SetSymbolFileFileSpec with2190// the symbol_file_spec later.2191// 2. module_sp:loaded, symbol_file_spec:empty2192// The callback only found a module file for the module_spec.2193// 3. module_sp:empty, symbol_file_spec:set2194// The callback only found a symbol file for the module. We continue2195// to find a module file for this module_spec and we will call2196// module_sp->SetSymbolFileFileSpec with the symbol_file_spec later.2197// 4. module_sp:empty, symbol_file_spec:empty2198// Platform does not exist, the callback is not set, the callback did2199// not find any module files nor any symbol files, the callback failed,2200// or something went wrong. We continue to find a module file for this2201// module_spec.22022203if (!module_sp) {2204// If there are image search path entries, try to use them to acquire a2205// suitable image.2206if (m_image_search_paths.GetSize()) {2207ModuleSpec transformed_spec(module_spec);2208ConstString transformed_dir;2209if (m_image_search_paths.RemapPath(2210module_spec.GetFileSpec().GetDirectory(), transformed_dir)) {2211transformed_spec.GetFileSpec().SetDirectory(transformed_dir);2212transformed_spec.GetFileSpec().SetFilename(2213module_spec.GetFileSpec().GetFilename());2214error = ModuleList::GetSharedModule(transformed_spec, module_sp,2215&search_paths, &old_modules,2216&did_create_module);2217}2218}2219}22202221if (!module_sp) {2222// If we have a UUID, we can check our global shared module list in case2223// we already have it. If we don't have a valid UUID, then we can't since2224// the path in "module_spec" will be a platform path, and we will need to2225// let the platform find that file. For example, we could be asking for2226// "/usr/lib/dyld" and if we do not have a UUID, we don't want to pick2227// the local copy of "/usr/lib/dyld" since our platform could be a remote2228// platform that has its own "/usr/lib/dyld" in an SDK or in a local file2229// cache.2230if (module_spec.GetUUID().IsValid()) {2231// We have a UUID, it is OK to check the global module list...2232error =2233ModuleList::GetSharedModule(module_spec, module_sp, &search_paths,2234&old_modules, &did_create_module);2235}22362237if (!module_sp) {2238// The platform is responsible for finding and caching an appropriate2239// module in the shared module cache.2240if (m_platform_sp) {2241error = m_platform_sp->GetSharedModule(2242module_spec, m_process_sp.get(), module_sp, &search_paths,2243&old_modules, &did_create_module);2244} else {2245error.SetErrorString("no platform is currently set");2246}2247}2248}22492250// We found a module that wasn't in our target list. Let's make sure that2251// there wasn't an equivalent module in the list already, and if there was,2252// let's remove it.2253if (module_sp) {2254ObjectFile *objfile = module_sp->GetObjectFile();2255if (objfile) {2256switch (objfile->GetType()) {2257case ObjectFile::eTypeCoreFile: /// A core file that has a checkpoint of2258/// a program's execution state2259case ObjectFile::eTypeExecutable: /// A normal executable2260case ObjectFile::eTypeDynamicLinker: /// The platform's dynamic linker2261/// executable2262case ObjectFile::eTypeObjectFile: /// An intermediate object file2263case ObjectFile::eTypeSharedLibrary: /// A shared library that can be2264/// used during execution2265break;2266case ObjectFile::eTypeDebugInfo: /// An object file that contains only2267/// debug information2268if (error_ptr)2269error_ptr->SetErrorString("debug info files aren't valid target "2270"modules, please specify an executable");2271return ModuleSP();2272case ObjectFile::eTypeStubLibrary: /// A library that can be linked2273/// against but not used for2274/// execution2275if (error_ptr)2276error_ptr->SetErrorString("stub libraries aren't valid target "2277"modules, please specify an executable");2278return ModuleSP();2279default:2280if (error_ptr)2281error_ptr->SetErrorString(2282"unsupported file type, please specify an executable");2283return ModuleSP();2284}2285// GetSharedModule is not guaranteed to find the old shared module, for2286// instance in the common case where you pass in the UUID, it is only2287// going to find the one module matching the UUID. In fact, it has no2288// good way to know what the "old module" relevant to this target is,2289// since there might be many copies of a module with this file spec in2290// various running debug sessions, but only one of them will belong to2291// this target. So let's remove the UUID from the module list, and look2292// in the target's module list. Only do this if there is SOMETHING else2293// in the module spec...2294if (module_spec.GetUUID().IsValid() &&2295!module_spec.GetFileSpec().GetFilename().IsEmpty() &&2296!module_spec.GetFileSpec().GetDirectory().IsEmpty()) {2297ModuleSpec module_spec_copy(module_spec.GetFileSpec());2298module_spec_copy.GetUUID().Clear();22992300ModuleList found_modules;2301m_images.FindModules(module_spec_copy, found_modules);2302found_modules.ForEach([&](const ModuleSP &found_module) -> bool {2303old_modules.push_back(found_module);2304return true;2305});2306}23072308// If the locate module callback had found a symbol file, set it to the2309// module_sp before preloading symbols.2310if (symbol_file_spec)2311module_sp->SetSymbolFileFileSpec(symbol_file_spec);23122313// Preload symbols outside of any lock, so hopefully we can do this for2314// each library in parallel.2315if (GetPreloadSymbols())2316module_sp->PreloadSymbols();2317llvm::SmallVector<ModuleSP, 1> replaced_modules;2318for (ModuleSP &old_module_sp : old_modules) {2319if (m_images.GetIndexForModule(old_module_sp.get()) !=2320LLDB_INVALID_INDEX32) {2321if (replaced_modules.empty())2322m_images.ReplaceModule(old_module_sp, module_sp);2323else2324m_images.Remove(old_module_sp);23252326replaced_modules.push_back(std::move(old_module_sp));2327}2328}23292330if (replaced_modules.size() > 1) {2331// The same new module replaced multiple old modules2332// simultaneously. It's not clear this should ever2333// happen (if we always replace old modules as we add2334// new ones, presumably we should never have more than2335// one old one). If there are legitimate cases where2336// this happens, then the ModuleList::Notifier interface2337// may need to be adjusted to allow reporting this.2338// In the meantime, just log that this has happened; just2339// above we called ReplaceModule on the first one, and Remove2340// on the rest.2341if (Log *log = GetLog(LLDBLog::Target | LLDBLog::Modules)) {2342StreamString message;2343auto dump = [&message](Module &dump_module) -> void {2344UUID dump_uuid = dump_module.GetUUID();23452346message << '[';2347dump_module.GetDescription(message.AsRawOstream());2348message << " (uuid ";23492350if (dump_uuid.IsValid())2351dump_uuid.Dump(message);2352else2353message << "not specified";23542355message << ")]";2356};23572358message << "New module ";2359dump(*module_sp);2360message.AsRawOstream()2361<< llvm::formatv(" simultaneously replaced {0} old modules: ",2362replaced_modules.size());2363for (ModuleSP &replaced_module_sp : replaced_modules)2364dump(*replaced_module_sp);23652366log->PutString(message.GetString());2367}2368}23692370if (replaced_modules.empty())2371m_images.Append(module_sp, notify);23722373for (ModuleSP &old_module_sp : replaced_modules) {2374Module *old_module_ptr = old_module_sp.get();2375old_module_sp.reset();2376ModuleList::RemoveSharedModuleIfOrphaned(old_module_ptr);2377}2378} else2379module_sp.reset();2380}2381}2382if (error_ptr)2383*error_ptr = error;2384return module_sp;2385}23862387TargetSP Target::CalculateTarget() { return shared_from_this(); }23882389ProcessSP Target::CalculateProcess() { return m_process_sp; }23902391ThreadSP Target::CalculateThread() { return ThreadSP(); }23922393StackFrameSP Target::CalculateStackFrame() { return StackFrameSP(); }23942395void Target::CalculateExecutionContext(ExecutionContext &exe_ctx) {2396exe_ctx.Clear();2397exe_ctx.SetTargetPtr(this);2398}23992400PathMappingList &Target::GetImageSearchPathList() {2401return m_image_search_paths;2402}24032404void Target::ImageSearchPathsChanged(const PathMappingList &path_list,2405void *baton) {2406Target *target = (Target *)baton;2407ModuleSP exe_module_sp(target->GetExecutableModule());2408if (exe_module_sp)2409target->SetExecutableModule(exe_module_sp, eLoadDependentsYes);2410}24112412llvm::Expected<lldb::TypeSystemSP>2413Target::GetScratchTypeSystemForLanguage(lldb::LanguageType language,2414bool create_on_demand) {2415if (!m_valid)2416return llvm::createStringError("Invalid Target");24172418if (language == eLanguageTypeMipsAssembler // GNU AS and LLVM use it for all2419// assembly code2420|| language == eLanguageTypeUnknown) {2421LanguageSet languages_for_expressions =2422Language::GetLanguagesSupportingTypeSystemsForExpressions();24232424if (languages_for_expressions[eLanguageTypeC]) {2425language = eLanguageTypeC; // LLDB's default. Override by setting the2426// target language.2427} else {2428if (languages_for_expressions.Empty())2429return llvm::createStringError(2430"No expression support for any languages");2431language = (LanguageType)languages_for_expressions.bitvector.find_first();2432}2433}24342435return m_scratch_type_system_map.GetTypeSystemForLanguage(language, this,2436create_on_demand);2437}24382439CompilerType Target::GetRegisterType(const std::string &name,2440const lldb_private::RegisterFlags &flags,2441uint32_t byte_size) {2442RegisterTypeBuilderSP provider = PluginManager::GetRegisterTypeBuilder(*this);2443assert(provider);2444return provider->GetRegisterType(name, flags, byte_size);2445}24462447std::vector<lldb::TypeSystemSP>2448Target::GetScratchTypeSystems(bool create_on_demand) {2449if (!m_valid)2450return {};24512452// Some TypeSystem instances are associated with several LanguageTypes so2453// they will show up several times in the loop below. The SetVector filters2454// out all duplicates as they serve no use for the caller.2455std::vector<lldb::TypeSystemSP> scratch_type_systems;24562457LanguageSet languages_for_expressions =2458Language::GetLanguagesSupportingTypeSystemsForExpressions();24592460for (auto bit : languages_for_expressions.bitvector.set_bits()) {2461auto language = (LanguageType)bit;2462auto type_system_or_err =2463GetScratchTypeSystemForLanguage(language, create_on_demand);2464if (!type_system_or_err)2465LLDB_LOG_ERROR(2466GetLog(LLDBLog::Target), type_system_or_err.takeError(),2467"Language '{1}' has expression support but no scratch type "2468"system available: {0}",2469Language::GetNameForLanguageType(language));2470else2471if (auto ts = *type_system_or_err)2472scratch_type_systems.push_back(ts);2473}24742475std::sort(scratch_type_systems.begin(), scratch_type_systems.end());2476scratch_type_systems.erase(2477std::unique(scratch_type_systems.begin(), scratch_type_systems.end()),2478scratch_type_systems.end());2479return scratch_type_systems;2480}24812482PersistentExpressionState *2483Target::GetPersistentExpressionStateForLanguage(lldb::LanguageType language) {2484auto type_system_or_err = GetScratchTypeSystemForLanguage(language, true);24852486if (auto err = type_system_or_err.takeError()) {2487LLDB_LOG_ERROR(2488GetLog(LLDBLog::Target), std::move(err),2489"Unable to get persistent expression state for language {1}: {0}",2490Language::GetNameForLanguageType(language));2491return nullptr;2492}24932494if (auto ts = *type_system_or_err)2495return ts->GetPersistentExpressionState();24962497LLDB_LOG(GetLog(LLDBLog::Target),2498"Unable to get persistent expression state for language {1}: {0}",2499Language::GetNameForLanguageType(language));2500return nullptr;2501}25022503UserExpression *Target::GetUserExpressionForLanguage(2504llvm::StringRef expr, llvm::StringRef prefix, SourceLanguage language,2505Expression::ResultType desired_type,2506const EvaluateExpressionOptions &options, ValueObject *ctx_obj,2507Status &error) {2508auto type_system_or_err =2509GetScratchTypeSystemForLanguage(language.AsLanguageType());2510if (auto err = type_system_or_err.takeError()) {2511error.SetErrorStringWithFormat(2512"Could not find type system for language %s: %s",2513Language::GetNameForLanguageType(language.AsLanguageType()),2514llvm::toString(std::move(err)).c_str());2515return nullptr;2516}25172518auto ts = *type_system_or_err;2519if (!ts) {2520error.SetErrorStringWithFormat(2521"Type system for language %s is no longer live",2522language.GetDescription().data());2523return nullptr;2524}25252526auto *user_expr = ts->GetUserExpression(expr, prefix, language, desired_type,2527options, ctx_obj);2528if (!user_expr)2529error.SetErrorStringWithFormat(2530"Could not create an expression for language %s",2531language.GetDescription().data());25322533return user_expr;2534}25352536FunctionCaller *Target::GetFunctionCallerForLanguage(2537lldb::LanguageType language, const CompilerType &return_type,2538const Address &function_address, const ValueList &arg_value_list,2539const char *name, Status &error) {2540auto type_system_or_err = GetScratchTypeSystemForLanguage(language);2541if (auto err = type_system_or_err.takeError()) {2542error.SetErrorStringWithFormat(2543"Could not find type system for language %s: %s",2544Language::GetNameForLanguageType(language),2545llvm::toString(std::move(err)).c_str());2546return nullptr;2547}2548auto ts = *type_system_or_err;2549if (!ts) {2550error.SetErrorStringWithFormat(2551"Type system for language %s is no longer live",2552Language::GetNameForLanguageType(language));2553return nullptr;2554}2555auto *persistent_fn = ts->GetFunctionCaller(return_type, function_address,2556arg_value_list, name);2557if (!persistent_fn)2558error.SetErrorStringWithFormat(2559"Could not create an expression for language %s",2560Language::GetNameForLanguageType(language));25612562return persistent_fn;2563}25642565llvm::Expected<std::unique_ptr<UtilityFunction>>2566Target::CreateUtilityFunction(std::string expression, std::string name,2567lldb::LanguageType language,2568ExecutionContext &exe_ctx) {2569auto type_system_or_err = GetScratchTypeSystemForLanguage(language);2570if (!type_system_or_err)2571return type_system_or_err.takeError();2572auto ts = *type_system_or_err;2573if (!ts)2574return llvm::createStringError(2575llvm::StringRef("Type system for language ") +2576Language::GetNameForLanguageType(language) +2577llvm::StringRef(" is no longer live"));2578std::unique_ptr<UtilityFunction> utility_fn =2579ts->CreateUtilityFunction(std::move(expression), std::move(name));2580if (!utility_fn)2581return llvm::createStringError(2582llvm::StringRef("Could not create an expression for language") +2583Language::GetNameForLanguageType(language));25842585DiagnosticManager diagnostics;2586if (!utility_fn->Install(diagnostics, exe_ctx))2587return llvm::createStringError(diagnostics.GetString());25882589return std::move(utility_fn);2590}25912592void Target::SettingsInitialize() { Process::SettingsInitialize(); }25932594void Target::SettingsTerminate() { Process::SettingsTerminate(); }25952596FileSpecList Target::GetDefaultExecutableSearchPaths() {2597return Target::GetGlobalProperties().GetExecutableSearchPaths();2598}25992600FileSpecList Target::GetDefaultDebugFileSearchPaths() {2601return Target::GetGlobalProperties().GetDebugFileSearchPaths();2602}26032604ArchSpec Target::GetDefaultArchitecture() {2605return Target::GetGlobalProperties().GetDefaultArchitecture();2606}26072608void Target::SetDefaultArchitecture(const ArchSpec &arch) {2609LLDB_LOG(GetLog(LLDBLog::Target),2610"setting target's default architecture to {0} ({1})",2611arch.GetArchitectureName(), arch.GetTriple().getTriple());2612Target::GetGlobalProperties().SetDefaultArchitecture(arch);2613}26142615llvm::Error Target::SetLabel(llvm::StringRef label) {2616size_t n = LLDB_INVALID_INDEX32;2617if (llvm::to_integer(label, n))2618return llvm::createStringError("Cannot use integer as target label.");2619TargetList &targets = GetDebugger().GetTargetList();2620for (size_t i = 0; i < targets.GetNumTargets(); i++) {2621TargetSP target_sp = targets.GetTargetAtIndex(i);2622if (target_sp && target_sp->GetLabel() == label) {2623return llvm::make_error<llvm::StringError>(2624llvm::formatv(2625"Cannot use label '{0}' since it's set in target #{1}.", label,2626i),2627llvm::inconvertibleErrorCode());2628}2629}26302631m_label = label.str();2632return llvm::Error::success();2633}26342635Target *Target::GetTargetFromContexts(const ExecutionContext *exe_ctx_ptr,2636const SymbolContext *sc_ptr) {2637// The target can either exist in the "process" of ExecutionContext, or in2638// the "target_sp" member of SymbolContext. This accessor helper function2639// will get the target from one of these locations.26402641Target *target = nullptr;2642if (sc_ptr != nullptr)2643target = sc_ptr->target_sp.get();2644if (target == nullptr && exe_ctx_ptr)2645target = exe_ctx_ptr->GetTargetPtr();2646return target;2647}26482649ExpressionResults Target::EvaluateExpression(2650llvm::StringRef expr, ExecutionContextScope *exe_scope,2651lldb::ValueObjectSP &result_valobj_sp,2652const EvaluateExpressionOptions &options, std::string *fixed_expression,2653ValueObject *ctx_obj) {2654result_valobj_sp.reset();26552656ExpressionResults execution_results = eExpressionSetupError;26572658if (expr.empty()) {2659m_stats.GetExpressionStats().NotifyFailure();2660return execution_results;2661}26622663// We shouldn't run stop hooks in expressions.2664bool old_suppress_value = m_suppress_stop_hooks;2665m_suppress_stop_hooks = true;2666auto on_exit = llvm::make_scope_exit([this, old_suppress_value]() {2667m_suppress_stop_hooks = old_suppress_value;2668});26692670ExecutionContext exe_ctx;26712672if (exe_scope) {2673exe_scope->CalculateExecutionContext(exe_ctx);2674} else if (m_process_sp) {2675m_process_sp->CalculateExecutionContext(exe_ctx);2676} else {2677CalculateExecutionContext(exe_ctx);2678}26792680// Make sure we aren't just trying to see the value of a persistent variable2681// (something like "$0")2682// Only check for persistent variables the expression starts with a '$'2683lldb::ExpressionVariableSP persistent_var_sp;2684if (expr[0] == '$') {2685auto type_system_or_err =2686GetScratchTypeSystemForLanguage(eLanguageTypeC);2687if (auto err = type_system_or_err.takeError()) {2688LLDB_LOG_ERROR(GetLog(LLDBLog::Target), std::move(err),2689"Unable to get scratch type system");2690} else {2691auto ts = *type_system_or_err;2692if (!ts)2693LLDB_LOG_ERROR(GetLog(LLDBLog::Target), std::move(err),2694"Scratch type system is no longer live: {0}");2695else2696persistent_var_sp =2697ts->GetPersistentExpressionState()->GetVariable(expr);2698}2699}2700if (persistent_var_sp) {2701result_valobj_sp = persistent_var_sp->GetValueObject();2702execution_results = eExpressionCompleted;2703} else {2704llvm::StringRef prefix = GetExpressionPrefixContents();2705Status error;2706execution_results = UserExpression::Evaluate(exe_ctx, options, expr, prefix,2707result_valobj_sp, error,2708fixed_expression, ctx_obj);2709// Pass up the error by wrapping it inside an error result.2710if (error.Fail() && !result_valobj_sp)2711result_valobj_sp = ValueObjectConstResult::Create(2712exe_ctx.GetBestExecutionContextScope(), error);2713}27142715if (execution_results == eExpressionCompleted)2716m_stats.GetExpressionStats().NotifySuccess();2717else2718m_stats.GetExpressionStats().NotifyFailure();2719return execution_results;2720}27212722lldb::ExpressionVariableSP Target::GetPersistentVariable(ConstString name) {2723lldb::ExpressionVariableSP variable_sp;2724m_scratch_type_system_map.ForEach(2725[name, &variable_sp](TypeSystemSP type_system) -> bool {2726auto ts = type_system.get();2727if (!ts)2728return true;2729if (PersistentExpressionState *persistent_state =2730ts->GetPersistentExpressionState()) {2731variable_sp = persistent_state->GetVariable(name);27322733if (variable_sp)2734return false; // Stop iterating the ForEach2735}2736return true; // Keep iterating the ForEach2737});2738return variable_sp;2739}27402741lldb::addr_t Target::GetPersistentSymbol(ConstString name) {2742lldb::addr_t address = LLDB_INVALID_ADDRESS;27432744m_scratch_type_system_map.ForEach(2745[name, &address](lldb::TypeSystemSP type_system) -> bool {2746auto ts = type_system.get();2747if (!ts)2748return true;27492750if (PersistentExpressionState *persistent_state =2751ts->GetPersistentExpressionState()) {2752address = persistent_state->LookupSymbol(name);2753if (address != LLDB_INVALID_ADDRESS)2754return false; // Stop iterating the ForEach2755}2756return true; // Keep iterating the ForEach2757});2758return address;2759}27602761llvm::Expected<lldb_private::Address> Target::GetEntryPointAddress() {2762Module *exe_module = GetExecutableModulePointer();27632764// Try to find the entry point address in the primary executable.2765const bool has_primary_executable = exe_module && exe_module->GetObjectFile();2766if (has_primary_executable) {2767Address entry_addr = exe_module->GetObjectFile()->GetEntryPointAddress();2768if (entry_addr.IsValid())2769return entry_addr;2770}27712772const ModuleList &modules = GetImages();2773const size_t num_images = modules.GetSize();2774for (size_t idx = 0; idx < num_images; ++idx) {2775ModuleSP module_sp(modules.GetModuleAtIndex(idx));2776if (!module_sp || !module_sp->GetObjectFile())2777continue;27782779Address entry_addr = module_sp->GetObjectFile()->GetEntryPointAddress();2780if (entry_addr.IsValid())2781return entry_addr;2782}27832784// We haven't found the entry point address. Return an appropriate error.2785if (!has_primary_executable)2786return llvm::createStringError(2787"No primary executable found and could not find entry point address in "2788"any executable module");27892790return llvm::createStringError(2791"Could not find entry point address for primary executable module \"" +2792exe_module->GetFileSpec().GetFilename().GetStringRef() + "\"");2793}27942795lldb::addr_t Target::GetCallableLoadAddress(lldb::addr_t load_addr,2796AddressClass addr_class) const {2797auto arch_plugin = GetArchitecturePlugin();2798return arch_plugin2799? arch_plugin->GetCallableLoadAddress(load_addr, addr_class)2800: load_addr;2801}28022803lldb::addr_t Target::GetOpcodeLoadAddress(lldb::addr_t load_addr,2804AddressClass addr_class) const {2805auto arch_plugin = GetArchitecturePlugin();2806return arch_plugin ? arch_plugin->GetOpcodeLoadAddress(load_addr, addr_class)2807: load_addr;2808}28092810lldb::addr_t Target::GetBreakableLoadAddress(lldb::addr_t addr) {2811auto arch_plugin = GetArchitecturePlugin();2812return arch_plugin ? arch_plugin->GetBreakableLoadAddress(addr, *this) : addr;2813}28142815SourceManager &Target::GetSourceManager() {2816if (!m_source_manager_up)2817m_source_manager_up = std::make_unique<SourceManager>(shared_from_this());2818return *m_source_manager_up;2819}28202821Target::StopHookSP Target::CreateStopHook(StopHook::StopHookKind kind) {2822lldb::user_id_t new_uid = ++m_stop_hook_next_id;2823Target::StopHookSP stop_hook_sp;2824switch (kind) {2825case StopHook::StopHookKind::CommandBased:2826stop_hook_sp.reset(new StopHookCommandLine(shared_from_this(), new_uid));2827break;2828case StopHook::StopHookKind::ScriptBased:2829stop_hook_sp.reset(new StopHookScripted(shared_from_this(), new_uid));2830break;2831}2832m_stop_hooks[new_uid] = stop_hook_sp;2833return stop_hook_sp;2834}28352836void Target::UndoCreateStopHook(lldb::user_id_t user_id) {2837if (!RemoveStopHookByID(user_id))2838return;2839if (user_id == m_stop_hook_next_id)2840m_stop_hook_next_id--;2841}28422843bool Target::RemoveStopHookByID(lldb::user_id_t user_id) {2844size_t num_removed = m_stop_hooks.erase(user_id);2845return (num_removed != 0);2846}28472848void Target::RemoveAllStopHooks() { m_stop_hooks.clear(); }28492850Target::StopHookSP Target::GetStopHookByID(lldb::user_id_t user_id) {2851StopHookSP found_hook;28522853StopHookCollection::iterator specified_hook_iter;2854specified_hook_iter = m_stop_hooks.find(user_id);2855if (specified_hook_iter != m_stop_hooks.end())2856found_hook = (*specified_hook_iter).second;2857return found_hook;2858}28592860bool Target::SetStopHookActiveStateByID(lldb::user_id_t user_id,2861bool active_state) {2862StopHookCollection::iterator specified_hook_iter;2863specified_hook_iter = m_stop_hooks.find(user_id);2864if (specified_hook_iter == m_stop_hooks.end())2865return false;28662867(*specified_hook_iter).second->SetIsActive(active_state);2868return true;2869}28702871void Target::SetAllStopHooksActiveState(bool active_state) {2872StopHookCollection::iterator pos, end = m_stop_hooks.end();2873for (pos = m_stop_hooks.begin(); pos != end; pos++) {2874(*pos).second->SetIsActive(active_state);2875}2876}28772878bool Target::RunStopHooks() {2879if (m_suppress_stop_hooks)2880return false;28812882if (!m_process_sp)2883return false;28842885// Somebody might have restarted the process:2886// Still return false, the return value is about US restarting the target.2887if (m_process_sp->GetState() != eStateStopped)2888return false;28892890if (m_stop_hooks.empty())2891return false;28922893// If there aren't any active stop hooks, don't bother either.2894bool any_active_hooks = false;2895for (auto hook : m_stop_hooks) {2896if (hook.second->IsActive()) {2897any_active_hooks = true;2898break;2899}2900}2901if (!any_active_hooks)2902return false;29032904// Make sure we check that we are not stopped because of us running a user2905// expression since in that case we do not want to run the stop-hooks. Note,2906// you can't just check whether the last stop was for a User Expression,2907// because breakpoint commands get run before stop hooks, and one of them2908// might have run an expression. You have to ensure you run the stop hooks2909// once per natural stop.2910uint32_t last_natural_stop = m_process_sp->GetModIDRef().GetLastNaturalStopID();2911if (last_natural_stop != 0 && m_latest_stop_hook_id == last_natural_stop)2912return false;29132914m_latest_stop_hook_id = last_natural_stop;29152916std::vector<ExecutionContext> exc_ctx_with_reasons;29172918ThreadList &cur_threadlist = m_process_sp->GetThreadList();2919size_t num_threads = cur_threadlist.GetSize();2920for (size_t i = 0; i < num_threads; i++) {2921lldb::ThreadSP cur_thread_sp = cur_threadlist.GetThreadAtIndex(i);2922if (cur_thread_sp->ThreadStoppedForAReason()) {2923lldb::StackFrameSP cur_frame_sp = cur_thread_sp->GetStackFrameAtIndex(0);2924exc_ctx_with_reasons.emplace_back(m_process_sp.get(), cur_thread_sp.get(),2925cur_frame_sp.get());2926}2927}29282929// If no threads stopped for a reason, don't run the stop-hooks.2930size_t num_exe_ctx = exc_ctx_with_reasons.size();2931if (num_exe_ctx == 0)2932return false;29332934StreamSP output_sp = m_debugger.GetAsyncOutputStream();29352936bool auto_continue = false;2937bool hooks_ran = false;2938bool print_hook_header = (m_stop_hooks.size() != 1);2939bool print_thread_header = (num_exe_ctx != 1);2940bool should_stop = false;2941bool somebody_restarted = false;29422943for (auto stop_entry : m_stop_hooks) {2944StopHookSP cur_hook_sp = stop_entry.second;2945if (!cur_hook_sp->IsActive())2946continue;29472948bool any_thread_matched = false;2949for (auto exc_ctx : exc_ctx_with_reasons) {2950// We detect somebody restarted in the stop-hook loop, and broke out of2951// that loop back to here. So break out of here too.2952if (somebody_restarted)2953break;29542955if (!cur_hook_sp->ExecutionContextPasses(exc_ctx))2956continue;29572958// We only consult the auto-continue for a stop hook if it matched the2959// specifier.2960auto_continue |= cur_hook_sp->GetAutoContinue();29612962if (!hooks_ran)2963hooks_ran = true;29642965if (print_hook_header && !any_thread_matched) {2966StreamString s;2967cur_hook_sp->GetDescription(s, eDescriptionLevelBrief);2968if (s.GetSize() != 0)2969output_sp->Printf("\n- Hook %" PRIu64 " (%s)\n", cur_hook_sp->GetID(),2970s.GetData());2971else2972output_sp->Printf("\n- Hook %" PRIu64 "\n", cur_hook_sp->GetID());2973any_thread_matched = true;2974}29752976if (print_thread_header)2977output_sp->Printf("-- Thread %d\n",2978exc_ctx.GetThreadPtr()->GetIndexID());29792980StopHook::StopHookResult this_result =2981cur_hook_sp->HandleStop(exc_ctx, output_sp);2982bool this_should_stop = true;29832984switch (this_result) {2985case StopHook::StopHookResult::KeepStopped:2986// If this hook is set to auto-continue that should override the2987// HandleStop result...2988if (cur_hook_sp->GetAutoContinue())2989this_should_stop = false;2990else2991this_should_stop = true;29922993break;2994case StopHook::StopHookResult::RequestContinue:2995this_should_stop = false;2996break;2997case StopHook::StopHookResult::AlreadyContinued:2998// We don't have a good way to prohibit people from restarting the2999// target willy nilly in a stop hook. If the hook did so, give a3000// gentle suggestion here and bag out if the hook processing.3001output_sp->Printf("\nAborting stop hooks, hook %" PRIu643002" set the program running.\n"3003" Consider using '-G true' to make "3004"stop hooks auto-continue.\n",3005cur_hook_sp->GetID());3006somebody_restarted = true;3007break;3008}3009// If we're already restarted, stop processing stop hooks.3010// FIXME: if we are doing non-stop mode for real, we would have to3011// check that OUR thread was restarted, otherwise we should keep3012// processing stop hooks.3013if (somebody_restarted)3014break;30153016// If anybody wanted to stop, we should all stop.3017if (!should_stop)3018should_stop = this_should_stop;3019}3020}30213022output_sp->Flush();30233024// If one of the commands in the stop hook already restarted the target,3025// report that fact.3026if (somebody_restarted)3027return true;30283029// Finally, if auto-continue was requested, do it now:3030// We only compute should_stop against the hook results if a hook got to run3031// which is why we have to do this conjoint test.3032if ((hooks_ran && !should_stop) || auto_continue) {3033Log *log = GetLog(LLDBLog::Process);3034Status error = m_process_sp->PrivateResume();3035if (error.Success()) {3036LLDB_LOG(log, "Resuming from RunStopHooks");3037return true;3038} else {3039LLDB_LOG(log, "Resuming from RunStopHooks failed: {0}", error);3040return false;3041}3042}30433044return false;3045}30463047TargetProperties &Target::GetGlobalProperties() {3048// NOTE: intentional leak so we don't crash if global destructor chain gets3049// called as other threads still use the result of this function3050static TargetProperties *g_settings_ptr =3051new TargetProperties(nullptr);3052return *g_settings_ptr;3053}30543055Status Target::Install(ProcessLaunchInfo *launch_info) {3056Status error;3057PlatformSP platform_sp(GetPlatform());3058if (platform_sp) {3059if (platform_sp->IsRemote()) {3060if (platform_sp->IsConnected()) {3061// Install all files that have an install path when connected to a3062// remote platform. If target.auto-install-main-executable is set then3063// also install the main executable even if it does not have an explicit3064// install path specified.3065const ModuleList &modules = GetImages();3066const size_t num_images = modules.GetSize();3067for (size_t idx = 0; idx < num_images; ++idx) {3068ModuleSP module_sp(modules.GetModuleAtIndex(idx));3069if (module_sp) {3070const bool is_main_executable = module_sp == GetExecutableModule();3071FileSpec local_file(module_sp->GetFileSpec());3072if (local_file) {3073FileSpec remote_file(module_sp->GetRemoteInstallFileSpec());3074if (!remote_file) {3075if (is_main_executable && GetAutoInstallMainExecutable()) {3076// Automatically install the main executable.3077remote_file = platform_sp->GetRemoteWorkingDirectory();3078remote_file.AppendPathComponent(3079module_sp->GetFileSpec().GetFilename().GetCString());3080}3081}3082if (remote_file) {3083error = platform_sp->Install(local_file, remote_file);3084if (error.Success()) {3085module_sp->SetPlatformFileSpec(remote_file);3086if (is_main_executable) {3087platform_sp->SetFilePermissions(remote_file, 0700);3088if (launch_info)3089launch_info->SetExecutableFile(remote_file, false);3090}3091} else3092break;3093}3094}3095}3096}3097}3098}3099}3100return error;3101}31023103bool Target::ResolveLoadAddress(addr_t load_addr, Address &so_addr,3104uint32_t stop_id) {3105return m_section_load_history.ResolveLoadAddress(stop_id, load_addr, so_addr);3106}31073108bool Target::ResolveFileAddress(lldb::addr_t file_addr,3109Address &resolved_addr) {3110return m_images.ResolveFileAddress(file_addr, resolved_addr);3111}31123113bool Target::SetSectionLoadAddress(const SectionSP §ion_sp,3114addr_t new_section_load_addr,3115bool warn_multiple) {3116const addr_t old_section_load_addr =3117m_section_load_history.GetSectionLoadAddress(3118SectionLoadHistory::eStopIDNow, section_sp);3119if (old_section_load_addr != new_section_load_addr) {3120uint32_t stop_id = 0;3121ProcessSP process_sp(GetProcessSP());3122if (process_sp)3123stop_id = process_sp->GetStopID();3124else3125stop_id = m_section_load_history.GetLastStopID();3126if (m_section_load_history.SetSectionLoadAddress(3127stop_id, section_sp, new_section_load_addr, warn_multiple))3128return true; // Return true if the section load address was changed...3129}3130return false; // Return false to indicate nothing changed3131}31323133size_t Target::UnloadModuleSections(const ModuleList &module_list) {3134size_t section_unload_count = 0;3135size_t num_modules = module_list.GetSize();3136for (size_t i = 0; i < num_modules; ++i) {3137section_unload_count +=3138UnloadModuleSections(module_list.GetModuleAtIndex(i));3139}3140return section_unload_count;3141}31423143size_t Target::UnloadModuleSections(const lldb::ModuleSP &module_sp) {3144uint32_t stop_id = 0;3145ProcessSP process_sp(GetProcessSP());3146if (process_sp)3147stop_id = process_sp->GetStopID();3148else3149stop_id = m_section_load_history.GetLastStopID();3150SectionList *sections = module_sp->GetSectionList();3151size_t section_unload_count = 0;3152if (sections) {3153const uint32_t num_sections = sections->GetNumSections(0);3154for (uint32_t i = 0; i < num_sections; ++i) {3155section_unload_count += m_section_load_history.SetSectionUnloaded(3156stop_id, sections->GetSectionAtIndex(i));3157}3158}3159return section_unload_count;3160}31613162bool Target::SetSectionUnloaded(const lldb::SectionSP §ion_sp) {3163uint32_t stop_id = 0;3164ProcessSP process_sp(GetProcessSP());3165if (process_sp)3166stop_id = process_sp->GetStopID();3167else3168stop_id = m_section_load_history.GetLastStopID();3169return m_section_load_history.SetSectionUnloaded(stop_id, section_sp);3170}31713172bool Target::SetSectionUnloaded(const lldb::SectionSP §ion_sp,3173addr_t load_addr) {3174uint32_t stop_id = 0;3175ProcessSP process_sp(GetProcessSP());3176if (process_sp)3177stop_id = process_sp->GetStopID();3178else3179stop_id = m_section_load_history.GetLastStopID();3180return m_section_load_history.SetSectionUnloaded(stop_id, section_sp,3181load_addr);3182}31833184void Target::ClearAllLoadedSections() { m_section_load_history.Clear(); }31853186void Target::SaveScriptedLaunchInfo(lldb_private::ProcessInfo &process_info) {3187if (process_info.IsScriptedProcess()) {3188// Only copy scripted process launch options.3189ProcessLaunchInfo &default_launch_info = const_cast<ProcessLaunchInfo &>(3190GetGlobalProperties().GetProcessLaunchInfo());3191default_launch_info.SetProcessPluginName("ScriptedProcess");3192default_launch_info.SetScriptedMetadata(process_info.GetScriptedMetadata());3193SetProcessLaunchInfo(default_launch_info);3194}3195}31963197Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) {3198m_stats.SetLaunchOrAttachTime();3199Status error;3200Log *log = GetLog(LLDBLog::Target);32013202LLDB_LOGF(log, "Target::%s() called for %s", __FUNCTION__,3203launch_info.GetExecutableFile().GetPath().c_str());32043205StateType state = eStateInvalid;32063207// Scope to temporarily get the process state in case someone has manually3208// remotely connected already to a process and we can skip the platform3209// launching.3210{3211ProcessSP process_sp(GetProcessSP());32123213if (process_sp) {3214state = process_sp->GetState();3215LLDB_LOGF(log,3216"Target::%s the process exists, and its current state is %s",3217__FUNCTION__, StateAsCString(state));3218} else {3219LLDB_LOGF(log, "Target::%s the process instance doesn't currently exist.",3220__FUNCTION__);3221}3222}32233224launch_info.GetFlags().Set(eLaunchFlagDebug);32253226SaveScriptedLaunchInfo(launch_info);32273228// Get the value of synchronous execution here. If you wait till after you3229// have started to run, then you could have hit a breakpoint, whose command3230// might switch the value, and then you'll pick up that incorrect value.3231Debugger &debugger = GetDebugger();3232const bool synchronous_execution =3233debugger.GetCommandInterpreter().GetSynchronous();32343235PlatformSP platform_sp(GetPlatform());32363237FinalizeFileActions(launch_info);32383239if (state == eStateConnected) {3240if (launch_info.GetFlags().Test(eLaunchFlagLaunchInTTY)) {3241error.SetErrorString(3242"can't launch in tty when launching through a remote connection");3243return error;3244}3245}32463247if (!launch_info.GetArchitecture().IsValid())3248launch_info.GetArchitecture() = GetArchitecture();32493250// Hijacking events of the process to be created to be sure that all events3251// until the first stop are intercepted (in case if platform doesn't define3252// its own hijacking listener or if the process is created by the target3253// manually, without the platform).3254if (!launch_info.GetHijackListener())3255launch_info.SetHijackListener(Listener::MakeListener(3256Process::LaunchSynchronousHijackListenerName.data()));32573258// If we're not already connected to the process, and if we have a platform3259// that can launch a process for debugging, go ahead and do that here.3260if (state != eStateConnected && platform_sp &&3261platform_sp->CanDebugProcess() && !launch_info.IsScriptedProcess()) {3262LLDB_LOGF(log, "Target::%s asking the platform to debug the process",3263__FUNCTION__);32643265// If there was a previous process, delete it before we make the new one.3266// One subtle point, we delete the process before we release the reference3267// to m_process_sp. That way even if we are the last owner, the process3268// will get Finalized before it gets destroyed.3269DeleteCurrentProcess();32703271m_process_sp =3272GetPlatform()->DebugProcess(launch_info, debugger, *this, error);32733274} else {3275LLDB_LOGF(log,3276"Target::%s the platform doesn't know how to debug a "3277"process, getting a process plugin to do this for us.",3278__FUNCTION__);32793280if (state == eStateConnected) {3281assert(m_process_sp);3282} else {3283// Use a Process plugin to construct the process.3284CreateProcess(launch_info.GetListener(),3285launch_info.GetProcessPluginName(), nullptr, false);3286}32873288// Since we didn't have a platform launch the process, launch it here.3289if (m_process_sp) {3290m_process_sp->HijackProcessEvents(launch_info.GetHijackListener());3291m_process_sp->SetShadowListener(launch_info.GetShadowListener());3292error = m_process_sp->Launch(launch_info);3293}3294}32953296if (!m_process_sp && error.Success())3297error.SetErrorString("failed to launch or debug process");32983299if (!error.Success())3300return error;33013302bool rebroadcast_first_stop =3303!synchronous_execution &&3304launch_info.GetFlags().Test(eLaunchFlagStopAtEntry);33053306assert(launch_info.GetHijackListener());33073308EventSP first_stop_event_sp;3309state = m_process_sp->WaitForProcessToStop(std::nullopt, &first_stop_event_sp,3310rebroadcast_first_stop,3311launch_info.GetHijackListener());3312m_process_sp->RestoreProcessEvents();33133314if (rebroadcast_first_stop) {3315assert(first_stop_event_sp);3316m_process_sp->BroadcastEvent(first_stop_event_sp);3317return error;3318}33193320switch (state) {3321case eStateStopped: {3322if (launch_info.GetFlags().Test(eLaunchFlagStopAtEntry))3323break;3324if (synchronous_execution)3325// Now we have handled the stop-from-attach, and we are just3326// switching to a synchronous resume. So we should switch to the3327// SyncResume hijacker.3328m_process_sp->ResumeSynchronous(stream);3329else3330error = m_process_sp->Resume();3331if (!error.Success()) {3332Status error2;3333error2.SetErrorStringWithFormat(3334"process resume at entry point failed: %s", error.AsCString());3335error = error2;3336}3337} break;3338case eStateExited: {3339bool with_shell = !!launch_info.GetShell();3340const int exit_status = m_process_sp->GetExitStatus();3341const char *exit_desc = m_process_sp->GetExitDescription();3342std::string desc;3343if (exit_desc && exit_desc[0])3344desc = " (" + std::string(exit_desc) + ')';3345if (with_shell)3346error.SetErrorStringWithFormat(3347"process exited with status %i%s\n"3348"'r' and 'run' are aliases that default to launching through a "3349"shell.\n"3350"Try launching without going through a shell by using "3351"'process launch'.",3352exit_status, desc.c_str());3353else3354error.SetErrorStringWithFormat("process exited with status %i%s",3355exit_status, desc.c_str());3356} break;3357default:3358error.SetErrorStringWithFormat("initial process state wasn't stopped: %s",3359StateAsCString(state));3360break;3361}3362return error;3363}33643365void Target::SetTrace(const TraceSP &trace_sp) { m_trace_sp = trace_sp; }33663367TraceSP Target::GetTrace() { return m_trace_sp; }33683369llvm::Expected<TraceSP> Target::CreateTrace() {3370if (!m_process_sp)3371return llvm::createStringError(llvm::inconvertibleErrorCode(),3372"A process is required for tracing");3373if (m_trace_sp)3374return llvm::createStringError(llvm::inconvertibleErrorCode(),3375"A trace already exists for the target");33763377llvm::Expected<TraceSupportedResponse> trace_type =3378m_process_sp->TraceSupported();3379if (!trace_type)3380return llvm::createStringError(3381llvm::inconvertibleErrorCode(), "Tracing is not supported. %s",3382llvm::toString(trace_type.takeError()).c_str());3383if (llvm::Expected<TraceSP> trace_sp =3384Trace::FindPluginForLiveProcess(trace_type->name, *m_process_sp))3385m_trace_sp = *trace_sp;3386else3387return llvm::createStringError(3388llvm::inconvertibleErrorCode(),3389"Couldn't create a Trace object for the process. %s",3390llvm::toString(trace_sp.takeError()).c_str());3391return m_trace_sp;3392}33933394llvm::Expected<TraceSP> Target::GetTraceOrCreate() {3395if (m_trace_sp)3396return m_trace_sp;3397return CreateTrace();3398}33993400Status Target::Attach(ProcessAttachInfo &attach_info, Stream *stream) {3401m_stats.SetLaunchOrAttachTime();3402auto state = eStateInvalid;3403auto process_sp = GetProcessSP();3404if (process_sp) {3405state = process_sp->GetState();3406if (process_sp->IsAlive() && state != eStateConnected) {3407if (state == eStateAttaching)3408return Status("process attach is in progress");3409return Status("a process is already being debugged");3410}3411}34123413const ModuleSP old_exec_module_sp = GetExecutableModule();34143415// If no process info was specified, then use the target executable name as3416// the process to attach to by default3417if (!attach_info.ProcessInfoSpecified()) {3418if (old_exec_module_sp)3419attach_info.GetExecutableFile().SetFilename(3420old_exec_module_sp->GetPlatformFileSpec().GetFilename());34213422if (!attach_info.ProcessInfoSpecified()) {3423return Status("no process specified, create a target with a file, or "3424"specify the --pid or --name");3425}3426}34273428const auto platform_sp =3429GetDebugger().GetPlatformList().GetSelectedPlatform();3430ListenerSP hijack_listener_sp;3431const bool async = attach_info.GetAsync();3432if (!async) {3433hijack_listener_sp = Listener::MakeListener(3434Process::AttachSynchronousHijackListenerName.data());3435attach_info.SetHijackListener(hijack_listener_sp);3436}34373438Status error;3439if (state != eStateConnected && platform_sp != nullptr &&3440platform_sp->CanDebugProcess() && !attach_info.IsScriptedProcess()) {3441SetPlatform(platform_sp);3442process_sp = platform_sp->Attach(attach_info, GetDebugger(), this, error);3443} else {3444if (state != eStateConnected) {3445SaveScriptedLaunchInfo(attach_info);3446llvm::StringRef plugin_name = attach_info.GetProcessPluginName();3447process_sp =3448CreateProcess(attach_info.GetListenerForProcess(GetDebugger()),3449plugin_name, nullptr, false);3450if (!process_sp) {3451error.SetErrorStringWithFormatv(3452"failed to create process using plugin '{0}'",3453plugin_name.empty() ? "<empty>" : plugin_name);3454return error;3455}3456}3457if (hijack_listener_sp)3458process_sp->HijackProcessEvents(hijack_listener_sp);3459error = process_sp->Attach(attach_info);3460}34613462if (error.Success() && process_sp) {3463if (async) {3464process_sp->RestoreProcessEvents();3465} else {3466// We are stopping all the way out to the user, so update selected frames.3467state = process_sp->WaitForProcessToStop(3468std::nullopt, nullptr, false, attach_info.GetHijackListener(), stream,3469true, SelectMostRelevantFrame);3470process_sp->RestoreProcessEvents();34713472if (state != eStateStopped) {3473const char *exit_desc = process_sp->GetExitDescription();3474if (exit_desc)3475error.SetErrorStringWithFormat("%s", exit_desc);3476else3477error.SetErrorString(3478"process did not stop (no such process or permission problem?)");3479process_sp->Destroy(false);3480}3481}3482}3483return error;3484}34853486void Target::FinalizeFileActions(ProcessLaunchInfo &info) {3487Log *log = GetLog(LLDBLog::Process);34883489// Finalize the file actions, and if none were given, default to opening up a3490// pseudo terminal3491PlatformSP platform_sp = GetPlatform();3492const bool default_to_use_pty =3493m_platform_sp ? m_platform_sp->IsHost() : false;3494LLDB_LOG(3495log,3496"have platform={0}, platform_sp->IsHost()={1}, default_to_use_pty={2}",3497bool(platform_sp),3498platform_sp ? (platform_sp->IsHost() ? "true" : "false") : "n/a",3499default_to_use_pty);35003501// If nothing for stdin or stdout or stderr was specified, then check the3502// process for any default settings that were set with "settings set"3503if (info.GetFileActionForFD(STDIN_FILENO) == nullptr ||3504info.GetFileActionForFD(STDOUT_FILENO) == nullptr ||3505info.GetFileActionForFD(STDERR_FILENO) == nullptr) {3506LLDB_LOG(log, "at least one of stdin/stdout/stderr was not set, evaluating "3507"default handling");35083509if (info.GetFlags().Test(eLaunchFlagLaunchInTTY)) {3510// Do nothing, if we are launching in a remote terminal no file actions3511// should be done at all.3512return;3513}35143515if (info.GetFlags().Test(eLaunchFlagDisableSTDIO)) {3516LLDB_LOG(log, "eLaunchFlagDisableSTDIO set, adding suppression action "3517"for stdin, stdout and stderr");3518info.AppendSuppressFileAction(STDIN_FILENO, true, false);3519info.AppendSuppressFileAction(STDOUT_FILENO, false, true);3520info.AppendSuppressFileAction(STDERR_FILENO, false, true);3521} else {3522// Check for any values that might have gotten set with any of: (lldb)3523// settings set target.input-path (lldb) settings set target.output-path3524// (lldb) settings set target.error-path3525FileSpec in_file_spec;3526FileSpec out_file_spec;3527FileSpec err_file_spec;3528// Only override with the target settings if we don't already have an3529// action for in, out or error3530if (info.GetFileActionForFD(STDIN_FILENO) == nullptr)3531in_file_spec = GetStandardInputPath();3532if (info.GetFileActionForFD(STDOUT_FILENO) == nullptr)3533out_file_spec = GetStandardOutputPath();3534if (info.GetFileActionForFD(STDERR_FILENO) == nullptr)3535err_file_spec = GetStandardErrorPath();35363537LLDB_LOG(log, "target stdin='{0}', target stdout='{1}', stderr='{1}'",3538in_file_spec, out_file_spec, err_file_spec);35393540if (in_file_spec) {3541info.AppendOpenFileAction(STDIN_FILENO, in_file_spec, true, false);3542LLDB_LOG(log, "appended stdin open file action for {0}", in_file_spec);3543}35443545if (out_file_spec) {3546info.AppendOpenFileAction(STDOUT_FILENO, out_file_spec, false, true);3547LLDB_LOG(log, "appended stdout open file action for {0}",3548out_file_spec);3549}35503551if (err_file_spec) {3552info.AppendOpenFileAction(STDERR_FILENO, err_file_spec, false, true);3553LLDB_LOG(log, "appended stderr open file action for {0}",3554err_file_spec);3555}35563557if (default_to_use_pty) {3558llvm::Error Err = info.SetUpPtyRedirection();3559LLDB_LOG_ERROR(log, std::move(Err), "SetUpPtyRedirection failed: {0}");3560}3561}3562}3563}35643565void Target::AddDummySignal(llvm::StringRef name, LazyBool pass, LazyBool notify,3566LazyBool stop) {3567if (name.empty())3568return;3569// Don't add a signal if all the actions are trivial:3570if (pass == eLazyBoolCalculate && notify == eLazyBoolCalculate3571&& stop == eLazyBoolCalculate)3572return;35733574auto& elem = m_dummy_signals[name];3575elem.pass = pass;3576elem.notify = notify;3577elem.stop = stop;3578}35793580bool Target::UpdateSignalFromDummy(UnixSignalsSP signals_sp,3581const DummySignalElement &elem) {3582if (!signals_sp)3583return false;35843585int32_t signo3586= signals_sp->GetSignalNumberFromName(elem.first().str().c_str());3587if (signo == LLDB_INVALID_SIGNAL_NUMBER)3588return false;35893590if (elem.second.pass == eLazyBoolYes)3591signals_sp->SetShouldSuppress(signo, false);3592else if (elem.second.pass == eLazyBoolNo)3593signals_sp->SetShouldSuppress(signo, true);35943595if (elem.second.notify == eLazyBoolYes)3596signals_sp->SetShouldNotify(signo, true);3597else if (elem.second.notify == eLazyBoolNo)3598signals_sp->SetShouldNotify(signo, false);35993600if (elem.second.stop == eLazyBoolYes)3601signals_sp->SetShouldStop(signo, true);3602else if (elem.second.stop == eLazyBoolNo)3603signals_sp->SetShouldStop(signo, false);3604return true;3605}36063607bool Target::ResetSignalFromDummy(UnixSignalsSP signals_sp,3608const DummySignalElement &elem) {3609if (!signals_sp)3610return false;3611int32_t signo3612= signals_sp->GetSignalNumberFromName(elem.first().str().c_str());3613if (signo == LLDB_INVALID_SIGNAL_NUMBER)3614return false;3615bool do_pass = elem.second.pass != eLazyBoolCalculate;3616bool do_stop = elem.second.stop != eLazyBoolCalculate;3617bool do_notify = elem.second.notify != eLazyBoolCalculate;3618signals_sp->ResetSignal(signo, do_stop, do_notify, do_pass);3619return true;3620}36213622void Target::UpdateSignalsFromDummy(UnixSignalsSP signals_sp,3623StreamSP warning_stream_sp) {3624if (!signals_sp)3625return;36263627for (const auto &elem : m_dummy_signals) {3628if (!UpdateSignalFromDummy(signals_sp, elem))3629warning_stream_sp->Printf("Target signal '%s' not found in process\n",3630elem.first().str().c_str());3631}3632}36333634void Target::ClearDummySignals(Args &signal_names) {3635ProcessSP process_sp = GetProcessSP();3636// The simplest case, delete them all with no process to update.3637if (signal_names.GetArgumentCount() == 0 && !process_sp) {3638m_dummy_signals.clear();3639return;3640}3641UnixSignalsSP signals_sp;3642if (process_sp)3643signals_sp = process_sp->GetUnixSignals();36443645for (const Args::ArgEntry &entry : signal_names) {3646const char *signal_name = entry.c_str();3647auto elem = m_dummy_signals.find(signal_name);3648// If we didn't find it go on.3649// FIXME: Should I pipe error handling through here?3650if (elem == m_dummy_signals.end()) {3651continue;3652}3653if (signals_sp)3654ResetSignalFromDummy(signals_sp, *elem);3655m_dummy_signals.erase(elem);3656}3657}36583659void Target::PrintDummySignals(Stream &strm, Args &signal_args) {3660strm.Printf("NAME PASS STOP NOTIFY\n");3661strm.Printf("=========== ======= ======= =======\n");36623663auto str_for_lazy = [] (LazyBool lazy) -> const char * {3664switch (lazy) {3665case eLazyBoolCalculate: return "not set";3666case eLazyBoolYes: return "true ";3667case eLazyBoolNo: return "false ";3668}3669llvm_unreachable("Fully covered switch above!");3670};3671size_t num_args = signal_args.GetArgumentCount();3672for (const auto &elem : m_dummy_signals) {3673bool print_it = false;3674for (size_t idx = 0; idx < num_args; idx++) {3675if (elem.first() == signal_args.GetArgumentAtIndex(idx)) {3676print_it = true;3677break;3678}3679}3680if (print_it) {3681strm.Printf("%-11s ", elem.first().str().c_str());3682strm.Printf("%s %s %s\n", str_for_lazy(elem.second.pass),3683str_for_lazy(elem.second.stop),3684str_for_lazy(elem.second.notify));3685}3686}3687}36883689// Target::StopHook3690Target::StopHook::StopHook(lldb::TargetSP target_sp, lldb::user_id_t uid)3691: UserID(uid), m_target_sp(target_sp), m_specifier_sp(),3692m_thread_spec_up() {}36933694Target::StopHook::StopHook(const StopHook &rhs)3695: UserID(rhs.GetID()), m_target_sp(rhs.m_target_sp),3696m_specifier_sp(rhs.m_specifier_sp), m_thread_spec_up(),3697m_active(rhs.m_active), m_auto_continue(rhs.m_auto_continue) {3698if (rhs.m_thread_spec_up)3699m_thread_spec_up = std::make_unique<ThreadSpec>(*rhs.m_thread_spec_up);3700}37013702void Target::StopHook::SetSpecifier(SymbolContextSpecifier *specifier) {3703m_specifier_sp.reset(specifier);3704}37053706void Target::StopHook::SetThreadSpecifier(ThreadSpec *specifier) {3707m_thread_spec_up.reset(specifier);3708}37093710bool Target::StopHook::ExecutionContextPasses(const ExecutionContext &exc_ctx) {3711SymbolContextSpecifier *specifier = GetSpecifier();3712if (!specifier)3713return true;37143715bool will_run = true;3716if (exc_ctx.GetFramePtr())3717will_run = GetSpecifier()->SymbolContextMatches(3718exc_ctx.GetFramePtr()->GetSymbolContext(eSymbolContextEverything));3719if (will_run && GetThreadSpecifier() != nullptr)3720will_run =3721GetThreadSpecifier()->ThreadPassesBasicTests(exc_ctx.GetThreadRef());37223723return will_run;3724}37253726void Target::StopHook::GetDescription(Stream &s,3727lldb::DescriptionLevel level) const {37283729// For brief descriptions, only print the subclass description:3730if (level == eDescriptionLevelBrief) {3731GetSubclassDescription(s, level);3732return;3733}37343735unsigned indent_level = s.GetIndentLevel();37363737s.SetIndentLevel(indent_level + 2);37383739s.Printf("Hook: %" PRIu64 "\n", GetID());3740if (m_active)3741s.Indent("State: enabled\n");3742else3743s.Indent("State: disabled\n");37443745if (m_auto_continue)3746s.Indent("AutoContinue on\n");37473748if (m_specifier_sp) {3749s.Indent();3750s.PutCString("Specifier:\n");3751s.SetIndentLevel(indent_level + 4);3752m_specifier_sp->GetDescription(&s, level);3753s.SetIndentLevel(indent_level + 2);3754}37553756if (m_thread_spec_up) {3757StreamString tmp;3758s.Indent("Thread:\n");3759m_thread_spec_up->GetDescription(&tmp, level);3760s.SetIndentLevel(indent_level + 4);3761s.Indent(tmp.GetString());3762s.PutCString("\n");3763s.SetIndentLevel(indent_level + 2);3764}3765GetSubclassDescription(s, level);3766}37673768void Target::StopHookCommandLine::GetSubclassDescription(3769Stream &s, lldb::DescriptionLevel level) const {3770// The brief description just prints the first command.3771if (level == eDescriptionLevelBrief) {3772if (m_commands.GetSize() == 1)3773s.PutCString(m_commands.GetStringAtIndex(0));3774return;3775}3776s.Indent("Commands: \n");3777s.SetIndentLevel(s.GetIndentLevel() + 4);3778uint32_t num_commands = m_commands.GetSize();3779for (uint32_t i = 0; i < num_commands; i++) {3780s.Indent(m_commands.GetStringAtIndex(i));3781s.PutCString("\n");3782}3783s.SetIndentLevel(s.GetIndentLevel() - 4);3784}37853786// Target::StopHookCommandLine3787void Target::StopHookCommandLine::SetActionFromString(const std::string &string) {3788GetCommands().SplitIntoLines(string);3789}37903791void Target::StopHookCommandLine::SetActionFromStrings(3792const std::vector<std::string> &strings) {3793for (auto string : strings)3794GetCommands().AppendString(string.c_str());3795}37963797Target::StopHook::StopHookResult3798Target::StopHookCommandLine::HandleStop(ExecutionContext &exc_ctx,3799StreamSP output_sp) {3800assert(exc_ctx.GetTargetPtr() && "Can't call PerformAction on a context "3801"with no target");38023803if (!m_commands.GetSize())3804return StopHookResult::KeepStopped;38053806CommandReturnObject result(false);3807result.SetImmediateOutputStream(output_sp);3808result.SetInteractive(false);3809Debugger &debugger = exc_ctx.GetTargetPtr()->GetDebugger();3810CommandInterpreterRunOptions options;3811options.SetStopOnContinue(true);3812options.SetStopOnError(true);3813options.SetEchoCommands(false);3814options.SetPrintResults(true);3815options.SetPrintErrors(true);3816options.SetAddToHistory(false);38173818// Force Async:3819bool old_async = debugger.GetAsyncExecution();3820debugger.SetAsyncExecution(true);3821debugger.GetCommandInterpreter().HandleCommands(GetCommands(), exc_ctx,3822options, result);3823debugger.SetAsyncExecution(old_async);3824lldb::ReturnStatus status = result.GetStatus();3825if (status == eReturnStatusSuccessContinuingNoResult ||3826status == eReturnStatusSuccessContinuingResult)3827return StopHookResult::AlreadyContinued;3828return StopHookResult::KeepStopped;3829}38303831// Target::StopHookScripted3832Status Target::StopHookScripted::SetScriptCallback(3833std::string class_name, StructuredData::ObjectSP extra_args_sp) {3834Status error;38353836ScriptInterpreter *script_interp =3837GetTarget()->GetDebugger().GetScriptInterpreter();3838if (!script_interp) {3839error.SetErrorString("No script interpreter installed.");3840return error;3841}38423843m_class_name = class_name;3844m_extra_args.SetObjectSP(extra_args_sp);38453846m_implementation_sp = script_interp->CreateScriptedStopHook(3847GetTarget(), m_class_name.c_str(), m_extra_args, error);38483849return error;3850}38513852Target::StopHook::StopHookResult3853Target::StopHookScripted::HandleStop(ExecutionContext &exc_ctx,3854StreamSP output_sp) {3855assert(exc_ctx.GetTargetPtr() && "Can't call HandleStop on a context "3856"with no target");38573858ScriptInterpreter *script_interp =3859GetTarget()->GetDebugger().GetScriptInterpreter();3860if (!script_interp)3861return StopHookResult::KeepStopped;38623863bool should_stop = script_interp->ScriptedStopHookHandleStop(3864m_implementation_sp, exc_ctx, output_sp);38653866return should_stop ? StopHookResult::KeepStopped3867: StopHookResult::RequestContinue;3868}38693870void Target::StopHookScripted::GetSubclassDescription(3871Stream &s, lldb::DescriptionLevel level) const {3872if (level == eDescriptionLevelBrief) {3873s.PutCString(m_class_name);3874return;3875}3876s.Indent("Class:");3877s.Printf("%s\n", m_class_name.c_str());38783879// Now print the extra args:3880// FIXME: We should use StructuredData.GetDescription on the m_extra_args3881// but that seems to rely on some printing plugin that doesn't exist.3882if (!m_extra_args.IsValid())3883return;3884StructuredData::ObjectSP object_sp = m_extra_args.GetObjectSP();3885if (!object_sp || !object_sp->IsValid())3886return;38873888StructuredData::Dictionary *as_dict = object_sp->GetAsDictionary();3889if (!as_dict || !as_dict->IsValid())3890return;38913892uint32_t num_keys = as_dict->GetSize();3893if (num_keys == 0)3894return;38953896s.Indent("Args:\n");3897s.SetIndentLevel(s.GetIndentLevel() + 4);38983899auto print_one_element = [&s](llvm::StringRef key,3900StructuredData::Object *object) {3901s.Indent();3902s.Format("{0} : {1}\n", key, object->GetStringValue());3903return true;3904};39053906as_dict->ForEach(print_one_element);39073908s.SetIndentLevel(s.GetIndentLevel() - 4);3909}39103911static constexpr OptionEnumValueElement g_dynamic_value_types[] = {3912{3913eNoDynamicValues,3914"no-dynamic-values",3915"Don't calculate the dynamic type of values",3916},3917{3918eDynamicCanRunTarget,3919"run-target",3920"Calculate the dynamic type of values "3921"even if you have to run the target.",3922},3923{3924eDynamicDontRunTarget,3925"no-run-target",3926"Calculate the dynamic type of values, but don't run the target.",3927},3928};39293930OptionEnumValues lldb_private::GetDynamicValueTypes() {3931return OptionEnumValues(g_dynamic_value_types);3932}39333934static constexpr OptionEnumValueElement g_inline_breakpoint_enums[] = {3935{3936eInlineBreakpointsNever,3937"never",3938"Never look for inline breakpoint locations (fastest). This setting "3939"should only be used if you know that no inlining occurs in your"3940"programs.",3941},3942{3943eInlineBreakpointsHeaders,3944"headers",3945"Only check for inline breakpoint locations when setting breakpoints "3946"in header files, but not when setting breakpoint in implementation "3947"source files (default).",3948},3949{3950eInlineBreakpointsAlways,3951"always",3952"Always look for inline breakpoint locations when setting file and "3953"line breakpoints (slower but most accurate).",3954},3955};39563957enum x86DisassemblyFlavor {3958eX86DisFlavorDefault,3959eX86DisFlavorIntel,3960eX86DisFlavorATT3961};39623963static constexpr OptionEnumValueElement g_x86_dis_flavor_value_types[] = {3964{3965eX86DisFlavorDefault,3966"default",3967"Disassembler default (currently att).",3968},3969{3970eX86DisFlavorIntel,3971"intel",3972"Intel disassembler flavor.",3973},3974{3975eX86DisFlavorATT,3976"att",3977"AT&T disassembler flavor.",3978},3979};39803981static constexpr OptionEnumValueElement g_import_std_module_value_types[] = {3982{3983eImportStdModuleFalse,3984"false",3985"Never import the 'std' C++ module in the expression parser.",3986},3987{3988eImportStdModuleFallback,3989"fallback",3990"Retry evaluating expressions with an imported 'std' C++ module if they"3991" failed to parse without the module. This allows evaluating more "3992"complex expressions involving C++ standard library types."3993},3994{3995eImportStdModuleTrue,3996"true",3997"Always import the 'std' C++ module. This allows evaluating more "3998"complex expressions involving C++ standard library types. This feature"3999" is experimental."4000},4001};40024003static constexpr OptionEnumValueElement4004g_dynamic_class_info_helper_value_types[] = {4005{4006eDynamicClassInfoHelperAuto,4007"auto",4008"Automatically determine the most appropriate method for the "4009"target OS.",4010},4011{eDynamicClassInfoHelperRealizedClassesStruct, "RealizedClassesStruct",4012"Prefer using the realized classes struct."},4013{eDynamicClassInfoHelperCopyRealizedClassList, "CopyRealizedClassList",4014"Prefer using the CopyRealizedClassList API."},4015{eDynamicClassInfoHelperGetRealizedClassList, "GetRealizedClassList",4016"Prefer using the GetRealizedClassList API."},4017};40184019static constexpr OptionEnumValueElement g_hex_immediate_style_values[] = {4020{4021Disassembler::eHexStyleC,4022"c",4023"C-style (0xffff).",4024},4025{4026Disassembler::eHexStyleAsm,4027"asm",4028"Asm-style (0ffffh).",4029},4030};40314032static constexpr OptionEnumValueElement g_load_script_from_sym_file_values[] = {4033{4034eLoadScriptFromSymFileTrue,4035"true",4036"Load debug scripts inside symbol files",4037},4038{4039eLoadScriptFromSymFileFalse,4040"false",4041"Do not load debug scripts inside symbol files.",4042},4043{4044eLoadScriptFromSymFileWarn,4045"warn",4046"Warn about debug scripts inside symbol files but do not load them.",4047},4048};40494050static constexpr OptionEnumValueElement g_load_cwd_lldbinit_values[] = {4051{4052eLoadCWDlldbinitTrue,4053"true",4054"Load .lldbinit files from current directory",4055},4056{4057eLoadCWDlldbinitFalse,4058"false",4059"Do not load .lldbinit files from current directory",4060},4061{4062eLoadCWDlldbinitWarn,4063"warn",4064"Warn about loading .lldbinit files from current directory",4065},4066};40674068static constexpr OptionEnumValueElement g_memory_module_load_level_values[] = {4069{4070eMemoryModuleLoadLevelMinimal,4071"minimal",4072"Load minimal information when loading modules from memory. Currently "4073"this setting loads sections only.",4074},4075{4076eMemoryModuleLoadLevelPartial,4077"partial",4078"Load partial information when loading modules from memory. Currently "4079"this setting loads sections and function bounds.",4080},4081{4082eMemoryModuleLoadLevelComplete,4083"complete",4084"Load complete information when loading modules from memory. Currently "4085"this setting loads sections and all symbols.",4086},4087};40884089#define LLDB_PROPERTIES_target4090#include "TargetProperties.inc"40914092enum {4093#define LLDB_PROPERTIES_target4094#include "TargetPropertiesEnum.inc"4095ePropertyExperimental,4096};40974098class TargetOptionValueProperties4099: public Cloneable<TargetOptionValueProperties, OptionValueProperties> {4100public:4101TargetOptionValueProperties(llvm::StringRef name) : Cloneable(name) {}41024103const Property *4104GetPropertyAtIndex(size_t idx,4105const ExecutionContext *exe_ctx = nullptr) const override {4106// When getting the value for a key from the target options, we will always4107// try and grab the setting from the current target if there is one. Else4108// we just use the one from this instance.4109if (exe_ctx) {4110Target *target = exe_ctx->GetTargetPtr();4111if (target) {4112TargetOptionValueProperties *target_properties =4113static_cast<TargetOptionValueProperties *>(4114target->GetValueProperties().get());4115if (this != target_properties)4116return target_properties->ProtectedGetPropertyAtIndex(idx);4117}4118}4119return ProtectedGetPropertyAtIndex(idx);4120}4121};41224123// TargetProperties4124#define LLDB_PROPERTIES_target_experimental4125#include "TargetProperties.inc"41264127enum {4128#define LLDB_PROPERTIES_target_experimental4129#include "TargetPropertiesEnum.inc"4130};41314132class TargetExperimentalOptionValueProperties4133: public Cloneable<TargetExperimentalOptionValueProperties,4134OptionValueProperties> {4135public:4136TargetExperimentalOptionValueProperties()4137: Cloneable(Properties::GetExperimentalSettingsName()) {}4138};41394140TargetExperimentalProperties::TargetExperimentalProperties()4141: Properties(OptionValuePropertiesSP(4142new TargetExperimentalOptionValueProperties())) {4143m_collection_sp->Initialize(g_target_experimental_properties);4144}41454146// TargetProperties4147TargetProperties::TargetProperties(Target *target)4148: Properties(), m_launch_info(), m_target(target) {4149if (target) {4150m_collection_sp =4151OptionValueProperties::CreateLocalCopy(Target::GetGlobalProperties());41524153// Set callbacks to update launch_info whenever "settins set" updated any4154// of these properties4155m_collection_sp->SetValueChangedCallback(4156ePropertyArg0, [this] { Arg0ValueChangedCallback(); });4157m_collection_sp->SetValueChangedCallback(4158ePropertyRunArgs, [this] { RunArgsValueChangedCallback(); });4159m_collection_sp->SetValueChangedCallback(4160ePropertyEnvVars, [this] { EnvVarsValueChangedCallback(); });4161m_collection_sp->SetValueChangedCallback(4162ePropertyUnsetEnvVars, [this] { EnvVarsValueChangedCallback(); });4163m_collection_sp->SetValueChangedCallback(4164ePropertyInheritEnv, [this] { EnvVarsValueChangedCallback(); });4165m_collection_sp->SetValueChangedCallback(4166ePropertyInputPath, [this] { InputPathValueChangedCallback(); });4167m_collection_sp->SetValueChangedCallback(4168ePropertyOutputPath, [this] { OutputPathValueChangedCallback(); });4169m_collection_sp->SetValueChangedCallback(4170ePropertyErrorPath, [this] { ErrorPathValueChangedCallback(); });4171m_collection_sp->SetValueChangedCallback(ePropertyDetachOnError, [this] {4172DetachOnErrorValueChangedCallback();4173});4174m_collection_sp->SetValueChangedCallback(4175ePropertyDisableASLR, [this] { DisableASLRValueChangedCallback(); });4176m_collection_sp->SetValueChangedCallback(4177ePropertyInheritTCC, [this] { InheritTCCValueChangedCallback(); });4178m_collection_sp->SetValueChangedCallback(4179ePropertyDisableSTDIO, [this] { DisableSTDIOValueChangedCallback(); });41804181m_collection_sp->SetValueChangedCallback(4182ePropertySaveObjectsDir, [this] { CheckJITObjectsDir(); });4183m_experimental_properties_up =4184std::make_unique<TargetExperimentalProperties>();4185m_collection_sp->AppendProperty(4186Properties::GetExperimentalSettingsName(),4187"Experimental settings - setting these won't produce "4188"errors if the setting is not present.",4189true, m_experimental_properties_up->GetValueProperties());4190} else {4191m_collection_sp = std::make_shared<TargetOptionValueProperties>("target");4192m_collection_sp->Initialize(g_target_properties);4193m_experimental_properties_up =4194std::make_unique<TargetExperimentalProperties>();4195m_collection_sp->AppendProperty(4196Properties::GetExperimentalSettingsName(),4197"Experimental settings - setting these won't produce "4198"errors if the setting is not present.",4199true, m_experimental_properties_up->GetValueProperties());4200m_collection_sp->AppendProperty(4201"process", "Settings specific to processes.", true,4202Process::GetGlobalProperties().GetValueProperties());4203m_collection_sp->SetValueChangedCallback(4204ePropertySaveObjectsDir, [this] { CheckJITObjectsDir(); });4205}4206}42074208TargetProperties::~TargetProperties() = default;42094210void TargetProperties::UpdateLaunchInfoFromProperties() {4211Arg0ValueChangedCallback();4212RunArgsValueChangedCallback();4213EnvVarsValueChangedCallback();4214InputPathValueChangedCallback();4215OutputPathValueChangedCallback();4216ErrorPathValueChangedCallback();4217DetachOnErrorValueChangedCallback();4218DisableASLRValueChangedCallback();4219InheritTCCValueChangedCallback();4220DisableSTDIOValueChangedCallback();4221}42224223std::optional<bool> TargetProperties::GetExperimentalPropertyValue(4224size_t prop_idx, ExecutionContext *exe_ctx) const {4225const Property *exp_property =4226m_collection_sp->GetPropertyAtIndex(ePropertyExperimental, exe_ctx);4227OptionValueProperties *exp_values =4228exp_property->GetValue()->GetAsProperties();4229if (exp_values)4230return exp_values->GetPropertyAtIndexAs<bool>(prop_idx, exe_ctx);4231return std::nullopt;4232}42334234bool TargetProperties::GetInjectLocalVariables(4235ExecutionContext *exe_ctx) const {4236return GetExperimentalPropertyValue(ePropertyInjectLocalVars, exe_ctx)4237.value_or(true);4238}42394240ArchSpec TargetProperties::GetDefaultArchitecture() const {4241const uint32_t idx = ePropertyDefaultArch;4242return GetPropertyAtIndexAs<ArchSpec>(idx, {});4243}42444245void TargetProperties::SetDefaultArchitecture(const ArchSpec &arch) {4246const uint32_t idx = ePropertyDefaultArch;4247SetPropertyAtIndex(idx, arch);4248}42494250bool TargetProperties::GetMoveToNearestCode() const {4251const uint32_t idx = ePropertyMoveToNearestCode;4252return GetPropertyAtIndexAs<bool>(4253idx, g_target_properties[idx].default_uint_value != 0);4254}42554256lldb::DynamicValueType TargetProperties::GetPreferDynamicValue() const {4257const uint32_t idx = ePropertyPreferDynamic;4258return GetPropertyAtIndexAs<lldb::DynamicValueType>(4259idx, static_cast<lldb::DynamicValueType>(4260g_target_properties[idx].default_uint_value));4261}42624263bool TargetProperties::SetPreferDynamicValue(lldb::DynamicValueType d) {4264const uint32_t idx = ePropertyPreferDynamic;4265return SetPropertyAtIndex(idx, d);4266}42674268bool TargetProperties::GetPreloadSymbols() const {4269if (INTERRUPT_REQUESTED(m_target->GetDebugger(),4270"Interrupted checking preload symbols")) {4271return false;4272}4273const uint32_t idx = ePropertyPreloadSymbols;4274return GetPropertyAtIndexAs<bool>(4275idx, g_target_properties[idx].default_uint_value != 0);4276}42774278void TargetProperties::SetPreloadSymbols(bool b) {4279const uint32_t idx = ePropertyPreloadSymbols;4280SetPropertyAtIndex(idx, b);4281}42824283bool TargetProperties::GetDisableASLR() const {4284const uint32_t idx = ePropertyDisableASLR;4285return GetPropertyAtIndexAs<bool>(4286idx, g_target_properties[idx].default_uint_value != 0);4287}42884289void TargetProperties::SetDisableASLR(bool b) {4290const uint32_t idx = ePropertyDisableASLR;4291SetPropertyAtIndex(idx, b);4292}42934294bool TargetProperties::GetInheritTCC() const {4295const uint32_t idx = ePropertyInheritTCC;4296return GetPropertyAtIndexAs<bool>(4297idx, g_target_properties[idx].default_uint_value != 0);4298}42994300void TargetProperties::SetInheritTCC(bool b) {4301const uint32_t idx = ePropertyInheritTCC;4302SetPropertyAtIndex(idx, b);4303}43044305bool TargetProperties::GetDetachOnError() const {4306const uint32_t idx = ePropertyDetachOnError;4307return GetPropertyAtIndexAs<bool>(4308idx, g_target_properties[idx].default_uint_value != 0);4309}43104311void TargetProperties::SetDetachOnError(bool b) {4312const uint32_t idx = ePropertyDetachOnError;4313SetPropertyAtIndex(idx, b);4314}43154316bool TargetProperties::GetDisableSTDIO() const {4317const uint32_t idx = ePropertyDisableSTDIO;4318return GetPropertyAtIndexAs<bool>(4319idx, g_target_properties[idx].default_uint_value != 0);4320}43214322void TargetProperties::SetDisableSTDIO(bool b) {4323const uint32_t idx = ePropertyDisableSTDIO;4324SetPropertyAtIndex(idx, b);4325}43264327const char *TargetProperties::GetDisassemblyFlavor() const {4328const uint32_t idx = ePropertyDisassemblyFlavor;4329const char *return_value;43304331x86DisassemblyFlavor flavor_value =4332GetPropertyAtIndexAs<x86DisassemblyFlavor>(4333idx, static_cast<x86DisassemblyFlavor>(4334g_target_properties[idx].default_uint_value));43354336return_value = g_x86_dis_flavor_value_types[flavor_value].string_value;4337return return_value;4338}43394340InlineStrategy TargetProperties::GetInlineStrategy() const {4341const uint32_t idx = ePropertyInlineStrategy;4342return GetPropertyAtIndexAs<InlineStrategy>(4343idx,4344static_cast<InlineStrategy>(g_target_properties[idx].default_uint_value));4345}43464347llvm::StringRef TargetProperties::GetArg0() const {4348const uint32_t idx = ePropertyArg0;4349return GetPropertyAtIndexAs<llvm::StringRef>(4350idx, g_target_properties[idx].default_cstr_value);4351}43524353void TargetProperties::SetArg0(llvm::StringRef arg) {4354const uint32_t idx = ePropertyArg0;4355SetPropertyAtIndex(idx, arg);4356m_launch_info.SetArg0(arg);4357}43584359bool TargetProperties::GetRunArguments(Args &args) const {4360const uint32_t idx = ePropertyRunArgs;4361return m_collection_sp->GetPropertyAtIndexAsArgs(idx, args);4362}43634364void TargetProperties::SetRunArguments(const Args &args) {4365const uint32_t idx = ePropertyRunArgs;4366m_collection_sp->SetPropertyAtIndexFromArgs(idx, args);4367m_launch_info.GetArguments() = args;4368}43694370Environment TargetProperties::ComputeEnvironment() const {4371Environment env;43724373if (m_target &&4374GetPropertyAtIndexAs<bool>(4375ePropertyInheritEnv,4376g_target_properties[ePropertyInheritEnv].default_uint_value != 0)) {4377if (auto platform_sp = m_target->GetPlatform()) {4378Environment platform_env = platform_sp->GetEnvironment();4379for (const auto &KV : platform_env)4380env[KV.first()] = KV.second;4381}4382}43834384Args property_unset_env;4385m_collection_sp->GetPropertyAtIndexAsArgs(ePropertyUnsetEnvVars,4386property_unset_env);4387for (const auto &var : property_unset_env)4388env.erase(var.ref());43894390Args property_env;4391m_collection_sp->GetPropertyAtIndexAsArgs(ePropertyEnvVars, property_env);4392for (const auto &KV : Environment(property_env))4393env[KV.first()] = KV.second;43944395return env;4396}43974398Environment TargetProperties::GetEnvironment() const {4399return ComputeEnvironment();4400}44014402Environment TargetProperties::GetInheritedEnvironment() const {4403Environment environment;44044405if (m_target == nullptr)4406return environment;44074408if (!GetPropertyAtIndexAs<bool>(4409ePropertyInheritEnv,4410g_target_properties[ePropertyInheritEnv].default_uint_value != 0))4411return environment;44124413PlatformSP platform_sp = m_target->GetPlatform();4414if (platform_sp == nullptr)4415return environment;44164417Environment platform_environment = platform_sp->GetEnvironment();4418for (const auto &KV : platform_environment)4419environment[KV.first()] = KV.second;44204421Args property_unset_environment;4422m_collection_sp->GetPropertyAtIndexAsArgs(ePropertyUnsetEnvVars,4423property_unset_environment);4424for (const auto &var : property_unset_environment)4425environment.erase(var.ref());44264427return environment;4428}44294430Environment TargetProperties::GetTargetEnvironment() const {4431Args property_environment;4432m_collection_sp->GetPropertyAtIndexAsArgs(ePropertyEnvVars,4433property_environment);4434Environment environment;4435for (const auto &KV : Environment(property_environment))4436environment[KV.first()] = KV.second;44374438return environment;4439}44404441void TargetProperties::SetEnvironment(Environment env) {4442// TODO: Get rid of the Args intermediate step4443const uint32_t idx = ePropertyEnvVars;4444m_collection_sp->SetPropertyAtIndexFromArgs(idx, Args(env));4445}44464447bool TargetProperties::GetSkipPrologue() const {4448const uint32_t idx = ePropertySkipPrologue;4449return GetPropertyAtIndexAs<bool>(4450idx, g_target_properties[idx].default_uint_value != 0);4451}44524453PathMappingList &TargetProperties::GetSourcePathMap() const {4454const uint32_t idx = ePropertySourceMap;4455OptionValuePathMappings *option_value =4456m_collection_sp->GetPropertyAtIndexAsOptionValuePathMappings(idx);4457assert(option_value);4458return option_value->GetCurrentValue();4459}44604461bool TargetProperties::GetAutoSourceMapRelative() const {4462const uint32_t idx = ePropertyAutoSourceMapRelative;4463return GetPropertyAtIndexAs<bool>(4464idx, g_target_properties[idx].default_uint_value != 0);4465}44664467void TargetProperties::AppendExecutableSearchPaths(const FileSpec &dir) {4468const uint32_t idx = ePropertyExecutableSearchPaths;4469OptionValueFileSpecList *option_value =4470m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(idx);4471assert(option_value);4472option_value->AppendCurrentValue(dir);4473}44744475FileSpecList TargetProperties::GetExecutableSearchPaths() {4476const uint32_t idx = ePropertyExecutableSearchPaths;4477return GetPropertyAtIndexAs<FileSpecList>(idx, {});4478}44794480FileSpecList TargetProperties::GetDebugFileSearchPaths() {4481const uint32_t idx = ePropertyDebugFileSearchPaths;4482return GetPropertyAtIndexAs<FileSpecList>(idx, {});4483}44844485FileSpecList TargetProperties::GetClangModuleSearchPaths() {4486const uint32_t idx = ePropertyClangModuleSearchPaths;4487return GetPropertyAtIndexAs<FileSpecList>(idx, {});4488}44894490bool TargetProperties::GetEnableAutoImportClangModules() const {4491const uint32_t idx = ePropertyAutoImportClangModules;4492return GetPropertyAtIndexAs<bool>(4493idx, g_target_properties[idx].default_uint_value != 0);4494}44954496ImportStdModule TargetProperties::GetImportStdModule() const {4497const uint32_t idx = ePropertyImportStdModule;4498return GetPropertyAtIndexAs<ImportStdModule>(4499idx, static_cast<ImportStdModule>(4500g_target_properties[idx].default_uint_value));4501}45024503DynamicClassInfoHelper TargetProperties::GetDynamicClassInfoHelper() const {4504const uint32_t idx = ePropertyDynamicClassInfoHelper;4505return GetPropertyAtIndexAs<DynamicClassInfoHelper>(4506idx, static_cast<DynamicClassInfoHelper>(4507g_target_properties[idx].default_uint_value));4508}45094510bool TargetProperties::GetEnableAutoApplyFixIts() const {4511const uint32_t idx = ePropertyAutoApplyFixIts;4512return GetPropertyAtIndexAs<bool>(4513idx, g_target_properties[idx].default_uint_value != 0);4514}45154516uint64_t TargetProperties::GetNumberOfRetriesWithFixits() const {4517const uint32_t idx = ePropertyRetriesWithFixIts;4518return GetPropertyAtIndexAs<uint64_t>(4519idx, g_target_properties[idx].default_uint_value);4520}45214522bool TargetProperties::GetEnableNotifyAboutFixIts() const {4523const uint32_t idx = ePropertyNotifyAboutFixIts;4524return GetPropertyAtIndexAs<bool>(4525idx, g_target_properties[idx].default_uint_value != 0);4526}45274528FileSpec TargetProperties::GetSaveJITObjectsDir() const {4529const uint32_t idx = ePropertySaveObjectsDir;4530return GetPropertyAtIndexAs<FileSpec>(idx, {});4531}45324533void TargetProperties::CheckJITObjectsDir() {4534FileSpec new_dir = GetSaveJITObjectsDir();4535if (!new_dir)4536return;45374538const FileSystem &instance = FileSystem::Instance();4539bool exists = instance.Exists(new_dir);4540bool is_directory = instance.IsDirectory(new_dir);4541std::string path = new_dir.GetPath(true);4542bool writable = llvm::sys::fs::can_write(path);4543if (exists && is_directory && writable)4544return;45454546m_collection_sp->GetPropertyAtIndex(ePropertySaveObjectsDir)4547->GetValue()4548->Clear();45494550std::string buffer;4551llvm::raw_string_ostream os(buffer);4552os << "JIT object dir '" << path << "' ";4553if (!exists)4554os << "does not exist";4555else if (!is_directory)4556os << "is not a directory";4557else if (!writable)4558os << "is not writable";45594560std::optional<lldb::user_id_t> debugger_id;4561if (m_target)4562debugger_id = m_target->GetDebugger().GetID();4563Debugger::ReportError(os.str(), debugger_id);4564}45654566bool TargetProperties::GetEnableSyntheticValue() const {4567const uint32_t idx = ePropertyEnableSynthetic;4568return GetPropertyAtIndexAs<bool>(4569idx, g_target_properties[idx].default_uint_value != 0);4570}45714572bool TargetProperties::ShowHexVariableValuesWithLeadingZeroes() const {4573const uint32_t idx = ePropertyShowHexVariableValuesWithLeadingZeroes;4574return GetPropertyAtIndexAs<bool>(4575idx, g_target_properties[idx].default_uint_value != 0);4576}45774578uint32_t TargetProperties::GetMaxZeroPaddingInFloatFormat() const {4579const uint32_t idx = ePropertyMaxZeroPaddingInFloatFormat;4580return GetPropertyAtIndexAs<uint64_t>(4581idx, g_target_properties[idx].default_uint_value);4582}45834584uint32_t TargetProperties::GetMaximumNumberOfChildrenToDisplay() const {4585const uint32_t idx = ePropertyMaxChildrenCount;4586return GetPropertyAtIndexAs<int64_t>(4587idx, g_target_properties[idx].default_uint_value);4588}45894590std::pair<uint32_t, bool>4591TargetProperties::GetMaximumDepthOfChildrenToDisplay() const {4592const uint32_t idx = ePropertyMaxChildrenDepth;4593auto *option_value =4594m_collection_sp->GetPropertyAtIndexAsOptionValueUInt64(idx);4595bool is_default = !option_value->OptionWasSet();4596return {option_value->GetCurrentValue(), is_default};4597}45984599uint32_t TargetProperties::GetMaximumSizeOfStringSummary() const {4600const uint32_t idx = ePropertyMaxSummaryLength;4601return GetPropertyAtIndexAs<uint64_t>(4602idx, g_target_properties[idx].default_uint_value);4603}46044605uint32_t TargetProperties::GetMaximumMemReadSize() const {4606const uint32_t idx = ePropertyMaxMemReadSize;4607return GetPropertyAtIndexAs<uint64_t>(4608idx, g_target_properties[idx].default_uint_value);4609}46104611FileSpec TargetProperties::GetStandardInputPath() const {4612const uint32_t idx = ePropertyInputPath;4613return GetPropertyAtIndexAs<FileSpec>(idx, {});4614}46154616void TargetProperties::SetStandardInputPath(llvm::StringRef path) {4617const uint32_t idx = ePropertyInputPath;4618SetPropertyAtIndex(idx, path);4619}46204621FileSpec TargetProperties::GetStandardOutputPath() const {4622const uint32_t idx = ePropertyOutputPath;4623return GetPropertyAtIndexAs<FileSpec>(idx, {});4624}46254626void TargetProperties::SetStandardOutputPath(llvm::StringRef path) {4627const uint32_t idx = ePropertyOutputPath;4628SetPropertyAtIndex(idx, path);4629}46304631FileSpec TargetProperties::GetStandardErrorPath() const {4632const uint32_t idx = ePropertyErrorPath;4633return GetPropertyAtIndexAs<FileSpec>(idx, {});4634}46354636void TargetProperties::SetStandardErrorPath(llvm::StringRef path) {4637const uint32_t idx = ePropertyErrorPath;4638SetPropertyAtIndex(idx, path);4639}46404641SourceLanguage TargetProperties::GetLanguage() const {4642const uint32_t idx = ePropertyLanguage;4643return {GetPropertyAtIndexAs<LanguageType>(idx, {})};4644}46454646llvm::StringRef TargetProperties::GetExpressionPrefixContents() {4647const uint32_t idx = ePropertyExprPrefix;4648OptionValueFileSpec *file =4649m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpec(idx);4650if (file) {4651DataBufferSP data_sp(file->GetFileContents());4652if (data_sp)4653return llvm::StringRef(4654reinterpret_cast<const char *>(data_sp->GetBytes()),4655data_sp->GetByteSize());4656}4657return "";4658}46594660uint64_t TargetProperties::GetExprErrorLimit() const {4661const uint32_t idx = ePropertyExprErrorLimit;4662return GetPropertyAtIndexAs<uint64_t>(4663idx, g_target_properties[idx].default_uint_value);4664}46654666uint64_t TargetProperties::GetExprAllocAddress() const {4667const uint32_t idx = ePropertyExprAllocAddress;4668return GetPropertyAtIndexAs<uint64_t>(4669idx, g_target_properties[idx].default_uint_value);4670}46714672uint64_t TargetProperties::GetExprAllocSize() const {4673const uint32_t idx = ePropertyExprAllocSize;4674return GetPropertyAtIndexAs<uint64_t>(4675idx, g_target_properties[idx].default_uint_value);4676}46774678uint64_t TargetProperties::GetExprAllocAlign() const {4679const uint32_t idx = ePropertyExprAllocAlign;4680return GetPropertyAtIndexAs<uint64_t>(4681idx, g_target_properties[idx].default_uint_value);4682}46834684bool TargetProperties::GetBreakpointsConsultPlatformAvoidList() {4685const uint32_t idx = ePropertyBreakpointUseAvoidList;4686return GetPropertyAtIndexAs<bool>(4687idx, g_target_properties[idx].default_uint_value != 0);4688}46894690bool TargetProperties::GetUseHexImmediates() const {4691const uint32_t idx = ePropertyUseHexImmediates;4692return GetPropertyAtIndexAs<bool>(4693idx, g_target_properties[idx].default_uint_value != 0);4694}46954696bool TargetProperties::GetUseFastStepping() const {4697const uint32_t idx = ePropertyUseFastStepping;4698return GetPropertyAtIndexAs<bool>(4699idx, g_target_properties[idx].default_uint_value != 0);4700}47014702bool TargetProperties::GetDisplayExpressionsInCrashlogs() const {4703const uint32_t idx = ePropertyDisplayExpressionsInCrashlogs;4704return GetPropertyAtIndexAs<bool>(4705idx, g_target_properties[idx].default_uint_value != 0);4706}47074708LoadScriptFromSymFile TargetProperties::GetLoadScriptFromSymbolFile() const {4709const uint32_t idx = ePropertyLoadScriptFromSymbolFile;4710return GetPropertyAtIndexAs<LoadScriptFromSymFile>(4711idx, static_cast<LoadScriptFromSymFile>(4712g_target_properties[idx].default_uint_value));4713}47144715LoadCWDlldbinitFile TargetProperties::GetLoadCWDlldbinitFile() const {4716const uint32_t idx = ePropertyLoadCWDlldbinitFile;4717return GetPropertyAtIndexAs<LoadCWDlldbinitFile>(4718idx, static_cast<LoadCWDlldbinitFile>(4719g_target_properties[idx].default_uint_value));4720}47214722Disassembler::HexImmediateStyle TargetProperties::GetHexImmediateStyle() const {4723const uint32_t idx = ePropertyHexImmediateStyle;4724return GetPropertyAtIndexAs<Disassembler::HexImmediateStyle>(4725idx, static_cast<Disassembler::HexImmediateStyle>(4726g_target_properties[idx].default_uint_value));4727}47284729MemoryModuleLoadLevel TargetProperties::GetMemoryModuleLoadLevel() const {4730const uint32_t idx = ePropertyMemoryModuleLoadLevel;4731return GetPropertyAtIndexAs<MemoryModuleLoadLevel>(4732idx, static_cast<MemoryModuleLoadLevel>(4733g_target_properties[idx].default_uint_value));4734}47354736bool TargetProperties::GetUserSpecifiedTrapHandlerNames(Args &args) const {4737const uint32_t idx = ePropertyTrapHandlerNames;4738return m_collection_sp->GetPropertyAtIndexAsArgs(idx, args);4739}47404741void TargetProperties::SetUserSpecifiedTrapHandlerNames(const Args &args) {4742const uint32_t idx = ePropertyTrapHandlerNames;4743m_collection_sp->SetPropertyAtIndexFromArgs(idx, args);4744}47454746bool TargetProperties::GetDisplayRuntimeSupportValues() const {4747const uint32_t idx = ePropertyDisplayRuntimeSupportValues;4748return GetPropertyAtIndexAs<bool>(4749idx, g_target_properties[idx].default_uint_value != 0);4750}47514752void TargetProperties::SetDisplayRuntimeSupportValues(bool b) {4753const uint32_t idx = ePropertyDisplayRuntimeSupportValues;4754SetPropertyAtIndex(idx, b);4755}47564757bool TargetProperties::GetDisplayRecognizedArguments() const {4758const uint32_t idx = ePropertyDisplayRecognizedArguments;4759return GetPropertyAtIndexAs<bool>(4760idx, g_target_properties[idx].default_uint_value != 0);4761}47624763void TargetProperties::SetDisplayRecognizedArguments(bool b) {4764const uint32_t idx = ePropertyDisplayRecognizedArguments;4765SetPropertyAtIndex(idx, b);4766}47674768const ProcessLaunchInfo &TargetProperties::GetProcessLaunchInfo() const {4769return m_launch_info;4770}47714772void TargetProperties::SetProcessLaunchInfo(4773const ProcessLaunchInfo &launch_info) {4774m_launch_info = launch_info;4775SetArg0(launch_info.GetArg0());4776SetRunArguments(launch_info.GetArguments());4777SetEnvironment(launch_info.GetEnvironment());4778const FileAction *input_file_action =4779launch_info.GetFileActionForFD(STDIN_FILENO);4780if (input_file_action) {4781SetStandardInputPath(input_file_action->GetPath());4782}4783const FileAction *output_file_action =4784launch_info.GetFileActionForFD(STDOUT_FILENO);4785if (output_file_action) {4786SetStandardOutputPath(output_file_action->GetPath());4787}4788const FileAction *error_file_action =4789launch_info.GetFileActionForFD(STDERR_FILENO);4790if (error_file_action) {4791SetStandardErrorPath(error_file_action->GetPath());4792}4793SetDetachOnError(launch_info.GetFlags().Test(lldb::eLaunchFlagDetachOnError));4794SetDisableASLR(launch_info.GetFlags().Test(lldb::eLaunchFlagDisableASLR));4795SetInheritTCC(4796launch_info.GetFlags().Test(lldb::eLaunchFlagInheritTCCFromParent));4797SetDisableSTDIO(launch_info.GetFlags().Test(lldb::eLaunchFlagDisableSTDIO));4798}47994800bool TargetProperties::GetRequireHardwareBreakpoints() const {4801const uint32_t idx = ePropertyRequireHardwareBreakpoints;4802return GetPropertyAtIndexAs<bool>(4803idx, g_target_properties[idx].default_uint_value != 0);4804}48054806void TargetProperties::SetRequireHardwareBreakpoints(bool b) {4807const uint32_t idx = ePropertyRequireHardwareBreakpoints;4808m_collection_sp->SetPropertyAtIndex(idx, b);4809}48104811bool TargetProperties::GetAutoInstallMainExecutable() const {4812const uint32_t idx = ePropertyAutoInstallMainExecutable;4813return GetPropertyAtIndexAs<bool>(4814idx, g_target_properties[idx].default_uint_value != 0);4815}48164817void TargetProperties::Arg0ValueChangedCallback() {4818m_launch_info.SetArg0(GetArg0());4819}48204821void TargetProperties::RunArgsValueChangedCallback() {4822Args args;4823if (GetRunArguments(args))4824m_launch_info.GetArguments() = args;4825}48264827void TargetProperties::EnvVarsValueChangedCallback() {4828m_launch_info.GetEnvironment() = ComputeEnvironment();4829}48304831void TargetProperties::InputPathValueChangedCallback() {4832m_launch_info.AppendOpenFileAction(STDIN_FILENO, GetStandardInputPath(), true,4833false);4834}48354836void TargetProperties::OutputPathValueChangedCallback() {4837m_launch_info.AppendOpenFileAction(STDOUT_FILENO, GetStandardOutputPath(),4838false, true);4839}48404841void TargetProperties::ErrorPathValueChangedCallback() {4842m_launch_info.AppendOpenFileAction(STDERR_FILENO, GetStandardErrorPath(),4843false, true);4844}48454846void TargetProperties::DetachOnErrorValueChangedCallback() {4847if (GetDetachOnError())4848m_launch_info.GetFlags().Set(lldb::eLaunchFlagDetachOnError);4849else4850m_launch_info.GetFlags().Clear(lldb::eLaunchFlagDetachOnError);4851}48524853void TargetProperties::DisableASLRValueChangedCallback() {4854if (GetDisableASLR())4855m_launch_info.GetFlags().Set(lldb::eLaunchFlagDisableASLR);4856else4857m_launch_info.GetFlags().Clear(lldb::eLaunchFlagDisableASLR);4858}48594860void TargetProperties::InheritTCCValueChangedCallback() {4861if (GetInheritTCC())4862m_launch_info.GetFlags().Set(lldb::eLaunchFlagInheritTCCFromParent);4863else4864m_launch_info.GetFlags().Clear(lldb::eLaunchFlagInheritTCCFromParent);4865}48664867void TargetProperties::DisableSTDIOValueChangedCallback() {4868if (GetDisableSTDIO())4869m_launch_info.GetFlags().Set(lldb::eLaunchFlagDisableSTDIO);4870else4871m_launch_info.GetFlags().Clear(lldb::eLaunchFlagDisableSTDIO);4872}48734874bool TargetProperties::GetDebugUtilityExpression() const {4875const uint32_t idx = ePropertyDebugUtilityExpression;4876return GetPropertyAtIndexAs<bool>(4877idx, g_target_properties[idx].default_uint_value != 0);4878}48794880void TargetProperties::SetDebugUtilityExpression(bool debug) {4881const uint32_t idx = ePropertyDebugUtilityExpression;4882SetPropertyAtIndex(idx, debug);4883}48844885// Target::TargetEventData48864887Target::TargetEventData::TargetEventData(const lldb::TargetSP &target_sp)4888: EventData(), m_target_sp(target_sp), m_module_list() {}48894890Target::TargetEventData::TargetEventData(const lldb::TargetSP &target_sp,4891const ModuleList &module_list)4892: EventData(), m_target_sp(target_sp), m_module_list(module_list) {}48934894Target::TargetEventData::~TargetEventData() = default;48954896llvm::StringRef Target::TargetEventData::GetFlavorString() {4897return "Target::TargetEventData";4898}48994900void Target::TargetEventData::Dump(Stream *s) const {4901for (size_t i = 0; i < m_module_list.GetSize(); ++i) {4902if (i != 0)4903*s << ", ";4904m_module_list.GetModuleAtIndex(i)->GetDescription(4905s->AsRawOstream(), lldb::eDescriptionLevelBrief);4906}4907}49084909const Target::TargetEventData *4910Target::TargetEventData::GetEventDataFromEvent(const Event *event_ptr) {4911if (event_ptr) {4912const EventData *event_data = event_ptr->GetData();4913if (event_data &&4914event_data->GetFlavor() == TargetEventData::GetFlavorString())4915return static_cast<const TargetEventData *>(event_ptr->GetData());4916}4917return nullptr;4918}49194920TargetSP Target::TargetEventData::GetTargetFromEvent(const Event *event_ptr) {4921TargetSP target_sp;4922const TargetEventData *event_data = GetEventDataFromEvent(event_ptr);4923if (event_data)4924target_sp = event_data->m_target_sp;4925return target_sp;4926}49274928ModuleList4929Target::TargetEventData::GetModuleListFromEvent(const Event *event_ptr) {4930ModuleList module_list;4931const TargetEventData *event_data = GetEventDataFromEvent(event_ptr);4932if (event_data)4933module_list = event_data->m_module_list;4934return module_list;4935}49364937std::recursive_mutex &Target::GetAPIMutex() {4938if (GetProcessSP() && GetProcessSP()->CurrentThreadIsPrivateStateThread())4939return m_private_mutex;4940else4941return m_mutex;4942}49434944/// Get metrics associated with this target in JSON format.4945llvm::json::Value4946Target::ReportStatistics(const lldb_private::StatisticsOptions &options) {4947return m_stats.ToJSON(*this, options);4948}494949504951