LLDB mainline
CommandObjectTarget.cpp
Go to the documentation of this file.
1//===-- CommandObjectTarget.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
10
11#include "lldb/Core/Address.h"
12#include "lldb/Core/Debugger.h"
13#include "lldb/Core/IOHandler.h"
14#include "lldb/Core/Module.h"
17#include "lldb/Core/Section.h"
43#include "lldb/Target/ABI.h"
44#include "lldb/Target/Process.h"
48#include "lldb/Target/Thread.h"
50#include "lldb/Utility/Args.h"
55#include "lldb/Utility/State.h"
56#include "lldb/Utility/Stream.h"
58#include "lldb/Utility/Timer.h"
61#include "lldb/lldb-forward.h"
63
64#include "clang/Driver/CreateInvocationFromArgs.h"
65#include "clang/Frontend/CompilerInstance.h"
66#include "clang/Frontend/CompilerInvocation.h"
67#include "clang/Frontend/FrontendActions.h"
68#include "clang/Serialization/ObjectFilePCHContainerReader.h"
69#include "llvm/ADT/ScopeExit.h"
70#include "llvm/ADT/StringRef.h"
71#include "llvm/Support/FileSystem.h"
72#include "llvm/Support/FormatAdapters.h"
73
74
75using namespace lldb;
76using namespace lldb_private;
77
78static void DumpTargetInfo(uint32_t target_idx, Target *target,
79 const char *prefix_cstr,
80 bool show_stopped_process_status, Stream &strm) {
81 const ArchSpec &target_arch = target->GetArchitecture();
82
83 Module *exe_module = target->GetExecutableModulePointer();
84 char exe_path[PATH_MAX];
85 bool exe_valid = false;
86 if (exe_module)
87 exe_valid = exe_module->GetFileSpec().GetPath(exe_path, sizeof(exe_path));
88
89 if (!exe_valid)
90 ::strcpy(exe_path, "<none>");
91
92 std::string formatted_label = "";
93 const std::string &label = target->GetLabel();
94 if (!label.empty()) {
95 formatted_label = " (" + label + ")";
96 }
97
98 strm.Printf("%starget #%u%s: %s", prefix_cstr ? prefix_cstr : "", target_idx,
99 formatted_label.data(), exe_path);
100
101 uint32_t properties = 0;
102 if (target_arch.IsValid()) {
103 strm.Printf(" ( arch=");
104 target_arch.DumpTriple(strm.AsRawOstream());
105 properties++;
106 }
107 PlatformSP platform_sp(target->GetPlatform());
108 if (platform_sp)
109 strm.Format("{0}platform={1}", properties++ > 0 ? ", " : " ( ",
110 platform_sp->GetName());
111
112 ProcessSP process_sp(target->GetProcessSP());
113 bool show_process_status = false;
114 if (process_sp) {
115 lldb::pid_t pid = process_sp->GetID();
116 StateType state = process_sp->GetState();
117 if (show_stopped_process_status)
118 show_process_status = StateIsStoppedState(state, true);
119 const char *state_cstr = StateAsCString(state);
120 if (pid != LLDB_INVALID_PROCESS_ID)
121 strm.Printf("%spid=%" PRIu64, properties++ > 0 ? ", " : " ( ", pid);
122 strm.Printf("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
123 }
124 if (properties > 0)
125 strm.PutCString(" )\n");
126 else
127 strm.EOL();
128 if (show_process_status) {
129 const bool only_threads_with_stop_reason = true;
130 const uint32_t start_frame = 0;
131 const uint32_t num_frames = 1;
132 const uint32_t num_frames_with_source = 1;
133 const bool stop_format = false;
134 process_sp->GetStatus(strm);
135 process_sp->GetThreadStatus(strm, only_threads_with_stop_reason,
136 start_frame, num_frames, num_frames_with_source,
137 stop_format);
138 }
139}
140
141static uint32_t DumpTargetList(TargetList &target_list,
142 bool show_stopped_process_status, Stream &strm) {
143 const uint32_t num_targets = target_list.GetNumTargets();
144 if (num_targets) {
145 TargetSP selected_target_sp(target_list.GetSelectedTarget());
146 strm.PutCString("Current targets:\n");
147 for (uint32_t i = 0; i < num_targets; ++i) {
148 TargetSP target_sp(target_list.GetTargetAtIndex(i));
149 if (target_sp) {
150 bool is_selected = target_sp.get() == selected_target_sp.get();
151 DumpTargetInfo(i, target_sp.get(), is_selected ? "* " : " ",
152 show_stopped_process_status, strm);
153 }
154 }
155 }
156 return num_targets;
157}
158
159#define LLDB_OPTIONS_target_dependents
160#include "CommandOptions.inc"
161
163public:
165
166 ~OptionGroupDependents() override = default;
167
168 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
169 return llvm::ArrayRef(g_target_dependents_options);
170 }
171
172 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
173 ExecutionContext *execution_context) override {
175
176 // For compatibility no value means don't load dependents.
177 if (option_value.empty()) {
179 return error;
180 }
181
182 const char short_option =
183 g_target_dependents_options[option_idx].short_option;
184 if (short_option == 'd') {
185 LoadDependentFiles tmp_load_dependents;
187 option_value, g_target_dependents_options[option_idx].enum_values, 0,
188 error);
189 if (error.Success())
190 m_load_dependent_files = tmp_load_dependents;
191 } else {
193 "unrecognized short option '%c'", short_option);
194 }
195
196 return error;
197 }
198
199 Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete;
200
204
206
207private:
211};
212
213#pragma mark CommandObjectTargetCreate
214
216public:
219 interpreter, "target create",
220 "Create a target using the argument as the main executable.",
221 nullptr),
222 m_platform_options(true), // Include the --platform option.
223 m_core_file(LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename,
224 "Fullpath to a core file to use for this target."),
225 m_label(LLDB_OPT_SET_1, false, "label", 'l', 0, eArgTypeName,
226 "Optional name for this target.", nullptr),
227 m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
229 "Fullpath to a stand alone debug "
230 "symbols file for when debug symbols "
231 "are not in the executable."),
233 LLDB_OPT_SET_1, false, "remote-file", 'r', 0, eArgTypeFilename,
234 "Fullpath to the file on the remote host if debugging remotely.") {
235
237
245 m_option_group.Finalize();
246 }
247
248 ~CommandObjectTargetCreate() override = default;
249
250 Options *GetOptions() override { return &m_option_group; }
251
252protected:
253 void DoExecute(Args &command, CommandReturnObject &result) override {
254 const size_t argc = command.GetArgumentCount();
255 FileSpec core_file(m_core_file.GetOptionValue().GetCurrentValue());
256 FileSpec remote_file(m_remote_file.GetOptionValue().GetCurrentValue());
257
258 if (core_file) {
259 auto file = FileSystem::Instance().Open(
261
262 if (!file) {
263 result.AppendErrorWithFormatv("Cannot open '{0}': {1}.",
264 core_file.GetPath(),
265 llvm::toString(file.takeError()));
266 return;
267 }
268 }
269
270 if (argc == 1 || core_file || remote_file) {
271 FileSpec symfile(m_symbol_file.GetOptionValue().GetCurrentValue());
272 if (symfile) {
273 auto file = FileSystem::Instance().Open(
275
276 if (!file) {
277 result.AppendErrorWithFormatv("Cannot open '{0}': {1}.",
278 symfile.GetPath(),
279 llvm::toString(file.takeError()));
280 return;
281 }
282 }
283
284 const char *file_path = command.GetArgumentAtIndex(0);
285 LLDB_SCOPED_TIMERF("(lldb) target create '%s'", file_path);
286
287 bool must_set_platform_path = false;
288
289 Debugger &debugger = GetDebugger();
290
291 TargetSP target_sp;
292 llvm::StringRef arch_cstr = m_arch_option.GetArchitectureName();
294 debugger, file_path, arch_cstr,
295 m_add_dependents.m_load_dependent_files, &m_platform_options,
296 target_sp));
297
298 if (!target_sp) {
299 result.AppendError(error.AsCString());
300 return;
301 }
302
303 const llvm::StringRef label =
304 m_label.GetOptionValue().GetCurrentValueAsRef();
305 if (!label.empty()) {
306 if (auto E = target_sp->SetLabel(label))
307 result.SetError(std::move(E));
308 else
310 return;
311 }
312
313 llvm::scope_exit on_error(
314 [&target_list = debugger.GetTargetList(), &target_sp]() {
315 target_list.DeleteTarget(target_sp);
316 });
317
318 // Only get the platform after we create the target because we might
319 // have switched platforms depending on what the arguments were to
320 // CreateTarget() we can't rely on the selected platform.
321
322 PlatformSP platform_sp = target_sp->GetPlatform();
323
324 FileSpec file_spec;
325 if (file_path) {
326 file_spec.SetFile(file_path, FileSpec::Style::native);
327 FileSystem::Instance().Resolve(file_spec);
328
329 // Try to resolve the exe based on PATH and/or platform-specific
330 // suffixes, but only if using the host platform.
331 if (platform_sp && platform_sp->IsHost() &&
332 !FileSystem::Instance().Exists(file_spec))
334 }
335
336 if (remote_file) {
337 if (platform_sp) {
338 // I have a remote file.. two possible cases
339 if (file_spec && FileSystem::Instance().Exists(file_spec)) {
340 // if the remote file does not exist, push it there
341 if (!platform_sp->GetFileExists(remote_file)) {
342 Status err = platform_sp->PutFile(file_spec, remote_file);
343 if (err.Fail()) {
344 result.AppendError(err.AsCString());
345 return;
346 }
347 }
348 } else {
349 // there is no local file and we need one
350 // in order to make the remote ---> local transfer we need a
351 // platform
352 // TODO: if the user has passed in a --platform argument, use it
353 // to fetch the right platform
354 if (file_path) {
355 // copy the remote file to the local file
356 Status err = platform_sp->GetFile(remote_file, file_spec);
357 if (err.Fail()) {
358 result.AppendError(err.AsCString());
359 return;
360 }
361 } else {
362 // If the remote file exists, we can debug reading that out of
363 // memory. If the platform is already connected to an lldb-server
364 // then we can at least check the file exists remotely. Otherwise
365 // we'll just have to trust that it will be there when we do
366 // process connect.
367 // I don't do this for the host platform because it seems odd to
368 // support supplying a remote file but no local file for a local
369 // debug session.
370 if (platform_sp->IsHost()) {
371 result.AppendError("Supply a local file, not a remote file, "
372 "when debugging on the host.");
373 return;
374 }
375 if (platform_sp->IsConnected() && !platform_sp->GetFileExists(remote_file)) {
376 result.AppendError("remote --> local transfer without local "
377 "path is not implemented yet");
378 return;
379 }
380 // Since there's only a remote file, we need to set the executable
381 // file spec to the remote one.
382 ProcessLaunchInfo launch_info = target_sp->GetProcessLaunchInfo();
383 launch_info.SetExecutableFile(FileSpec(remote_file), true);
384 target_sp->SetProcessLaunchInfo(launch_info);
385 }
386 }
387 } else {
388 result.AppendError("no platform found for target");
389 return;
390 }
391 }
392
393 if (symfile || remote_file) {
394 ModuleSP module_sp(target_sp->GetExecutableModule());
395 if (module_sp) {
396 if (symfile)
397 module_sp->SetSymbolFileFileSpec(symfile);
398 if (remote_file) {
399 std::string remote_path = remote_file.GetPath();
400 target_sp->SetArg0(remote_path.c_str());
401 module_sp->SetPlatformFileSpec(remote_file);
402 }
403 }
404 }
405
406 if (must_set_platform_path) {
407 ModuleSpec main_module_spec(file_spec);
408 ModuleSP module_sp =
409 target_sp->GetOrCreateModule(main_module_spec, true /* notify */);
410 if (module_sp)
411 module_sp->SetPlatformFileSpec(remote_file);
412 }
413
414 if (core_file) {
415 FileSpec core_file_dir;
416 core_file_dir.SetDirectory(core_file.GetDirectory());
417 target_sp->AppendExecutableSearchPaths(core_file_dir);
418
419 ProcessSP process_sp(target_sp->CreateProcess(
420 GetDebugger().GetListener(), llvm::StringRef(), &core_file, false));
421
422 if (process_sp) {
423 // Seems weird that we Launch a core file, but that is what we
424 // do!
425 {
426 ElapsedTime load_core_time(
427 target_sp->GetStatistics().GetLoadCoreTime());
428 error = process_sp->LoadCore();
429 }
430
431 if (error.Fail()) {
432 result.AppendError(error.AsCString("unknown core file format"));
433 return;
434 } else {
436 "Core file '{0}' ({1}) was loaded.\n", core_file.GetPath(),
437 target_sp->GetArchitecture().GetArchitectureName());
438 if (auto core_args = process_sp->GetCoreFileArgs())
439 core_args->Format(result.GetOutputStream());
441 on_error.release();
442 }
443 } else {
444 result.AppendErrorWithFormatv("Unknown core file format '{0}'\n",
445 core_file.GetPath());
446 }
447 } else {
449 "Current executable set to '{0}' ({1}).",
450 file_spec.GetPath().c_str(),
451 target_sp->GetArchitecture().GetArchitectureName());
453 on_error.release();
454 }
455 } else {
456 result.AppendErrorWithFormat("'%s' takes exactly one executable path "
457 "argument, or use the --core option",
458 m_cmd_name.c_str());
459 }
460 }
461
462private:
471};
472
473#pragma mark CommandObjectTargetList
474
476public:
479 interpreter, "target list",
480 "List all current targets in the current debug session.", nullptr) {
481 }
482
483 ~CommandObjectTargetList() override = default;
484
485protected:
486 void DoExecute(Args &args, CommandReturnObject &result) override {
487 Stream &strm = result.GetOutputStream();
488
489 bool show_stopped_process_status = false;
490 if (DumpTargetList(GetDebugger().GetTargetList(),
491 show_stopped_process_status, strm) == 0) {
492 strm.PutCString("No targets.\n");
493 }
495 }
496};
497
498#pragma mark CommandObjectTargetSelect
499
501public:
504 interpreter, "target select",
505 "Select a target as the current target by target index.", nullptr) {
507 }
508
509 ~CommandObjectTargetSelect() override = default;
510
511protected:
512 void DoExecute(Args &args, CommandReturnObject &result) override {
513 if (args.GetArgumentCount() == 1) {
514 const char *target_identifier = args.GetArgumentAtIndex(0);
515 uint32_t target_idx = LLDB_INVALID_INDEX32;
516 TargetList &target_list = GetDebugger().GetTargetList();
517 const uint32_t num_targets = target_list.GetNumTargets();
518 if (llvm::to_integer(target_identifier, target_idx)) {
519 if (target_idx < num_targets) {
520 target_list.SetSelectedTarget(target_idx);
521 Stream &strm = result.GetOutputStream();
522 bool show_stopped_process_status = false;
523 DumpTargetList(target_list, show_stopped_process_status, strm);
525 } else {
526 if (num_targets > 0) {
528 "index %u is out of range, valid target indexes are 0 - %u",
529 target_idx, num_targets - 1);
530 } else {
532 "index %u is out of range since there are no active targets",
533 target_idx);
534 }
535 }
536 } else {
537 for (size_t i = 0; i < num_targets; i++) {
538 if (TargetSP target_sp = target_list.GetTargetAtIndex(i)) {
539 const std::string &label = target_sp->GetLabel();
540 if (!label.empty() && label == target_identifier) {
541 target_idx = i;
542 break;
543 }
544 }
545 }
546
547 if (target_idx != LLDB_INVALID_INDEX32) {
548 target_list.SetSelectedTarget(target_idx);
549 Stream &strm = result.GetOutputStream();
550 bool show_stopped_process_status = false;
551 DumpTargetList(target_list, show_stopped_process_status, strm);
553 } else {
554 result.AppendErrorWithFormat("invalid index string value '%s'",
555 target_identifier);
556 }
557 }
558 } else {
559 result.AppendError(
560 "'target select' takes a single argument: a target index\n");
561 }
562 }
563};
564
565#pragma mark CommandObjectTargetDelete
566
568public:
570 : CommandObjectParsed(interpreter, "target delete",
571 "Delete one or more targets by target index.",
572 nullptr),
573 m_all_option(LLDB_OPT_SET_1, false, "all", 'a', "Delete all targets.",
574 false, true),
576 LLDB_OPT_SET_1, false, "clean", 'c',
577 "Perform extra cleanup to minimize memory consumption after "
578 "deleting the target. "
579 "By default, LLDB will keep in memory any modules previously "
580 "loaded by the target as well "
581 "as all of its debug info. Specifying --clean will unload all of "
582 "these shared modules and "
583 "cause them to be reparsed again the next time the target is run",
584 false, true) {
587 m_option_group.Finalize();
589 }
590
591 ~CommandObjectTargetDelete() override = default;
592
593 Options *GetOptions() override { return &m_option_group; }
594
595protected:
596 void DoExecute(Args &args, CommandReturnObject &result) override {
597 const size_t argc = args.GetArgumentCount();
598 std::vector<TargetSP> delete_target_list;
599 TargetList &target_list = GetDebugger().GetTargetList();
600 TargetSP target_sp;
601
602 if (m_all_option.GetOptionValue()) {
603 for (size_t i = 0; i < target_list.GetNumTargets(); ++i)
604 delete_target_list.push_back(target_list.GetTargetAtIndex(i));
605 } else if (argc > 0) {
606 const uint32_t num_targets = target_list.GetNumTargets();
607 // Bail out if don't have any targets.
608 if (num_targets == 0) {
609 result.AppendError("no targets to delete");
610 return;
611 }
612
613 for (auto &entry : args.entries()) {
614 uint32_t target_idx;
615 if (entry.ref().getAsInteger(0, target_idx)) {
616 result.AppendErrorWithFormat("invalid target index '%s'",
617 entry.c_str());
618 return;
619 }
620 if (target_idx < num_targets) {
621 target_sp = target_list.GetTargetAtIndex(target_idx);
622 if (target_sp) {
623 delete_target_list.push_back(target_sp);
624 continue;
625 }
626 }
627 if (num_targets > 1)
628 result.AppendErrorWithFormat("target index %u is out of range, valid "
629 "target indexes are 0 - %u",
630 target_idx, num_targets - 1);
631 else
633 "target index %u is out of range, the only valid index is 0",
634 target_idx);
635
636 return;
637 }
638 } else {
639 target_sp = target_list.GetSelectedTarget();
640 if (!target_sp) {
641 result.AppendErrorWithFormat("no target is currently selected");
642 return;
643 }
644 delete_target_list.push_back(target_sp);
645 }
646
647 const size_t num_targets_to_delete = delete_target_list.size();
648 for (size_t idx = 0; idx < num_targets_to_delete; ++idx) {
649 target_sp = delete_target_list[idx];
650 target_list.DeleteTarget(target_sp);
651 target_sp->Destroy();
652 }
653 // If "--clean" was specified, prune any orphaned shared modules from the
654 // global shared module list
655 if (m_cleanup_option.GetOptionValue()) {
656 const bool mandatory = true;
658 }
659 result.GetOutputStream().Printf("%u targets deleted.\n",
660 (uint32_t)num_targets_to_delete);
662 }
663
667};
668
670public:
673 interpreter, "target show-launch-environment",
674 "Shows the environment being passed to the process when launched, "
675 "taking info account 3 settings: target.env-vars, "
676 "target.inherit-env and target.unset-env-vars.",
677 nullptr, eCommandRequiresTarget) {}
678
680
681protected:
682 void DoExecute(Args &args, CommandReturnObject &result) override {
683 Target *target = m_exe_ctx.GetTargetPtr();
684 Environment env = target->GetEnvironment();
685
686 std::vector<Environment::value_type *> env_vector;
687 env_vector.reserve(env.size());
688 for (auto &KV : env)
689 env_vector.push_back(&KV);
690 std::sort(env_vector.begin(), env_vector.end(),
691 [](Environment::value_type *a, Environment::value_type *b) {
692 return a->first() < b->first();
693 });
694
695 auto &strm = result.GetOutputStream();
696 for (auto &KV : env_vector)
697 strm.Format("{0}={1}\n", KV->first(), KV->second);
698
700 }
701};
702
703#pragma mark CommandObjectTargetVariable
704
706 static const uint32_t SHORT_OPTION_FILE = 0x66696c65; // 'file'
707 static const uint32_t SHORT_OPTION_SHLB = 0x73686c62; // 'shlb'
708
709public:
711 : CommandObjectParsed(interpreter, "target variable",
712 "Read global variables for the current target, "
713 "before or while running a process.",
714 nullptr, eCommandRequiresTarget),
715 m_option_variable(false), // Don't include frame options
719 "A basename or fullpath to a file that contains "
720 "global variables. This option can be "
721 "specified multiple times."),
723 LLDB_OPT_SET_1, false, "shlib", SHORT_OPTION_SHLB, 0,
725 "A basename or fullpath to a shared library to use in the search "
726 "for global "
727 "variables. This option can be specified multiple times.") {
729
740 m_option_group.Finalize();
741 }
742
743 ~CommandObjectTargetVariable() override = default;
744
745 void DumpValueObject(Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp,
746 const char *root_name) {
747 DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions());
748
749 if (!valobj_sp->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
750 valobj_sp->IsRuntimeSupportValue())
751 return;
752
753 switch (var_sp->GetScope()) {
755 if (m_option_variable.show_scope)
756 s.PutCString("GLOBAL: ");
757 break;
758
760 if (m_option_variable.show_scope)
761 s.PutCString("STATIC: ");
762 break;
763
765 if (m_option_variable.show_scope)
766 s.PutCString(" ARG: ");
767 break;
768
770 if (m_option_variable.show_scope)
771 s.PutCString(" LOCAL: ");
772 break;
773
775 if (m_option_variable.show_scope)
776 s.PutCString("THREAD: ");
777 break;
778
779 default:
780 break;
781 }
782
783 if (m_option_variable.show_decl) {
784 bool show_fullpaths = false;
785 bool show_module = true;
786 if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
787 s.PutCString(": ");
788 }
789
790 const Format format = m_option_format.GetFormat();
791 if (format != eFormatDefault)
792 options.SetFormat(format);
793
794 options.SetRootValueObjectName(root_name);
795
796 if (llvm::Error error = valobj_sp->Dump(s, options))
797 s << "error: " << toString(std::move(error));
798 }
799
800 static size_t GetVariableCallback(void *baton, const char *name,
801 VariableList &variable_list) {
802 size_t old_size = variable_list.GetSize();
803 Target *target = static_cast<Target *>(baton);
804 if (target)
806 variable_list);
807 return variable_list.GetSize() - old_size;
808 }
809
810 Options *GetOptions() override { return &m_option_group; }
811
812protected:
814 const SymbolContext &sc,
815 const VariableList &variable_list,
816 CommandReturnObject &result) {
817 Stream &s = result.GetOutputStream();
818 if (variable_list.Empty())
819 return;
820 if (sc.module_sp) {
821 if (sc.comp_unit) {
822 s.Format("Global variables for {0} in {1}:\n",
823 sc.comp_unit->GetPrimaryFile(), sc.module_sp->GetFileSpec());
824 } else {
825 s.Printf("Global variables for %s\n",
826 sc.module_sp->GetFileSpec().GetPath().c_str());
827 }
828 } else if (sc.comp_unit) {
829 s.Format("Global variables for {0}\n", sc.comp_unit->GetPrimaryFile());
830 }
831
832 for (VariableSP var_sp : variable_list) {
833 if (!var_sp)
834 continue;
836 exe_ctx.GetBestExecutionContextScope(), var_sp));
837
838 if (valobj_sp) {
839 result.GetValueObjectList().Append(valobj_sp);
840 DumpValueObject(s, var_sp, valobj_sp, var_sp->GetName().GetCString());
841 }
842 }
843 }
844
845 void DoExecute(Args &args, CommandReturnObject &result) override {
846 Target *target = m_exe_ctx.GetTargetPtr();
847 const size_t argc = args.GetArgumentCount();
848
849 if (argc > 0) {
850 for (const Args::ArgEntry &arg : args) {
851 VariableList variable_list;
852 ValueObjectList valobj_list;
853
854 size_t matches = 0;
855 bool use_var_name = false;
856 if (m_option_variable.use_regex) {
857 RegularExpression regex(arg.ref());
858 if (!regex.IsValid()) {
859 result.GetErrorStream().Printf(
860 "error: invalid regular expression: '%s'\n", arg.c_str());
861 return;
862 }
863 use_var_name = true;
865 variable_list);
866 matches = variable_list.GetSize();
867 } else {
869 arg.c_str(), m_exe_ctx.GetBestExecutionContextScope(),
870 GetVariableCallback, target, variable_list, valobj_list));
871 matches = variable_list.GetSize();
872 }
873
874 if (matches == 0) {
875 result.AppendErrorWithFormat("can't find global variable '%s'",
876 arg.c_str());
877 return;
878 } else {
879 for (uint32_t global_idx = 0; global_idx < matches; ++global_idx) {
880 VariableSP var_sp(variable_list.GetVariableAtIndex(global_idx));
881 if (var_sp) {
882 ValueObjectSP valobj_sp(
883 valobj_list.GetValueObjectAtIndex(global_idx));
884 if (!valobj_sp)
885 valobj_sp = ValueObjectVariable::Create(
886 m_exe_ctx.GetBestExecutionContextScope(), var_sp);
887
888 if (valobj_sp)
889 DumpValueObject(result.GetOutputStream(), var_sp, valobj_sp,
890 use_var_name ? var_sp->GetName().GetCString()
891 : arg.c_str());
892 }
893 }
894 }
895 }
896 } else {
897 const FileSpecList &compile_units =
898 m_option_compile_units.GetOptionValue().GetCurrentValue();
899 const FileSpecList &shlibs =
900 m_option_shared_libraries.GetOptionValue().GetCurrentValue();
901 SymbolContextList sc_list;
902 const size_t num_compile_units = compile_units.GetSize();
903 const size_t num_shlibs = shlibs.GetSize();
904 if (num_compile_units == 0 && num_shlibs == 0) {
905 bool success = false;
906 StackFrame *frame = m_exe_ctx.GetFramePtr();
907 CompileUnit *comp_unit = nullptr;
908 if (frame) {
909 SymbolContext sc = frame->GetSymbolContext(eSymbolContextCompUnit);
910 comp_unit = sc.comp_unit;
911 if (sc.comp_unit) {
912 const bool can_create = true;
913 VariableListSP comp_unit_varlist_sp(
914 sc.comp_unit->GetVariableList(can_create));
915 if (comp_unit_varlist_sp) {
916 size_t count = comp_unit_varlist_sp->GetSize();
917 if (count > 0) {
918 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp,
919 result);
920 success = true;
921 }
922 }
923 }
924 }
925 if (!success) {
926 if (frame) {
927 if (comp_unit)
929 "no global variables in current compile unit: {0}\n",
930 comp_unit->GetPrimaryFile());
931 else
932 result.AppendErrorWithFormat("no debug information for frame %u",
933 frame->GetFrameIndex());
934 } else
935 result.AppendError("'target variable' takes one or more global "
936 "variable names as arguments\n");
937 }
938 } else {
939 SymbolContextList sc_list;
940 // We have one or more compile unit or shlib
941 if (num_shlibs > 0) {
942 for (size_t shlib_idx = 0; shlib_idx < num_shlibs; ++shlib_idx) {
943 const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx));
944 ModuleSpec module_spec(module_file);
945
946 ModuleSP module_sp(
947 target->GetImages().FindFirstModule(module_spec));
948 if (module_sp) {
949 if (num_compile_units > 0) {
950 for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
951 module_sp->FindCompileUnits(
952 compile_units.GetFileSpecAtIndex(cu_idx), sc_list);
953 } else {
954 SymbolContext sc;
955 sc.module_sp = module_sp;
956 sc_list.Append(sc);
957 }
958 } else {
959 // Didn't find matching shlib/module in target...
961 "target doesn't contain the specified shared library: %s",
962 module_file.GetPath().c_str());
963 }
964 }
965 } else {
966 // No shared libraries, we just want to find globals for the compile
967 // units files that were specified
968 for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
969 target->GetImages().FindCompileUnits(
970 compile_units.GetFileSpecAtIndex(cu_idx), sc_list);
971 }
972
973 for (const SymbolContext &sc : sc_list) {
974 if (sc.comp_unit) {
975 const bool can_create = true;
976 VariableListSP comp_unit_varlist_sp(
977 sc.comp_unit->GetVariableList(can_create));
978 if (comp_unit_varlist_sp)
979 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp,
980 result);
981 } else if (sc.module_sp) {
982 // Get all global variables for this module
983 lldb_private::RegularExpression all_globals_regex(
984 llvm::StringRef(".")); // Any global with at least one character
985 VariableList variable_list;
986 sc.module_sp->FindGlobalVariables(all_globals_regex, UINT32_MAX,
987 variable_list);
988 DumpGlobalVariableList(m_exe_ctx, sc, variable_list, result);
989 }
990 }
991 }
992 }
993
994 m_interpreter.PrintWarningsIfNecessary(result.GetOutputStream(),
995 m_cmd_name);
996 if (result.GetStatus() != eReturnStatusFailed)
998 }
999
1006};
1007
1008#pragma mark CommandObjectTargetModulesSearchPathsAdd
1009
1011public:
1013 : CommandObjectParsed(interpreter, "target modules search-paths add",
1014 "Add new image search paths substitution pairs to "
1015 "the current target.",
1016 nullptr, eCommandRequiresTarget) {
1018 CommandArgumentData old_prefix_arg;
1019 CommandArgumentData new_prefix_arg;
1020
1021 // Define the first variant of this arg pair.
1022 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1023 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1024
1025 // Define the first variant of this arg pair.
1026 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1027 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1028
1029 // There are two required arguments that must always occur together, i.e.
1030 // an argument "pair". Because they must always occur together, they are
1031 // treated as two variants of one argument rather than two independent
1032 // arguments. Push them both into the first argument position for
1033 // m_arguments...
1034
1035 arg.push_back(old_prefix_arg);
1036 arg.push_back(new_prefix_arg);
1037
1038 m_arguments.push_back(arg);
1039 }
1040
1042
1043protected:
1044 void DoExecute(Args &command, CommandReturnObject &result) override {
1045 Target *target = GetTarget();
1046 assert(target && "target guaranteed by eCommandRequiresTarget");
1047 const size_t argc = command.GetArgumentCount();
1048 if (argc & 1) {
1049 result.AppendError("add requires an even number of arguments\n");
1050 } else {
1051 for (size_t i = 0; i < argc; i += 2) {
1052 const char *from = command.GetArgumentAtIndex(i);
1053 const char *to = command.GetArgumentAtIndex(i + 1);
1054
1055 if (from[0] && to[0]) {
1057 "target modules search path adding ImageSearchPath "
1058 "pair: '%s' -> '%s'",
1059 from, to);
1060 bool last_pair = ((argc - i) == 2);
1062 from, to, last_pair); // Notify if this is the last pair
1064 } else {
1065 if (from[0])
1066 result.AppendError("<path-prefix> can't be empty\n");
1067 else
1068 result.AppendError("<new-path-prefix> can't be empty\n");
1069 }
1070 }
1071 }
1072 }
1073};
1074
1075#pragma mark CommandObjectTargetModulesSearchPathsClear
1076
1078public:
1080 : CommandObjectParsed(interpreter, "target modules search-paths clear",
1081 "Clear all current image search path substitution "
1082 "pairs from the current target.",
1083 "target modules search-paths clear",
1084 eCommandRequiresTarget) {}
1085
1087
1088protected:
1089 void DoExecute(Args &command, CommandReturnObject &result) override {
1090 Target *target = GetTarget();
1091 assert(target && "target guaranteed by eCommandRequiresTarget");
1092 bool notify = true;
1093 target->GetImageSearchPathList().Clear(notify);
1095 }
1096};
1097
1098#pragma mark CommandObjectTargetModulesSearchPathsInsert
1099
1101public:
1103 : CommandObjectParsed(interpreter, "target modules search-paths insert",
1104 "Insert a new image search path substitution pair "
1105 "into the current target at the specified index.",
1106 nullptr, eCommandRequiresTarget) {
1109 CommandArgumentData index_arg;
1110 CommandArgumentData old_prefix_arg;
1111 CommandArgumentData new_prefix_arg;
1112
1113 // Define the first and only variant of this arg.
1114 index_arg.arg_type = eArgTypeIndex;
1115 index_arg.arg_repetition = eArgRepeatPlain;
1116
1117 // Put the one and only variant into the first arg for m_arguments:
1118 arg1.push_back(index_arg);
1119
1120 // Define the first variant of this arg pair.
1121 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1122 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1123
1124 // Define the first variant of this arg pair.
1125 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1126 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1127
1128 // There are two required arguments that must always occur together, i.e.
1129 // an argument "pair". Because they must always occur together, they are
1130 // treated as two variants of one argument rather than two independent
1131 // arguments. Push them both into the same argument position for
1132 // m_arguments...
1133
1134 arg2.push_back(old_prefix_arg);
1135 arg2.push_back(new_prefix_arg);
1136
1137 // Add arguments to m_arguments.
1138 m_arguments.push_back(arg1);
1139 m_arguments.push_back(arg2);
1140 }
1141
1143
1144 void
1146 OptionElementVector &opt_element_vector) override {
1147 if (!m_exe_ctx.HasTargetScope() || request.GetCursorIndex() != 0)
1148 return;
1149
1150 Target *target = m_exe_ctx.GetTargetPtr();
1151
1152 const PathMappingList &list = target->GetImageSearchPathList();
1153 const size_t num = list.GetSize();
1154 ConstString old_path, new_path;
1155 for (size_t i = 0; i < num; ++i) {
1156 if (!list.GetPathsAtIndex(i, old_path, new_path))
1157 break;
1158 StreamString strm;
1159 strm << old_path << " -> " << new_path;
1160 request.TryCompleteCurrentArg(std::to_string(i), strm.GetString());
1161 }
1162 }
1163
1164protected:
1165 void DoExecute(Args &command, CommandReturnObject &result) override {
1166 Target *target = GetTarget();
1167 assert(target && "target guaranteed by eCommandRequiresTarget");
1168 size_t argc = command.GetArgumentCount();
1169 // check for at least 3 arguments and an odd number of parameters
1170 if (argc >= 3 && argc & 1) {
1171 uint32_t insert_idx;
1172
1173 if (!llvm::to_integer(command.GetArgumentAtIndex(0), insert_idx)) {
1174 result.AppendErrorWithFormat(
1175 "<index> parameter is not an integer: '%s'",
1176 command.GetArgumentAtIndex(0));
1177 return;
1178 }
1179
1180 // shift off the index
1181 command.Shift();
1182 argc = command.GetArgumentCount();
1183
1184 for (uint32_t i = 0; i < argc; i += 2, ++insert_idx) {
1185 const char *from = command.GetArgumentAtIndex(i);
1186 const char *to = command.GetArgumentAtIndex(i + 1);
1187
1188 if (from[0] && to[0]) {
1189 bool last_pair = ((argc - i) == 2);
1190 target->GetImageSearchPathList().Insert(from, to, insert_idx,
1191 last_pair);
1193 } else {
1194 if (from[0])
1195 result.AppendError("<path-prefix> can't be empty\n");
1196 else
1197 result.AppendError("<new-path-prefix> can't be empty\n");
1198 return;
1199 }
1200 }
1201 } else {
1202 result.AppendError("insert requires at least three arguments\n");
1203 }
1204 }
1205};
1206
1207#pragma mark CommandObjectTargetModulesSearchPathsList
1208
1210public:
1212 : CommandObjectParsed(interpreter, "target modules search-paths list",
1213 "List all current image search path substitution "
1214 "pairs in the current target.",
1215 "target modules search-paths list",
1216 eCommandRequiresTarget) {}
1217
1219
1220protected:
1221 void DoExecute(Args &command, CommandReturnObject &result) override {
1222 Target *target = GetTarget();
1223 assert(target && "target guaranteed by eCommandRequiresTarget");
1224 target->GetImageSearchPathList().Dump(&result.GetOutputStream());
1226 }
1227};
1228
1229#pragma mark CommandObjectTargetModulesSearchPathsQuery
1230
1232public:
1235 interpreter, "target modules search-paths query",
1236 "Transform a path using the first applicable image search path.",
1237 nullptr, eCommandRequiresTarget) {
1239 }
1240
1242
1243protected:
1244 void DoExecute(Args &command, CommandReturnObject &result) override {
1245 Target *target = GetTarget();
1246 assert(target && "target guaranteed by eCommandRequiresTarget");
1247 if (command.GetArgumentCount() != 1) {
1248 result.AppendError("query requires one argument\n");
1249 return;
1250 }
1251
1252 ConstString orig(command.GetArgumentAtIndex(0));
1253 ConstString transformed;
1254 if (target->GetImageSearchPathList().RemapPath(orig, transformed))
1255 result.GetOutputStream().Printf("%s\n", transformed.GetCString());
1256 else
1257 result.GetOutputStream().Printf("%s\n", orig.GetCString());
1258
1260 }
1261};
1262
1263// Static Helper functions
1264static void DumpModuleArchitecture(Stream &strm, Module *module,
1265 bool full_triple, uint32_t width) {
1266 if (module) {
1267 StreamString arch_strm;
1268
1269 if (full_triple)
1270 module->GetArchitecture().DumpTriple(arch_strm.AsRawOstream());
1271 else
1272 arch_strm.PutCString(module->GetArchitecture().GetArchitectureName());
1273 std::string arch_str = std::string(arch_strm.GetString());
1274
1275 if (width)
1276 strm.Printf("%-*s", width, arch_str.c_str());
1277 else
1278 strm.PutCString(arch_str);
1279 }
1280}
1281
1282static void DumpModuleUUID(Stream &strm, Module *module) {
1283 if (module && module->GetUUID().IsValid())
1284 module->GetUUID().Dump(strm);
1285 else
1286 strm.PutCString(" ");
1287}
1288
1290 Stream &strm, Module *module,
1291 const FileSpec &file_spec,
1292 lldb::DescriptionLevel desc_level) {
1293 uint32_t num_matches = 0;
1294 if (module) {
1295 SymbolContextList sc_list;
1296 num_matches = module->ResolveSymbolContextsForFileSpec(
1297 file_spec, 0, false, eSymbolContextCompUnit, sc_list);
1298
1299 bool first_module = true;
1300 for (const SymbolContext &sc : sc_list) {
1301 if (!first_module)
1302 strm << "\n\n";
1303
1304 strm << "Line table for " << sc.comp_unit->GetPrimaryFile() << " in `"
1305 << module->GetFileSpec().GetFilename() << "\n";
1306 LineTable *line_table = sc.comp_unit->GetLineTable();
1307 if (line_table)
1308 line_table->GetDescription(
1309 &strm, interpreter.GetExecutionContext().GetTargetPtr(),
1310 desc_level);
1311 else
1312 strm << "No line table";
1313
1314 first_module = false;
1315 }
1316 }
1317 return num_matches;
1318}
1319
1320static void DumpFullpath(Stream &strm, const FileSpec *file_spec_ptr,
1321 uint32_t width) {
1322 if (file_spec_ptr) {
1323 if (width > 0) {
1324 std::string fullpath = file_spec_ptr->GetPath();
1325 strm.Printf("%-*s", width, fullpath.c_str());
1326 return;
1327 } else {
1328 file_spec_ptr->Dump(strm.AsRawOstream());
1329 return;
1330 }
1331 }
1332 // Keep the width spacing correct if things go wrong...
1333 if (width > 0)
1334 strm.Printf("%-*s", width, "");
1335}
1336
1337static void DumpDirectory(Stream &strm, const FileSpec *file_spec_ptr,
1338 uint32_t width) {
1339 if (file_spec_ptr) {
1340 if (width > 0)
1341 strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
1342 else
1343 file_spec_ptr->GetDirectory().Dump(&strm);
1344 return;
1345 }
1346 // Keep the width spacing correct if things go wrong...
1347 if (width > 0)
1348 strm.Printf("%-*s", width, "");
1349}
1350
1351static void DumpBasename(Stream &strm, const FileSpec *file_spec_ptr,
1352 uint32_t width) {
1353 if (file_spec_ptr) {
1354 if (width > 0)
1355 strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
1356 else
1357 file_spec_ptr->GetFilename().Dump(&strm);
1358 return;
1359 }
1360 // Keep the width spacing correct if things go wrong...
1361 if (width > 0)
1362 strm.Printf("%-*s", width, "");
1363}
1364
1365static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) {
1366 std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
1367 const size_t num_modules = module_list.GetSize();
1368 if (num_modules == 0)
1369 return 0;
1370
1371 size_t num_dumped = 0;
1372 strm.Format("Dumping headers for {0} module(s).\n", num_modules);
1373 strm.IndentMore();
1374 for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
1375 if (module_sp) {
1376 if (num_dumped++ > 0) {
1377 strm.EOL();
1378 strm.EOL();
1379 }
1380 ObjectFile *objfile = module_sp->GetObjectFile();
1381 if (objfile)
1382 objfile->Dump(&strm);
1383 else {
1384 strm.Format("No object file for module: {0:F}\n",
1385 module_sp->GetFileSpec());
1386 }
1387 }
1388 }
1389 strm.IndentLess();
1390 return num_dumped;
1391}
1392
1393static void DumpModuleSymtab(CommandInterpreter &interpreter, Stream &strm,
1394 Module *module, SortOrder sort_order,
1395 Mangled::NamePreference name_preference) {
1396 if (!module)
1397 return;
1398 if (Symtab *symtab = module->GetSymtab())
1399 symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(),
1400 sort_order, name_preference);
1401}
1402
1403static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm,
1404 Module *module) {
1405 if (module) {
1406 SectionList *section_list = module->GetSectionList();
1407 if (section_list) {
1408 strm.Printf("Sections for '%s' (%s):\n",
1409 module->GetSpecificationDescription().c_str(),
1411 section_list->Dump(strm.AsRawOstream(), strm.GetIndentLevel() + 2,
1412 interpreter.GetExecutionContext().GetTargetPtr(), true,
1413 UINT32_MAX);
1414 }
1415 }
1416}
1417
1418static bool DumpModuleSymbolFile(Stream &strm, Module *module) {
1419 if (module) {
1420 if (SymbolFile *symbol_file = module->GetSymbolFile(true)) {
1421 symbol_file->Dump(strm);
1422 return true;
1423 }
1424 }
1425 return false;
1426}
1427
1429 Module *module, bool errors_only,
1430 bool load_all_debug_info) {
1431 if (module) {
1432 if (SymbolFile *symbol_file = module->GetSymbolFile(/*can_create=*/true)) {
1434 if (symbol_file->GetSeparateDebugInfo(d, errors_only,
1435 load_all_debug_info)) {
1436 list.AddItem(
1437 std::make_shared<StructuredData::Dictionary>(std::move(d)));
1438 return true;
1439 }
1440 }
1441 }
1442 return false;
1443}
1444
1445static void DumpDwoFilesTable(Stream &strm,
1446 StructuredData::Array &dwo_listings) {
1447 strm.PutCString("Dwo ID Err Dwo Path");
1448 strm.EOL();
1449 strm.PutCString(
1450 "------------------ --- -----------------------------------------");
1451 strm.EOL();
1452 dwo_listings.ForEach([&strm](StructuredData::Object *dwo) {
1454 if (!dict)
1455 return false;
1456
1457 uint64_t dwo_id;
1458 if (dict->GetValueForKeyAsInteger("dwo_id", dwo_id))
1459 strm.Printf("0x%16.16" PRIx64 " ", dwo_id);
1460 else
1461 strm.Printf("0x???????????????? ");
1462
1463 llvm::StringRef error;
1464 if (dict->GetValueForKeyAsString("error", error))
1465 strm << "E " << error;
1466 else {
1467 llvm::StringRef resolved_dwo_path;
1468 if (dict->GetValueForKeyAsString("resolved_dwo_path",
1469 resolved_dwo_path)) {
1470 strm << " " << resolved_dwo_path;
1471 if (resolved_dwo_path.ends_with(".dwp")) {
1472 llvm::StringRef dwo_name;
1473 if (dict->GetValueForKeyAsString("dwo_name", dwo_name))
1474 strm << "(" << dwo_name << ")";
1475 }
1476 }
1477 }
1478 strm.EOL();
1479 return true;
1480 });
1481}
1482
1483static void DumpOsoFilesTable(Stream &strm,
1484 StructuredData::Array &oso_listings) {
1485 strm.PutCString("Mod Time Err Oso Path");
1486 strm.EOL();
1487 strm.PutCString("------------------ --- ---------------------");
1488 strm.EOL();
1489 oso_listings.ForEach([&strm](StructuredData::Object *oso) {
1491 if (!dict)
1492 return false;
1493
1494 uint32_t oso_mod_time;
1495 if (dict->GetValueForKeyAsInteger("oso_mod_time", oso_mod_time))
1496 strm.Printf("0x%16.16" PRIx32 " ", oso_mod_time);
1497
1498 llvm::StringRef error;
1499 if (dict->GetValueForKeyAsString("error", error))
1500 strm << "E " << error;
1501 else {
1502 llvm::StringRef oso_path;
1503 if (dict->GetValueForKeyAsString("oso_path", oso_path))
1504 strm << " " << oso_path;
1505 }
1506 strm.EOL();
1507 return true;
1508 });
1509}
1510
1511static void
1512DumpAddress(ExecutionContextScope *exe_scope, const Address &so_addr,
1513 bool verbose, bool all_ranges, Stream &strm,
1514 std::optional<Stream::HighlightSettings> settings = std::nullopt) {
1515 strm.IndentMore();
1516 strm.Indent(" Address: ");
1517 so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
1518 strm.PutCString(" (");
1519 so_addr.Dump(&strm, exe_scope, Address::DumpStyleSectionNameOffset);
1520 strm.PutCString(")\n");
1521 strm.Indent(" Summary: ");
1522 const uint32_t save_indent = strm.GetIndentLevel();
1523 strm.SetIndentLevel(save_indent + 13);
1524 so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription,
1525 Address::DumpStyleInvalid, UINT32_MAX, false, settings);
1526 strm.SetIndentLevel(save_indent);
1527 // Print out detailed address information when verbose is enabled
1528 if (verbose) {
1529 strm.EOL();
1530 so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext,
1531 Address::DumpStyleInvalid, UINT32_MAX, all_ranges, settings);
1532 }
1533 strm.IndentLess();
1534}
1535
1536static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm,
1537 Module *module, uint32_t resolve_mask,
1538 lldb::addr_t raw_addr, lldb::addr_t offset,
1539 bool verbose, bool all_ranges) {
1540 if (module) {
1541 lldb::addr_t addr = raw_addr - offset;
1542 Address so_addr;
1543 SymbolContext sc;
1544 Target *target = interpreter.GetExecutionContext().GetTargetPtr();
1545 if (target && target->HasLoadedSections()) {
1546 if (!target->ResolveLoadAddress(addr, so_addr))
1547 return false;
1548 else if (so_addr.GetModule().get() != module)
1549 return false;
1550 } else {
1551 if (!module->ResolveFileAddress(addr, so_addr))
1552 return false;
1553 }
1554
1555 ExecutionContextScope *exe_scope =
1557 DumpAddress(exe_scope, so_addr, verbose, all_ranges, strm);
1558 return true;
1559 }
1560
1561 return false;
1562}
1563
1564static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
1565 Stream &strm, Module *module,
1566 const char *name, bool name_is_regex,
1567 bool verbose, bool all_ranges) {
1568 if (!module)
1569 return 0;
1570
1571 Symtab *symtab = module->GetSymtab();
1572 if (!symtab)
1573 return 0;
1574
1575 SymbolContext sc;
1576 const bool use_color = interpreter.GetDebugger().GetUseColor();
1577 std::vector<uint32_t> match_indexes;
1578 ConstString symbol_name(name);
1579 uint32_t num_matches = 0;
1580 if (name_is_regex) {
1581 RegularExpression name_regexp(symbol_name.GetStringRef());
1582 num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType(
1583 name_regexp, eSymbolTypeAny, match_indexes);
1584 } else {
1585 num_matches =
1586 symtab->AppendSymbolIndexesWithName(symbol_name, match_indexes);
1587 }
1588
1589 if (num_matches > 0) {
1590 strm.Indent();
1591 strm.Printf("%u symbols match %s'%s' in ", num_matches,
1592 name_is_regex ? "the regular expression " : "", name);
1593 DumpFullpath(strm, &module->GetFileSpec(), 0);
1594 strm.PutCString(":\n");
1595 strm.IndentMore();
1597 name, interpreter.GetDebugger().GetRegexMatchAnsiPrefix(),
1598 interpreter.GetDebugger().GetRegexMatchAnsiSuffix());
1599 for (uint32_t i = 0; i < num_matches; ++i) {
1600 const Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
1601 if (symbol) {
1602 if (symbol->ValueIsAddress()) {
1605 symbol->GetAddressRef(), verbose, all_ranges, strm,
1606 use_color && name_is_regex
1607 ? std::optional<Stream::HighlightSettings>{settings}
1608 : std::nullopt);
1609 strm.EOL();
1610 } else {
1611 strm.IndentMore();
1612 strm.Indent(" Name: ");
1614 symbol->GetDisplayName().GetStringRef(),
1615 use_color && name_is_regex
1616 ? std::optional<Stream::HighlightSettings>{settings}
1617 : std::nullopt);
1618 strm.EOL();
1619 strm.Indent(" Value: ");
1620 strm.Printf("0x%16.16" PRIx64 "\n", symbol->GetRawValue());
1621 if (symbol->GetByteSizeIsValid()) {
1622 strm.Indent(" Size: ");
1623 strm.Printf("0x%16.16" PRIx64 "\n", symbol->GetByteSize());
1624 }
1625 strm.IndentLess();
1626 }
1627 }
1628 }
1629 strm.IndentLess();
1630 }
1631 return num_matches;
1632}
1633
1635 ExecutionContextScope *exe_scope, Stream &strm,
1636 const SymbolContextList &sc_list, bool verbose, bool all_ranges,
1637 std::optional<Stream::HighlightSettings> settings = std::nullopt) {
1638 strm.IndentMore();
1639 bool first_module = true;
1640 for (const SymbolContext &sc : sc_list) {
1641 if (!first_module)
1642 strm.EOL();
1643
1644 Address addr;
1645 if (sc.line_entry.IsValid())
1646 addr = sc.line_entry.range.GetBaseAddress();
1647 else if (sc.block && sc.block->GetContainingInlinedBlock())
1648 sc.block->GetContainingInlinedBlock()->GetStartAddress(addr);
1649 else
1650 addr = sc.GetFunctionOrSymbolAddress();
1651
1652 DumpAddress(exe_scope, addr, verbose, all_ranges, strm, settings);
1653 first_module = false;
1654 }
1655 strm.IndentLess();
1656}
1657
1659 Stream &strm, Module *module,
1660 const char *name, bool name_is_regex,
1661 const ModuleFunctionSearchOptions &options,
1662 bool verbose, bool all_ranges) {
1663 if (module && name && name[0]) {
1664 SymbolContextList sc_list;
1665 size_t num_matches = 0;
1666 if (name_is_regex) {
1667 RegularExpression function_name_regex((llvm::StringRef(name)));
1668 module->FindFunctions(function_name_regex, options, sc_list);
1669 } else {
1670 ConstString function_name(name);
1671 module->FindFunctions(function_name, CompilerDeclContext(),
1672 eFunctionNameTypeAuto, options, sc_list);
1673 }
1674 num_matches = sc_list.GetSize();
1675 if (num_matches) {
1676 strm.Indent();
1677 strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
1678 num_matches > 1 ? "es" : "");
1679 DumpFullpath(strm, &module->GetFileSpec(), 0);
1680 strm.PutCString(":\n");
1683 strm, sc_list, verbose, all_ranges);
1684 }
1685 return num_matches;
1686 }
1687 return 0;
1688}
1689
1690static size_t LookupTypeInModule(Target *target,
1691 CommandInterpreter &interpreter, Stream &strm,
1692 Module *module, const char *name_cstr,
1693 bool name_is_regex) {
1694 if (module && name_cstr && name_cstr[0]) {
1695 TypeQuery query(name_cstr);
1696 TypeResults results;
1697 module->FindTypes(query, results);
1698
1699 TypeList type_list;
1700 SymbolContext sc;
1701 if (module)
1702 sc.module_sp = module->shared_from_this();
1703 // Sort the type results and put the results that matched in \a module
1704 // first if \a module was specified.
1705 sc.SortTypeList(results.GetTypeMap(), type_list);
1706 if (type_list.Empty())
1707 return 0;
1708
1709 const uint64_t num_matches = type_list.GetSize();
1710
1711 strm.Indent();
1712 strm.Printf("%" PRIu64 " match%s found in ", num_matches,
1713 num_matches > 1 ? "es" : "");
1714 DumpFullpath(strm, &module->GetFileSpec(), 0);
1715 strm.PutCString(":\n");
1716 for (TypeSP type_sp : type_list.Types()) {
1717 if (!type_sp)
1718 continue;
1719 // Resolve the clang type so that any forward references to types
1720 // that haven't yet been parsed will get parsed.
1721 type_sp->GetFullCompilerType();
1722 type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target);
1723 // Print all typedef chains
1724 TypeSP typedef_type_sp(type_sp);
1725 TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1726 while (typedefed_type_sp) {
1727 strm.EOL();
1728 strm.Printf(" typedef '%s': ",
1729 typedef_type_sp->GetName().GetCString());
1730 typedefed_type_sp->GetFullCompilerType();
1731 typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true,
1732 target);
1733 typedef_type_sp = typedefed_type_sp;
1734 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1735 }
1736 strm.EOL();
1737 }
1738 return type_list.GetSize();
1739 }
1740 return 0;
1741}
1742
1743static size_t LookupTypeHere(Target *target, CommandInterpreter &interpreter,
1744 Stream &strm, Module &module,
1745 const char *name_cstr, bool name_is_regex) {
1746 TypeQuery query(name_cstr);
1747 TypeResults results;
1748 module.FindTypes(query, results);
1749 TypeList type_list;
1750 SymbolContext sc;
1751 sc.module_sp = module.shared_from_this();
1752 sc.SortTypeList(results.GetTypeMap(), type_list);
1753 if (type_list.Empty())
1754 return 0;
1755
1756 strm.Indent();
1757 strm.PutCString("Best match found in ");
1758 DumpFullpath(strm, &module.GetFileSpec(), 0);
1759 strm.PutCString(":\n");
1760
1761 TypeSP type_sp(type_list.GetTypeAtIndex(0));
1762 if (type_sp) {
1763 // Resolve the clang type so that any forward references to types that
1764 // haven't yet been parsed will get parsed.
1765 type_sp->GetFullCompilerType();
1766 type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target);
1767 // Print all typedef chains.
1768 TypeSP typedef_type_sp(type_sp);
1769 TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1770 while (typedefed_type_sp) {
1771 strm.EOL();
1772 strm.Printf(" typedef '%s': ",
1773 typedef_type_sp->GetName().GetCString());
1774 typedefed_type_sp->GetFullCompilerType();
1775 typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true,
1776 target);
1777 typedef_type_sp = typedefed_type_sp;
1778 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1779 }
1780 }
1781 strm.EOL();
1782 return type_list.GetSize();
1783}
1784
1786 Stream &strm, Module *module,
1787 const FileSpec &file_spec,
1788 uint32_t line, bool check_inlines,
1789 bool verbose, bool all_ranges) {
1790 if (module && file_spec) {
1791 SymbolContextList sc_list;
1792 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(
1793 file_spec, line, check_inlines, eSymbolContextEverything, sc_list);
1794 if (num_matches > 0) {
1795 strm.Indent();
1796 strm.Printf("%u match%s found in ", num_matches,
1797 num_matches > 1 ? "es" : "");
1798 strm << file_spec;
1799 if (line > 0)
1800 strm.Printf(":%u", line);
1801 strm << " in ";
1802 DumpFullpath(strm, &module->GetFileSpec(), 0);
1803 strm.PutCString(":\n");
1806 strm, sc_list, verbose, all_ranges);
1807 return num_matches;
1808 }
1809 }
1810 return 0;
1811}
1812
1813static size_t FindModulesByName(Target *target, const char *module_name,
1814 ModuleList &module_list,
1815 bool check_global_list) {
1816 FileSpec module_file_spec(module_name);
1817 ModuleSpec module_spec(module_file_spec);
1818
1819 const size_t initial_size = module_list.GetSize();
1820
1821 if (check_global_list) {
1822 // Check the global list
1823 std::lock_guard<std::recursive_mutex> guard(
1825 const size_t num_modules = Module::GetNumberAllocatedModules();
1826 ModuleSP module_sp;
1827 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
1828 Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
1829
1830 if (module) {
1831 if (module->MatchesModuleSpec(module_spec)) {
1832 module_sp = module->shared_from_this();
1833 module_list.AppendIfNeeded(module_sp);
1834 }
1835 }
1836 }
1837 } else {
1838 if (target) {
1839 target->GetImages().FindModules(module_spec, module_list);
1840 const size_t num_matches = module_list.GetSize();
1841
1842 // Not found in our module list for our target, check the main shared
1843 // module list in case it is a extra file used somewhere else
1844 if (num_matches == 0) {
1845 module_spec.GetArchitecture() = target->GetArchitecture();
1846 ModuleList::FindSharedModules(module_spec, module_list);
1847 }
1848 } else {
1849 ModuleList::FindSharedModules(module_spec, module_list);
1850 }
1851 }
1852
1853 return module_list.GetSize() - initial_size;
1854}
1855
1856#pragma mark CommandObjectTargetModulesModuleAutoComplete
1857
1858// A base command object class that can auto complete with module file
1859// paths
1860
1862 : public CommandObjectParsed {
1863public:
1865 const char *name,
1866 const char *help,
1867 const char *syntax,
1868 uint32_t flags = 0)
1869 : CommandObjectParsed(interpreter, name, help, syntax, flags) {
1871 }
1872
1874
1875 void
1881};
1882
1883#pragma mark CommandObjectTargetModulesSourceFileAutoComplete
1884
1885// A base command object class that can auto complete with module source
1886// file paths
1887
1889 : public CommandObjectParsed {
1890public:
1892 CommandInterpreter &interpreter, const char *name, const char *help,
1893 const char *syntax, uint32_t flags)
1894 : CommandObjectParsed(interpreter, name, help, syntax, flags) {
1896 }
1897
1899
1900 void
1906};
1907
1908#pragma mark CommandObjectTargetModulesDumpObjfile
1909
1912public:
1915 interpreter, "target modules dump objfile",
1916 "Dump the object file headers from one or more target modules.",
1917 nullptr, eCommandRequiresTarget) {}
1918
1920
1921protected:
1922 void DoExecute(Args &command, CommandReturnObject &result) override {
1923 Target *target = GetTarget();
1924 assert(target && "target guaranteed by eCommandRequiresTarget");
1925 size_t num_dumped = 0;
1926 if (command.GetArgumentCount() == 0) {
1927 // Dump all headers for all modules images
1928 num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(),
1929 target->GetImages());
1930 if (num_dumped == 0) {
1931 result.AppendError("the target has no associated executable images");
1932 }
1933 } else {
1934 // Find the modules that match the basename or full path.
1935 ModuleList module_list;
1936 const char *arg_cstr;
1937 for (int arg_idx = 0;
1938 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
1939 ++arg_idx) {
1940 size_t num_matched =
1941 FindModulesByName(target, arg_cstr, module_list, true);
1942 if (num_matched == 0) {
1944 "unable to find an image that matches '{0}'", arg_cstr);
1945 }
1946 }
1947 // Dump all the modules we found.
1948 num_dumped =
1949 DumpModuleObjfileHeaders(result.GetOutputStream(), module_list);
1950 }
1951
1952 if (num_dumped > 0) {
1954 } else {
1955 result.AppendError("no matching executable images found");
1956 }
1957 }
1958};
1959
1960#define LLDB_OPTIONS_target_modules_dump_symtab
1961#include "CommandOptions.inc"
1962
1965public:
1968 interpreter, "target modules dump symtab",
1969 "Dump the symbol table from one or more target modules.", nullptr,
1970 eCommandRequiresTarget) {}
1971
1973
1974 Options *GetOptions() override { return &m_options; }
1975
1976 class CommandOptions : public Options {
1977 public:
1978 CommandOptions() = default;
1979
1980 ~CommandOptions() override = default;
1981
1982 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1983 ExecutionContext *execution_context) override {
1984 Status error;
1985 const int short_option = m_getopt_table[option_idx].val;
1986
1987 switch (short_option) {
1988 case 'm':
1989 m_prefer_mangled.SetCurrentValue(true);
1990 m_prefer_mangled.SetOptionWasSet();
1991 break;
1992
1993 case 's':
1995 option_arg, GetDefinitions()[option_idx].enum_values,
1997 break;
1998
1999 default:
2000 llvm_unreachable("Unimplemented option");
2001 }
2002 return error;
2003 }
2004
2005 void OptionParsingStarting(ExecutionContext *execution_context) override {
2007 m_prefer_mangled.Clear();
2008 }
2009
2010 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2011 return llvm::ArrayRef(g_target_modules_dump_symtab_options);
2012 }
2013
2016 };
2017
2018protected:
2019 void DoExecute(Args &command, CommandReturnObject &result) override {
2020 Target *target = GetTarget();
2021 assert(target && "target guaranteed by eCommandRequiresTarget");
2022 uint32_t num_dumped = 0;
2023 Mangled::NamePreference name_preference =
2024 (m_options.m_prefer_mangled ? Mangled::ePreferMangled
2026
2027 if (command.GetArgumentCount() == 0) {
2028 // Dump all sections for all modules images
2029 const ModuleList &module_list = target->GetImages();
2030 std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
2031 const size_t num_modules = module_list.GetSize();
2032 if (num_modules > 0) {
2033 result.GetOutputStream().Format(
2034 "Dumping symbol table for {0} modules.\n", num_modules);
2035 for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
2036 if (num_dumped > 0) {
2037 result.GetOutputStream().EOL();
2038 result.GetOutputStream().EOL();
2039 }
2041 "Interrupted in dump all symtabs with {0} "
2042 "of {1} dumped.", num_dumped, num_modules))
2043 break;
2044
2045 num_dumped++;
2047 module_sp.get(), m_options.m_sort_order,
2048 name_preference);
2049 }
2050 } else {
2051 result.AppendError("the target has no associated executable images");
2052 return;
2053 }
2054 } else {
2055 // Dump specified images (by basename or fullpath)
2056 const char *arg_cstr;
2057 for (int arg_idx = 0;
2058 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2059 ++arg_idx) {
2060 ModuleList module_list;
2061 const size_t num_matches =
2062 FindModulesByName(target, arg_cstr, module_list, true);
2063 if (num_matches > 0) {
2064 for (ModuleSP module_sp : module_list.Modules()) {
2065 if (module_sp) {
2066 if (num_dumped > 0) {
2067 result.GetOutputStream().EOL();
2068 result.GetOutputStream().EOL();
2069 }
2071 "Interrupted in dump symtab list with {0} of {1} dumped.",
2072 num_dumped, num_matches))
2073 break;
2074
2075 num_dumped++;
2077 module_sp.get(), m_options.m_sort_order,
2078 name_preference);
2079 }
2080 }
2081 } else
2083 "unable to find an image that matches '{0}'", arg_cstr);
2084 }
2085 }
2086
2087 if (num_dumped > 0)
2089 else {
2090 result.AppendError("no matching executable images found");
2091 }
2092 }
2093
2095};
2096
2097#pragma mark CommandObjectTargetModulesDumpSections
2098
2099// Image section dumping command
2100
2103public:
2106 interpreter, "target modules dump sections",
2107 "Dump the sections from one or more target modules.",
2108 //"target modules dump sections [<file1> ...]")
2109 nullptr, eCommandRequiresTarget) {}
2110
2112
2113protected:
2114 void DoExecute(Args &command, CommandReturnObject &result) override {
2115 Target *target = GetTarget();
2116 assert(target && "target guaranteed by eCommandRequiresTarget");
2117 uint32_t num_dumped = 0;
2118
2119 if (command.GetArgumentCount() == 0) {
2120 // Dump all sections for all modules images
2121 const size_t num_modules = target->GetImages().GetSize();
2122 if (num_modules == 0) {
2123 result.AppendError("the target has no associated executable images");
2124 return;
2125 }
2126
2127 result.GetOutputStream().Format("Dumping sections for {0} modules.\n",
2128 num_modules);
2129 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2131 "Interrupted in dump all sections with {0} of {1} dumped",
2132 image_idx, num_modules))
2133 break;
2134
2135 num_dumped++;
2138 target->GetImages().GetModulePointerAtIndex(image_idx));
2139 }
2140 } else {
2141 // Dump specified images (by basename or fullpath)
2142 const char *arg_cstr;
2143 for (int arg_idx = 0;
2144 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2145 ++arg_idx) {
2146 ModuleList module_list;
2147 const size_t num_matches =
2148 FindModulesByName(target, arg_cstr, module_list, true);
2149 if (num_matches > 0) {
2150 for (size_t i = 0; i < num_matches; ++i) {
2152 "Interrupted in dump section list with {0} of {1} dumped.",
2153 i, num_matches))
2154 break;
2155
2156 Module *module = module_list.GetModulePointerAtIndex(i);
2157 if (module) {
2158 num_dumped++;
2160 module);
2161 }
2162 }
2163 } else {
2164 // Check the global list
2165 std::lock_guard<std::recursive_mutex> guard(
2167
2169 "unable to find an image that matches '{0}'", arg_cstr);
2170 }
2171 }
2172 }
2173
2174 if (num_dumped > 0)
2176 else {
2177 result.AppendError("no matching executable images found");
2178 }
2179 }
2180};
2181
2183public:
2186 interpreter, "target modules dump pcm-info",
2187 "Dump information about the given clang module (pcm).") {
2188 // Take a single file argument.
2190 }
2191
2193
2194protected:
2195 void DoExecute(Args &command, CommandReturnObject &result) override {
2196 if (command.GetArgumentCount() != 1) {
2197 result.AppendErrorWithFormat("'%s' takes exactly one pcm path argument",
2198 m_cmd_name.c_str());
2199 return;
2200 }
2201
2202 const char *pcm_path = command.GetArgumentAtIndex(0);
2203 const FileSpec pcm_file{pcm_path};
2204
2205 if (pcm_file.GetFileNameExtension() != ".pcm") {
2206 result.AppendError("file must have a .pcm extension");
2207 return;
2208 }
2209
2210 if (!FileSystem::Instance().Exists(pcm_file)) {
2211 result.AppendError("pcm file does not exist");
2212 return;
2213 }
2214
2215 const char *clang_args[] = {"clang", pcm_path};
2216 clang::CompilerInstance compiler(clang::createInvocation(clang_args));
2217 compiler.setVirtualFileSystem(
2218 FileSystem::Instance().GetVirtualFileSystem());
2219 compiler.createDiagnostics();
2220
2221 // Pass empty deleter to not attempt to free memory that was allocated
2222 // outside of the current scope, possibly statically.
2223 std::shared_ptr<llvm::raw_ostream> Out(
2224 &result.GetOutputStream().AsRawOstream(), [](llvm::raw_ostream *) {});
2225 clang::DumpModuleInfoAction dump_module_info(Out);
2226 // DumpModuleInfoAction requires ObjectFilePCHContainerReader.
2227 compiler.getPCHContainerOperations()->registerReader(
2228 std::make_unique<clang::ObjectFilePCHContainerReader>());
2229
2230 if (compiler.ExecuteAction(dump_module_info))
2232 }
2233};
2234
2235#pragma mark CommandObjectTargetModulesDumpClangAST
2236
2237// Clang AST dumping command
2238
2241public:
2244 interpreter, "target modules dump ast",
2245 "Dump the clang ast for a given module's symbol file.",
2246 "target modules dump ast [--filter <name>] [<file1> ...]",
2247 eCommandRequiresTarget),
2248 m_filter(LLDB_OPT_SET_1, false, "filter", 'f', 0, eArgTypeName,
2249 "Dump only the decls whose names contain the specified filter "
2250 "string.",
2251 /*default_value=*/"") {
2253 m_option_group.Finalize();
2254 }
2255
2256 Options *GetOptions() override { return &m_option_group; }
2257
2259
2262
2263protected:
2264 void DoExecute(Args &command, CommandReturnObject &result) override {
2265 Target *target = GetTarget();
2266 assert(target && "target guaranteed by eCommandRequiresTarget");
2267 const ModuleList &module_list = target->GetImages();
2268 const size_t num_modules = module_list.GetSize();
2269 if (num_modules == 0) {
2270 result.AppendError("the target has no associated executable images");
2271 return;
2272 }
2273
2274 llvm::StringRef filter = m_filter.GetOptionValue().GetCurrentValueAsRef();
2275
2276 if (command.GetArgumentCount() == 0) {
2277 // Dump all ASTs for all modules images
2278 result.GetOutputStream().Format("Dumping clang ast for {0} modules.\n",
2279 num_modules);
2280 for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
2281 if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted dumping clang ast"))
2282 break;
2283 if (SymbolFile *sf = module_sp->GetSymbolFile())
2284 sf->DumpClangAST(result.GetOutputStream(), filter,
2285 GetCommandInterpreter().GetDebugger().GetUseColor());
2286 }
2288 return;
2289 }
2290
2291 // Dump specified ASTs (by basename or fullpath)
2292 for (const Args::ArgEntry &arg : command.entries()) {
2293 ModuleList module_list;
2294 const size_t num_matches =
2295 FindModulesByName(target, arg.c_str(), module_list, true);
2296 if (num_matches == 0) {
2297 // Check the global list
2298 std::lock_guard<std::recursive_mutex> guard(
2300
2302 "unable to find an image that matches '{0}'", arg.c_str());
2303 continue;
2304 }
2305
2306 for (size_t i = 0; i < num_matches; ++i) {
2308 "Interrupted in dump clang ast list with {0} of {1} dumped.",
2309 i, num_matches))
2310 break;
2311
2312 Module *m = module_list.GetModulePointerAtIndex(i);
2313 if (SymbolFile *sf = m->GetSymbolFile())
2314 sf->DumpClangAST(result.GetOutputStream(), filter,
2315 GetCommandInterpreter().GetDebugger().GetUseColor());
2316 }
2317 }
2319 }
2320};
2321
2322#pragma mark CommandObjectTargetModulesDumpSymfile
2323
2324// Image debug symbol dumping command
2325
2328public:
2331 interpreter, "target modules dump symfile",
2332 "Dump the debug symbol file for one or more target modules.",
2333 //"target modules dump symfile [<file1> ...]")
2334 nullptr, eCommandRequiresTarget) {}
2335
2337
2338protected:
2339 void DoExecute(Args &command, CommandReturnObject &result) override {
2340 Target *target = GetTarget();
2341 assert(target && "target guaranteed by eCommandRequiresTarget");
2342 uint32_t num_dumped = 0;
2343
2344 if (command.GetArgumentCount() == 0) {
2345 // Dump all sections for all modules images
2346 const ModuleList &target_modules = target->GetImages();
2347 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2348 const size_t num_modules = target_modules.GetSize();
2349 if (num_modules == 0) {
2350 result.AppendError("the target has no associated executable images");
2351 return;
2352 }
2353 result.GetOutputStream().Format(
2354 "Dumping debug symbols for {0} modules.\n", num_modules);
2355 for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
2356 if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted in dumping all "
2357 "debug symbols with {0} of {1} modules dumped",
2358 num_dumped, num_modules))
2359 break;
2360
2361 if (DumpModuleSymbolFile(result.GetOutputStream(), module_sp.get()))
2362 num_dumped++;
2363 }
2364 } else {
2365 // Dump specified images (by basename or fullpath)
2366 const char *arg_cstr;
2367 for (int arg_idx = 0;
2368 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2369 ++arg_idx) {
2370 ModuleList module_list;
2371 const size_t num_matches =
2372 FindModulesByName(target, arg_cstr, module_list, true);
2373 if (num_matches > 0) {
2374 for (size_t i = 0; i < num_matches; ++i) {
2375 if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted dumping {0} "
2376 "of {1} requested modules",
2377 i, num_matches))
2378 break;
2379 Module *module = module_list.GetModulePointerAtIndex(i);
2380 if (module) {
2381 if (DumpModuleSymbolFile(result.GetOutputStream(), module))
2382 num_dumped++;
2383 }
2384 }
2385 } else
2387 "unable to find an image that matches '{0}'", arg_cstr);
2388 }
2389 }
2390
2391 if (num_dumped > 0)
2393 else {
2394 result.AppendError("no matching executable images found");
2395 }
2396 }
2397};
2398
2399#pragma mark CommandObjectTargetModulesDumpLineTable
2400#define LLDB_OPTIONS_target_modules_dump
2401#include "CommandOptions.inc"
2402
2403// Image debug line table dumping command
2404
2407public:
2410 interpreter, "target modules dump line-table",
2411 "Dump the line table for one or more compilation units.", nullptr,
2412 eCommandRequiresTarget) {}
2413
2415
2416 Options *GetOptions() override { return &m_options; }
2417
2418protected:
2419 void DoExecute(Args &command, CommandReturnObject &result) override {
2420 Target *target = m_exe_ctx.GetTargetPtr();
2421 uint32_t total_num_dumped = 0;
2422
2423 if (command.GetArgumentCount() == 0) {
2424 result.AppendError("file option must be specified");
2425 return;
2426 } else {
2427 // Dump specified images (by basename or fullpath)
2428 const char *arg_cstr;
2429 for (int arg_idx = 0;
2430 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2431 ++arg_idx) {
2432 FileSpec file_spec(arg_cstr);
2433
2434 const ModuleList &target_modules = target->GetImages();
2435 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2436 size_t num_modules = target_modules.GetSize();
2437 if (num_modules > 0) {
2438 uint32_t num_dumped = 0;
2439 for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
2441 "Interrupted in dump all line tables with "
2442 "{0} of {1} dumped", num_dumped,
2443 num_modules))
2444 break;
2445
2447 m_interpreter, result.GetOutputStream(), module_sp.get(),
2448 file_spec,
2451 num_dumped++;
2452 }
2453 if (num_dumped == 0)
2454 result.AppendWarningWithFormatv("no source filenames matched '{0}'",
2455 arg_cstr);
2456 else
2457 total_num_dumped += num_dumped;
2458 }
2459 }
2460 }
2461
2462 if (total_num_dumped > 0)
2464 else {
2465 result.AppendError("no source filenames matched any command arguments");
2466 }
2467 }
2468
2469 class CommandOptions : public Options {
2470 public:
2472
2473 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2474 ExecutionContext *execution_context) override {
2475 assert(option_idx == 0 && "We only have one option.");
2476 m_verbose = true;
2477
2478 return Status();
2479 }
2480
2481 void OptionParsingStarting(ExecutionContext *execution_context) override {
2482 m_verbose = false;
2483 }
2484
2485 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2486 return llvm::ArrayRef(g_target_modules_dump_options);
2487 }
2488
2490 };
2491
2493};
2494
2495#pragma mark CommandObjectTargetModulesDumpSeparateDebugInfoFiles
2496#define LLDB_OPTIONS_target_modules_dump_separate_debug_info
2497#include "CommandOptions.inc"
2498
2499// Image debug separate debug info dumping command
2500
2503public:
2505 CommandInterpreter &interpreter)
2507 interpreter, "target modules dump separate-debug-info",
2508 "List the separate debug info symbol files for one or more target "
2509 "modules.",
2510 nullptr, eCommandRequiresTarget) {}
2511
2513
2514 Options *GetOptions() override { return &m_options; }
2515
2516 class CommandOptions : public Options {
2517 public:
2518 CommandOptions() = default;
2519
2520 ~CommandOptions() override = default;
2521
2522 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2523 ExecutionContext *execution_context) override {
2524 Status error;
2525 const int short_option = m_getopt_table[option_idx].val;
2526
2527 switch (short_option) {
2528 case 'f':
2529 m_load_all_debug_info.SetCurrentValue(true);
2530 m_load_all_debug_info.SetOptionWasSet();
2531 break;
2532 case 'j':
2533 m_json.SetCurrentValue(true);
2534 m_json.SetOptionWasSet();
2535 break;
2536 case 'e':
2537 m_errors_only.SetCurrentValue(true);
2538 m_errors_only.SetOptionWasSet();
2539 break;
2540 default:
2541 llvm_unreachable("Unimplemented option");
2542 }
2543 return error;
2544 }
2545
2546 void OptionParsingStarting(ExecutionContext *execution_context) override {
2547 m_json.Clear();
2548 m_errors_only.Clear();
2549 m_load_all_debug_info.Clear();
2550 }
2551
2552 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2553 return llvm::ArrayRef(g_target_modules_dump_separate_debug_info_options);
2554 }
2555
2559 };
2560
2561protected:
2562 void DoExecute(Args &command, CommandReturnObject &result) override {
2563 Target *target = GetTarget();
2564 assert(target && "target guaranteed by eCommandRequiresTarget");
2565 uint32_t num_dumped = 0;
2566
2567 StructuredData::Array separate_debug_info_lists_by_module;
2568 if (command.GetArgumentCount() == 0) {
2569 // Dump all sections for all modules images
2570 const ModuleList &target_modules = target->GetImages();
2571 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2572 const size_t num_modules = target_modules.GetSize();
2573 if (num_modules == 0) {
2574 result.AppendError("the target has no associated executable images");
2575 return;
2576 }
2577 for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
2579 GetDebugger(),
2580 "Interrupted in dumping all "
2581 "separate debug info with {0} of {1} modules dumped",
2582 num_dumped, num_modules))
2583 break;
2584
2585 if (GetSeparateDebugInfoList(separate_debug_info_lists_by_module,
2586 module_sp.get(),
2587 bool(m_options.m_errors_only),
2588 bool(m_options.m_load_all_debug_info)))
2589 num_dumped++;
2590 }
2591 } else {
2592 // Dump specified images (by basename or fullpath)
2593 const char *arg_cstr;
2594 for (int arg_idx = 0;
2595 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2596 ++arg_idx) {
2597 ModuleList module_list;
2598 const size_t num_matches =
2599 FindModulesByName(target, arg_cstr, module_list, true);
2600 if (num_matches > 0) {
2601 for (size_t i = 0; i < num_matches; ++i) {
2603 "Interrupted dumping {0} "
2604 "of {1} requested modules",
2605 i, num_matches))
2606 break;
2607 Module *module = module_list.GetModulePointerAtIndex(i);
2608 if (GetSeparateDebugInfoList(separate_debug_info_lists_by_module,
2609 module, bool(m_options.m_errors_only),
2610 bool(m_options.m_load_all_debug_info)))
2611 num_dumped++;
2612 }
2613 } else
2615 "unable to find an image that matches '{0}'", arg_cstr);
2616 }
2617 }
2618
2619 if (num_dumped > 0) {
2620 Stream &strm = result.GetOutputStream();
2621 // Display the debug info files in some format.
2622 if (m_options.m_json) {
2623 // JSON format
2624 separate_debug_info_lists_by_module.Dump(strm,
2625 /*pretty_print=*/true);
2626 } else {
2627 // Human-readable table format
2628 separate_debug_info_lists_by_module.ForEach(
2629 [&result, &strm](StructuredData::Object *obj) {
2630 if (!obj) {
2631 return false;
2632 }
2633
2634 // Each item in `separate_debug_info_lists_by_module` should be a
2635 // valid structured data dictionary.
2636 StructuredData::Dictionary *separate_debug_info_list =
2637 obj->GetAsDictionary();
2638 if (!separate_debug_info_list) {
2639 return false;
2640 }
2641
2642 llvm::StringRef type;
2643 llvm::StringRef symfile;
2644 StructuredData::Array *files;
2645 if (!(separate_debug_info_list->GetValueForKeyAsString("type",
2646 type) &&
2647 separate_debug_info_list->GetValueForKeyAsString("symfile",
2648 symfile) &&
2649 separate_debug_info_list->GetValueForKeyAsArray(
2650 "separate-debug-info-files", files))) {
2651 assert(false);
2652 }
2653
2654 strm << "Symbol file: " << symfile;
2655 strm.EOL();
2656 strm << "Type: \"" << type << "\"";
2657 strm.EOL();
2658 if (type == "dwo") {
2659 DumpDwoFilesTable(strm, *files);
2660 } else if (type == "oso") {
2661 DumpOsoFilesTable(strm, *files);
2662 } else {
2664 "found unsupported debug info type '{0}'", type);
2665 }
2666 return true;
2667 });
2668 }
2670 } else {
2671 result.AppendError("no matching executable images found");
2672 }
2673 }
2674
2676};
2677
2678#pragma mark CommandObjectTargetModulesDump
2679
2680// Dump multi-word command for target modules
2681
2683public:
2684 // Constructors and Destructors
2687 interpreter, "target modules dump",
2688 "Commands for dumping information about one or more target "
2689 "modules.",
2690 "target modules dump "
2691 "[objfile|symtab|sections|ast|symfile|line-table|pcm-info|separate-"
2692 "debug-info] "
2693 "[<file1> <file2> ...]") {
2694 LoadSubCommand("objfile",
2696 new CommandObjectTargetModulesDumpObjfile(interpreter)));
2698 "symtab",
2700 LoadSubCommand("sections",
2702 interpreter)));
2703 LoadSubCommand("symfile",
2705 new CommandObjectTargetModulesDumpSymfile(interpreter)));
2707 "ast", CommandObjectSP(
2708 new CommandObjectTargetModulesDumpClangAST(interpreter)));
2709 LoadSubCommand("line-table",
2711 interpreter)));
2713 "pcm-info",
2716 LoadSubCommand("separate-debug-info",
2719 interpreter)));
2720 }
2721
2723};
2724
2726public:
2728 : CommandObjectParsed(interpreter, "target modules add",
2729 "Add a new module to the current target's modules.",
2730 "target modules add [<module>]",
2731 eCommandRequiresTarget),
2732 m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
2734 "Fullpath to a stand alone debug "
2735 "symbols file for when debug symbols "
2736 "are not in the executable.") {
2740 m_option_group.Finalize();
2742 }
2743
2745
2746 Options *GetOptions() override { return &m_option_group; }
2747
2748protected:
2752
2753 void DoExecute(Args &args, CommandReturnObject &result) override {
2754 Target *target = GetTarget();
2755 assert(target && "target guaranteed by eCommandRequiresTarget");
2756 bool flush = false;
2757
2758 const size_t argc = args.GetArgumentCount();
2759 if (argc == 0) {
2760 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2761 // We are given a UUID only, go locate the file
2762 ModuleSpec module_spec;
2763 module_spec.GetUUID() =
2764 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2765 if (m_symbol_file.GetOptionValue().OptionWasSet())
2766 module_spec.GetSymbolFileSpec() =
2767 m_symbol_file.GetOptionValue().GetCurrentValue();
2768 Status error;
2770 ModuleSP module_sp(
2771 target->GetOrCreateModule(module_spec, true /* notify */));
2772 if (module_sp) {
2774 return;
2775 } else {
2776 StreamString strm;
2777 module_spec.GetUUID().Dump(strm);
2778 if (module_spec.GetFileSpec()) {
2779 if (module_spec.GetSymbolFileSpec()) {
2780 result.AppendErrorWithFormat(
2781 "Unable to create the executable or symbol file with "
2782 "UUID %s with path %s and symbol file %s",
2783 strm.GetData(), module_spec.GetFileSpec().GetPath().c_str(),
2784 module_spec.GetSymbolFileSpec().GetPath().c_str());
2785 } else {
2786 result.AppendErrorWithFormat(
2787 "Unable to create the executable or symbol file with "
2788 "UUID %s with path %s",
2789 strm.GetData(),
2790 module_spec.GetFileSpec().GetPath().c_str());
2791 }
2792 } else {
2793 result.AppendErrorWithFormat("Unable to create the executable "
2794 "or symbol file with UUID %s",
2795 strm.GetData());
2796 }
2797 return;
2798 }
2799 } else {
2800 StreamString strm;
2801 module_spec.GetUUID().Dump(strm);
2802 result.AppendErrorWithFormat(
2803 "Unable to locate the executable or symbol file with UUID %s",
2804 strm.GetData());
2805 result.SetError(std::move(error));
2806 return;
2807 }
2808 } else {
2809 result.AppendError(
2810 "one or more executable image paths must be specified");
2811 return;
2812 }
2813 } else {
2814 for (auto &entry : args.entries()) {
2815 if (entry.ref().empty())
2816 continue;
2817
2818 FileSpec file_spec(entry.ref());
2819 if (FileSystem::Instance().Exists(file_spec)) {
2820 ModuleSpec module_spec(file_spec);
2821 if (m_uuid_option_group.GetOptionValue().OptionWasSet())
2822 module_spec.GetUUID() =
2823 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2824 if (m_symbol_file.GetOptionValue().OptionWasSet())
2825 module_spec.GetSymbolFileSpec() =
2826 m_symbol_file.GetOptionValue().GetCurrentValue();
2827 if (!module_spec.GetArchitecture().IsValid())
2828 module_spec.GetArchitecture() = target->GetArchitecture();
2829 Status error;
2830 ModuleSP module_sp(target->GetOrCreateModule(
2831 module_spec, true /* notify */, &error));
2832 if (!module_sp) {
2833 const char *error_cstr = error.AsCString();
2834 if (error_cstr)
2835 result.AppendError(error_cstr);
2836 else
2837 result.AppendErrorWithFormat("unsupported module: %s",
2838 entry.c_str());
2839 return;
2840 } else {
2841 flush = true;
2842 }
2844 } else {
2845 std::string resolved_path = file_spec.GetPath();
2846 if (resolved_path != entry.ref()) {
2847 result.AppendErrorWithFormat(
2848 "invalid module path '%s' with resolved path '%s'",
2849 entry.ref().str().c_str(), resolved_path.c_str());
2850 break;
2851 }
2852 result.AppendErrorWithFormat("invalid module path '%s'",
2853 entry.c_str());
2854 break;
2855 }
2856 }
2857 }
2858
2859 if (flush) {
2860 ProcessSP process = target->GetProcessSP();
2861 if (process)
2862 process->Flush();
2863 }
2864 }
2865};
2866
2869public:
2872 interpreter, "target modules load",
2873 "Set the load addresses for one or more sections in a target "
2874 "module.",
2875 "target modules load [--file <module> --uuid <uuid>] <sect-name> "
2876 "<address> [<sect-name> <address> ....]",
2877 eCommandRequiresTarget),
2878 m_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName,
2879 "Fullpath or basename for module to load.", ""),
2880 m_load_option(LLDB_OPT_SET_1, false, "load", 'l',
2881 "Write file contents to the memory.", false, true),
2882 m_pc_option(LLDB_OPT_SET_1, false, "set-pc-to-entry", 'p',
2883 "Set PC to the entry point."
2884 " Only applicable with '--load' option.",
2885 false, true),
2886 m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset,
2887 "Set the load address for all sections to be the "
2888 "virtual address in the file plus the offset.",
2889 0) {
2896 m_option_group.Finalize();
2897 }
2898
2900
2901 Options *GetOptions() override { return &m_option_group; }
2902
2903protected:
2904 void DoExecute(Args &args, CommandReturnObject &result) override {
2905 Target *target = GetTarget();
2906 assert(target && "target guaranteed by eCommandRequiresTarget");
2907 const bool load = m_load_option.GetOptionValue().GetCurrentValue();
2908 const bool set_pc = m_pc_option.GetOptionValue().GetCurrentValue();
2909
2910 const size_t argc = args.GetArgumentCount();
2911 ModuleSpec module_spec;
2912 bool search_using_module_spec = false;
2913
2914 // Allow "load" option to work without --file or --uuid option.
2915 if (load) {
2916 if (!m_file_option.GetOptionValue().OptionWasSet() &&
2917 !m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2918 ModuleList &module_list = target->GetImages();
2919 if (module_list.GetSize() == 1) {
2920 search_using_module_spec = true;
2921 module_spec.GetFileSpec() =
2922 module_list.GetModuleAtIndex(0)->GetFileSpec();
2923 }
2924 }
2925 }
2926
2927 if (m_file_option.GetOptionValue().OptionWasSet()) {
2928 search_using_module_spec = true;
2929 const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
2930 const bool use_global_module_list = true;
2931 ModuleList module_list;
2932 const size_t num_matches = FindModulesByName(
2933 target, arg_cstr, module_list, use_global_module_list);
2934 if (num_matches == 1) {
2935 module_spec.GetFileSpec() =
2936 module_list.GetModuleAtIndex(0)->GetFileSpec();
2937 } else if (num_matches > 1) {
2938 search_using_module_spec = false;
2939 result.AppendErrorWithFormat("more than 1 module matched by name '%s'",
2940 arg_cstr);
2941 } else {
2942 search_using_module_spec = false;
2943 result.AppendErrorWithFormat("no object file for module '%s'",
2944 arg_cstr);
2945 }
2946 }
2947
2948 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2949 search_using_module_spec = true;
2950 module_spec.GetUUID() =
2951 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2952 }
2953
2954 if (search_using_module_spec) {
2955 ModuleList matching_modules;
2956 target->GetImages().FindModules(module_spec, matching_modules);
2957 const size_t num_matches = matching_modules.GetSize();
2958
2959 char path[PATH_MAX];
2960 if (num_matches == 1) {
2961 Module *module = matching_modules.GetModulePointerAtIndex(0);
2962 if (module) {
2963 ObjectFile *objfile = module->GetObjectFile();
2964 if (objfile) {
2965 SectionList *section_list = module->GetSectionList();
2966 if (section_list) {
2967 bool changed = false;
2968 if (argc == 0) {
2969 if (m_slide_option.GetOptionValue().OptionWasSet()) {
2970 const addr_t slide =
2971 m_slide_option.GetOptionValue().GetCurrentValue();
2972 const bool slide_is_offset = true;
2973 module->SetLoadAddress(*target, slide, slide_is_offset,
2974 changed);
2975 } else {
2976 result.AppendError("one or more section name + load "
2977 "address pair must be specified");
2978 return;
2979 }
2980 } else {
2981 if (m_slide_option.GetOptionValue().OptionWasSet()) {
2982 result.AppendError("The \"--slide <offset>\" option can't "
2983 "be used in conjunction with setting "
2984 "section load addresses.\n");
2985 return;
2986 }
2987
2988 for (size_t i = 0; i < argc; i += 2) {
2989 const char *sect_name = args.GetArgumentAtIndex(i);
2990 const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1);
2991 if (sect_name && load_addr_cstr) {
2992 ConstString const_sect_name(sect_name);
2993 addr_t load_addr;
2994 if (llvm::to_integer(load_addr_cstr, load_addr)) {
2995 SectionSP section_sp(
2996 section_list->FindSectionByName(const_sect_name));
2997 if (section_sp) {
2998 if (section_sp->IsThreadSpecific()) {
2999 result.AppendErrorWithFormat(
3000 "thread specific sections are not yet "
3001 "supported (section '%s')",
3002 sect_name);
3003 break;
3004 } else {
3005 if (target->SetSectionLoadAddress(section_sp,
3006 load_addr))
3007 changed = true;
3009 "section '{0}' loaded at {1:x}", sect_name,
3010 load_addr);
3011 }
3012 } else {
3013 result.AppendErrorWithFormat("no section found that "
3014 "matches the section "
3015 "name '%s'",
3016 sect_name);
3017 break;
3018 }
3019 } else {
3020 result.AppendErrorWithFormat(
3021 "invalid load address string '%s'", load_addr_cstr);
3022 break;
3023 }
3024 } else {
3025 if (sect_name)
3026 result.AppendError("section names must be followed by "
3027 "a load address.\n");
3028 else
3029 result.AppendError("one or more section name + load "
3030 "address pair must be specified.\n");
3031 break;
3032 }
3033 }
3034 }
3035
3036 if (changed) {
3037 target->ModulesDidLoad(matching_modules);
3038 Process *process = m_exe_ctx.GetProcessPtr();
3039 if (process)
3040 process->Flush();
3041 }
3042 if (load) {
3043 ProcessSP process = target->CalculateProcess();
3044 Address file_entry = objfile->GetEntryPointAddress();
3045 if (!process) {
3046 result.AppendError("No process");
3047 return;
3048 }
3049 if (set_pc && !file_entry.IsValid()) {
3050 result.AppendError("No entry address in object file");
3051 return;
3052 }
3053 std::vector<ObjectFile::LoadableData> loadables(
3054 objfile->GetLoadableData(*target));
3055 if (loadables.size() == 0) {
3056 result.AppendError("No loadable sections");
3057 return;
3058 }
3059 Status error = process->WriteObjectFile(std::move(loadables));
3060 if (error.Fail()) {
3061 result.AppendError(error.AsCString());
3062 return;
3063 }
3064 if (set_pc) {
3065 ThreadList &thread_list = process->GetThreadList();
3066 RegisterContextSP reg_context(
3067 thread_list.GetSelectedThread()->GetRegisterContext());
3068 addr_t file_entry_addr = file_entry.GetLoadAddress(target);
3069 if (!reg_context->SetPC(file_entry_addr)) {
3070 result.AppendErrorWithFormat("failed to set PC value to "
3071 "0x%" PRIx64,
3072 file_entry_addr);
3073 }
3074 }
3075 }
3076 } else {
3077 module->GetFileSpec().GetPath(path, sizeof(path));
3078 result.AppendErrorWithFormat("no sections in object file '%s'",
3079 path);
3080 }
3081 } else {
3082 module->GetFileSpec().GetPath(path, sizeof(path));
3083 result.AppendErrorWithFormat("no object file for module '%s'",
3084 path);
3085 }
3086 } else {
3087 FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
3088 if (module_spec_file) {
3089 module_spec_file->GetPath(path, sizeof(path));
3090 result.AppendErrorWithFormat("invalid module '%s'", path);
3091 } else
3092 result.AppendError("no module spec");
3093 }
3094 } else {
3095 std::string uuid_str;
3096
3097 if (module_spec.GetFileSpec())
3098 module_spec.GetFileSpec().GetPath(path, sizeof(path));
3099 else
3100 path[0] = '\0';
3101
3102 if (module_spec.GetUUIDPtr())
3103 uuid_str = module_spec.GetUUID().GetAsString();
3104 if (num_matches > 1) {
3105 result.AppendErrorWithFormat(
3106 "multiple modules match%s%s%s%s:", path[0] ? " file=" : "", path,
3107 !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
3108 for (size_t i = 0; i < num_matches; ++i) {
3109 if (matching_modules.GetModulePointerAtIndex(i)
3110 ->GetFileSpec()
3111 .GetPath(path, sizeof(path)))
3112 result.AppendMessageWithFormatv("{0}", path);
3113 }
3114 } else {
3115 result.AppendErrorWithFormat(
3116 "no modules were found that match%s%s%s%s",
3117 path[0] ? " file=" : "", path, !uuid_str.empty() ? " uuid=" : "",
3118 uuid_str.c_str());
3119 }
3120 }
3121 } else {
3122 result.AppendError("either the \"--file <module>\" or the \"--uuid "
3123 "<uuid>\" option must be specified.\n");
3124 }
3125 if (result.GetStatus() != eReturnStatusFailed)
3127 }
3128
3135};
3136
3137#pragma mark CommandObjectTargetModulesList
3138// List images with associated information
3139#define LLDB_OPTIONS_target_modules_list
3140#include "CommandOptions.inc"
3141
3143public:
3144 class CommandOptions : public Options {
3145 public:
3146 CommandOptions() = default;
3147
3148 ~CommandOptions() override = default;
3149
3150 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3151 ExecutionContext *execution_context) override {
3152 Status error;
3153
3154 const int short_option = m_getopt_table[option_idx].val;
3155 if (short_option == 'g') {
3157 } else if (short_option == 'a') {
3159 execution_context, option_arg, LLDB_INVALID_ADDRESS, &error);
3160 } else {
3161 unsigned long width = 0;
3162 option_arg.getAsInteger(0, width);
3163 m_format_array.push_back(std::make_pair(short_option, width));
3164 }
3165 return error;
3166 }
3167
3168 void OptionParsingStarting(ExecutionContext *execution_context) override {
3169 m_format_array.clear();
3172 }
3173
3174 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3175 return llvm::ArrayRef(g_target_modules_list_options);
3176 }
3177
3178 // Instance variables to hold the values for command options.
3179 typedef std::vector<std::pair<char, uint32_t>> FormatWidthCollection;
3183 };
3184
3187 interpreter, "target modules list",
3188 "List current executable and dependent shared library images.",
3189 nullptr, eCommandAllowsDummyTarget) {
3191 }
3192
3194
3195 Options *GetOptions() override { return &m_options; }
3196
3197protected:
3198 void DoExecute(Args &command, CommandReturnObject &result) override {
3199 Target *target = GetTarget();
3200 const bool use_global_module_list = m_options.m_use_global_module_list;
3201
3202 // Every code path other than the global module list needs a real target.
3203 if (!use_global_module_list && (!target || target->IsDummyTarget())) {
3205 return;
3206 }
3207
3208 // Define a local module list here to ensure it lives longer than any
3209 // "locker" object which might lock its contents below (through the
3210 // "module_list_ptr" variable).
3211 ModuleList module_list;
3212 // Dump all sections for all modules images
3213 Stream &strm = result.GetOutputStream();
3214
3215 if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) {
3216 Address module_address;
3217 if (module_address.SetLoadAddress(m_options.m_module_addr, target)) {
3218 ModuleSP module_sp(module_address.GetModule());
3219 if (module_sp) {
3220 PrintModule(*target, module_sp.get(), 0, strm);
3222 } else {
3223 result.AppendErrorWithFormat(
3224 "Couldn't find module matching address: 0x%" PRIx64,
3225 m_options.m_module_addr);
3226 }
3227 } else {
3228 result.AppendErrorWithFormat(
3229 "Couldn't find module containing address: 0x%" PRIx64,
3230 m_options.m_module_addr);
3231 }
3232 return;
3233 }
3234
3235 size_t num_modules = 0;
3236
3237 // This locker will be locked on the mutex in module_list_ptr if it is
3238 // non-nullptr. Otherwise it will lock the
3239 // AllocationModuleCollectionMutex when accessing the global module list
3240 // directly.
3241 std::unique_lock<std::recursive_mutex> guard(
3243
3244 const ModuleList *module_list_ptr = nullptr;
3245 const size_t argc = command.GetArgumentCount();
3246 if (argc == 0) {
3247 if (use_global_module_list) {
3248 guard.lock();
3249 num_modules = Module::GetNumberAllocatedModules();
3250 } else {
3251 module_list_ptr = &target->GetImages();
3252 }
3253 } else {
3254 for (const Args::ArgEntry &arg : command) {
3255 // Dump specified images (by basename or fullpath)
3256 const size_t num_matches = FindModulesByName(
3257 target, arg.c_str(), module_list, use_global_module_list);
3258 if (num_matches == 0) {
3259 if (argc == 1) {
3260 result.AppendErrorWithFormat("no modules found that match '%s'",
3261 arg.c_str());
3262 return;
3263 }
3264 }
3265 }
3266
3267 module_list_ptr = &module_list;
3268 }
3269
3270 std::unique_lock<std::recursive_mutex> lock;
3271 if (module_list_ptr != nullptr) {
3272 lock =
3273 std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex());
3274
3275 num_modules = module_list_ptr->GetSize();
3276 }
3277
3278 if (num_modules > 0) {
3279 for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
3280 ModuleSP module_sp;
3281 Module *module;
3282 if (module_list_ptr) {
3283 module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
3284 module = module_sp.get();
3285 } else {
3286 module = Module::GetAllocatedModuleAtIndex(image_idx);
3287 module_sp = module->shared_from_this();
3288 }
3289
3290 const size_t indent = strm.Printf("[%3u] ", image_idx);
3291 PrintModule(*target, module, indent, strm);
3292 }
3294 } else {
3295 if (argc) {
3296 if (use_global_module_list)
3297 result.AppendError(
3298 "the global module list has no matching modules");
3299 else
3300 result.AppendError("the target has no matching modules");
3301 } else {
3302 if (use_global_module_list)
3303 result.AppendError("the global module list is empty");
3304 else
3305 result.AppendError(
3306 "the target has no associated executable images");
3307 }
3308 return;
3309 }
3310 }
3311
3312 void PrintModule(Target &target, Module *module, int indent, Stream &strm) {
3313 if (module == nullptr) {
3314 strm.PutCString("Null module");
3315 return;
3316 }
3317
3318 bool dump_object_name = false;
3319 if (m_options.m_format_array.empty()) {
3320 m_options.m_format_array.push_back(std::make_pair('u', 0));
3321 m_options.m_format_array.push_back(std::make_pair('h', 0));
3322 m_options.m_format_array.push_back(std::make_pair('f', 0));
3323 m_options.m_format_array.push_back(std::make_pair('S', 0));
3324 }
3325 const size_t num_entries = m_options.m_format_array.size();
3326 bool print_space = false;
3327 for (size_t i = 0; i < num_entries; ++i) {
3328 if (print_space)
3329 strm.PutChar(' ');
3330 print_space = true;
3331 const char format_char = m_options.m_format_array[i].first;
3332 uint32_t width = m_options.m_format_array[i].second;
3333 switch (format_char) {
3334 case 'A':
3335 DumpModuleArchitecture(strm, module, false, width);
3336 break;
3337
3338 case 't':
3339 DumpModuleArchitecture(strm, module, true, width);
3340 break;
3341
3342 case 'f':
3343 DumpFullpath(strm, &module->GetFileSpec(), width);
3344 dump_object_name = true;
3345 break;
3346
3347 case 'd':
3348 DumpDirectory(strm, &module->GetFileSpec(), width);
3349 break;
3350
3351 case 'b':
3352 DumpBasename(strm, &module->GetFileSpec(), width);
3353 dump_object_name = true;
3354 break;
3355
3356 case 'h':
3357 case 'o':
3358 // Image header address
3359 {
3360 uint32_t addr_nibble_width =
3361 target.GetArchitecture().GetAddressByteSize() * 2;
3362
3363 ObjectFile *objfile = module->GetObjectFile();
3364 if (objfile) {
3365 Address base_addr(objfile->GetBaseAddress());
3366 if (base_addr.IsValid()) {
3367 if (target.HasLoadedSections()) {
3368 lldb::addr_t load_addr = base_addr.GetLoadAddress(&target);
3369 if (load_addr == LLDB_INVALID_ADDRESS) {
3370 base_addr.Dump(&strm, &target,
3373 } else {
3374 if (format_char == 'o') {
3375 // Show the offset of slide for the image
3376 strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3377 addr_nibble_width,
3378 load_addr - base_addr.GetFileAddress());
3379 } else {
3380 // Show the load address of the image
3381 strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3382 addr_nibble_width, load_addr);
3383 }
3384 }
3385 break;
3386 }
3387 // The address was valid, but the image isn't loaded, output the
3388 // address in an appropriate format
3389 base_addr.Dump(&strm, &target, Address::DumpStyleFileAddress);
3390 break;
3391 }
3392 }
3393 strm.Printf("%*s", addr_nibble_width + 2, "");
3394 }
3395 break;
3396
3397 case 'r': {
3398 size_t ref_count = 0;
3399 char in_shared_cache = 'Y';
3400
3401 ModuleSP module_sp(module->shared_from_this());
3402 if (!ModuleList::ModuleIsInCache(module))
3403 in_shared_cache = 'N';
3404 if (module_sp) {
3405 // Take one away to make sure we don't count our local "module_sp"
3406 ref_count = module_sp.use_count() - 1;
3407 }
3408 if (width)
3409 strm.Printf("{%c %*" PRIu64 "}", in_shared_cache, width, (uint64_t)ref_count);
3410 else
3411 strm.Printf("{%c %" PRIu64 "}", in_shared_cache, (uint64_t)ref_count);
3412 } break;
3413
3414 case 's':
3415 case 'S': {
3416 if (const SymbolFile *symbol_file = module->GetSymbolFile()) {
3417 const FileSpec symfile_spec =
3418 symbol_file->GetObjectFile()->GetFileSpec();
3419 if (format_char == 'S') {
3420 // Dump symbol file only if different from module file
3421 if (!symfile_spec || symfile_spec == module->GetFileSpec()) {
3422 print_space = false;
3423 break;
3424 }
3425 // Add a newline and indent past the index
3426 strm.Printf("\n%*s", indent, "");
3427 }
3428 DumpFullpath(strm, &symfile_spec, width);
3429 dump_object_name = true;
3430 break;
3431 }
3432 strm.Printf("%.*s", width, "<NONE>");
3433 } break;
3434
3435 case 'm':
3436 strm.Format("{0:%c}", llvm::fmt_align(module->GetModificationTime(),
3437 llvm::AlignStyle::Left, width));
3438 break;
3439
3440 case 'p':
3441 strm.Printf("%p", static_cast<void *>(module));
3442 break;
3443
3444 case 'u':
3445 DumpModuleUUID(strm, module);
3446 break;
3447
3448 default:
3449 break;
3450 }
3451 }
3452 if (dump_object_name) {
3453 const char *object_name = module->GetObjectName().GetCString();
3454 if (object_name)
3455 strm.Printf("(%s)", object_name);
3456 std::optional<addr_t> memory_addr = module->GetMemoryModuleAddress();
3457 if (memory_addr.has_value())
3458 strm.Printf("(0x%" PRIx64 ")", memory_addr.value());
3459 }
3460 strm.EOL();
3461 }
3462
3464};
3465
3466#pragma mark CommandObjectTargetModulesShowUnwind
3467
3468// Lookup unwind information in images
3469#define LLDB_OPTIONS_target_modules_show_unwind
3470#include "CommandOptions.inc"
3471
3473public:
3474 enum {
3481 };
3482
3483 class CommandOptions : public Options {
3484 public:
3485 CommandOptions() = default;
3486
3487 ~CommandOptions() override = default;
3488
3489 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3490 ExecutionContext *execution_context) override {
3491 Status error;
3492
3493 const int short_option = m_getopt_table[option_idx].val;
3494
3495 switch (short_option) {
3496 case 'a': {
3497 m_str = std::string(option_arg);
3499 m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
3503 "invalid address string '%s'", option_arg.str().c_str());
3504 break;
3505 }
3506
3507 case 'n':
3508 m_str = std::string(option_arg);
3510 break;
3511
3512 case 'c':
3513 bool value, success;
3514 value = OptionArgParser::ToBoolean(option_arg, false, &success);
3515 if (success) {
3516 m_cached = value;
3517 } else {
3519 "invalid boolean value '{}' passed for -c option", option_arg);
3520 }
3521 break;
3522
3523 default:
3524 llvm_unreachable("Unimplemented option");
3525 }
3526
3527 return error;
3528 }
3529
3530 void OptionParsingStarting(ExecutionContext *execution_context) override {
3532 m_str.clear();
3534 m_cached = false;
3535 }
3536
3537 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3538 return llvm::ArrayRef(g_target_modules_show_unwind_options);
3539 }
3540
3541 // Instance variables to hold the values for command options.
3542
3543 int m_type = eLookupTypeInvalid; // Should be a eLookupTypeXXX enum after
3544 // parsing options
3545 std::string m_str; // Holds name lookup
3546 lldb::addr_t m_addr = LLDB_INVALID_ADDRESS; // Holds the address to lookup
3547 bool m_cached = true;
3548 };
3549
3552 interpreter, "target modules show-unwind",
3553 "Show synthesized unwind instructions for a function.", nullptr,
3554 eCommandRequiresTarget | eCommandRequiresProcess |
3555 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {}
3556
3558
3559 Options *GetOptions() override { return &m_options; }
3560
3561protected:
3562 void DoExecute(Args &command, CommandReturnObject &result) override {
3563 Target *target = m_exe_ctx.GetTargetPtr();
3564 Process *process = m_exe_ctx.GetProcessPtr();
3565 ABI *abi = nullptr;
3566 if (process)
3567 abi = process->GetABI().get();
3568
3569 if (process == nullptr) {
3570 result.AppendError(
3571 "You must have a process running to use this command.");
3572 return;
3573 }
3574
3575 ThreadList threads(process->GetThreadList());
3576 if (threads.GetSize() == 0) {
3577 result.AppendError("the process must be paused to use this command");
3578 return;
3579 }
3580
3581 ThreadSP thread(threads.GetThreadAtIndex(0));
3582 if (!thread) {
3583 result.AppendError("the process must be paused to use this command");
3584 return;
3585 }
3586
3587 SymbolContextList sc_list;
3588
3589 if (m_options.m_type == eLookupTypeFunctionOrSymbol) {
3590 ConstString function_name(m_options.m_str);
3591 ModuleFunctionSearchOptions function_options;
3592 function_options.include_symbols = true;
3593 function_options.include_inlines = false;
3594 target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto,
3595 function_options, sc_list);
3596 } else if (m_options.m_type == eLookupTypeAddress && target) {
3597 Address addr;
3598 if (target->ResolveLoadAddress(m_options.m_addr, addr)) {
3599 SymbolContext sc;
3600 ModuleSP module_sp(addr.GetModule());
3601 module_sp->ResolveSymbolContextForAddress(addr,
3602 eSymbolContextEverything, sc);
3603 if (sc.function || sc.symbol) {
3604 sc_list.Append(sc);
3605 }
3606 }
3607 } else {
3608 result.AppendError(
3609 "address-expression or function name option must be specified.");
3610 return;
3611 }
3612
3613 if (sc_list.GetSize() == 0) {
3614 result.AppendErrorWithFormat("no unwind data found that matches '%s'",
3615 m_options.m_str.c_str());
3616 return;
3617 }
3618
3619 for (const SymbolContext &sc : sc_list) {
3620 if (sc.symbol == nullptr && sc.function == nullptr)
3621 continue;
3622 if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr)
3623 continue;
3624 Address addr = sc.GetFunctionOrSymbolAddress();
3625 if (!addr.IsValid())
3626 continue;
3627 ConstString funcname(sc.GetFunctionName());
3628 if (funcname.IsEmpty())
3629 continue;
3630 addr_t start_addr = addr.GetLoadAddress(target);
3631 if (abi)
3632 start_addr = abi->FixCodeAddress(start_addr);
3633
3634 UnwindTable &uw_table = sc.module_sp->GetUnwindTable();
3635 FuncUnwindersSP func_unwinders_sp =
3636 m_options.m_cached
3637 ? uw_table.GetFuncUnwindersContainingAddress(Address(start_addr),
3638 sc)
3640 Address(start_addr), sc);
3641 if (!func_unwinders_sp)
3642 continue;
3643
3644 result.GetOutputStream().Format(
3645 "UNWIND PLANS for {0}`{1} (start addr {2:x})\n",
3646 sc.module_sp->GetPlatformFileSpec().GetFilename(), funcname,
3647 start_addr);
3648
3649 Args args;
3651 size_t count = args.GetArgumentCount();
3652 for (size_t i = 0; i < count; i++) {
3653 const char *trap_func_name = args.GetArgumentAtIndex(i);
3654 if (strcmp(funcname.GetCString(), trap_func_name) == 0)
3655 result.GetOutputStream().Printf(
3656 "This function is "
3657 "treated as a trap handler function via user setting.\n");
3658 }
3659 PlatformSP platform_sp(target->GetPlatform());
3660 if (platform_sp) {
3661 const std::vector<ConstString> trap_handler_names(
3662 platform_sp->GetTrapHandlerSymbolNames());
3663 for (ConstString trap_name : trap_handler_names) {
3664 if (trap_name == funcname) {
3665 result.GetOutputStream().Printf(
3666 "This function's "
3667 "name is listed by the platform as a trap handler.\n");
3668 }
3669 }
3670 }
3671
3672 result.GetOutputStream().Printf("\n");
3673
3674 if (std::shared_ptr<const UnwindPlan> plan_sp =
3675 func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread)) {
3676 result.GetOutputStream().Format(
3677 "Asynchronous (not restricted to call-sites) UnwindPlan is '{0}'\n",
3678 plan_sp->GetSourceName());
3679 }
3680 if (std::shared_ptr<const UnwindPlan> plan_sp =
3681 func_unwinders_sp->GetUnwindPlanAtCallSite(*target, *thread)) {
3682 result.GetOutputStream().Format(
3683 "Synchronous (restricted to call-sites) UnwindPlan is '{0}'\n",
3684 plan_sp->GetSourceName());
3685 }
3686 if (std::shared_ptr<const UnwindPlan> plan_sp =
3687 func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread)) {
3688 result.GetOutputStream().Format("Fast UnwindPlan is '{0}'\n",
3689 plan_sp->GetSourceName());
3690 }
3691
3692 result.GetOutputStream().Printf("\n");
3693
3694 if (std::shared_ptr<const UnwindPlan> plan_sp =
3695 func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread)) {
3696 result.GetOutputStream().Printf(
3697 "Assembly language inspection UnwindPlan:\n");
3698 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3700 result.GetOutputStream().Printf("\n");
3701 }
3702
3703 if (std::shared_ptr<const UnwindPlan> plan_sp =
3704 func_unwinders_sp->GetObjectFileUnwindPlan(*target)) {
3705 result.GetOutputStream().Printf("object file UnwindPlan:\n");
3706 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3708 result.GetOutputStream().Printf("\n");
3709 }
3710
3711 if (std::shared_ptr<const UnwindPlan> plan_sp =
3712 func_unwinders_sp->GetObjectFileAugmentedUnwindPlan(*target,
3713 *thread)) {
3714 result.GetOutputStream().Printf("object file augmented UnwindPlan:\n");
3715 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3717 result.GetOutputStream().Printf("\n");
3718 }
3719
3720 if (std::shared_ptr<const UnwindPlan> plan_sp =
3721 func_unwinders_sp->GetEHFrameUnwindPlan(*target)) {
3722 result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
3723 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3725 result.GetOutputStream().Printf("\n");
3726 }
3727
3728 if (std::shared_ptr<const UnwindPlan> plan_sp =
3729 func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target,
3730 *thread)) {
3731 result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
3732 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3734 result.GetOutputStream().Printf("\n");
3735 }
3736
3737 if (std::shared_ptr<const UnwindPlan> plan_sp =
3738 func_unwinders_sp->GetDebugFrameUnwindPlan(*target)) {
3739 result.GetOutputStream().Printf("debug_frame UnwindPlan:\n");
3740 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3742 result.GetOutputStream().Printf("\n");
3743 }
3744
3745 if (std::shared_ptr<const UnwindPlan> plan_sp =
3746 func_unwinders_sp->GetDebugFrameAugmentedUnwindPlan(*target,
3747 *thread)) {
3748 result.GetOutputStream().Printf("debug_frame augmented UnwindPlan:\n");
3749 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3751 result.GetOutputStream().Printf("\n");
3752 }
3753
3754 if (std::shared_ptr<const UnwindPlan> plan_sp =
3755 func_unwinders_sp->GetArmUnwindUnwindPlan(*target)) {
3756 result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
3757 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3759 result.GetOutputStream().Printf("\n");
3760 }
3761
3762 if (std::shared_ptr<const UnwindPlan> plan_sp =
3763 func_unwinders_sp->GetSymbolFileUnwindPlan(*thread)) {
3764 result.GetOutputStream().Printf("Symbol file UnwindPlan:\n");
3765 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3767 result.GetOutputStream().Printf("\n");
3768 }
3769
3770 if (std::shared_ptr<const UnwindPlan> plan_sp =
3771 func_unwinders_sp->GetCompactUnwindUnwindPlan(*target)) {
3772 result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
3773 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3775 result.GetOutputStream().Printf("\n");
3776 }
3777
3778 if (std::shared_ptr<const UnwindPlan> plan_sp =
3779 func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread)) {
3780 result.GetOutputStream().Printf("Fast UnwindPlan:\n");
3781 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3783 result.GetOutputStream().Printf("\n");
3784 }
3785
3786 ABISP abi_sp = process->GetABI();
3787 if (abi_sp) {
3788 if (UnwindPlanSP plan_sp = abi_sp->CreateDefaultUnwindPlan()) {
3789 assert(((!plan_sp || plan_sp->GetRowCount() == 0 ||
3790 plan_sp->GetRowAtIndex(0)
3791 ->GetUnspecifiedRegistersAreUndefined())) &&
3792 "Default UnwindPlan must set "
3793 "UnspecifiedRegistersAreUndefined to true");
3794 result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
3795 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3797 result.GetOutputStream().Printf("\n");
3798 }
3799
3800 if (UnwindPlanSP plan_sp = abi_sp->CreateFunctionEntryUnwindPlan()) {
3801 result.GetOutputStream().Printf(
3802 "Arch default at entry point UnwindPlan:\n");
3803 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3805 result.GetOutputStream().Printf("\n");
3806 }
3807 }
3808
3809 result.GetOutputStream().Printf("\n");
3810 }
3812 }
3813
3815};
3816
3817// Lookup information in images
3818#define LLDB_OPTIONS_target_modules_lookup
3819#include "CommandOptions.inc"
3820
3822public:
3823 enum {
3827 eLookupTypeFileLine, // Line is optional
3832 };
3833
3834 class CommandOptions : public Options {
3835 public:
3837
3838 ~CommandOptions() override = default;
3839
3840 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3841 ExecutionContext *execution_context) override {
3842 Status error;
3843
3844 const int short_option = m_getopt_table[option_idx].val;
3845
3846 switch (short_option) {
3847 case 'a': {
3849 m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
3851 } break;
3852
3853 case 'o':
3854 if (option_arg.getAsInteger(0, m_offset))
3856 "invalid offset string '%s'", option_arg.str().c_str());
3857 break;
3858
3859 case 's':
3860 m_str = std::string(option_arg);
3862 break;
3863
3864 case 'f':
3865 m_file.SetFile(option_arg, FileSpec::Style::native);
3867 break;
3868
3869 case 'i':
3870 m_include_inlines = false;
3871 break;
3872
3873 case 'l':
3874 if (option_arg.getAsInteger(0, m_line_number))
3876 "invalid line number string '%s'", option_arg.str().c_str());
3877 else if (m_line_number == 0)
3878 error = Status::FromErrorString("zero is an invalid line number");
3880 break;
3881
3882 case 'F':
3883 m_str = std::string(option_arg);
3885 break;
3886
3887 case 'n':
3888 m_str = std::string(option_arg);
3890 break;
3891
3892 case 't':
3893 m_str = std::string(option_arg);
3895 break;
3896
3897 case 'v':
3898 m_verbose = true;
3899 break;
3900
3901 case 'A':
3902 m_print_all = true;
3903 break;
3904
3905 case 'r':
3906 m_use_regex = true;
3907 break;
3908
3909 case '\x01':
3910 m_all_ranges = true;
3911 break;
3912 default:
3913 llvm_unreachable("Unimplemented option");
3914 }
3915
3916 return error;
3917 }
3918
3919 void OptionParsingStarting(ExecutionContext *execution_context) override {
3921 m_str.clear();
3922 m_file.Clear();
3924 m_offset = 0;
3925 m_line_number = 0;
3926 m_use_regex = false;
3927 m_include_inlines = true;
3928 m_all_ranges = false;
3929 m_verbose = false;
3930 m_print_all = false;
3931 }
3932
3933 Status OptionParsingFinished(ExecutionContext *execution_context) override {
3934 Status status;
3935 if (m_all_ranges && !m_verbose) {
3936 status =
3937 Status::FromErrorString("--show-variable-ranges must be used in "
3938 "conjunction with --verbose.");
3939 }
3940 return status;
3941 }
3942
3943 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3944 return llvm::ArrayRef(g_target_modules_lookup_options);
3945 }
3946
3947 int m_type; // Should be a eLookupTypeXXX enum after parsing options
3948 std::string m_str; // Holds name lookup
3949 FileSpec m_file; // Files for file lookups
3950 lldb::addr_t m_addr; // Holds the address to lookup
3952 m_offset; // Subtract this offset from m_addr before doing lookups.
3953 uint32_t m_line_number; // Line number for file+line lookups
3954 bool m_use_regex; // Name lookups in m_str are regular expressions.
3955 bool m_include_inlines; // Check for inline entries when looking up by
3956 // file/line.
3957 bool m_all_ranges; // Print all ranges or single range.
3958 bool m_verbose; // Enable verbose lookup info
3959 bool m_print_all; // Print all matches, even in cases where there's a best
3960 // match.
3961 };
3962
3964 : CommandObjectParsed(interpreter, "target modules lookup",
3965 "Look up information within executable and "
3966 "dependent shared library images.",
3967 nullptr, eCommandRequiresTarget) {
3969 }
3970
3972
3973 Options *GetOptions() override { return &m_options; }
3974
3976 bool &syntax_error) {
3977 switch (m_options.m_type) {
3978 case eLookupTypeAddress:
3982 case eLookupTypeSymbol:
3983 default:
3984 return false;
3985 case eLookupTypeType:
3986 break;
3987 }
3988
3989 StackFrameSP frame = m_exe_ctx.GetFrameSP();
3990
3991 if (!frame)
3992 return false;
3993
3994 const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
3995
3996 if (!sym_ctx.module_sp)
3997 return false;
3998
3999 switch (m_options.m_type) {
4000 default:
4001 return false;
4002 case eLookupTypeType:
4003 if (!m_options.m_str.empty()) {
4005 *sym_ctx.module_sp, m_options.m_str.c_str(),
4006 m_options.m_use_regex)) {
4008 return true;
4009 }
4010 }
4011 break;
4012 }
4013
4014 return false;
4015 }
4016
4017 bool LookupInModule(CommandInterpreter &interpreter, Module *module,
4018 CommandReturnObject &result, bool &syntax_error) {
4019 switch (m_options.m_type) {
4020 case eLookupTypeAddress:
4021 if (m_options.m_addr != LLDB_INVALID_ADDRESS) {
4023 m_interpreter, result.GetOutputStream(), module,
4024 eSymbolContextEverything |
4025 (m_options.m_verbose
4026 ? static_cast<int>(eSymbolContextVariable)
4027 : 0),
4028 m_options.m_addr, m_options.m_offset, m_options.m_verbose,
4029 m_options.m_all_ranges)) {
4031 return true;
4032 }
4033 }
4034 break;
4035
4036 case eLookupTypeSymbol:
4037 if (!m_options.m_str.empty()) {
4039 module, m_options.m_str.c_str(),
4040 m_options.m_use_regex, m_options.m_verbose,
4041 m_options.m_all_ranges)) {
4043 return true;
4044 }
4045 }
4046 break;
4047
4049 if (m_options.m_file) {
4051 m_interpreter, result.GetOutputStream(), module,
4052 m_options.m_file, m_options.m_line_number,
4053 m_options.m_include_inlines, m_options.m_verbose,
4054 m_options.m_all_ranges)) {
4056 return true;
4057 }
4058 }
4059 break;
4060
4063 if (!m_options.m_str.empty()) {
4064 ModuleFunctionSearchOptions function_options;
4065 function_options.include_symbols =
4067 function_options.include_inlines = m_options.m_include_inlines;
4068
4070 module, m_options.m_str.c_str(),
4071 m_options.m_use_regex, function_options,
4072 m_options.m_verbose,
4073 m_options.m_all_ranges)) {
4075 return true;
4076 }
4077 }
4078 break;
4079
4080 case eLookupTypeType:
4081 if (!m_options.m_str.empty()) {
4083 GetTarget(), m_interpreter, result.GetOutputStream(), module,
4084 m_options.m_str.c_str(), m_options.m_use_regex)) {
4086 return true;
4087 }
4088 }
4089 break;
4090
4091 default:
4092 m_options.GenerateOptionUsage(
4093 result.GetErrorStream(), *this,
4094 GetCommandInterpreter().GetDebugger().GetTerminalWidth(),
4095 GetCommandInterpreter().GetDebugger().GetUseColor());
4096 syntax_error = true;
4097 break;
4098 }
4099
4101 return false;
4102 }
4103
4104protected:
4105 void DoExecute(Args &command, CommandReturnObject &result) override {
4106 Target *target = GetTarget();
4107 assert(target && "target guaranteed by eCommandRequiresTarget");
4108 bool syntax_error = false;
4109 uint32_t i;
4110 uint32_t num_successful_lookups = 0;
4111 // Dump all sections for all modules images
4112
4113 if (command.GetArgumentCount() == 0) {
4114 // Where it is possible to look in the current symbol context first,
4115 // try that. If this search was successful and --all was not passed,
4116 // don't print anything else.
4117 if (LookupHere(m_interpreter, result, syntax_error)) {
4118 result.GetOutputStream().EOL();
4119 num_successful_lookups++;
4120 if (!m_options.m_print_all) {
4122 return;
4123 }
4124 }
4125
4126 // Dump all sections for all other modules
4127
4128 const ModuleList &target_modules = target->GetImages();
4129 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
4130 if (target_modules.GetSize() == 0) {
4131 result.AppendError("the target has no associated executable images");
4132 return;
4133 }
4134
4135 for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
4136 if (LookupInModule(m_interpreter, module_sp.get(), result,
4137 syntax_error)) {
4138 result.GetOutputStream().EOL();
4139 num_successful_lookups++;
4140 }
4141 }
4142 } else {
4143 // Dump specified images (by basename or fullpath)
4144 const char *arg_cstr;
4145 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr &&
4146 !syntax_error;
4147 ++i) {
4148 ModuleList module_list;
4149 const size_t num_matches =
4150 FindModulesByName(target, arg_cstr, module_list, false);
4151 if (num_matches > 0) {
4152 for (size_t j = 0; j < num_matches; ++j) {
4153 Module *module = module_list.GetModulePointerAtIndex(j);
4154 if (module) {
4155 if (LookupInModule(m_interpreter, module, result, syntax_error)) {
4156 result.GetOutputStream().EOL();
4157 num_successful_lookups++;
4158 }
4159 }
4160 }
4161 } else
4163 "unable to find an image that matches '{0}'", arg_cstr);
4164 }
4165 }
4166
4167 if (num_successful_lookups > 0)
4169 else
4171 }
4172
4174};
4175
4176#pragma mark CommandObjectMultiwordImageSearchPaths
4177
4178// CommandObjectMultiwordImageSearchPaths
4179
4181 : public CommandObjectMultiword {
4182public:
4185 interpreter, "target modules search-paths",
4186 "Commands for managing module search paths for a target.",
4187 "target modules search-paths <subcommand> [<subcommand-options>]") {
4189 "add", CommandObjectSP(
4193 interpreter)));
4195 "insert",
4200 interpreter)));
4203 interpreter)));
4204 }
4205
4207};
4208
4209#pragma mark CommandObjectTargetModules
4210
4211// CommandObjectTargetModules
4212
4214public:
4215 // Constructors and Destructors
4217 : CommandObjectMultiword(interpreter, "target modules",
4218 "Commands for accessing information for one or "
4219 "more target modules.",
4220 "target modules <sub-command> ...") {
4222 "add", CommandObjectSP(new CommandObjectTargetModulesAdd(interpreter)));
4224 interpreter)));
4226 interpreter)));
4228 interpreter)));
4230 "lookup",
4233 "search-paths",
4237 "show-unwind",
4239 }
4240
4241 ~CommandObjectTargetModules() override = default;
4242
4243private:
4244 // For CommandObjectTargetModules only
4248};
4249
4251public:
4254 interpreter, "target symbols add",
4255 "Add a debug symbol file to one of the target's current modules by "
4256 "specifying a path to a debug symbols file or by using the options "
4257 "to specify a module.",
4258 "target symbols add <cmd-options> [<symfile>]",
4259 eCommandRequiresTarget),
4261 LLDB_OPT_SET_1, false, "shlib", 's', lldb::eModuleCompletion,
4263 "Locate the debug symbols for the shared library specified by "
4264 "name."),
4266 LLDB_OPT_SET_2, false, "frame", 'F',
4267 "Locate the debug symbols for the currently selected frame.", false,
4268 true),
4269 m_current_stack_option(LLDB_OPT_SET_2, false, "stack", 'S',
4270 "Locate the debug symbols for every frame in "
4271 "the current call stack.",
4272 false, true)
4273
4274 {
4282 m_option_group.Finalize();
4284 }
4285
4287
4288 Options *GetOptions() override { return &m_option_group; }
4289
4290protected:
4291 bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush,
4292 CommandReturnObject &result) {
4293 const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
4294 if (!symbol_fspec) {
4295 result.AppendError(
4296 "one or more executable image paths must be specified");
4297 return false;
4298 }
4299
4300 char symfile_path[PATH_MAX];
4301 symbol_fspec.GetPath(symfile_path, sizeof(symfile_path));
4302
4303 if (!module_spec.GetUUID().IsValid()) {
4304 if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
4305 module_spec.GetFileSpec().SetFilename(symbol_fspec.GetFilename());
4306 }
4307
4308 // Now module_spec represents a symbol file for a module that might exist
4309 // in the current target. Let's find possible matches.
4310 ModuleList matching_modules;
4311
4312 // First extract all module specs from the symbol file
4313 lldb_private::ModuleSpecList symfile_module_specs =
4315 0);
4316 if (symfile_module_specs.GetSize() > 0) {
4317 // Now extract the module spec that matches the target architecture
4318 ModuleSpec target_arch_module_spec;
4319 ModuleSpec symfile_module_spec;
4320 target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
4321 if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec,
4322 symfile_module_spec)) {
4323 if (symfile_module_spec.GetUUID().IsValid()) {
4324 // It has a UUID, look for this UUID in the target modules
4325 ModuleSpec symfile_uuid_module_spec;
4326 symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
4327 target->GetImages().FindModules(symfile_uuid_module_spec,
4328 matching_modules);
4329 }
4330 }
4331
4332 if (matching_modules.IsEmpty()) {
4333 // No matches yet. Iterate through the module specs to find a UUID
4334 // value that we can match up to an image in our target.
4335 const size_t num_symfile_module_specs = symfile_module_specs.GetSize();
4336 for (size_t i = 0;
4337 i < num_symfile_module_specs && matching_modules.IsEmpty(); ++i) {
4338 if (symfile_module_specs.GetModuleSpecAtIndex(
4339 i, symfile_module_spec)) {
4340 if (symfile_module_spec.GetUUID().IsValid()) {
4341 // It has a UUID. Look for this UUID in the target modules.
4342 ModuleSpec symfile_uuid_module_spec;
4343 symfile_uuid_module_spec.GetUUID() =
4344 symfile_module_spec.GetUUID();
4345 target->GetImages().FindModules(symfile_uuid_module_spec,
4346 matching_modules);
4347 }
4348 }
4349 }
4350 }
4351 }
4352
4353 // Just try to match up the file by basename if we have no matches at
4354 // this point. For example, module foo might have symbols in foo.debug.
4355 if (matching_modules.IsEmpty())
4356 target->GetImages().FindModules(module_spec, matching_modules);
4357
4358 while (matching_modules.IsEmpty()) {
4359 ConstString filename_no_extension(
4361 // Empty string returned, let's bail
4362 if (!filename_no_extension)
4363 break;
4364
4365 // Check if there was no extension to strip and the basename is the same
4366 if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
4367 break;
4368
4369 // Replace basename with one fewer extension
4370 module_spec.GetFileSpec().SetFilename(filename_no_extension);
4371 target->GetImages().FindModules(module_spec, matching_modules);
4372 }
4373
4374 if (matching_modules.GetSize() > 1) {
4375 result.AppendErrorWithFormat("multiple modules match symbol file '%s', "
4376 "use the --uuid option to resolve the "
4377 "ambiguity",
4378 symfile_path);
4379 return false;
4380 }
4381
4382 if (matching_modules.GetSize() == 1) {
4383 ModuleSP module_sp(matching_modules.GetModuleAtIndex(0));
4384
4385 // The module has not yet created its symbol vendor, we can just give
4386 // the existing target module the symfile path to use for when it
4387 // decides to create it!
4388 module_sp->SetSymbolFileFileSpec(symbol_fspec);
4389
4390 SymbolFile *symbol_file =
4391 module_sp->GetSymbolFile(true, &result.GetErrorStream());
4392 if (symbol_file) {
4393 ObjectFile *object_file = symbol_file->GetObjectFile();
4394 if (object_file && object_file->GetFileSpec() == symbol_fspec) {
4395 // Provide feedback that the symfile has been successfully added.
4396 const FileSpec &module_fs = module_sp->GetFileSpec();
4398 "symbol file '{0}' has been added to '{1}'", symfile_path,
4399 module_fs.GetPath().c_str());
4400
4401 // Let clients know something changed in the module if it is
4402 // currently loaded
4403 ModuleList module_list;
4404 module_list.Append(module_sp);
4405 target->SymbolsDidLoad(module_list);
4406
4407 // Make sure we load any scripting resources that may be embedded
4408 // in the debug info files in case the platform supports that.
4409 std::list<Status> errors;
4410 module_list.LoadScriptingResourcesInTarget(target, errors);
4411 for (const auto &err : errors)
4412 result.AppendWarning(err.AsCString());
4413
4414 flush = true;
4416 return true;
4417 }
4418 }
4419 // Clear the symbol file spec if anything went wrong
4420 module_sp->SetSymbolFileFileSpec(FileSpec());
4421 }
4422
4423 StreamString ss_symfile_uuid;
4424 if (module_spec.GetUUID().IsValid()) {
4425 ss_symfile_uuid << " (";
4426 module_spec.GetUUID().Dump(ss_symfile_uuid);
4427 ss_symfile_uuid << ')';
4428 }
4429 result.AppendErrorWithFormat(
4430 "symbol file '%s'%s does not match any existing module%s", symfile_path,
4431 ss_symfile_uuid.GetData(),
4432 !llvm::sys::fs::is_regular_file(symbol_fspec.GetPath())
4433 ? "\n please specify the full path to the symbol file"
4434 : "");
4435 return false;
4436 }
4437
4439 CommandReturnObject &result, bool &flush) {
4440 Status error;
4442 if (module_spec.GetSymbolFileSpec())
4443 return AddModuleSymbols(m_exe_ctx.GetTargetPtr(), module_spec, flush,
4444 result);
4445 } else {
4446 result.SetError(std::move(error));
4447 }
4448 return false;
4449 }
4450
4451 bool AddSymbolsForUUID(CommandReturnObject &result, bool &flush) {
4452 assert(m_uuid_option_group.GetOptionValue().OptionWasSet());
4453
4454 ModuleSpec module_spec;
4455 module_spec.GetUUID() =
4456 m_uuid_option_group.GetOptionValue().GetCurrentValue();
4457
4458 if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) {
4459 StreamString error_strm;
4460 error_strm.PutCString("unable to find debug symbols for UUID ");
4461 module_spec.GetUUID().Dump(error_strm);
4462 result.AppendError(error_strm.GetString());
4463 return false;
4464 }
4465
4466 return true;
4467 }
4468
4469 bool AddSymbolsForFile(CommandReturnObject &result, bool &flush) {
4470 assert(m_file_option.GetOptionValue().OptionWasSet());
4471
4472 ModuleSpec module_spec;
4473 module_spec.GetFileSpec() =
4474 m_file_option.GetOptionValue().GetCurrentValue();
4475
4476 Target *target = m_exe_ctx.GetTargetPtr();
4477
4478 ModuleSP module_sp(target->GetImages().FindFirstModule(module_spec));
4479 if (module_sp) {
4480 module_spec.GetFileSpec() = module_sp->GetFileSpec();
4481 module_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec();
4482 module_spec.GetUUID() = module_sp->GetUUID();
4483 module_spec.GetArchitecture() = module_sp->GetArchitecture();
4484 } else {
4485 module_spec.GetArchitecture() = target->GetArchitecture();
4486 }
4487
4488 if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) {
4489 StreamString error_strm;
4490 error_strm.PutCString(
4491 "unable to find debug symbols for the executable file ");
4492 error_strm << module_spec.GetFileSpec();
4493 result.AppendError(error_strm.GetString());
4494 return false;
4495 }
4496
4497 return true;
4498 }
4499
4500 bool AddSymbolsForFrame(CommandReturnObject &result, bool &flush) {
4501 assert(m_current_frame_option.GetOptionValue().OptionWasSet());
4502
4503 Process *process = m_exe_ctx.GetProcessPtr();
4504 if (!process) {
4505 result.AppendError(
4506 "a process must exist in order to use the --frame option");
4507 return false;
4508 }
4509
4510 const StateType process_state = process->GetState();
4511 if (!StateIsStoppedState(process_state, true)) {
4512 result.AppendErrorWithFormat("process is not stopped: %s",
4513 StateAsCString(process_state));
4514 return false;
4515 }
4516
4517 StackFrame *frame = m_exe_ctx.GetFramePtr();
4518 if (!frame) {
4519 result.AppendError("invalid current frame");
4520 return false;
4521 }
4522
4523 ModuleSP frame_module_sp(
4524 frame->GetSymbolContext(eSymbolContextModule).module_sp);
4525 if (!frame_module_sp) {
4526 result.AppendError("frame has no module");
4527 return false;
4528 }
4529
4530 ModuleSpec module_spec;
4531 module_spec.GetUUID() = frame_module_sp->GetUUID();
4532 module_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
4533 module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
4534
4535 if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) {
4536 result.AppendError("unable to find debug symbols for the current frame");
4537 return false;
4538 }
4539
4540 return true;
4541 }
4542
4543 bool AddSymbolsForStack(CommandReturnObject &result, bool &flush) {
4544 assert(m_current_stack_option.GetOptionValue().OptionWasSet());
4545
4546 Process *process = m_exe_ctx.GetProcessPtr();
4547 if (!process) {
4548 result.AppendError(
4549 "a process must exist in order to use the --stack option");
4550 return false;
4551 }
4552
4553 const StateType process_state = process->GetState();
4554 if (!StateIsStoppedState(process_state, true)) {
4555 result.AppendErrorWithFormat("process is not stopped: %s",
4556 StateAsCString(process_state));
4557 return false;
4558 }
4559
4560 Thread *thread = m_exe_ctx.GetThreadPtr();
4561 if (!thread) {
4562 result.AppendError("invalid current thread");
4563 return false;
4564 }
4565
4566 bool symbols_found = false;
4567 uint32_t frame_count = thread->GetStackFrameCount();
4568 for (uint32_t i = 0; i < frame_count; ++i) {
4569 lldb::StackFrameSP frame_sp = thread->GetStackFrameAtIndex(i);
4570
4571 ModuleSP frame_module_sp(
4572 frame_sp->GetSymbolContext(eSymbolContextModule).module_sp);
4573 if (!frame_module_sp)
4574 continue;
4575
4576 ModuleSpec module_spec;
4577 module_spec.GetUUID() = frame_module_sp->GetUUID();
4578 module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
4579 module_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
4580
4581 bool current_frame_flush = false;
4582 if (DownloadObjectAndSymbolFile(module_spec, result, current_frame_flush))
4583 symbols_found = true;
4584 flush |= current_frame_flush;
4585 }
4586
4587 if (!symbols_found) {
4588 result.AppendError(
4589 "unable to find debug symbols in the current call stack");
4590 return false;
4591 }
4592
4593 return true;
4594 }
4595
4596 void DoExecute(Args &args, CommandReturnObject &result) override {
4597 Target *target = m_exe_ctx.GetTargetPtr();
4599 bool flush = false;
4600 ModuleSpec module_spec;
4601 const bool uuid_option_set =
4602 m_uuid_option_group.GetOptionValue().OptionWasSet();
4603 const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
4604 const bool frame_option_set =
4605 m_current_frame_option.GetOptionValue().OptionWasSet();
4606 const bool stack_option_set =
4607 m_current_stack_option.GetOptionValue().OptionWasSet();
4608 const size_t argc = args.GetArgumentCount();
4609
4610 if (argc == 0) {
4611 if (uuid_option_set)
4612 AddSymbolsForUUID(result, flush);
4613 else if (file_option_set)
4614 AddSymbolsForFile(result, flush);
4615 else if (frame_option_set)
4616 AddSymbolsForFrame(result, flush);
4617 else if (stack_option_set)
4618 AddSymbolsForStack(result, flush);
4619 else
4620 result.AppendError("one or more symbol file paths must be specified, "
4621 "or options must be specified");
4622 } else {
4623 if (uuid_option_set) {
4624 result.AppendError("specify either one or more paths to symbol files "
4625 "or use the --uuid option without arguments");
4626 } else if (frame_option_set) {
4627 result.AppendError("specify either one or more paths to symbol files "
4628 "or use the --frame option without arguments");
4629 } else if (file_option_set && argc > 1) {
4630 result.AppendError("specify at most one symbol file path when "
4631 "--shlib option is set");
4632 } else {
4633 PlatformSP platform_sp(target->GetPlatform());
4634
4635 for (auto &entry : args.entries()) {
4636 if (!entry.ref().empty()) {
4637 auto &symbol_file_spec = module_spec.GetSymbolFileSpec();
4638 symbol_file_spec.SetFile(entry.ref(), FileSpec::Style::native);
4639 FileSystem::Instance().Resolve(symbol_file_spec);
4640 if (file_option_set) {
4641 module_spec.GetFileSpec() =
4642 m_file_option.GetOptionValue().GetCurrentValue();
4643 }
4644 if (platform_sp) {
4645 FileSpec symfile_spec;
4646 if (platform_sp
4647 ->ResolveSymbolFile(*target, module_spec, symfile_spec)
4648 .Success())
4649 module_spec.GetSymbolFileSpec() = symfile_spec;
4650 }
4651
4652 bool symfile_exists =
4654
4655 if (symfile_exists) {
4656 if (!AddModuleSymbols(target, module_spec, flush, result))
4657 break;
4658 } else {
4659 std::string resolved_symfile_path =
4660 module_spec.GetSymbolFileSpec().GetPath();
4661 if (resolved_symfile_path != entry.ref()) {
4662 result.AppendErrorWithFormat(
4663 "invalid module path '%s' with resolved path '%s'",
4664 entry.c_str(), resolved_symfile_path.c_str());
4665 break;
4666 }
4667 result.AppendErrorWithFormat("invalid module path '%s'",
4668 entry.c_str());
4669 break;
4670 }
4671 }
4672 }
4673 }
4674 }
4675
4676 if (flush) {
4677 Process *process = m_exe_ctx.GetProcessPtr();
4678 if (process)
4679 process->Flush();
4680 }
4681 }
4682
4688};
4689
4690#pragma mark CommandObjectTargetSymbols
4691
4692// CommandObjectTargetSymbols
4693
4695public:
4696 // Constructors and Destructors
4699 interpreter, "target symbols",
4700 "Commands for adding and managing debug symbol files.",
4701 "target symbols <sub-command> ...") {
4703 "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter)));
4704 }
4705
4706 ~CommandObjectTargetSymbols() override = default;
4707
4708private:
4709 // For CommandObjectTargetModules only
4713};
4714
4715#pragma mark CommandObjectTargetStopHookAdd
4716
4717// CommandObjectTargetStopHookAdd
4718#define LLDB_OPTIONS_target_stop_hook_add
4719#include "CommandOptions.inc"
4720
4723public:
4725 public:
4727
4728 ~CommandOptions() override = default;
4729
4730 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
4731 return llvm::ArrayRef(g_target_stop_hook_add_options);
4732 }
4733
4734 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
4735 ExecutionContext *execution_context) override {
4736 Status error;
4737 const int short_option =
4738 g_target_stop_hook_add_options[option_idx].short_option;
4739
4740 switch (short_option) {
4741 case 'c':
4742 m_class_name = std::string(option_arg);
4743 m_sym_ctx_specified = true;
4744 break;
4745
4746 case 'e':
4747 if (option_arg.getAsInteger(0, m_line_end)) {
4749 "invalid end line number: \"%s\"", option_arg.str().c_str());
4750 break;
4751 }
4752 m_sym_ctx_specified = true;
4753 break;
4754
4755 case 'G': {
4756 bool value, success;
4757 value = OptionArgParser::ToBoolean(option_arg, false, &success);
4758 if (success) {
4759 m_auto_continue = value;
4760 } else
4762 "invalid boolean value '%s' passed for -G option",
4763 option_arg.str().c_str());
4764 } break;
4765 case 'l':
4766 if (option_arg.getAsInteger(0, m_line_start)) {
4768 "invalid start line number: \"%s\"", option_arg.str().c_str());
4769 break;
4770 }
4771 m_sym_ctx_specified = true;
4772 break;
4773
4774 case 'i':
4775 m_no_inlines = true;
4776 break;
4777
4778 case 'n':
4779 m_function_name = std::string(option_arg);
4780 m_func_name_type_mask |= eFunctionNameTypeAuto;
4781 m_sym_ctx_specified = true;
4782 break;
4783
4784 case 'f':
4785 m_file_name = std::string(option_arg);
4786 m_sym_ctx_specified = true;
4787 break;
4788
4789 case 's':
4790 m_module_name = std::string(option_arg);
4791 m_sym_ctx_specified = true;
4792 break;
4793
4794 case 't':
4795 if (option_arg.getAsInteger(0, m_thread_id))
4797 "invalid thread id string '%s'", option_arg.str().c_str());
4798 m_thread_specified = true;
4799 break;
4800
4801 case 'T':
4802 m_thread_name = std::string(option_arg);
4803 m_thread_specified = true;
4804 break;
4805
4806 case 'q':
4807 m_queue_name = std::string(option_arg);
4808 m_thread_specified = true;
4809 break;
4810
4811 case 'x':
4812 if (option_arg.getAsInteger(0, m_thread_index))
4814 "invalid thread index string '%s'", option_arg.str().c_str());
4815 m_thread_specified = true;
4816 break;
4817
4818 case 'o':
4819 m_use_one_liner = true;
4820 m_one_liner.push_back(std::string(option_arg));
4821 break;
4822
4823 case 'I': {
4824 bool value, success;
4825 value = OptionArgParser::ToBoolean(option_arg, false, &success);
4826 if (success)
4827 m_at_initial_stop = value;
4828 else
4830 "invalid boolean value '%s' passed for -F option",
4831 option_arg.str().c_str());
4832 } break;
4833
4834 default:
4835 llvm_unreachable("Unimplemented option");
4836 }
4837 return error;
4838 }
4839
4840 void OptionParsingStarting(ExecutionContext *execution_context) override {
4841 m_class_name.clear();
4842 m_function_name.clear();
4843 m_line_start = 0;
4845 m_file_name.clear();
4846 m_module_name.clear();
4847 m_func_name_type_mask = eFunctionNameTypeAuto;
4850 m_thread_name.clear();
4851 m_queue_name.clear();
4852
4853 m_no_inlines = false;
4854 m_sym_ctx_specified = false;
4855 m_thread_specified = false;
4856
4857 m_use_one_liner = false;
4858 m_one_liner.clear();
4859 m_auto_continue = false;
4860 m_at_initial_stop = true;
4861 }
4862
4863 std::string m_class_name;
4864 std::string m_function_name;
4865 uint32_t m_line_start = 0;
4867 std::string m_file_name;
4868 std::string m_module_name;
4870 eFunctionNameTypeAuto; // A pick from lldb::FunctionNameType.
4873 std::string m_thread_name;
4874 std::string m_queue_name;
4876 bool m_no_inlines = false;
4878 // Instance variables to hold the values for one_liner options.
4879 bool m_use_one_liner = false;
4880 std::vector<std::string> m_one_liner;
4882
4883 bool m_auto_continue = false;
4884 };
4885
4887 : CommandObjectParsed(interpreter, "target stop-hook add",
4888 "Add a hook to be executed when the target stops."
4889 "The hook can either be a list of commands or an "
4890 "appropriately defined Python class. You can also "
4891 "add filters so the hook only runs a certain stop "
4892 "points.",
4893 "target stop-hook add", eCommandAllowsDummyTarget),
4896 m_python_class_options("scripted stop-hook", true, 'P') {
4898 R"(
4899Command Based stop-hooks:
4900-------------------------
4901 Stop hooks can run a list of lldb commands by providing one or more
4902 --one-liner options. The commands will get run in the order they are added.
4903 Or you can provide no commands, in which case you will enter a command editor
4904 where you can enter the commands to be run.
4905
4906Python Based Stop Hooks:
4907------------------------
4908 Stop hooks can be implemented with a suitably defined Python class, whose name
4909 is passed in the --python-class option.
4910
4911 When the stop hook is added, the class is initialized by calling:
4912
4913 def __init__(self, target, extra_args, internal_dict):
4914
4915 target: The target that the stop hook is being added to.
4916 extra_args: An SBStructuredData Dictionary filled with the -key -value
4917 option pairs passed to the command.
4918 dict: An implementation detail provided by lldb.
4919
4920 Then when the stop-hook triggers, lldb will run the 'handle_stop' method.
4921 The method has the signature:
4923 def handle_stop(self, exe_ctx, stream):
4924
4925 exe_ctx: An SBExecutionContext for the thread that has stopped.
4926 stream: An SBStream, anything written to this stream will be printed in the
4927 the stop message when the process stops.
4928
4929 Return Value: The method returns "should_stop". If should_stop is false
4930 from all the stop hook executions on threads that stopped
4931 with a reason, then the process will continue. Note that this
4932 will happen only after all the stop hooks are run.
4933
4934Filter Options:
4935---------------
4936 Stop hooks can be set to always run, or to only run when the stopped thread
4937 matches the filter options passed on the command line. The available filter
4938 options include a shared library or a thread or queue specification,
4939 a line range in a source file, a function name or a class name.
4940 )");
4943 LLDB_OPT_SET_FROM_TO(4, 6));
4944 m_all_options.Append(&m_options);
4945 m_all_options.Finalize();
4946 }
4947
4948 ~CommandObjectTargetStopHookAdd() override = default;
4949
4950 Options *GetOptions() override { return &m_all_options; }
4951
4952protected:
4953 void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
4954 if (interactive) {
4955 if (lldb::LockableStreamFileSP output_sp =
4956 io_handler.GetOutputStreamFileSP()) {
4957 LockedStreamFile locked_stream = output_sp->Lock();
4958 locked_stream.PutCString(
4959 "Enter your stop hook command(s). Type 'DONE' to end.\n");
4960 }
4961 }
4962 }
4963
4964 void IOHandlerInputComplete(IOHandler &io_handler,
4965 std::string &line) override {
4966 if (m_stop_hook_sp) {
4967 if (line.empty()) {
4968 if (lldb::LockableStreamFileSP error_sp =
4969 io_handler.GetErrorStreamFileSP()) {
4970 LockedStreamFile locked_stream = error_sp->Lock();
4971 locked_stream.Printf("error: stop hook #%" PRIu64
4972 " aborted, no commands.\n",
4973 m_stop_hook_sp->GetID());
4974 }
4976 } else {
4977 // The IOHandler editor is only for command lines stop hooks:
4978 Target::StopHookCommandLine *hook_ptr =
4979 static_cast<Target::StopHookCommandLine *>(m_stop_hook_sp.get());
4980
4981 hook_ptr->SetActionFromString(line);
4982 if (lldb::LockableStreamFileSP output_sp =
4983 io_handler.GetOutputStreamFileSP()) {
4984 LockedStreamFile locked_stream = output_sp->Lock();
4985 locked_stream.Printf("Stop hook #%" PRIu64 " added.\n",
4986 m_stop_hook_sp->GetID());
4987 }
4988 }
4989 m_stop_hook_sp.reset();
4990 }
4991 io_handler.SetIsDone(true);
4992 }
4993
4994 void DoExecute(Args &command, CommandReturnObject &result) override {
4995 m_stop_hook_sp.reset();
4996
4997 Target *target = GetTarget();
4998 assert(target && "target guaranteed by eCommandRequiresTarget");
4999 Target::StopHookSP new_hook_sp = target->CreateStopHook(
5000 m_python_class_options.GetName().empty()
5001 ? Target::StopHook::StopHookKind::CommandBased
5002 : Target::StopHook::StopHookKind::ScriptBased);
5003
5004 // First step, make the specifier.
5005 std::unique_ptr<SymbolContextSpecifier> specifier_up;
5006 if (m_options.m_sym_ctx_specified) {
5007 specifier_up =
5008 std::make_unique<SymbolContextSpecifier>(target->shared_from_this());
5009
5010 if (!m_options.m_module_name.empty()) {
5011 specifier_up->AddSpecification(
5012 m_options.m_module_name.c_str(),
5014 }
5015
5016 if (!m_options.m_class_name.empty()) {
5017 specifier_up->AddSpecification(
5018 m_options.m_class_name.c_str(),
5020 }
5021
5022 if (!m_options.m_file_name.empty()) {
5023 specifier_up->AddSpecification(m_options.m_file_name.c_str(),
5025 }
5026
5027 if (m_options.m_line_start != 0) {
5028 specifier_up->AddLineSpecification(
5029 m_options.m_line_start,
5031 }
5032
5033 if (m_options.m_line_end != UINT_MAX) {
5034 specifier_up->AddLineSpecification(
5036 }
5037
5038 if (!m_options.m_function_name.empty()) {
5039 specifier_up->AddSpecification(
5040 m_options.m_function_name.c_str(),
5042 }
5043 }
5044
5045 if (specifier_up)
5046 new_hook_sp->SetSpecifier(specifier_up.release());
5047
5048 // Should we run at the initial stop:
5049 new_hook_sp->SetRunAtInitialStop(m_options.m_at_initial_stop);
5050
5051 // Next see if any of the thread options have been entered:
5052
5053 if (m_options.m_thread_specified) {
5054 ThreadSpec *thread_spec = new ThreadSpec();
5055
5056 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) {
5057 thread_spec->SetTID(m_options.m_thread_id);
5058 }
5059
5060 if (m_options.m_thread_index != UINT32_MAX)
5061 thread_spec->SetIndex(m_options.m_thread_index);
5062
5063 if (!m_options.m_thread_name.empty())
5064 thread_spec->SetName(m_options.m_thread_name.c_str());
5066 if (!m_options.m_queue_name.empty())
5067 thread_spec->SetQueueName(m_options.m_queue_name.c_str());
5068
5069 new_hook_sp->SetThreadSpecifier(thread_spec);
5070 }
5071
5072 new_hook_sp->SetAutoContinue(m_options.m_auto_continue);
5074 // This is a command line stop hook:
5075 Target::StopHookCommandLine *hook_ptr =
5076 static_cast<Target::StopHookCommandLine *>(new_hook_sp.get());
5078 result.AppendMessageWithFormatv("Stop hook #{0} added.",
5079 new_hook_sp->GetID());
5080 } else if (!m_python_class_options.GetName().empty()) {
5081 // This is a scripted stop hook:
5082 Target::StopHookScripted *hook_ptr =
5083 static_cast<Target::StopHookScripted *>(new_hook_sp.get());
5084 ScriptedMetadata scripted_metadata(
5085 m_python_class_options.GetName(),
5086 m_python_class_options.GetStructuredData());
5087 Status error = hook_ptr->SetScriptCallback(scripted_metadata);
5088 if (error.Success())
5089 result.AppendMessageWithFormatv("Stop hook #{0} added.",
5090 new_hook_sp->GetID());
5091 else {
5092 // FIXME: Set the stop hook ID counter back.
5093 result.AppendErrorWithFormat("Couldn't add stop hook: %s",
5094 error.AsCString());
5095 target->UndoCreateStopHook(new_hook_sp->GetID());
5096 return;
5097 }
5098 } else {
5099 m_stop_hook_sp = new_hook_sp;
5100 m_interpreter.GetLLDBCommandsFromIOHandler("> ", // Prompt
5101 *this); // IOHandlerDelegate
5102 }
5104 }
5105
5106private:
5108 OptionGroupPythonClassWithDict m_python_class_options;
5109 OptionGroupOptions m_all_options;
5110
5112};
5113
5114#pragma mark CommandObjectTargetStopHookDelete
5115
5116// CommandObjectTargetStopHookDelete
5117
5119public:
5122 interpreter, "target stop-hook delete", "Delete a stop-hook.",
5123 "target stop-hook delete [<idx>]", eCommandAllowsDummyTarget) {
5125 R"(
5126Deletes the stop hook by index.
5127
5128At any given stop, all enabled stop hooks that pass the stop filter will
5129get a chance to run. That means if one stop-hook deletes another stop hook
5130while executing, the deleted stop hook will still fire for the stop at which
5131it was deleted.
5132 )");
5134 }
5135
5136 ~CommandObjectTargetStopHookDelete() override = default;
5137
5138 void
5140 OptionElementVector &opt_element_vector) override {
5141 if (request.GetCursorIndex())
5142 return;
5143 CommandObject::HandleArgumentCompletion(request, opt_element_vector);
5144 }
5145
5146protected:
5147 void DoExecute(Args &command, CommandReturnObject &result) override {
5148 Target *target = GetTarget();
5149 assert(target && "target guaranteed by eCommandRequiresTarget");
5150 // FIXME: see if we can use the breakpoint id style parser?
5151 size_t num_args = command.GetArgumentCount();
5152 if (num_args == 0) {
5153 if (!m_interpreter.Confirm("Delete all stop hooks?", true)) {
5155 return;
5156 } else {
5157 target->RemoveAllStopHooks();
5158 }
5159 } else {
5160 for (size_t i = 0; i < num_args; i++) {
5161 lldb::user_id_t user_id;
5162 if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
5163 result.AppendErrorWithFormat("invalid stop hook id: \"%s\"",
5164 command.GetArgumentAtIndex(i));
5165 return;
5166 }
5167 if (!target->RemoveStopHookByID(user_id)) {
5168 result.AppendErrorWithFormat("unknown stop hook id: \"%s\"",
5169 command.GetArgumentAtIndex(i));
5170 return;
5171 }
5172 }
5173 }
5175 }
5176};
5177
5178#pragma mark CommandObjectTargetStopHookEnableDisable
5179
5180// CommandObjectTargetStopHookEnableDisable
5181
5183public:
5185 bool enable, const char *name,
5186 const char *help, const char *syntax)
5187 : CommandObjectParsed(interpreter, name, help, syntax,
5188 eCommandAllowsDummyTarget),
5189 m_enable(enable) {
5191 }
5192
5194
5195 void
5197 OptionElementVector &opt_element_vector) override {
5198 if (request.GetCursorIndex())
5199 return;
5200 CommandObject::HandleArgumentCompletion(request, opt_element_vector);
5201 }
5202
5203protected:
5204 void DoExecute(Args &command, CommandReturnObject &result) override {
5205 Target *target = GetTarget();
5206 assert(target && "target guaranteed by eCommandRequiresTarget");
5207 // FIXME: see if we can use the breakpoint id style parser?
5208 size_t num_args = command.GetArgumentCount();
5209 bool success;
5210
5211 if (num_args == 0) {
5213 } else {
5214 for (size_t i = 0; i < num_args; i++) {
5215 lldb::user_id_t user_id;
5216 if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
5217 result.AppendErrorWithFormat("invalid stop hook id: \"%s\"",
5218 command.GetArgumentAtIndex(i));
5219 return;
5220 }
5221 success = target->SetStopHookActiveStateByID(user_id, m_enable);
5222 if (!success) {
5223 result.AppendErrorWithFormat("unknown stop hook id: \"%s\"",
5224 command.GetArgumentAtIndex(i));
5225 return;
5226 }
5227 }
5228 }
5230 }
5231
5232private:
5234};
5235
5236#pragma mark CommandObjectTargetStopHookList
5237
5238// CommandObjectTargetStopHookList
5239#define LLDB_OPTIONS_target_stop_hook_list
5240#include "CommandOptions.inc"
5241
5243public:
5245 : CommandObjectParsed(interpreter, "target stop-hook list",
5246 "List all stop-hooks.", nullptr,
5247 eCommandAllowsDummyTarget) {}
5248
5250
5251 Options *GetOptions() override { return &m_options; }
5252
5253 class CommandOptions : public Options {
5254 public:
5255 CommandOptions() = default;
5256 ~CommandOptions() override = default;
5257
5258 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
5259 ExecutionContext *execution_context) override {
5260 Status error;
5261 const int short_option = m_getopt_table[option_idx].val;
5262
5263 switch (short_option) {
5264 case 'i':
5265 m_internal = true;
5266 break;
5267 default:
5268 llvm_unreachable("Unimplemented option");
5269 }
5270
5271 return error;
5272 }
5273
5274 void OptionParsingStarting(ExecutionContext *execution_context) override {
5275 m_internal = false;
5276 }
5277
5278 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
5279 return llvm::ArrayRef(g_target_stop_hook_list_options);
5280 }
5281
5282 // Instance variables to hold the values for command options.
5283 bool m_internal = false;
5284 };
5285
5286protected:
5287 void DoExecute(Args &command, CommandReturnObject &result) override {
5288 Target *target = GetTarget();
5289 assert(target && "target guaranteed by eCommandRequiresTarget");
5290 bool printed_hook = false;
5291 for (auto &hook : target->GetStopHooks(m_options.m_internal)) {
5292 if (printed_hook)
5293 result.GetOutputStream().PutCString("\n");
5294 hook->GetDescription(result.GetOutputStream(), eDescriptionLevelFull);
5295 printed_hook = true;
5296 }
5297
5298 if (!printed_hook)
5299 result.GetOutputStream().PutCString("No stop hooks.\n");
5300
5302 }
5303
5304private:
5306};
5307
5308#pragma mark CommandObjectMultiwordTargetStopHooks
5309
5310// CommandObjectMultiwordTargetStopHooks
5311
5313public:
5316 interpreter, "target stop-hook",
5317 "Commands for operating on debugger target stop-hooks.",
5318 "target stop-hook <subcommand> [<subcommand-options>]") {
5320 new CommandObjectTargetStopHookAdd(interpreter)));
5322 "delete",
5324 LoadSubCommand("disable",
5326 interpreter, false, "target stop-hook disable [<id>]",
5327 "Disable a stop-hook.", "target stop-hook disable")));
5328 LoadSubCommand("enable",
5330 interpreter, true, "target stop-hook enable [<id>]",
5331 "Enable a stop-hook.", "target stop-hook enable")));
5333 interpreter)));
5334 }
5335
5337};
5338
5339#pragma mark CommandObjectTargetHookAdd
5340
5341#define LLDB_OPTIONS_target_hook_add
5342#include "CommandOptions.inc"
5343
5346public:
5348 public:
5349 CommandOptions() = default;
5350 ~CommandOptions() override = default;
5351
5352 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
5353 return llvm::ArrayRef(g_target_hook_add_options);
5354 }
5355
5356 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
5357 ExecutionContext *execution_context) override {
5358 Status error;
5359 const int short_option =
5360 g_target_hook_add_options[option_idx].short_option;
5361 switch (short_option) {
5362 case 'o':
5363 m_use_one_liner = true;
5364 m_one_liner.push_back(std::string(option_arg));
5365 break;
5366 case 'L':
5367 m_on_load = true;
5368 break;
5369 case 'u':
5370 m_on_unload = true;
5371 break;
5372 case 'S':
5373 m_on_stop = true;
5374 break;
5375 case 's':
5376 m_module_name = std::string(option_arg);
5377 m_sym_ctx_specified = true;
5378 break;
5379 case 'x': {
5380 uint32_t thread_index;
5381 if (option_arg.getAsInteger(0, thread_index))
5382 error = Status::FromErrorStringWithFormat("invalid thread index '%s'",
5383 option_arg.str().c_str());
5384 else
5385 m_thread_index = thread_index;
5386 m_thread_specified = true;
5387 break;
5388 }
5389 case 't': {
5390 lldb::tid_t thread_id;
5391 if (option_arg.getAsInteger(0, thread_id))
5392 error = Status::FromErrorStringWithFormat("invalid thread id '%s'",
5393 option_arg.str().c_str());
5394 else
5395 m_thread_id = thread_id;
5396 m_thread_specified = true;
5397 break;
5398 }
5399 case 'T':
5400 m_thread_name = std::string(option_arg);
5401 m_thread_specified = true;
5402 break;
5403 case 'q':
5404 m_queue_name = std::string(option_arg);
5405 m_thread_specified = true;
5406 break;
5407 case 'f':
5408 m_file_name = std::string(option_arg);
5409 m_sym_ctx_specified = true;
5410 break;
5411 case 'l': {
5412 uint32_t line;
5413 if (option_arg.getAsInteger(0, line))
5415 "invalid start line number '%s'", option_arg.str().c_str());
5416 else
5417 m_line_start = line;
5418 m_sym_ctx_specified = true;
5419 break;
5420 }
5421 case 'e': {
5422 uint32_t line;
5423 if (option_arg.getAsInteger(0, line))
5425 "invalid end line number '%s'", option_arg.str().c_str());
5426 else
5427 m_line_end = line;
5428 m_sym_ctx_specified = true;
5429 break;
5430 }
5431 case 'c':
5432 m_class_name = std::string(option_arg);
5433 m_sym_ctx_specified = true;
5434 break;
5435 case 'n':
5436 m_function_name = std::string(option_arg);
5437 m_sym_ctx_specified = true;
5438 break;
5439 case 'G': {
5440 bool value, success;
5441 value = OptionArgParser::ToBoolean(option_arg, false, &success);
5442 if (success)
5443 m_auto_continue = value;
5444 else
5446 "invalid boolean value '%s' passed for -G option",
5447 option_arg.str().c_str());
5448 break;
5449 }
5450 case 'I': {
5451 bool value, success;
5452 value = OptionArgParser::ToBoolean(option_arg, true, &success);
5453 if (success)
5454 m_at_initial_stop = value;
5455 else
5457 "invalid boolean value '%s' passed for -I option",
5458 option_arg.str().c_str());
5459 break;
5460 }
5461 default:
5462 llvm_unreachable("unhandled option");
5463 }
5464 return error;
5465 }
5466
5467 void OptionParsingStarting(ExecutionContext *execution_context) override {
5468 m_use_one_liner = false;
5469 m_one_liner.clear();
5470 m_on_load = false;
5471 m_on_unload = false;
5472 m_on_stop = false;
5473 m_sym_ctx_specified = false;
5474 m_thread_specified = false;
5475 m_module_name.clear();
5476 m_file_name.clear();
5477 m_class_name.clear();
5478 m_function_name.clear();
5479 m_line_start = 0;
5480 m_line_end = UINT_MAX;
5483 m_thread_name.clear();
5484 m_queue_name.clear();
5485 m_auto_continue = false;
5486 m_at_initial_stop = true;
5487 }
5488
5489 std::vector<std::string> m_one_liner;
5490 bool m_use_one_liner = false;
5491 bool m_on_load = false;
5492 bool m_on_unload = false;
5493 bool m_on_stop = false;
5494
5495 // Filter options (for stop trigger).
5498 std::string m_module_name;
5499 std::string m_file_name;
5500 std::string m_class_name;
5501 std::string m_function_name;
5502 uint32_t m_line_start = 0;
5503 uint32_t m_line_end = UINT_MAX;
5506 std::string m_thread_name;
5507 std::string m_queue_name;
5508 bool m_auto_continue = false;
5510 };
5511
5514 interpreter, "target hook add",
5515 "Add a hook to be executed on target lifecycle events.",
5516 "target hook add", eCommandAllowsDummyTarget),
5519 m_python_class_options("scripted hook", false, 'P') {
5520 SetHelpLong(R"help(
5521Command-based hooks:
5522--------------------
5523 Specify which triggers the hook responds to with --on-load (-L),
5524 --on-unload (-u), and/or --on-stop (-S). At least one trigger is required.
5525 Provide commands with --one-liner (-o), or omit -o to enter an interactive
5526 command editor. All commands run for every trigger the hook is signed up
5527 for; there is no per-trigger command list.
5528
5529 Examples:
5530 target hook add -L -o "script print('module loaded')"
5531 target hook add -L -u -o "script print('module event')"
5532 target hook add -S -o "bt"
5533 target hook add -L -u -S -o "script print('all events')"
5534 target hook add -S -s mylib.so -n main -o "bt"
5535 target hook add -S -G true -o "thread info"
5537Python class hooks:
5538-------------------
5539 Provide a Python class with --python-class (-P). The class controls which
5540 events it handles by implementing the corresponding methods; you do not
5541 specify triggers on the command line. Use -k <key> -v <value> to pass
5542 extra_args to the class constructor.
5543
5544 Examples:
5545 target hook add -P mymodule.MyHook
5546 target hook add -P mymodule.MyHook -k verbose -v true
5548 The Python class should implement at least one of these methods:
5549
5550 class MyHook:
5551 def __init__(self, target, extra_args, internal_dict):
5552 self.target = target
5553 def handle_module_loaded(self, stream):
5554 pass
5555 def handle_module_unloaded(self, stream):
5556 pass
5557 def handle_stop(self, exe_ctx, stream):
5558 return True # True = should_stop, False = continue
5559
5560Filter options:
5561---------------
5562 Filters (-s, -f, -l, -e, -c, -n, -x, -t, -T, -q) restrict when the hook
5563 fires. They apply to both command-based and Python class hooks.
5564)help");
5565 // Python class options (-P, -k, -v) are placed in Set 2 (dst_mask).
5566 // src_mask must cover Set 1 | Set 2 to match the internal usage masks of
5567 // OptionGroupPythonClassWithDict (class=Set1, key/value=Set2).
5568 // Since -o, -L, -u, -S are Group<1> only, the parser prevents mixing.
5571 m_all_options.Append(&m_options);
5572 m_all_options.Finalize();
5573 }
5575 ~CommandObjectTargetHookAdd() override = default;
5576
5577 Options *GetOptions() override { return &m_all_options; }
5578
5579protected:
5580 void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
5581 if (interactive) {
5582 if (lldb::LockableStreamFileSP output_sp =
5583 io_handler.GetOutputStreamFileSP()) {
5584 LockedStreamFile locked_stream = output_sp->Lock();
5585 locked_stream.PutCString(
5586 "Enter your hook command(s). Type 'DONE' to end.\n");
5587 }
5588 }
5589 }
5590
5591 void IOHandlerInputComplete(IOHandler &io_handler,
5592 std::string &line) override {
5593 if (m_hook_sp) {
5594 if (line.empty()) {
5595 if (lldb::LockableStreamFileSP error_sp =
5596 io_handler.GetErrorStreamFileSP()) {
5597 LockedStreamFile locked_stream = error_sp->Lock();
5598 locked_stream.Printf("error: hook #%" PRIu64
5599 " aborted, no commands.\n",
5600 m_hook_sp->GetID());
5601 }
5602 GetTarget()->UndoCreateHook(m_hook_sp->GetID());
5603 } else {
5604 auto *hook = static_cast<Target::HookCommandLine *>(m_hook_sp.get());
5605 hook->SetActionFromString(line);
5606 if (lldb::LockableStreamFileSP output_sp =
5607 io_handler.GetOutputStreamFileSP()) {
5608 LockedStreamFile locked_stream = output_sp->Lock();
5609 locked_stream.Printf("Hook #%" PRIu64 " added.\n",
5610 m_hook_sp->GetID());
5611 }
5612 }
5613 m_hook_sp.reset();
5614 }
5615 io_handler.SetIsDone(true);
5616 }
5617
5618 void DoExecute(Args &command, CommandReturnObject &result) override {
5619 m_hook_sp.reset();
5620 Target *target = GetTarget();
5621 assert(target && "target guaranteed by eCommandRequiresTarget");
5622 bool is_python_class = !m_python_class_options.GetName().empty();
5623
5624 // Command-based hooks require at least one explicit trigger.
5625 if (!is_python_class && !m_options.m_on_load && !m_options.m_on_unload &&
5626 !m_options.m_on_stop) {
5627 result.AppendError("at least one trigger must be specified: "
5628 "--on-load (-L), --on-unload (-u), or --on-stop (-S)");
5629 return;
5630 }
5631
5632 Target::Hook::HookKind hook_kind =
5633 is_python_class ? Target::Hook::HookKind::ScriptBased
5634 : Target::Hook::HookKind::CommandBased;
5635
5636 Target::HookSP new_hook_sp = target->CreateHook(hook_kind);
5637
5638 if (!is_python_class) {
5639 // Build trigger mask from explicit command-line flags.
5640 auto *cmd_hook =
5641 static_cast<Target::HookCommandLine *>(new_hook_sp.get());
5642 uint32_t trigger_mask = 0;
5643 if (m_options.m_on_load)
5644 trigger_mask |= Target::Hook::kModulesLoaded;
5645 if (m_options.m_on_unload)
5646 trigger_mask |= Target::Hook::kModulesUnloaded;
5647 if (m_options.m_on_stop)
5648 trigger_mask |= Target::Hook::kProcessStop;
5649 cmd_hook->SetTriggerMask(trigger_mask);
5650 }
5651 // Python class hooks: triggers are computed in SetScriptCallback based
5652 // on which callback methods the class implements.
5653
5654 // Set up symbol context specifier if filter options were provided.
5655 if (m_options.m_sym_ctx_specified) {
5656 auto specifier_up =
5657 std::make_unique<SymbolContextSpecifier>(target->shared_from_this());
5658
5659 if (!m_options.m_module_name.empty())
5660 specifier_up->AddSpecification(
5661 m_options.m_module_name.c_str(),
5663
5664 if (!m_options.m_class_name.empty())
5665 specifier_up->AddSpecification(
5666 m_options.m_class_name.c_str(),
5668
5669 if (!m_options.m_file_name.empty())
5670 specifier_up->AddSpecification(m_options.m_file_name.c_str(),
5672
5673 if (m_options.m_line_start != 0)
5674 specifier_up->AddLineSpecification(
5675 m_options.m_line_start,
5677
5678 if (m_options.m_line_end != UINT_MAX)
5679 specifier_up->AddLineSpecification(
5681
5682 if (!m_options.m_function_name.empty())
5683 specifier_up->AddSpecification(
5684 m_options.m_function_name.c_str(),
5686
5687 new_hook_sp->SetSCSpecifier(specifier_up.release());
5688 }
5689
5690 // Set up thread specifier.
5691 if (m_options.m_thread_specified) {
5692 ThreadSpec *thread_spec = new ThreadSpec();
5693
5694 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
5695 thread_spec->SetTID(m_options.m_thread_id);
5697 if (m_options.m_thread_index != UINT32_MAX)
5698 thread_spec->SetIndex(m_options.m_thread_index);
5700 if (!m_options.m_thread_name.empty())
5701 thread_spec->SetName(m_options.m_thread_name.c_str());
5702
5703 if (!m_options.m_queue_name.empty())
5704 thread_spec->SetQueueName(m_options.m_queue_name.c_str());
5705
5706 new_hook_sp->SetThreadSpecifier(thread_spec);
5707 }
5708
5709 new_hook_sp->SetAutoContinue(m_options.m_auto_continue);
5710 new_hook_sp->SetRunAtInitialStop(m_options.m_at_initial_stop);
5711
5713 auto *hook = static_cast<Target::HookCommandLine *>(new_hook_sp.get());
5715 result.AppendMessageWithFormatv("Hook #{0} added.\n",
5716 new_hook_sp->GetID());
5717 } else if (!m_python_class_options.GetName().empty()) {
5718 auto *hook = static_cast<Target::HookScripted *>(new_hook_sp.get());
5719 ScriptedMetadata scripted_metadata(
5720 m_python_class_options.GetName(),
5721 m_python_class_options.GetStructuredData());
5722 Status callback_error = hook->SetScriptCallback(scripted_metadata);
5723 if (callback_error.Fail()) {
5724 result.AppendErrorWithFormat("couldn't add hook: %s",
5725 callback_error.AsCString());
5726 target->UndoCreateHook(new_hook_sp->GetID());
5727 return;
5728 }
5729 result.AppendMessageWithFormatv("Hook #{0} added.\n",
5730 new_hook_sp->GetID());
5731 } else {
5732 m_hook_sp = new_hook_sp;
5733 m_interpreter.GetLLDBCommandsFromIOHandler("> ", // prompt
5734 *this); // delegate
5735 }
5737 }
5738
5739private:
5741 OptionGroupPythonClassWithDict m_python_class_options;
5742 OptionGroupOptions m_all_options;
5744};
5745
5746#pragma mark CommandObjectTargetHookDelete
5747
5749public:
5751 : CommandObjectParsed(interpreter, "target hook delete", "Delete a hook.",
5752 "target hook delete [<id>]",
5753 eCommandAllowsDummyTarget) {
5755 }
5756
5758
5759protected:
5760 void DoExecute(Args &command, CommandReturnObject &result) override {
5761 Target *target = GetTarget();
5762 assert(target && "target guaranteed by eCommandRequiresTarget");
5763 if (command.GetArgumentCount() == 0) {
5764 if (!m_interpreter.Confirm("Delete all hooks?", true)) {
5766 return;
5767 }
5768 target->RemoveAllHooks();
5770 return;
5771 }
5772
5773 for (size_t i = 0; i < command.GetArgumentCount(); i++) {
5774 lldb::user_id_t user_id;
5775 if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
5776 result.AppendErrorWithFormat("invalid hook id: \"%s\"",
5777 command.GetArgumentAtIndex(i));
5778 return;
5779 }
5780 if (!target->RemoveHookByID(user_id)) {
5781 result.AppendErrorWithFormat("unknown hook id: \"%s\"",
5782 command.GetArgumentAtIndex(i));
5783 return;
5784 }
5785 }
5787 }
5788};
5789
5790#pragma mark CommandObjectTargetHookEnableDisable
5791
5793public:
5795 bool enable, const char *name,
5796 const char *help, const char *syntax)
5797 : CommandObjectParsed(interpreter, name, help, syntax,
5798 eCommandAllowsDummyTarget),
5799 m_enable(enable) {
5801 }
5802
5804
5805protected:
5806 void DoExecute(Args &command, CommandReturnObject &result) override {
5807 Target *target = GetTarget();
5808 assert(target && "target guaranteed by eCommandRequiresTarget");
5809 // No IDs = apply to all hooks.
5810 if (command.GetArgumentCount() == 0) {
5813 return;
5814 }
5815
5816 for (size_t i = 0; i < command.GetArgumentCount(); i++) {
5817 lldb::user_id_t user_id;
5818 if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
5819 result.AppendErrorWithFormat("invalid hook id: \"%s\"",
5820 command.GetArgumentAtIndex(i));
5821 return;
5822 }
5823 if (!target->SetHookEnabledStateByID(user_id, m_enable)) {
5824 result.AppendErrorWithFormat("unknown hook id: \"%s\"",
5825 command.GetArgumentAtIndex(i));
5826 return;
5827 }
5828 }
5830 }
5831
5832private:
5834};
5835
5836#pragma mark CommandObjectTargetHookModify
5837
5838#define LLDB_OPTIONS_target_hook_modify
5839#include "CommandOptions.inc"
5840
5841/// Modify trigger settings on a hook. Only valid for command-based hooks;
5842/// scripted hooks derive their triggers from the class methods.
5844public:
5845 class CommandOptions : public Options {
5846 public:
5847 CommandOptions() = default;
5848 ~CommandOptions() override = default;
5849
5850 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
5851 return llvm::ArrayRef(g_target_hook_modify_options);
5852 }
5853
5854 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
5855 ExecutionContext *execution_context) override {
5856 Status error;
5857 const int short_option =
5858 g_target_hook_modify_options[option_idx].short_option;
5859 switch (short_option) {
5860 case 'e':
5861 m_enable_trigger = option_arg.str();
5862 break;
5863 case 'd':
5864 m_disable_trigger = option_arg.str();
5865 break;
5866 default:
5867 llvm_unreachable("unhandled option");
5868 }
5869 return error;
5870 }
5871
5872 void OptionParsingStarting(ExecutionContext *execution_context) override {
5873 m_enable_trigger.clear();
5874 m_disable_trigger.clear();
5875 }
5876
5877 std::string m_enable_trigger;
5879 };
5880
5882 : CommandObjectParsed(interpreter, "target hook modify",
5883 "Modify trigger settings on a hook.",
5884 "target hook modify [--enable-trigger <name>] "
5885 "[--disable-trigger <name>] [<id>]",
5886 eCommandAllowsDummyTarget) {
5888 SetHelpLong(R"help(
5889Modify trigger settings on command-based hooks. Scripted hooks derive their
5890triggers from the class methods and cannot be modified.
5892If no hook ID is given, the last added hook is modified.
5894Valid trigger names: load, unload, stop.
5895
5896Examples:
5897 target hook modify --enable-trigger stop 1
5898 target hook modify --disable-trigger load 1
5899 target hook modify --enable-trigger stop (modifies last added hook)
5900)help");
5901 }
5902
5903 ~CommandObjectTargetHookModify() override = default;
5904
5905 Options *GetOptions() override { return &m_options; }
5907protected:
5908 static uint32_t ParseTriggerName(llvm::StringRef name) {
5909 if (name == "load")
5911 if (name == "unload")
5913 if (name == "stop")
5915 return 0;
5916 }
5917
5918 void DoExecute(Args &command, CommandReturnObject &result) override {
5919 Target *target = GetTarget();
5920 assert(target && "target guaranteed by eCommandRequiresTarget");
5921 if (m_options.m_enable_trigger.empty() &&
5922 m_options.m_disable_trigger.empty()) {
5923 result.AppendError("at least one of --enable-trigger or "
5924 "--disable-trigger must be specified");
5925 return;
5926 }
5927
5928 // Resolve the hook ID. Default to last added if not specified.
5929 Target::HookSP hook_sp;
5930 if (command.GetArgumentCount() == 0) {
5931 size_t num_hooks = target->GetNumHooks();
5932 if (num_hooks == 0) {
5933 result.AppendError("no hooks exist");
5934 return;
5935 }
5936 hook_sp = target->GetHookAtIndex(num_hooks - 1);
5937 } else {
5938 lldb::user_id_t user_id;
5939 if (!llvm::to_integer(command.GetArgumentAtIndex(0), user_id)) {
5940 result.AppendErrorWithFormat("invalid hook id: \"%s\"",
5941 command.GetArgumentAtIndex(0));
5942 return;
5943 }
5944 hook_sp = target->GetHookByID(user_id);
5945 if (!hook_sp) {
5946 result.AppendErrorWithFormat("unknown hook id: \"%s\"",
5947 command.GetArgumentAtIndex(0));
5948 return;
5949 }
5950 }
5951
5952 // Reject trigger modification on scripted hooks.
5953 if (hook_sp->GetHookKind() != Target::Hook::HookKind::CommandBased) {
5954 result.AppendError("cannot modify triggers on a scripted hook; "
5955 "triggers are determined by the class methods");
5956 return;
5957 }
5958 auto *cmd_hook = static_cast<Target::HookCommandLine *>(hook_sp.get());
5959
5960 if (!m_options.m_enable_trigger.empty()) {
5961 uint32_t trigger = ParseTriggerName(m_options.m_enable_trigger);
5962 if (!trigger) {
5963 result.AppendErrorWithFormat("unknown trigger name: \"%s\". "
5964 "Valid names: load, unload, stop",
5965 m_options.m_enable_trigger.c_str());
5966 return;
5967 }
5968 cmd_hook->AddTrigger(trigger);
5969 }
5970
5971 if (!m_options.m_disable_trigger.empty()) {
5972 uint32_t trigger = ParseTriggerName(m_options.m_disable_trigger);
5973 if (!trigger) {
5974 result.AppendErrorWithFormat("unknown trigger name: \"%s\". "
5975 "Valid names: load, unload, stop",
5976 m_options.m_disable_trigger.c_str());
5977 return;
5978 }
5979 cmd_hook->RemoveTrigger(trigger);
5980 }
5981
5983 }
5984
5985private:
5987};
5988
5989#pragma mark CommandObjectTargetHookList
5990
5992public:
5994 : CommandObjectParsed(interpreter, "target hook list", "List all hooks.",
5995 "target hook list", eCommandAllowsDummyTarget) {}
5996
5997 ~CommandObjectTargetHookList() override = default;
5998
5999protected:
6000 void DoExecute(Args &command, CommandReturnObject &result) override {
6001 Target *target = GetTarget();
6002 assert(target && "target guaranteed by eCommandRequiresTarget");
6003 size_t num_hooks = target->GetNumHooks();
6004 if (num_hooks == 0) {
6005 result.GetOutputStream().PutCString("No hooks.\n");
6006 } else {
6007 for (size_t i = 0; i < num_hooks; i++) {
6008 Target::HookSP hook_sp = target->GetHookAtIndex(i);
6009 if (hook_sp)
6010 hook_sp->GetDescription(result.GetOutputStream(),
6012 }
6013 }
6015 }
6016};
6017
6018#pragma mark CommandObjectMultiwordTargetHooks
6019
6021public:
6024 interpreter, "target hook",
6025 "Commands for operating on target hooks.",
6026 "target hook <subcommand> [<subcommand-options>]") {
6028 "add", CommandObjectSP(new CommandObjectTargetHookAdd(interpreter)));
6030 interpreter)));
6031 LoadSubCommand("disable",
6033 interpreter, false, "target hook disable",
6034 "Disable a hook.", "target hook disable [<id> ...]")));
6035 LoadSubCommand("enable",
6037 interpreter, true, "target hook enable",
6038 "Enable a hook.", "target hook enable [<id> ...]")));
6040 "list", CommandObjectSP(new CommandObjectTargetHookList(interpreter)));
6042 interpreter)));
6043 }
6044
6046};
6047
6048#pragma mark CommandObjectTargetDumpTypesystem
6049
6050/// Dumps the TypeSystem of the selected Target.
6052public:
6055 interpreter, "target dump typesystem",
6056 "Dump the state of the target's internal type system. Intended to "
6057 "be used for debugging LLDB itself.",
6058 nullptr, eCommandRequiresTarget) {}
6059
6061
6062protected:
6063 void DoExecute(Args &command, CommandReturnObject &result) override {
6064 // Go over every scratch TypeSystem and dump to the command output.
6065 for (lldb::TypeSystemSP ts : GetTarget()->GetScratchTypeSystems())
6066 if (ts)
6067 ts->Dump(result.GetOutputStream().AsRawOstream(), "",
6068 GetCommandInterpreter().GetDebugger().GetUseColor());
6069
6071 }
6072};
6073
6074#pragma mark CommandObjectTargetDumpSectionLoadList
6075
6076/// Dumps the SectionLoadList of the selected Target.
6078public:
6081 interpreter, "target dump section-load-list",
6082 "Dump the state of the target's internal section load list. "
6083 "Intended to be used for debugging LLDB itself.",
6084 nullptr, eCommandRequiresTarget) {}
6085
6087
6088protected:
6089 void DoExecute(Args &command, CommandReturnObject &result) override {
6090 Target *target = GetTarget();
6091 assert(target && "target guaranteed by eCommandRequiresTarget");
6092 target->DumpSectionLoadList(result.GetOutputStream());
6094 }
6095};
6096
6097#pragma mark CommandObjectTargetDump
6098
6099/// Multi-word command for 'target dump'.
6101public:
6102 // Constructors and Destructors
6105 interpreter, "target dump",
6106 "Commands for dumping information about the target.",
6107 "target dump [typesystem|section-load-list]") {
6109 "typesystem",
6111 LoadSubCommand("section-load-list",
6113 interpreter)));
6114 }
6115
6116 ~CommandObjectTargetDump() override = default;
6117};
6118
6119#pragma mark CommandObjectTargetFrameProvider
6120
6121#define LLDB_OPTIONS_target_frame_provider_register
6122#include "CommandOptions.inc"
6123
6125public:
6128 interpreter, "target frame-provider register",
6129 "Register frame provider for all threads in this target.", nullptr,
6130 eCommandRequiresTarget),
6131
6132 m_class_options("target frame-provider", true, 'C', 'k', 'v', 0) {
6135 m_all_options.Finalize();
6136 }
6137
6139
6140 Options *GetOptions() override { return &m_all_options; }
6141
6142 std::optional<std::string> GetRepeatCommand(Args &current_command_args,
6143 uint32_t index) override {
6144 return std::string("");
6145 }
6146
6147protected:
6148 void DoExecute(Args &command, CommandReturnObject &result) override {
6149 ScriptedMetadataSP metadata_sp = std::make_shared<ScriptedMetadata>(
6150 m_class_options.GetName(), m_class_options.GetStructuredData());
6151
6152 Target *target = m_exe_ctx.GetTargetPtr();
6153
6154 if (!target)
6155 target = &GetDebugger().GetDummyTarget();
6156
6157 // Create the interface for calling static methods.
6159 GetDebugger()
6162
6163 // Create a descriptor from the metadata (applies to all threads by
6164 // default).
6165 ScriptedFrameProviderDescriptor descriptor(metadata_sp);
6166 descriptor.interface_sp = interface_sp;
6167
6168 auto id_or_err = target->AddScriptedFrameProviderDescriptor(descriptor);
6169 if (!id_or_err) {
6170 result.SetError(id_or_err.takeError());
6171 return;
6172 }
6173
6175 "successfully registered scripted frame provider '{0}' for target",
6176 m_class_options.GetName().c_str());
6177 }
6178
6181};
6182
6184public:
6187 interpreter, "target frame-provider clear",
6188 "Clear all registered frame providers from this target.", nullptr,
6189 eCommandRequiresTarget) {}
6190
6192
6193protected:
6194 void DoExecute(Args &command, CommandReturnObject &result) override {
6195 Target *target = m_exe_ctx.GetTargetPtr();
6196 if (!target) {
6197 result.AppendError("invalid target");
6198 return;
6199 }
6200
6202
6204 }
6205};
6206
6208public:
6211 interpreter, "target frame-provider list",
6212 "List all registered frame providers for the target.", nullptr,
6213 eCommandRequiresTarget) {}
6214
6216
6217protected:
6218 void DoExecute(Args &command, CommandReturnObject &result) override {
6219 Target *target = m_exe_ctx.GetTargetPtr();
6220 if (!target)
6221 target = &GetDebugger().GetDummyTarget();
6222
6223 const auto &descriptors = target->GetScriptedFrameProviderDescriptors();
6224 if (descriptors.empty()) {
6225 result.AppendMessage("no frame providers registered for this target.");
6227 return;
6228 }
6229
6230 Stream &strm = result.GetOutputStream();
6231 strm << llvm::formatv("{0} frame provider(s) registered:\n\n",
6232 descriptors.size());
6233
6234 for (const auto &entry : descriptors) {
6235 const ScriptedFrameProviderDescriptor &descriptor = entry.second;
6236 descriptor.Dump(&strm);
6237 strm.PutChar('\n');
6238 }
6239
6241 }
6242};
6243
6245public:
6248 interpreter, "target frame-provider remove",
6249 "Remove a registered frame provider from the target by id.",
6250 "target frame-provider remove <provider-id>",
6251 eCommandRequiresTarget) {
6253 }
6254
6256
6257protected:
6258 void DoExecute(Args &command, CommandReturnObject &result) override {
6259 Target *target = m_exe_ctx.GetTargetPtr();
6260 if (!target)
6261 target = &GetDebugger().GetDummyTarget();
6262
6263 std::vector<uint32_t> removed_provider_ids;
6264 for (size_t i = 0; i < command.GetArgumentCount(); i++) {
6265 uint32_t provider_id = 0;
6266 if (!llvm::to_integer(command[i].ref(), provider_id)) {
6267 result.AppendError("target frame-provider remove requires integer "
6268 "provider id argument");
6269 return;
6270 }
6271
6272 if (!target->RemoveScriptedFrameProviderDescriptor(provider_id)) {
6273 result.AppendErrorWithFormat(
6274 "no frame provider named '%u' found in target", provider_id);
6275 return;
6276 }
6277 removed_provider_ids.push_back(provider_id);
6278 }
6279
6280 if (size_t num_removed_providers = removed_provider_ids.size()) {
6282 "Successfully removed {0} frame-providers.", num_removed_providers);
6284 } else {
6285 result.AppendError("0 frame providers removed.\n");
6286 }
6287 }
6288};
6289
6291public:
6294 interpreter, "target frame-provider",
6295 "Commands for registering and viewing frame providers for the "
6296 "target.",
6297 "target frame-provider [<sub-command-options>] ") {
6298 LoadSubCommand("register",
6300 interpreter)));
6301 LoadSubCommand("clear",
6303 new CommandObjectTargetFrameProviderClear(interpreter)));
6305 "list",
6308 "remove", CommandObjectSP(
6309 new CommandObjectTargetFrameProviderRemove(interpreter)));
6310 }
6311
6313};
6314
6315#pragma mark CommandObjectMultiwordTarget
6316
6317// CommandObjectMultiwordTarget
6318
6320 CommandInterpreter &interpreter)
6321 : CommandObjectMultiword(interpreter, "target",
6322 "Commands for operating on debugger targets.",
6323 "target <subcommand> [<subcommand-options>]") {
6324 LoadSubCommand("create",
6325 CommandObjectSP(new CommandObjectTargetCreate(interpreter)));
6326 LoadSubCommand("delete",
6327 CommandObjectSP(new CommandObjectTargetDelete(interpreter)));
6328 LoadSubCommand("dump",
6329 CommandObjectSP(new CommandObjectTargetDump(interpreter)));
6331 "frame-provider",
6333 LoadSubCommand("list",
6334 CommandObjectSP(new CommandObjectTargetList(interpreter)));
6335 LoadSubCommand("select",
6336 CommandObjectSP(new CommandObjectTargetSelect(interpreter)));
6337 LoadSubCommand("show-launch-environment",
6339 interpreter)));
6341 "stop-hook",
6344 interpreter)));
6345 LoadSubCommand("modules",
6347 LoadSubCommand("symbols",
6349 LoadSubCommand("variable",
6351}
6352
static bool GetSeparateDebugInfoList(StructuredData::Array &list, Module *module, bool errors_only, bool load_all_debug_info)
static uint32_t DumpTargetList(TargetList &target_list, bool show_stopped_process_status, Stream &strm)
static void DumpModuleUUID(Stream &strm, Module *module)
static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm, Module *module)
static void DumpModuleArchitecture(Stream &strm, Module *module, bool full_triple, uint32_t width)
static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm, Module *module, uint32_t resolve_mask, lldb::addr_t raw_addr, lldb::addr_t offset, bool verbose, bool all_ranges)
static void DumpTargetInfo(uint32_t target_idx, Target *target, const char *prefix_cstr, bool show_stopped_process_status, Stream &strm)
static void DumpDirectory(Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex, bool verbose, bool all_ranges)
static size_t LookupTypeInModule(Target *target, CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name_cstr, bool name_is_regex)
static bool DumpModuleSymbolFile(Stream &strm, Module *module)
static void DumpFullpath(Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
static void DumpDwoFilesTable(Stream &strm, StructuredData::Array &dwo_listings)
static size_t LookupFunctionInModule(CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex, const ModuleFunctionSearchOptions &options, bool verbose, bool all_ranges)
static size_t LookupTypeHere(Target *target, CommandInterpreter &interpreter, Stream &strm, Module &module, const char *name_cstr, bool name_is_regex)
static uint32_t DumpCompileUnitLineTable(CommandInterpreter &interpreter, Stream &strm, Module *module, const FileSpec &file_spec, lldb::DescriptionLevel desc_level)
static void DumpBasename(Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list)
static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter, Stream &strm, Module *module, const FileSpec &file_spec, uint32_t line, bool check_inlines, bool verbose, bool all_ranges)
static void DumpSymbolContextList(ExecutionContextScope *exe_scope, Stream &strm, const SymbolContextList &sc_list, bool verbose, bool all_ranges, std::optional< Stream::HighlightSettings > settings=std::nullopt)
static void DumpOsoFilesTable(Stream &strm, StructuredData::Array &oso_listings)
static size_t FindModulesByName(Target *target, const char *module_name, ModuleList &module_list, bool check_global_list)
static void DumpModuleSymtab(CommandInterpreter &interpreter, Stream &strm, Module *module, SortOrder sort_order, Mangled::NamePreference name_preference)
static llvm::raw_ostream & error(Stream &strm)
#define INTERRUPT_REQUESTED(debugger,...)
This handy define will keep you from having to generate a report for the interruption by hand.
Definition Debugger.h:494
#define LLDB_LOGF(log,...)
Definition Log.h:378
#define LLDB_SCOPED_TIMERF(...)
Definition Timer.h:86
CommandObjectMultiwordTargetHooks(CommandInterpreter &interpreter)
~CommandObjectMultiwordTargetHooks() override=default
~CommandObjectMultiwordTargetStopHooks() override=default
CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter)
OptionGroupPlatform m_platform_options
~CommandObjectTargetCreate() override=default
OptionGroupArchitecture m_arch_option
CommandObjectTargetCreate(CommandInterpreter &interpreter)
OptionGroupDependents m_add_dependents
void DoExecute(Args &command, CommandReturnObject &result) override
void DoExecute(Args &args, CommandReturnObject &result) override
CommandObjectTargetDelete(CommandInterpreter &interpreter)
~CommandObjectTargetDelete() override=default
Dumps the SectionLoadList of the selected Target.
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetDumpSectionLoadList() override=default
CommandObjectTargetDumpSectionLoadList(CommandInterpreter &interpreter)
Dumps the TypeSystem of the selected Target.
CommandObjectTargetDumpTypesystem(CommandInterpreter &interpreter)
~CommandObjectTargetDumpTypesystem() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
Multi-word command for 'target dump'.
CommandObjectTargetDump(CommandInterpreter &interpreter)
~CommandObjectTargetDump() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTargetFrameProviderClear(CommandInterpreter &interpreter)
~CommandObjectTargetFrameProviderClear() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetFrameProviderList() override=default
CommandObjectTargetFrameProviderList(CommandInterpreter &interpreter)
OptionGroupPythonClassWithDict m_class_options
~CommandObjectTargetFrameProviderRegister() override=default
CommandObjectTargetFrameProviderRegister(CommandInterpreter &interpreter)
std::optional< std::string > GetRepeatCommand(Args &current_command_args, uint32_t index) override
Get the command that appropriate for a "repeat" of the current command.
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetFrameProviderRemove() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTargetFrameProviderRemove(CommandInterpreter &interpreter)
~CommandObjectTargetFrameProvider() override=default
CommandObjectTargetFrameProvider(CommandInterpreter &interpreter)
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
CommandObjectTargetHookAdd(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
OptionGroupPythonClassWithDict m_python_class_options
void IOHandlerInputComplete(IOHandler &io_handler, std::string &line) override
Called when a line or lines have been retrieved.
~CommandObjectTargetHookAdd() override=default
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override
CommandObjectTargetHookDelete(CommandInterpreter &interpreter)
~CommandObjectTargetHookDelete() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetHookEnableDisable() override=default
CommandObjectTargetHookEnableDisable(CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax)
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTargetHookList(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetHookList() override=default
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
Modify trigger settings on a hook.
void DoExecute(Args &command, CommandReturnObject &result) override
static uint32_t ParseTriggerName(llvm::StringRef name)
CommandObjectTargetHookModify(CommandInterpreter &interpreter)
~CommandObjectTargetHookModify() override=default
CommandObjectTargetList(CommandInterpreter &interpreter)
void DoExecute(Args &args, CommandReturnObject &result) override
~CommandObjectTargetList() override=default
CommandObjectTargetModulesAdd(CommandInterpreter &interpreter)
void DoExecute(Args &args, CommandReturnObject &result) override
~CommandObjectTargetModulesAdd() override=default
CommandObjectTargetModulesDumpClangAST(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetModulesDumpClangAST() override=default
~CommandObjectTargetModulesDumpClangPCMInfo() override=default
CommandObjectTargetModulesDumpClangPCMInfo(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
~CommandObjectTargetModulesDumpLineTable() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTargetModulesDumpLineTable(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetModulesDumpObjfile() override=default
CommandObjectTargetModulesDumpObjfile(CommandInterpreter &interpreter)
CommandObjectTargetModulesDumpSections(CommandInterpreter &interpreter)
~CommandObjectTargetModulesDumpSections() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
~CommandObjectTargetModulesDumpSeparateDebugInfoFiles() override=default
CommandObjectTargetModulesDumpSeparateDebugInfoFiles(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTargetModulesDumpSymfile(CommandInterpreter &interpreter)
~CommandObjectTargetModulesDumpSymfile() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTargetModulesDumpSymtab(CommandInterpreter &interpreter)
~CommandObjectTargetModulesDumpSymtab() override=default
~CommandObjectTargetModulesDump() override=default
CommandObjectTargetModulesDump(CommandInterpreter &interpreter)
CommandObjectTargetModulesImageSearchPaths(CommandInterpreter &interpreter)
~CommandObjectTargetModulesImageSearchPaths() override=default
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
std::vector< std::pair< char, uint32_t > > FormatWidthCollection
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
CommandObjectTargetModulesList(CommandInterpreter &interpreter)
~CommandObjectTargetModulesList() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
void PrintModule(Target &target, Module *module, int indent, Stream &strm)
void DoExecute(Args &args, CommandReturnObject &result) override
~CommandObjectTargetModulesLoad() override=default
CommandObjectTargetModulesLoad(CommandInterpreter &interpreter)
void OptionParsingStarting(ExecutionContext *execution_context) override
Status OptionParsingFinished(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
bool LookupInModule(CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error)
~CommandObjectTargetModulesLookup() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
bool LookupHere(CommandInterpreter &interpreter, CommandReturnObject &result, bool &syntax_error)
CommandObjectTargetModulesLookup(CommandInterpreter &interpreter)
CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter &interpreter, const char *name, const char *help, const char *syntax, uint32_t flags=0)
~CommandObjectTargetModulesModuleAutoComplete() override=default
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
~CommandObjectTargetModulesSearchPathsAdd() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTargetModulesSearchPathsAdd(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetModulesSearchPathsClear() override=default
CommandObjectTargetModulesSearchPathsClear(CommandInterpreter &interpreter)
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
~CommandObjectTargetModulesSearchPathsInsert() override=default
CommandObjectTargetModulesSearchPathsInsert(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetModulesSearchPathsList() override=default
CommandObjectTargetModulesSearchPathsList(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetModulesSearchPathsQuery() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter &interpreter)
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
CommandObjectTargetModulesShowUnwind(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetModulesShowUnwind() override=default
CommandObjectTargetModulesSourceFileAutoComplete(CommandInterpreter &interpreter, const char *name, const char *help, const char *syntax, uint32_t flags)
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
~CommandObjectTargetModulesSourceFileAutoComplete() override=default
~CommandObjectTargetModules() override=default
const CommandObjectTargetModules & operator=(const CommandObjectTargetModules &)=delete
CommandObjectTargetModules(const CommandObjectTargetModules &)=delete
CommandObjectTargetModules(CommandInterpreter &interpreter)
~CommandObjectTargetSelect() override=default
void DoExecute(Args &args, CommandReturnObject &result) override
CommandObjectTargetSelect(CommandInterpreter &interpreter)
CommandObjectTargetShowLaunchEnvironment(CommandInterpreter &interpreter)
void DoExecute(Args &args, CommandReturnObject &result) override
~CommandObjectTargetShowLaunchEnvironment() override=default
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override
CommandObjectTargetStopHookAdd(CommandInterpreter &interpreter)
void IOHandlerInputComplete(IOHandler &io_handler, std::string &line) override
Called when a line or lines have been retrieved.
~CommandObjectTargetStopHookAdd() override=default
OptionGroupPythonClassWithDict m_python_class_options
void DoExecute(Args &command, CommandReturnObject &result) override
void DoExecute(Args &command, CommandReturnObject &result) override
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
CommandObjectTargetStopHookDelete(CommandInterpreter &interpreter)
~CommandObjectTargetStopHookDelete() override=default
~CommandObjectTargetStopHookEnableDisable() override=default
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTargetStopHookEnableDisable(CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax)
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetStopHookList() override=default
CommandObjectTargetStopHookList(CommandInterpreter &interpreter)
bool AddSymbolsForUUID(CommandReturnObject &result, bool &flush)
bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec, CommandReturnObject &result, bool &flush)
bool AddSymbolsForStack(CommandReturnObject &result, bool &flush)
CommandObjectTargetSymbolsAdd(CommandInterpreter &interpreter)
bool AddSymbolsForFrame(CommandReturnObject &result, bool &flush)
~CommandObjectTargetSymbolsAdd() override=default
void DoExecute(Args &args, CommandReturnObject &result) override
bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush, CommandReturnObject &result)
bool AddSymbolsForFile(CommandReturnObject &result, bool &flush)
const CommandObjectTargetSymbols & operator=(const CommandObjectTargetSymbols &)=delete
CommandObjectTargetSymbols(CommandInterpreter &interpreter)
~CommandObjectTargetSymbols() override=default
CommandObjectTargetSymbols(const CommandObjectTargetSymbols &)=delete
void DumpGlobalVariableList(const ExecutionContext &exe_ctx, const SymbolContext &sc, const VariableList &variable_list, CommandReturnObject &result)
void DumpValueObject(Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp, const char *root_name)
static size_t GetVariableCallback(void *baton, const char *name, VariableList &variable_list)
static const uint32_t SHORT_OPTION_SHLB
CommandObjectTargetVariable(CommandInterpreter &interpreter)
OptionGroupFileList m_option_shared_libraries
void DoExecute(Args &args, CommandReturnObject &result) override
OptionGroupFileList m_option_compile_units
static const uint32_t SHORT_OPTION_FILE
OptionGroupValueObjectDisplay m_varobj_options
~CommandObjectTargetVariable() override=default
~OptionGroupDependents() override=default
OptionGroupDependents()=default
LoadDependentFiles m_load_dependent_files
OptionGroupDependents(const OptionGroupDependents &)=delete
const OptionGroupDependents & operator=(const OptionGroupDependents &)=delete
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t, const char *, ExecutionContext *)=delete
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
virtual lldb::addr_t FixCodeAddress(lldb::addr_t pc)
Some targets might use bits in a code address to indicate a mode switch.
Definition ABI.cpp:141
A section + offset based address class.
Definition Address.h:62
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
Definition Address.cpp:301
bool SetLoadAddress(lldb::addr_t load_addr, Target *target, bool allow_section_end=false)
Set the address to represent load_addr.
Definition Address.cpp:1034
@ DumpStyleFileAddress
Display as the file address (if any).
Definition Address.h:87
@ DumpStyleSectionNameOffset
Display as the section name + offset.
Definition Address.h:74
@ DumpStyleDetailedSymbolContext
Detailed symbol context information for an address for all symbol context members.
Definition Address.h:112
@ DumpStyleInvalid
Invalid dump style.
Definition Address.h:68
@ DumpStyleModuleWithFileAddress
Display as the file address with the module name prepended (if any).
Definition Address.h:93
@ DumpStyleResolvedDescription
Display the details about what an address resolves to.
Definition Address.h:104
bool Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style=DumpStyleInvalid, uint32_t addr_byte_size=UINT32_MAX, bool all_ranges=false, std::optional< Stream::HighlightSettings > settings=std::nullopt) const
Dump a description of this object to a Stream.
Definition Address.cpp:396
lldb::ModuleSP GetModule() const
Get accessor for the module for this address.
Definition Address.cpp:273
lldb::addr_t GetFileAddress() const
Get the file address.
Definition Address.cpp:281
bool IsValid() const
Check if the object state is valid.
Definition Address.h:355
An architecture specification class.
Definition ArchSpec.h:32
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
Definition ArchSpec.cpp:690
bool IsValid() const
Tests if this ArchSpec is valid.
Definition ArchSpec.h:370
void DumpTriple(llvm::raw_ostream &s) const
const char * GetArchitectureName() const
Returns a static string representing the current architecture.
Definition ArchSpec.cpp:557
A command line argument class.
Definition Args.h:33
void Shift()
Shifts the first argument C string value of the array off the argument array.
Definition Args.cpp:295
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
Definition Args.h:120
llvm::ArrayRef< ArgEntry > entries() const
Definition Args.h:132
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx.
Definition Args.cpp:273
static bool InvokeCommonCompletionCallbacks(CommandInterpreter &interpreter, uint32_t completion_mask, lldb_private::CompletionRequest &request, SearchFilter *searcher)
bool Confirm(llvm::StringRef message, bool default_answer)
ExecutionContext GetExecutionContext(bool adopt_dummy_target=true) const
Returns the execution context the interpreter should run a command in.
CommandObjectMultiwordTarget(CommandInterpreter &interpreter)
bool LoadSubCommand(llvm::StringRef cmd_name, const lldb::CommandObjectSP &command_obj) override
CommandObjectMultiword(CommandInterpreter &interpreter, const char *name, const char *help=nullptr, const char *syntax=nullptr, uint32_t flags=0)
CommandObjectParsed(CommandInterpreter &interpreter, const char *name, const char *help=nullptr, const char *syntax=nullptr, uint32_t flags=0)
std::vector< CommandArgumentData > CommandArgumentEntry
virtual void SetHelpLong(llvm::StringRef str)
void AddSimpleArgumentList(lldb::CommandArgumentType arg_type, ArgumentRepetitionType repetition_type=eArgRepeatPlain)
virtual const char * GetInvalidTargetDescription()
std::vector< CommandArgumentEntry > m_arguments
CommandInterpreter & GetCommandInterpreter()
CommandInterpreter & m_interpreter
virtual void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector)
The default version handles argument definitions that have only one argument type,...
Target * GetTarget()
Get the target this command should operate on.
void AppendMessage(llvm::StringRef in_string)
void AppendError(llvm::StringRef in_string)
const ValueObjectList & GetValueObjectList() const
void AppendWarningWithFormatv(const char *format, Args &&...args)
void SetStatus(lldb::ReturnStatus status)
void AppendErrorWithFormat(const char *format,...) __attribute__((format(printf
void void AppendMessageWithFormatv(const char *format, Args &&...args)
void AppendWarning(llvm::StringRef in_string)
void AppendErrorWithFormatv(const char *format, Args &&...args)
A class that describes a compilation unit.
Definition CompileUnit.h:43
lldb::VariableListSP GetVariableList(bool can_create)
Get the variable list for a compile unit.
const FileSpec & GetPrimaryFile() const
Return the primary source spec associated with this compile unit.
"lldb/Utility/ArgCompletionRequest.h"
void TryCompleteCurrentArg(llvm::StringRef completion, llvm::StringRef description="")
Adds a possible completion string if the completion would complete the current argument.
A uniqued constant string class.
Definition ConstString.h:40
void Dump(Stream *s, const char *value_if_empty=nullptr) const
Dump the object description to a stream.
bool IsEmpty() const
Test for empty string.
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
const char * GetCString() const
Get the string value as a C string.
const char * AsCString(const char *value_if_empty) const
Get the string value as a C string.
A class to manage flag bits.
Definition Debugger.h:100
TargetList & GetTargetList()
Get accessor for the target list.
Definition Debugger.h:220
bool GetUseColor() const
Definition Debugger.cpp:522
llvm::StringRef GetRegexMatchAnsiSuffix() const
Definition Debugger.cpp:627
Target & GetDummyTarget()
Definition Debugger.h:536
llvm::StringRef GetRegexMatchAnsiPrefix() const
Definition Debugger.cpp:621
ScriptInterpreter * GetScriptInterpreter(bool can_create=true, std::optional< lldb::ScriptLanguage > language={})
DumpValueObjectOptions & SetRootValueObjectName(const char *name=nullptr)
DumpValueObjectOptions & SetFormat(lldb::Format format=lldb::eFormatDefault)
A class that measures elapsed time in an exception safe way.
Definition Statistics.h:76
"lldb/Target/ExecutionContextScope.h" Inherit from this if your object can reconstruct its execution ...
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
ExecutionContextScope * GetBestExecutionContextScope() const
Target * GetTargetPtr() const
Returns a pointer to the target object.
A file collection class.
const FileSpec & GetFileSpecAtIndex(size_t idx) const
Get file at index.
size_t GetSize() const
Get the number of files in the file list.
A file utility class.
Definition FileSpec.h:57
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
Definition FileSpec.cpp:174
void SetDirectory(ConstString directory)
Directory string set accessor.
Definition FileSpec.cpp:342
const ConstString & GetFilename() const
Filename string const get accessor.
Definition FileSpec.h:250
llvm::StringRef GetFileNameStrippingExtension() const
Return the filename without the extension part.
Definition FileSpec.cpp:410
const ConstString & GetDirectory() const
Directory string const get accessor.
Definition FileSpec.h:234
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition FileSpec.cpp:374
void Dump(llvm::raw_ostream &s) const
Dump this object to a Stream.
Definition FileSpec.cpp:325
llvm::StringRef GetFileNameExtension() const
Extract the extension of the file.
Definition FileSpec.cpp:406
void SetFilename(ConstString filename)
Filename string set accessor.
Definition FileSpec.cpp:352
bool ResolveExecutableLocation(FileSpec &file_spec)
Call into the Host to see if it can help find the file.
bool Exists(const FileSpec &file_spec) const
Returns whether the given file exists.
int Open(const char *path, int flags, int mode=0600)
Wraps open in a platform-independent way.
static FileSystem & Instance()
void Resolve(llvm::SmallVectorImpl< char > &path, bool force_make_absolute=false)
Resolve path to make it canonical.
IOHandlerDelegateMultiline(llvm::StringRef end_line, Completion completion=Completion::None)
Definition IOHandler.h:289
A delegate class for use with IOHandler subclasses.
Definition IOHandler.h:184
lldb::LockableStreamFileSP GetErrorStreamFileSP()
Definition IOHandler.cpp:95
lldb::LockableStreamFileSP GetOutputStreamFileSP()
Definition IOHandler.cpp:93
void SetIsDone(bool b)
Definition IOHandler.h:81
A line table class.
Definition LineTable.h:25
void GetDescription(Stream *s, Target *target, lldb::DescriptionLevel level)
A collection class for Module objects.
Definition ModuleList.h:125
void FindFunctions(ConstString name, lldb::FunctionNameType name_type_mask, const ModuleFunctionSearchOptions &options, SymbolContextList &sc_list) const
ModuleIterableNoLocking ModulesNoLocking() const
Definition ModuleList.h:576
static bool ModuleIsInCache(const Module *module_ptr)
void FindGlobalVariables(ConstString name, size_t max_matches, VariableList &variable_list) const
Find global and static variables by name.
std::recursive_mutex & GetMutex() const
Definition ModuleList.h:252
lldb::ModuleSP FindFirstModule(const ModuleSpec &module_spec) const
Finds the first module whose file specification matches module_spec.
lldb::ModuleSP GetModuleAtIndexUnlocked(size_t idx) const
Get the module shared pointer for the module at index idx without acquiring the ModuleList mutex.
void FindCompileUnits(const FileSpec &path, SymbolContextList &sc_list) const
Find compile units by partial or full path.
bool AppendIfNeeded(const lldb::ModuleSP &new_module, bool notify=true)
Append a module to the module list, if it is not already there.
Module * GetModulePointerAtIndex(size_t idx) const
Get the module pointer for the module at index idx.
void FindModules(const ModuleSpec &module_spec, ModuleList &matching_module_list) const
Finds modules whose file specification matches module_spec.
lldb::ModuleSP GetModuleAtIndex(size_t idx) const
Get the module shared pointer for the module at index idx.
void Append(const lldb::ModuleSP &module_sp, bool notify=true)
Append a module to the module list.
static size_t RemoveOrphanSharedModules(bool mandatory)
static void FindSharedModules(const ModuleSpec &module_spec, ModuleList &matching_module_list)
bool LoadScriptingResourcesInTarget(Target *target, std::list< Status > &errors, bool continue_on_error=true)
ModuleIterable Modules() const
Definition ModuleList.h:570
size_t GetSize() const
Gets the size of the module list.
bool GetModuleSpecAtIndex(size_t i, ModuleSpec &module_spec) const
Definition ModuleSpec.h:356
bool FindMatchingModuleSpec(const ModuleSpec &module_spec, ModuleSpec &match_module_spec) const
Definition ModuleSpec.h:366
FileSpec & GetPlatformFileSpec()
Definition ModuleSpec.h:69
FileSpec & GetFileSpec()
Definition ModuleSpec.h:57
ArchSpec & GetArchitecture()
Definition ModuleSpec.h:93
FileSpec * GetFileSpecPtr()
Definition ModuleSpec.h:51
FileSpec & GetSymbolFileSpec()
Definition ModuleSpec.h:81
A class that describes an executable image and its associated object and symbol files.
Definition Module.h:91
const lldb_private::UUID & GetUUID()
Get a reference to the UUID value contained in this object.
Definition Module.cpp:341
virtual SymbolFile * GetSymbolFile(bool can_create=true, Stream *feedback_strm=nullptr)
Get the module's symbol file.
Definition Module.cpp:977
static Module * GetAllocatedModuleAtIndex(size_t idx)
Definition Module.cpp:124
static std::recursive_mutex & GetAllocationModuleCollectionMutex()
Definition Module.cpp:106
bool ResolveFileAddress(lldb::addr_t vm_addr, Address &so_addr)
Definition Module.cpp:425
Symtab * GetSymtab(bool can_create=true)
Get the module's symbol table.
Definition Module.cpp:1004
bool MatchesModuleSpec(const ModuleSpec &module_ref)
Definition Module.cpp:1456
static size_t GetNumberAllocatedModules()
Definition Module.cpp:118
const ArchSpec & GetArchitecture() const
Get const accessor for the module architecture.
Definition Module.cpp:1019
std::string GetSpecificationDescription() const
Get the module path and object name.
Definition Module.cpp:1021
const FileSpec & GetFileSpec() const
Get const accessor for the module file specification.
Definition Module.h:447
const llvm::sys::TimePoint & GetModificationTime() const
Definition Module.h:485
A plug-in interface definition class for object file parsers.
Definition ObjectFile.h:46
virtual void Dump(Stream *s)=0
Dump a description of this object to a Stream.
virtual std::vector< LoadableData > GetLoadableData(Target &target)
Loads this objfile to memory.
virtual lldb_private::Address GetEntryPointAddress()
Returns the address of the Entry Point in this object file - if the object file doesn't have an entry...
Definition ObjectFile.h:452
virtual FileSpec & GetFileSpec()
Get accessor to the object file specification.
Definition ObjectFile.h:280
static ModuleSpecList GetModuleSpecifications(const FileSpec &file, lldb::offset_t file_offset, lldb::offset_t file_size, lldb::DataExtractorSP=lldb::DataExtractorSP())
virtual lldb_private::Address GetBaseAddress()
Returns base address of this object file.
Definition ObjectFile.h:462
static const uint32_t OPTION_GROUP_GDB_FMT
static const uint32_t OPTION_GROUP_FORMAT
A command line option parsing protocol class.
Definition Options.h:58
std::vector< Option > m_getopt_table
Definition Options.h:198
void Insert(llvm::StringRef path, llvm::StringRef replacement, uint32_t insert_idx, bool notify)
void Append(llvm::StringRef path, llvm::StringRef replacement, bool notify)
bool RemapPath(ConstString path, ConstString &new_path) const
bool GetPathsAtIndex(uint32_t idx, ConstString &path, ConstString &new_path) const
void Dump(Stream *s, int pair_index=-1)
static bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec, Status &error, bool force_lookup=true, bool copy_executable=true)
void SetExecutableFile(const FileSpec &exe_file, bool add_exe_file_as_first_arg)
A plug-in interface definition class for debugging a process.
Definition Process.h:357
ThreadList & GetThreadList()
Definition Process.h:2381
void Flush()
Flush all data in the process.
Definition Process.cpp:6163
lldb::StateType GetState()
Get accessor for the current process state.
Definition Process.cpp:1279
const lldb::ABISP & GetABI()
Definition Process.cpp:1483
bool IsValid() const
Test if this object contains a valid regular expression.
virtual lldb::ScriptedFrameProviderInterfaceSP CreateScriptedFrameProviderInterface()
lldb::SectionSP FindSectionByName(ConstString section_dstr) const
Definition Section.cpp:559
void Dump(llvm::raw_ostream &s, unsigned indent, Target *target, bool show_header, uint32_t depth) const
Definition Section.cpp:645
This base class provides an interface to stack frames.
Definition StackFrame.h:44
virtual const SymbolContext & GetSymbolContext(lldb::SymbolContextItem resolve_scope)
Provide a SymbolContext for this StackFrame's current pc value.
virtual uint32_t GetFrameIndex() const
Query this frame to find what frame it is in this Thread's StackFrameList.
An error handling class.
Definition Status.h:118
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Definition Status.cpp:106
static Status FromErrorString(const char *str)
Definition Status.h:141
bool Fail() const
Test for error condition.
Definition Status.cpp:293
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition Status.cpp:194
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
Definition Status.h:151
const char * GetData() const
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
Definition Stream.h:28
void Format(const char *format, Args &&... args)
Forwards the arguments to llvm::formatv and writes to the stream.
Definition Stream.h:370
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
Definition Stream.h:405
size_t Indent(llvm::StringRef s="")
Indent the current line in the stream.
Definition Stream.cpp:157
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition Stream.cpp:134
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition Stream.cpp:63
size_t PutChar(char ch)
Definition Stream.cpp:131
void SetIndentLevel(unsigned level)
Set the current indentation level.
Definition Stream.cpp:196
void PutCStringColorHighlighted(llvm::StringRef text, std::optional< HighlightSettings > settings=std::nullopt)
Output a C string to the stream with color highlighting.
Definition Stream.cpp:73
size_t EOL()
Output and End of Line character to the stream.
Definition Stream.cpp:155
void IndentLess(unsigned amount=2)
Decrement the current indentation level.
Definition Stream.cpp:204
void IndentMore(unsigned amount=2)
Increment the current indentation level.
Definition Stream.cpp:201
unsigned GetIndentLevel() const
Get the current indentation level.
Definition Stream.cpp:193
void AddItem(const ObjectSP &item)
bool ForEach(std::function< bool(Object *object)> const &foreach_callback) const
bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const
bool GetValueForKeyAsString(llvm::StringRef key, llvm::StringRef &result) const
bool GetValueForKeyAsArray(llvm::StringRef key, Array *&result) const
void Dump(lldb_private::Stream &s, bool pretty_print=true) const
Defines a list of symbol context objects.
uint32_t GetSize() const
Get accessor for a symbol context list size.
void Append(const SymbolContext &sc)
Append a new symbol context to the list.
Defines a symbol context baton that can be handed other debug core functions.
Function * function
The Function for a given query.
void SortTypeList(TypeMap &type_map, TypeList &type_list) const
Sorts the types in TypeMap according to SymbolContext to TypeList.
lldb::ModuleSP module_sp
The Module for a given query.
CompileUnit * comp_unit
The CompileUnit for a given query.
Symbol * symbol
The Symbol for a given query.
Provides public interface for all SymbolFiles.
Definition SymbolFile.h:51
virtual ObjectFile * GetObjectFile()=0
bool ValueIsAddress() const
Definition Symbol.cpp:165
bool GetByteSizeIsValid() const
Definition Symbol.h:209
Address & GetAddressRef()
Definition Symbol.h:73
lldb::addr_t GetByteSize() const
Definition Symbol.cpp:431
ConstString GetDisplayName() const
Definition Symbol.cpp:169
uint64_t GetRawValue() const
Get the raw value of the symbol from the symbol table.
Definition Symbol.h:110
Symbol * SymbolAtIndex(size_t idx)
Definition Symtab.cpp:225
uint32_t AppendSymbolIndexesWithName(ConstString symbol_name, std::vector< uint32_t > &matches)
Definition Symtab.cpp:679
uint32_t AppendSymbolIndexesMatchingRegExAndType(const RegularExpression &regex, lldb::SymbolType symbol_type, std::vector< uint32_t > &indexes, Mangled::NamePreference name_preference=Mangled::ePreferDemangled)
Definition Symtab.cpp:746
lldb::TargetSP GetTargetAtIndex(uint32_t index) const
Status CreateTarget(Debugger &debugger, llvm::StringRef user_exe_path, llvm::StringRef triple_str, LoadDependentFiles get_dependent_modules, const OptionGroupPlatform *platform_options, lldb::TargetSP &target_sp)
Create a new Target.
void SetSelectedTarget(uint32_t index)
bool DeleteTarget(lldb::TargetSP &target_sp)
Delete a Target object from the list.
lldb::TargetSP GetSelectedTarget()
size_t GetNumTargets() const
bool GetUserSpecifiedTrapHandlerNames(Args &args) const
Definition Target.cpp:5707
Environment GetEnvironment() const
Definition Target.cpp:5355
void SetActionFromStrings(const std::vector< std::string > &strings)
Populate the command list from a vector of individual command strings.
Definition Target.cpp:4518
void SetActionFromString(const std::string &strings)
Definition Target.cpp:4239
void SetActionFromStrings(const std::vector< std::string > &strings)
Definition Target.cpp:4243
Status SetScriptCallback(const ScriptedMetadata &scripted_metadata)
Definition Target.cpp:4284
void ModulesDidLoad(ModuleList &module_list)
This call may preload module symbols, and may do so in parallel depending on the following target set...
Definition Target.cpp:1909
llvm::Expected< uint32_t > AddScriptedFrameProviderDescriptor(const ScriptedFrameProviderDescriptor &descriptor)
Add or update a scripted frame provider descriptor for this target.
Definition Target.cpp:3849
Module * GetExecutableModulePointer()
Definition Target.cpp:1609
bool RemoveHookByID(lldb::user_id_t uid)
Definition Target.cpp:4745
PathMappingList & GetImageSearchPathList()
Definition Target.cpp:2659
size_t GetNumHooks() const
Definition Target.h:1929
std::shared_ptr< StopHook > StopHookSP
Definition Target.h:1739
void SymbolsDidLoad(ModuleList &module_list)
Definition Target.cpp:1937
const std::vector< StopHookSP > GetStopHooks(bool internal=false) const
Definition Target.cpp:3187
const llvm::MapVector< uint32_t, ScriptedFrameProviderDescriptor > & GetScriptedFrameProviderDescriptors() const
Get all scripted frame provider descriptors for this target.
Definition Target.cpp:3910
bool RemoveScriptedFrameProviderDescriptor(uint32_t id)
Remove a scripted frame provider descriptor by id.
Definition Target.cpp:3885
HookSP CreateHook(Hook::HookKind kind)
Definition Target.cpp:4723
void DumpSectionLoadList(Stream &s)
Definition Target.cpp:5987
bool SetHookEnabledStateByID(lldb::user_id_t uid, bool enabled)
Definition Target.cpp:4767
const lldb::ProcessSP & GetProcessSP() const
Definition Target.cpp:328
lldb::ModuleSP GetOrCreateModule(const ModuleSpec &module_spec, bool notify, Status *error_ptr=nullptr)
Find a binary on the system and return its Module, or return an existing Module that is already in th...
Definition Target.cpp:2409
void UndoCreateStopHook(lldb::user_id_t uid)
If you tried to create a stop hook, and that failed, call this to remove the stop hook,...
Definition Target.cpp:3139
bool ResolveLoadAddress(lldb::addr_t load_addr, Address &so_addr, uint32_t stop_id=SectionLoadHistory::eStopIDNow, bool allow_section_end=false)
Definition Target.cpp:3449
HookSP GetHookByID(lldb::user_id_t uid)
Definition Target.cpp:4752
bool SetStopHookActiveStateByID(lldb::user_id_t uid, bool active_state)
Definition Target.cpp:3163
void SetAllStopHooksActiveState(bool active_state)
Definition Target.cpp:3174
StopHookSP CreateStopHook(StopHook::StopHookKind kind, bool internal=false)
Add an empty stop hook to the Target's stop hook list, and returns a shared pointer to the new hook.
Definition Target.cpp:3117
void SetAllHooksEnabledState(bool enabled)
Definition Target.cpp:4775
void UndoCreateHook(lldb::user_id_t uid)
Removes the most recently created hook.
Definition Target.cpp:4738
HookSP GetHookAtIndex(size_t index)
Definition Target.cpp:4759
lldb::PlatformSP GetPlatform()
Definition Target.h:1969
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition Target.h:1241
const ArchSpec & GetArchitecture() const
Definition Target.h:1283
bool IsDummyTarget() const
Definition Target.h:671
const std::string & GetLabel() const
Definition Target.h:684
void ClearScriptedFrameProviderDescriptors()
Clear all scripted frame provider descriptors for this target.
Definition Target.cpp:3898
std::shared_ptr< Hook > HookSP
Definition Target.h:1910
lldb::ProcessSP CalculateProcess() override
Definition Target.cpp:2648
bool SetSectionLoadAddress(const lldb::SectionSP &section, lldb::addr_t load_addr, bool warn_multiple=false)
Definition Target.cpp:3460
bool RemoveStopHookByID(lldb::user_id_t uid)
Definition Target.cpp:3146
lldb::ThreadSP GetSelectedThread()
uint32_t GetSize(bool can_update=true)
lldb::ThreadSP GetThreadAtIndex(uint32_t idx, bool can_update=true)
void SetIndex(uint32_t index)
Definition ThreadSpec.h:47
void SetName(llvm::StringRef name)
Definition ThreadSpec.h:51
void SetTID(lldb::tid_t tid)
Definition ThreadSpec.h:49
void SetQueueName(llvm::StringRef queue_name)
Definition ThreadSpec.h:53
uint32_t GetSize() const
Definition TypeList.cpp:36
bool Empty() const
Definition TypeList.h:35
TypeIterable Types()
Definition TypeList.h:42
lldb::TypeSP GetTypeAtIndex(uint32_t idx)
Definition TypeList.cpp:42
A class that contains all state required for type lookups.
Definition Type.h:104
This class tracks the state and results of a TypeQuery.
Definition Type.h:344
TypeMap & GetTypeMap()
Definition Type.h:386
void Dump(Stream &s) const
Definition UUID.cpp:68
std::string GetAsString(llvm::StringRef separator="-") const
Definition UUID.cpp:54
bool IsValid() const
Definition UUID.h:69
lldb::FuncUnwindersSP GetFuncUnwindersContainingAddress(const Address &addr, const SymbolContext &sc)
lldb::FuncUnwindersSP GetUncachedFuncUnwindersContainingAddress(const Address &addr, const SymbolContext &sc)
A collection of ValueObject values that.
void Append(const lldb::ValueObjectSP &val_obj_sp)
lldb::ValueObjectSP GetValueObjectAtIndex(size_t idx)
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, const lldb::VariableSP &var_sp)
lldb::VariableSP GetVariableAtIndex(size_t idx) const
static Status GetValuesForVariableExpressionPath(llvm::StringRef variable_expr_path, ExecutionContextScope *scope, GetVariableCallback callback, void *baton, VariableList &variable_list, ValueObjectList &valobj_list)
Definition Variable.cpp:335
#define LLDB_OPT_SET_1
#define LLDB_OPT_SET_FROM_TO(A, B)
#define LLDB_OPT_SET_2
#define LLDB_INVALID_LINE_NUMBER
#define LLDB_INVALID_THREAD_ID
#define LLDB_INVALID_INDEX32
#define LLDB_OPT_SET_ALL
#define LLDB_INVALID_ADDRESS
#define UINT32_MAX
#define LLDB_INVALID_PROCESS_ID
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:327
std::vector< OptionArgElement > OptionElementVector
Definition Options.h:43
bool StateIsStoppedState(lldb::StateType state, bool must_exist)
Check if a state represents a state where the process or thread is stopped.
Definition State.cpp:89
void DumpAddress(llvm::raw_ostream &s, uint64_t addr, uint32_t addr_size, const char *prefix=nullptr, const char *suffix=nullptr)
Output an address value to this stream.
Definition Stream.cpp:108
const char * StateAsCString(lldb::StateType state)
Converts a StateType to a C string.
Definition State.cpp:14
std::string toString(FormatterBytecode::OpCodes op)
@ eSourceFileCompletion
std::shared_ptr< lldb_private::TypeSystem > TypeSystemSP
std::shared_ptr< lldb_private::ABI > ABISP
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
DescriptionLevel
Description levels for "void GetDescription(Stream *, DescriptionLevel)" calls.
@ eDescriptionLevelBrief
@ eDescriptionLevelFull
std::shared_ptr< lldb_private::Thread > ThreadSP
std::shared_ptr< lldb_private::ScriptedMetadata > ScriptedMetadataSP
std::shared_ptr< lldb_private::CommandObject > CommandObjectSP
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
Format
Display format definitions.
std::shared_ptr< lldb_private::Platform > PlatformSP
StateType
Process and Thread States.
std::shared_ptr< lldb_private::FuncUnwinders > FuncUnwindersSP
std::shared_ptr< lldb_private::Type > TypeSP
std::shared_ptr< lldb_private::Process > ProcessSP
@ eReturnStatusFailed
@ eReturnStatusSuccessFinishResult
@ eReturnStatusSuccessFinishNoResult
uint64_t pid_t
Definition lldb-types.h:83
@ eArgTypeOldPathPrefix
@ eArgTypeNewPathPrefix
@ eArgTypeUnsignedInteger
@ eArgTypeDirectoryName
std::shared_ptr< lldb_private::VariableList > VariableListSP
std::shared_ptr< lldb_private::UnwindPlan > UnwindPlanSP
std::shared_ptr< lldb_private::Variable > VariableSP
std::shared_ptr< lldb_private::ScriptedFrameProviderInterface > ScriptedFrameProviderInterfaceSP
@ eValueTypeVariableGlobal
globals variable
@ eValueTypeVariableLocal
function local variables
@ eValueTypeVariableArgument
function argument variables
@ eValueTypeVariableStatic
static variable
@ eValueTypeVariableThreadLocal
thread local storage variable
uint64_t user_id_t
Definition lldb-types.h:82
std::shared_ptr< lldb_private::LockableStreamFile > LockableStreamFileSP
std::shared_ptr< lldb_private::Section > SectionSP
uint64_t addr_t
Definition lldb-types.h:80
std::shared_ptr< lldb_private::Target > TargetSP
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
uint64_t tid_t
Definition lldb-types.h:84
std::shared_ptr< lldb_private::Module > ModuleSP
Used to build individual command argument lists.
Options used by Module::FindFunctions.
Definition Module.h:67
bool include_inlines
Include inlined functions.
Definition Module.h:71
bool include_symbols
Include the symbol table.
Definition Module.h:69
static int64_t ToOptionEnum(llvm::StringRef s, const OptionEnumValues &enum_values, int32_t fail_value, Status &error)
static lldb::addr_t ToAddress(const ExecutionContext *exe_ctx, llvm::StringRef s, lldb::addr_t fail_value, Status *error_ptr)
Try to parse an address.
static bool ToBoolean(llvm::StringRef s, bool fail_value, bool *success_ptr)
This struct contains the metadata needed to instantiate a frame provider and optional filters to cont...
void Dump(Stream *s) const
Dump a description of this descriptor to the given stream.
lldb::ScriptedFrameProviderInterfaceSP interface_sp
Interface for calling static methods on the provider class.
Struct to store information for color highlighting in the stream.
Definition Stream.h:37
#define PATH_MAX