1//===-- Target.cpp --------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "lldb/Target/Target.h"
10#include "lldb/Breakpoint/BreakpointIDList.h"
11#include "lldb/Breakpoint/BreakpointPrecondition.h"
12#include "lldb/Breakpoint/BreakpointResolver.h"
13#include "lldb/Breakpoint/BreakpointResolverAddress.h"
14#include "lldb/Breakpoint/BreakpointResolverFileLine.h"
15#include "lldb/Breakpoint/BreakpointResolverFileRegex.h"
16#include "lldb/Breakpoint/BreakpointResolverName.h"
17#include "lldb/Breakpoint/BreakpointResolverScripted.h"
18#include "lldb/Breakpoint/Watchpoint.h"
19#include "lldb/Core/Debugger.h"
20#include "lldb/Core/Module.h"
21#include "lldb/Core/ModuleSpec.h"
22#include "lldb/Core/PluginManager.h"
23#include "lldb/Core/SearchFilter.h"
24#include "lldb/Core/Section.h"
25#include "lldb/Core/SourceManager.h"
26#include "lldb/Core/StructuredDataImpl.h"
27#include "lldb/Core/ValueObject.h"
28#include "lldb/Core/ValueObjectConstResult.h"
29#include "lldb/Expression/DiagnosticManager.h"
30#include "lldb/Expression/ExpressionVariable.h"
31#include "lldb/Expression/REPL.h"
32#include "lldb/Expression/UserExpression.h"
33#include "lldb/Expression/UtilityFunction.h"
34#include "lldb/Host/Host.h"
35#include "lldb/Host/PosixApi.h"
36#include "lldb/Host/StreamFile.h"
37#include "lldb/Interpreter/CommandInterpreter.h"
38#include "lldb/Interpreter/CommandReturnObject.h"
39#include "lldb/Interpreter/OptionGroupWatchpoint.h"
40#include "lldb/Interpreter/OptionValues.h"
41#include "lldb/Interpreter/Property.h"
42#include "lldb/Symbol/Function.h"
43#include "lldb/Symbol/ObjectFile.h"
44#include "lldb/Symbol/Symbol.h"
45#include "lldb/Target/ABI.h"
46#include "lldb/Target/ExecutionContext.h"
47#include "lldb/Target/Language.h"
48#include "lldb/Target/LanguageRuntime.h"
49#include "lldb/Target/Process.h"
50#include "lldb/Target/RegisterTypeBuilder.h"
51#include "lldb/Target/SectionLoadList.h"
52#include "lldb/Target/StackFrame.h"
53#include "lldb/Target/StackFrameRecognizer.h"
54#include "lldb/Target/SystemRuntime.h"
55#include "lldb/Target/Thread.h"
56#include "lldb/Target/ThreadSpec.h"
57#include "lldb/Target/UnixSignals.h"
58#include "lldb/Utility/Event.h"
59#include "lldb/Utility/FileSpec.h"
60#include "lldb/Utility/LLDBAssert.h"
61#include "lldb/Utility/LLDBLog.h"
62#include "lldb/Utility/Log.h"
63#include "lldb/Utility/State.h"
64#include "lldb/Utility/StreamString.h"
65#include "lldb/Utility/Timer.h"
66
67#include "llvm/ADT/ScopeExit.h"
68#include "llvm/ADT/SetVector.h"
69
70#include <memory>
71#include <mutex>
72#include <optional>
73#include <sstream>
74
75using namespace lldb;
76using namespace lldb_private;
77
78constexpr std::chrono::milliseconds EvaluateExpressionOptions::default_timeout;
79
80Target::Arch::Arch(const ArchSpec &spec)
81 : m_spec(spec),
82 m_plugin_up(PluginManager::CreateArchitectureInstance(arch: spec)) {}
83
84const Target::Arch &Target::Arch::operator=(const ArchSpec &spec) {
85 m_spec = spec;
86 m_plugin_up = PluginManager::CreateArchitectureInstance(arch: spec);
87 return *this;
88}
89
90ConstString &Target::GetStaticBroadcasterClass() {
91 static ConstString class_name("lldb.target");
92 return class_name;
93}
94
95Target::Target(Debugger &debugger, const ArchSpec &target_arch,
96 const lldb::PlatformSP &platform_sp, bool is_dummy_target)
97 : TargetProperties(this),
98 Broadcaster(debugger.GetBroadcasterManager(),
99 Target::GetStaticBroadcasterClass().AsCString()),
100 ExecutionContextScope(), m_debugger(debugger), m_platform_sp(platform_sp),
101 m_mutex(), m_arch(target_arch), m_images(this), m_section_load_history(),
102 m_breakpoint_list(false), m_internal_breakpoint_list(true),
103 m_watchpoint_list(), m_process_sp(), m_search_filter_sp(),
104 m_image_search_paths(ImageSearchPathsChanged, this),
105 m_source_manager_up(), m_stop_hooks(), m_stop_hook_next_id(0),
106 m_latest_stop_hook_id(0), m_valid(true), m_suppress_stop_hooks(false),
107 m_is_dummy_target(is_dummy_target),
108 m_frame_recognizer_manager_up(
109 std::make_unique<StackFrameRecognizerManager>()) {
110 SetEventName(event_mask: eBroadcastBitBreakpointChanged, name: "breakpoint-changed");
111 SetEventName(event_mask: eBroadcastBitModulesLoaded, name: "modules-loaded");
112 SetEventName(event_mask: eBroadcastBitModulesUnloaded, name: "modules-unloaded");
113 SetEventName(event_mask: eBroadcastBitWatchpointChanged, name: "watchpoint-changed");
114 SetEventName(event_mask: eBroadcastBitSymbolsLoaded, name: "symbols-loaded");
115
116 CheckInWithManager();
117
118 LLDB_LOG(GetLog(LLDBLog::Object), "{0} Target::Target()",
119 static_cast<void *>(this));
120 if (target_arch.IsValid()) {
121 LLDB_LOG(GetLog(LLDBLog::Target),
122 "Target::Target created with architecture {0} ({1})",
123 target_arch.GetArchitectureName(),
124 target_arch.GetTriple().getTriple().c_str());
125 }
126
127 UpdateLaunchInfoFromProperties();
128}
129
130Target::~Target() {
131 Log *log = GetLog(mask: LLDBLog::Object);
132 LLDB_LOG(log, "{0} Target::~Target()", static_cast<void *>(this));
133 DeleteCurrentProcess();
134}
135
136void Target::PrimeFromDummyTarget(Target &target) {
137 m_stop_hooks = target.m_stop_hooks;
138
139 for (const auto &breakpoint_sp : target.m_breakpoint_list.Breakpoints()) {
140 if (breakpoint_sp->IsInternal())
141 continue;
142
143 BreakpointSP new_bp(
144 Breakpoint::CopyFromBreakpoint(new_target: shared_from_this(), bp_to_copy_from: *breakpoint_sp));
145 AddBreakpoint(breakpoint_sp: std::move(new_bp), internal: false);
146 }
147
148 for (const auto &bp_name_entry : target.m_breakpoint_names) {
149 AddBreakpointName(bp_name: std::make_unique<BreakpointName>(args&: *bp_name_entry.second));
150 }
151
152 m_frame_recognizer_manager_up = std::make_unique<StackFrameRecognizerManager>(
153 args&: *target.m_frame_recognizer_manager_up);
154
155 m_dummy_signals = target.m_dummy_signals;
156}
157
158void Target::Dump(Stream *s, lldb::DescriptionLevel description_level) {
159 // s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
160 if (description_level != lldb::eDescriptionLevelBrief) {
161 s->Indent();
162 s->PutCString(cstr: "Target\n");
163 s->IndentMore();
164 m_images.Dump(s);
165 m_breakpoint_list.Dump(s);
166 m_internal_breakpoint_list.Dump(s);
167 s->IndentLess();
168 } else {
169 Module *exe_module = GetExecutableModulePointer();
170 if (exe_module)
171 s->PutCString(cstr: exe_module->GetFileSpec().GetFilename().GetCString());
172 else
173 s->PutCString(cstr: "No executable module.");
174 }
175}
176
177void Target::CleanupProcess() {
178 // Do any cleanup of the target we need to do between process instances.
179 // NB It is better to do this before destroying the process in case the
180 // clean up needs some help from the process.
181 m_breakpoint_list.ClearAllBreakpointSites();
182 m_internal_breakpoint_list.ClearAllBreakpointSites();
183 ResetBreakpointHitCounts();
184 // Disable watchpoints just on the debugger side.
185 std::unique_lock<std::recursive_mutex> lock;
186 this->GetWatchpointList().GetListMutex(lock);
187 DisableAllWatchpoints(end_to_end: false);
188 ClearAllWatchpointHitCounts();
189 ClearAllWatchpointHistoricValues();
190 m_latest_stop_hook_id = 0;
191}
192
193void Target::DeleteCurrentProcess() {
194 if (m_process_sp) {
195 // We dispose any active tracing sessions on the current process
196 m_trace_sp.reset();
197 m_section_load_history.Clear();
198 if (m_process_sp->IsAlive())
199 m_process_sp->Destroy(force_kill: false);
200
201 m_process_sp->Finalize(destructing: false /* not destructing */);
202
203 CleanupProcess();
204
205 m_process_sp.reset();
206 }
207}
208
209const lldb::ProcessSP &Target::CreateProcess(ListenerSP listener_sp,
210 llvm::StringRef plugin_name,
211 const FileSpec *crash_file,
212 bool can_connect) {
213 if (!listener_sp)
214 listener_sp = GetDebugger().GetListener();
215 DeleteCurrentProcess();
216 m_process_sp = Process::FindPlugin(target_sp: shared_from_this(), plugin_name,
217 listener_sp, crash_file_path: crash_file, can_connect);
218 return m_process_sp;
219}
220
221const lldb::ProcessSP &Target::GetProcessSP() const { return m_process_sp; }
222
223lldb::REPLSP Target::GetREPL(Status &err, lldb::LanguageType language,
224 const char *repl_options, bool can_create) {
225 if (language == eLanguageTypeUnknown)
226 language = m_debugger.GetREPLLanguage();
227
228 if (language == eLanguageTypeUnknown) {
229 LanguageSet repl_languages = Language::GetLanguagesSupportingREPLs();
230
231 if (auto single_lang = repl_languages.GetSingularLanguage()) {
232 language = *single_lang;
233 } else if (repl_languages.Empty()) {
234 err.SetErrorString(
235 "LLDB isn't configured with REPL support for any languages.");
236 return REPLSP();
237 } else {
238 err.SetErrorString(
239 "Multiple possible REPL languages. Please specify a language.");
240 return REPLSP();
241 }
242 }
243
244 REPLMap::iterator pos = m_repl_map.find(x: language);
245
246 if (pos != m_repl_map.end()) {
247 return pos->second;
248 }
249
250 if (!can_create) {
251 err.SetErrorStringWithFormat(
252 "Couldn't find an existing REPL for %s, and can't create a new one",
253 Language::GetNameForLanguageType(language));
254 return lldb::REPLSP();
255 }
256
257 Debugger *const debugger = nullptr;
258 lldb::REPLSP ret = REPL::Create(Status&: err, language, debugger, target: this, repl_options);
259
260 if (ret) {
261 m_repl_map[language] = ret;
262 return m_repl_map[language];
263 }
264
265 if (err.Success()) {
266 err.SetErrorStringWithFormat("Couldn't create a REPL for %s",
267 Language::GetNameForLanguageType(language));
268 }
269
270 return lldb::REPLSP();
271}
272
273void Target::SetREPL(lldb::LanguageType language, lldb::REPLSP repl_sp) {
274 lldbassert(!m_repl_map.count(language));
275
276 m_repl_map[language] = repl_sp;
277}
278
279void Target::Destroy() {
280 std::lock_guard<std::recursive_mutex> guard(m_mutex);
281 m_valid = false;
282 DeleteCurrentProcess();
283 m_platform_sp.reset();
284 m_arch = ArchSpec();
285 ClearModules(delete_locations: true);
286 m_section_load_history.Clear();
287 const bool notify = false;
288 m_breakpoint_list.RemoveAll(notify);
289 m_internal_breakpoint_list.RemoveAll(notify);
290 m_last_created_breakpoint.reset();
291 m_watchpoint_list.RemoveAll(notify);
292 m_last_created_watchpoint.reset();
293 m_search_filter_sp.reset();
294 m_image_search_paths.Clear(notify);
295 m_stop_hooks.clear();
296 m_stop_hook_next_id = 0;
297 m_suppress_stop_hooks = false;
298 m_repl_map.clear();
299 Args signal_args;
300 ClearDummySignals(signal_names&: signal_args);
301}
302
303llvm::StringRef Target::GetABIName() const {
304 lldb::ABISP abi_sp;
305 if (m_process_sp)
306 abi_sp = m_process_sp->GetABI();
307 if (!abi_sp)
308 abi_sp = ABI::FindPlugin(process_sp: ProcessSP(), arch: GetArchitecture());
309 if (abi_sp)
310 return abi_sp->GetPluginName();
311 return {};
312}
313
314BreakpointList &Target::GetBreakpointList(bool internal) {
315 if (internal)
316 return m_internal_breakpoint_list;
317 else
318 return m_breakpoint_list;
319}
320
321const BreakpointList &Target::GetBreakpointList(bool internal) const {
322 if (internal)
323 return m_internal_breakpoint_list;
324 else
325 return m_breakpoint_list;
326}
327
328BreakpointSP Target::GetBreakpointByID(break_id_t break_id) {
329 BreakpointSP bp_sp;
330
331 if (LLDB_BREAK_ID_IS_INTERNAL(break_id))
332 bp_sp = m_internal_breakpoint_list.FindBreakpointByID(breakID: break_id);
333 else
334 bp_sp = m_breakpoint_list.FindBreakpointByID(breakID: break_id);
335
336 return bp_sp;
337}
338
339lldb::BreakpointSP
340lldb_private::Target::CreateBreakpointAtUserEntry(Status &error) {
341 ModuleSP main_module_sp = GetExecutableModule();
342 FileSpecList shared_lib_filter;
343 shared_lib_filter.Append(file: main_module_sp->GetFileSpec());
344 llvm::SetVector<std::string, std::vector<std::string>,
345 std::unordered_set<std::string>>
346 entryPointNamesSet;
347 for (LanguageType lang_type : Language::GetSupportedLanguages()) {
348 Language *lang = Language::FindPlugin(language: lang_type);
349 if (!lang) {
350 error.SetErrorString("Language not found\n");
351 return lldb::BreakpointSP();
352 }
353 std::string entryPointName = lang->GetUserEntryPointName().str();
354 if (!entryPointName.empty())
355 entryPointNamesSet.insert(X: entryPointName);
356 }
357 if (entryPointNamesSet.empty()) {
358 error.SetErrorString("No entry point name found\n");
359 return lldb::BreakpointSP();
360 }
361 BreakpointSP bp_sp = CreateBreakpoint(
362 containingModules: &shared_lib_filter,
363 /*containingSourceFiles=*/nullptr, func_names: entryPointNamesSet.takeVector(),
364 /*func_name_type_mask=*/eFunctionNameTypeFull,
365 /*language=*/eLanguageTypeUnknown,
366 /*offset=*/m_offset: 0,
367 /*skip_prologue=*/eLazyBoolNo,
368 /*internal=*/false,
369 /*hardware=*/request_hardware: false);
370 if (!bp_sp) {
371 error.SetErrorString("Breakpoint creation failed.\n");
372 return lldb::BreakpointSP();
373 }
374 bp_sp->SetOneShot(true);
375 return bp_sp;
376}
377
378BreakpointSP Target::CreateSourceRegexBreakpoint(
379 const FileSpecList *containingModules,
380 const FileSpecList *source_file_spec_list,
381 const std::unordered_set<std::string> &function_names,
382 RegularExpression source_regex, bool internal, bool hardware,
383 LazyBool move_to_nearest_code) {
384 SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList(
385 containingModules, containingSourceFiles: source_file_spec_list));
386 if (move_to_nearest_code == eLazyBoolCalculate)
387 move_to_nearest_code = GetMoveToNearestCode() ? eLazyBoolYes : eLazyBoolNo;
388 BreakpointResolverSP resolver_sp(new BreakpointResolverFileRegex(
389 nullptr, std::move(source_regex), function_names,
390 !static_cast<bool>(move_to_nearest_code)));
391
392 return CreateBreakpoint(filter_sp, resolver_sp, internal, request_hardware: hardware, resolve_indirect_symbols: true);
393}
394
395BreakpointSP Target::CreateBreakpoint(const FileSpecList *containingModules,
396 const FileSpec &file, uint32_t line_no,
397 uint32_t column, lldb::addr_t offset,
398 LazyBool check_inlines,
399 LazyBool skip_prologue, bool internal,
400 bool hardware,
401 LazyBool move_to_nearest_code) {
402 FileSpec remapped_file;
403 std::optional<llvm::StringRef> removed_prefix_opt =
404 GetSourcePathMap().ReverseRemapPath(file, fixed&: remapped_file);
405 if (!removed_prefix_opt)
406 remapped_file = file;
407
408 if (check_inlines == eLazyBoolCalculate) {
409 const InlineStrategy inline_strategy = GetInlineStrategy();
410 switch (inline_strategy) {
411 case eInlineBreakpointsNever:
412 check_inlines = eLazyBoolNo;
413 break;
414
415 case eInlineBreakpointsHeaders:
416 if (remapped_file.IsSourceImplementationFile())
417 check_inlines = eLazyBoolNo;
418 else
419 check_inlines = eLazyBoolYes;
420 break;
421
422 case eInlineBreakpointsAlways:
423 check_inlines = eLazyBoolYes;
424 break;
425 }
426 }
427 SearchFilterSP filter_sp;
428 if (check_inlines == eLazyBoolNo) {
429 // Not checking for inlines, we are looking only for matching compile units
430 FileSpecList compile_unit_list;
431 compile_unit_list.Append(file: remapped_file);
432 filter_sp = GetSearchFilterForModuleAndCUList(containingModules,
433 containingSourceFiles: &compile_unit_list);
434 } else {
435 filter_sp = GetSearchFilterForModuleList(containingModuleList: containingModules);
436 }
437 if (skip_prologue == eLazyBoolCalculate)
438 skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;
439 if (move_to_nearest_code == eLazyBoolCalculate)
440 move_to_nearest_code = GetMoveToNearestCode() ? eLazyBoolYes : eLazyBoolNo;
441
442 SourceLocationSpec location_spec(remapped_file, line_no, column,
443 check_inlines,
444 !static_cast<bool>(move_to_nearest_code));
445 if (!location_spec)
446 return nullptr;
447
448 BreakpointResolverSP resolver_sp(new BreakpointResolverFileLine(
449 nullptr, offset, skip_prologue, location_spec, removed_prefix_opt));
450 return CreateBreakpoint(filter_sp, resolver_sp, internal, request_hardware: hardware, resolve_indirect_symbols: true);
451}
452
453BreakpointSP Target::CreateBreakpoint(lldb::addr_t addr, bool internal,
454 bool hardware) {
455 Address so_addr;
456
457 // Check for any reason we want to move this breakpoint to other address.
458 addr = GetBreakableLoadAddress(addr);
459
460 // Attempt to resolve our load address if possible, though it is ok if it
461 // doesn't resolve to section/offset.
462
463 // Try and resolve as a load address if possible
464 GetSectionLoadList().ResolveLoadAddress(load_addr: addr, so_addr);
465 if (!so_addr.IsValid()) {
466 // The address didn't resolve, so just set this as an absolute address
467 so_addr.SetOffset(addr);
468 }
469 BreakpointSP bp_sp(CreateBreakpoint(addr: so_addr, internal, request_hardware: hardware));
470 return bp_sp;
471}
472
473BreakpointSP Target::CreateBreakpoint(const Address &addr, bool internal,
474 bool hardware) {
475 SearchFilterSP filter_sp(
476 new SearchFilterForUnconstrainedSearches(shared_from_this()));
477 BreakpointResolverSP resolver_sp(
478 new BreakpointResolverAddress(nullptr, addr));
479 return CreateBreakpoint(filter_sp, resolver_sp, internal, request_hardware: hardware, resolve_indirect_symbols: false);
480}
481
482lldb::BreakpointSP
483Target::CreateAddressInModuleBreakpoint(lldb::addr_t file_addr, bool internal,
484 const FileSpec &file_spec,
485 bool request_hardware) {
486 SearchFilterSP filter_sp(
487 new SearchFilterForUnconstrainedSearches(shared_from_this()));
488 BreakpointResolverSP resolver_sp(new BreakpointResolverAddress(
489 nullptr, file_addr, file_spec));
490 return CreateBreakpoint(filter_sp, resolver_sp, internal, request_hardware,
491 resolve_indirect_symbols: false);
492}
493
494BreakpointSP Target::CreateBreakpoint(
495 const FileSpecList *containingModules,
496 const FileSpecList *containingSourceFiles, const char *func_name,
497 FunctionNameType func_name_type_mask, LanguageType language,
498 lldb::addr_t offset, LazyBool skip_prologue, bool internal, bool hardware) {
499 BreakpointSP bp_sp;
500 if (func_name) {
501 SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList(
502 containingModules, containingSourceFiles));
503
504 if (skip_prologue == eLazyBoolCalculate)
505 skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;
506 if (language == lldb::eLanguageTypeUnknown)
507 language = GetLanguage();
508
509 BreakpointResolverSP resolver_sp(new BreakpointResolverName(
510 nullptr, func_name, func_name_type_mask, language, Breakpoint::Exact,
511 offset, skip_prologue));
512 bp_sp = CreateBreakpoint(filter_sp, resolver_sp, internal, request_hardware: hardware, resolve_indirect_symbols: true);
513 }
514 return bp_sp;
515}
516
517lldb::BreakpointSP
518Target::CreateBreakpoint(const FileSpecList *containingModules,
519 const FileSpecList *containingSourceFiles,
520 const std::vector<std::string> &func_names,
521 FunctionNameType func_name_type_mask,
522 LanguageType language, lldb::addr_t offset,
523 LazyBool skip_prologue, bool internal, bool hardware) {
524 BreakpointSP bp_sp;
525 size_t num_names = func_names.size();
526 if (num_names > 0) {
527 SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList(
528 containingModules, containingSourceFiles));
529
530 if (skip_prologue == eLazyBoolCalculate)
531 skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;
532 if (language == lldb::eLanguageTypeUnknown)
533 language = GetLanguage();
534
535 BreakpointResolverSP resolver_sp(
536 new BreakpointResolverName(nullptr, func_names, func_name_type_mask,
537 language, offset, skip_prologue));
538 bp_sp = CreateBreakpoint(filter_sp, resolver_sp, internal, request_hardware: hardware, resolve_indirect_symbols: true);
539 }
540 return bp_sp;
541}
542
543BreakpointSP
544Target::CreateBreakpoint(const FileSpecList *containingModules,
545 const FileSpecList *containingSourceFiles,
546 const char *func_names[], size_t num_names,
547 FunctionNameType func_name_type_mask,
548 LanguageType language, lldb::addr_t offset,
549 LazyBool skip_prologue, bool internal, bool hardware) {
550 BreakpointSP bp_sp;
551 if (num_names > 0) {
552 SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList(
553 containingModules, containingSourceFiles));
554
555 if (skip_prologue == eLazyBoolCalculate) {
556 if (offset == 0)
557 skip_prologue = GetSkipPrologue() ? eLazyBoolYes : eLazyBoolNo;
558 else
559 skip_prologue = eLazyBoolNo;
560 }
561 if (language == lldb::eLanguageTypeUnknown)
562 language = GetLanguage();
563
564 BreakpointResolverSP resolver_sp(new BreakpointResolverName(
565 nullptr, func_names, num_names, func_name_type_mask, language, offset,
566 skip_prologue));
567 resolver_sp->SetOffset(offset);
568 bp_sp = CreateBreakpoint(filter_sp, resolver_sp, internal, request_hardware: hardware, resolve_indirect_symbols: true);
569 }
570 return bp_sp;
571}
572
573SearchFilterSP
574Target::GetSearchFilterForModule(const FileSpec *containingModule) {
575 SearchFilterSP filter_sp;
576 if (containingModule != nullptr) {
577 // TODO: We should look into sharing module based search filters
578 // across many breakpoints like we do for the simple target based one
579 filter_sp = std::make_shared<SearchFilterByModule>(args: shared_from_this(),
580 args: *containingModule);
581 } else {
582 if (!m_search_filter_sp)
583 m_search_filter_sp =
584 std::make_shared<SearchFilterForUnconstrainedSearches>(
585 args: shared_from_this());
586 filter_sp = m_search_filter_sp;
587 }
588 return filter_sp;
589}
590
591SearchFilterSP
592Target::GetSearchFilterForModuleList(const FileSpecList *containingModules) {
593 SearchFilterSP filter_sp;
594 if (containingModules && containingModules->GetSize() != 0) {
595 // TODO: We should look into sharing module based search filters
596 // across many breakpoints like we do for the simple target based one
597 filter_sp = std::make_shared<SearchFilterByModuleList>(args: shared_from_this(),
598 args: *containingModules);
599 } else {
600 if (!m_search_filter_sp)
601 m_search_filter_sp =
602 std::make_shared<SearchFilterForUnconstrainedSearches>(
603 args: shared_from_this());
604 filter_sp = m_search_filter_sp;
605 }
606 return filter_sp;
607}
608
609SearchFilterSP Target::GetSearchFilterForModuleAndCUList(
610 const FileSpecList *containingModules,
611 const FileSpecList *containingSourceFiles) {
612 if (containingSourceFiles == nullptr || containingSourceFiles->GetSize() == 0)
613 return GetSearchFilterForModuleList(containingModules);
614
615 SearchFilterSP filter_sp;
616 if (containingModules == nullptr) {
617 // We could make a special "CU List only SearchFilter". Better yet was if
618 // these could be composable, but that will take a little reworking.
619
620 filter_sp = std::make_shared<SearchFilterByModuleListAndCU>(
621 args: shared_from_this(), args: FileSpecList(), args: *containingSourceFiles);
622 } else {
623 filter_sp = std::make_shared<SearchFilterByModuleListAndCU>(
624 args: shared_from_this(), args: *containingModules, args: *containingSourceFiles);
625 }
626 return filter_sp;
627}
628
629BreakpointSP Target::CreateFuncRegexBreakpoint(
630 const FileSpecList *containingModules,
631 const FileSpecList *containingSourceFiles, RegularExpression func_regex,
632 lldb::LanguageType requested_language, LazyBool skip_prologue,
633 bool internal, bool hardware) {
634 SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList(
635 containingModules, containingSourceFiles));
636 bool skip = (skip_prologue == eLazyBoolCalculate)
637 ? GetSkipPrologue()
638 : static_cast<bool>(skip_prologue);
639 BreakpointResolverSP resolver_sp(new BreakpointResolverName(
640 nullptr, std::move(func_regex), requested_language, 0, skip));
641
642 return CreateBreakpoint(filter_sp, resolver_sp, internal, request_hardware: hardware, resolve_indirect_symbols: true);
643}
644
645lldb::BreakpointSP
646Target::CreateExceptionBreakpoint(enum lldb::LanguageType language,
647 bool catch_bp, bool throw_bp, bool internal,
648 Args *additional_args, Status *error) {
649 BreakpointSP exc_bkpt_sp = LanguageRuntime::CreateExceptionBreakpoint(
650 target&: *this, language, catch_bp, throw_bp, is_internal: internal);
651 if (exc_bkpt_sp && additional_args) {
652 BreakpointPreconditionSP precondition_sp = exc_bkpt_sp->GetPrecondition();
653 if (precondition_sp && additional_args) {
654 if (error)
655 *error = precondition_sp->ConfigurePrecondition(args&: *additional_args);
656 else
657 precondition_sp->ConfigurePrecondition(args&: *additional_args);
658 }
659 }
660 return exc_bkpt_sp;
661}
662
663lldb::BreakpointSP Target::CreateScriptedBreakpoint(
664 const llvm::StringRef class_name, const FileSpecList *containingModules,
665 const FileSpecList *containingSourceFiles, bool internal,
666 bool request_hardware, StructuredData::ObjectSP extra_args_sp,
667 Status *creation_error) {
668 SearchFilterSP filter_sp;
669
670 lldb::SearchDepth depth = lldb::eSearchDepthTarget;
671 bool has_files =
672 containingSourceFiles && containingSourceFiles->GetSize() > 0;
673 bool has_modules = containingModules && containingModules->GetSize() > 0;
674
675 if (has_files && has_modules) {
676 filter_sp = GetSearchFilterForModuleAndCUList(containingModules,
677 containingSourceFiles);
678 } else if (has_files) {
679 filter_sp =
680 GetSearchFilterForModuleAndCUList(containingModules: nullptr, containingSourceFiles);
681 } else if (has_modules) {
682 filter_sp = GetSearchFilterForModuleList(containingModules);
683 } else {
684 filter_sp = std::make_shared<SearchFilterForUnconstrainedSearches>(
685 args: shared_from_this());
686 }
687
688 BreakpointResolverSP resolver_sp(new BreakpointResolverScripted(
689 nullptr, class_name, depth, StructuredDataImpl(extra_args_sp)));
690 return CreateBreakpoint(filter_sp, resolver_sp, internal, request_hardware: false, resolve_indirect_symbols: true);
691}
692
693BreakpointSP Target::CreateBreakpoint(SearchFilterSP &filter_sp,
694 BreakpointResolverSP &resolver_sp,
695 bool internal, bool request_hardware,
696 bool resolve_indirect_symbols) {
697 BreakpointSP bp_sp;
698 if (filter_sp && resolver_sp) {
699 const bool hardware = request_hardware || GetRequireHardwareBreakpoints();
700 bp_sp.reset(p: new Breakpoint(*this, filter_sp, resolver_sp, hardware,
701 resolve_indirect_symbols));
702 resolver_sp->SetBreakpoint(bp_sp);
703 AddBreakpoint(breakpoint_sp: bp_sp, internal);
704 }
705 return bp_sp;
706}
707
708void Target::AddBreakpoint(lldb::BreakpointSP bp_sp, bool internal) {
709 if (!bp_sp)
710 return;
711 if (internal)
712 m_internal_breakpoint_list.Add(bp_sp, notify: false);
713 else
714 m_breakpoint_list.Add(bp_sp, notify: true);
715
716 Log *log = GetLog(mask: LLDBLog::Breakpoints);
717 if (log) {
718 StreamString s;
719 bp_sp->GetDescription(s: &s, level: lldb::eDescriptionLevelVerbose);
720 LLDB_LOGF(log, "Target::%s (internal = %s) => break_id = %s\n",
721 __FUNCTION__, bp_sp->IsInternal() ? "yes" : "no", s.GetData());
722 }
723
724 bp_sp->ResolveBreakpoint();
725
726 if (!internal) {
727 m_last_created_breakpoint = bp_sp;
728 }
729}
730
731void Target::AddNameToBreakpoint(BreakpointID &id, llvm::StringRef name,
732 Status &error) {
733 BreakpointSP bp_sp =
734 m_breakpoint_list.FindBreakpointByID(breakID: id.GetBreakpointID());
735 if (!bp_sp) {
736 StreamString s;
737 id.GetDescription(s: &s, level: eDescriptionLevelBrief);
738 error.SetErrorStringWithFormat("Could not find breakpoint %s", s.GetData());
739 return;
740 }
741 AddNameToBreakpoint(bp_sp, name, error);
742}
743
744void Target::AddNameToBreakpoint(BreakpointSP &bp_sp, llvm::StringRef name,
745 Status &error) {
746 if (!bp_sp)
747 return;
748
749 BreakpointName *bp_name = FindBreakpointName(name: ConstString(name), can_create: true, error);
750 if (!bp_name)
751 return;
752
753 bp_name->ConfigureBreakpoint(bp_sp);
754 bp_sp->AddName(new_name: name);
755}
756
757void Target::AddBreakpointName(std::unique_ptr<BreakpointName> bp_name) {
758 m_breakpoint_names.insert(
759 x: std::make_pair(x: bp_name->GetName(), y: std::move(bp_name)));
760}
761
762BreakpointName *Target::FindBreakpointName(ConstString name, bool can_create,
763 Status &error) {
764 BreakpointID::StringIsBreakpointName(str: name.GetStringRef(), error);
765 if (!error.Success())
766 return nullptr;
767
768 BreakpointNameList::iterator iter = m_breakpoint_names.find(x: name);
769 if (iter != m_breakpoint_names.end()) {
770 return iter->second.get();
771 }
772
773 if (!can_create) {
774 error.SetErrorStringWithFormat("Breakpoint name \"%s\" doesn't exist and "
775 "can_create is false.",
776 name.AsCString());
777 return nullptr;
778 }
779
780 return m_breakpoint_names
781 .insert(x: std::make_pair(x&: name, y: std::make_unique<BreakpointName>(args&: name)))
782 .first->second.get();
783}
784
785void Target::DeleteBreakpointName(ConstString name) {
786 BreakpointNameList::iterator iter = m_breakpoint_names.find(x: name);
787
788 if (iter != m_breakpoint_names.end()) {
789 const char *name_cstr = name.AsCString();
790 m_breakpoint_names.erase(position: iter);
791 for (auto bp_sp : m_breakpoint_list.Breakpoints())
792 bp_sp->RemoveName(name_to_remove: name_cstr);
793 }
794}
795
796void Target::RemoveNameFromBreakpoint(lldb::BreakpointSP &bp_sp,
797 ConstString name) {
798 bp_sp->RemoveName(name_to_remove: name.AsCString());
799}
800
801void Target::ConfigureBreakpointName(
802 BreakpointName &bp_name, const BreakpointOptions &new_options,
803 const BreakpointName::Permissions &new_permissions) {
804 bp_name.GetOptions().CopyOverSetOptions(rhs: new_options);
805 bp_name.GetPermissions().MergeInto(incoming: new_permissions);
806 ApplyNameToBreakpoints(bp_name);
807}
808
809void Target::ApplyNameToBreakpoints(BreakpointName &bp_name) {
810 llvm::Expected<std::vector<BreakpointSP>> expected_vector =
811 m_breakpoint_list.FindBreakpointsByName(name: bp_name.GetName().AsCString());
812
813 if (!expected_vector) {
814 LLDB_LOG(GetLog(LLDBLog::Breakpoints), "invalid breakpoint name: {}",
815 llvm::toString(expected_vector.takeError()));
816 return;
817 }
818
819 for (auto bp_sp : *expected_vector)
820 bp_name.ConfigureBreakpoint(bp_sp);
821}
822
823void Target::GetBreakpointNames(std::vector<std::string> &names) {
824 names.clear();
825 for (const auto& bp_name_entry : m_breakpoint_names) {
826 names.push_back(x: bp_name_entry.first.AsCString());
827 }
828 llvm::sort(C&: names);
829}
830
831bool Target::ProcessIsValid() {
832 return (m_process_sp && m_process_sp->IsAlive());
833}
834
835static bool CheckIfWatchpointsSupported(Target *target, Status &error) {
836 std::optional<uint32_t> num_supported_hardware_watchpoints =
837 target->GetProcessSP()->GetWatchpointSlotCount();
838
839 // If unable to determine the # of watchpoints available,
840 // assume they are supported.
841 if (!num_supported_hardware_watchpoints)
842 return true;
843
844 if (num_supported_hardware_watchpoints == 0) {
845 error.SetErrorStringWithFormat(
846 "Target supports (%u) hardware watchpoint slots.\n",
847 *num_supported_hardware_watchpoints);
848 return false;
849 }
850 return true;
851}
852
853// See also Watchpoint::SetWatchpointType(uint32_t type) and the
854// OptionGroupWatchpoint::WatchType enum type.
855WatchpointSP Target::CreateWatchpoint(lldb::addr_t addr, size_t size,
856 const CompilerType *type, uint32_t kind,
857 Status &error) {
858 Log *log = GetLog(mask: LLDBLog::Watchpoints);
859 LLDB_LOGF(log,
860 "Target::%s (addr = 0x%8.8" PRIx64 " size = %" PRIu64
861 " type = %u)\n",
862 __FUNCTION__, addr, (uint64_t)size, kind);
863
864 WatchpointSP wp_sp;
865 if (!ProcessIsValid()) {
866 error.SetErrorString("process is not alive");
867 return wp_sp;
868 }
869
870 if (addr == LLDB_INVALID_ADDRESS || size == 0) {
871 if (size == 0)
872 error.SetErrorString("cannot set a watchpoint with watch_size of 0");
873 else
874 error.SetErrorStringWithFormat("invalid watch address: %" PRIu64, addr);
875 return wp_sp;
876 }
877
878 if (!LLDB_WATCH_TYPE_IS_VALID(kind)) {
879 error.SetErrorStringWithFormat("invalid watchpoint type: %d", kind);
880 }
881
882 if (!CheckIfWatchpointsSupported(target: this, error))
883 return wp_sp;
884
885 // Currently we only support one watchpoint per address, with total number of
886 // watchpoints limited by the hardware which the inferior is running on.
887
888 // Grab the list mutex while doing operations.
889 const bool notify = false; // Don't notify about all the state changes we do
890 // on creating the watchpoint.
891
892 // Mask off ignored bits from watchpoint address.
893 if (ABISP abi = m_process_sp->GetABI())
894 addr = abi->FixDataAddress(pc: addr);
895
896 // LWP_TODO this sequence is looking for an existing watchpoint
897 // at the exact same user-specified address, disables the new one
898 // if addr/size/type match. If type/size differ, disable old one.
899 // This isn't correct, we need both watchpoints to use a shared
900 // WatchpointResource in the target, and expand the WatchpointResource
901 // to handle the needs of both Watchpoints.
902 // Also, even if the addresses don't match, they may need to be
903 // supported by the same WatchpointResource, e.g. a watchpoint
904 // watching 1 byte at 0x102 and a watchpoint watching 1 byte at 0x103.
905 // They're in the same word and must be watched by a single hardware
906 // watchpoint register.
907
908 std::unique_lock<std::recursive_mutex> lock;
909 this->GetWatchpointList().GetListMutex(lock);
910 WatchpointSP matched_sp = m_watchpoint_list.FindByAddress(addr);
911 if (matched_sp) {
912 size_t old_size = matched_sp->GetByteSize();
913 uint32_t old_type =
914 (matched_sp->WatchpointRead() ? LLDB_WATCH_TYPE_READ : 0) |
915 (matched_sp->WatchpointWrite() ? LLDB_WATCH_TYPE_WRITE : 0) |
916 (matched_sp->WatchpointModify() ? LLDB_WATCH_TYPE_MODIFY : 0);
917 // Return the existing watchpoint if both size and type match.
918 if (size == old_size && kind == old_type) {
919 wp_sp = matched_sp;
920 wp_sp->SetEnabled(enabled: false, notify);
921 } else {
922 // Nil the matched watchpoint; we will be creating a new one.
923 m_process_sp->DisableWatchpoint(wp_sp: matched_sp, notify);
924 m_watchpoint_list.Remove(watchID: matched_sp->GetID(), notify: true);
925 }
926 }
927
928 if (!wp_sp) {
929 wp_sp = std::make_shared<Watchpoint>(args&: *this, args&: addr, args&: size, args&: type);
930 wp_sp->SetWatchpointType(type: kind, notify);
931 m_watchpoint_list.Add(wp_sp, notify: true);
932 }
933
934 error = m_process_sp->EnableWatchpoint(wp_sp, notify);
935 LLDB_LOGF(log, "Target::%s (creation of watchpoint %s with id = %u)\n",
936 __FUNCTION__, error.Success() ? "succeeded" : "failed",
937 wp_sp->GetID());
938
939 if (error.Fail()) {
940 // Enabling the watchpoint on the device side failed. Remove the said
941 // watchpoint from the list maintained by the target instance.
942 m_watchpoint_list.Remove(watchID: wp_sp->GetID(), notify: true);
943 wp_sp.reset();
944 } else
945 m_last_created_watchpoint = wp_sp;
946 return wp_sp;
947}
948
949void Target::RemoveAllowedBreakpoints() {
950 Log *log = GetLog(mask: LLDBLog::Breakpoints);
951 LLDB_LOGF(log, "Target::%s \n", __FUNCTION__);
952
953 m_breakpoint_list.RemoveAllowed(notify: true);
954
955 m_last_created_breakpoint.reset();
956}
957
958void Target::RemoveAllBreakpoints(bool internal_also) {
959 Log *log = GetLog(mask: LLDBLog::Breakpoints);
960 LLDB_LOGF(log, "Target::%s (internal_also = %s)\n", __FUNCTION__,
961 internal_also ? "yes" : "no");
962
963 m_breakpoint_list.RemoveAll(notify: true);
964 if (internal_also)
965 m_internal_breakpoint_list.RemoveAll(notify: false);
966
967 m_last_created_breakpoint.reset();
968}
969
970void Target::DisableAllBreakpoints(bool internal_also) {
971 Log *log = GetLog(mask: LLDBLog::Breakpoints);
972 LLDB_LOGF(log, "Target::%s (internal_also = %s)\n", __FUNCTION__,
973 internal_also ? "yes" : "no");
974
975 m_breakpoint_list.SetEnabledAll(false);
976 if (internal_also)
977 m_internal_breakpoint_list.SetEnabledAll(false);
978}
979
980void Target::DisableAllowedBreakpoints() {
981 Log *log = GetLog(mask: LLDBLog::Breakpoints);
982 LLDB_LOGF(log, "Target::%s", __FUNCTION__);
983
984 m_breakpoint_list.SetEnabledAllowed(false);
985}
986
987void Target::EnableAllBreakpoints(bool internal_also) {
988 Log *log = GetLog(mask: LLDBLog::Breakpoints);
989 LLDB_LOGF(log, "Target::%s (internal_also = %s)\n", __FUNCTION__,
990 internal_also ? "yes" : "no");
991
992 m_breakpoint_list.SetEnabledAll(true);
993 if (internal_also)
994 m_internal_breakpoint_list.SetEnabledAll(true);
995}
996
997void Target::EnableAllowedBreakpoints() {
998 Log *log = GetLog(mask: LLDBLog::Breakpoints);
999 LLDB_LOGF(log, "Target::%s", __FUNCTION__);
1000
1001 m_breakpoint_list.SetEnabledAllowed(true);
1002}
1003
1004bool Target::RemoveBreakpointByID(break_id_t break_id) {
1005 Log *log = GetLog(mask: LLDBLog::Breakpoints);
1006 LLDB_LOGF(log, "Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__,
1007 break_id, LLDB_BREAK_ID_IS_INTERNAL(break_id) ? "yes" : "no");
1008
1009 if (DisableBreakpointByID(break_id)) {
1010 if (LLDB_BREAK_ID_IS_INTERNAL(break_id))
1011 m_internal_breakpoint_list.Remove(breakID: break_id, notify: false);
1012 else {
1013 if (m_last_created_breakpoint) {
1014 if (m_last_created_breakpoint->GetID() == break_id)
1015 m_last_created_breakpoint.reset();
1016 }
1017 m_breakpoint_list.Remove(breakID: break_id, notify: true);
1018 }
1019 return true;
1020 }
1021 return false;
1022}
1023
1024bool Target::DisableBreakpointByID(break_id_t break_id) {
1025 Log *log = GetLog(mask: LLDBLog::Breakpoints);
1026 LLDB_LOGF(log, "Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__,
1027 break_id, LLDB_BREAK_ID_IS_INTERNAL(break_id) ? "yes" : "no");
1028
1029 BreakpointSP bp_sp;
1030
1031 if (LLDB_BREAK_ID_IS_INTERNAL(break_id))
1032 bp_sp = m_internal_breakpoint_list.FindBreakpointByID(breakID: break_id);
1033 else
1034 bp_sp = m_breakpoint_list.FindBreakpointByID(breakID: break_id);
1035 if (bp_sp) {
1036 bp_sp->SetEnabled(false);
1037 return true;
1038 }
1039 return false;
1040}
1041
1042bool Target::EnableBreakpointByID(break_id_t break_id) {
1043 Log *log = GetLog(mask: LLDBLog::Breakpoints);
1044 LLDB_LOGF(log, "Target::%s (break_id = %i, internal = %s)\n", __FUNCTION__,
1045 break_id, LLDB_BREAK_ID_IS_INTERNAL(break_id) ? "yes" : "no");
1046
1047 BreakpointSP bp_sp;
1048
1049 if (LLDB_BREAK_ID_IS_INTERNAL(break_id))
1050 bp_sp = m_internal_breakpoint_list.FindBreakpointByID(breakID: break_id);
1051 else
1052 bp_sp = m_breakpoint_list.FindBreakpointByID(breakID: break_id);
1053
1054 if (bp_sp) {
1055 bp_sp->SetEnabled(true);
1056 return true;
1057 }
1058 return false;
1059}
1060
1061void Target::ResetBreakpointHitCounts() {
1062 GetBreakpointList().ResetHitCounts();
1063}
1064
1065Status Target::SerializeBreakpointsToFile(const FileSpec &file,
1066 const BreakpointIDList &bp_ids,
1067 bool append) {
1068 Status error;
1069
1070 if (!file) {
1071 error.SetErrorString("Invalid FileSpec.");
1072 return error;
1073 }
1074
1075 std::string path(file.GetPath());
1076 StructuredData::ObjectSP input_data_sp;
1077
1078 StructuredData::ArraySP break_store_sp;
1079 StructuredData::Array *break_store_ptr = nullptr;
1080
1081 if (append) {
1082 input_data_sp = StructuredData::ParseJSONFromFile(file, error);
1083 if (error.Success()) {
1084 break_store_ptr = input_data_sp->GetAsArray();
1085 if (!break_store_ptr) {
1086 error.SetErrorStringWithFormat(
1087 "Tried to append to invalid input file %s", path.c_str());
1088 return error;
1089 }
1090 }
1091 }
1092
1093 if (!break_store_ptr) {
1094 break_store_sp = std::make_shared<StructuredData::Array>();
1095 break_store_ptr = break_store_sp.get();
1096 }
1097
1098 StreamFile out_file(path.c_str(),
1099 File::eOpenOptionTruncate | File::eOpenOptionWriteOnly |
1100 File::eOpenOptionCanCreate |
1101 File::eOpenOptionCloseOnExec,
1102 lldb::eFilePermissionsFileDefault);
1103 if (!out_file.GetFile().IsValid()) {
1104 error.SetErrorStringWithFormat("Unable to open output file: %s.",
1105 path.c_str());
1106 return error;
1107 }
1108
1109 std::unique_lock<std::recursive_mutex> lock;
1110 GetBreakpointList().GetListMutex(lock);
1111
1112 if (bp_ids.GetSize() == 0) {
1113 const BreakpointList &breakpoints = GetBreakpointList();
1114
1115 size_t num_breakpoints = breakpoints.GetSize();
1116 for (size_t i = 0; i < num_breakpoints; i++) {
1117 Breakpoint *bp = breakpoints.GetBreakpointAtIndex(i).get();
1118 StructuredData::ObjectSP bkpt_save_sp = bp->SerializeToStructuredData();
1119 // If a breakpoint can't serialize it, just ignore it for now:
1120 if (bkpt_save_sp)
1121 break_store_ptr->AddItem(item: bkpt_save_sp);
1122 }
1123 } else {
1124
1125 std::unordered_set<lldb::break_id_t> processed_bkpts;
1126 const size_t count = bp_ids.GetSize();
1127 for (size_t i = 0; i < count; ++i) {
1128 BreakpointID cur_bp_id = bp_ids.GetBreakpointIDAtIndex(index: i);
1129 lldb::break_id_t bp_id = cur_bp_id.GetBreakpointID();
1130
1131 if (bp_id != LLDB_INVALID_BREAK_ID) {
1132 // Only do each breakpoint once:
1133 std::pair<std::unordered_set<lldb::break_id_t>::iterator, bool>
1134 insert_result = processed_bkpts.insert(x: bp_id);
1135 if (!insert_result.second)
1136 continue;
1137
1138 Breakpoint *bp = GetBreakpointByID(break_id: bp_id).get();
1139 StructuredData::ObjectSP bkpt_save_sp = bp->SerializeToStructuredData();
1140 // If the user explicitly asked to serialize a breakpoint, and we
1141 // can't, then raise an error:
1142 if (!bkpt_save_sp) {
1143 error.SetErrorStringWithFormat("Unable to serialize breakpoint %d",
1144 bp_id);
1145 return error;
1146 }
1147 break_store_ptr->AddItem(item: bkpt_save_sp);
1148 }
1149 }
1150 }
1151
1152 break_store_ptr->Dump(s&: out_file, pretty_print: false);
1153 out_file.PutChar(ch: '\n');
1154 return error;
1155}
1156
1157Status Target::CreateBreakpointsFromFile(const FileSpec &file,
1158 BreakpointIDList &new_bps) {
1159 std::vector<std::string> no_names;
1160 return CreateBreakpointsFromFile(file, names&: no_names, new_bps);
1161}
1162
1163Status Target::CreateBreakpointsFromFile(const FileSpec &file,
1164 std::vector<std::string> &names,
1165 BreakpointIDList &new_bps) {
1166 std::unique_lock<std::recursive_mutex> lock;
1167 GetBreakpointList().GetListMutex(lock);
1168
1169 Status error;
1170 StructuredData::ObjectSP input_data_sp =
1171 StructuredData::ParseJSONFromFile(file, error);
1172 if (!error.Success()) {
1173 return error;
1174 } else if (!input_data_sp || !input_data_sp->IsValid()) {
1175 error.SetErrorStringWithFormat("Invalid JSON from input file: %s.",
1176 file.GetPath().c_str());
1177 return error;
1178 }
1179
1180 StructuredData::Array *bkpt_array = input_data_sp->GetAsArray();
1181 if (!bkpt_array) {
1182 error.SetErrorStringWithFormat(
1183 "Invalid breakpoint data from input file: %s.", file.GetPath().c_str());
1184 return error;
1185 }
1186
1187 size_t num_bkpts = bkpt_array->GetSize();
1188 size_t num_names = names.size();
1189
1190 for (size_t i = 0; i < num_bkpts; i++) {
1191 StructuredData::ObjectSP bkpt_object_sp = bkpt_array->GetItemAtIndex(idx: i);
1192 // Peel off the breakpoint key, and feed the rest to the Breakpoint:
1193 StructuredData::Dictionary *bkpt_dict = bkpt_object_sp->GetAsDictionary();
1194 if (!bkpt_dict) {
1195 error.SetErrorStringWithFormat(
1196 "Invalid breakpoint data for element %zu from input file: %s.", i,
1197 file.GetPath().c_str());
1198 return error;
1199 }
1200 StructuredData::ObjectSP bkpt_data_sp =
1201 bkpt_dict->GetValueForKey(key: Breakpoint::GetSerializationKey());
1202 if (num_names &&
1203 !Breakpoint::SerializedBreakpointMatchesNames(bkpt_object_sp&: bkpt_data_sp, names))
1204 continue;
1205
1206 BreakpointSP bkpt_sp = Breakpoint::CreateFromStructuredData(
1207 target_sp: shared_from_this(), data_object_sp&: bkpt_data_sp, error);
1208 if (!error.Success()) {
1209 error.SetErrorStringWithFormat(
1210 "Error restoring breakpoint %zu from %s: %s.", i,
1211 file.GetPath().c_str(), error.AsCString());
1212 return error;
1213 }
1214 new_bps.AddBreakpointID(bp_id: BreakpointID(bkpt_sp->GetID()));
1215 }
1216 return error;
1217}
1218
1219// The flag 'end_to_end', default to true, signifies that the operation is
1220// performed end to end, for both the debugger and the debuggee.
1221
1222// Assumption: Caller holds the list mutex lock for m_watchpoint_list for end
1223// to end operations.
1224bool Target::RemoveAllWatchpoints(bool end_to_end) {
1225 Log *log = GetLog(mask: LLDBLog::Watchpoints);
1226 LLDB_LOGF(log, "Target::%s\n", __FUNCTION__);
1227
1228 if (!end_to_end) {
1229 m_watchpoint_list.RemoveAll(notify: true);
1230 return true;
1231 }
1232
1233 // Otherwise, it's an end to end operation.
1234
1235 if (!ProcessIsValid())
1236 return false;
1237
1238 for (WatchpointSP wp_sp : m_watchpoint_list.Watchpoints()) {
1239 if (!wp_sp)
1240 return false;
1241
1242 Status rc = m_process_sp->DisableWatchpoint(wp_sp);
1243 if (rc.Fail())
1244 return false;
1245 }
1246 m_watchpoint_list.RemoveAll(notify: true);
1247 m_last_created_watchpoint.reset();
1248 return true; // Success!
1249}
1250
1251// Assumption: Caller holds the list mutex lock for m_watchpoint_list for end
1252// to end operations.
1253bool Target::DisableAllWatchpoints(bool end_to_end) {
1254 Log *log = GetLog(mask: LLDBLog::Watchpoints);
1255 LLDB_LOGF(log, "Target::%s\n", __FUNCTION__);
1256
1257 if (!end_to_end) {
1258 m_watchpoint_list.SetEnabledAll(false);
1259 return true;
1260 }
1261
1262 // Otherwise, it's an end to end operation.
1263
1264 if (!ProcessIsValid())
1265 return false;
1266
1267 for (WatchpointSP wp_sp : m_watchpoint_list.Watchpoints()) {
1268 if (!wp_sp)
1269 return false;
1270
1271 Status rc = m_process_sp->DisableWatchpoint(wp_sp);
1272 if (rc.Fail())
1273 return false;
1274 }
1275 return true; // Success!
1276}
1277
1278// Assumption: Caller holds the list mutex lock for m_watchpoint_list for end
1279// to end operations.
1280bool Target::EnableAllWatchpoints(bool end_to_end) {
1281 Log *log = GetLog(mask: LLDBLog::Watchpoints);
1282 LLDB_LOGF(log, "Target::%s\n", __FUNCTION__);
1283
1284 if (!end_to_end) {
1285 m_watchpoint_list.SetEnabledAll(true);
1286 return true;
1287 }
1288
1289 // Otherwise, it's an end to end operation.
1290
1291 if (!ProcessIsValid())
1292 return false;
1293
1294 for (WatchpointSP wp_sp : m_watchpoint_list.Watchpoints()) {
1295 if (!wp_sp)
1296 return false;
1297
1298 Status rc = m_process_sp->EnableWatchpoint(wp_sp);
1299 if (rc.Fail())
1300 return false;
1301 }
1302 return true; // Success!
1303}
1304
1305// Assumption: Caller holds the list mutex lock for m_watchpoint_list.
1306bool Target::ClearAllWatchpointHitCounts() {
1307 Log *log = GetLog(mask: LLDBLog::Watchpoints);
1308 LLDB_LOGF(log, "Target::%s\n", __FUNCTION__);
1309
1310 for (WatchpointSP wp_sp : m_watchpoint_list.Watchpoints()) {
1311 if (!wp_sp)
1312 return false;
1313
1314 wp_sp->ResetHitCount();
1315 }
1316 return true; // Success!
1317}
1318
1319// Assumption: Caller holds the list mutex lock for m_watchpoint_list.
1320bool Target::ClearAllWatchpointHistoricValues() {
1321 Log *log = GetLog(mask: LLDBLog::Watchpoints);
1322 LLDB_LOGF(log, "Target::%s\n", __FUNCTION__);
1323
1324 for (WatchpointSP wp_sp : m_watchpoint_list.Watchpoints()) {
1325 if (!wp_sp)
1326 return false;
1327
1328 wp_sp->ResetHistoricValues();
1329 }
1330 return true; // Success!
1331}
1332
1333// Assumption: Caller holds the list mutex lock for m_watchpoint_list during
1334// these operations.
1335bool Target::IgnoreAllWatchpoints(uint32_t ignore_count) {
1336 Log *log = GetLog(mask: LLDBLog::Watchpoints);
1337 LLDB_LOGF(log, "Target::%s\n", __FUNCTION__);
1338
1339 if (!ProcessIsValid())
1340 return false;
1341
1342 for (WatchpointSP wp_sp : m_watchpoint_list.Watchpoints()) {
1343 if (!wp_sp)
1344 return false;
1345
1346 wp_sp->SetIgnoreCount(ignore_count);
1347 }
1348 return true; // Success!
1349}
1350
1351// Assumption: Caller holds the list mutex lock for m_watchpoint_list.
1352bool Target::DisableWatchpointByID(lldb::watch_id_t watch_id) {
1353 Log *log = GetLog(mask: LLDBLog::Watchpoints);
1354 LLDB_LOGF(log, "Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);
1355
1356 if (!ProcessIsValid())
1357 return false;
1358
1359 WatchpointSP wp_sp = m_watchpoint_list.FindByID(watchID: watch_id);
1360 if (wp_sp) {
1361 Status rc = m_process_sp->DisableWatchpoint(wp_sp);
1362 if (rc.Success())
1363 return true;
1364
1365 // Else, fallthrough.
1366 }
1367 return false;
1368}
1369
1370// Assumption: Caller holds the list mutex lock for m_watchpoint_list.
1371bool Target::EnableWatchpointByID(lldb::watch_id_t watch_id) {
1372 Log *log = GetLog(mask: LLDBLog::Watchpoints);
1373 LLDB_LOGF(log, "Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);
1374
1375 if (!ProcessIsValid())
1376 return false;
1377
1378 WatchpointSP wp_sp = m_watchpoint_list.FindByID(watchID: watch_id);
1379 if (wp_sp) {
1380 Status rc = m_process_sp->EnableWatchpoint(wp_sp);
1381 if (rc.Success())
1382 return true;
1383
1384 // Else, fallthrough.
1385 }
1386 return false;
1387}
1388
1389// Assumption: Caller holds the list mutex lock for m_watchpoint_list.
1390bool Target::RemoveWatchpointByID(lldb::watch_id_t watch_id) {
1391 Log *log = GetLog(mask: LLDBLog::Watchpoints);
1392 LLDB_LOGF(log, "Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);
1393
1394 WatchpointSP watch_to_remove_sp = m_watchpoint_list.FindByID(watchID: watch_id);
1395 if (watch_to_remove_sp == m_last_created_watchpoint)
1396 m_last_created_watchpoint.reset();
1397
1398 if (DisableWatchpointByID(watch_id)) {
1399 m_watchpoint_list.Remove(watchID: watch_id, notify: true);
1400 return true;
1401 }
1402 return false;
1403}
1404
1405// Assumption: Caller holds the list mutex lock for m_watchpoint_list.
1406bool Target::IgnoreWatchpointByID(lldb::watch_id_t watch_id,
1407 uint32_t ignore_count) {
1408 Log *log = GetLog(mask: LLDBLog::Watchpoints);
1409 LLDB_LOGF(log, "Target::%s (watch_id = %i)\n", __FUNCTION__, watch_id);
1410
1411 if (!ProcessIsValid())
1412 return false;
1413
1414 WatchpointSP wp_sp = m_watchpoint_list.FindByID(watchID: watch_id);
1415 if (wp_sp) {
1416 wp_sp->SetIgnoreCount(ignore_count);
1417 return true;
1418 }
1419 return false;
1420}
1421
1422ModuleSP Target::GetExecutableModule() {
1423 // search for the first executable in the module list
1424 for (size_t i = 0; i < m_images.GetSize(); ++i) {
1425 ModuleSP module_sp = m_images.GetModuleAtIndex(idx: i);
1426 lldb_private::ObjectFile *obj = module_sp->GetObjectFile();
1427 if (obj == nullptr)
1428 continue;
1429 if (obj->GetType() == ObjectFile::Type::eTypeExecutable)
1430 return module_sp;
1431 }
1432 // as fall back return the first module loaded
1433 return m_images.GetModuleAtIndex(idx: 0);
1434}
1435
1436Module *Target::GetExecutableModulePointer() {
1437 return GetExecutableModule().get();
1438}
1439
1440static void LoadScriptingResourceForModule(const ModuleSP &module_sp,
1441 Target *target) {
1442 Status error;
1443 StreamString feedback_stream;
1444 if (module_sp && !module_sp->LoadScriptingResourceInTarget(target, error,
1445 feedback_stream)) {
1446 if (error.AsCString())
1447 target->GetDebugger().GetErrorStream().Printf(
1448 format: "unable to load scripting data for module %s - error reported was "
1449 "%s\n",
1450 module_sp->GetFileSpec().GetFileNameStrippingExtension().GetCString(),
1451 error.AsCString());
1452 }
1453 if (feedback_stream.GetSize())
1454 target->GetDebugger().GetErrorStream().Printf(format: "%s\n",
1455 feedback_stream.GetData());
1456}
1457
1458void Target::ClearModules(bool delete_locations) {
1459 ModulesDidUnload(module_list&: m_images, delete_locations);
1460 m_section_load_history.Clear();
1461 m_images.Clear();
1462 m_scratch_type_system_map.Clear();
1463}
1464
1465void Target::DidExec() {
1466 // When a process exec's we need to know about it so we can do some cleanup.
1467 m_breakpoint_list.RemoveInvalidLocations(arch: m_arch.GetSpec());
1468 m_internal_breakpoint_list.RemoveInvalidLocations(arch: m_arch.GetSpec());
1469}
1470
1471void Target::SetExecutableModule(ModuleSP &executable_sp,
1472 LoadDependentFiles load_dependent_files) {
1473 Log *log = GetLog(mask: LLDBLog::Target);
1474 ClearModules(delete_locations: false);
1475
1476 if (executable_sp) {
1477 ElapsedTime elapsed(m_stats.GetCreateTime());
1478 LLDB_SCOPED_TIMERF("Target::SetExecutableModule (executable = '%s')",
1479 executable_sp->GetFileSpec().GetPath().c_str());
1480
1481 const bool notify = true;
1482 m_images.Append(module_sp: executable_sp,
1483 notify); // The first image is our executable file
1484
1485 // If we haven't set an architecture yet, reset our architecture based on
1486 // what we found in the executable module.
1487 if (!m_arch.GetSpec().IsValid()) {
1488 m_arch = executable_sp->GetArchitecture();
1489 LLDB_LOG(log,
1490 "Target::SetExecutableModule setting architecture to {0} ({1}) "
1491 "based on executable file",
1492 m_arch.GetSpec().GetArchitectureName(),
1493 m_arch.GetSpec().GetTriple().getTriple());
1494 }
1495
1496 FileSpecList dependent_files;
1497 ObjectFile *executable_objfile = executable_sp->GetObjectFile();
1498 bool load_dependents = true;
1499 switch (load_dependent_files) {
1500 case eLoadDependentsDefault:
1501 load_dependents = executable_sp->IsExecutable();
1502 break;
1503 case eLoadDependentsYes:
1504 load_dependents = true;
1505 break;
1506 case eLoadDependentsNo:
1507 load_dependents = false;
1508 break;
1509 }
1510
1511 if (executable_objfile && load_dependents) {
1512 ModuleList added_modules;
1513 executable_objfile->GetDependentModules(file_list&: dependent_files);
1514 for (uint32_t i = 0; i < dependent_files.GetSize(); i++) {
1515 FileSpec dependent_file_spec(dependent_files.GetFileSpecAtIndex(idx: i));
1516 FileSpec platform_dependent_file_spec;
1517 if (m_platform_sp)
1518 m_platform_sp->GetFileWithUUID(platform_file: dependent_file_spec, uuid_ptr: nullptr,
1519 local_file&: platform_dependent_file_spec);
1520 else
1521 platform_dependent_file_spec = dependent_file_spec;
1522
1523 ModuleSpec module_spec(platform_dependent_file_spec, m_arch.GetSpec());
1524 ModuleSP image_module_sp(
1525 GetOrCreateModule(module_spec, notify: false /* notify */));
1526 if (image_module_sp) {
1527 added_modules.AppendIfNeeded(new_module: image_module_sp, notify: false);
1528 ObjectFile *objfile = image_module_sp->GetObjectFile();
1529 if (objfile)
1530 objfile->GetDependentModules(file_list&: dependent_files);
1531 }
1532 }
1533 ModulesDidLoad(module_list&: added_modules);
1534 }
1535 }
1536}
1537
1538bool Target::SetArchitecture(const ArchSpec &arch_spec, bool set_platform,
1539 bool merge) {
1540 Log *log = GetLog(mask: LLDBLog::Target);
1541 bool missing_local_arch = !m_arch.GetSpec().IsValid();
1542 bool replace_local_arch = true;
1543 bool compatible_local_arch = false;
1544 ArchSpec other(arch_spec);
1545
1546 // Changing the architecture might mean that the currently selected platform
1547 // isn't compatible. Set the platform correctly if we are asked to do so,
1548 // otherwise assume the user will set the platform manually.
1549 if (set_platform) {
1550 if (other.IsValid()) {
1551 auto platform_sp = GetPlatform();
1552 if (!platform_sp || !platform_sp->IsCompatibleArchitecture(
1553 arch: other, process_host_arch: {}, match: ArchSpec::CompatibleMatch, compatible_arch_ptr: nullptr)) {
1554 ArchSpec platform_arch;
1555 if (PlatformSP arch_platform_sp =
1556 GetDebugger().GetPlatformList().GetOrCreate(arch: other, process_host_arch: {},
1557 platform_arch_ptr: &platform_arch)) {
1558 SetPlatform(arch_platform_sp);
1559 if (platform_arch.IsValid())
1560 other = platform_arch;
1561 }
1562 }
1563 }
1564 }
1565
1566 if (!missing_local_arch) {
1567 if (merge && m_arch.GetSpec().IsCompatibleMatch(rhs: arch_spec)) {
1568 other.MergeFrom(other: m_arch.GetSpec());
1569
1570 if (m_arch.GetSpec().IsCompatibleMatch(rhs: other)) {
1571 compatible_local_arch = true;
1572
1573 if (m_arch.GetSpec().GetTriple() == other.GetTriple())
1574 replace_local_arch = false;
1575 }
1576 }
1577 }
1578
1579 if (compatible_local_arch || missing_local_arch) {
1580 // If we haven't got a valid arch spec, or the architectures are compatible
1581 // update the architecture, unless the one we already have is more
1582 // specified
1583 if (replace_local_arch)
1584 m_arch = other;
1585 LLDB_LOG(log,
1586 "Target::SetArchitecture merging compatible arch; arch "
1587 "is now {0} ({1})",
1588 m_arch.GetSpec().GetArchitectureName(),
1589 m_arch.GetSpec().GetTriple().getTriple());
1590 return true;
1591 }
1592
1593 // If we have an executable file, try to reset the executable to the desired
1594 // architecture
1595 LLDB_LOGF(
1596 log,
1597 "Target::SetArchitecture changing architecture to %s (%s) from %s (%s)",
1598 arch_spec.GetArchitectureName(),
1599 arch_spec.GetTriple().getTriple().c_str(),
1600 m_arch.GetSpec().GetArchitectureName(),
1601 m_arch.GetSpec().GetTriple().getTriple().c_str());
1602 m_arch = other;
1603 ModuleSP executable_sp = GetExecutableModule();
1604
1605 ClearModules(delete_locations: true);
1606 // Need to do something about unsetting breakpoints.
1607
1608 if (executable_sp) {
1609 LLDB_LOGF(log,
1610 "Target::SetArchitecture Trying to select executable file "
1611 "architecture %s (%s)",
1612 arch_spec.GetArchitectureName(),
1613 arch_spec.GetTriple().getTriple().c_str());
1614 ModuleSpec module_spec(executable_sp->GetFileSpec(), other);
1615 FileSpecList search_paths = GetExecutableSearchPaths();
1616 Status error = ModuleList::GetSharedModule(module_spec, module_sp&: executable_sp,
1617 module_search_paths_ptr: &search_paths, old_modules: nullptr, did_create_ptr: nullptr);
1618
1619 if (!error.Fail() && executable_sp) {
1620 SetExecutableModule(executable_sp, load_dependent_files: eLoadDependentsYes);
1621 return true;
1622 }
1623 }
1624 return false;
1625}
1626
1627bool Target::MergeArchitecture(const ArchSpec &arch_spec) {
1628 Log *log = GetLog(mask: LLDBLog::Target);
1629 if (arch_spec.IsValid()) {
1630 if (m_arch.GetSpec().IsCompatibleMatch(rhs: arch_spec)) {
1631 // The current target arch is compatible with "arch_spec", see if we can
1632 // improve our current architecture using bits from "arch_spec"
1633
1634 LLDB_LOGF(log,
1635 "Target::MergeArchitecture target has arch %s, merging with "
1636 "arch %s",
1637 m_arch.GetSpec().GetTriple().getTriple().c_str(),
1638 arch_spec.GetTriple().getTriple().c_str());
1639
1640 // Merge bits from arch_spec into "merged_arch" and set our architecture
1641 ArchSpec merged_arch(m_arch.GetSpec());
1642 merged_arch.MergeFrom(other: arch_spec);
1643 return SetArchitecture(arch_spec: merged_arch);
1644 } else {
1645 // The new architecture is different, we just need to replace it
1646 return SetArchitecture(arch_spec);
1647 }
1648 }
1649 return false;
1650}
1651
1652void Target::NotifyWillClearList(const ModuleList &module_list) {}
1653
1654void Target::NotifyModuleAdded(const ModuleList &module_list,
1655 const ModuleSP &module_sp) {
1656 // A module is being added to this target for the first time
1657 if (m_valid) {
1658 ModuleList my_module_list;
1659 my_module_list.Append(module_sp);
1660 ModulesDidLoad(module_list&: my_module_list);
1661 }
1662}
1663
1664void Target::NotifyModuleRemoved(const ModuleList &module_list,
1665 const ModuleSP &module_sp) {
1666 // A module is being removed from this target.
1667 if (m_valid) {
1668 ModuleList my_module_list;
1669 my_module_list.Append(module_sp);
1670 ModulesDidUnload(module_list&: my_module_list, delete_locations: false);
1671 }
1672}
1673
1674void Target::NotifyModuleUpdated(const ModuleList &module_list,
1675 const ModuleSP &old_module_sp,
1676 const ModuleSP &new_module_sp) {
1677 // A module is replacing an already added module
1678 if (m_valid) {
1679 m_breakpoint_list.UpdateBreakpointsWhenModuleIsReplaced(old_module_sp,
1680 new_module_sp);
1681 m_internal_breakpoint_list.UpdateBreakpointsWhenModuleIsReplaced(
1682 old_module_sp, new_module_sp);
1683 }
1684}
1685
1686void Target::NotifyModulesRemoved(lldb_private::ModuleList &module_list) {
1687 ModulesDidUnload(module_list, delete_locations: false);
1688}
1689
1690void Target::ModulesDidLoad(ModuleList &module_list) {
1691 const size_t num_images = module_list.GetSize();
1692 if (m_valid && num_images) {
1693 for (size_t idx = 0; idx < num_images; ++idx) {
1694 ModuleSP module_sp(module_list.GetModuleAtIndex(idx));
1695 LoadScriptingResourceForModule(module_sp, target: this);
1696 }
1697 m_breakpoint_list.UpdateBreakpoints(module_list, load: true, delete_locations: false);
1698 m_internal_breakpoint_list.UpdateBreakpoints(module_list, load: true, delete_locations: false);
1699 if (m_process_sp) {
1700 m_process_sp->ModulesDidLoad(module_list);
1701 }
1702 auto data_sp =
1703 std::make_shared<TargetEventData>(args: shared_from_this(), args&: module_list);
1704 BroadcastEvent(event_type: eBroadcastBitModulesLoaded, event_data_sp: data_sp);
1705 }
1706}
1707
1708void Target::SymbolsDidLoad(ModuleList &module_list) {
1709 if (m_valid && module_list.GetSize()) {
1710 if (m_process_sp) {
1711 for (LanguageRuntime *runtime : m_process_sp->GetLanguageRuntimes()) {
1712 runtime->SymbolsDidLoad(module_list);
1713 }
1714 }
1715
1716 m_breakpoint_list.UpdateBreakpoints(module_list, load: true, delete_locations: false);
1717 m_internal_breakpoint_list.UpdateBreakpoints(module_list, load: true, delete_locations: false);
1718 auto data_sp =
1719 std::make_shared<TargetEventData>(args: shared_from_this(), args&: module_list);
1720 BroadcastEvent(event_type: eBroadcastBitSymbolsLoaded, event_data_sp: data_sp);
1721 }
1722}
1723
1724void Target::ModulesDidUnload(ModuleList &module_list, bool delete_locations) {
1725 if (m_valid && module_list.GetSize()) {
1726 UnloadModuleSections(module_list);
1727 auto data_sp =
1728 std::make_shared<TargetEventData>(args: shared_from_this(), args&: module_list);
1729 BroadcastEvent(event_type: eBroadcastBitModulesUnloaded, event_data_sp: data_sp);
1730 m_breakpoint_list.UpdateBreakpoints(module_list, load: false, delete_locations);
1731 m_internal_breakpoint_list.UpdateBreakpoints(module_list, load: false,
1732 delete_locations);
1733
1734 // If a module was torn down it will have torn down the 'TypeSystemClang's
1735 // that we used as source 'ASTContext's for the persistent variables in
1736 // the current target. Those would now be unsafe to access because the
1737 // 'DeclOrigin' are now possibly stale. Thus clear all persistent
1738 // variables. We only want to flush 'TypeSystem's if the module being
1739 // unloaded was capable of describing a source type. JITted module unloads
1740 // happen frequently for Objective-C utility functions or the REPL and rely
1741 // on the persistent variables to stick around.
1742 const bool should_flush_type_systems =
1743 module_list.AnyOf(callback: [](lldb_private::Module &module) {
1744 auto *object_file = module.GetObjectFile();
1745
1746 if (!object_file)
1747 return false;
1748
1749 auto type = object_file->GetType();
1750
1751 // eTypeExecutable: when debugged binary was rebuilt
1752 // eTypeSharedLibrary: if dylib was re-loaded
1753 return module.FileHasChanged() &&
1754 (type == ObjectFile::eTypeObjectFile ||
1755 type == ObjectFile::eTypeExecutable ||
1756 type == ObjectFile::eTypeSharedLibrary);
1757 });
1758
1759 if (should_flush_type_systems)
1760 m_scratch_type_system_map.Clear();
1761 }
1762}
1763
1764bool Target::ModuleIsExcludedForUnconstrainedSearches(
1765 const FileSpec &module_file_spec) {
1766 if (GetBreakpointsConsultPlatformAvoidList()) {
1767 ModuleList matchingModules;
1768 ModuleSpec module_spec(module_file_spec);
1769 GetImages().FindModules(module_spec, matching_module_list&: matchingModules);
1770 size_t num_modules = matchingModules.GetSize();
1771
1772 // If there is more than one module for this file spec, only
1773 // return true if ALL the modules are on the black list.
1774 if (num_modules > 0) {
1775 for (size_t i = 0; i < num_modules; i++) {
1776 if (!ModuleIsExcludedForUnconstrainedSearches(
1777 module_sp: matchingModules.GetModuleAtIndex(idx: i)))
1778 return false;
1779 }
1780 return true;
1781 }
1782 }
1783 return false;
1784}
1785
1786bool Target::ModuleIsExcludedForUnconstrainedSearches(
1787 const lldb::ModuleSP &module_sp) {
1788 if (GetBreakpointsConsultPlatformAvoidList()) {
1789 if (m_platform_sp)
1790 return m_platform_sp->ModuleIsExcludedForUnconstrainedSearches(target&: *this,
1791 module_sp);
1792 }
1793 return false;
1794}
1795
1796size_t Target::ReadMemoryFromFileCache(const Address &addr, void *dst,
1797 size_t dst_len, Status &error) {
1798 SectionSP section_sp(addr.GetSection());
1799 if (section_sp) {
1800 // If the contents of this section are encrypted, the on-disk file is
1801 // unusable. Read only from live memory.
1802 if (section_sp->IsEncrypted()) {
1803 error.SetErrorString("section is encrypted");
1804 return 0;
1805 }
1806 ModuleSP module_sp(section_sp->GetModule());
1807 if (module_sp) {
1808 ObjectFile *objfile = section_sp->GetModule()->GetObjectFile();
1809 if (objfile) {
1810 size_t bytes_read = objfile->ReadSectionData(
1811 section: section_sp.get(), section_offset: addr.GetOffset(), dst, dst_len);
1812 if (bytes_read > 0)
1813 return bytes_read;
1814 else
1815 error.SetErrorStringWithFormat("error reading data from section %s",
1816 section_sp->GetName().GetCString());
1817 } else
1818 error.SetErrorString("address isn't from a object file");
1819 } else
1820 error.SetErrorString("address isn't in a module");
1821 } else
1822 error.SetErrorString("address doesn't contain a section that points to a "
1823 "section in a object file");
1824
1825 return 0;
1826}
1827
1828size_t Target::ReadMemory(const Address &addr, void *dst, size_t dst_len,
1829 Status &error, bool force_live_memory,
1830 lldb::addr_t *load_addr_ptr) {
1831 error.Clear();
1832
1833 Address fixed_addr = addr;
1834 if (ProcessIsValid())
1835 if (const ABISP &abi = m_process_sp->GetABI())
1836 fixed_addr.SetLoadAddress(load_addr: abi->FixAnyAddress(pc: addr.GetLoadAddress(target: this)),
1837 target: this);
1838
1839 // if we end up reading this from process memory, we will fill this with the
1840 // actual load address
1841 if (load_addr_ptr)
1842 *load_addr_ptr = LLDB_INVALID_ADDRESS;
1843
1844 size_t bytes_read = 0;
1845
1846 addr_t load_addr = LLDB_INVALID_ADDRESS;
1847 addr_t file_addr = LLDB_INVALID_ADDRESS;
1848 Address resolved_addr;
1849 if (!fixed_addr.IsSectionOffset()) {
1850 SectionLoadList &section_load_list = GetSectionLoadList();
1851 if (section_load_list.IsEmpty()) {
1852 // No sections are loaded, so we must assume we are not running yet and
1853 // anything we are given is a file address.
1854 file_addr =
1855 fixed_addr.GetOffset(); // "fixed_addr" doesn't have a section, so
1856 // its offset is the file address
1857 m_images.ResolveFileAddress(vm_addr: file_addr, so_addr&: resolved_addr);
1858 } else {
1859 // We have at least one section loaded. This can be because we have
1860 // manually loaded some sections with "target modules load ..." or
1861 // because we have a live process that has sections loaded through
1862 // the dynamic loader
1863 load_addr =
1864 fixed_addr.GetOffset(); // "fixed_addr" doesn't have a section, so
1865 // its offset is the load address
1866 section_load_list.ResolveLoadAddress(load_addr, so_addr&: resolved_addr);
1867 }
1868 }
1869 if (!resolved_addr.IsValid())
1870 resolved_addr = fixed_addr;
1871
1872 // If we read from the file cache but can't get as many bytes as requested,
1873 // we keep the result around in this buffer, in case this result is the
1874 // best we can do.
1875 std::unique_ptr<uint8_t[]> file_cache_read_buffer;
1876 size_t file_cache_bytes_read = 0;
1877
1878 // Read from file cache if read-only section.
1879 if (!force_live_memory && resolved_addr.IsSectionOffset()) {
1880 SectionSP section_sp(resolved_addr.GetSection());
1881 if (section_sp) {
1882 auto permissions = Flags(section_sp->GetPermissions());
1883 bool is_readonly = !permissions.Test(bit: ePermissionsWritable) &&
1884 permissions.Test(bit: ePermissionsReadable);
1885 if (is_readonly) {
1886 file_cache_bytes_read =
1887 ReadMemoryFromFileCache(addr: resolved_addr, dst, dst_len, error);
1888 if (file_cache_bytes_read == dst_len)
1889 return file_cache_bytes_read;
1890 else if (file_cache_bytes_read > 0) {
1891 file_cache_read_buffer =
1892 std::make_unique<uint8_t[]>(num: file_cache_bytes_read);
1893 std::memcpy(dest: file_cache_read_buffer.get(), src: dst, n: file_cache_bytes_read);
1894 }
1895 }
1896 }
1897 }
1898
1899 if (ProcessIsValid()) {
1900 if (load_addr == LLDB_INVALID_ADDRESS)
1901 load_addr = resolved_addr.GetLoadAddress(target: this);
1902
1903 if (load_addr == LLDB_INVALID_ADDRESS) {
1904 ModuleSP addr_module_sp(resolved_addr.GetModule());
1905 if (addr_module_sp && addr_module_sp->GetFileSpec())
1906 error.SetErrorStringWithFormatv(
1907 format: "{0:F}[{1:x+}] can't be resolved, {0:F} is not currently loaded",
1908 args: addr_module_sp->GetFileSpec(), args: resolved_addr.GetFileAddress());
1909 else
1910 error.SetErrorStringWithFormat("0x%" PRIx64 " can't be resolved",
1911 resolved_addr.GetFileAddress());
1912 } else {
1913 bytes_read = m_process_sp->ReadMemory(vm_addr: load_addr, buf: dst, size: dst_len, error);
1914 if (bytes_read != dst_len) {
1915 if (error.Success()) {
1916 if (bytes_read == 0)
1917 error.SetErrorStringWithFormat(
1918 "read memory from 0x%" PRIx64 " failed", load_addr);
1919 else
1920 error.SetErrorStringWithFormat(
1921 "only %" PRIu64 " of %" PRIu64
1922 " bytes were read from memory at 0x%" PRIx64,
1923 (uint64_t)bytes_read, (uint64_t)dst_len, load_addr);
1924 }
1925 }
1926 if (bytes_read) {
1927 if (load_addr_ptr)
1928 *load_addr_ptr = load_addr;
1929 return bytes_read;
1930 }
1931 }
1932 }
1933
1934 if (file_cache_read_buffer && file_cache_bytes_read > 0) {
1935 // Reading from the process failed. If we've previously succeeded in reading
1936 // something from the file cache, then copy that over and return that.
1937 std::memcpy(dest: dst, src: file_cache_read_buffer.get(), n: file_cache_bytes_read);
1938 return file_cache_bytes_read;
1939 }
1940
1941 if (!file_cache_read_buffer && resolved_addr.IsSectionOffset()) {
1942 // If we didn't already try and read from the object file cache, then try
1943 // it after failing to read from the process.
1944 return ReadMemoryFromFileCache(addr: resolved_addr, dst, dst_len, error);
1945 }
1946 return 0;
1947}
1948
1949size_t Target::ReadCStringFromMemory(const Address &addr, std::string &out_str,
1950 Status &error, bool force_live_memory) {
1951 char buf[256];
1952 out_str.clear();
1953 addr_t curr_addr = addr.GetLoadAddress(target: this);
1954 Address address(addr);
1955 while (true) {
1956 size_t length = ReadCStringFromMemory(addr: address, dst: buf, dst_max_len: sizeof(buf), result_error&: error,
1957 force_live_memory);
1958 if (length == 0)
1959 break;
1960 out_str.append(s: buf, n: length);
1961 // If we got "length - 1" bytes, we didn't get the whole C string, we need
1962 // to read some more characters
1963 if (length == sizeof(buf) - 1)
1964 curr_addr += length;
1965 else
1966 break;
1967 address = Address(curr_addr);
1968 }
1969 return out_str.size();
1970}
1971
1972size_t Target::ReadCStringFromMemory(const Address &addr, char *dst,
1973 size_t dst_max_len, Status &result_error,
1974 bool force_live_memory) {
1975 size_t total_cstr_len = 0;
1976 if (dst && dst_max_len) {
1977 result_error.Clear();
1978 // NULL out everything just to be safe
1979 memset(s: dst, c: 0, n: dst_max_len);
1980 Status error;
1981 addr_t curr_addr = addr.GetLoadAddress(target: this);
1982 Address address(addr);
1983
1984 // We could call m_process_sp->GetMemoryCacheLineSize() but I don't think
1985 // this really needs to be tied to the memory cache subsystem's cache line
1986 // size, so leave this as a fixed constant.
1987 const size_t cache_line_size = 512;
1988
1989 size_t bytes_left = dst_max_len - 1;
1990 char *curr_dst = dst;
1991
1992 while (bytes_left > 0) {
1993 addr_t cache_line_bytes_left =
1994 cache_line_size - (curr_addr % cache_line_size);
1995 addr_t bytes_to_read =
1996 std::min<addr_t>(a: bytes_left, b: cache_line_bytes_left);
1997 size_t bytes_read = ReadMemory(addr: address, dst: curr_dst, dst_len: bytes_to_read, error,
1998 force_live_memory);
1999
2000 if (bytes_read == 0) {
2001 result_error = error;
2002 dst[total_cstr_len] = '\0';
2003 break;
2004 }
2005 const size_t len = strlen(s: curr_dst);
2006
2007 total_cstr_len += len;
2008
2009 if (len < bytes_to_read)
2010 break;
2011
2012 curr_dst += bytes_read;
2013 curr_addr += bytes_read;
2014 bytes_left -= bytes_read;
2015 address = Address(curr_addr);
2016 }
2017 } else {
2018 if (dst == nullptr)
2019 result_error.SetErrorString("invalid arguments");
2020 else
2021 result_error.Clear();
2022 }
2023 return total_cstr_len;
2024}
2025
2026addr_t Target::GetReasonableReadSize(const Address &addr) {
2027 addr_t load_addr = addr.GetLoadAddress(target: this);
2028 if (load_addr != LLDB_INVALID_ADDRESS && m_process_sp) {
2029 // Avoid crossing cache line boundaries.
2030 addr_t cache_line_size = m_process_sp->GetMemoryCacheLineSize();
2031 return cache_line_size - (load_addr % cache_line_size);
2032 }
2033
2034 // The read is going to go to the file cache, so we can just pick a largish
2035 // value.
2036 return 0x1000;
2037}
2038
2039size_t Target::ReadStringFromMemory(const Address &addr, char *dst,
2040 size_t max_bytes, Status &error,
2041 size_t type_width, bool force_live_memory) {
2042 if (!dst || !max_bytes || !type_width || max_bytes < type_width)
2043 return 0;
2044
2045 size_t total_bytes_read = 0;
2046
2047 // Ensure a null terminator independent of the number of bytes that is
2048 // read.
2049 memset(s: dst, c: 0, n: max_bytes);
2050 size_t bytes_left = max_bytes - type_width;
2051
2052 const char terminator[4] = {'\0', '\0', '\0', '\0'};
2053 assert(sizeof(terminator) >= type_width && "Attempting to validate a "
2054 "string with more than 4 bytes "
2055 "per character!");
2056
2057 Address address = addr;
2058 char *curr_dst = dst;
2059
2060 error.Clear();
2061 while (bytes_left > 0 && error.Success()) {
2062 addr_t bytes_to_read =
2063 std::min<addr_t>(a: bytes_left, b: GetReasonableReadSize(addr: address));
2064 size_t bytes_read =
2065 ReadMemory(addr: address, dst: curr_dst, dst_len: bytes_to_read, error, force_live_memory);
2066
2067 if (bytes_read == 0)
2068 break;
2069
2070 // Search for a null terminator of correct size and alignment in
2071 // bytes_read
2072 size_t aligned_start = total_bytes_read - total_bytes_read % type_width;
2073 for (size_t i = aligned_start;
2074 i + type_width <= total_bytes_read + bytes_read; i += type_width)
2075 if (::memcmp(s1: &dst[i], s2: terminator, n: type_width) == 0) {
2076 error.Clear();
2077 return i;
2078 }
2079
2080 total_bytes_read += bytes_read;
2081 curr_dst += bytes_read;
2082 address.Slide(offset: bytes_read);
2083 bytes_left -= bytes_read;
2084 }
2085 return total_bytes_read;
2086}
2087
2088size_t Target::ReadScalarIntegerFromMemory(const Address &addr, uint32_t byte_size,
2089 bool is_signed, Scalar &scalar,
2090 Status &error,
2091 bool force_live_memory) {
2092 uint64_t uval;
2093
2094 if (byte_size <= sizeof(uval)) {
2095 size_t bytes_read =
2096 ReadMemory(addr, dst: &uval, dst_len: byte_size, error, force_live_memory);
2097 if (bytes_read == byte_size) {
2098 DataExtractor data(&uval, sizeof(uval), m_arch.GetSpec().GetByteOrder(),
2099 m_arch.GetSpec().GetAddressByteSize());
2100 lldb::offset_t offset = 0;
2101 if (byte_size <= 4)
2102 scalar = data.GetMaxU32(offset_ptr: &offset, byte_size);
2103 else
2104 scalar = data.GetMaxU64(offset_ptr: &offset, byte_size);
2105
2106 if (is_signed)
2107 scalar.SignExtend(bit_pos: byte_size * 8);
2108 return bytes_read;
2109 }
2110 } else {
2111 error.SetErrorStringWithFormat(
2112 "byte size of %u is too large for integer scalar type", byte_size);
2113 }
2114 return 0;
2115}
2116
2117uint64_t Target::ReadUnsignedIntegerFromMemory(const Address &addr,
2118 size_t integer_byte_size,
2119 uint64_t fail_value, Status &error,
2120 bool force_live_memory) {
2121 Scalar scalar;
2122 if (ReadScalarIntegerFromMemory(addr, byte_size: integer_byte_size, is_signed: false, scalar, error,
2123 force_live_memory))
2124 return scalar.ULongLong(fail_value);
2125 return fail_value;
2126}
2127
2128bool Target::ReadPointerFromMemory(const Address &addr, Status &error,
2129 Address &pointer_addr,
2130 bool force_live_memory) {
2131 Scalar scalar;
2132 if (ReadScalarIntegerFromMemory(addr, byte_size: m_arch.GetSpec().GetAddressByteSize(),
2133 is_signed: false, scalar, error, force_live_memory)) {
2134 addr_t pointer_vm_addr = scalar.ULongLong(LLDB_INVALID_ADDRESS);
2135 if (pointer_vm_addr != LLDB_INVALID_ADDRESS) {
2136 SectionLoadList &section_load_list = GetSectionLoadList();
2137 if (section_load_list.IsEmpty()) {
2138 // No sections are loaded, so we must assume we are not running yet and
2139 // anything we are given is a file address.
2140 m_images.ResolveFileAddress(vm_addr: pointer_vm_addr, so_addr&: pointer_addr);
2141 } else {
2142 // We have at least one section loaded. This can be because we have
2143 // manually loaded some sections with "target modules load ..." or
2144 // because we have a live process that has sections loaded through
2145 // the dynamic loader
2146 section_load_list.ResolveLoadAddress(load_addr: pointer_vm_addr, so_addr&: pointer_addr);
2147 }
2148 // We weren't able to resolve the pointer value, so just return an
2149 // address with no section
2150 if (!pointer_addr.IsValid())
2151 pointer_addr.SetOffset(pointer_vm_addr);
2152 return true;
2153 }
2154 }
2155 return false;
2156}
2157
2158ModuleSP Target::GetOrCreateModule(const ModuleSpec &module_spec, bool notify,
2159 Status *error_ptr) {
2160 ModuleSP module_sp;
2161
2162 Status error;
2163
2164 // First see if we already have this module in our module list. If we do,
2165 // then we're done, we don't need to consult the shared modules list. But
2166 // only do this if we are passed a UUID.
2167
2168 if (module_spec.GetUUID().IsValid())
2169 module_sp = m_images.FindFirstModule(module_spec);
2170
2171 if (!module_sp) {
2172 llvm::SmallVector<ModuleSP, 1>
2173 old_modules; // This will get filled in if we have a new version
2174 // of the library
2175 bool did_create_module = false;
2176 FileSpecList search_paths = GetExecutableSearchPaths();
2177 FileSpec symbol_file_spec;
2178
2179 // Call locate module callback if set. This allows users to implement their
2180 // own module cache system. For example, to leverage build system artifacts,
2181 // to bypass pulling files from remote platform, or to search symbol files
2182 // from symbol servers.
2183 if (m_platform_sp)
2184 m_platform_sp->CallLocateModuleCallbackIfSet(
2185 module_spec, module_sp, symbol_file_spec, did_create_ptr: &did_create_module);
2186
2187 // The result of this CallLocateModuleCallbackIfSet is one of the following.
2188 // 1. module_sp:loaded, symbol_file_spec:set
2189 // The callback found a module file and a symbol file for the
2190 // module_spec. We will call module_sp->SetSymbolFileFileSpec with
2191 // the symbol_file_spec later.
2192 // 2. module_sp:loaded, symbol_file_spec:empty
2193 // The callback only found a module file for the module_spec.
2194 // 3. module_sp:empty, symbol_file_spec:set
2195 // The callback only found a symbol file for the module. We continue
2196 // to find a module file for this module_spec and we will call
2197 // module_sp->SetSymbolFileFileSpec with the symbol_file_spec later.
2198 // 4. module_sp:empty, symbol_file_spec:empty
2199 // Platform does not exist, the callback is not set, the callback did
2200 // not find any module files nor any symbol files, the callback failed,
2201 // or something went wrong. We continue to find a module file for this
2202 // module_spec.
2203
2204 if (!module_sp) {
2205 // If there are image search path entries, try to use them to acquire a
2206 // suitable image.
2207 if (m_image_search_paths.GetSize()) {
2208 ModuleSpec transformed_spec(module_spec);
2209 ConstString transformed_dir;
2210 if (m_image_search_paths.RemapPath(
2211 path: module_spec.GetFileSpec().GetDirectory(), new_path&: transformed_dir)) {
2212 transformed_spec.GetFileSpec().SetDirectory(transformed_dir);
2213 transformed_spec.GetFileSpec().SetFilename(
2214 module_spec.GetFileSpec().GetFilename());
2215 error = ModuleList::GetSharedModule(module_spec: transformed_spec, module_sp,
2216 module_search_paths_ptr: &search_paths, old_modules: &old_modules,
2217 did_create_ptr: &did_create_module);
2218 }
2219 }
2220 }
2221
2222 if (!module_sp) {
2223 // If we have a UUID, we can check our global shared module list in case
2224 // we already have it. If we don't have a valid UUID, then we can't since
2225 // the path in "module_spec" will be a platform path, and we will need to
2226 // let the platform find that file. For example, we could be asking for
2227 // "/usr/lib/dyld" and if we do not have a UUID, we don't want to pick
2228 // the local copy of "/usr/lib/dyld" since our platform could be a remote
2229 // platform that has its own "/usr/lib/dyld" in an SDK or in a local file
2230 // cache.
2231 if (module_spec.GetUUID().IsValid()) {
2232 // We have a UUID, it is OK to check the global module list...
2233 error =
2234 ModuleList::GetSharedModule(module_spec, module_sp, module_search_paths_ptr: &search_paths,
2235 old_modules: &old_modules, did_create_ptr: &did_create_module);
2236 }
2237
2238 if (!module_sp) {
2239 // The platform is responsible for finding and caching an appropriate
2240 // module in the shared module cache.
2241 if (m_platform_sp) {
2242 error = m_platform_sp->GetSharedModule(
2243 module_spec, process: m_process_sp.get(), module_sp, module_search_paths_ptr: &search_paths,
2244 old_modules: &old_modules, did_create_ptr: &did_create_module);
2245 } else {
2246 error.SetErrorString("no platform is currently set");
2247 }
2248 }
2249 }
2250
2251 // We found a module that wasn't in our target list. Let's make sure that
2252 // there wasn't an equivalent module in the list already, and if there was,
2253 // let's remove it.
2254 if (module_sp) {
2255 ObjectFile *objfile = module_sp->GetObjectFile();
2256 if (objfile) {
2257 switch (objfile->GetType()) {
2258 case ObjectFile::eTypeCoreFile: /// A core file that has a checkpoint of
2259 /// a program's execution state
2260 case ObjectFile::eTypeExecutable: /// A normal executable
2261 case ObjectFile::eTypeDynamicLinker: /// The platform's dynamic linker
2262 /// executable
2263 case ObjectFile::eTypeObjectFile: /// An intermediate object file
2264 case ObjectFile::eTypeSharedLibrary: /// A shared library that can be
2265 /// used during execution
2266 break;
2267 case ObjectFile::eTypeDebugInfo: /// An object file that contains only
2268 /// debug information
2269 if (error_ptr)
2270 error_ptr->SetErrorString("debug info files aren't valid target "
2271 "modules, please specify an executable");
2272 return ModuleSP();
2273 case ObjectFile::eTypeStubLibrary: /// A library that can be linked
2274 /// against but not used for
2275 /// execution
2276 if (error_ptr)
2277 error_ptr->SetErrorString("stub libraries aren't valid target "
2278 "modules, please specify an executable");
2279 return ModuleSP();
2280 default:
2281 if (error_ptr)
2282 error_ptr->SetErrorString(
2283 "unsupported file type, please specify an executable");
2284 return ModuleSP();
2285 }
2286 // GetSharedModule is not guaranteed to find the old shared module, for
2287 // instance in the common case where you pass in the UUID, it is only
2288 // going to find the one module matching the UUID. In fact, it has no
2289 // good way to know what the "old module" relevant to this target is,
2290 // since there might be many copies of a module with this file spec in
2291 // various running debug sessions, but only one of them will belong to
2292 // this target. So let's remove the UUID from the module list, and look
2293 // in the target's module list. Only do this if there is SOMETHING else
2294 // in the module spec...
2295 if (module_spec.GetUUID().IsValid() &&
2296 !module_spec.GetFileSpec().GetFilename().IsEmpty() &&
2297 !module_spec.GetFileSpec().GetDirectory().IsEmpty()) {
2298 ModuleSpec module_spec_copy(module_spec.GetFileSpec());
2299 module_spec_copy.GetUUID().Clear();
2300
2301 ModuleList found_modules;
2302 m_images.FindModules(module_spec: module_spec_copy, matching_module_list&: found_modules);
2303 found_modules.ForEach(callback: [&](const ModuleSP &found_module) -> bool {
2304 old_modules.push_back(Elt: found_module);
2305 return true;
2306 });
2307 }
2308
2309 // If the locate module callback had found a symbol file, set it to the
2310 // module_sp before preloading symbols.
2311 if (symbol_file_spec)
2312 module_sp->SetSymbolFileFileSpec(symbol_file_spec);
2313
2314 // Preload symbols outside of any lock, so hopefully we can do this for
2315 // each library in parallel.
2316 if (GetPreloadSymbols())
2317 module_sp->PreloadSymbols();
2318 llvm::SmallVector<ModuleSP, 1> replaced_modules;
2319 for (ModuleSP &old_module_sp : old_modules) {
2320 if (m_images.GetIndexForModule(module: old_module_sp.get()) !=
2321 LLDB_INVALID_INDEX32) {
2322 if (replaced_modules.empty())
2323 m_images.ReplaceModule(old_module_sp, new_module_sp: module_sp);
2324 else
2325 m_images.Remove(module_sp: old_module_sp);
2326
2327 replaced_modules.push_back(Elt: std::move(old_module_sp));
2328 }
2329 }
2330
2331 if (replaced_modules.size() > 1) {
2332 // The same new module replaced multiple old modules
2333 // simultaneously. It's not clear this should ever
2334 // happen (if we always replace old modules as we add
2335 // new ones, presumably we should never have more than
2336 // one old one). If there are legitimate cases where
2337 // this happens, then the ModuleList::Notifier interface
2338 // may need to be adjusted to allow reporting this.
2339 // In the meantime, just log that this has happened; just
2340 // above we called ReplaceModule on the first one, and Remove
2341 // on the rest.
2342 if (Log *log = GetLog(mask: LLDBLog::Target | LLDBLog::Modules)) {
2343 StreamString message;
2344 auto dump = [&message](Module &dump_module) -> void {
2345 UUID dump_uuid = dump_module.GetUUID();
2346
2347 message << '[';
2348 dump_module.GetDescription(s&: message.AsRawOstream());
2349 message << " (uuid ";
2350
2351 if (dump_uuid.IsValid())
2352 dump_uuid.Dump(s&: message);
2353 else
2354 message << "not specified";
2355
2356 message << ")]";
2357 };
2358
2359 message << "New module ";
2360 dump(*module_sp);
2361 message.AsRawOstream()
2362 << llvm::formatv(Fmt: " simultaneously replaced {0} old modules: ",
2363 Vals: replaced_modules.size());
2364 for (ModuleSP &replaced_module_sp : replaced_modules)
2365 dump(*replaced_module_sp);
2366
2367 log->PutString(str: message.GetString());
2368 }
2369 }
2370
2371 if (replaced_modules.empty())
2372 m_images.Append(module_sp, notify);
2373
2374 for (ModuleSP &old_module_sp : replaced_modules) {
2375 Module *old_module_ptr = old_module_sp.get();
2376 old_module_sp.reset();
2377 ModuleList::RemoveSharedModuleIfOrphaned(module_ptr: old_module_ptr);
2378 }
2379 } else
2380 module_sp.reset();
2381 }
2382 }
2383 if (error_ptr)
2384 *error_ptr = error;
2385 return module_sp;
2386}
2387
2388TargetSP Target::CalculateTarget() { return shared_from_this(); }
2389
2390ProcessSP Target::CalculateProcess() { return m_process_sp; }
2391
2392ThreadSP Target::CalculateThread() { return ThreadSP(); }
2393
2394StackFrameSP Target::CalculateStackFrame() { return StackFrameSP(); }
2395
2396void Target::CalculateExecutionContext(ExecutionContext &exe_ctx) {
2397 exe_ctx.Clear();
2398 exe_ctx.SetTargetPtr(this);
2399}
2400
2401PathMappingList &Target::GetImageSearchPathList() {
2402 return m_image_search_paths;
2403}
2404
2405void Target::ImageSearchPathsChanged(const PathMappingList &path_list,
2406 void *baton) {
2407 Target *target = (Target *)baton;
2408 ModuleSP exe_module_sp(target->GetExecutableModule());
2409 if (exe_module_sp)
2410 target->SetExecutableModule(executable_sp&: exe_module_sp, load_dependent_files: eLoadDependentsYes);
2411}
2412
2413llvm::Expected<lldb::TypeSystemSP>
2414Target::GetScratchTypeSystemForLanguage(lldb::LanguageType language,
2415 bool create_on_demand) {
2416 if (!m_valid)
2417 return llvm::make_error<llvm::StringError>(Args: "Invalid Target",
2418 Args: llvm::inconvertibleErrorCode());
2419
2420 if (language == eLanguageTypeMipsAssembler // GNU AS and LLVM use it for all
2421 // assembly code
2422 || language == eLanguageTypeUnknown) {
2423 LanguageSet languages_for_expressions =
2424 Language::GetLanguagesSupportingTypeSystemsForExpressions();
2425
2426 if (languages_for_expressions[eLanguageTypeC]) {
2427 language = eLanguageTypeC; // LLDB's default. Override by setting the
2428 // target language.
2429 } else {
2430 if (languages_for_expressions.Empty())
2431 return llvm::make_error<llvm::StringError>(
2432 Args: "No expression support for any languages",
2433 Args: llvm::inconvertibleErrorCode());
2434 language = (LanguageType)languages_for_expressions.bitvector.find_first();
2435 }
2436 }
2437
2438 return m_scratch_type_system_map.GetTypeSystemForLanguage(language, target: this,
2439 can_create: create_on_demand);
2440}
2441
2442CompilerType Target::GetRegisterType(const std::string &name,
2443 const lldb_private::RegisterFlags &flags,
2444 uint32_t byte_size) {
2445 RegisterTypeBuilderSP provider = PluginManager::GetRegisterTypeBuilder(target&: *this);
2446 assert(provider);
2447 return provider->GetRegisterType(name, flags, byte_size);
2448}
2449
2450std::vector<lldb::TypeSystemSP>
2451Target::GetScratchTypeSystems(bool create_on_demand) {
2452 if (!m_valid)
2453 return {};
2454
2455 // Some TypeSystem instances are associated with several LanguageTypes so
2456 // they will show up several times in the loop below. The SetVector filters
2457 // out all duplicates as they serve no use for the caller.
2458 std::vector<lldb::TypeSystemSP> scratch_type_systems;
2459
2460 LanguageSet languages_for_expressions =
2461 Language::GetLanguagesSupportingTypeSystemsForExpressions();
2462
2463 for (auto bit : languages_for_expressions.bitvector.set_bits()) {
2464 auto language = (LanguageType)bit;
2465 auto type_system_or_err =
2466 GetScratchTypeSystemForLanguage(language, create_on_demand);
2467 if (!type_system_or_err)
2468 LLDB_LOG_ERROR(
2469 GetLog(LLDBLog::Target), type_system_or_err.takeError(),
2470 "Language '{1}' has expression support but no scratch type "
2471 "system available: {0}",
2472 Language::GetNameForLanguageType(language));
2473 else
2474 if (auto ts = *type_system_or_err)
2475 scratch_type_systems.push_back(x: ts);
2476 }
2477
2478 std::sort(first: scratch_type_systems.begin(), last: scratch_type_systems.end());
2479 scratch_type_systems.erase(
2480 first: std::unique(first: scratch_type_systems.begin(), last: scratch_type_systems.end()),
2481 last: scratch_type_systems.end());
2482 return scratch_type_systems;
2483}
2484
2485PersistentExpressionState *
2486Target::GetPersistentExpressionStateForLanguage(lldb::LanguageType language) {
2487 auto type_system_or_err = GetScratchTypeSystemForLanguage(language, create_on_demand: true);
2488
2489 if (auto err = type_system_or_err.takeError()) {
2490 LLDB_LOG_ERROR(
2491 GetLog(LLDBLog::Target), std::move(err),
2492 "Unable to get persistent expression state for language {1}: {0}",
2493 Language::GetNameForLanguageType(language));
2494 return nullptr;
2495 }
2496
2497 if (auto ts = *type_system_or_err)
2498 return ts->GetPersistentExpressionState();
2499
2500 LLDB_LOG(GetLog(LLDBLog::Target),
2501 "Unable to get persistent expression state for language {1}: {0}",
2502 Language::GetNameForLanguageType(language));
2503 return nullptr;
2504}
2505
2506UserExpression *Target::GetUserExpressionForLanguage(
2507 llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language,
2508 Expression::ResultType desired_type,
2509 const EvaluateExpressionOptions &options, ValueObject *ctx_obj,
2510 Status &error) {
2511 auto type_system_or_err = GetScratchTypeSystemForLanguage(language);
2512 if (auto err = type_system_or_err.takeError()) {
2513 error.SetErrorStringWithFormat(
2514 "Could not find type system for language %s: %s",
2515 Language::GetNameForLanguageType(language),
2516 llvm::toString(E: std::move(err)).c_str());
2517 return nullptr;
2518 }
2519
2520 auto ts = *type_system_or_err;
2521 if (!ts) {
2522 error.SetErrorStringWithFormat(
2523 "Type system for language %s is no longer live",
2524 Language::GetNameForLanguageType(language));
2525 return nullptr;
2526 }
2527
2528 auto *user_expr = ts->GetUserExpression(expr, prefix, language, desired_type,
2529 options, ctx_obj);
2530 if (!user_expr)
2531 error.SetErrorStringWithFormat(
2532 "Could not create an expression for language %s",
2533 Language::GetNameForLanguageType(language));
2534
2535 return user_expr;
2536}
2537
2538FunctionCaller *Target::GetFunctionCallerForLanguage(
2539 lldb::LanguageType language, const CompilerType &return_type,
2540 const Address &function_address, const ValueList &arg_value_list,
2541 const char *name, Status &error) {
2542 auto type_system_or_err = GetScratchTypeSystemForLanguage(language);
2543 if (auto err = type_system_or_err.takeError()) {
2544 error.SetErrorStringWithFormat(
2545 "Could not find type system for language %s: %s",
2546 Language::GetNameForLanguageType(language),
2547 llvm::toString(E: std::move(err)).c_str());
2548 return nullptr;
2549 }
2550 auto ts = *type_system_or_err;
2551 if (!ts) {
2552 error.SetErrorStringWithFormat(
2553 "Type system for language %s is no longer live",
2554 Language::GetNameForLanguageType(language));
2555 return nullptr;
2556 }
2557 auto *persistent_fn = ts->GetFunctionCaller(return_type, function_address,
2558 arg_value_list, name);
2559 if (!persistent_fn)
2560 error.SetErrorStringWithFormat(
2561 "Could not create an expression for language %s",
2562 Language::GetNameForLanguageType(language));
2563
2564 return persistent_fn;
2565}
2566
2567llvm::Expected<std::unique_ptr<UtilityFunction>>
2568Target::CreateUtilityFunction(std::string expression, std::string name,
2569 lldb::LanguageType language,
2570 ExecutionContext &exe_ctx) {
2571 auto type_system_or_err = GetScratchTypeSystemForLanguage(language);
2572 if (!type_system_or_err)
2573 return type_system_or_err.takeError();
2574 auto ts = *type_system_or_err;
2575 if (!ts)
2576 return llvm::make_error<llvm::StringError>(
2577 Args: llvm::StringRef("Type system for language ") +
2578 Language::GetNameForLanguageType(language) +
2579 llvm::StringRef(" is no longer live"),
2580 Args: llvm::inconvertibleErrorCode());
2581 std::unique_ptr<UtilityFunction> utility_fn =
2582 ts->CreateUtilityFunction(text: std::move(expression), name: std::move(name));
2583 if (!utility_fn)
2584 return llvm::make_error<llvm::StringError>(
2585 Args: llvm::StringRef("Could not create an expression for language") +
2586 Language::GetNameForLanguageType(language),
2587 Args: llvm::inconvertibleErrorCode());
2588
2589 DiagnosticManager diagnostics;
2590 if (!utility_fn->Install(diagnostic_manager&: diagnostics, exe_ctx))
2591 return llvm::make_error<llvm::StringError>(Args: diagnostics.GetString(),
2592 Args: llvm::inconvertibleErrorCode());
2593
2594 return std::move(utility_fn);
2595}
2596
2597void Target::SettingsInitialize() { Process::SettingsInitialize(); }
2598
2599void Target::SettingsTerminate() { Process::SettingsTerminate(); }
2600
2601FileSpecList Target::GetDefaultExecutableSearchPaths() {
2602 return Target::GetGlobalProperties().GetExecutableSearchPaths();
2603}
2604
2605FileSpecList Target::GetDefaultDebugFileSearchPaths() {
2606 return Target::GetGlobalProperties().GetDebugFileSearchPaths();
2607}
2608
2609ArchSpec Target::GetDefaultArchitecture() {
2610 return Target::GetGlobalProperties().GetDefaultArchitecture();
2611}
2612
2613void Target::SetDefaultArchitecture(const ArchSpec &arch) {
2614 LLDB_LOG(GetLog(LLDBLog::Target),
2615 "setting target's default architecture to {0} ({1})",
2616 arch.GetArchitectureName(), arch.GetTriple().getTriple());
2617 Target::GetGlobalProperties().SetDefaultArchitecture(arch);
2618}
2619
2620llvm::Error Target::SetLabel(llvm::StringRef label) {
2621 size_t n = LLDB_INVALID_INDEX32;
2622 if (llvm::to_integer(S: label, Num&: n))
2623 return llvm::make_error<llvm::StringError>(
2624 Args: "Cannot use integer as target label.", Args: llvm::inconvertibleErrorCode());
2625 TargetList &targets = GetDebugger().GetTargetList();
2626 for (size_t i = 0; i < targets.GetNumTargets(); i++) {
2627 TargetSP target_sp = targets.GetTargetAtIndex(index: i);
2628 if (target_sp && target_sp->GetLabel() == label) {
2629 return llvm::make_error<llvm::StringError>(
2630 Args: llvm::formatv(
2631 Fmt: "Cannot use label '{0}' since it's set in target #{1}.", Vals&: label,
2632 Vals&: i),
2633 Args: llvm::inconvertibleErrorCode());
2634 }
2635 }
2636
2637 m_label = label.str();
2638 return llvm::Error::success();
2639}
2640
2641Target *Target::GetTargetFromContexts(const ExecutionContext *exe_ctx_ptr,
2642 const SymbolContext *sc_ptr) {
2643 // The target can either exist in the "process" of ExecutionContext, or in
2644 // the "target_sp" member of SymbolContext. This accessor helper function
2645 // will get the target from one of these locations.
2646
2647 Target *target = nullptr;
2648 if (sc_ptr != nullptr)
2649 target = sc_ptr->target_sp.get();
2650 if (target == nullptr && exe_ctx_ptr)
2651 target = exe_ctx_ptr->GetTargetPtr();
2652 return target;
2653}
2654
2655ExpressionResults Target::EvaluateExpression(
2656 llvm::StringRef expr, ExecutionContextScope *exe_scope,
2657 lldb::ValueObjectSP &result_valobj_sp,
2658 const EvaluateExpressionOptions &options, std::string *fixed_expression,
2659 ValueObject *ctx_obj) {
2660 result_valobj_sp.reset();
2661
2662 ExpressionResults execution_results = eExpressionSetupError;
2663
2664 if (expr.empty()) {
2665 m_stats.GetExpressionStats().NotifyFailure();
2666 return execution_results;
2667 }
2668
2669 // We shouldn't run stop hooks in expressions.
2670 bool old_suppress_value = m_suppress_stop_hooks;
2671 m_suppress_stop_hooks = true;
2672 auto on_exit = llvm::make_scope_exit(F: [this, old_suppress_value]() {
2673 m_suppress_stop_hooks = old_suppress_value;
2674 });
2675
2676 ExecutionContext exe_ctx;
2677
2678 if (exe_scope) {
2679 exe_scope->CalculateExecutionContext(exe_ctx);
2680 } else if (m_process_sp) {
2681 m_process_sp->CalculateExecutionContext(exe_ctx);
2682 } else {
2683 CalculateExecutionContext(exe_ctx);
2684 }
2685
2686 // Make sure we aren't just trying to see the value of a persistent variable
2687 // (something like "$0")
2688 // Only check for persistent variables the expression starts with a '$'
2689 lldb::ExpressionVariableSP persistent_var_sp;
2690 if (expr[0] == '$') {
2691 auto type_system_or_err =
2692 GetScratchTypeSystemForLanguage(language: eLanguageTypeC);
2693 if (auto err = type_system_or_err.takeError()) {
2694 LLDB_LOG_ERROR(GetLog(LLDBLog::Target), std::move(err),
2695 "Unable to get scratch type system");
2696 } else {
2697 auto ts = *type_system_or_err;
2698 if (!ts)
2699 LLDB_LOG_ERROR(GetLog(LLDBLog::Target), std::move(err),
2700 "Scratch type system is no longer live: {0}");
2701 else
2702 persistent_var_sp =
2703 ts->GetPersistentExpressionState()->GetVariable(name: expr);
2704 }
2705 }
2706 if (persistent_var_sp) {
2707 result_valobj_sp = persistent_var_sp->GetValueObject();
2708 execution_results = eExpressionCompleted;
2709 } else {
2710 llvm::StringRef prefix = GetExpressionPrefixContents();
2711 Status error;
2712 execution_results = UserExpression::Evaluate(exe_ctx, options, expr_cstr: expr, expr_prefix: prefix,
2713 result_valobj_sp, error,
2714 fixed_expression, ctx_obj);
2715 // Pass up the error by wrapping it inside an error result.
2716 if (error.Fail() && !result_valobj_sp)
2717 result_valobj_sp = ValueObjectConstResult::Create(
2718 exe_scope: exe_ctx.GetBestExecutionContextScope(), error);
2719 }
2720
2721 if (execution_results == eExpressionCompleted)
2722 m_stats.GetExpressionStats().NotifySuccess();
2723 else
2724 m_stats.GetExpressionStats().NotifyFailure();
2725 return execution_results;
2726}
2727
2728lldb::ExpressionVariableSP Target::GetPersistentVariable(ConstString name) {
2729 lldb::ExpressionVariableSP variable_sp;
2730 m_scratch_type_system_map.ForEach(
2731 callback: [name, &variable_sp](TypeSystemSP type_system) -> bool {
2732 auto ts = type_system.get();
2733 if (!ts)
2734 return true;
2735 if (PersistentExpressionState *persistent_state =
2736 ts->GetPersistentExpressionState()) {
2737 variable_sp = persistent_state->GetVariable(name);
2738
2739 if (variable_sp)
2740 return false; // Stop iterating the ForEach
2741 }
2742 return true; // Keep iterating the ForEach
2743 });
2744 return variable_sp;
2745}
2746
2747lldb::addr_t Target::GetPersistentSymbol(ConstString name) {
2748 lldb::addr_t address = LLDB_INVALID_ADDRESS;
2749
2750 m_scratch_type_system_map.ForEach(
2751 callback: [name, &address](lldb::TypeSystemSP type_system) -> bool {
2752 auto ts = type_system.get();
2753 if (!ts)
2754 return true;
2755
2756 if (PersistentExpressionState *persistent_state =
2757 ts->GetPersistentExpressionState()) {
2758 address = persistent_state->LookupSymbol(name);
2759 if (address != LLDB_INVALID_ADDRESS)
2760 return false; // Stop iterating the ForEach
2761 }
2762 return true; // Keep iterating the ForEach
2763 });
2764 return address;
2765}
2766
2767llvm::Expected<lldb_private::Address> Target::GetEntryPointAddress() {
2768 Module *exe_module = GetExecutableModulePointer();
2769
2770 // Try to find the entry point address in the primary executable.
2771 const bool has_primary_executable = exe_module && exe_module->GetObjectFile();
2772 if (has_primary_executable) {
2773 Address entry_addr = exe_module->GetObjectFile()->GetEntryPointAddress();
2774 if (entry_addr.IsValid())
2775 return entry_addr;
2776 }
2777
2778 const ModuleList &modules = GetImages();
2779 const size_t num_images = modules.GetSize();
2780 for (size_t idx = 0; idx < num_images; ++idx) {
2781 ModuleSP module_sp(modules.GetModuleAtIndex(idx));
2782 if (!module_sp || !module_sp->GetObjectFile())
2783 continue;
2784
2785 Address entry_addr = module_sp->GetObjectFile()->GetEntryPointAddress();
2786 if (entry_addr.IsValid())
2787 return entry_addr;
2788 }
2789
2790 // We haven't found the entry point address. Return an appropriate error.
2791 if (!has_primary_executable)
2792 return llvm::make_error<llvm::StringError>(
2793 Args: "No primary executable found and could not find entry point address in "
2794 "any executable module",
2795 Args: llvm::inconvertibleErrorCode());
2796
2797 return llvm::make_error<llvm::StringError>(
2798 Args: "Could not find entry point address for primary executable module \"" +
2799 exe_module->GetFileSpec().GetFilename().GetStringRef() + "\"",
2800 Args: llvm::inconvertibleErrorCode());
2801}
2802
2803lldb::addr_t Target::GetCallableLoadAddress(lldb::addr_t load_addr,
2804 AddressClass addr_class) const {
2805 auto arch_plugin = GetArchitecturePlugin();
2806 return arch_plugin
2807 ? arch_plugin->GetCallableLoadAddress(addr: load_addr, addr_class)
2808 : load_addr;
2809}
2810
2811lldb::addr_t Target::GetOpcodeLoadAddress(lldb::addr_t load_addr,
2812 AddressClass addr_class) const {
2813 auto arch_plugin = GetArchitecturePlugin();
2814 return arch_plugin ? arch_plugin->GetOpcodeLoadAddress(addr: load_addr, addr_class)
2815 : load_addr;
2816}
2817
2818lldb::addr_t Target::GetBreakableLoadAddress(lldb::addr_t addr) {
2819 auto arch_plugin = GetArchitecturePlugin();
2820 return arch_plugin ? arch_plugin->GetBreakableLoadAddress(addr, target&: *this) : addr;
2821}
2822
2823SourceManager &Target::GetSourceManager() {
2824 if (!m_source_manager_up)
2825 m_source_manager_up = std::make_unique<SourceManager>(args: shared_from_this());
2826 return *m_source_manager_up;
2827}
2828
2829Target::StopHookSP Target::CreateStopHook(StopHook::StopHookKind kind) {
2830 lldb::user_id_t new_uid = ++m_stop_hook_next_id;
2831 Target::StopHookSP stop_hook_sp;
2832 switch (kind) {
2833 case StopHook::StopHookKind::CommandBased:
2834 stop_hook_sp.reset(p: new StopHookCommandLine(shared_from_this(), new_uid));
2835 break;
2836 case StopHook::StopHookKind::ScriptBased:
2837 stop_hook_sp.reset(p: new StopHookScripted(shared_from_this(), new_uid));
2838 break;
2839 }
2840 m_stop_hooks[new_uid] = stop_hook_sp;
2841 return stop_hook_sp;
2842}
2843
2844void Target::UndoCreateStopHook(lldb::user_id_t user_id) {
2845 if (!RemoveStopHookByID(uid: user_id))
2846 return;
2847 if (user_id == m_stop_hook_next_id)
2848 m_stop_hook_next_id--;
2849}
2850
2851bool Target::RemoveStopHookByID(lldb::user_id_t user_id) {
2852 size_t num_removed = m_stop_hooks.erase(x: user_id);
2853 return (num_removed != 0);
2854}
2855
2856void Target::RemoveAllStopHooks() { m_stop_hooks.clear(); }
2857
2858Target::StopHookSP Target::GetStopHookByID(lldb::user_id_t user_id) {
2859 StopHookSP found_hook;
2860
2861 StopHookCollection::iterator specified_hook_iter;
2862 specified_hook_iter = m_stop_hooks.find(x: user_id);
2863 if (specified_hook_iter != m_stop_hooks.end())
2864 found_hook = (*specified_hook_iter).second;
2865 return found_hook;
2866}
2867
2868bool Target::SetStopHookActiveStateByID(lldb::user_id_t user_id,
2869 bool active_state) {
2870 StopHookCollection::iterator specified_hook_iter;
2871 specified_hook_iter = m_stop_hooks.find(x: user_id);
2872 if (specified_hook_iter == m_stop_hooks.end())
2873 return false;
2874
2875 (*specified_hook_iter).second->SetIsActive(active_state);
2876 return true;
2877}
2878
2879void Target::SetAllStopHooksActiveState(bool active_state) {
2880 StopHookCollection::iterator pos, end = m_stop_hooks.end();
2881 for (pos = m_stop_hooks.begin(); pos != end; pos++) {
2882 (*pos).second->SetIsActive(active_state);
2883 }
2884}
2885
2886bool Target::RunStopHooks() {
2887 if (m_suppress_stop_hooks)
2888 return false;
2889
2890 if (!m_process_sp)
2891 return false;
2892
2893 // Somebody might have restarted the process:
2894 // Still return false, the return value is about US restarting the target.
2895 if (m_process_sp->GetState() != eStateStopped)
2896 return false;
2897
2898 if (m_stop_hooks.empty())
2899 return false;
2900
2901 // If there aren't any active stop hooks, don't bother either.
2902 bool any_active_hooks = false;
2903 for (auto hook : m_stop_hooks) {
2904 if (hook.second->IsActive()) {
2905 any_active_hooks = true;
2906 break;
2907 }
2908 }
2909 if (!any_active_hooks)
2910 return false;
2911
2912 // Make sure we check that we are not stopped because of us running a user
2913 // expression since in that case we do not want to run the stop-hooks. Note,
2914 // you can't just check whether the last stop was for a User Expression,
2915 // because breakpoint commands get run before stop hooks, and one of them
2916 // might have run an expression. You have to ensure you run the stop hooks
2917 // once per natural stop.
2918 uint32_t last_natural_stop = m_process_sp->GetModIDRef().GetLastNaturalStopID();
2919 if (last_natural_stop != 0 && m_latest_stop_hook_id == last_natural_stop)
2920 return false;
2921
2922 m_latest_stop_hook_id = last_natural_stop;
2923
2924 std::vector<ExecutionContext> exc_ctx_with_reasons;
2925
2926 ThreadList &cur_threadlist = m_process_sp->GetThreadList();
2927 size_t num_threads = cur_threadlist.GetSize();
2928 for (size_t i = 0; i < num_threads; i++) {
2929 lldb::ThreadSP cur_thread_sp = cur_threadlist.GetThreadAtIndex(idx: i);
2930 if (cur_thread_sp->ThreadStoppedForAReason()) {
2931 lldb::StackFrameSP cur_frame_sp = cur_thread_sp->GetStackFrameAtIndex(idx: 0);
2932 exc_ctx_with_reasons.emplace_back(args: m_process_sp.get(), args: cur_thread_sp.get(),
2933 args: cur_frame_sp.get());
2934 }
2935 }
2936
2937 // If no threads stopped for a reason, don't run the stop-hooks.
2938 size_t num_exe_ctx = exc_ctx_with_reasons.size();
2939 if (num_exe_ctx == 0)
2940 return false;
2941
2942 StreamSP output_sp = m_debugger.GetAsyncOutputStream();
2943
2944 bool auto_continue = false;
2945 bool hooks_ran = false;
2946 bool print_hook_header = (m_stop_hooks.size() != 1);
2947 bool print_thread_header = (num_exe_ctx != 1);
2948 bool should_stop = false;
2949 bool somebody_restarted = false;
2950
2951 for (auto stop_entry : m_stop_hooks) {
2952 StopHookSP cur_hook_sp = stop_entry.second;
2953 if (!cur_hook_sp->IsActive())
2954 continue;
2955
2956 bool any_thread_matched = false;
2957 for (auto exc_ctx : exc_ctx_with_reasons) {
2958 // We detect somebody restarted in the stop-hook loop, and broke out of
2959 // that loop back to here. So break out of here too.
2960 if (somebody_restarted)
2961 break;
2962
2963 if (!cur_hook_sp->ExecutionContextPasses(exe_ctx: exc_ctx))
2964 continue;
2965
2966 // We only consult the auto-continue for a stop hook if it matched the
2967 // specifier.
2968 auto_continue |= cur_hook_sp->GetAutoContinue();
2969
2970 if (!hooks_ran)
2971 hooks_ran = true;
2972
2973 if (print_hook_header && !any_thread_matched) {
2974 StreamString s;
2975 cur_hook_sp->GetDescription(s, level: eDescriptionLevelBrief);
2976 if (s.GetSize() != 0)
2977 output_sp->Printf(format: "\n- Hook %" PRIu64 " (%s)\n", cur_hook_sp->GetID(),
2978 s.GetData());
2979 else
2980 output_sp->Printf(format: "\n- Hook %" PRIu64 "\n", cur_hook_sp->GetID());
2981 any_thread_matched = true;
2982 }
2983
2984 if (print_thread_header)
2985 output_sp->Printf(format: "-- Thread %d\n",
2986 exc_ctx.GetThreadPtr()->GetIndexID());
2987
2988 StopHook::StopHookResult this_result =
2989 cur_hook_sp->HandleStop(exe_ctx&: exc_ctx, output: output_sp);
2990 bool this_should_stop = true;
2991
2992 switch (this_result) {
2993 case StopHook::StopHookResult::KeepStopped:
2994 // If this hook is set to auto-continue that should override the
2995 // HandleStop result...
2996 if (cur_hook_sp->GetAutoContinue())
2997 this_should_stop = false;
2998 else
2999 this_should_stop = true;
3000
3001 break;
3002 case StopHook::StopHookResult::RequestContinue:
3003 this_should_stop = false;
3004 break;
3005 case StopHook::StopHookResult::AlreadyContinued:
3006 // We don't have a good way to prohibit people from restarting the
3007 // target willy nilly in a stop hook. If the hook did so, give a
3008 // gentle suggestion here and bag out if the hook processing.
3009 output_sp->Printf(format: "\nAborting stop hooks, hook %" PRIu64
3010 " set the program running.\n"
3011 " Consider using '-G true' to make "
3012 "stop hooks auto-continue.\n",
3013 cur_hook_sp->GetID());
3014 somebody_restarted = true;
3015 break;
3016 }
3017 // If we're already restarted, stop processing stop hooks.
3018 // FIXME: if we are doing non-stop mode for real, we would have to
3019 // check that OUR thread was restarted, otherwise we should keep
3020 // processing stop hooks.
3021 if (somebody_restarted)
3022 break;
3023
3024 // If anybody wanted to stop, we should all stop.
3025 if (!should_stop)
3026 should_stop = this_should_stop;
3027 }
3028 }
3029
3030 output_sp->Flush();
3031
3032 // If one of the commands in the stop hook already restarted the target,
3033 // report that fact.
3034 if (somebody_restarted)
3035 return true;
3036
3037 // Finally, if auto-continue was requested, do it now:
3038 // We only compute should_stop against the hook results if a hook got to run
3039 // which is why we have to do this conjoint test.
3040 if ((hooks_ran && !should_stop) || auto_continue) {
3041 Log *log = GetLog(mask: LLDBLog::Process);
3042 Status error = m_process_sp->PrivateResume();
3043 if (error.Success()) {
3044 LLDB_LOG(log, "Resuming from RunStopHooks");
3045 return true;
3046 } else {
3047 LLDB_LOG(log, "Resuming from RunStopHooks failed: {0}", error);
3048 return false;
3049 }
3050 }
3051
3052 return false;
3053}
3054
3055TargetProperties &Target::GetGlobalProperties() {
3056 // NOTE: intentional leak so we don't crash if global destructor chain gets
3057 // called as other threads still use the result of this function
3058 static TargetProperties *g_settings_ptr =
3059 new TargetProperties(nullptr);
3060 return *g_settings_ptr;
3061}
3062
3063Status Target::Install(ProcessLaunchInfo *launch_info) {
3064 Status error;
3065 PlatformSP platform_sp(GetPlatform());
3066 if (platform_sp) {
3067 if (platform_sp->IsRemote()) {
3068 if (platform_sp->IsConnected()) {
3069 // Install all files that have an install path when connected to a
3070 // remote platform. If target.auto-install-main-executable is set then
3071 // also install the main executable even if it does not have an explicit
3072 // install path specified.
3073 const ModuleList &modules = GetImages();
3074 const size_t num_images = modules.GetSize();
3075 for (size_t idx = 0; idx < num_images; ++idx) {
3076 ModuleSP module_sp(modules.GetModuleAtIndex(idx));
3077 if (module_sp) {
3078 const bool is_main_executable = module_sp == GetExecutableModule();
3079 FileSpec local_file(module_sp->GetFileSpec());
3080 if (local_file) {
3081 FileSpec remote_file(module_sp->GetRemoteInstallFileSpec());
3082 if (!remote_file) {
3083 if (is_main_executable && GetAutoInstallMainExecutable()) {
3084 // Automatically install the main executable.
3085 remote_file = platform_sp->GetRemoteWorkingDirectory();
3086 remote_file.AppendPathComponent(
3087 component: module_sp->GetFileSpec().GetFilename().GetCString());
3088 }
3089 }
3090 if (remote_file) {
3091 error = platform_sp->Install(src: local_file, dst: remote_file);
3092 if (error.Success()) {
3093 module_sp->SetPlatformFileSpec(remote_file);
3094 if (is_main_executable) {
3095 platform_sp->SetFilePermissions(file_spec: remote_file, file_permissions: 0700);
3096 if (launch_info)
3097 launch_info->SetExecutableFile(exe_file: remote_file, add_exe_file_as_first_arg: false);
3098 }
3099 } else
3100 break;
3101 }
3102 }
3103 }
3104 }
3105 }
3106 }
3107 }
3108 return error;
3109}
3110
3111bool Target::ResolveLoadAddress(addr_t load_addr, Address &so_addr,
3112 uint32_t stop_id) {
3113 return m_section_load_history.ResolveLoadAddress(stop_id, load_addr, so_addr);
3114}
3115
3116bool Target::ResolveFileAddress(lldb::addr_t file_addr,
3117 Address &resolved_addr) {
3118 return m_images.ResolveFileAddress(vm_addr: file_addr, so_addr&: resolved_addr);
3119}
3120
3121bool Target::SetSectionLoadAddress(const SectionSP &section_sp,
3122 addr_t new_section_load_addr,
3123 bool warn_multiple) {
3124 const addr_t old_section_load_addr =
3125 m_section_load_history.GetSectionLoadAddress(
3126 stop_id: SectionLoadHistory::eStopIDNow, section_sp);
3127 if (old_section_load_addr != new_section_load_addr) {
3128 uint32_t stop_id = 0;
3129 ProcessSP process_sp(GetProcessSP());
3130 if (process_sp)
3131 stop_id = process_sp->GetStopID();
3132 else
3133 stop_id = m_section_load_history.GetLastStopID();
3134 if (m_section_load_history.SetSectionLoadAddress(
3135 stop_id, section_sp, load_addr: new_section_load_addr, warn_multiple))
3136 return true; // Return true if the section load address was changed...
3137 }
3138 return false; // Return false to indicate nothing changed
3139}
3140
3141size_t Target::UnloadModuleSections(const ModuleList &module_list) {
3142 size_t section_unload_count = 0;
3143 size_t num_modules = module_list.GetSize();
3144 for (size_t i = 0; i < num_modules; ++i) {
3145 section_unload_count +=
3146 UnloadModuleSections(module_sp: module_list.GetModuleAtIndex(idx: i));
3147 }
3148 return section_unload_count;
3149}
3150
3151size_t Target::UnloadModuleSections(const lldb::ModuleSP &module_sp) {
3152 uint32_t stop_id = 0;
3153 ProcessSP process_sp(GetProcessSP());
3154 if (process_sp)
3155 stop_id = process_sp->GetStopID();
3156 else
3157 stop_id = m_section_load_history.GetLastStopID();
3158 SectionList *sections = module_sp->GetSectionList();
3159 size_t section_unload_count = 0;
3160 if (sections) {
3161 const uint32_t num_sections = sections->GetNumSections(depth: 0);
3162 for (uint32_t i = 0; i < num_sections; ++i) {
3163 section_unload_count += m_section_load_history.SetSectionUnloaded(
3164 stop_id, section_sp: sections->GetSectionAtIndex(idx: i));
3165 }
3166 }
3167 return section_unload_count;
3168}
3169
3170bool Target::SetSectionUnloaded(const lldb::SectionSP &section_sp) {
3171 uint32_t stop_id = 0;
3172 ProcessSP process_sp(GetProcessSP());
3173 if (process_sp)
3174 stop_id = process_sp->GetStopID();
3175 else
3176 stop_id = m_section_load_history.GetLastStopID();
3177 return m_section_load_history.SetSectionUnloaded(stop_id, section_sp);
3178}
3179
3180bool Target::SetSectionUnloaded(const lldb::SectionSP &section_sp,
3181 addr_t load_addr) {
3182 uint32_t stop_id = 0;
3183 ProcessSP process_sp(GetProcessSP());
3184 if (process_sp)
3185 stop_id = process_sp->GetStopID();
3186 else
3187 stop_id = m_section_load_history.GetLastStopID();
3188 return m_section_load_history.SetSectionUnloaded(stop_id, section_sp,
3189 load_addr);
3190}
3191
3192void Target::ClearAllLoadedSections() { m_section_load_history.Clear(); }
3193
3194void Target::SaveScriptedLaunchInfo(lldb_private::ProcessInfo &process_info) {
3195 if (process_info.IsScriptedProcess()) {
3196 // Only copy scripted process launch options.
3197 ProcessLaunchInfo &default_launch_info = const_cast<ProcessLaunchInfo &>(
3198 GetGlobalProperties().GetProcessLaunchInfo());
3199 default_launch_info.SetProcessPluginName("ScriptedProcess");
3200 default_launch_info.SetScriptedMetadata(process_info.GetScriptedMetadata());
3201 SetProcessLaunchInfo(default_launch_info);
3202 }
3203}
3204
3205Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) {
3206 m_stats.SetLaunchOrAttachTime();
3207 Status error;
3208 Log *log = GetLog(mask: LLDBLog::Target);
3209
3210 LLDB_LOGF(log, "Target::%s() called for %s", __FUNCTION__,
3211 launch_info.GetExecutableFile().GetPath().c_str());
3212
3213 StateType state = eStateInvalid;
3214
3215 // Scope to temporarily get the process state in case someone has manually
3216 // remotely connected already to a process and we can skip the platform
3217 // launching.
3218 {
3219 ProcessSP process_sp(GetProcessSP());
3220
3221 if (process_sp) {
3222 state = process_sp->GetState();
3223 LLDB_LOGF(log,
3224 "Target::%s the process exists, and its current state is %s",
3225 __FUNCTION__, StateAsCString(state));
3226 } else {
3227 LLDB_LOGF(log, "Target::%s the process instance doesn't currently exist.",
3228 __FUNCTION__);
3229 }
3230 }
3231
3232 launch_info.GetFlags().Set(eLaunchFlagDebug);
3233
3234 SaveScriptedLaunchInfo(process_info&: launch_info);
3235
3236 // Get the value of synchronous execution here. If you wait till after you
3237 // have started to run, then you could have hit a breakpoint, whose command
3238 // might switch the value, and then you'll pick up that incorrect value.
3239 Debugger &debugger = GetDebugger();
3240 const bool synchronous_execution =
3241 debugger.GetCommandInterpreter().GetSynchronous();
3242
3243 PlatformSP platform_sp(GetPlatform());
3244
3245 FinalizeFileActions(info&: launch_info);
3246
3247 if (state == eStateConnected) {
3248 if (launch_info.GetFlags().Test(bit: eLaunchFlagLaunchInTTY)) {
3249 error.SetErrorString(
3250 "can't launch in tty when launching through a remote connection");
3251 return error;
3252 }
3253 }
3254
3255 if (!launch_info.GetArchitecture().IsValid())
3256 launch_info.GetArchitecture() = GetArchitecture();
3257
3258 // Hijacking events of the process to be created to be sure that all events
3259 // until the first stop are intercepted (in case if platform doesn't define
3260 // its own hijacking listener or if the process is created by the target
3261 // manually, without the platform).
3262 if (!launch_info.GetHijackListener())
3263 launch_info.SetHijackListener(Listener::MakeListener(
3264 name: Process::LaunchSynchronousHijackListenerName.data()));
3265
3266 // If we're not already connected to the process, and if we have a platform
3267 // that can launch a process for debugging, go ahead and do that here.
3268 if (state != eStateConnected && platform_sp &&
3269 platform_sp->CanDebugProcess() && !launch_info.IsScriptedProcess()) {
3270 LLDB_LOGF(log, "Target::%s asking the platform to debug the process",
3271 __FUNCTION__);
3272
3273 // If there was a previous process, delete it before we make the new one.
3274 // One subtle point, we delete the process before we release the reference
3275 // to m_process_sp. That way even if we are the last owner, the process
3276 // will get Finalized before it gets destroyed.
3277 DeleteCurrentProcess();
3278
3279 m_process_sp =
3280 GetPlatform()->DebugProcess(launch_info, debugger, target&: *this, error);
3281
3282 } else {
3283 LLDB_LOGF(log,
3284 "Target::%s the platform doesn't know how to debug a "
3285 "process, getting a process plugin to do this for us.",
3286 __FUNCTION__);
3287
3288 if (state == eStateConnected) {
3289 assert(m_process_sp);
3290 } else {
3291 // Use a Process plugin to construct the process.
3292 CreateProcess(listener_sp: launch_info.GetListener(),
3293 plugin_name: launch_info.GetProcessPluginName(), crash_file: nullptr, can_connect: false);
3294 }
3295
3296 // Since we didn't have a platform launch the process, launch it here.
3297 if (m_process_sp) {
3298 m_process_sp->HijackProcessEvents(listener_sp: launch_info.GetHijackListener());
3299 m_process_sp->SetShadowListener(launch_info.GetShadowListener());
3300 error = m_process_sp->Launch(launch_info);
3301 }
3302 }
3303
3304 if (!m_process_sp && error.Success())
3305 error.SetErrorString("failed to launch or debug process");
3306
3307 if (!error.Success())
3308 return error;
3309
3310 bool rebroadcast_first_stop =
3311 !synchronous_execution &&
3312 launch_info.GetFlags().Test(bit: eLaunchFlagStopAtEntry);
3313
3314 assert(launch_info.GetHijackListener());
3315
3316 EventSP first_stop_event_sp;
3317 state = m_process_sp->WaitForProcessToStop(timeout: std::nullopt, event_sp_ptr: &first_stop_event_sp,
3318 wait_always: rebroadcast_first_stop,
3319 hijack_listener: launch_info.GetHijackListener());
3320 m_process_sp->RestoreProcessEvents();
3321
3322 if (rebroadcast_first_stop) {
3323 assert(first_stop_event_sp);
3324 m_process_sp->BroadcastEvent(event_sp&: first_stop_event_sp);
3325 return error;
3326 }
3327
3328 switch (state) {
3329 case eStateStopped: {
3330 if (launch_info.GetFlags().Test(bit: eLaunchFlagStopAtEntry))
3331 break;
3332 if (synchronous_execution)
3333 // Now we have handled the stop-from-attach, and we are just
3334 // switching to a synchronous resume. So we should switch to the
3335 // SyncResume hijacker.
3336 m_process_sp->ResumeSynchronous(stream);
3337 else
3338 error = m_process_sp->Resume();
3339 if (!error.Success()) {
3340 Status error2;
3341 error2.SetErrorStringWithFormat(
3342 "process resume at entry point failed: %s", error.AsCString());
3343 error = error2;
3344 }
3345 } break;
3346 case eStateExited: {
3347 bool with_shell = !!launch_info.GetShell();
3348 const int exit_status = m_process_sp->GetExitStatus();
3349 const char *exit_desc = m_process_sp->GetExitDescription();
3350 std::string desc;
3351 if (exit_desc && exit_desc[0])
3352 desc = " (" + std::string(exit_desc) + ')';
3353 if (with_shell)
3354 error.SetErrorStringWithFormat(
3355 "process exited with status %i%s\n"
3356 "'r' and 'run' are aliases that default to launching through a "
3357 "shell.\n"
3358 "Try launching without going through a shell by using "
3359 "'process launch'.",
3360 exit_status, desc.c_str());
3361 else
3362 error.SetErrorStringWithFormat("process exited with status %i%s",
3363 exit_status, desc.c_str());
3364 } break;
3365 default:
3366 error.SetErrorStringWithFormat("initial process state wasn't stopped: %s",
3367 StateAsCString(state));
3368 break;
3369 }
3370 return error;
3371}
3372
3373void Target::SetTrace(const TraceSP &trace_sp) { m_trace_sp = trace_sp; }
3374
3375TraceSP Target::GetTrace() { return m_trace_sp; }
3376
3377llvm::Expected<TraceSP> Target::CreateTrace() {
3378 if (!m_process_sp)
3379 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
3380 Msg: "A process is required for tracing");
3381 if (m_trace_sp)
3382 return llvm::createStringError(EC: llvm::inconvertibleErrorCode(),
3383 Msg: "A trace already exists for the target");
3384
3385 llvm::Expected<TraceSupportedResponse> trace_type =
3386 m_process_sp->TraceSupported();
3387 if (!trace_type)
3388 return llvm::createStringError(
3389 EC: llvm::inconvertibleErrorCode(), Fmt: "Tracing is not supported. %s",
3390 Vals: llvm::toString(E: trace_type.takeError()).c_str());
3391 if (llvm::Expected<TraceSP> trace_sp =
3392 Trace::FindPluginForLiveProcess(plugin_name: trace_type->name, process&: *m_process_sp))
3393 m_trace_sp = *trace_sp;
3394 else
3395 return llvm::createStringError(
3396 EC: llvm::inconvertibleErrorCode(),
3397 Fmt: "Couldn't create a Trace object for the process. %s",
3398 Vals: llvm::toString(E: trace_sp.takeError()).c_str());
3399 return m_trace_sp;
3400}
3401
3402llvm::Expected<TraceSP> Target::GetTraceOrCreate() {
3403 if (m_trace_sp)
3404 return m_trace_sp;
3405 return CreateTrace();
3406}
3407
3408Status Target::Attach(ProcessAttachInfo &attach_info, Stream *stream) {
3409 m_stats.SetLaunchOrAttachTime();
3410 auto state = eStateInvalid;
3411 auto process_sp = GetProcessSP();
3412 if (process_sp) {
3413 state = process_sp->GetState();
3414 if (process_sp->IsAlive() && state != eStateConnected) {
3415 if (state == eStateAttaching)
3416 return Status("process attach is in progress");
3417 return Status("a process is already being debugged");
3418 }
3419 }
3420
3421 const ModuleSP old_exec_module_sp = GetExecutableModule();
3422
3423 // If no process info was specified, then use the target executable name as
3424 // the process to attach to by default
3425 if (!attach_info.ProcessInfoSpecified()) {
3426 if (old_exec_module_sp)
3427 attach_info.GetExecutableFile().SetFilename(
3428 old_exec_module_sp->GetPlatformFileSpec().GetFilename());
3429
3430 if (!attach_info.ProcessInfoSpecified()) {
3431 return Status("no process specified, create a target with a file, or "
3432 "specify the --pid or --name");
3433 }
3434 }
3435
3436 const auto platform_sp =
3437 GetDebugger().GetPlatformList().GetSelectedPlatform();
3438 ListenerSP hijack_listener_sp;
3439 const bool async = attach_info.GetAsync();
3440 if (!async) {
3441 hijack_listener_sp = Listener::MakeListener(
3442 name: Process::AttachSynchronousHijackListenerName.data());
3443 attach_info.SetHijackListener(hijack_listener_sp);
3444 }
3445
3446 Status error;
3447 if (state != eStateConnected && platform_sp != nullptr &&
3448 platform_sp->CanDebugProcess() && !attach_info.IsScriptedProcess()) {
3449 SetPlatform(platform_sp);
3450 process_sp = platform_sp->Attach(attach_info, debugger&: GetDebugger(), target: this, error);
3451 } else {
3452 if (state != eStateConnected) {
3453 SaveScriptedLaunchInfo(process_info&: attach_info);
3454 llvm::StringRef plugin_name = attach_info.GetProcessPluginName();
3455 process_sp =
3456 CreateProcess(listener_sp: attach_info.GetListenerForProcess(debugger&: GetDebugger()),
3457 plugin_name, crash_file: nullptr, can_connect: false);
3458 if (!process_sp) {
3459 error.SetErrorStringWithFormatv(
3460 format: "failed to create process using plugin '{0}'",
3461 args: plugin_name.empty() ? "<empty>" : plugin_name);
3462 return error;
3463 }
3464 }
3465 if (hijack_listener_sp)
3466 process_sp->HijackProcessEvents(listener_sp: hijack_listener_sp);
3467 error = process_sp->Attach(attach_info);
3468 }
3469
3470 if (error.Success() && process_sp) {
3471 if (async) {
3472 process_sp->RestoreProcessEvents();
3473 } else {
3474 // We are stopping all the way out to the user, so update selected frames.
3475 state = process_sp->WaitForProcessToStop(
3476 timeout: std::nullopt, event_sp_ptr: nullptr, wait_always: false, hijack_listener: attach_info.GetHijackListener(), stream,
3477 use_run_lock: true, select_most_relevant: SelectMostRelevantFrame);
3478 process_sp->RestoreProcessEvents();
3479
3480 if (state != eStateStopped) {
3481 const char *exit_desc = process_sp->GetExitDescription();
3482 if (exit_desc)
3483 error.SetErrorStringWithFormat("%s", exit_desc);
3484 else
3485 error.SetErrorString(
3486 "process did not stop (no such process or permission problem?)");
3487 process_sp->Destroy(force_kill: false);
3488 }
3489 }
3490 }
3491 return error;
3492}
3493
3494void Target::FinalizeFileActions(ProcessLaunchInfo &info) {
3495 Log *log = GetLog(mask: LLDBLog::Process);
3496
3497 // Finalize the file actions, and if none were given, default to opening up a
3498 // pseudo terminal
3499 PlatformSP platform_sp = GetPlatform();
3500 const bool default_to_use_pty =
3501 m_platform_sp ? m_platform_sp->IsHost() : false;
3502 LLDB_LOG(
3503 log,
3504 "have platform={0}, platform_sp->IsHost()={1}, default_to_use_pty={2}",
3505 bool(platform_sp),
3506 platform_sp ? (platform_sp->IsHost() ? "true" : "false") : "n/a",
3507 default_to_use_pty);
3508
3509 // If nothing for stdin or stdout or stderr was specified, then check the
3510 // process for any default settings that were set with "settings set"
3511 if (info.GetFileActionForFD(STDIN_FILENO) == nullptr ||
3512 info.GetFileActionForFD(STDOUT_FILENO) == nullptr ||
3513 info.GetFileActionForFD(STDERR_FILENO) == nullptr) {
3514 LLDB_LOG(log, "at least one of stdin/stdout/stderr was not set, evaluating "
3515 "default handling");
3516
3517 if (info.GetFlags().Test(bit: eLaunchFlagLaunchInTTY)) {
3518 // Do nothing, if we are launching in a remote terminal no file actions
3519 // should be done at all.
3520 return;
3521 }
3522
3523 if (info.GetFlags().Test(bit: eLaunchFlagDisableSTDIO)) {
3524 LLDB_LOG(log, "eLaunchFlagDisableSTDIO set, adding suppression action "
3525 "for stdin, stdout and stderr");
3526 info.AppendSuppressFileAction(STDIN_FILENO, read: true, write: false);
3527 info.AppendSuppressFileAction(STDOUT_FILENO, read: false, write: true);
3528 info.AppendSuppressFileAction(STDERR_FILENO, read: false, write: true);
3529 } else {
3530 // Check for any values that might have gotten set with any of: (lldb)
3531 // settings set target.input-path (lldb) settings set target.output-path
3532 // (lldb) settings set target.error-path
3533 FileSpec in_file_spec;
3534 FileSpec out_file_spec;
3535 FileSpec err_file_spec;
3536 // Only override with the target settings if we don't already have an
3537 // action for in, out or error
3538 if (info.GetFileActionForFD(STDIN_FILENO) == nullptr)
3539 in_file_spec = GetStandardInputPath();
3540 if (info.GetFileActionForFD(STDOUT_FILENO) == nullptr)
3541 out_file_spec = GetStandardOutputPath();
3542 if (info.GetFileActionForFD(STDERR_FILENO) == nullptr)
3543 err_file_spec = GetStandardErrorPath();
3544
3545 LLDB_LOG(log, "target stdin='{0}', target stdout='{1}', stderr='{1}'",
3546 in_file_spec, out_file_spec, err_file_spec);
3547
3548 if (in_file_spec) {
3549 info.AppendOpenFileAction(STDIN_FILENO, file_spec: in_file_spec, read: true, write: false);
3550 LLDB_LOG(log, "appended stdin open file action for {0}", in_file_spec);
3551 }
3552
3553 if (out_file_spec) {
3554 info.AppendOpenFileAction(STDOUT_FILENO, file_spec: out_file_spec, read: false, write: true);
3555 LLDB_LOG(log, "appended stdout open file action for {0}",
3556 out_file_spec);
3557 }
3558
3559 if (err_file_spec) {
3560 info.AppendOpenFileAction(STDERR_FILENO, file_spec: err_file_spec, read: false, write: true);
3561 LLDB_LOG(log, "appended stderr open file action for {0}",
3562 err_file_spec);
3563 }
3564
3565 if (default_to_use_pty) {
3566 llvm::Error Err = info.SetUpPtyRedirection();
3567 LLDB_LOG_ERROR(log, std::move(Err), "SetUpPtyRedirection failed: {0}");
3568 }
3569 }
3570 }
3571}
3572
3573void Target::AddDummySignal(llvm::StringRef name, LazyBool pass, LazyBool notify,
3574 LazyBool stop) {
3575 if (name.empty())
3576 return;
3577 // Don't add a signal if all the actions are trivial:
3578 if (pass == eLazyBoolCalculate && notify == eLazyBoolCalculate
3579 && stop == eLazyBoolCalculate)
3580 return;
3581
3582 auto& elem = m_dummy_signals[name];
3583 elem.pass = pass;
3584 elem.notify = notify;
3585 elem.stop = stop;
3586}
3587
3588bool Target::UpdateSignalFromDummy(UnixSignalsSP signals_sp,
3589 const DummySignalElement &elem) {
3590 if (!signals_sp)
3591 return false;
3592
3593 int32_t signo
3594 = signals_sp->GetSignalNumberFromName(name: elem.first().str().c_str());
3595 if (signo == LLDB_INVALID_SIGNAL_NUMBER)
3596 return false;
3597
3598 if (elem.second.pass == eLazyBoolYes)
3599 signals_sp->SetShouldSuppress(signo, value: false);
3600 else if (elem.second.pass == eLazyBoolNo)
3601 signals_sp->SetShouldSuppress(signo, value: true);
3602
3603 if (elem.second.notify == eLazyBoolYes)
3604 signals_sp->SetShouldNotify(signo, value: true);
3605 else if (elem.second.notify == eLazyBoolNo)
3606 signals_sp->SetShouldNotify(signo, value: false);
3607
3608 if (elem.second.stop == eLazyBoolYes)
3609 signals_sp->SetShouldStop(signo, value: true);
3610 else if (elem.second.stop == eLazyBoolNo)
3611 signals_sp->SetShouldStop(signo, value: false);
3612 return true;
3613}
3614
3615bool Target::ResetSignalFromDummy(UnixSignalsSP signals_sp,
3616 const DummySignalElement &elem) {
3617 if (!signals_sp)
3618 return false;
3619 int32_t signo
3620 = signals_sp->GetSignalNumberFromName(name: elem.first().str().c_str());
3621 if (signo == LLDB_INVALID_SIGNAL_NUMBER)
3622 return false;
3623 bool do_pass = elem.second.pass != eLazyBoolCalculate;
3624 bool do_stop = elem.second.stop != eLazyBoolCalculate;
3625 bool do_notify = elem.second.notify != eLazyBoolCalculate;
3626 signals_sp->ResetSignal(signo, reset_stop: do_stop, reset_notify: do_notify, reset_suppress: do_pass);
3627 return true;
3628}
3629
3630void Target::UpdateSignalsFromDummy(UnixSignalsSP signals_sp,
3631 StreamSP warning_stream_sp) {
3632 if (!signals_sp)
3633 return;
3634
3635 for (const auto &elem : m_dummy_signals) {
3636 if (!UpdateSignalFromDummy(signals_sp, elem))
3637 warning_stream_sp->Printf(format: "Target signal '%s' not found in process\n",
3638 elem.first().str().c_str());
3639 }
3640}
3641
3642void Target::ClearDummySignals(Args &signal_names) {
3643 ProcessSP process_sp = GetProcessSP();
3644 // The simplest case, delete them all with no process to update.
3645 if (signal_names.GetArgumentCount() == 0 && !process_sp) {
3646 m_dummy_signals.clear();
3647 return;
3648 }
3649 UnixSignalsSP signals_sp;
3650 if (process_sp)
3651 signals_sp = process_sp->GetUnixSignals();
3652
3653 for (const Args::ArgEntry &entry : signal_names) {
3654 const char *signal_name = entry.c_str();
3655 auto elem = m_dummy_signals.find(Key: signal_name);
3656 // If we didn't find it go on.
3657 // FIXME: Should I pipe error handling through here?
3658 if (elem == m_dummy_signals.end()) {
3659 continue;
3660 }
3661 if (signals_sp)
3662 ResetSignalFromDummy(signals_sp, elem: *elem);
3663 m_dummy_signals.erase(I: elem);
3664 }
3665}
3666
3667void Target::PrintDummySignals(Stream &strm, Args &signal_args) {
3668 strm.Printf(format: "NAME PASS STOP NOTIFY\n");
3669 strm.Printf(format: "=========== ======= ======= =======\n");
3670
3671 auto str_for_lazy = [] (LazyBool lazy) -> const char * {
3672 switch (lazy) {
3673 case eLazyBoolCalculate: return "not set";
3674 case eLazyBoolYes: return "true ";
3675 case eLazyBoolNo: return "false ";
3676 }
3677 llvm_unreachable("Fully covered switch above!");
3678 };
3679 size_t num_args = signal_args.GetArgumentCount();
3680 for (const auto &elem : m_dummy_signals) {
3681 bool print_it = false;
3682 for (size_t idx = 0; idx < num_args; idx++) {
3683 if (elem.first() == signal_args.GetArgumentAtIndex(idx)) {
3684 print_it = true;
3685 break;
3686 }
3687 }
3688 if (print_it) {
3689 strm.Printf(format: "%-11s ", elem.first().str().c_str());
3690 strm.Printf(format: "%s %s %s\n", str_for_lazy(elem.second.pass),
3691 str_for_lazy(elem.second.stop),
3692 str_for_lazy(elem.second.notify));
3693 }
3694 }
3695}
3696
3697// Target::StopHook
3698Target::StopHook::StopHook(lldb::TargetSP target_sp, lldb::user_id_t uid)
3699 : UserID(uid), m_target_sp(target_sp), m_specifier_sp(),
3700 m_thread_spec_up() {}
3701
3702Target::StopHook::StopHook(const StopHook &rhs)
3703 : UserID(rhs.GetID()), m_target_sp(rhs.m_target_sp),
3704 m_specifier_sp(rhs.m_specifier_sp), m_thread_spec_up(),
3705 m_active(rhs.m_active), m_auto_continue(rhs.m_auto_continue) {
3706 if (rhs.m_thread_spec_up)
3707 m_thread_spec_up = std::make_unique<ThreadSpec>(args&: *rhs.m_thread_spec_up);
3708}
3709
3710void Target::StopHook::SetSpecifier(SymbolContextSpecifier *specifier) {
3711 m_specifier_sp.reset(p: specifier);
3712}
3713
3714void Target::StopHook::SetThreadSpecifier(ThreadSpec *specifier) {
3715 m_thread_spec_up.reset(p: specifier);
3716}
3717
3718bool Target::StopHook::ExecutionContextPasses(const ExecutionContext &exc_ctx) {
3719 SymbolContextSpecifier *specifier = GetSpecifier();
3720 if (!specifier)
3721 return true;
3722
3723 bool will_run = true;
3724 if (exc_ctx.GetFramePtr())
3725 will_run = GetSpecifier()->SymbolContextMatches(
3726 sc: exc_ctx.GetFramePtr()->GetSymbolContext(resolve_scope: eSymbolContextEverything));
3727 if (will_run && GetThreadSpecifier() != nullptr)
3728 will_run =
3729 GetThreadSpecifier()->ThreadPassesBasicTests(thread&: exc_ctx.GetThreadRef());
3730
3731 return will_run;
3732}
3733
3734void Target::StopHook::GetDescription(Stream &s,
3735 lldb::DescriptionLevel level) const {
3736
3737 // For brief descriptions, only print the subclass description:
3738 if (level == eDescriptionLevelBrief) {
3739 GetSubclassDescription(s, level);
3740 return;
3741 }
3742
3743 unsigned indent_level = s.GetIndentLevel();
3744
3745 s.SetIndentLevel(indent_level + 2);
3746
3747 s.Printf(format: "Hook: %" PRIu64 "\n", GetID());
3748 if (m_active)
3749 s.Indent(s: "State: enabled\n");
3750 else
3751 s.Indent(s: "State: disabled\n");
3752
3753 if (m_auto_continue)
3754 s.Indent(s: "AutoContinue on\n");
3755
3756 if (m_specifier_sp) {
3757 s.Indent();
3758 s.PutCString(cstr: "Specifier:\n");
3759 s.SetIndentLevel(indent_level + 4);
3760 m_specifier_sp->GetDescription(s: &s, level);
3761 s.SetIndentLevel(indent_level + 2);
3762 }
3763
3764 if (m_thread_spec_up) {
3765 StreamString tmp;
3766 s.Indent(s: "Thread:\n");
3767 m_thread_spec_up->GetDescription(s: &tmp, level);
3768 s.SetIndentLevel(indent_level + 4);
3769 s.Indent(s: tmp.GetString());
3770 s.PutCString(cstr: "\n");
3771 s.SetIndentLevel(indent_level + 2);
3772 }
3773 GetSubclassDescription(s, level);
3774}
3775
3776void Target::StopHookCommandLine::GetSubclassDescription(
3777 Stream &s, lldb::DescriptionLevel level) const {
3778 // The brief description just prints the first command.
3779 if (level == eDescriptionLevelBrief) {
3780 if (m_commands.GetSize() == 1)
3781 s.PutCString(cstr: m_commands.GetStringAtIndex(idx: 0));
3782 return;
3783 }
3784 s.Indent(s: "Commands: \n");
3785 s.SetIndentLevel(s.GetIndentLevel() + 4);
3786 uint32_t num_commands = m_commands.GetSize();
3787 for (uint32_t i = 0; i < num_commands; i++) {
3788 s.Indent(s: m_commands.GetStringAtIndex(idx: i));
3789 s.PutCString(cstr: "\n");
3790 }
3791 s.SetIndentLevel(s.GetIndentLevel() - 4);
3792}
3793
3794// Target::StopHookCommandLine
3795void Target::StopHookCommandLine::SetActionFromString(const std::string &string) {
3796 GetCommands().SplitIntoLines(lines: string);
3797}
3798
3799void Target::StopHookCommandLine::SetActionFromStrings(
3800 const std::vector<std::string> &strings) {
3801 for (auto string : strings)
3802 GetCommands().AppendString(str: string.c_str());
3803}
3804
3805Target::StopHook::StopHookResult
3806Target::StopHookCommandLine::HandleStop(ExecutionContext &exc_ctx,
3807 StreamSP output_sp) {
3808 assert(exc_ctx.GetTargetPtr() && "Can't call PerformAction on a context "
3809 "with no target");
3810
3811 if (!m_commands.GetSize())
3812 return StopHookResult::KeepStopped;
3813
3814 CommandReturnObject result(false);
3815 result.SetImmediateOutputStream(output_sp);
3816 result.SetInteractive(false);
3817 Debugger &debugger = exc_ctx.GetTargetPtr()->GetDebugger();
3818 CommandInterpreterRunOptions options;
3819 options.SetStopOnContinue(true);
3820 options.SetStopOnError(true);
3821 options.SetEchoCommands(false);
3822 options.SetPrintResults(true);
3823 options.SetPrintErrors(true);
3824 options.SetAddToHistory(false);
3825
3826 // Force Async:
3827 bool old_async = debugger.GetAsyncExecution();
3828 debugger.SetAsyncExecution(true);
3829 debugger.GetCommandInterpreter().HandleCommands(commands: GetCommands(), context: exc_ctx,
3830 options, result);
3831 debugger.SetAsyncExecution(old_async);
3832 lldb::ReturnStatus status = result.GetStatus();
3833 if (status == eReturnStatusSuccessContinuingNoResult ||
3834 status == eReturnStatusSuccessContinuingResult)
3835 return StopHookResult::AlreadyContinued;
3836 return StopHookResult::KeepStopped;
3837}
3838
3839// Target::StopHookScripted
3840Status Target::StopHookScripted::SetScriptCallback(
3841 std::string class_name, StructuredData::ObjectSP extra_args_sp) {
3842 Status error;
3843
3844 ScriptInterpreter *script_interp =
3845 GetTarget()->GetDebugger().GetScriptInterpreter();
3846 if (!script_interp) {
3847 error.SetErrorString("No script interpreter installed.");
3848 return error;
3849 }
3850
3851 m_class_name = class_name;
3852 m_extra_args.SetObjectSP(extra_args_sp);
3853
3854 m_implementation_sp = script_interp->CreateScriptedStopHook(
3855 target_sp: GetTarget(), class_name: m_class_name.c_str(), args_data: m_extra_args, error);
3856
3857 return error;
3858}
3859
3860Target::StopHook::StopHookResult
3861Target::StopHookScripted::HandleStop(ExecutionContext &exc_ctx,
3862 StreamSP output_sp) {
3863 assert(exc_ctx.GetTargetPtr() && "Can't call HandleStop on a context "
3864 "with no target");
3865
3866 ScriptInterpreter *script_interp =
3867 GetTarget()->GetDebugger().GetScriptInterpreter();
3868 if (!script_interp)
3869 return StopHookResult::KeepStopped;
3870
3871 bool should_stop = script_interp->ScriptedStopHookHandleStop(
3872 implementor_sp: m_implementation_sp, exc_ctx, stream_sp: output_sp);
3873
3874 return should_stop ? StopHookResult::KeepStopped
3875 : StopHookResult::RequestContinue;
3876}
3877
3878void Target::StopHookScripted::GetSubclassDescription(
3879 Stream &s, lldb::DescriptionLevel level) const {
3880 if (level == eDescriptionLevelBrief) {
3881 s.PutCString(cstr: m_class_name);
3882 return;
3883 }
3884 s.Indent(s: "Class:");
3885 s.Printf(format: "%s\n", m_class_name.c_str());
3886
3887 // Now print the extra args:
3888 // FIXME: We should use StructuredData.GetDescription on the m_extra_args
3889 // but that seems to rely on some printing plugin that doesn't exist.
3890 if (!m_extra_args.IsValid())
3891 return;
3892 StructuredData::ObjectSP object_sp = m_extra_args.GetObjectSP();
3893 if (!object_sp || !object_sp->IsValid())
3894 return;
3895
3896 StructuredData::Dictionary *as_dict = object_sp->GetAsDictionary();
3897 if (!as_dict || !as_dict->IsValid())
3898 return;
3899
3900 uint32_t num_keys = as_dict->GetSize();
3901 if (num_keys == 0)
3902 return;
3903
3904 s.Indent(s: "Args:\n");
3905 s.SetIndentLevel(s.GetIndentLevel() + 4);
3906
3907 auto print_one_element = [&s](llvm::StringRef key,
3908 StructuredData::Object *object) {
3909 s.Indent();
3910 s.Format(format: "{0} : {1}\n", args&: key, args: object->GetStringValue());
3911 return true;
3912 };
3913
3914 as_dict->ForEach(callback: print_one_element);
3915
3916 s.SetIndentLevel(s.GetIndentLevel() - 4);
3917}
3918
3919static constexpr OptionEnumValueElement g_dynamic_value_types[] = {
3920 {
3921 .value: eNoDynamicValues,
3922 .string_value: "no-dynamic-values",
3923 .usage: "Don't calculate the dynamic type of values",
3924 },
3925 {
3926 .value: eDynamicCanRunTarget,
3927 .string_value: "run-target",
3928 .usage: "Calculate the dynamic type of values "
3929 "even if you have to run the target.",
3930 },
3931 {
3932 .value: eDynamicDontRunTarget,
3933 .string_value: "no-run-target",
3934 .usage: "Calculate the dynamic type of values, but don't run the target.",
3935 },
3936};
3937
3938OptionEnumValues lldb_private::GetDynamicValueTypes() {
3939 return OptionEnumValues(g_dynamic_value_types);
3940}
3941
3942static constexpr OptionEnumValueElement g_inline_breakpoint_enums[] = {
3943 {
3944 .value: eInlineBreakpointsNever,
3945 .string_value: "never",
3946 .usage: "Never look for inline breakpoint locations (fastest). This setting "
3947 "should only be used if you know that no inlining occurs in your"
3948 "programs.",
3949 },
3950 {
3951 .value: eInlineBreakpointsHeaders,
3952 .string_value: "headers",
3953 .usage: "Only check for inline breakpoint locations when setting breakpoints "
3954 "in header files, but not when setting breakpoint in implementation "
3955 "source files (default).",
3956 },
3957 {
3958 .value: eInlineBreakpointsAlways,
3959 .string_value: "always",
3960 .usage: "Always look for inline breakpoint locations when setting file and "
3961 "line breakpoints (slower but most accurate).",
3962 },
3963};
3964
3965enum x86DisassemblyFlavor {
3966 eX86DisFlavorDefault,
3967 eX86DisFlavorIntel,
3968 eX86DisFlavorATT
3969};
3970
3971static constexpr OptionEnumValueElement g_x86_dis_flavor_value_types[] = {
3972 {
3973 .value: eX86DisFlavorDefault,
3974 .string_value: "default",
3975 .usage: "Disassembler default (currently att).",
3976 },
3977 {
3978 .value: eX86DisFlavorIntel,
3979 .string_value: "intel",
3980 .usage: "Intel disassembler flavor.",
3981 },
3982 {
3983 .value: eX86DisFlavorATT,
3984 .string_value: "att",
3985 .usage: "AT&T disassembler flavor.",
3986 },
3987};
3988
3989static constexpr OptionEnumValueElement g_import_std_module_value_types[] = {
3990 {
3991 .value: eImportStdModuleFalse,
3992 .string_value: "false",
3993 .usage: "Never import the 'std' C++ module in the expression parser.",
3994 },
3995 {
3996 .value: eImportStdModuleFallback,
3997 .string_value: "fallback",
3998 .usage: "Retry evaluating expressions with an imported 'std' C++ module if they"
3999 " failed to parse without the module. This allows evaluating more "
4000 "complex expressions involving C++ standard library types."
4001 },
4002 {
4003 .value: eImportStdModuleTrue,
4004 .string_value: "true",
4005 .usage: "Always import the 'std' C++ module. This allows evaluating more "
4006 "complex expressions involving C++ standard library types. This feature"
4007 " is experimental."
4008 },
4009};
4010
4011static constexpr OptionEnumValueElement
4012 g_dynamic_class_info_helper_value_types[] = {
4013 {
4014 .value: eDynamicClassInfoHelperAuto,
4015 .string_value: "auto",
4016 .usage: "Automatically determine the most appropriate method for the "
4017 "target OS.",
4018 },
4019 {.value: eDynamicClassInfoHelperRealizedClassesStruct, .string_value: "RealizedClassesStruct",
4020 .usage: "Prefer using the realized classes struct."},
4021 {.value: eDynamicClassInfoHelperCopyRealizedClassList, .string_value: "CopyRealizedClassList",
4022 .usage: "Prefer using the CopyRealizedClassList API."},
4023 {.value: eDynamicClassInfoHelperGetRealizedClassList, .string_value: "GetRealizedClassList",
4024 .usage: "Prefer using the GetRealizedClassList API."},
4025};
4026
4027static constexpr OptionEnumValueElement g_hex_immediate_style_values[] = {
4028 {
4029 .value: Disassembler::eHexStyleC,
4030 .string_value: "c",
4031 .usage: "C-style (0xffff).",
4032 },
4033 {
4034 .value: Disassembler::eHexStyleAsm,
4035 .string_value: "asm",
4036 .usage: "Asm-style (0ffffh).",
4037 },
4038};
4039
4040static constexpr OptionEnumValueElement g_load_script_from_sym_file_values[] = {
4041 {
4042 .value: eLoadScriptFromSymFileTrue,
4043 .string_value: "true",
4044 .usage: "Load debug scripts inside symbol files",
4045 },
4046 {
4047 .value: eLoadScriptFromSymFileFalse,
4048 .string_value: "false",
4049 .usage: "Do not load debug scripts inside symbol files.",
4050 },
4051 {
4052 .value: eLoadScriptFromSymFileWarn,
4053 .string_value: "warn",
4054 .usage: "Warn about debug scripts inside symbol files but do not load them.",
4055 },
4056};
4057
4058static constexpr OptionEnumValueElement g_load_cwd_lldbinit_values[] = {
4059 {
4060 .value: eLoadCWDlldbinitTrue,
4061 .string_value: "true",
4062 .usage: "Load .lldbinit files from current directory",
4063 },
4064 {
4065 .value: eLoadCWDlldbinitFalse,
4066 .string_value: "false",
4067 .usage: "Do not load .lldbinit files from current directory",
4068 },
4069 {
4070 .value: eLoadCWDlldbinitWarn,
4071 .string_value: "warn",
4072 .usage: "Warn about loading .lldbinit files from current directory",
4073 },
4074};
4075
4076static constexpr OptionEnumValueElement g_memory_module_load_level_values[] = {
4077 {
4078 .value: eMemoryModuleLoadLevelMinimal,
4079 .string_value: "minimal",
4080 .usage: "Load minimal information when loading modules from memory. Currently "
4081 "this setting loads sections only.",
4082 },
4083 {
4084 .value: eMemoryModuleLoadLevelPartial,
4085 .string_value: "partial",
4086 .usage: "Load partial information when loading modules from memory. Currently "
4087 "this setting loads sections and function bounds.",
4088 },
4089 {
4090 .value: eMemoryModuleLoadLevelComplete,
4091 .string_value: "complete",
4092 .usage: "Load complete information when loading modules from memory. Currently "
4093 "this setting loads sections and all symbols.",
4094 },
4095};
4096
4097#define LLDB_PROPERTIES_target
4098#include "TargetProperties.inc"
4099
4100enum {
4101#define LLDB_PROPERTIES_target
4102#include "TargetPropertiesEnum.inc"
4103 ePropertyExperimental,
4104};
4105
4106class TargetOptionValueProperties
4107 : public Cloneable<TargetOptionValueProperties, OptionValueProperties> {
4108public:
4109 TargetOptionValueProperties(llvm::StringRef name) : Cloneable(name) {}
4110
4111 const Property *
4112 GetPropertyAtIndex(size_t idx,
4113 const ExecutionContext *exe_ctx = nullptr) const override {
4114 // When getting the value for a key from the target options, we will always
4115 // try and grab the setting from the current target if there is one. Else
4116 // we just use the one from this instance.
4117 if (exe_ctx) {
4118 Target *target = exe_ctx->GetTargetPtr();
4119 if (target) {
4120 TargetOptionValueProperties *target_properties =
4121 static_cast<TargetOptionValueProperties *>(
4122 target->GetValueProperties().get());
4123 if (this != target_properties)
4124 return target_properties->ProtectedGetPropertyAtIndex(idx);
4125 }
4126 }
4127 return ProtectedGetPropertyAtIndex(idx);
4128 }
4129};
4130
4131// TargetProperties
4132#define LLDB_PROPERTIES_target_experimental
4133#include "TargetProperties.inc"
4134
4135enum {
4136#define LLDB_PROPERTIES_target_experimental
4137#include "TargetPropertiesEnum.inc"
4138};
4139
4140class TargetExperimentalOptionValueProperties
4141 : public Cloneable<TargetExperimentalOptionValueProperties,
4142 OptionValueProperties> {
4143public:
4144 TargetExperimentalOptionValueProperties()
4145 : Cloneable(Properties::GetExperimentalSettingsName()) {}
4146};
4147
4148TargetExperimentalProperties::TargetExperimentalProperties()
4149 : Properties(OptionValuePropertiesSP(
4150 new TargetExperimentalOptionValueProperties())) {
4151 m_collection_sp->Initialize(setting_definitions: g_target_experimental_properties);
4152}
4153
4154// TargetProperties
4155TargetProperties::TargetProperties(Target *target)
4156 : Properties(), m_launch_info(), m_target(target) {
4157 if (target) {
4158 m_collection_sp =
4159 OptionValueProperties::CreateLocalCopy(global_properties: Target::GetGlobalProperties());
4160
4161 // Set callbacks to update launch_info whenever "settins set" updated any
4162 // of these properties
4163 m_collection_sp->SetValueChangedCallback(
4164 property_idx: ePropertyArg0, callback: [this] { Arg0ValueChangedCallback(); });
4165 m_collection_sp->SetValueChangedCallback(
4166 property_idx: ePropertyRunArgs, callback: [this] { RunArgsValueChangedCallback(); });
4167 m_collection_sp->SetValueChangedCallback(
4168 property_idx: ePropertyEnvVars, callback: [this] { EnvVarsValueChangedCallback(); });
4169 m_collection_sp->SetValueChangedCallback(
4170 property_idx: ePropertyUnsetEnvVars, callback: [this] { EnvVarsValueChangedCallback(); });
4171 m_collection_sp->SetValueChangedCallback(
4172 property_idx: ePropertyInheritEnv, callback: [this] { EnvVarsValueChangedCallback(); });
4173 m_collection_sp->SetValueChangedCallback(
4174 property_idx: ePropertyInputPath, callback: [this] { InputPathValueChangedCallback(); });
4175 m_collection_sp->SetValueChangedCallback(
4176 property_idx: ePropertyOutputPath, callback: [this] { OutputPathValueChangedCallback(); });
4177 m_collection_sp->SetValueChangedCallback(
4178 property_idx: ePropertyErrorPath, callback: [this] { ErrorPathValueChangedCallback(); });
4179 m_collection_sp->SetValueChangedCallback(property_idx: ePropertyDetachOnError, callback: [this] {
4180 DetachOnErrorValueChangedCallback();
4181 });
4182 m_collection_sp->SetValueChangedCallback(
4183 property_idx: ePropertyDisableASLR, callback: [this] { DisableASLRValueChangedCallback(); });
4184 m_collection_sp->SetValueChangedCallback(
4185 property_idx: ePropertyInheritTCC, callback: [this] { InheritTCCValueChangedCallback(); });
4186 m_collection_sp->SetValueChangedCallback(
4187 property_idx: ePropertyDisableSTDIO, callback: [this] { DisableSTDIOValueChangedCallback(); });
4188
4189 m_collection_sp->SetValueChangedCallback(
4190 property_idx: ePropertySaveObjectsDir, callback: [this] { CheckJITObjectsDir(); });
4191 m_experimental_properties_up =
4192 std::make_unique<TargetExperimentalProperties>();
4193 m_collection_sp->AppendProperty(
4194 name: Properties::GetExperimentalSettingsName(),
4195 desc: "Experimental settings - setting these won't produce "
4196 "errors if the setting is not present.",
4197 is_global: true, value_sp: m_experimental_properties_up->GetValueProperties());
4198 } else {
4199 m_collection_sp = std::make_shared<TargetOptionValueProperties>(args: "target");
4200 m_collection_sp->Initialize(setting_definitions: g_target_properties);
4201 m_experimental_properties_up =
4202 std::make_unique<TargetExperimentalProperties>();
4203 m_collection_sp->AppendProperty(
4204 name: Properties::GetExperimentalSettingsName(),
4205 desc: "Experimental settings - setting these won't produce "
4206 "errors if the setting is not present.",
4207 is_global: true, value_sp: m_experimental_properties_up->GetValueProperties());
4208 m_collection_sp->AppendProperty(
4209 name: "process", desc: "Settings specific to processes.", is_global: true,
4210 value_sp: Process::GetGlobalProperties().GetValueProperties());
4211 m_collection_sp->SetValueChangedCallback(
4212 property_idx: ePropertySaveObjectsDir, callback: [this] { CheckJITObjectsDir(); });
4213 }
4214}
4215
4216TargetProperties::~TargetProperties() = default;
4217
4218void TargetProperties::UpdateLaunchInfoFromProperties() {
4219 Arg0ValueChangedCallback();
4220 RunArgsValueChangedCallback();
4221 EnvVarsValueChangedCallback();
4222 InputPathValueChangedCallback();
4223 OutputPathValueChangedCallback();
4224 ErrorPathValueChangedCallback();
4225 DetachOnErrorValueChangedCallback();
4226 DisableASLRValueChangedCallback();
4227 InheritTCCValueChangedCallback();
4228 DisableSTDIOValueChangedCallback();
4229}
4230
4231std::optional<bool> TargetProperties::GetExperimentalPropertyValue(
4232 size_t prop_idx, ExecutionContext *exe_ctx) const {
4233 const Property *exp_property =
4234 m_collection_sp->GetPropertyAtIndex(idx: ePropertyExperimental, exe_ctx);
4235 OptionValueProperties *exp_values =
4236 exp_property->GetValue()->GetAsProperties();
4237 if (exp_values)
4238 return exp_values->GetPropertyAtIndexAs<bool>(idx: prop_idx, exe_ctx);
4239 return std::nullopt;
4240}
4241
4242bool TargetProperties::GetInjectLocalVariables(
4243 ExecutionContext *exe_ctx) const {
4244 return GetExperimentalPropertyValue(prop_idx: ePropertyInjectLocalVars, exe_ctx)
4245 .value_or(true);
4246}
4247
4248ArchSpec TargetProperties::GetDefaultArchitecture() const {
4249 const uint32_t idx = ePropertyDefaultArch;
4250 return GetPropertyAtIndexAs<ArchSpec>(idx, default_value: {});
4251}
4252
4253void TargetProperties::SetDefaultArchitecture(const ArchSpec &arch) {
4254 const uint32_t idx = ePropertyDefaultArch;
4255 SetPropertyAtIndex(idx, t: arch);
4256}
4257
4258bool TargetProperties::GetMoveToNearestCode() const {
4259 const uint32_t idx = ePropertyMoveToNearestCode;
4260 return GetPropertyAtIndexAs<bool>(
4261 idx, g_target_properties[idx].default_uint_value != 0);
4262}
4263
4264lldb::DynamicValueType TargetProperties::GetPreferDynamicValue() const {
4265 const uint32_t idx = ePropertyPreferDynamic;
4266 return GetPropertyAtIndexAs<lldb::DynamicValueType>(
4267 idx, static_cast<lldb::DynamicValueType>(
4268 g_target_properties[idx].default_uint_value));
4269}
4270
4271bool TargetProperties::SetPreferDynamicValue(lldb::DynamicValueType d) {
4272 const uint32_t idx = ePropertyPreferDynamic;
4273 return SetPropertyAtIndex(idx, t: d);
4274}
4275
4276bool TargetProperties::GetPreloadSymbols() const {
4277 if (INTERRUPT_REQUESTED(m_target->GetDebugger(),
4278 "Interrupted checking preload symbols")) {
4279 return false;
4280 }
4281 const uint32_t idx = ePropertyPreloadSymbols;
4282 return GetPropertyAtIndexAs<bool>(
4283 idx, g_target_properties[idx].default_uint_value != 0);
4284}
4285
4286void TargetProperties::SetPreloadSymbols(bool b) {
4287 const uint32_t idx = ePropertyPreloadSymbols;
4288 SetPropertyAtIndex(idx, t: b);
4289}
4290
4291bool TargetProperties::GetDisableASLR() const {
4292 const uint32_t idx = ePropertyDisableASLR;
4293 return GetPropertyAtIndexAs<bool>(
4294 idx, g_target_properties[idx].default_uint_value != 0);
4295}
4296
4297void TargetProperties::SetDisableASLR(bool b) {
4298 const uint32_t idx = ePropertyDisableASLR;
4299 SetPropertyAtIndex(idx, t: b);
4300}
4301
4302bool TargetProperties::GetInheritTCC() const {
4303 const uint32_t idx = ePropertyInheritTCC;
4304 return GetPropertyAtIndexAs<bool>(
4305 idx, g_target_properties[idx].default_uint_value != 0);
4306}
4307
4308void TargetProperties::SetInheritTCC(bool b) {
4309 const uint32_t idx = ePropertyInheritTCC;
4310 SetPropertyAtIndex(idx, t: b);
4311}
4312
4313bool TargetProperties::GetDetachOnError() const {
4314 const uint32_t idx = ePropertyDetachOnError;
4315 return GetPropertyAtIndexAs<bool>(
4316 idx, g_target_properties[idx].default_uint_value != 0);
4317}
4318
4319void TargetProperties::SetDetachOnError(bool b) {
4320 const uint32_t idx = ePropertyDetachOnError;
4321 SetPropertyAtIndex(idx, t: b);
4322}
4323
4324bool TargetProperties::GetDisableSTDIO() const {
4325 const uint32_t idx = ePropertyDisableSTDIO;
4326 return GetPropertyAtIndexAs<bool>(
4327 idx, g_target_properties[idx].default_uint_value != 0);
4328}
4329
4330void TargetProperties::SetDisableSTDIO(bool b) {
4331 const uint32_t idx = ePropertyDisableSTDIO;
4332 SetPropertyAtIndex(idx, t: b);
4333}
4334
4335const char *TargetProperties::GetDisassemblyFlavor() const {
4336 const uint32_t idx = ePropertyDisassemblyFlavor;
4337 const char *return_value;
4338
4339 x86DisassemblyFlavor flavor_value =
4340 GetPropertyAtIndexAs<x86DisassemblyFlavor>(
4341 idx, static_cast<x86DisassemblyFlavor>(
4342 g_target_properties[idx].default_uint_value));
4343
4344 return_value = g_x86_dis_flavor_value_types[flavor_value].string_value;
4345 return return_value;
4346}
4347
4348InlineStrategy TargetProperties::GetInlineStrategy() const {
4349 const uint32_t idx = ePropertyInlineStrategy;
4350 return GetPropertyAtIndexAs<InlineStrategy>(
4351 idx,
4352 static_cast<InlineStrategy>(g_target_properties[idx].default_uint_value));
4353}
4354
4355llvm::StringRef TargetProperties::GetArg0() const {
4356 const uint32_t idx = ePropertyArg0;
4357 return GetPropertyAtIndexAs<llvm::StringRef>(
4358 idx, g_target_properties[idx].default_cstr_value);
4359}
4360
4361void TargetProperties::SetArg0(llvm::StringRef arg) {
4362 const uint32_t idx = ePropertyArg0;
4363 SetPropertyAtIndex(idx, t: arg);
4364 m_launch_info.SetArg0(arg);
4365}
4366
4367bool TargetProperties::GetRunArguments(Args &args) const {
4368 const uint32_t idx = ePropertyRunArgs;
4369 return m_collection_sp->GetPropertyAtIndexAsArgs(idx, args);
4370}
4371
4372void TargetProperties::SetRunArguments(const Args &args) {
4373 const uint32_t idx = ePropertyRunArgs;
4374 m_collection_sp->SetPropertyAtIndexFromArgs(idx, args);
4375 m_launch_info.GetArguments() = args;
4376}
4377
4378Environment TargetProperties::ComputeEnvironment() const {
4379 Environment env;
4380
4381 if (m_target &&
4382 GetPropertyAtIndexAs<bool>(
4383 ePropertyInheritEnv,
4384 g_target_properties[ePropertyInheritEnv].default_uint_value != 0)) {
4385 if (auto platform_sp = m_target->GetPlatform()) {
4386 Environment platform_env = platform_sp->GetEnvironment();
4387 for (const auto &KV : platform_env)
4388 env[KV.first()] = KV.second;
4389 }
4390 }
4391
4392 Args property_unset_env;
4393 m_collection_sp->GetPropertyAtIndexAsArgs(ePropertyUnsetEnvVars,
4394 property_unset_env);
4395 for (const auto &var : property_unset_env)
4396 env.erase(Key: var.ref());
4397
4398 Args property_env;
4399 m_collection_sp->GetPropertyAtIndexAsArgs(ePropertyEnvVars, property_env);
4400 for (const auto &KV : Environment(property_env))
4401 env[KV.first()] = KV.second;
4402
4403 return env;
4404}
4405
4406Environment TargetProperties::GetEnvironment() const {
4407 return ComputeEnvironment();
4408}
4409
4410Environment TargetProperties::GetInheritedEnvironment() const {
4411 Environment environment;
4412
4413 if (m_target == nullptr)
4414 return environment;
4415
4416 if (!GetPropertyAtIndexAs<bool>(
4417 ePropertyInheritEnv,
4418 g_target_properties[ePropertyInheritEnv].default_uint_value != 0))
4419 return environment;
4420
4421 PlatformSP platform_sp = m_target->GetPlatform();
4422 if (platform_sp == nullptr)
4423 return environment;
4424
4425 Environment platform_environment = platform_sp->GetEnvironment();
4426 for (const auto &KV : platform_environment)
4427 environment[KV.first()] = KV.second;
4428
4429 Args property_unset_environment;
4430 m_collection_sp->GetPropertyAtIndexAsArgs(ePropertyUnsetEnvVars,
4431 property_unset_environment);
4432 for (const auto &var : property_unset_environment)
4433 environment.erase(Key: var.ref());
4434
4435 return environment;
4436}
4437
4438Environment TargetProperties::GetTargetEnvironment() const {
4439 Args property_environment;
4440 m_collection_sp->GetPropertyAtIndexAsArgs(ePropertyEnvVars,
4441 property_environment);
4442 Environment environment;
4443 for (const auto &KV : Environment(property_environment))
4444 environment[KV.first()] = KV.second;
4445
4446 return environment;
4447}
4448
4449void TargetProperties::SetEnvironment(Environment env) {
4450 // TODO: Get rid of the Args intermediate step
4451 const uint32_t idx = ePropertyEnvVars;
4452 m_collection_sp->SetPropertyAtIndexFromArgs(idx, args: Args(env));
4453}
4454
4455bool TargetProperties::GetSkipPrologue() const {
4456 const uint32_t idx = ePropertySkipPrologue;
4457 return GetPropertyAtIndexAs<bool>(
4458 idx, g_target_properties[idx].default_uint_value != 0);
4459}
4460
4461PathMappingList &TargetProperties::GetSourcePathMap() const {
4462 const uint32_t idx = ePropertySourceMap;
4463 OptionValuePathMappings *option_value =
4464 m_collection_sp->GetPropertyAtIndexAsOptionValuePathMappings(idx);
4465 assert(option_value);
4466 return option_value->GetCurrentValue();
4467}
4468
4469bool TargetProperties::GetAutoSourceMapRelative() const {
4470 const uint32_t idx = ePropertyAutoSourceMapRelative;
4471 return GetPropertyAtIndexAs<bool>(
4472 idx, g_target_properties[idx].default_uint_value != 0);
4473}
4474
4475void TargetProperties::AppendExecutableSearchPaths(const FileSpec &dir) {
4476 const uint32_t idx = ePropertyExecutableSearchPaths;
4477 OptionValueFileSpecList *option_value =
4478 m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(idx);
4479 assert(option_value);
4480 option_value->AppendCurrentValue(value: dir);
4481}
4482
4483FileSpecList TargetProperties::GetExecutableSearchPaths() {
4484 const uint32_t idx = ePropertyExecutableSearchPaths;
4485 return GetPropertyAtIndexAs<FileSpecList>(idx, default_value: {});
4486}
4487
4488FileSpecList TargetProperties::GetDebugFileSearchPaths() {
4489 const uint32_t idx = ePropertyDebugFileSearchPaths;
4490 return GetPropertyAtIndexAs<FileSpecList>(idx, default_value: {});
4491}
4492
4493FileSpecList TargetProperties::GetClangModuleSearchPaths() {
4494 const uint32_t idx = ePropertyClangModuleSearchPaths;
4495 return GetPropertyAtIndexAs<FileSpecList>(idx, default_value: {});
4496}
4497
4498bool TargetProperties::GetEnableAutoImportClangModules() const {
4499 const uint32_t idx = ePropertyAutoImportClangModules;
4500 return GetPropertyAtIndexAs<bool>(
4501 idx, g_target_properties[idx].default_uint_value != 0);
4502}
4503
4504ImportStdModule TargetProperties::GetImportStdModule() const {
4505 const uint32_t idx = ePropertyImportStdModule;
4506 return GetPropertyAtIndexAs<ImportStdModule>(
4507 idx, static_cast<ImportStdModule>(
4508 g_target_properties[idx].default_uint_value));
4509}
4510
4511DynamicClassInfoHelper TargetProperties::GetDynamicClassInfoHelper() const {
4512 const uint32_t idx = ePropertyDynamicClassInfoHelper;
4513 return GetPropertyAtIndexAs<DynamicClassInfoHelper>(
4514 idx, static_cast<DynamicClassInfoHelper>(
4515 g_target_properties[idx].default_uint_value));
4516}
4517
4518bool TargetProperties::GetEnableAutoApplyFixIts() const {
4519 const uint32_t idx = ePropertyAutoApplyFixIts;
4520 return GetPropertyAtIndexAs<bool>(
4521 idx, g_target_properties[idx].default_uint_value != 0);
4522}
4523
4524uint64_t TargetProperties::GetNumberOfRetriesWithFixits() const {
4525 const uint32_t idx = ePropertyRetriesWithFixIts;
4526 return GetPropertyAtIndexAs<uint64_t>(
4527 idx, g_target_properties[idx].default_uint_value);
4528}
4529
4530bool TargetProperties::GetEnableNotifyAboutFixIts() const {
4531 const uint32_t idx = ePropertyNotifyAboutFixIts;
4532 return GetPropertyAtIndexAs<bool>(
4533 idx, g_target_properties[idx].default_uint_value != 0);
4534}
4535
4536FileSpec TargetProperties::GetSaveJITObjectsDir() const {
4537 const uint32_t idx = ePropertySaveObjectsDir;
4538 return GetPropertyAtIndexAs<FileSpec>(idx, default_value: {});
4539}
4540
4541void TargetProperties::CheckJITObjectsDir() {
4542 FileSpec new_dir = GetSaveJITObjectsDir();
4543 if (!new_dir)
4544 return;
4545
4546 const FileSystem &instance = FileSystem::Instance();
4547 bool exists = instance.Exists(file_spec: new_dir);
4548 bool is_directory = instance.IsDirectory(file_spec: new_dir);
4549 std::string path = new_dir.GetPath(denormalize: true);
4550 bool writable = llvm::sys::fs::can_write(Path: path);
4551 if (exists && is_directory && writable)
4552 return;
4553
4554 m_collection_sp->GetPropertyAtIndex(ePropertySaveObjectsDir)
4555 ->GetValue()
4556 ->Clear();
4557
4558 std::string buffer;
4559 llvm::raw_string_ostream os(buffer);
4560 os << "JIT object dir '" << path << "' ";
4561 if (!exists)
4562 os << "does not exist";
4563 else if (!is_directory)
4564 os << "is not a directory";
4565 else if (!writable)
4566 os << "is not writable";
4567
4568 std::optional<lldb::user_id_t> debugger_id;
4569 if (m_target)
4570 debugger_id = m_target->GetDebugger().GetID();
4571 Debugger::ReportError(message: os.str(), debugger_id);
4572}
4573
4574bool TargetProperties::GetEnableSyntheticValue() const {
4575 const uint32_t idx = ePropertyEnableSynthetic;
4576 return GetPropertyAtIndexAs<bool>(
4577 idx, g_target_properties[idx].default_uint_value != 0);
4578}
4579
4580bool TargetProperties::ShowHexVariableValuesWithLeadingZeroes() const {
4581 const uint32_t idx = ePropertyShowHexVariableValuesWithLeadingZeroes;
4582 return GetPropertyAtIndexAs<bool>(
4583 idx, g_target_properties[idx].default_uint_value != 0);
4584}
4585
4586uint32_t TargetProperties::GetMaxZeroPaddingInFloatFormat() const {
4587 const uint32_t idx = ePropertyMaxZeroPaddingInFloatFormat;
4588 return GetPropertyAtIndexAs<uint64_t>(
4589 idx, g_target_properties[idx].default_uint_value);
4590}
4591
4592uint32_t TargetProperties::GetMaximumNumberOfChildrenToDisplay() const {
4593 const uint32_t idx = ePropertyMaxChildrenCount;
4594 return GetPropertyAtIndexAs<int64_t>(
4595 idx, g_target_properties[idx].default_uint_value);
4596}
4597
4598std::pair<uint32_t, bool>
4599TargetProperties::GetMaximumDepthOfChildrenToDisplay() const {
4600 const uint32_t idx = ePropertyMaxChildrenDepth;
4601 auto *option_value =
4602 m_collection_sp->GetPropertyAtIndexAsOptionValueUInt64(idx);
4603 bool is_default = !option_value->OptionWasSet();
4604 return {option_value->GetCurrentValue(), is_default};
4605}
4606
4607uint32_t TargetProperties::GetMaximumSizeOfStringSummary() const {
4608 const uint32_t idx = ePropertyMaxSummaryLength;
4609 return GetPropertyAtIndexAs<uint64_t>(
4610 idx, g_target_properties[idx].default_uint_value);
4611}
4612
4613uint32_t TargetProperties::GetMaximumMemReadSize() const {
4614 const uint32_t idx = ePropertyMaxMemReadSize;
4615 return GetPropertyAtIndexAs<uint64_t>(
4616 idx, g_target_properties[idx].default_uint_value);
4617}
4618
4619FileSpec TargetProperties::GetStandardInputPath() const {
4620 const uint32_t idx = ePropertyInputPath;
4621 return GetPropertyAtIndexAs<FileSpec>(idx, default_value: {});
4622}
4623
4624void TargetProperties::SetStandardInputPath(llvm::StringRef path) {
4625 const uint32_t idx = ePropertyInputPath;
4626 SetPropertyAtIndex(idx, t: path);
4627}
4628
4629FileSpec TargetProperties::GetStandardOutputPath() const {
4630 const uint32_t idx = ePropertyOutputPath;
4631 return GetPropertyAtIndexAs<FileSpec>(idx, default_value: {});
4632}
4633
4634void TargetProperties::SetStandardOutputPath(llvm::StringRef path) {
4635 const uint32_t idx = ePropertyOutputPath;
4636 SetPropertyAtIndex(idx, t: path);
4637}
4638
4639FileSpec TargetProperties::GetStandardErrorPath() const {
4640 const uint32_t idx = ePropertyErrorPath;
4641 return GetPropertyAtIndexAs<FileSpec>(idx, default_value: {});
4642}
4643
4644void TargetProperties::SetStandardErrorPath(llvm::StringRef path) {
4645 const uint32_t idx = ePropertyErrorPath;
4646 SetPropertyAtIndex(idx, t: path);
4647}
4648
4649LanguageType TargetProperties::GetLanguage() const {
4650 const uint32_t idx = ePropertyLanguage;
4651 return GetPropertyAtIndexAs<LanguageType>(idx, default_value: {});
4652}
4653
4654llvm::StringRef TargetProperties::GetExpressionPrefixContents() {
4655 const uint32_t idx = ePropertyExprPrefix;
4656 OptionValueFileSpec *file =
4657 m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpec(idx);
4658 if (file) {
4659 DataBufferSP data_sp(file->GetFileContents());
4660 if (data_sp)
4661 return llvm::StringRef(
4662 reinterpret_cast<const char *>(data_sp->GetBytes()),
4663 data_sp->GetByteSize());
4664 }
4665 return "";
4666}
4667
4668uint64_t TargetProperties::GetExprErrorLimit() const {
4669 const uint32_t idx = ePropertyExprErrorLimit;
4670 return GetPropertyAtIndexAs<uint64_t>(
4671 idx, g_target_properties[idx].default_uint_value);
4672}
4673
4674uint64_t TargetProperties::GetExprAllocAddress() const {
4675 const uint32_t idx = ePropertyExprAllocAddress;
4676 return GetPropertyAtIndexAs<uint64_t>(
4677 idx, g_target_properties[idx].default_uint_value);
4678}
4679
4680uint64_t TargetProperties::GetExprAllocSize() const {
4681 const uint32_t idx = ePropertyExprAllocSize;
4682 return GetPropertyAtIndexAs<uint64_t>(
4683 idx, g_target_properties[idx].default_uint_value);
4684}
4685
4686uint64_t TargetProperties::GetExprAllocAlign() const {
4687 const uint32_t idx = ePropertyExprAllocAlign;
4688 return GetPropertyAtIndexAs<uint64_t>(
4689 idx, g_target_properties[idx].default_uint_value);
4690}
4691
4692bool TargetProperties::GetBreakpointsConsultPlatformAvoidList() {
4693 const uint32_t idx = ePropertyBreakpointUseAvoidList;
4694 return GetPropertyAtIndexAs<bool>(
4695 idx, g_target_properties[idx].default_uint_value != 0);
4696}
4697
4698bool TargetProperties::GetUseHexImmediates() const {
4699 const uint32_t idx = ePropertyUseHexImmediates;
4700 return GetPropertyAtIndexAs<bool>(
4701 idx, g_target_properties[idx].default_uint_value != 0);
4702}
4703
4704bool TargetProperties::GetUseFastStepping() const {
4705 const uint32_t idx = ePropertyUseFastStepping;
4706 return GetPropertyAtIndexAs<bool>(
4707 idx, g_target_properties[idx].default_uint_value != 0);
4708}
4709
4710bool TargetProperties::GetDisplayExpressionsInCrashlogs() const {
4711 const uint32_t idx = ePropertyDisplayExpressionsInCrashlogs;
4712 return GetPropertyAtIndexAs<bool>(
4713 idx, g_target_properties[idx].default_uint_value != 0);
4714}
4715
4716LoadScriptFromSymFile TargetProperties::GetLoadScriptFromSymbolFile() const {
4717 const uint32_t idx = ePropertyLoadScriptFromSymbolFile;
4718 return GetPropertyAtIndexAs<LoadScriptFromSymFile>(
4719 idx, static_cast<LoadScriptFromSymFile>(
4720 g_target_properties[idx].default_uint_value));
4721}
4722
4723LoadCWDlldbinitFile TargetProperties::GetLoadCWDlldbinitFile() const {
4724 const uint32_t idx = ePropertyLoadCWDlldbinitFile;
4725 return GetPropertyAtIndexAs<LoadCWDlldbinitFile>(
4726 idx, static_cast<LoadCWDlldbinitFile>(
4727 g_target_properties[idx].default_uint_value));
4728}
4729
4730Disassembler::HexImmediateStyle TargetProperties::GetHexImmediateStyle() const {
4731 const uint32_t idx = ePropertyHexImmediateStyle;
4732 return GetPropertyAtIndexAs<Disassembler::HexImmediateStyle>(
4733 idx, static_cast<Disassembler::HexImmediateStyle>(
4734 g_target_properties[idx].default_uint_value));
4735}
4736
4737MemoryModuleLoadLevel TargetProperties::GetMemoryModuleLoadLevel() const {
4738 const uint32_t idx = ePropertyMemoryModuleLoadLevel;
4739 return GetPropertyAtIndexAs<MemoryModuleLoadLevel>(
4740 idx, static_cast<MemoryModuleLoadLevel>(
4741 g_target_properties[idx].default_uint_value));
4742}
4743
4744bool TargetProperties::GetUserSpecifiedTrapHandlerNames(Args &args) const {
4745 const uint32_t idx = ePropertyTrapHandlerNames;
4746 return m_collection_sp->GetPropertyAtIndexAsArgs(idx, args);
4747}
4748
4749void TargetProperties::SetUserSpecifiedTrapHandlerNames(const Args &args) {
4750 const uint32_t idx = ePropertyTrapHandlerNames;
4751 m_collection_sp->SetPropertyAtIndexFromArgs(idx, args);
4752}
4753
4754bool TargetProperties::GetDisplayRuntimeSupportValues() const {
4755 const uint32_t idx = ePropertyDisplayRuntimeSupportValues;
4756 return GetPropertyAtIndexAs<bool>(
4757 idx, g_target_properties[idx].default_uint_value != 0);
4758}
4759
4760void TargetProperties::SetDisplayRuntimeSupportValues(bool b) {
4761 const uint32_t idx = ePropertyDisplayRuntimeSupportValues;
4762 SetPropertyAtIndex(idx, t: b);
4763}
4764
4765bool TargetProperties::GetDisplayRecognizedArguments() const {
4766 const uint32_t idx = ePropertyDisplayRecognizedArguments;
4767 return GetPropertyAtIndexAs<bool>(
4768 idx, g_target_properties[idx].default_uint_value != 0);
4769}
4770
4771void TargetProperties::SetDisplayRecognizedArguments(bool b) {
4772 const uint32_t idx = ePropertyDisplayRecognizedArguments;
4773 SetPropertyAtIndex(idx, t: b);
4774}
4775
4776const ProcessLaunchInfo &TargetProperties::GetProcessLaunchInfo() const {
4777 return m_launch_info;
4778}
4779
4780void TargetProperties::SetProcessLaunchInfo(
4781 const ProcessLaunchInfo &launch_info) {
4782 m_launch_info = launch_info;
4783 SetArg0(launch_info.GetArg0());
4784 SetRunArguments(launch_info.GetArguments());
4785 SetEnvironment(launch_info.GetEnvironment());
4786 const FileAction *input_file_action =
4787 launch_info.GetFileActionForFD(STDIN_FILENO);
4788 if (input_file_action) {
4789 SetStandardInputPath(input_file_action->GetPath());
4790 }
4791 const FileAction *output_file_action =
4792 launch_info.GetFileActionForFD(STDOUT_FILENO);
4793 if (output_file_action) {
4794 SetStandardOutputPath(output_file_action->GetPath());
4795 }
4796 const FileAction *error_file_action =
4797 launch_info.GetFileActionForFD(STDERR_FILENO);
4798 if (error_file_action) {
4799 SetStandardErrorPath(error_file_action->GetPath());
4800 }
4801 SetDetachOnError(launch_info.GetFlags().Test(bit: lldb::eLaunchFlagDetachOnError));
4802 SetDisableASLR(launch_info.GetFlags().Test(bit: lldb::eLaunchFlagDisableASLR));
4803 SetInheritTCC(
4804 launch_info.GetFlags().Test(bit: lldb::eLaunchFlagInheritTCCFromParent));
4805 SetDisableSTDIO(launch_info.GetFlags().Test(bit: lldb::eLaunchFlagDisableSTDIO));
4806}
4807
4808bool TargetProperties::GetRequireHardwareBreakpoints() const {
4809 const uint32_t idx = ePropertyRequireHardwareBreakpoints;
4810 return GetPropertyAtIndexAs<bool>(
4811 idx, g_target_properties[idx].default_uint_value != 0);
4812}
4813
4814void TargetProperties::SetRequireHardwareBreakpoints(bool b) {
4815 const uint32_t idx = ePropertyRequireHardwareBreakpoints;
4816 m_collection_sp->SetPropertyAtIndex(idx, t: b);
4817}
4818
4819bool TargetProperties::GetAutoInstallMainExecutable() const {
4820 const uint32_t idx = ePropertyAutoInstallMainExecutable;
4821 return GetPropertyAtIndexAs<bool>(
4822 idx, g_target_properties[idx].default_uint_value != 0);
4823}
4824
4825void TargetProperties::Arg0ValueChangedCallback() {
4826 m_launch_info.SetArg0(GetArg0());
4827}
4828
4829void TargetProperties::RunArgsValueChangedCallback() {
4830 Args args;
4831 if (GetRunArguments(args))
4832 m_launch_info.GetArguments() = args;
4833}
4834
4835void TargetProperties::EnvVarsValueChangedCallback() {
4836 m_launch_info.GetEnvironment() = ComputeEnvironment();
4837}
4838
4839void TargetProperties::InputPathValueChangedCallback() {
4840 m_launch_info.AppendOpenFileAction(STDIN_FILENO, file_spec: GetStandardInputPath(), read: true,
4841 write: false);
4842}
4843
4844void TargetProperties::OutputPathValueChangedCallback() {
4845 m_launch_info.AppendOpenFileAction(STDOUT_FILENO, file_spec: GetStandardOutputPath(),
4846 read: false, write: true);
4847}
4848
4849void TargetProperties::ErrorPathValueChangedCallback() {
4850 m_launch_info.AppendOpenFileAction(STDERR_FILENO, file_spec: GetStandardErrorPath(),
4851 read: false, write: true);
4852}
4853
4854void TargetProperties::DetachOnErrorValueChangedCallback() {
4855 if (GetDetachOnError())
4856 m_launch_info.GetFlags().Set(lldb::eLaunchFlagDetachOnError);
4857 else
4858 m_launch_info.GetFlags().Clear(mask: lldb::eLaunchFlagDetachOnError);
4859}
4860
4861void TargetProperties::DisableASLRValueChangedCallback() {
4862 if (GetDisableASLR())
4863 m_launch_info.GetFlags().Set(lldb::eLaunchFlagDisableASLR);
4864 else
4865 m_launch_info.GetFlags().Clear(mask: lldb::eLaunchFlagDisableASLR);
4866}
4867
4868void TargetProperties::InheritTCCValueChangedCallback() {
4869 if (GetInheritTCC())
4870 m_launch_info.GetFlags().Set(lldb::eLaunchFlagInheritTCCFromParent);
4871 else
4872 m_launch_info.GetFlags().Clear(mask: lldb::eLaunchFlagInheritTCCFromParent);
4873}
4874
4875void TargetProperties::DisableSTDIOValueChangedCallback() {
4876 if (GetDisableSTDIO())
4877 m_launch_info.GetFlags().Set(lldb::eLaunchFlagDisableSTDIO);
4878 else
4879 m_launch_info.GetFlags().Clear(mask: lldb::eLaunchFlagDisableSTDIO);
4880}
4881
4882bool TargetProperties::GetDebugUtilityExpression() const {
4883 const uint32_t idx = ePropertyDebugUtilityExpression;
4884 return GetPropertyAtIndexAs<bool>(
4885 idx, g_target_properties[idx].default_uint_value != 0);
4886}
4887
4888void TargetProperties::SetDebugUtilityExpression(bool debug) {
4889 const uint32_t idx = ePropertyDebugUtilityExpression;
4890 SetPropertyAtIndex(idx, t: debug);
4891}
4892
4893// Target::TargetEventData
4894
4895Target::TargetEventData::TargetEventData(const lldb::TargetSP &target_sp)
4896 : EventData(), m_target_sp(target_sp), m_module_list() {}
4897
4898Target::TargetEventData::TargetEventData(const lldb::TargetSP &target_sp,
4899 const ModuleList &module_list)
4900 : EventData(), m_target_sp(target_sp), m_module_list(module_list) {}
4901
4902Target::TargetEventData::~TargetEventData() = default;
4903
4904llvm::StringRef Target::TargetEventData::GetFlavorString() {
4905 return "Target::TargetEventData";
4906}
4907
4908void Target::TargetEventData::Dump(Stream *s) const {
4909 for (size_t i = 0; i < m_module_list.GetSize(); ++i) {
4910 if (i != 0)
4911 *s << ", ";
4912 m_module_list.GetModuleAtIndex(idx: i)->GetDescription(
4913 s&: s->AsRawOstream(), level: lldb::eDescriptionLevelBrief);
4914 }
4915}
4916
4917const Target::TargetEventData *
4918Target::TargetEventData::GetEventDataFromEvent(const Event *event_ptr) {
4919 if (event_ptr) {
4920 const EventData *event_data = event_ptr->GetData();
4921 if (event_data &&
4922 event_data->GetFlavor() == TargetEventData::GetFlavorString())
4923 return static_cast<const TargetEventData *>(event_ptr->GetData());
4924 }
4925 return nullptr;
4926}
4927
4928TargetSP Target::TargetEventData::GetTargetFromEvent(const Event *event_ptr) {
4929 TargetSP target_sp;
4930 const TargetEventData *event_data = GetEventDataFromEvent(event_ptr);
4931 if (event_data)
4932 target_sp = event_data->m_target_sp;
4933 return target_sp;
4934}
4935
4936ModuleList
4937Target::TargetEventData::GetModuleListFromEvent(const Event *event_ptr) {
4938 ModuleList module_list;
4939 const TargetEventData *event_data = GetEventDataFromEvent(event_ptr);
4940 if (event_data)
4941 module_list = event_data->m_module_list;
4942 return module_list;
4943}
4944
4945std::recursive_mutex &Target::GetAPIMutex() {
4946 if (GetProcessSP() && GetProcessSP()->CurrentThreadIsPrivateStateThread())
4947 return m_private_mutex;
4948 else
4949 return m_mutex;
4950}
4951
4952/// Get metrics associated with this target in JSON format.
4953llvm::json::Value
4954Target::ReportStatistics(const lldb_private::StatisticsOptions &options) {
4955 return m_stats.ToJSON(target&: *this, options);
4956}
4957

source code of lldb/source/Target/Target.cpp