1 //===-- CommandObjectTarget.cpp ---------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #include "CommandObjectTarget.h"
11 #include "lldb/Core/Debugger.h"
12 #include "lldb/Core/IOHandler.h"
13 #include "lldb/Core/Module.h"
14 #include "lldb/Core/ModuleSpec.h"
15 #include "lldb/Core/Section.h"
16 #include "lldb/Core/ValueObjectVariable.h"
17 #include "lldb/DataFormatters/ValueObjectPrinter.h"
18 #include "lldb/Host/OptionParser.h"
19 #include "lldb/Host/StringConvert.h"
20 #include "lldb/Interpreter/CommandInterpreter.h"
21 #include "lldb/Interpreter/CommandReturnObject.h"
22 #include "lldb/Interpreter/OptionArgParser.h"
23 #include "lldb/Interpreter/OptionGroupArchitecture.h"
24 #include "lldb/Interpreter/OptionGroupBoolean.h"
25 #include "lldb/Interpreter/OptionGroupFile.h"
26 #include "lldb/Interpreter/OptionGroupFormat.h"
27 #include "lldb/Interpreter/OptionGroupPlatform.h"
28 #include "lldb/Interpreter/OptionGroupString.h"
29 #include "lldb/Interpreter/OptionGroupUInt64.h"
30 #include "lldb/Interpreter/OptionGroupUUID.h"
31 #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
32 #include "lldb/Interpreter/OptionGroupVariable.h"
33 #include "lldb/Interpreter/Options.h"
34 #include "lldb/Symbol/CompileUnit.h"
35 #include "lldb/Symbol/FuncUnwinders.h"
36 #include "lldb/Symbol/LineTable.h"
37 #include "lldb/Symbol/LocateSymbolFile.h"
38 #include "lldb/Symbol/ObjectFile.h"
39 #include "lldb/Symbol/SymbolFile.h"
40 #include "lldb/Symbol/SymbolVendor.h"
41 #include "lldb/Symbol/UnwindPlan.h"
42 #include "lldb/Symbol/VariableList.h"
43 #include "lldb/Target/ABI.h"
44 #include "lldb/Target/Process.h"
45 #include "lldb/Target/RegisterContext.h"
46 #include "lldb/Target/SectionLoadList.h"
47 #include "lldb/Target/StackFrame.h"
48 #include "lldb/Target/Thread.h"
49 #include "lldb/Target/ThreadSpec.h"
50 #include "lldb/Utility/Args.h"
51 #include "lldb/Utility/State.h"
52 #include "lldb/Utility/Timer.h"
54 #include "llvm/Support/FileSystem.h"
55 #include "llvm/Support/FormatAdapters.h"
60 using namespace lldb_private;
62 static void DumpTargetInfo(uint32_t target_idx, Target *target,
63 const char *prefix_cstr,
64 bool show_stopped_process_status, Stream &strm) {
65 const ArchSpec &target_arch = target->GetArchitecture();
67 Module *exe_module = target->GetExecutableModulePointer();
68 char exe_path[PATH_MAX];
69 bool exe_valid = false;
71 exe_valid = exe_module->GetFileSpec().GetPath(exe_path, sizeof(exe_path));
74 ::strcpy(exe_path, "<none>");
76 strm.Printf("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx,
79 uint32_t properties = 0;
80 if (target_arch.IsValid()) {
81 strm.Printf("%sarch=", properties++ > 0 ? ", " : " ( ");
82 target_arch.DumpTriple(strm);
85 PlatformSP platform_sp(target->GetPlatform());
87 strm.Printf("%splatform=%s", properties++ > 0 ? ", " : " ( ",
88 platform_sp->GetName().GetCString());
90 ProcessSP process_sp(target->GetProcessSP());
91 bool show_process_status = false;
93 lldb::pid_t pid = process_sp->GetID();
94 StateType state = process_sp->GetState();
95 if (show_stopped_process_status)
96 show_process_status = StateIsStoppedState(state, true);
97 const char *state_cstr = StateAsCString(state);
98 if (pid != LLDB_INVALID_PROCESS_ID)
99 strm.Printf("%spid=%" PRIu64, properties++ > 0 ? ", " : " ( ", pid);
100 strm.Printf("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
103 strm.PutCString(" )\n");
106 if (show_process_status) {
107 const bool only_threads_with_stop_reason = true;
108 const uint32_t start_frame = 0;
109 const uint32_t num_frames = 1;
110 const uint32_t num_frames_with_source = 1;
111 const bool stop_format = false;
112 process_sp->GetStatus(strm);
113 process_sp->GetThreadStatus(strm, only_threads_with_stop_reason,
114 start_frame, num_frames,
115 num_frames_with_source, stop_format);
119 static uint32_t DumpTargetList(TargetList &target_list,
120 bool show_stopped_process_status, Stream &strm) {
121 const uint32_t num_targets = target_list.GetNumTargets();
123 TargetSP selected_target_sp(target_list.GetSelectedTarget());
124 strm.PutCString("Current targets:\n");
125 for (uint32_t i = 0; i < num_targets; ++i) {
126 TargetSP target_sp(target_list.GetTargetAtIndex(i));
128 bool is_selected = target_sp.get() == selected_target_sp.get();
129 DumpTargetInfo(i, target_sp.get(), is_selected ? "* " : " ",
130 show_stopped_process_status, strm);
137 // Note that the negation in the argument name causes a slightly confusing
138 // mapping of the enum values,
139 static constexpr OptionEnumValueElement g_dependents_enumaration[] = {
140 {eLoadDependentsDefault, "default",
141 "Only load dependents when the target is an executable."},
142 {eLoadDependentsNo, "true",
143 "Don't load dependents, even if the target is an executable."},
144 {eLoadDependentsYes, "false",
145 "Load dependents, even if the target is not an executable."}};
147 static constexpr OptionDefinition g_dependents_options[] = {
148 {LLDB_OPT_SET_1, false, "no-dependents", 'd',
149 OptionParser::eOptionalArgument, nullptr,
150 OptionEnumValues(g_dependents_enumaration), 0, eArgTypeValue,
151 "Whether or not to load dependents when creating a target. If the option "
152 "is not specified, the value is implicitly 'default'. If the option is "
153 "specified but without a value, the value is implicitly 'true'."}};
155 class OptionGroupDependents : public OptionGroup {
157 OptionGroupDependents() {}
159 ~OptionGroupDependents() override {}
161 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
162 return llvm::makeArrayRef(g_dependents_options);
165 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
166 ExecutionContext *execution_context) override {
169 // For compatibility no value means don't load dependents.
170 if (option_value.empty()) {
171 m_load_dependent_files = eLoadDependentsNo;
175 const char short_option = g_dependents_options[option_idx].short_option;
176 if (short_option == 'd') {
177 LoadDependentFiles tmp_load_dependents;
178 tmp_load_dependents = (LoadDependentFiles)OptionArgParser::ToOptionEnum(
179 option_value, g_dependents_options[option_idx].enum_values, 0, error);
181 m_load_dependent_files = tmp_load_dependents;
183 error.SetErrorStringWithFormat("unrecognized short option '%c'",
190 Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete;
192 void OptionParsingStarting(ExecutionContext *execution_context) override {
193 m_load_dependent_files = eLoadDependentsDefault;
196 LoadDependentFiles m_load_dependent_files;
199 DISALLOW_COPY_AND_ASSIGN(OptionGroupDependents);
202 #pragma mark CommandObjectTargetCreate
206 class CommandObjectTargetCreate : public CommandObjectParsed {
208 CommandObjectTargetCreate(CommandInterpreter &interpreter)
209 : CommandObjectParsed(
210 interpreter, "target create",
211 "Create a target using the argument as the main executable.",
213 m_option_group(), m_arch_option(),
214 m_core_file(LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename,
215 "Fullpath to a core file to use for this target."),
216 m_platform_path(LLDB_OPT_SET_1, false, "platform-path", 'P', 0,
218 "Path to the remote file to use for this target."),
219 m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
221 "Fullpath to a stand alone debug "
222 "symbols file for when debug symbols "
223 "are not in the executable."),
225 LLDB_OPT_SET_1, false, "remote-file", 'r', 0, eArgTypeFilename,
226 "Fullpath to the file on the remote host if debugging remotely."),
228 CommandArgumentEntry arg;
229 CommandArgumentData file_arg;
231 // Define the first (and only) variant of this arg.
232 file_arg.arg_type = eArgTypeFilename;
233 file_arg.arg_repetition = eArgRepeatPlain;
235 // There is only one variant this argument could be; put it into the
237 arg.push_back(file_arg);
239 // Push the data for the first argument into the m_arguments vector.
240 m_arguments.push_back(arg);
242 m_option_group.Append(&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
243 m_option_group.Append(&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
244 m_option_group.Append(&m_platform_path, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
245 m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
246 m_option_group.Append(&m_remote_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
247 m_option_group.Append(&m_add_dependents, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
248 m_option_group.Finalize();
251 ~CommandObjectTargetCreate() override = default;
253 Options *GetOptions() override { return &m_option_group; }
255 int HandleArgumentCompletion(
256 CompletionRequest &request,
257 OptionElementVector &opt_element_vector) override {
258 CommandCompletions::InvokeCommonCompletionCallbacks(
259 GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
261 return request.GetNumberOfMatches();
265 bool DoExecute(Args &command, CommandReturnObject &result) override {
266 const size_t argc = command.GetArgumentCount();
267 FileSpec core_file(m_core_file.GetOptionValue().GetCurrentValue());
268 FileSpec remote_file(m_remote_file.GetOptionValue().GetCurrentValue());
271 if (!FileSystem::Instance().Exists(core_file)) {
272 result.AppendErrorWithFormat("core file '%s' doesn't exist",
273 core_file.GetPath().c_str());
274 result.SetStatus(eReturnStatusFailed);
277 if (!FileSystem::Instance().Readable(core_file)) {
278 result.AppendErrorWithFormat("core file '%s' is not readable",
279 core_file.GetPath().c_str());
280 result.SetStatus(eReturnStatusFailed);
285 if (argc == 1 || core_file || remote_file) {
286 FileSpec symfile(m_symbol_file.GetOptionValue().GetCurrentValue());
288 if (FileSystem::Instance().Exists(symfile)) {
289 if (!FileSystem::Instance().Readable(symfile)) {
290 result.AppendErrorWithFormat("symbol file '%s' is not readable",
291 symfile.GetPath().c_str());
292 result.SetStatus(eReturnStatusFailed);
296 char symfile_path[PATH_MAX];
297 symfile.GetPath(symfile_path, sizeof(symfile_path));
298 result.AppendErrorWithFormat("invalid symbol file path '%s'",
300 result.SetStatus(eReturnStatusFailed);
305 const char *file_path = command.GetArgumentAtIndex(0);
306 static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
307 Timer scoped_timer(func_cat, "(lldb) target create '%s'", file_path);
311 file_spec.SetFile(file_path, FileSpec::Style::native);
312 FileSystem::Instance().Resolve(file_spec);
315 bool must_set_platform_path = false;
317 Debugger &debugger = GetDebugger();
320 llvm::StringRef arch_cstr = m_arch_option.GetArchitectureName();
321 Status error(debugger.GetTargetList().CreateTarget(
322 debugger, file_path, arch_cstr,
323 m_add_dependents.m_load_dependent_files, nullptr, target_sp));
326 // Only get the platform after we create the target because we might
327 // have switched platforms depending on what the arguments were to
328 // CreateTarget() we can't rely on the selected platform.
330 PlatformSP platform_sp = target_sp->GetPlatform();
334 // I have a remote file.. two possible cases
335 if (file_spec && FileSystem::Instance().Exists(file_spec)) {
336 // if the remote file does not exist, push it there
337 if (!platform_sp->GetFileExists(remote_file)) {
338 Status err = platform_sp->PutFile(file_spec, remote_file);
340 result.AppendError(err.AsCString());
341 result.SetStatus(eReturnStatusFailed);
346 // there is no local file and we need one
347 // in order to make the remote ---> local transfer we need a
349 // TODO: if the user has passed in a --platform argument, use it
350 // to fetch the right platform
353 "unable to perform remote debugging without a platform");
354 result.SetStatus(eReturnStatusFailed);
358 // copy the remote file to the local file
359 Status err = platform_sp->GetFile(remote_file, file_spec);
361 result.AppendError(err.AsCString());
362 result.SetStatus(eReturnStatusFailed);
366 // make up a local file
367 result.AppendError("remote --> local transfer without local "
368 "path is not implemented yet");
369 result.SetStatus(eReturnStatusFailed);
374 result.AppendError("no platform found for target");
375 result.SetStatus(eReturnStatusFailed);
380 if (symfile || remote_file) {
381 ModuleSP module_sp(target_sp->GetExecutableModule());
384 module_sp->SetSymbolFileFileSpec(symfile);
386 std::string remote_path = remote_file.GetPath();
387 target_sp->SetArg0(remote_path.c_str());
388 module_sp->SetPlatformFileSpec(remote_file);
393 debugger.GetTargetList().SetSelectedTarget(target_sp.get());
394 if (must_set_platform_path) {
395 ModuleSpec main_module_spec(file_spec);
396 ModuleSP module_sp = target_sp->GetOrCreateModule(main_module_spec,
399 module_sp->SetPlatformFileSpec(remote_file);
402 char core_path[PATH_MAX];
403 core_file.GetPath(core_path, sizeof(core_path));
404 if (FileSystem::Instance().Exists(core_file)) {
405 if (!FileSystem::Instance().Readable(core_file)) {
406 result.AppendMessageWithFormat(
407 "Core file '%s' is not readable.\n", core_path);
408 result.SetStatus(eReturnStatusFailed);
411 FileSpec core_file_dir;
412 core_file_dir.GetDirectory() = core_file.GetDirectory();
413 target_sp->AppendExecutableSearchPaths(core_file_dir);
415 ProcessSP process_sp(target_sp->CreateProcess(
416 GetDebugger().GetListener(), llvm::StringRef(), &core_file));
419 // Seems weird that we Launch a core file, but that is what we
421 error = process_sp->LoadCore();
425 error.AsCString("can't find plug-in for core file"));
426 result.SetStatus(eReturnStatusFailed);
429 result.AppendMessageWithFormat(
430 "Core file '%s' (%s) was loaded.\n", core_path,
431 target_sp->GetArchitecture().GetArchitectureName());
432 result.SetStatus(eReturnStatusSuccessFinishNoResult);
435 result.AppendErrorWithFormat(
436 "Unable to find process plug-in for core file '%s'\n",
438 result.SetStatus(eReturnStatusFailed);
441 result.AppendErrorWithFormat("Core file '%s' does not exist\n",
443 result.SetStatus(eReturnStatusFailed);
446 result.AppendMessageWithFormat(
447 "Current executable set to '%s' (%s).\n", file_path,
448 target_sp->GetArchitecture().GetArchitectureName());
449 result.SetStatus(eReturnStatusSuccessFinishNoResult);
452 result.AppendError(error.AsCString());
453 result.SetStatus(eReturnStatusFailed);
456 result.AppendErrorWithFormat("'%s' takes exactly one executable path "
457 "argument, or use the --core option.\n",
459 result.SetStatus(eReturnStatusFailed);
461 return result.Succeeded();
465 OptionGroupOptions m_option_group;
466 OptionGroupArchitecture m_arch_option;
467 OptionGroupFile m_core_file;
468 OptionGroupFile m_platform_path;
469 OptionGroupFile m_symbol_file;
470 OptionGroupFile m_remote_file;
471 OptionGroupDependents m_add_dependents;
474 #pragma mark CommandObjectTargetList
478 class CommandObjectTargetList : public CommandObjectParsed {
480 CommandObjectTargetList(CommandInterpreter &interpreter)
481 : CommandObjectParsed(
482 interpreter, "target list",
483 "List all current targets in the current debug session.", nullptr) {
486 ~CommandObjectTargetList() override = default;
489 bool DoExecute(Args &args, CommandReturnObject &result) override {
490 if (args.GetArgumentCount() == 0) {
491 Stream &strm = result.GetOutputStream();
493 bool show_stopped_process_status = false;
494 if (DumpTargetList(GetDebugger().GetTargetList(),
495 show_stopped_process_status, strm) == 0) {
496 strm.PutCString("No targets.\n");
498 result.SetStatus(eReturnStatusSuccessFinishResult);
500 result.AppendError("the 'target list' command takes no arguments\n");
501 result.SetStatus(eReturnStatusFailed);
503 return result.Succeeded();
507 #pragma mark CommandObjectTargetSelect
511 class CommandObjectTargetSelect : public CommandObjectParsed {
513 CommandObjectTargetSelect(CommandInterpreter &interpreter)
514 : CommandObjectParsed(
515 interpreter, "target select",
516 "Select a target as the current target by target index.", nullptr) {
519 ~CommandObjectTargetSelect() override = default;
522 bool DoExecute(Args &args, CommandReturnObject &result) override {
523 if (args.GetArgumentCount() == 1) {
524 bool success = false;
525 const char *target_idx_arg = args.GetArgumentAtIndex(0);
526 uint32_t target_idx =
527 StringConvert::ToUInt32(target_idx_arg, UINT32_MAX, 0, &success);
529 TargetList &target_list = GetDebugger().GetTargetList();
530 const uint32_t num_targets = target_list.GetNumTargets();
531 if (target_idx < num_targets) {
532 TargetSP target_sp(target_list.GetTargetAtIndex(target_idx));
534 Stream &strm = result.GetOutputStream();
535 target_list.SetSelectedTarget(target_sp.get());
536 bool show_stopped_process_status = false;
537 DumpTargetList(target_list, show_stopped_process_status, strm);
538 result.SetStatus(eReturnStatusSuccessFinishResult);
540 result.AppendErrorWithFormat("target #%u is NULL in target list\n",
542 result.SetStatus(eReturnStatusFailed);
545 if (num_targets > 0) {
546 result.AppendErrorWithFormat(
547 "index %u is out of range, valid target indexes are 0 - %u\n",
548 target_idx, num_targets - 1);
550 result.AppendErrorWithFormat(
551 "index %u is out of range since there are no active targets\n",
554 result.SetStatus(eReturnStatusFailed);
557 result.AppendErrorWithFormat("invalid index string value '%s'\n",
559 result.SetStatus(eReturnStatusFailed);
563 "'target select' takes a single argument: a target index\n");
564 result.SetStatus(eReturnStatusFailed);
566 return result.Succeeded();
570 #pragma mark CommandObjectTargetSelect
574 class CommandObjectTargetDelete : public CommandObjectParsed {
576 CommandObjectTargetDelete(CommandInterpreter &interpreter)
577 : CommandObjectParsed(interpreter, "target delete",
578 "Delete one or more targets by target index.",
580 m_option_group(), m_all_option(LLDB_OPT_SET_1, false, "all", 'a',
581 "Delete all targets.", false, true),
583 LLDB_OPT_SET_1, false, "clean", 'c',
584 "Perform extra cleanup to minimize memory consumption after "
585 "deleting the target. "
586 "By default, LLDB will keep in memory any modules previously "
587 "loaded by the target as well "
588 "as all of its debug info. Specifying --clean will unload all of "
589 "these shared modules and "
590 "cause them to be reparsed again the next time the target is run",
592 m_option_group.Append(&m_all_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
593 m_option_group.Append(&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
594 m_option_group.Finalize();
597 ~CommandObjectTargetDelete() override = default;
599 Options *GetOptions() override { return &m_option_group; }
602 bool DoExecute(Args &args, CommandReturnObject &result) override {
603 const size_t argc = args.GetArgumentCount();
604 std::vector<TargetSP> delete_target_list;
605 TargetList &target_list = GetDebugger().GetTargetList();
608 if (m_all_option.GetOptionValue()) {
609 for (int i = 0; i < target_list.GetNumTargets(); ++i)
610 delete_target_list.push_back(target_list.GetTargetAtIndex(i));
611 } else if (argc > 0) {
612 const uint32_t num_targets = target_list.GetNumTargets();
613 // Bail out if don't have any targets.
614 if (num_targets == 0) {
615 result.AppendError("no targets to delete");
616 result.SetStatus(eReturnStatusFailed);
620 for (auto &entry : args.entries()) {
622 if (entry.ref.getAsInteger(0, target_idx)) {
623 result.AppendErrorWithFormat("invalid target index '%s'\n",
625 result.SetStatus(eReturnStatusFailed);
628 if (target_idx < num_targets) {
629 target_sp = target_list.GetTargetAtIndex(target_idx);
631 delete_target_list.push_back(target_sp);
636 result.AppendErrorWithFormat("target index %u is out of range, valid "
637 "target indexes are 0 - %u\n",
638 target_idx, num_targets - 1);
640 result.AppendErrorWithFormat(
641 "target index %u is out of range, the only valid index is 0\n",
644 result.SetStatus(eReturnStatusFailed);
648 target_sp = target_list.GetSelectedTarget();
650 result.AppendErrorWithFormat("no target is currently selected\n");
651 result.SetStatus(eReturnStatusFailed);
654 delete_target_list.push_back(target_sp);
657 const size_t num_targets_to_delete = delete_target_list.size();
658 for (size_t idx = 0; idx < num_targets_to_delete; ++idx) {
659 target_sp = delete_target_list[idx];
660 target_list.DeleteTarget(target_sp);
661 target_sp->Destroy();
663 // If "--clean" was specified, prune any orphaned shared modules from the
664 // global shared module list
665 if (m_cleanup_option.GetOptionValue()) {
666 const bool mandatory = true;
667 ModuleList::RemoveOrphanSharedModules(mandatory);
669 result.GetOutputStream().Printf("%u targets deleted.\n",
670 (uint32_t)num_targets_to_delete);
671 result.SetStatus(eReturnStatusSuccessFinishResult);
676 OptionGroupOptions m_option_group;
677 OptionGroupBoolean m_all_option;
678 OptionGroupBoolean m_cleanup_option;
681 #pragma mark CommandObjectTargetVariable
685 class CommandObjectTargetVariable : public CommandObjectParsed {
686 static const uint32_t SHORT_OPTION_FILE = 0x66696c65; // 'file'
687 static const uint32_t SHORT_OPTION_SHLB = 0x73686c62; // 'shlb'
690 CommandObjectTargetVariable(CommandInterpreter &interpreter)
691 : CommandObjectParsed(interpreter, "target variable",
692 "Read global variables for the current target, "
693 "before or while running a process.",
694 nullptr, eCommandRequiresTarget),
696 m_option_variable(false), // Don't include frame options
697 m_option_format(eFormatDefault),
698 m_option_compile_units(LLDB_OPT_SET_1, false, "file", SHORT_OPTION_FILE,
700 "A basename or fullpath to a file that contains "
701 "global variables. This option can be "
702 "specified multiple times."),
703 m_option_shared_libraries(
704 LLDB_OPT_SET_1, false, "shlib", SHORT_OPTION_SHLB, 0,
706 "A basename or fullpath to a shared library to use in the search "
708 "variables. This option can be specified multiple times."),
710 CommandArgumentEntry arg;
711 CommandArgumentData var_name_arg;
713 // Define the first (and only) variant of this arg.
714 var_name_arg.arg_type = eArgTypeVarName;
715 var_name_arg.arg_repetition = eArgRepeatPlus;
717 // There is only one variant this argument could be; put it into the
719 arg.push_back(var_name_arg);
721 // Push the data for the first argument into the m_arguments vector.
722 m_arguments.push_back(arg);
724 m_option_group.Append(&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
725 m_option_group.Append(&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
726 m_option_group.Append(&m_option_format,
727 OptionGroupFormat::OPTION_GROUP_FORMAT |
728 OptionGroupFormat::OPTION_GROUP_GDB_FMT,
730 m_option_group.Append(&m_option_compile_units, LLDB_OPT_SET_ALL,
732 m_option_group.Append(&m_option_shared_libraries, LLDB_OPT_SET_ALL,
734 m_option_group.Finalize();
737 ~CommandObjectTargetVariable() override = default;
739 void DumpValueObject(Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp,
740 const char *root_name) {
741 DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions());
743 if (!valobj_sp->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
744 valobj_sp->IsRuntimeSupportValue())
747 switch (var_sp->GetScope()) {
748 case eValueTypeVariableGlobal:
749 if (m_option_variable.show_scope)
750 s.PutCString("GLOBAL: ");
753 case eValueTypeVariableStatic:
754 if (m_option_variable.show_scope)
755 s.PutCString("STATIC: ");
758 case eValueTypeVariableArgument:
759 if (m_option_variable.show_scope)
760 s.PutCString(" ARG: ");
763 case eValueTypeVariableLocal:
764 if (m_option_variable.show_scope)
765 s.PutCString(" LOCAL: ");
768 case eValueTypeVariableThreadLocal:
769 if (m_option_variable.show_scope)
770 s.PutCString("THREAD: ");
777 if (m_option_variable.show_decl) {
778 bool show_fullpaths = false;
779 bool show_module = true;
780 if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
784 const Format format = m_option_format.GetFormat();
785 if (format != eFormatDefault)
786 options.SetFormat(format);
788 options.SetRootValueObjectName(root_name);
790 valobj_sp->Dump(s, options);
793 static size_t GetVariableCallback(void *baton, const char *name,
794 VariableList &variable_list) {
795 Target *target = static_cast<Target *>(baton);
797 return target->GetImages().FindGlobalVariables(ConstString(name),
798 UINT32_MAX, variable_list);
803 Options *GetOptions() override { return &m_option_group; }
806 void DumpGlobalVariableList(const ExecutionContext &exe_ctx,
807 const SymbolContext &sc,
808 const VariableList &variable_list, Stream &s) {
809 size_t count = variable_list.GetSize();
813 s.Printf("Global variables for %s in %s:\n",
814 sc.comp_unit->GetPath().c_str(),
815 sc.module_sp->GetFileSpec().GetPath().c_str());
817 s.Printf("Global variables for %s\n",
818 sc.module_sp->GetFileSpec().GetPath().c_str());
820 } else if (sc.comp_unit) {
821 s.Printf("Global variables for %s\n", sc.comp_unit->GetPath().c_str());
824 for (uint32_t i = 0; i < count; ++i) {
825 VariableSP var_sp(variable_list.GetVariableAtIndex(i));
827 ValueObjectSP valobj_sp(ValueObjectVariable::Create(
828 exe_ctx.GetBestExecutionContextScope(), var_sp));
831 DumpValueObject(s, var_sp, valobj_sp,
832 var_sp->GetName().GetCString());
838 bool DoExecute(Args &args, CommandReturnObject &result) override {
839 Target *target = m_exe_ctx.GetTargetPtr();
840 const size_t argc = args.GetArgumentCount();
841 Stream &s = result.GetOutputStream();
845 // TODO: Convert to entry-based iteration. Requires converting
847 for (size_t idx = 0; idx < argc; ++idx) {
848 VariableList variable_list;
849 ValueObjectList valobj_list;
851 const char *arg = args.GetArgumentAtIndex(idx);
853 bool use_var_name = false;
854 if (m_option_variable.use_regex) {
855 RegularExpression regex(llvm::StringRef::withNullAsEmpty(arg));
856 if (!regex.IsValid()) {
857 result.GetErrorStream().Printf(
858 "error: invalid regular expression: '%s'\n", arg);
859 result.SetStatus(eReturnStatusFailed);
863 matches = target->GetImages().FindGlobalVariables(regex, UINT32_MAX,
866 Status error(Variable::GetValuesForVariableExpressionPath(
867 arg, m_exe_ctx.GetBestExecutionContextScope(),
868 GetVariableCallback, target, variable_list, valobj_list));
869 matches = variable_list.GetSize();
873 result.GetErrorStream().Printf(
874 "error: can't find global variable '%s'\n", arg);
875 result.SetStatus(eReturnStatusFailed);
878 for (uint32_t global_idx = 0; global_idx < matches; ++global_idx) {
879 VariableSP var_sp(variable_list.GetVariableAtIndex(global_idx));
881 ValueObjectSP valobj_sp(
882 valobj_list.GetValueObjectAtIndex(global_idx));
884 valobj_sp = ValueObjectVariable::Create(
885 m_exe_ctx.GetBestExecutionContextScope(), var_sp);
888 DumpValueObject(s, var_sp, valobj_sp,
889 use_var_name ? var_sp->GetName().GetCString()
896 const FileSpecList &compile_units =
897 m_option_compile_units.GetOptionValue().GetCurrentValue();
898 const FileSpecList &shlibs =
899 m_option_shared_libraries.GetOptionValue().GetCurrentValue();
900 SymbolContextList sc_list;
901 const size_t num_compile_units = compile_units.GetSize();
902 const size_t num_shlibs = shlibs.GetSize();
903 if (num_compile_units == 0 && num_shlibs == 0) {
904 bool success = false;
905 StackFrame *frame = m_exe_ctx.GetFramePtr();
906 CompileUnit *comp_unit = nullptr;
908 SymbolContext sc = frame->GetSymbolContext(eSymbolContextCompUnit);
910 const bool can_create = true;
911 VariableListSP comp_unit_varlist_sp(
912 sc.comp_unit->GetVariableList(can_create));
913 if (comp_unit_varlist_sp) {
914 size_t count = comp_unit_varlist_sp->GetSize();
916 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
925 result.AppendErrorWithFormat(
926 "no global variables in current compile unit: %s\n",
927 comp_unit->GetPath().c_str());
929 result.AppendErrorWithFormat(
930 "no debug information for frame %u\n",
931 frame->GetFrameIndex());
933 result.AppendError("'target variable' takes one or more global "
934 "variable names as arguments\n");
935 result.SetStatus(eReturnStatusFailed);
938 SymbolContextList sc_list;
939 const bool append = true;
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);
947 target->GetImages().FindFirstModule(module_spec));
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), append,
956 sc.module_sp = module_sp;
960 // Didn't find matching shlib/module in target...
961 result.AppendErrorWithFormat(
962 "target doesn't contain the specified shared library: %s\n",
963 module_file.GetPath().c_str());
967 // No shared libraries, we just want to find globals for the compile
968 // units files that were specified
969 for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
970 target->GetImages().FindCompileUnits(
971 compile_units.GetFileSpecAtIndex(cu_idx), append, sc_list);
974 const uint32_t num_scs = sc_list.GetSize();
977 for (uint32_t sc_idx = 0; sc_idx < num_scs; ++sc_idx) {
978 if (sc_list.GetContextAtIndex(sc_idx, sc)) {
980 const bool can_create = true;
981 VariableListSP comp_unit_varlist_sp(
982 sc.comp_unit->GetVariableList(can_create));
983 if (comp_unit_varlist_sp)
984 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp,
986 } else if (sc.module_sp) {
987 // Get all global variables for this module
988 lldb_private::RegularExpression all_globals_regex(
990 ".")); // Any global with at least one character
991 VariableList variable_list;
992 sc.module_sp->FindGlobalVariables(all_globals_regex, UINT32_MAX,
994 DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s);
1002 if (m_interpreter.TruncationWarningNecessary()) {
1003 result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(),
1004 m_cmd_name.c_str());
1005 m_interpreter.TruncationWarningGiven();
1008 return result.Succeeded();
1011 OptionGroupOptions m_option_group;
1012 OptionGroupVariable m_option_variable;
1013 OptionGroupFormat m_option_format;
1014 OptionGroupFileList m_option_compile_units;
1015 OptionGroupFileList m_option_shared_libraries;
1016 OptionGroupValueObjectDisplay m_varobj_options;
1019 #pragma mark CommandObjectTargetModulesSearchPathsAdd
1021 class CommandObjectTargetModulesSearchPathsAdd : public CommandObjectParsed {
1023 CommandObjectTargetModulesSearchPathsAdd(CommandInterpreter &interpreter)
1024 : CommandObjectParsed(interpreter, "target modules search-paths add",
1025 "Add new image search paths substitution pairs to "
1026 "the current target.",
1028 CommandArgumentEntry arg;
1029 CommandArgumentData old_prefix_arg;
1030 CommandArgumentData new_prefix_arg;
1032 // Define the first variant of this arg pair.
1033 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1034 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1036 // Define the first variant of this arg pair.
1037 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1038 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1040 // There are two required arguments that must always occur together, i.e.
1041 // an argument "pair". Because they must always occur together, they are
1042 // treated as two variants of one argument rather than two independent
1043 // arguments. Push them both into the first argument position for
1046 arg.push_back(old_prefix_arg);
1047 arg.push_back(new_prefix_arg);
1049 m_arguments.push_back(arg);
1052 ~CommandObjectTargetModulesSearchPathsAdd() override = default;
1055 bool DoExecute(Args &command, CommandReturnObject &result) override {
1056 Target *target = GetDebugger().GetSelectedTarget().get();
1058 const size_t argc = command.GetArgumentCount();
1060 result.AppendError("add requires an even number of arguments\n");
1061 result.SetStatus(eReturnStatusFailed);
1063 for (size_t i = 0; i < argc; i += 2) {
1064 const char *from = command.GetArgumentAtIndex(i);
1065 const char *to = command.GetArgumentAtIndex(i + 1);
1067 if (from[0] && to[0]) {
1068 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
1070 log->Printf("target modules search path adding ImageSearchPath "
1071 "pair: '%s' -> '%s'",
1074 bool last_pair = ((argc - i) == 2);
1075 target->GetImageSearchPathList().Append(
1076 ConstString(from), ConstString(to),
1077 last_pair); // Notify if this is the last pair
1078 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1081 result.AppendError("<path-prefix> can't be empty\n");
1083 result.AppendError("<new-path-prefix> can't be empty\n");
1084 result.SetStatus(eReturnStatusFailed);
1089 result.AppendError("invalid target\n");
1090 result.SetStatus(eReturnStatusFailed);
1092 return result.Succeeded();
1096 #pragma mark CommandObjectTargetModulesSearchPathsClear
1098 class CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed {
1100 CommandObjectTargetModulesSearchPathsClear(CommandInterpreter &interpreter)
1101 : CommandObjectParsed(interpreter, "target modules search-paths clear",
1102 "Clear all current image search path substitution "
1103 "pairs from the current target.",
1104 "target modules search-paths clear") {}
1106 ~CommandObjectTargetModulesSearchPathsClear() override = default;
1109 bool DoExecute(Args &command, CommandReturnObject &result) override {
1110 Target *target = GetDebugger().GetSelectedTarget().get();
1113 target->GetImageSearchPathList().Clear(notify);
1114 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1116 result.AppendError("invalid target\n");
1117 result.SetStatus(eReturnStatusFailed);
1119 return result.Succeeded();
1123 #pragma mark CommandObjectTargetModulesSearchPathsInsert
1125 class CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed {
1127 CommandObjectTargetModulesSearchPathsInsert(CommandInterpreter &interpreter)
1128 : CommandObjectParsed(interpreter, "target modules search-paths insert",
1129 "Insert a new image search path substitution pair "
1130 "into the current target at the specified index.",
1132 CommandArgumentEntry arg1;
1133 CommandArgumentEntry arg2;
1134 CommandArgumentData index_arg;
1135 CommandArgumentData old_prefix_arg;
1136 CommandArgumentData new_prefix_arg;
1138 // Define the first and only variant of this arg.
1139 index_arg.arg_type = eArgTypeIndex;
1140 index_arg.arg_repetition = eArgRepeatPlain;
1142 // Put the one and only variant into the first arg for m_arguments:
1143 arg1.push_back(index_arg);
1145 // Define the first variant of this arg pair.
1146 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1147 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1149 // Define the first variant of this arg pair.
1150 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1151 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1153 // There are two required arguments that must always occur together, i.e.
1154 // an argument "pair". Because they must always occur together, they are
1155 // treated as two variants of one argument rather than two independent
1156 // arguments. Push them both into the same argument position for
1159 arg2.push_back(old_prefix_arg);
1160 arg2.push_back(new_prefix_arg);
1162 // Add arguments to m_arguments.
1163 m_arguments.push_back(arg1);
1164 m_arguments.push_back(arg2);
1167 ~CommandObjectTargetModulesSearchPathsInsert() override = default;
1170 bool DoExecute(Args &command, CommandReturnObject &result) override {
1171 Target *target = GetDebugger().GetSelectedTarget().get();
1173 size_t argc = command.GetArgumentCount();
1174 // check for at least 3 arguments and an odd number of parameters
1175 if (argc >= 3 && argc & 1) {
1176 bool success = false;
1178 uint32_t insert_idx = StringConvert::ToUInt32(
1179 command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);
1182 result.AppendErrorWithFormat(
1183 "<index> parameter is not an integer: '%s'.\n",
1184 command.GetArgumentAtIndex(0));
1185 result.SetStatus(eReturnStatusFailed);
1186 return result.Succeeded();
1189 // shift off the index
1191 argc = command.GetArgumentCount();
1193 for (uint32_t i = 0; i < argc; i += 2, ++insert_idx) {
1194 const char *from = command.GetArgumentAtIndex(i);
1195 const char *to = command.GetArgumentAtIndex(i + 1);
1197 if (from[0] && to[0]) {
1198 bool last_pair = ((argc - i) == 2);
1199 target->GetImageSearchPathList().Insert(
1200 ConstString(from), ConstString(to), insert_idx, last_pair);
1201 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1204 result.AppendError("<path-prefix> can't be empty\n");
1206 result.AppendError("<new-path-prefix> can't be empty\n");
1207 result.SetStatus(eReturnStatusFailed);
1212 result.AppendError("insert requires at least three arguments\n");
1213 result.SetStatus(eReturnStatusFailed);
1214 return result.Succeeded();
1218 result.AppendError("invalid target\n");
1219 result.SetStatus(eReturnStatusFailed);
1221 return result.Succeeded();
1225 #pragma mark CommandObjectTargetModulesSearchPathsList
1227 class CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed {
1229 CommandObjectTargetModulesSearchPathsList(CommandInterpreter &interpreter)
1230 : CommandObjectParsed(interpreter, "target modules search-paths list",
1231 "List all current image search path substitution "
1232 "pairs in the current target.",
1233 "target modules search-paths list") {}
1235 ~CommandObjectTargetModulesSearchPathsList() override = default;
1238 bool DoExecute(Args &command, CommandReturnObject &result) override {
1239 Target *target = GetDebugger().GetSelectedTarget().get();
1241 if (command.GetArgumentCount() != 0) {
1242 result.AppendError("list takes no arguments\n");
1243 result.SetStatus(eReturnStatusFailed);
1244 return result.Succeeded();
1247 target->GetImageSearchPathList().Dump(&result.GetOutputStream());
1248 result.SetStatus(eReturnStatusSuccessFinishResult);
1250 result.AppendError("invalid target\n");
1251 result.SetStatus(eReturnStatusFailed);
1253 return result.Succeeded();
1257 #pragma mark CommandObjectTargetModulesSearchPathsQuery
1259 class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed {
1261 CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter &interpreter)
1262 : CommandObjectParsed(
1263 interpreter, "target modules search-paths query",
1264 "Transform a path using the first applicable image search path.",
1266 CommandArgumentEntry arg;
1267 CommandArgumentData path_arg;
1269 // Define the first (and only) variant of this arg.
1270 path_arg.arg_type = eArgTypeDirectoryName;
1271 path_arg.arg_repetition = eArgRepeatPlain;
1273 // There is only one variant this argument could be; put it into the
1275 arg.push_back(path_arg);
1277 // Push the data for the first argument into the m_arguments vector.
1278 m_arguments.push_back(arg);
1281 ~CommandObjectTargetModulesSearchPathsQuery() override = default;
1284 bool DoExecute(Args &command, CommandReturnObject &result) override {
1285 Target *target = GetDebugger().GetSelectedTarget().get();
1287 if (command.GetArgumentCount() != 1) {
1288 result.AppendError("query requires one argument\n");
1289 result.SetStatus(eReturnStatusFailed);
1290 return result.Succeeded();
1293 ConstString orig(command.GetArgumentAtIndex(0));
1294 ConstString transformed;
1295 if (target->GetImageSearchPathList().RemapPath(orig, transformed))
1296 result.GetOutputStream().Printf("%s\n", transformed.GetCString());
1298 result.GetOutputStream().Printf("%s\n", orig.GetCString());
1300 result.SetStatus(eReturnStatusSuccessFinishResult);
1302 result.AppendError("invalid target\n");
1303 result.SetStatus(eReturnStatusFailed);
1305 return result.Succeeded();
1309 // Static Helper functions
1310 static void DumpModuleArchitecture(Stream &strm, Module *module,
1311 bool full_triple, uint32_t width) {
1313 StreamString arch_strm;
1316 module->GetArchitecture().DumpTriple(arch_strm);
1318 arch_strm.PutCString(module->GetArchitecture().GetArchitectureName());
1319 std::string arch_str = arch_strm.GetString();
1322 strm.Printf("%-*s", width, arch_str.c_str());
1324 strm.PutCString(arch_str);
1328 static void DumpModuleUUID(Stream &strm, Module *module) {
1329 if (module && module->GetUUID().IsValid())
1330 module->GetUUID().Dump(&strm);
1332 strm.PutCString(" ");
1335 static uint32_t DumpCompileUnitLineTable(CommandInterpreter &interpreter,
1336 Stream &strm, Module *module,
1337 const FileSpec &file_spec,
1338 lldb::DescriptionLevel desc_level) {
1339 uint32_t num_matches = 0;
1341 SymbolContextList sc_list;
1342 num_matches = module->ResolveSymbolContextsForFileSpec(
1343 file_spec, 0, false, eSymbolContextCompUnit, sc_list);
1345 for (uint32_t i = 0; i < num_matches; ++i) {
1347 if (sc_list.GetContextAtIndex(i, sc)) {
1351 strm << "Line table for " << *static_cast<FileSpec *>(sc.comp_unit)
1352 << " in `" << module->GetFileSpec().GetFilename() << "\n";
1353 LineTable *line_table = sc.comp_unit->GetLineTable();
1355 line_table->GetDescription(
1356 &strm, interpreter.GetExecutionContext().GetTargetPtr(),
1359 strm << "No line table";
1366 static void DumpFullpath(Stream &strm, const FileSpec *file_spec_ptr,
1368 if (file_spec_ptr) {
1370 std::string fullpath = file_spec_ptr->GetPath();
1371 strm.Printf("%-*s", width, fullpath.c_str());
1374 file_spec_ptr->Dump(&strm);
1378 // Keep the width spacing correct if things go wrong...
1380 strm.Printf("%-*s", width, "");
1383 static void DumpDirectory(Stream &strm, const FileSpec *file_spec_ptr,
1385 if (file_spec_ptr) {
1387 strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
1389 file_spec_ptr->GetDirectory().Dump(&strm);
1392 // Keep the width spacing correct if things go wrong...
1394 strm.Printf("%-*s", width, "");
1397 static void DumpBasename(Stream &strm, const FileSpec *file_spec_ptr,
1399 if (file_spec_ptr) {
1401 strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
1403 file_spec_ptr->GetFilename().Dump(&strm);
1406 // Keep the width spacing correct if things go wrong...
1408 strm.Printf("%-*s", width, "");
1411 static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) {
1412 size_t num_dumped = 0;
1413 std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
1414 const size_t num_modules = module_list.GetSize();
1415 if (num_modules > 0) {
1416 strm.Printf("Dumping headers for %" PRIu64 " module(s).\n",
1417 static_cast<uint64_t>(num_modules));
1419 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
1420 Module *module = module_list.GetModulePointerAtIndexUnlocked(image_idx);
1422 if (num_dumped++ > 0) {
1426 ObjectFile *objfile = module->GetObjectFile();
1428 objfile->Dump(&strm);
1430 strm.Format("No object file for module: {0:F}\n",
1431 module->GetFileSpec());
1440 static void DumpModuleSymtab(CommandInterpreter &interpreter, Stream &strm,
1441 Module *module, SortOrder sort_order) {
1443 SymbolVendor *sym_vendor = module->GetSymbolVendor();
1445 Symtab *symtab = sym_vendor->GetSymtab();
1447 symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(),
1453 static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm,
1456 SectionList *section_list = module->GetSectionList();
1458 strm.Printf("Sections for '%s' (%s):\n",
1459 module->GetSpecificationDescription().c_str(),
1460 module->GetArchitecture().GetArchitectureName());
1462 section_list->Dump(&strm,
1463 interpreter.GetExecutionContext().GetTargetPtr(), true,
1470 static bool DumpModuleSymbolVendor(Stream &strm, Module *module) {
1472 SymbolVendor *symbol_vendor = module->GetSymbolVendor(true);
1473 if (symbol_vendor) {
1474 symbol_vendor->Dump(&strm);
1481 static void DumpAddress(ExecutionContextScope *exe_scope,
1482 const Address &so_addr, bool verbose, Stream &strm) {
1484 strm.Indent(" Address: ");
1485 so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
1486 strm.PutCString(" (");
1487 so_addr.Dump(&strm, exe_scope, Address::DumpStyleSectionNameOffset);
1488 strm.PutCString(")\n");
1489 strm.Indent(" Summary: ");
1490 const uint32_t save_indent = strm.GetIndentLevel();
1491 strm.SetIndentLevel(save_indent + 13);
1492 so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription);
1493 strm.SetIndentLevel(save_indent);
1494 // Print out detailed address information when verbose is enabled
1497 so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext);
1502 static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm,
1503 Module *module, uint32_t resolve_mask,
1504 lldb::addr_t raw_addr, lldb::addr_t offset,
1507 lldb::addr_t addr = raw_addr - offset;
1510 Target *target = interpreter.GetExecutionContext().GetTargetPtr();
1511 if (target && !target->GetSectionLoadList().IsEmpty()) {
1512 if (!target->GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
1514 else if (so_addr.GetModule().get() != module)
1517 if (!module->ResolveFileAddress(addr, so_addr))
1521 ExecutionContextScope *exe_scope =
1522 interpreter.GetExecutionContext().GetBestExecutionContextScope();
1523 DumpAddress(exe_scope, so_addr, verbose, strm);
1524 // strm.IndentMore();
1525 // strm.Indent (" Address: ");
1526 // so_addr.Dump (&strm, exe_scope,
1527 // Address::DumpStyleModuleWithFileAddress);
1528 // strm.PutCString (" (");
1529 // so_addr.Dump (&strm, exe_scope,
1530 // Address::DumpStyleSectionNameOffset);
1531 // strm.PutCString (")\n");
1532 // strm.Indent (" Summary: ");
1533 // const uint32_t save_indent = strm.GetIndentLevel ();
1534 // strm.SetIndentLevel (save_indent + 13);
1535 // so_addr.Dump (&strm, exe_scope,
1536 // Address::DumpStyleResolvedDescription);
1537 // strm.SetIndentLevel (save_indent);
1538 // // Print out detailed address information when verbose is enabled
1542 // so_addr.Dump (&strm, exe_scope,
1543 // Address::DumpStyleDetailedSymbolContext);
1545 // strm.IndentLess();
1552 static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
1553 Stream &strm, Module *module,
1554 const char *name, bool name_is_regex,
1559 SymbolVendor *sym_vendor = module->GetSymbolVendor();
1561 Symtab *symtab = sym_vendor->GetSymtab();
1563 std::vector<uint32_t> match_indexes;
1564 ConstString symbol_name(name);
1565 uint32_t num_matches = 0;
1566 if (name_is_regex) {
1567 RegularExpression name_regexp(symbol_name.GetStringRef());
1568 num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType(
1569 name_regexp, eSymbolTypeAny, match_indexes);
1572 symtab->AppendSymbolIndexesWithName(symbol_name, match_indexes);
1575 if (num_matches > 0) {
1577 strm.Printf("%u symbols match %s'%s' in ", num_matches,
1578 name_is_regex ? "the regular expression " : "", name);
1579 DumpFullpath(strm, &module->GetFileSpec(), 0);
1580 strm.PutCString(":\n");
1582 for (uint32_t i = 0; i < num_matches; ++i) {
1583 Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
1584 if (symbol && symbol->ValueIsAddress()) {
1585 DumpAddress(interpreter.GetExecutionContext()
1586 .GetBestExecutionContextScope(),
1587 symbol->GetAddressRef(), verbose, strm);
1599 static void DumpSymbolContextList(ExecutionContextScope *exe_scope,
1600 Stream &strm, SymbolContextList &sc_list,
1604 const uint32_t num_matches = sc_list.GetSize();
1606 for (uint32_t i = 0; i < num_matches; ++i) {
1608 if (sc_list.GetContextAtIndex(i, sc)) {
1611 sc.GetAddressRange(eSymbolContextEverything, 0, true, range);
1613 DumpAddress(exe_scope, range.GetBaseAddress(), verbose, strm);
1619 static size_t LookupFunctionInModule(CommandInterpreter &interpreter,
1620 Stream &strm, Module *module,
1621 const char *name, bool name_is_regex,
1622 bool include_inlines, bool include_symbols,
1624 if (module && name && name[0]) {
1625 SymbolContextList sc_list;
1626 const bool append = true;
1627 size_t num_matches = 0;
1628 if (name_is_regex) {
1629 RegularExpression function_name_regex((llvm::StringRef(name)));
1630 num_matches = module->FindFunctions(function_name_regex, include_symbols,
1631 include_inlines, append, sc_list);
1633 ConstString function_name(name);
1634 num_matches = module->FindFunctions(
1635 function_name, nullptr, eFunctionNameTypeAuto, include_symbols,
1636 include_inlines, append, sc_list);
1641 strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
1642 num_matches > 1 ? "es" : "");
1643 DumpFullpath(strm, &module->GetFileSpec(), 0);
1644 strm.PutCString(":\n");
1645 DumpSymbolContextList(
1646 interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1647 strm, sc_list, verbose);
1654 static size_t LookupTypeInModule(CommandInterpreter &interpreter, Stream &strm,
1655 Module *module, const char *name_cstr,
1656 bool name_is_regex) {
1657 if (module && name_cstr && name_cstr[0]) {
1659 const uint32_t max_num_matches = UINT32_MAX;
1660 size_t num_matches = 0;
1661 bool name_is_fully_qualified = false;
1663 ConstString name(name_cstr);
1664 llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
1666 module->FindTypes(name, name_is_fully_qualified, max_num_matches,
1667 searched_symbol_files, type_list);
1671 strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
1672 num_matches > 1 ? "es" : "");
1673 DumpFullpath(strm, &module->GetFileSpec(), 0);
1674 strm.PutCString(":\n");
1675 for (TypeSP type_sp : type_list.Types()) {
1677 // Resolve the clang type so that any forward references to types
1678 // that haven't yet been parsed will get parsed.
1679 type_sp->GetFullCompilerType();
1680 type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
1681 // Print all typedef chains
1682 TypeSP typedef_type_sp(type_sp);
1683 TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1684 while (typedefed_type_sp) {
1686 strm.Printf(" typedef '%s': ",
1687 typedef_type_sp->GetName().GetCString());
1688 typedefed_type_sp->GetFullCompilerType();
1689 typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull,
1691 typedef_type_sp = typedefed_type_sp;
1692 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1703 static size_t LookupTypeHere(CommandInterpreter &interpreter, Stream &strm,
1704 Module &module, const char *name_cstr,
1705 bool name_is_regex) {
1707 const uint32_t max_num_matches = UINT32_MAX;
1708 size_t num_matches = 1;
1709 bool name_is_fully_qualified = false;
1711 ConstString name(name_cstr);
1712 llvm::DenseSet<SymbolFile *> searched_symbol_files;
1713 num_matches = module.FindTypes(name, name_is_fully_qualified, max_num_matches,
1714 searched_symbol_files, type_list);
1718 strm.PutCString("Best match found in ");
1719 DumpFullpath(strm, &module.GetFileSpec(), 0);
1720 strm.PutCString(":\n");
1722 TypeSP type_sp(type_list.GetTypeAtIndex(0));
1724 // Resolve the clang type so that any forward references to types that
1725 // haven't yet been parsed will get parsed.
1726 type_sp->GetFullCompilerType();
1727 type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
1728 // Print all typedef chains
1729 TypeSP typedef_type_sp(type_sp);
1730 TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1731 while (typedefed_type_sp) {
1733 strm.Printf(" typedef '%s': ",
1734 typedef_type_sp->GetName().GetCString());
1735 typedefed_type_sp->GetFullCompilerType();
1736 typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
1737 typedef_type_sp = typedefed_type_sp;
1738 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1746 static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter,
1747 Stream &strm, Module *module,
1748 const FileSpec &file_spec,
1749 uint32_t line, bool check_inlines,
1751 if (module && file_spec) {
1752 SymbolContextList sc_list;
1753 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(
1754 file_spec, line, check_inlines, eSymbolContextEverything, sc_list);
1755 if (num_matches > 0) {
1757 strm.Printf("%u match%s found in ", num_matches,
1758 num_matches > 1 ? "es" : "");
1761 strm.Printf(":%u", line);
1763 DumpFullpath(strm, &module->GetFileSpec(), 0);
1764 strm.PutCString(":\n");
1765 DumpSymbolContextList(
1766 interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1767 strm, sc_list, verbose);
1774 static size_t FindModulesByName(Target *target, const char *module_name,
1775 ModuleList &module_list,
1776 bool check_global_list) {
1777 FileSpec module_file_spec(module_name);
1778 ModuleSpec module_spec(module_file_spec);
1780 const size_t initial_size = module_list.GetSize();
1782 if (check_global_list) {
1783 // Check the global list
1784 std::lock_guard<std::recursive_mutex> guard(
1785 Module::GetAllocationModuleCollectionMutex());
1786 const size_t num_modules = Module::GetNumberAllocatedModules();
1788 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
1789 Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
1792 if (module->MatchesModuleSpec(module_spec)) {
1793 module_sp = module->shared_from_this();
1794 module_list.AppendIfNeeded(module_sp);
1800 const size_t num_matches =
1801 target->GetImages().FindModules(module_spec, module_list);
1803 // Not found in our module list for our target, check the main shared
1804 // module list in case it is a extra file used somewhere else
1805 if (num_matches == 0) {
1806 module_spec.GetArchitecture() = target->GetArchitecture();
1807 ModuleList::FindSharedModules(module_spec, module_list);
1810 ModuleList::FindSharedModules(module_spec, module_list);
1814 return module_list.GetSize() - initial_size;
1817 #pragma mark CommandObjectTargetModulesModuleAutoComplete
1819 // A base command object class that can auto complete with module file
1822 class CommandObjectTargetModulesModuleAutoComplete
1823 : public CommandObjectParsed {
1825 CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter &interpreter,
1829 : CommandObjectParsed(interpreter, name, help, syntax) {
1830 CommandArgumentEntry arg;
1831 CommandArgumentData file_arg;
1833 // Define the first (and only) variant of this arg.
1834 file_arg.arg_type = eArgTypeFilename;
1835 file_arg.arg_repetition = eArgRepeatStar;
1837 // There is only one variant this argument could be; put it into the
1839 arg.push_back(file_arg);
1841 // Push the data for the first argument into the m_arguments vector.
1842 m_arguments.push_back(arg);
1845 ~CommandObjectTargetModulesModuleAutoComplete() override = default;
1847 int HandleArgumentCompletion(
1848 CompletionRequest &request,
1849 OptionElementVector &opt_element_vector) override {
1850 CommandCompletions::InvokeCommonCompletionCallbacks(
1851 GetCommandInterpreter(), CommandCompletions::eModuleCompletion, request,
1853 return request.GetNumberOfMatches();
1857 #pragma mark CommandObjectTargetModulesSourceFileAutoComplete
1859 // A base command object class that can auto complete with module source
1862 class CommandObjectTargetModulesSourceFileAutoComplete
1863 : public CommandObjectParsed {
1865 CommandObjectTargetModulesSourceFileAutoComplete(
1866 CommandInterpreter &interpreter, const char *name, const char *help,
1867 const char *syntax, uint32_t flags)
1868 : CommandObjectParsed(interpreter, name, help, syntax, flags) {
1869 CommandArgumentEntry arg;
1870 CommandArgumentData source_file_arg;
1872 // Define the first (and only) variant of this arg.
1873 source_file_arg.arg_type = eArgTypeSourceFile;
1874 source_file_arg.arg_repetition = eArgRepeatPlus;
1876 // There is only one variant this argument could be; put it into the
1878 arg.push_back(source_file_arg);
1880 // Push the data for the first argument into the m_arguments vector.
1881 m_arguments.push_back(arg);
1884 ~CommandObjectTargetModulesSourceFileAutoComplete() override = default;
1886 int HandleArgumentCompletion(
1887 CompletionRequest &request,
1888 OptionElementVector &opt_element_vector) override {
1889 CommandCompletions::InvokeCommonCompletionCallbacks(
1890 GetCommandInterpreter(), CommandCompletions::eSourceFileCompletion,
1892 return request.GetNumberOfMatches();
1896 #pragma mark CommandObjectTargetModulesDumpObjfile
1898 class CommandObjectTargetModulesDumpObjfile
1899 : public CommandObjectTargetModulesModuleAutoComplete {
1901 CommandObjectTargetModulesDumpObjfile(CommandInterpreter &interpreter)
1902 : CommandObjectTargetModulesModuleAutoComplete(
1903 interpreter, "target modules dump objfile",
1904 "Dump the object file headers from one or more target modules.",
1907 ~CommandObjectTargetModulesDumpObjfile() override = default;
1910 bool DoExecute(Args &command, CommandReturnObject &result) override {
1911 Target *target = GetDebugger().GetSelectedTarget().get();
1912 if (target == nullptr) {
1913 result.AppendError("invalid target, create a debug target using the "
1914 "'target create' command");
1915 result.SetStatus(eReturnStatusFailed);
1919 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1920 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1921 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1923 size_t num_dumped = 0;
1924 if (command.GetArgumentCount() == 0) {
1925 // Dump all headers for all modules images
1926 num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(),
1927 target->GetImages());
1928 if (num_dumped == 0) {
1929 result.AppendError("the target has no associated executable images");
1930 result.SetStatus(eReturnStatusFailed);
1933 // Find the modules that match the basename or full path.
1934 ModuleList module_list;
1935 const char *arg_cstr;
1936 for (int arg_idx = 0;
1937 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
1939 size_t num_matched =
1940 FindModulesByName(target, arg_cstr, module_list, true);
1941 if (num_matched == 0) {
1942 result.AppendWarningWithFormat(
1943 "Unable to find an image that matches '%s'.\n", arg_cstr);
1946 // Dump all the modules we found.
1948 DumpModuleObjfileHeaders(result.GetOutputStream(), module_list);
1951 if (num_dumped > 0) {
1952 result.SetStatus(eReturnStatusSuccessFinishResult);
1954 result.AppendError("no matching executable images found");
1955 result.SetStatus(eReturnStatusFailed);
1957 return result.Succeeded();
1961 #pragma mark CommandObjectTargetModulesDumpSymtab
1963 static constexpr OptionEnumValueElement g_sort_option_enumeration[] = {
1964 {eSortOrderNone, "none",
1965 "No sorting, use the original symbol table order."},
1966 {eSortOrderByAddress, "address", "Sort output by symbol address."},
1967 {eSortOrderByName, "name", "Sort output by symbol name."} };
1969 static constexpr OptionDefinition g_target_modules_dump_symtab_options[] = {
1970 #define LLDB_OPTIONS_target_modules_dump_symtab
1971 #include "CommandOptions.inc"
1974 class CommandObjectTargetModulesDumpSymtab
1975 : public CommandObjectTargetModulesModuleAutoComplete {
1977 CommandObjectTargetModulesDumpSymtab(CommandInterpreter &interpreter)
1978 : CommandObjectTargetModulesModuleAutoComplete(
1979 interpreter, "target modules dump symtab",
1980 "Dump the symbol table from one or more target modules.", nullptr),
1983 ~CommandObjectTargetModulesDumpSymtab() override = default;
1985 Options *GetOptions() override { return &m_options; }
1987 class CommandOptions : public Options {
1989 CommandOptions() : Options(), m_sort_order(eSortOrderNone) {}
1991 ~CommandOptions() override = default;
1993 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1994 ExecutionContext *execution_context) override {
1996 const int short_option = m_getopt_table[option_idx].val;
1998 switch (short_option) {
2000 m_sort_order = (SortOrder)OptionArgParser::ToOptionEnum(
2001 option_arg, GetDefinitions()[option_idx].enum_values,
2002 eSortOrderNone, error);
2006 error.SetErrorStringWithFormat("invalid short option character '%c'",
2013 void OptionParsingStarting(ExecutionContext *execution_context) override {
2014 m_sort_order = eSortOrderNone;
2017 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2018 return llvm::makeArrayRef(g_target_modules_dump_symtab_options);
2021 SortOrder m_sort_order;
2025 bool DoExecute(Args &command, CommandReturnObject &result) override {
2026 Target *target = GetDebugger().GetSelectedTarget().get();
2027 if (target == nullptr) {
2028 result.AppendError("invalid target, create a debug target using the "
2029 "'target create' command");
2030 result.SetStatus(eReturnStatusFailed);
2033 uint32_t num_dumped = 0;
2035 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2036 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2037 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2039 if (command.GetArgumentCount() == 0) {
2040 // Dump all sections for all modules images
2041 std::lock_guard<std::recursive_mutex> guard(
2042 target->GetImages().GetMutex());
2043 const size_t num_modules = target->GetImages().GetSize();
2044 if (num_modules > 0) {
2045 result.GetOutputStream().Printf("Dumping symbol table for %" PRIu64
2047 (uint64_t)num_modules);
2048 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2049 if (num_dumped > 0) {
2050 result.GetOutputStream().EOL();
2051 result.GetOutputStream().EOL();
2053 if (m_interpreter.WasInterrupted())
2057 m_interpreter, result.GetOutputStream(),
2058 target->GetImages().GetModulePointerAtIndexUnlocked(image_idx),
2059 m_options.m_sort_order);
2062 result.AppendError("the target has no associated executable images");
2063 result.SetStatus(eReturnStatusFailed);
2067 // Dump specified images (by basename or fullpath)
2068 const char *arg_cstr;
2069 for (int arg_idx = 0;
2070 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2072 ModuleList module_list;
2073 const size_t num_matches =
2074 FindModulesByName(target, arg_cstr, module_list, true);
2075 if (num_matches > 0) {
2076 for (size_t i = 0; i < num_matches; ++i) {
2077 Module *module = module_list.GetModulePointerAtIndex(i);
2079 if (num_dumped > 0) {
2080 result.GetOutputStream().EOL();
2081 result.GetOutputStream().EOL();
2083 if (m_interpreter.WasInterrupted())
2086 DumpModuleSymtab(m_interpreter, result.GetOutputStream(),
2087 module, m_options.m_sort_order);
2091 result.AppendWarningWithFormat(
2092 "Unable to find an image that matches '%s'.\n", arg_cstr);
2097 result.SetStatus(eReturnStatusSuccessFinishResult);
2099 result.AppendError("no matching executable images found");
2100 result.SetStatus(eReturnStatusFailed);
2103 return result.Succeeded();
2106 CommandOptions m_options;
2109 #pragma mark CommandObjectTargetModulesDumpSections
2111 // Image section dumping command
2113 class CommandObjectTargetModulesDumpSections
2114 : public CommandObjectTargetModulesModuleAutoComplete {
2116 CommandObjectTargetModulesDumpSections(CommandInterpreter &interpreter)
2117 : CommandObjectTargetModulesModuleAutoComplete(
2118 interpreter, "target modules dump sections",
2119 "Dump the sections from one or more target modules.",
2120 //"target modules dump sections [<file1> ...]")
2123 ~CommandObjectTargetModulesDumpSections() override = default;
2126 bool DoExecute(Args &command, CommandReturnObject &result) override {
2127 Target *target = GetDebugger().GetSelectedTarget().get();
2128 if (target == nullptr) {
2129 result.AppendError("invalid target, create a debug target using the "
2130 "'target create' command");
2131 result.SetStatus(eReturnStatusFailed);
2134 uint32_t num_dumped = 0;
2136 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2137 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2138 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2140 if (command.GetArgumentCount() == 0) {
2141 // Dump all sections for all modules images
2142 const size_t num_modules = target->GetImages().GetSize();
2143 if (num_modules > 0) {
2144 result.GetOutputStream().Printf("Dumping sections for %" PRIu64
2146 (uint64_t)num_modules);
2147 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2148 if (m_interpreter.WasInterrupted())
2152 m_interpreter, result.GetOutputStream(),
2153 target->GetImages().GetModulePointerAtIndex(image_idx));
2156 result.AppendError("the target has no associated executable images");
2157 result.SetStatus(eReturnStatusFailed);
2161 // Dump specified images (by basename or fullpath)
2162 const char *arg_cstr;
2163 for (int arg_idx = 0;
2164 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2166 ModuleList module_list;
2167 const size_t num_matches =
2168 FindModulesByName(target, arg_cstr, module_list, true);
2169 if (num_matches > 0) {
2170 for (size_t i = 0; i < num_matches; ++i) {
2171 if (m_interpreter.WasInterrupted())
2173 Module *module = module_list.GetModulePointerAtIndex(i);
2176 DumpModuleSections(m_interpreter, result.GetOutputStream(),
2181 // Check the global list
2182 std::lock_guard<std::recursive_mutex> guard(
2183 Module::GetAllocationModuleCollectionMutex());
2185 result.AppendWarningWithFormat(
2186 "Unable to find an image that matches '%s'.\n", arg_cstr);
2192 result.SetStatus(eReturnStatusSuccessFinishResult);
2194 result.AppendError("no matching executable images found");
2195 result.SetStatus(eReturnStatusFailed);
2198 return result.Succeeded();
2202 #pragma mark CommandObjectTargetModulesDumpSections
2204 // Clang AST dumping command
2206 class CommandObjectTargetModulesDumpClangAST
2207 : public CommandObjectTargetModulesModuleAutoComplete {
2209 CommandObjectTargetModulesDumpClangAST(CommandInterpreter &interpreter)
2210 : CommandObjectTargetModulesModuleAutoComplete(
2211 interpreter, "target modules dump ast",
2212 "Dump the clang ast for a given module's symbol file.",
2213 //"target modules dump ast [<file1> ...]")
2216 ~CommandObjectTargetModulesDumpClangAST() override = default;
2219 bool DoExecute(Args &command, CommandReturnObject &result) override {
2220 Target *target = GetDebugger().GetSelectedTarget().get();
2221 if (target == nullptr) {
2222 result.AppendError("invalid target, create a debug target using the "
2223 "'target create' command");
2224 result.SetStatus(eReturnStatusFailed);
2228 const size_t num_modules = target->GetImages().GetSize();
2229 if (num_modules == 0) {
2230 result.AppendError("the target has no associated executable images");
2231 result.SetStatus(eReturnStatusFailed);
2235 if (command.GetArgumentCount() == 0) {
2236 // Dump all ASTs for all modules images
2237 result.GetOutputStream().Printf("Dumping clang ast for %" PRIu64
2239 (uint64_t)num_modules);
2240 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2241 if (m_interpreter.WasInterrupted())
2243 Module *m = target->GetImages().GetModulePointerAtIndex(image_idx);
2244 SymbolFile *sf = m->GetSymbolVendor()->GetSymbolFile();
2245 sf->DumpClangAST(result.GetOutputStream());
2247 result.SetStatus(eReturnStatusSuccessFinishResult);
2251 // Dump specified ASTs (by basename or fullpath)
2252 for (const Args::ArgEntry &arg : command.entries()) {
2253 ModuleList module_list;
2254 const size_t num_matches =
2255 FindModulesByName(target, arg.c_str(), module_list, true);
2256 if (num_matches == 0) {
2257 // Check the global list
2258 std::lock_guard<std::recursive_mutex> guard(
2259 Module::GetAllocationModuleCollectionMutex());
2261 result.AppendWarningWithFormat(
2262 "Unable to find an image that matches '%s'.\n", arg.c_str());
2266 for (size_t i = 0; i < num_matches; ++i) {
2267 if (m_interpreter.WasInterrupted())
2269 Module *m = module_list.GetModulePointerAtIndex(i);
2270 SymbolFile *sf = m->GetSymbolVendor()->GetSymbolFile();
2271 sf->DumpClangAST(result.GetOutputStream());
2274 result.SetStatus(eReturnStatusSuccessFinishResult);
2279 #pragma mark CommandObjectTargetModulesDumpSymfile
2281 // Image debug symbol dumping command
2283 class CommandObjectTargetModulesDumpSymfile
2284 : public CommandObjectTargetModulesModuleAutoComplete {
2286 CommandObjectTargetModulesDumpSymfile(CommandInterpreter &interpreter)
2287 : CommandObjectTargetModulesModuleAutoComplete(
2288 interpreter, "target modules dump symfile",
2289 "Dump the debug symbol file for one or more target modules.",
2290 //"target modules dump symfile [<file1> ...]")
2293 ~CommandObjectTargetModulesDumpSymfile() override = default;
2296 bool DoExecute(Args &command, CommandReturnObject &result) override {
2297 Target *target = GetDebugger().GetSelectedTarget().get();
2298 if (target == nullptr) {
2299 result.AppendError("invalid target, create a debug target using the "
2300 "'target create' command");
2301 result.SetStatus(eReturnStatusFailed);
2304 uint32_t num_dumped = 0;
2306 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2307 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2308 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2310 if (command.GetArgumentCount() == 0) {
2311 // Dump all sections for all modules images
2312 const ModuleList &target_modules = target->GetImages();
2313 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2314 const size_t num_modules = target_modules.GetSize();
2315 if (num_modules > 0) {
2316 result.GetOutputStream().Printf("Dumping debug symbols for %" PRIu64
2318 (uint64_t)num_modules);
2319 for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2320 if (m_interpreter.WasInterrupted())
2322 if (DumpModuleSymbolVendor(
2323 result.GetOutputStream(),
2324 target_modules.GetModulePointerAtIndexUnlocked(image_idx)))
2328 result.AppendError("the target has no associated executable images");
2329 result.SetStatus(eReturnStatusFailed);
2333 // Dump specified images (by basename or fullpath)
2334 const char *arg_cstr;
2335 for (int arg_idx = 0;
2336 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2338 ModuleList module_list;
2339 const size_t num_matches =
2340 FindModulesByName(target, arg_cstr, module_list, true);
2341 if (num_matches > 0) {
2342 for (size_t i = 0; i < num_matches; ++i) {
2343 if (m_interpreter.WasInterrupted())
2345 Module *module = module_list.GetModulePointerAtIndex(i);
2347 if (DumpModuleSymbolVendor(result.GetOutputStream(), module))
2352 result.AppendWarningWithFormat(
2353 "Unable to find an image that matches '%s'.\n", arg_cstr);
2358 result.SetStatus(eReturnStatusSuccessFinishResult);
2360 result.AppendError("no matching executable images found");
2361 result.SetStatus(eReturnStatusFailed);
2364 return result.Succeeded();
2368 #pragma mark CommandObjectTargetModulesDumpLineTable
2370 // Image debug line table dumping command
2372 class CommandObjectTargetModulesDumpLineTable
2373 : public CommandObjectTargetModulesSourceFileAutoComplete {
2375 CommandObjectTargetModulesDumpLineTable(CommandInterpreter &interpreter)
2376 : CommandObjectTargetModulesSourceFileAutoComplete(
2377 interpreter, "target modules dump line-table",
2378 "Dump the line table for one or more compilation units.", nullptr,
2379 eCommandRequiresTarget) {}
2381 ~CommandObjectTargetModulesDumpLineTable() override = default;
2383 Options *GetOptions() override { return &m_options; }
2386 bool DoExecute(Args &command, CommandReturnObject &result) override {
2387 Target *target = m_exe_ctx.GetTargetPtr();
2388 uint32_t total_num_dumped = 0;
2390 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2391 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2392 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2394 if (command.GetArgumentCount() == 0) {
2395 result.AppendError("file option must be specified.");
2396 result.SetStatus(eReturnStatusFailed);
2397 return result.Succeeded();
2399 // Dump specified images (by basename or fullpath)
2400 const char *arg_cstr;
2401 for (int arg_idx = 0;
2402 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2404 FileSpec file_spec(arg_cstr);
2406 const ModuleList &target_modules = target->GetImages();
2407 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2408 const size_t num_modules = target_modules.GetSize();
2409 if (num_modules > 0) {
2410 uint32_t num_dumped = 0;
2411 for (uint32_t i = 0; i < num_modules; ++i) {
2412 if (m_interpreter.WasInterrupted())
2414 if (DumpCompileUnitLineTable(
2415 m_interpreter, result.GetOutputStream(),
2416 target_modules.GetModulePointerAtIndexUnlocked(i),
2418 m_options.m_verbose ? eDescriptionLevelFull
2419 : eDescriptionLevelBrief))
2422 if (num_dumped == 0)
2423 result.AppendWarningWithFormat(
2424 "No source filenames matched '%s'.\n", arg_cstr);
2426 total_num_dumped += num_dumped;
2431 if (total_num_dumped > 0)
2432 result.SetStatus(eReturnStatusSuccessFinishResult);
2434 result.AppendError("no source filenames matched any command arguments");
2435 result.SetStatus(eReturnStatusFailed);
2437 return result.Succeeded();
2440 class CommandOptions : public Options {
2442 CommandOptions() : Options() { OptionParsingStarting(nullptr); }
2444 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2445 ExecutionContext *execution_context) override {
2446 assert(option_idx == 0 && "We only have one option.");
2452 void OptionParsingStarting(ExecutionContext *execution_context) override {
2456 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2457 static constexpr OptionDefinition g_options[] = {
2462 OptionParser::eNoArgument,
2467 "Enable verbose dump."},
2469 return llvm::makeArrayRef(g_options);
2475 CommandOptions m_options;
2478 #pragma mark CommandObjectTargetModulesDump
2480 // Dump multi-word command for target modules
2482 class CommandObjectTargetModulesDump : public CommandObjectMultiword {
2484 // Constructors and Destructors
2485 CommandObjectTargetModulesDump(CommandInterpreter &interpreter)
2486 : CommandObjectMultiword(
2487 interpreter, "target modules dump",
2488 "Commands for dumping information about one or "
2489 "more target modules.",
2490 "target modules dump "
2491 "[headers|symtab|sections|ast|symfile|line-table] "
2492 "[<file1> <file2> ...]") {
2493 LoadSubCommand("objfile",
2495 new CommandObjectTargetModulesDumpObjfile(interpreter)));
2498 CommandObjectSP(new CommandObjectTargetModulesDumpSymtab(interpreter)));
2499 LoadSubCommand("sections",
2500 CommandObjectSP(new CommandObjectTargetModulesDumpSections(
2502 LoadSubCommand("symfile",
2504 new CommandObjectTargetModulesDumpSymfile(interpreter)));
2506 "ast", CommandObjectSP(
2507 new CommandObjectTargetModulesDumpClangAST(interpreter)));
2508 LoadSubCommand("line-table",
2509 CommandObjectSP(new CommandObjectTargetModulesDumpLineTable(
2513 ~CommandObjectTargetModulesDump() override = default;
2516 class CommandObjectTargetModulesAdd : public CommandObjectParsed {
2518 CommandObjectTargetModulesAdd(CommandInterpreter &interpreter)
2519 : CommandObjectParsed(interpreter, "target modules add",
2520 "Add a new module to the current target's modules.",
2521 "target modules add [<module>]"),
2523 m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
2524 eArgTypeFilename, "Fullpath to a stand alone debug "
2525 "symbols file for when debug symbols "
2526 "are not in the executable.") {
2527 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
2529 m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2530 m_option_group.Finalize();
2533 ~CommandObjectTargetModulesAdd() override = default;
2535 Options *GetOptions() override { return &m_option_group; }
2537 int HandleArgumentCompletion(
2538 CompletionRequest &request,
2539 OptionElementVector &opt_element_vector) override {
2540 CommandCompletions::InvokeCommonCompletionCallbacks(
2541 GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
2543 return request.GetNumberOfMatches();
2547 OptionGroupOptions m_option_group;
2548 OptionGroupUUID m_uuid_option_group;
2549 OptionGroupFile m_symbol_file;
2551 bool DoExecute(Args &args, CommandReturnObject &result) override {
2552 Target *target = GetDebugger().GetSelectedTarget().get();
2553 if (target == nullptr) {
2554 result.AppendError("invalid target, create a debug target using the "
2555 "'target create' command");
2556 result.SetStatus(eReturnStatusFailed);
2561 const size_t argc = args.GetArgumentCount();
2563 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2564 // We are given a UUID only, go locate the file
2565 ModuleSpec module_spec;
2566 module_spec.GetUUID() =
2567 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2568 if (m_symbol_file.GetOptionValue().OptionWasSet())
2569 module_spec.GetSymbolFileSpec() =
2570 m_symbol_file.GetOptionValue().GetCurrentValue();
2571 if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
2572 ModuleSP module_sp(target->GetOrCreateModule(module_spec,
2573 true /* notify */));
2575 result.SetStatus(eReturnStatusSuccessFinishResult);
2579 module_spec.GetUUID().Dump(&strm);
2580 if (module_spec.GetFileSpec()) {
2581 if (module_spec.GetSymbolFileSpec()) {
2582 result.AppendErrorWithFormat(
2583 "Unable to create the executable or symbol file with "
2584 "UUID %s with path %s and symbol file %s",
2586 module_spec.GetFileSpec().GetPath().c_str(),
2587 module_spec.GetSymbolFileSpec().GetPath().c_str());
2589 result.AppendErrorWithFormat(
2590 "Unable to create the executable or symbol file with "
2591 "UUID %s with path %s",
2593 module_spec.GetFileSpec().GetPath().c_str());
2596 result.AppendErrorWithFormat("Unable to create the executable "
2597 "or symbol file with UUID %s",
2600 result.SetStatus(eReturnStatusFailed);
2605 module_spec.GetUUID().Dump(&strm);
2606 result.AppendErrorWithFormat(
2607 "Unable to locate the executable or symbol file with UUID %s",
2609 result.SetStatus(eReturnStatusFailed);
2614 "one or more executable image paths must be specified");
2615 result.SetStatus(eReturnStatusFailed);
2619 for (auto &entry : args.entries()) {
2620 if (entry.ref.empty())
2623 FileSpec file_spec(entry.ref);
2624 if (FileSystem::Instance().Exists(file_spec)) {
2625 ModuleSpec module_spec(file_spec);
2626 if (m_uuid_option_group.GetOptionValue().OptionWasSet())
2627 module_spec.GetUUID() =
2628 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2629 if (m_symbol_file.GetOptionValue().OptionWasSet())
2630 module_spec.GetSymbolFileSpec() =
2631 m_symbol_file.GetOptionValue().GetCurrentValue();
2632 if (!module_spec.GetArchitecture().IsValid())
2633 module_spec.GetArchitecture() = target->GetArchitecture();
2635 ModuleSP module_sp(target->GetOrCreateModule(module_spec,
2636 true /* notify */, &error));
2638 const char *error_cstr = error.AsCString();
2640 result.AppendError(error_cstr);
2642 result.AppendErrorWithFormat("unsupported module: %s",
2644 result.SetStatus(eReturnStatusFailed);
2649 result.SetStatus(eReturnStatusSuccessFinishResult);
2651 std::string resolved_path = file_spec.GetPath();
2652 result.SetStatus(eReturnStatusFailed);
2653 if (resolved_path != entry.ref) {
2654 result.AppendErrorWithFormat(
2655 "invalid module path '%s' with resolved path '%s'\n",
2656 entry.ref.str().c_str(), resolved_path.c_str());
2659 result.AppendErrorWithFormat("invalid module path '%s'\n",
2667 ProcessSP process = target->GetProcessSP();
2673 return result.Succeeded();
2677 class CommandObjectTargetModulesLoad
2678 : public CommandObjectTargetModulesModuleAutoComplete {
2680 CommandObjectTargetModulesLoad(CommandInterpreter &interpreter)
2681 : CommandObjectTargetModulesModuleAutoComplete(
2682 interpreter, "target modules load", "Set the load addresses for "
2683 "one or more sections in a "
2685 "target modules load [--file <module> --uuid <uuid>] <sect-name> "
2686 "<address> [<sect-name> <address> ....]"),
2688 m_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName,
2689 "Fullpath or basename for module to load.", ""),
2690 m_load_option(LLDB_OPT_SET_1, false, "load", 'l',
2691 "Write file contents to the memory.", false, true),
2692 m_pc_option(LLDB_OPT_SET_1, false, "set-pc-to-entry", 'p',
2693 "Set PC to the entry point."
2694 " Only applicable with '--load' option.",
2696 m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset,
2697 "Set the load address for all sections to be the "
2698 "virtual address in the file plus the offset.",
2700 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
2702 m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2703 m_option_group.Append(&m_load_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2704 m_option_group.Append(&m_pc_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2705 m_option_group.Append(&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2706 m_option_group.Finalize();
2709 ~CommandObjectTargetModulesLoad() override = default;
2711 Options *GetOptions() override { return &m_option_group; }
2714 bool DoExecute(Args &args, CommandReturnObject &result) override {
2715 Target *target = GetDebugger().GetSelectedTarget().get();
2716 const bool load = m_load_option.GetOptionValue().GetCurrentValue();
2717 const bool set_pc = m_pc_option.GetOptionValue().GetCurrentValue();
2718 if (target == nullptr) {
2719 result.AppendError("invalid target, create a debug target using the "
2720 "'target create' command");
2721 result.SetStatus(eReturnStatusFailed);
2724 const size_t argc = args.GetArgumentCount();
2725 ModuleSpec module_spec;
2726 bool search_using_module_spec = false;
2728 // Allow "load" option to work without --file or --uuid option.
2730 if (!m_file_option.GetOptionValue().OptionWasSet() &&
2731 !m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2732 ModuleList &module_list = target->GetImages();
2733 if (module_list.GetSize() == 1) {
2734 search_using_module_spec = true;
2735 module_spec.GetFileSpec() =
2736 module_list.GetModuleAtIndex(0)->GetFileSpec();
2741 if (m_file_option.GetOptionValue().OptionWasSet()) {
2742 search_using_module_spec = true;
2743 const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
2744 const bool use_global_module_list = true;
2745 ModuleList module_list;
2746 const size_t num_matches = FindModulesByName(
2747 target, arg_cstr, module_list, use_global_module_list);
2748 if (num_matches == 1) {
2749 module_spec.GetFileSpec() =
2750 module_list.GetModuleAtIndex(0)->GetFileSpec();
2751 } else if (num_matches > 1) {
2752 search_using_module_spec = false;
2753 result.AppendErrorWithFormat(
2754 "more than 1 module matched by name '%s'\n", arg_cstr);
2755 result.SetStatus(eReturnStatusFailed);
2757 search_using_module_spec = false;
2758 result.AppendErrorWithFormat("no object file for module '%s'\n",
2760 result.SetStatus(eReturnStatusFailed);
2764 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2765 search_using_module_spec = true;
2766 module_spec.GetUUID() =
2767 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2770 if (search_using_module_spec) {
2771 ModuleList matching_modules;
2772 const size_t num_matches =
2773 target->GetImages().FindModules(module_spec, matching_modules);
2775 char path[PATH_MAX];
2776 if (num_matches == 1) {
2777 Module *module = matching_modules.GetModulePointerAtIndex(0);
2779 ObjectFile *objfile = module->GetObjectFile();
2781 SectionList *section_list = module->GetSectionList();
2783 bool changed = false;
2785 if (m_slide_option.GetOptionValue().OptionWasSet()) {
2786 const addr_t slide =
2787 m_slide_option.GetOptionValue().GetCurrentValue();
2788 const bool slide_is_offset = true;
2789 module->SetLoadAddress(*target, slide, slide_is_offset,
2792 result.AppendError("one or more section name + load "
2793 "address pair must be specified");
2794 result.SetStatus(eReturnStatusFailed);
2798 if (m_slide_option.GetOptionValue().OptionWasSet()) {
2799 result.AppendError("The \"--slide <offset>\" option can't "
2800 "be used in conjunction with setting "
2801 "section load addresses.\n");
2802 result.SetStatus(eReturnStatusFailed);
2806 for (size_t i = 0; i < argc; i += 2) {
2807 const char *sect_name = args.GetArgumentAtIndex(i);
2808 const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1);
2809 if (sect_name && load_addr_cstr) {
2810 ConstString const_sect_name(sect_name);
2811 bool success = false;
2812 addr_t load_addr = StringConvert::ToUInt64(
2813 load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success);
2815 SectionSP section_sp(
2816 section_list->FindSectionByName(const_sect_name));
2818 if (section_sp->IsThreadSpecific()) {
2819 result.AppendErrorWithFormat(
2820 "thread specific sections are not yet "
2821 "supported (section '%s')\n",
2823 result.SetStatus(eReturnStatusFailed);
2826 if (target->GetSectionLoadList()
2827 .SetSectionLoadAddress(section_sp,
2830 result.AppendMessageWithFormat(
2831 "section '%s' loaded at 0x%" PRIx64 "\n",
2832 sect_name, load_addr);
2835 result.AppendErrorWithFormat("no section found that "
2836 "matches the section "
2839 result.SetStatus(eReturnStatusFailed);
2843 result.AppendErrorWithFormat(
2844 "invalid load address string '%s'\n",
2846 result.SetStatus(eReturnStatusFailed);
2851 result.AppendError("section names must be followed by "
2852 "a load address.\n");
2854 result.AppendError("one or more section name + load "
2855 "address pair must be specified.\n");
2856 result.SetStatus(eReturnStatusFailed);
2863 target->ModulesDidLoad(matching_modules);
2864 Process *process = m_exe_ctx.GetProcessPtr();
2869 ProcessSP process = target->CalculateProcess();
2870 Address file_entry = objfile->GetEntryPointAddress();
2872 result.AppendError("No process");
2875 if (set_pc && !file_entry.IsValid()) {
2876 result.AppendError("No entry address in object file");
2879 std::vector<ObjectFile::LoadableData> loadables(
2880 objfile->GetLoadableData(*target));
2881 if (loadables.size() == 0) {
2882 result.AppendError("No loadable sections");
2885 Status error = process->WriteObjectFile(std::move(loadables));
2887 result.AppendError(error.AsCString());
2891 ThreadList &thread_list = process->GetThreadList();
2892 RegisterContextSP reg_context(
2893 thread_list.GetSelectedThread()->GetRegisterContext());
2894 addr_t file_entry_addr = file_entry.GetLoadAddress(target);
2895 if (!reg_context->SetPC(file_entry_addr)) {
2896 result.AppendErrorWithFormat("failed to set PC value to "
2899 result.SetStatus(eReturnStatusFailed);
2904 module->GetFileSpec().GetPath(path, sizeof(path));
2905 result.AppendErrorWithFormat(
2906 "no sections in object file '%s'\n", path);
2907 result.SetStatus(eReturnStatusFailed);
2910 module->GetFileSpec().GetPath(path, sizeof(path));
2911 result.AppendErrorWithFormat("no object file for module '%s'\n",
2913 result.SetStatus(eReturnStatusFailed);
2916 FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
2917 if (module_spec_file) {
2918 module_spec_file->GetPath(path, sizeof(path));
2919 result.AppendErrorWithFormat("invalid module '%s'.\n", path);
2921 result.AppendError("no module spec");
2922 result.SetStatus(eReturnStatusFailed);
2925 std::string uuid_str;
2927 if (module_spec.GetFileSpec())
2928 module_spec.GetFileSpec().GetPath(path, sizeof(path));
2932 if (module_spec.GetUUIDPtr())
2933 uuid_str = module_spec.GetUUID().GetAsString();
2934 if (num_matches > 1) {
2935 result.AppendErrorWithFormat(
2936 "multiple modules match%s%s%s%s:\n", path[0] ? " file=" : "",
2937 path, !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
2938 for (size_t i = 0; i < num_matches; ++i) {
2939 if (matching_modules.GetModulePointerAtIndex(i)
2941 .GetPath(path, sizeof(path)))
2942 result.AppendMessageWithFormat("%s\n", path);
2945 result.AppendErrorWithFormat(
2946 "no modules were found that match%s%s%s%s.\n",
2947 path[0] ? " file=" : "", path,
2948 !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
2950 result.SetStatus(eReturnStatusFailed);
2953 result.AppendError("either the \"--file <module>\" or the \"--uuid "
2954 "<uuid>\" option must be specified.\n");
2955 result.SetStatus(eReturnStatusFailed);
2959 return result.Succeeded();
2962 OptionGroupOptions m_option_group;
2963 OptionGroupUUID m_uuid_option_group;
2964 OptionGroupString m_file_option;
2965 OptionGroupBoolean m_load_option;
2966 OptionGroupBoolean m_pc_option;
2967 OptionGroupUInt64 m_slide_option;
2970 // List images with associated information
2972 static constexpr OptionDefinition g_target_modules_list_options[] = {
2974 { LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Display the image at this address." },
2975 { LLDB_OPT_SET_1, false, "arch", 'A', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the architecture when listing images." },
2976 { LLDB_OPT_SET_1, false, "triple", 't', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the triple when listing images." },
2977 { LLDB_OPT_SET_1, false, "header", 'h', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display the image base address as a load address if debugging, a file address otherwise." },
2978 { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display the image load address offset from the base file address (the slide amount)." },
2979 { LLDB_OPT_SET_1, false, "uuid", 'u', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display the UUID when listing images." },
2980 { LLDB_OPT_SET_1, false, "fullpath", 'f', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the fullpath to the image object file." },
2981 { LLDB_OPT_SET_1, false, "directory", 'd', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the directory with optional width for the image object file." },
2982 { LLDB_OPT_SET_1, false, "basename", 'b', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the basename with optional width for the image object file." },
2983 { LLDB_OPT_SET_1, false, "symfile", 's', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width." },
2984 { LLDB_OPT_SET_1, false, "symfile-unique", 'S', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the symbol file with optional width only if it is different from the executable object file." },
2985 { LLDB_OPT_SET_1, false, "mod-time", 'm', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the modification time with optional width of the module." },
2986 { LLDB_OPT_SET_1, false, "ref-count", 'r', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the reference count if the module is still in the shared module cache." },
2987 { LLDB_OPT_SET_1, false, "pointer", 'p', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeNone, "Display the module pointer." },
2988 { LLDB_OPT_SET_1, false, "global", 'g', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display the modules from the global module list, not just the current target." }
2992 class CommandObjectTargetModulesList : public CommandObjectParsed {
2994 class CommandOptions : public Options {
2997 : Options(), m_format_array(), m_use_global_module_list(false),
2998 m_module_addr(LLDB_INVALID_ADDRESS) {}
3000 ~CommandOptions() override = default;
3002 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3003 ExecutionContext *execution_context) override {
3006 const int short_option = m_getopt_table[option_idx].val;
3007 if (short_option == 'g') {
3008 m_use_global_module_list = true;
3009 } else if (short_option == 'a') {
3010 m_module_addr = OptionArgParser::ToAddress(
3011 execution_context, option_arg, LLDB_INVALID_ADDRESS, &error);
3013 unsigned long width = 0;
3014 option_arg.getAsInteger(0, width);
3015 m_format_array.push_back(std::make_pair(short_option, width));
3020 void OptionParsingStarting(ExecutionContext *execution_context) override {
3021 m_format_array.clear();
3022 m_use_global_module_list = false;
3023 m_module_addr = LLDB_INVALID_ADDRESS;
3026 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3027 return llvm::makeArrayRef(g_target_modules_list_options);
3030 // Instance variables to hold the values for command options.
3031 typedef std::vector<std::pair<char, uint32_t>> FormatWidthCollection;
3032 FormatWidthCollection m_format_array;
3033 bool m_use_global_module_list;
3034 lldb::addr_t m_module_addr;
3037 CommandObjectTargetModulesList(CommandInterpreter &interpreter)
3038 : CommandObjectParsed(
3039 interpreter, "target modules list",
3040 "List current executable and dependent shared library images.",
3041 "target modules list [<cmd-options>]"),
3044 ~CommandObjectTargetModulesList() override = default;
3046 Options *GetOptions() override { return &m_options; }
3049 bool DoExecute(Args &command, CommandReturnObject &result) override {
3050 Target *target = GetDebugger().GetSelectedTarget().get();
3051 const bool use_global_module_list = m_options.m_use_global_module_list;
3052 // Define a local module list here to ensure it lives longer than any
3053 // "locker" object which might lock its contents below (through the
3054 // "module_list_ptr" variable).
3055 ModuleList module_list;
3056 if (target == nullptr && !use_global_module_list) {
3057 result.AppendError("invalid target, create a debug target using the "
3058 "'target create' command");
3059 result.SetStatus(eReturnStatusFailed);
3063 uint32_t addr_byte_size =
3064 target->GetArchitecture().GetAddressByteSize();
3065 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3066 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3068 // Dump all sections for all modules images
3069 Stream &strm = result.GetOutputStream();
3071 if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) {
3073 Address module_address;
3074 if (module_address.SetLoadAddress(m_options.m_module_addr, target)) {
3075 ModuleSP module_sp(module_address.GetModule());
3077 PrintModule(target, module_sp.get(), 0, strm);
3078 result.SetStatus(eReturnStatusSuccessFinishResult);
3080 result.AppendErrorWithFormat(
3081 "Couldn't find module matching address: 0x%" PRIx64 ".",
3082 m_options.m_module_addr);
3083 result.SetStatus(eReturnStatusFailed);
3086 result.AppendErrorWithFormat(
3087 "Couldn't find module containing address: 0x%" PRIx64 ".",
3088 m_options.m_module_addr);
3089 result.SetStatus(eReturnStatusFailed);
3093 "Can only look up modules by address with a valid target.");
3094 result.SetStatus(eReturnStatusFailed);
3096 return result.Succeeded();
3099 size_t num_modules = 0;
3101 // This locker will be locked on the mutex in module_list_ptr if it is
3102 // non-nullptr. Otherwise it will lock the
3103 // AllocationModuleCollectionMutex when accessing the global module list
3105 std::unique_lock<std::recursive_mutex> guard(
3106 Module::GetAllocationModuleCollectionMutex(), std::defer_lock);
3108 const ModuleList *module_list_ptr = nullptr;
3109 const size_t argc = command.GetArgumentCount();
3111 if (use_global_module_list) {
3113 num_modules = Module::GetNumberAllocatedModules();
3115 module_list_ptr = &target->GetImages();
3118 // TODO: Convert to entry based iteration. Requires converting
3119 // FindModulesByName.
3120 for (size_t i = 0; i < argc; ++i) {
3121 // Dump specified images (by basename or fullpath)
3122 const char *arg_cstr = command.GetArgumentAtIndex(i);
3123 const size_t num_matches = FindModulesByName(
3124 target, arg_cstr, module_list, use_global_module_list);
3125 if (num_matches == 0) {
3127 result.AppendErrorWithFormat("no modules found that match '%s'",
3129 result.SetStatus(eReturnStatusFailed);
3135 module_list_ptr = &module_list;
3138 std::unique_lock<std::recursive_mutex> lock;
3139 if (module_list_ptr != nullptr) {
3141 std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex());
3143 num_modules = module_list_ptr->GetSize();
3146 if (num_modules > 0) {
3147 for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
3150 if (module_list_ptr) {
3151 module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
3152 module = module_sp.get();
3154 module = Module::GetAllocatedModuleAtIndex(image_idx);
3155 module_sp = module->shared_from_this();
3158 const size_t indent = strm.Printf("[%3u] ", image_idx);
3159 PrintModule(target, module, indent, strm);
3161 result.SetStatus(eReturnStatusSuccessFinishResult);
3164 if (use_global_module_list)
3166 "the global module list has no matching modules");
3168 result.AppendError("the target has no matching modules");
3170 if (use_global_module_list)
3171 result.AppendError("the global module list is empty");
3174 "the target has no associated executable images");
3176 result.SetStatus(eReturnStatusFailed);
3180 return result.Succeeded();
3183 void PrintModule(Target *target, Module *module, int indent, Stream &strm) {
3184 if (module == nullptr) {
3185 strm.PutCString("Null module");
3189 bool dump_object_name = false;
3190 if (m_options.m_format_array.empty()) {
3191 m_options.m_format_array.push_back(std::make_pair('u', 0));
3192 m_options.m_format_array.push_back(std::make_pair('h', 0));
3193 m_options.m_format_array.push_back(std::make_pair('f', 0));
3194 m_options.m_format_array.push_back(std::make_pair('S', 0));
3196 const size_t num_entries = m_options.m_format_array.size();
3197 bool print_space = false;
3198 for (size_t i = 0; i < num_entries; ++i) {
3202 const char format_char = m_options.m_format_array[i].first;
3203 uint32_t width = m_options.m_format_array[i].second;
3204 switch (format_char) {
3206 DumpModuleArchitecture(strm, module, false, width);
3210 DumpModuleArchitecture(strm, module, true, width);
3214 DumpFullpath(strm, &module->GetFileSpec(), width);
3215 dump_object_name = true;
3219 DumpDirectory(strm, &module->GetFileSpec(), width);
3223 DumpBasename(strm, &module->GetFileSpec(), width);
3224 dump_object_name = true;
3229 // Image header address
3231 uint32_t addr_nibble_width =
3232 target ? (target->GetArchitecture().GetAddressByteSize() * 2)
3235 ObjectFile *objfile = module->GetObjectFile();
3237 Address base_addr(objfile->GetBaseAddress());
3238 if (base_addr.IsValid()) {
3239 if (target && !target->GetSectionLoadList().IsEmpty()) {
3240 lldb::addr_t load_addr =
3241 base_addr.GetLoadAddress(target);
3242 if (load_addr == LLDB_INVALID_ADDRESS) {
3243 base_addr.Dump(&strm, target,
3244 Address::DumpStyleModuleWithFileAddress,
3245 Address::DumpStyleFileAddress);
3247 if (format_char == 'o') {
3248 // Show the offset of slide for the image
3250 "0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width,
3251 load_addr - base_addr.GetFileAddress());
3253 // Show the load address of the image
3254 strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3255 addr_nibble_width, load_addr);
3260 // The address was valid, but the image isn't loaded, output the
3261 // address in an appropriate format
3262 base_addr.Dump(&strm, target, Address::DumpStyleFileAddress);
3266 strm.Printf("%*s", addr_nibble_width + 2, "");
3271 size_t ref_count = 0;
3272 ModuleSP module_sp(module->shared_from_this());
3274 // Take one away to make sure we don't count our local "module_sp"
3275 ref_count = module_sp.use_count() - 1;
3278 strm.Printf("{%*" PRIu64 "}", width, (uint64_t)ref_count);
3280 strm.Printf("{%" PRIu64 "}", (uint64_t)ref_count);
3285 const SymbolVendor *symbol_vendor = module->GetSymbolVendor();
3286 if (symbol_vendor) {
3287 const FileSpec symfile_spec = symbol_vendor->GetMainFileSpec();
3288 if (format_char == 'S') {
3289 // Dump symbol file only if different from module file
3290 if (!symfile_spec || symfile_spec == module->GetFileSpec()) {
3291 print_space = false;
3294 // Add a newline and indent past the index
3295 strm.Printf("\n%*s", indent, "");
3297 DumpFullpath(strm, &symfile_spec, width);
3298 dump_object_name = true;
3301 strm.Printf("%.*s", width, "<NONE>");
3305 strm.Format("{0:%c}", llvm::fmt_align(module->GetModificationTime(),
3306 llvm::AlignStyle::Left, width));
3310 strm.Printf("%p", static_cast<void *>(module));
3314 DumpModuleUUID(strm, module);
3321 if (dump_object_name) {
3322 const char *object_name = module->GetObjectName().GetCString();
3324 strm.Printf("(%s)", object_name);
3329 CommandOptions m_options;
3332 #pragma mark CommandObjectTargetModulesShowUnwind
3334 // Lookup unwind information in images
3336 static constexpr OptionDefinition g_target_modules_show_unwind_options[] = {
3338 { LLDB_OPT_SET_1, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFunctionName, "Show unwind instructions for a function or symbol name." },
3339 { LLDB_OPT_SET_2, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address" }
3343 class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {
3346 eLookupTypeInvalid = -1,
3347 eLookupTypeAddress = 0,
3349 eLookupTypeFunction,
3350 eLookupTypeFunctionOrSymbol,
3354 class CommandOptions : public Options {
3357 : Options(), m_type(eLookupTypeInvalid), m_str(),
3358 m_addr(LLDB_INVALID_ADDRESS) {}
3360 ~CommandOptions() override = default;
3362 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3363 ExecutionContext *execution_context) override {
3366 const int short_option = m_getopt_table[option_idx].val;
3368 switch (short_option) {
3371 m_type = eLookupTypeAddress;
3372 m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
3373 LLDB_INVALID_ADDRESS, &error);
3374 if (m_addr == LLDB_INVALID_ADDRESS)
3375 error.SetErrorStringWithFormat("invalid address string '%s'",
3376 option_arg.str().c_str());
3382 m_type = eLookupTypeFunctionOrSymbol;
3386 error.SetErrorStringWithFormat("unrecognized option %c.", short_option);
3393 void OptionParsingStarting(ExecutionContext *execution_context) override {
3394 m_type = eLookupTypeInvalid;
3396 m_addr = LLDB_INVALID_ADDRESS;
3399 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3400 return llvm::makeArrayRef(g_target_modules_show_unwind_options);
3403 // Instance variables to hold the values for command options.
3405 int m_type; // Should be a eLookupTypeXXX enum after parsing options
3406 std::string m_str; // Holds name lookup
3407 lldb::addr_t m_addr; // Holds the address to lookup
3410 CommandObjectTargetModulesShowUnwind(CommandInterpreter &interpreter)
3411 : CommandObjectParsed(
3412 interpreter, "target modules show-unwind",
3413 "Show synthesized unwind instructions for a function.", nullptr,
3414 eCommandRequiresTarget | eCommandRequiresProcess |
3415 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
3418 ~CommandObjectTargetModulesShowUnwind() override = default;
3420 Options *GetOptions() override { return &m_options; }
3423 bool DoExecute(Args &command, CommandReturnObject &result) override {
3424 Target *target = m_exe_ctx.GetTargetPtr();
3425 Process *process = m_exe_ctx.GetProcessPtr();
3428 abi = process->GetABI().get();
3430 if (process == nullptr) {
3432 "You must have a process running to use this command.");
3433 result.SetStatus(eReturnStatusFailed);
3437 ThreadList threads(process->GetThreadList());
3438 if (threads.GetSize() == 0) {
3439 result.AppendError("The process must be paused to use this command.");
3440 result.SetStatus(eReturnStatusFailed);
3444 ThreadSP thread(threads.GetThreadAtIndex(0));
3446 result.AppendError("The process must be paused to use this command.");
3447 result.SetStatus(eReturnStatusFailed);
3451 SymbolContextList sc_list;
3453 if (m_options.m_type == eLookupTypeFunctionOrSymbol) {
3454 ConstString function_name(m_options.m_str.c_str());
3455 target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto,
3456 true, false, true, sc_list);
3457 } else if (m_options.m_type == eLookupTypeAddress && target) {
3459 if (target->GetSectionLoadList().ResolveLoadAddress(m_options.m_addr,
3462 ModuleSP module_sp(addr.GetModule());
3463 module_sp->ResolveSymbolContextForAddress(addr,
3464 eSymbolContextEverything, sc);
3465 if (sc.function || sc.symbol) {
3471 "address-expression or function name option must be specified.");
3472 result.SetStatus(eReturnStatusFailed);
3476 size_t num_matches = sc_list.GetSize();
3477 if (num_matches == 0) {
3478 result.AppendErrorWithFormat("no unwind data found that matches '%s'.",
3479 m_options.m_str.c_str());
3480 result.SetStatus(eReturnStatusFailed);
3484 for (uint32_t idx = 0; idx < num_matches; idx++) {
3486 sc_list.GetContextAtIndex(idx, sc);
3487 if (sc.symbol == nullptr && sc.function == nullptr)
3489 if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr)
3492 if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,
3495 if (!range.GetBaseAddress().IsValid())
3497 ConstString funcname(sc.GetFunctionName());
3498 if (funcname.IsEmpty())
3500 addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
3502 start_addr = abi->FixCodeAddress(start_addr);
3504 FuncUnwindersSP func_unwinders_sp(
3505 sc.module_sp->GetUnwindTable()
3506 .GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
3507 if (!func_unwinders_sp)
3510 result.GetOutputStream().Printf(
3511 "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n\n",
3512 sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(),
3513 funcname.AsCString(), start_addr);
3515 UnwindPlanSP non_callsite_unwind_plan =
3516 func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread);
3517 if (non_callsite_unwind_plan) {
3518 result.GetOutputStream().Printf(
3519 "Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n",
3520 non_callsite_unwind_plan->GetSourceName().AsCString());
3522 UnwindPlanSP callsite_unwind_plan =
3523 func_unwinders_sp->GetUnwindPlanAtCallSite(*target, *thread);
3524 if (callsite_unwind_plan) {
3525 result.GetOutputStream().Printf(
3526 "Synchronous (restricted to call-sites) UnwindPlan is '%s'\n",
3527 callsite_unwind_plan->GetSourceName().AsCString());
3529 UnwindPlanSP fast_unwind_plan =
3530 func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread);
3531 if (fast_unwind_plan) {
3532 result.GetOutputStream().Printf(
3533 "Fast UnwindPlan is '%s'\n",
3534 fast_unwind_plan->GetSourceName().AsCString());
3537 result.GetOutputStream().Printf("\n");
3539 UnwindPlanSP assembly_sp =
3540 func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread);
3542 result.GetOutputStream().Printf(
3543 "Assembly language inspection UnwindPlan:\n");
3544 assembly_sp->Dump(result.GetOutputStream(), thread.get(),
3545 LLDB_INVALID_ADDRESS);
3546 result.GetOutputStream().Printf("\n");
3549 UnwindPlanSP ehframe_sp =
3550 func_unwinders_sp->GetEHFrameUnwindPlan(*target);
3552 result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
3553 ehframe_sp->Dump(result.GetOutputStream(), thread.get(),
3554 LLDB_INVALID_ADDRESS);
3555 result.GetOutputStream().Printf("\n");
3558 UnwindPlanSP ehframe_augmented_sp =
3559 func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread);
3560 if (ehframe_augmented_sp) {
3561 result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
3562 ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
3563 LLDB_INVALID_ADDRESS);
3564 result.GetOutputStream().Printf("\n");
3567 if (UnwindPlanSP plan_sp =
3568 func_unwinders_sp->GetDebugFrameUnwindPlan(*target)) {
3569 result.GetOutputStream().Printf("debug_frame UnwindPlan:\n");
3570 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3571 LLDB_INVALID_ADDRESS);
3572 result.GetOutputStream().Printf("\n");
3575 if (UnwindPlanSP plan_sp =
3576 func_unwinders_sp->GetDebugFrameAugmentedUnwindPlan(*target,
3578 result.GetOutputStream().Printf("debug_frame augmented UnwindPlan:\n");
3579 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3580 LLDB_INVALID_ADDRESS);
3581 result.GetOutputStream().Printf("\n");
3584 UnwindPlanSP arm_unwind_sp =
3585 func_unwinders_sp->GetArmUnwindUnwindPlan(*target);
3586 if (arm_unwind_sp) {
3587 result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
3588 arm_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3589 LLDB_INVALID_ADDRESS);
3590 result.GetOutputStream().Printf("\n");
3593 if (UnwindPlanSP symfile_plan_sp =
3594 func_unwinders_sp->GetSymbolFileUnwindPlan(*thread)) {
3595 result.GetOutputStream().Printf("Symbol file UnwindPlan:\n");
3596 symfile_plan_sp->Dump(result.GetOutputStream(), thread.get(),
3597 LLDB_INVALID_ADDRESS);
3598 result.GetOutputStream().Printf("\n");
3601 UnwindPlanSP compact_unwind_sp =
3602 func_unwinders_sp->GetCompactUnwindUnwindPlan(*target);
3603 if (compact_unwind_sp) {
3604 result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
3605 compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3606 LLDB_INVALID_ADDRESS);
3607 result.GetOutputStream().Printf("\n");
3610 if (fast_unwind_plan) {
3611 result.GetOutputStream().Printf("Fast UnwindPlan:\n");
3612 fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(),
3613 LLDB_INVALID_ADDRESS);
3614 result.GetOutputStream().Printf("\n");
3617 ABISP abi_sp = process->GetABI();
3619 UnwindPlan arch_default(lldb::eRegisterKindGeneric);
3620 if (abi_sp->CreateDefaultUnwindPlan(arch_default)) {
3621 result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
3622 arch_default.Dump(result.GetOutputStream(), thread.get(),
3623 LLDB_INVALID_ADDRESS);
3624 result.GetOutputStream().Printf("\n");
3627 UnwindPlan arch_entry(lldb::eRegisterKindGeneric);
3628 if (abi_sp->CreateFunctionEntryUnwindPlan(arch_entry)) {
3629 result.GetOutputStream().Printf(
3630 "Arch default at entry point UnwindPlan:\n");
3631 arch_entry.Dump(result.GetOutputStream(), thread.get(),
3632 LLDB_INVALID_ADDRESS);
3633 result.GetOutputStream().Printf("\n");
3637 result.GetOutputStream().Printf("\n");
3639 return result.Succeeded();
3642 CommandOptions m_options;
3645 // Lookup information in images
3647 static constexpr OptionDefinition g_target_modules_lookup_options[] = {
3649 { LLDB_OPT_SET_1, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules." },
3650 { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOffset, "When looking up an address subtract <offset> from any addresses before doing the lookup." },
3651 /* FIXME: re-enable regex for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */
3652 { LLDB_OPT_SET_2 | LLDB_OPT_SET_4 | LLDB_OPT_SET_5, false, "regex", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "The <name> argument for name lookups are regular expressions." },
3653 { LLDB_OPT_SET_2, true, "symbol", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeSymbol, "Lookup a symbol by name in the symbol tables in one or more target modules." },
3654 { LLDB_OPT_SET_3, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFilename, "Lookup a file by fullpath or basename in one or more target modules." },
3655 { LLDB_OPT_SET_3, false, "line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "Lookup a line number in a file (must be used in conjunction with --file)." },
3656 { LLDB_OPT_SET_FROM_TO(3,5), false, "no-inlines", 'i', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Ignore inline entries (must be used in conjunction with --file or --function)." },
3657 { LLDB_OPT_SET_4, true, "function", 'F', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFunctionName, "Lookup a function by name in the debug symbols in one or more target modules." },
3658 { LLDB_OPT_SET_5, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFunctionOrSymbol, "Lookup a function or symbol by name in one or more target modules." },
3659 { LLDB_OPT_SET_6, true, "type", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeName, "Lookup a type by name in the debug symbols in one or more target modules." },
3660 { LLDB_OPT_SET_ALL, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Enable verbose lookup information." },
3661 { LLDB_OPT_SET_ALL, false, "all", 'A', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Print all matches, not just the best match, if a best match is available." },
3665 class CommandObjectTargetModulesLookup : public CommandObjectParsed {
3668 eLookupTypeInvalid = -1,
3669 eLookupTypeAddress = 0,
3671 eLookupTypeFileLine, // Line is optional
3672 eLookupTypeFunction,
3673 eLookupTypeFunctionOrSymbol,
3678 class CommandOptions : public Options {
3680 CommandOptions() : Options() { OptionParsingStarting(nullptr); }
3682 ~CommandOptions() override = default;
3684 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3685 ExecutionContext *execution_context) override {
3688 const int short_option = m_getopt_table[option_idx].val;
3690 switch (short_option) {
3692 m_type = eLookupTypeAddress;
3693 m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
3694 LLDB_INVALID_ADDRESS, &error);
3698 if (option_arg.getAsInteger(0, m_offset))
3699 error.SetErrorStringWithFormat("invalid offset string '%s'",
3700 option_arg.str().c_str());
3705 m_type = eLookupTypeSymbol;
3709 m_file.SetFile(option_arg, FileSpec::Style::native);
3710 m_type = eLookupTypeFileLine;
3714 m_include_inlines = false;
3718 if (option_arg.getAsInteger(0, m_line_number))
3719 error.SetErrorStringWithFormat("invalid line number string '%s'",
3720 option_arg.str().c_str());
3721 else if (m_line_number == 0)
3722 error.SetErrorString("zero is an invalid line number");
3723 m_type = eLookupTypeFileLine;
3728 m_type = eLookupTypeFunction;
3733 m_type = eLookupTypeFunctionOrSymbol;
3738 m_type = eLookupTypeType;
3757 void OptionParsingStarting(ExecutionContext *execution_context) override {
3758 m_type = eLookupTypeInvalid;
3761 m_addr = LLDB_INVALID_ADDRESS;
3764 m_use_regex = false;
3765 m_include_inlines = true;
3767 m_print_all = false;
3770 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3771 return llvm::makeArrayRef(g_target_modules_lookup_options);
3774 int m_type; // Should be a eLookupTypeXXX enum after parsing options
3775 std::string m_str; // Holds name lookup
3776 FileSpec m_file; // Files for file lookups
3777 lldb::addr_t m_addr; // Holds the address to lookup
3779 m_offset; // Subtract this offset from m_addr before doing lookups.
3780 uint32_t m_line_number; // Line number for file+line lookups
3781 bool m_use_regex; // Name lookups in m_str are regular expressions.
3782 bool m_include_inlines; // Check for inline entries when looking up by
3784 bool m_verbose; // Enable verbose lookup info
3785 bool m_print_all; // Print all matches, even in cases where there's a best
3789 CommandObjectTargetModulesLookup(CommandInterpreter &interpreter)
3790 : CommandObjectParsed(interpreter, "target modules lookup",
3791 "Look up information within executable and "
3792 "dependent shared library images.",
3793 nullptr, eCommandRequiresTarget),
3795 CommandArgumentEntry arg;
3796 CommandArgumentData file_arg;
3798 // Define the first (and only) variant of this arg.
3799 file_arg.arg_type = eArgTypeFilename;
3800 file_arg.arg_repetition = eArgRepeatStar;
3802 // There is only one variant this argument could be; put it into the
3804 arg.push_back(file_arg);
3806 // Push the data for the first argument into the m_arguments vector.
3807 m_arguments.push_back(arg);
3810 ~CommandObjectTargetModulesLookup() override = default;
3812 Options *GetOptions() override { return &m_options; }
3814 bool LookupHere(CommandInterpreter &interpreter, CommandReturnObject &result,
3815 bool &syntax_error) {
3816 switch (m_options.m_type) {
3817 case eLookupTypeAddress:
3818 case eLookupTypeFileLine:
3819 case eLookupTypeFunction:
3820 case eLookupTypeFunctionOrSymbol:
3821 case eLookupTypeSymbol:
3824 case eLookupTypeType:
3828 StackFrameSP frame = m_exe_ctx.GetFrameSP();
3833 const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
3835 if (!sym_ctx.module_sp)
3838 switch (m_options.m_type) {
3841 case eLookupTypeType:
3842 if (!m_options.m_str.empty()) {
3843 if (LookupTypeHere(m_interpreter, result.GetOutputStream(),
3844 *sym_ctx.module_sp, m_options.m_str.c_str(),
3845 m_options.m_use_regex)) {
3846 result.SetStatus(eReturnStatusSuccessFinishResult);
3856 bool LookupInModule(CommandInterpreter &interpreter, Module *module,
3857 CommandReturnObject &result, bool &syntax_error) {
3858 switch (m_options.m_type) {
3859 case eLookupTypeAddress:
3860 if (m_options.m_addr != LLDB_INVALID_ADDRESS) {
3861 if (LookupAddressInModule(
3862 m_interpreter, result.GetOutputStream(), module,
3863 eSymbolContextEverything |
3864 (m_options.m_verbose
3865 ? static_cast<int>(eSymbolContextVariable)
3867 m_options.m_addr, m_options.m_offset, m_options.m_verbose)) {
3868 result.SetStatus(eReturnStatusSuccessFinishResult);
3874 case eLookupTypeSymbol:
3875 if (!m_options.m_str.empty()) {
3876 if (LookupSymbolInModule(m_interpreter, result.GetOutputStream(),
3877 module, m_options.m_str.c_str(),
3878 m_options.m_use_regex, m_options.m_verbose)) {
3879 result.SetStatus(eReturnStatusSuccessFinishResult);
3885 case eLookupTypeFileLine:
3886 if (m_options.m_file) {
3887 if (LookupFileAndLineInModule(
3888 m_interpreter, result.GetOutputStream(), module,
3889 m_options.m_file, m_options.m_line_number,
3890 m_options.m_include_inlines, m_options.m_verbose)) {
3891 result.SetStatus(eReturnStatusSuccessFinishResult);
3897 case eLookupTypeFunctionOrSymbol:
3898 case eLookupTypeFunction:
3899 if (!m_options.m_str.empty()) {
3900 if (LookupFunctionInModule(
3901 m_interpreter, result.GetOutputStream(), module,
3902 m_options.m_str.c_str(), m_options.m_use_regex,
3903 m_options.m_include_inlines,
3905 eLookupTypeFunctionOrSymbol, // include symbols
3906 m_options.m_verbose)) {
3907 result.SetStatus(eReturnStatusSuccessFinishResult);
3913 case eLookupTypeType:
3914 if (!m_options.m_str.empty()) {
3915 if (LookupTypeInModule(m_interpreter, result.GetOutputStream(), module,
3916 m_options.m_str.c_str(),
3917 m_options.m_use_regex)) {
3918 result.SetStatus(eReturnStatusSuccessFinishResult);
3925 m_options.GenerateOptionUsage(
3926 result.GetErrorStream(), this,
3927 GetCommandInterpreter().GetDebugger().GetTerminalWidth());
3928 syntax_error = true;
3932 result.SetStatus(eReturnStatusFailed);
3937 bool DoExecute(Args &command, CommandReturnObject &result) override {
3938 Target *target = GetDebugger().GetSelectedTarget().get();
3939 if (target == nullptr) {
3940 result.AppendError("invalid target, create a debug target using the "
3941 "'target create' command");
3942 result.SetStatus(eReturnStatusFailed);
3945 bool syntax_error = false;
3947 uint32_t num_successful_lookups = 0;
3948 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
3949 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3950 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3951 // Dump all sections for all modules images
3953 if (command.GetArgumentCount() == 0) {
3954 ModuleSP current_module;
3956 // Where it is possible to look in the current symbol context first,
3957 // try that. If this search was successful and --all was not passed,
3958 // don't print anything else.
3959 if (LookupHere(m_interpreter, result, syntax_error)) {
3960 result.GetOutputStream().EOL();
3961 num_successful_lookups++;
3962 if (!m_options.m_print_all) {
3963 result.SetStatus(eReturnStatusSuccessFinishResult);
3964 return result.Succeeded();
3968 // Dump all sections for all other modules
3970 const ModuleList &target_modules = target->GetImages();
3971 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
3972 const size_t num_modules = target_modules.GetSize();
3973 if (num_modules > 0) {
3974 for (i = 0; i < num_modules && !syntax_error; ++i) {
3975 Module *module_pointer =
3976 target_modules.GetModulePointerAtIndexUnlocked(i);
3978 if (module_pointer != current_module.get() &&
3981 target_modules.GetModulePointerAtIndexUnlocked(i), result,
3983 result.GetOutputStream().EOL();
3984 num_successful_lookups++;
3988 result.AppendError("the target has no associated executable images");
3989 result.SetStatus(eReturnStatusFailed);
3993 // Dump specified images (by basename or fullpath)
3994 const char *arg_cstr;
3995 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr &&
3998 ModuleList module_list;
3999 const size_t num_matches =
4000 FindModulesByName(target, arg_cstr, module_list, false);
4001 if (num_matches > 0) {
4002 for (size_t j = 0; j < num_matches; ++j) {
4003 Module *module = module_list.GetModulePointerAtIndex(j);
4005 if (LookupInModule(m_interpreter, module, result,
4007 result.GetOutputStream().EOL();
4008 num_successful_lookups++;
4013 result.AppendWarningWithFormat(
4014 "Unable to find an image that matches '%s'.\n", arg_cstr);
4018 if (num_successful_lookups > 0)
4019 result.SetStatus(eReturnStatusSuccessFinishResult);
4021 result.SetStatus(eReturnStatusFailed);
4023 return result.Succeeded();
4026 CommandOptions m_options;
4029 #pragma mark CommandObjectMultiwordImageSearchPaths
4031 // CommandObjectMultiwordImageSearchPaths
4033 class CommandObjectTargetModulesImageSearchPaths
4034 : public CommandObjectMultiword {
4036 CommandObjectTargetModulesImageSearchPaths(CommandInterpreter &interpreter)
4037 : CommandObjectMultiword(
4038 interpreter, "target modules search-paths",
4039 "Commands for managing module search paths for a target.",
4040 "target modules search-paths <subcommand> [<subcommand-options>]") {
4042 "add", CommandObjectSP(
4043 new CommandObjectTargetModulesSearchPathsAdd(interpreter)));
4045 "clear", CommandObjectSP(new CommandObjectTargetModulesSearchPathsClear(
4050 new CommandObjectTargetModulesSearchPathsInsert(interpreter)));
4052 "list", CommandObjectSP(new CommandObjectTargetModulesSearchPathsList(
4055 "query", CommandObjectSP(new CommandObjectTargetModulesSearchPathsQuery(
4059 ~CommandObjectTargetModulesImageSearchPaths() override = default;
4062 #pragma mark CommandObjectTargetModules
4064 // CommandObjectTargetModules
4066 class CommandObjectTargetModules : public CommandObjectMultiword {
4068 // Constructors and Destructors
4069 CommandObjectTargetModules(CommandInterpreter &interpreter)
4070 : CommandObjectMultiword(interpreter, "target modules",
4071 "Commands for accessing information for one or "
4072 "more target modules.",
4073 "target modules <sub-command> ...") {
4075 "add", CommandObjectSP(new CommandObjectTargetModulesAdd(interpreter)));
4076 LoadSubCommand("load", CommandObjectSP(new CommandObjectTargetModulesLoad(
4078 LoadSubCommand("dump", CommandObjectSP(new CommandObjectTargetModulesDump(
4080 LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetModulesList(
4084 CommandObjectSP(new CommandObjectTargetModulesLookup(interpreter)));
4088 new CommandObjectTargetModulesImageSearchPaths(interpreter)));
4091 CommandObjectSP(new CommandObjectTargetModulesShowUnwind(interpreter)));
4094 ~CommandObjectTargetModules() override = default;
4097 // For CommandObjectTargetModules only
4098 DISALLOW_COPY_AND_ASSIGN(CommandObjectTargetModules);
4101 class CommandObjectTargetSymbolsAdd : public CommandObjectParsed {
4103 CommandObjectTargetSymbolsAdd(CommandInterpreter &interpreter)
4104 : CommandObjectParsed(
4105 interpreter, "target symbols add",
4106 "Add a debug symbol file to one of the target's current modules by "
4107 "specifying a path to a debug symbols file, or using the options "
4108 "to specify a module to download symbols for.",
4109 "target symbols add <cmd-options> [<symfile>]",
4110 eCommandRequiresTarget),
4113 LLDB_OPT_SET_1, false, "shlib", 's',
4114 CommandCompletions::eModuleCompletion, eArgTypeShlibName,
4115 "Fullpath or basename for module to find debug symbols for."),
4116 m_current_frame_option(
4117 LLDB_OPT_SET_2, false, "frame", 'F',
4118 "Locate the debug symbols the currently selected frame.", false,
4122 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
4124 m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
4125 m_option_group.Append(&m_current_frame_option, LLDB_OPT_SET_2,
4127 m_option_group.Finalize();
4130 ~CommandObjectTargetSymbolsAdd() override = default;
4132 int HandleArgumentCompletion(
4133 CompletionRequest &request,
4134 OptionElementVector &opt_element_vector) override {
4135 CommandCompletions::InvokeCommonCompletionCallbacks(
4136 GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
4138 return request.GetNumberOfMatches();
4141 Options *GetOptions() override { return &m_option_group; }
4144 bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush,
4145 CommandReturnObject &result) {
4146 const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
4148 char symfile_path[PATH_MAX];
4149 symbol_fspec.GetPath(symfile_path, sizeof(symfile_path));
4151 if (!module_spec.GetUUID().IsValid()) {
4152 if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
4153 module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename();
4155 // We now have a module that represents a symbol file that can be used
4156 // for a module that might exist in the current target, so we need to
4157 // find that module in the target
4158 ModuleList matching_module_list;
4160 size_t num_matches = 0;
4161 // First extract all module specs from the symbol file
4162 lldb_private::ModuleSpecList symfile_module_specs;
4163 if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(),
4164 0, 0, symfile_module_specs)) {
4165 // Now extract the module spec that matches the target architecture
4166 ModuleSpec target_arch_module_spec;
4167 ModuleSpec symfile_module_spec;
4168 target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
4169 if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec,
4170 symfile_module_spec)) {
4171 // See if it has a UUID?
4172 if (symfile_module_spec.GetUUID().IsValid()) {
4173 // It has a UUID, look for this UUID in the target modules
4174 ModuleSpec symfile_uuid_module_spec;
4175 symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
4176 num_matches = target->GetImages().FindModules(
4177 symfile_uuid_module_spec, matching_module_list);
4181 if (num_matches == 0) {
4182 // No matches yet, iterate through the module specs to find a UUID
4183 // value that we can match up to an image in our target
4184 const size_t num_symfile_module_specs =
4185 symfile_module_specs.GetSize();
4186 for (size_t i = 0; i < num_symfile_module_specs && num_matches == 0;
4188 if (symfile_module_specs.GetModuleSpecAtIndex(
4189 i, symfile_module_spec)) {
4190 if (symfile_module_spec.GetUUID().IsValid()) {
4191 // It has a UUID, look for this UUID in the target modules
4192 ModuleSpec symfile_uuid_module_spec;
4193 symfile_uuid_module_spec.GetUUID() =
4194 symfile_module_spec.GetUUID();
4195 num_matches = target->GetImages().FindModules(
4196 symfile_uuid_module_spec, matching_module_list);
4203 // Just try to match up the file by basename if we have no matches at
4205 if (num_matches == 0)
4207 target->GetImages().FindModules(module_spec, matching_module_list);
4209 while (num_matches == 0) {
4210 ConstString filename_no_extension(
4211 module_spec.GetFileSpec().GetFileNameStrippingExtension());
4212 // Empty string returned, lets bail
4213 if (!filename_no_extension)
4216 // Check if there was no extension to strip and the basename is the
4218 if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
4221 // Replace basename with one less extension
4222 module_spec.GetFileSpec().GetFilename() = filename_no_extension;
4225 target->GetImages().FindModules(module_spec, matching_module_list);
4228 if (num_matches > 1) {
4229 result.AppendErrorWithFormat("multiple modules match symbol file '%s', "
4230 "use the --uuid option to resolve the "
4233 } else if (num_matches == 1) {
4234 ModuleSP module_sp(matching_module_list.GetModuleAtIndex(0));
4236 // The module has not yet created its symbol vendor, we can just give
4237 // the existing target module the symfile path to use for when it
4238 // decides to create it!
4239 module_sp->SetSymbolFileFileSpec(symbol_fspec);
4241 SymbolVendor *symbol_vendor =
4242 module_sp->GetSymbolVendor(true, &result.GetErrorStream());
4243 if (symbol_vendor) {
4244 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
4247 ObjectFile *object_file = symbol_file->GetObjectFile();
4249 if (object_file && object_file->GetFileSpec() == symbol_fspec) {
4250 // Provide feedback that the symfile has been successfully added.
4251 const FileSpec &module_fs = module_sp->GetFileSpec();
4252 result.AppendMessageWithFormat(
4253 "symbol file '%s' has been added to '%s'\n", symfile_path,
4254 module_fs.GetPath().c_str());
4256 // Let clients know something changed in the module if it is
4258 ModuleList module_list;
4259 module_list.Append(module_sp);
4260 target->SymbolsDidLoad(module_list);
4262 // Make sure we load any scripting resources that may be embedded
4263 // in the debug info files in case the platform supports that.
4265 StreamString feedback_stream;
4266 module_sp->LoadScriptingResourceInTarget(target, error,
4268 if (error.Fail() && error.AsCString())
4269 result.AppendWarningWithFormat(
4270 "unable to load scripting data for module %s - error "
4272 module_sp->GetFileSpec()
4273 .GetFileNameStrippingExtension()
4276 else if (feedback_stream.GetSize())
4277 result.AppendWarningWithFormat("%s", feedback_stream.GetData());
4280 result.SetStatus(eReturnStatusSuccessFinishResult);
4285 // Clear the symbol file spec if anything went wrong
4286 module_sp->SetSymbolFileFileSpec(FileSpec());
4289 namespace fs = llvm::sys::fs;
4290 if (module_spec.GetUUID().IsValid()) {
4291 StreamString ss_symfile_uuid;
4292 module_spec.GetUUID().Dump(&ss_symfile_uuid);
4293 result.AppendErrorWithFormat(
4294 "symbol file '%s' (%s) does not match any existing module%s\n",
4295 symfile_path, ss_symfile_uuid.GetData(),
4296 !fs::is_regular_file(symbol_fspec.GetPath())
4297 ? "\n please specify the full path to the symbol file"
4300 result.AppendErrorWithFormat(
4301 "symbol file '%s' does not match any existing module%s\n",
4303 !fs::is_regular_file(symbol_fspec.GetPath())
4304 ? "\n please specify the full path to the symbol file"
4309 "one or more executable image paths must be specified");
4311 result.SetStatus(eReturnStatusFailed);
4315 bool DoExecute(Args &args, CommandReturnObject &result) override {
4316 Target *target = m_exe_ctx.GetTargetPtr();
4317 result.SetStatus(eReturnStatusFailed);
4319 ModuleSpec module_spec;
4320 const bool uuid_option_set =
4321 m_uuid_option_group.GetOptionValue().OptionWasSet();
4322 const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
4323 const bool frame_option_set =
4324 m_current_frame_option.GetOptionValue().OptionWasSet();
4325 const size_t argc = args.GetArgumentCount();
4328 if (uuid_option_set || file_option_set || frame_option_set) {
4329 bool success = false;
4330 bool error_set = false;
4331 if (frame_option_set) {
4332 Process *process = m_exe_ctx.GetProcessPtr();
4334 const StateType process_state = process->GetState();
4335 if (StateIsStoppedState(process_state, true)) {
4336 StackFrame *frame = m_exe_ctx.GetFramePtr();
4338 ModuleSP frame_module_sp(
4339 frame->GetSymbolContext(eSymbolContextModule).module_sp);
4340 if (frame_module_sp) {
4341 if (FileSystem::Instance().Exists(
4342 frame_module_sp->GetPlatformFileSpec())) {
4343 module_spec.GetArchitecture() =
4344 frame_module_sp->GetArchitecture();
4345 module_spec.GetFileSpec() =
4346 frame_module_sp->GetPlatformFileSpec();
4348 module_spec.GetUUID() = frame_module_sp->GetUUID();
4349 success = module_spec.GetUUID().IsValid() ||
4350 module_spec.GetFileSpec();
4352 result.AppendError("frame has no module");
4356 result.AppendError("invalid current frame");
4360 result.AppendErrorWithFormat("process is not stopped: %s",
4361 StateAsCString(process_state));
4366 "a process must exist in order to use the --frame option");
4370 if (uuid_option_set) {
4371 module_spec.GetUUID() =
4372 m_uuid_option_group.GetOptionValue().GetCurrentValue();
4373 success |= module_spec.GetUUID().IsValid();
4374 } else if (file_option_set) {
4375 module_spec.GetFileSpec() =
4376 m_file_option.GetOptionValue().GetCurrentValue();
4378 target->GetImages().FindFirstModule(module_spec));
4380 module_spec.GetFileSpec() = module_sp->GetFileSpec();
4381 module_spec.GetPlatformFileSpec() =
4382 module_sp->GetPlatformFileSpec();
4383 module_spec.GetUUID() = module_sp->GetUUID();
4384 module_spec.GetArchitecture() = module_sp->GetArchitecture();
4386 module_spec.GetArchitecture() = target->GetArchitecture();
4388 success |= module_spec.GetUUID().IsValid() ||
4389 FileSystem::Instance().Exists(module_spec.GetFileSpec());
4394 if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
4395 if (module_spec.GetSymbolFileSpec())
4396 success = AddModuleSymbols(target, module_spec, flush, result);
4400 if (!success && !error_set) {
4401 StreamString error_strm;
4402 if (uuid_option_set) {
4403 error_strm.PutCString("unable to find debug symbols for UUID ");
4404 module_spec.GetUUID().Dump(&error_strm);
4405 } else if (file_option_set) {
4406 error_strm.PutCString(
4407 "unable to find debug symbols for the executable file ");
4408 error_strm << module_spec.GetFileSpec();
4409 } else if (frame_option_set) {
4410 error_strm.PutCString(
4411 "unable to find debug symbols for the current frame");
4413 result.AppendError(error_strm.GetString());
4416 result.AppendError("one or more symbol file paths must be specified, "
4417 "or options must be specified");
4420 if (uuid_option_set) {
4421 result.AppendError("specify either one or more paths to symbol files "
4422 "or use the --uuid option without arguments");
4423 } else if (frame_option_set) {
4424 result.AppendError("specify either one or more paths to symbol files "
4425 "or use the --frame option without arguments");
4426 } else if (file_option_set && argc > 1) {
4427 result.AppendError("specify at most one symbol file path when "
4428 "--shlib option is set");
4430 PlatformSP platform_sp(target->GetPlatform());
4432 for (auto &entry : args.entries()) {
4433 if (!entry.ref.empty()) {
4434 auto &symbol_file_spec = module_spec.GetSymbolFileSpec();
4435 symbol_file_spec.SetFile(entry.ref, FileSpec::Style::native);
4436 FileSystem::Instance().Resolve(symbol_file_spec);
4437 if (file_option_set) {
4438 module_spec.GetFileSpec() =
4439 m_file_option.GetOptionValue().GetCurrentValue();
4442 FileSpec symfile_spec;
4444 ->ResolveSymbolFile(*target, module_spec, symfile_spec)
4446 module_spec.GetSymbolFileSpec() = symfile_spec;
4450 bool symfile_exists =
4451 FileSystem::Instance().Exists(module_spec.GetSymbolFileSpec());
4453 if (symfile_exists) {
4454 if (!AddModuleSymbols(target, module_spec, flush, result))
4457 std::string resolved_symfile_path =
4458 module_spec.GetSymbolFileSpec().GetPath();
4459 if (resolved_symfile_path != entry.ref) {
4460 result.AppendErrorWithFormat(
4461 "invalid module path '%s' with resolved path '%s'\n",
4462 entry.c_str(), resolved_symfile_path.c_str());
4465 result.AppendErrorWithFormat("invalid module path '%s'\n",
4475 Process *process = m_exe_ctx.GetProcessPtr();
4479 return result.Succeeded();
4482 OptionGroupOptions m_option_group;
4483 OptionGroupUUID m_uuid_option_group;
4484 OptionGroupFile m_file_option;
4485 OptionGroupBoolean m_current_frame_option;
4488 #pragma mark CommandObjectTargetSymbols
4490 // CommandObjectTargetSymbols
4492 class CommandObjectTargetSymbols : public CommandObjectMultiword {
4494 // Constructors and Destructors
4495 CommandObjectTargetSymbols(CommandInterpreter &interpreter)
4496 : CommandObjectMultiword(
4497 interpreter, "target symbols",
4498 "Commands for adding and managing debug symbol files.",
4499 "target symbols <sub-command> ...") {
4501 "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter)));
4504 ~CommandObjectTargetSymbols() override = default;
4507 // For CommandObjectTargetModules only
4508 DISALLOW_COPY_AND_ASSIGN(CommandObjectTargetSymbols);
4511 #pragma mark CommandObjectTargetStopHookAdd
4513 // CommandObjectTargetStopHookAdd
4515 static constexpr OptionDefinition g_target_stop_hook_add_options[] = {
4517 { LLDB_OPT_SET_ALL, false, "one-liner", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOneLiner, "Add a command for the stop hook. Can be specified more than once, and commands will be run in the order they appear." },
4518 { LLDB_OPT_SET_ALL, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Set the module within which the stop-hook is to be run." },
4519 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadIndex, "The stop hook is run only for the thread whose index matches this argument." },
4520 { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadID, "The stop hook is run only for the thread whose TID matches this argument." },
4521 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadName, "The stop hook is run only for the thread whose thread name matches this argument." },
4522 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeQueueName, "The stop hook is run only for threads in the queue whose name is given by this argument." },
4523 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specify the source file within which the stop-hook is to be run." },
4524 { LLDB_OPT_SET_1, false, "start-line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "Set the start of the line range for which the stop-hook is to be run." },
4525 { LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "Set the end of the line range for which the stop-hook is to be run." },
4526 { LLDB_OPT_SET_2, false, "classname", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeClassName, "Specify the class within which the stop-hook is to be run." },
4527 { LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the function name within which the stop hook will be run." },
4528 { LLDB_OPT_SET_ALL, false, "auto-continue",'G', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "The breakpoint will auto-continue after running its commands." },
4532 class CommandObjectTargetStopHookAdd : public CommandObjectParsed,
4533 public IOHandlerDelegateMultiline {
4535 class CommandOptions : public Options {
4538 : Options(), m_line_start(0), m_line_end(UINT_MAX),
4539 m_func_name_type_mask(eFunctionNameTypeAuto),
4540 m_sym_ctx_specified(false), m_thread_specified(false),
4541 m_use_one_liner(false), m_one_liner() {}
4543 ~CommandOptions() override = default;
4545 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
4546 return llvm::makeArrayRef(g_target_stop_hook_add_options);
4549 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
4550 ExecutionContext *execution_context) override {
4552 const int short_option = m_getopt_table[option_idx].val;
4554 switch (short_option) {
4556 m_class_name = option_arg;
4557 m_sym_ctx_specified = true;
4561 if (option_arg.getAsInteger(0, m_line_end)) {
4562 error.SetErrorStringWithFormat("invalid end line number: \"%s\"",
4563 option_arg.str().c_str());
4566 m_sym_ctx_specified = true;
4570 bool value, success;
4571 value = OptionArgParser::ToBoolean(option_arg, false, &success);
4573 m_auto_continue = value;
4575 error.SetErrorStringWithFormat(
4576 "invalid boolean value '%s' passed for -G option",
4577 option_arg.str().c_str());
4581 if (option_arg.getAsInteger(0, m_line_start)) {
4582 error.SetErrorStringWithFormat("invalid start line number: \"%s\"",
4583 option_arg.str().c_str());
4586 m_sym_ctx_specified = true;
4590 m_no_inlines = true;
4594 m_function_name = option_arg;
4595 m_func_name_type_mask |= eFunctionNameTypeAuto;
4596 m_sym_ctx_specified = true;
4600 m_file_name = option_arg;
4601 m_sym_ctx_specified = true;
4605 m_module_name = option_arg;
4606 m_sym_ctx_specified = true;
4610 if (option_arg.getAsInteger(0, m_thread_id))
4611 error.SetErrorStringWithFormat("invalid thread id string '%s'",
4612 option_arg.str().c_str());
4613 m_thread_specified = true;
4617 m_thread_name = option_arg;
4618 m_thread_specified = true;
4622 m_queue_name = option_arg;
4623 m_thread_specified = true;
4627 if (option_arg.getAsInteger(0, m_thread_index))
4628 error.SetErrorStringWithFormat("invalid thread index string '%s'",
4629 option_arg.str().c_str());
4630 m_thread_specified = true;
4634 m_use_one_liner = true;
4635 m_one_liner.push_back(option_arg);
4639 error.SetErrorStringWithFormat("unrecognized option %c.", short_option);
4645 void OptionParsingStarting(ExecutionContext *execution_context) override {
4646 m_class_name.clear();
4647 m_function_name.clear();
4649 m_line_end = UINT_MAX;
4650 m_file_name.clear();
4651 m_module_name.clear();
4652 m_func_name_type_mask = eFunctionNameTypeAuto;
4653 m_thread_id = LLDB_INVALID_THREAD_ID;
4654 m_thread_index = UINT32_MAX;
4655 m_thread_name.clear();
4656 m_queue_name.clear();
4658 m_no_inlines = false;
4659 m_sym_ctx_specified = false;
4660 m_thread_specified = false;
4662 m_use_one_liner = false;
4663 m_one_liner.clear();
4664 m_auto_continue = false;
4667 std::string m_class_name;
4668 std::string m_function_name;
4669 uint32_t m_line_start;
4670 uint32_t m_line_end;
4671 std::string m_file_name;
4672 std::string m_module_name;
4673 uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType.
4674 lldb::tid_t m_thread_id;
4675 uint32_t m_thread_index;
4676 std::string m_thread_name;
4677 std::string m_queue_name;
4678 bool m_sym_ctx_specified;
4680 bool m_thread_specified;
4681 // Instance variables to hold the values for one_liner options.
4682 bool m_use_one_liner;
4683 std::vector<std::string> m_one_liner;
4684 bool m_auto_continue;
4687 CommandObjectTargetStopHookAdd(CommandInterpreter &interpreter)
4688 : CommandObjectParsed(interpreter, "target stop-hook add",
4689 "Add a hook to be executed when the target stops.",
4690 "target stop-hook add"),
4691 IOHandlerDelegateMultiline("DONE",
4692 IOHandlerDelegate::Completion::LLDBCommand),
4695 ~CommandObjectTargetStopHookAdd() override = default;
4697 Options *GetOptions() override { return &m_options; }
4700 void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
4701 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
4702 if (output_sp && interactive) {
4703 output_sp->PutCString(
4704 "Enter your stop hook command(s). Type 'DONE' to end.\n");
4709 void IOHandlerInputComplete(IOHandler &io_handler,
4710 std::string &line) override {
4711 if (m_stop_hook_sp) {
4713 StreamFileSP error_sp(io_handler.GetErrorStreamFile());
4715 error_sp->Printf("error: stop hook #%" PRIu64
4716 " aborted, no commands.\n",
4717 m_stop_hook_sp->GetID());
4720 Target *target = GetDebugger().GetSelectedTarget().get();
4722 target->RemoveStopHookByID(m_stop_hook_sp->GetID());
4724 m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line);
4725 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
4727 output_sp->Printf("Stop hook #%" PRIu64 " added.\n",
4728 m_stop_hook_sp->GetID());
4732 m_stop_hook_sp.reset();
4734 io_handler.SetIsDone(true);
4737 bool DoExecute(Args &command, CommandReturnObject &result) override {
4738 m_stop_hook_sp.reset();
4740 Target *target = GetSelectedOrDummyTarget();
4742 Target::StopHookSP new_hook_sp = target->CreateStopHook();
4744 // First step, make the specifier.
4745 std::unique_ptr<SymbolContextSpecifier> specifier_up;
4746 if (m_options.m_sym_ctx_specified) {
4748 new SymbolContextSpecifier(GetDebugger().GetSelectedTarget()));
4750 if (!m_options.m_module_name.empty()) {
4751 specifier_up->AddSpecification(
4752 m_options.m_module_name.c_str(),
4753 SymbolContextSpecifier::eModuleSpecified);
4756 if (!m_options.m_class_name.empty()) {
4757 specifier_up->AddSpecification(
4758 m_options.m_class_name.c_str(),
4759 SymbolContextSpecifier::eClassOrNamespaceSpecified);
4762 if (!m_options.m_file_name.empty()) {
4763 specifier_up->AddSpecification(
4764 m_options.m_file_name.c_str(),
4765 SymbolContextSpecifier::eFileSpecified);
4768 if (m_options.m_line_start != 0) {
4769 specifier_up->AddLineSpecification(
4770 m_options.m_line_start,
4771 SymbolContextSpecifier::eLineStartSpecified);
4774 if (m_options.m_line_end != UINT_MAX) {
4775 specifier_up->AddLineSpecification(
4776 m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
4779 if (!m_options.m_function_name.empty()) {
4780 specifier_up->AddSpecification(
4781 m_options.m_function_name.c_str(),
4782 SymbolContextSpecifier::eFunctionSpecified);
4787 new_hook_sp->SetSpecifier(specifier_up.release());
4789 // Next see if any of the thread options have been entered:
4791 if (m_options.m_thread_specified) {
4792 ThreadSpec *thread_spec = new ThreadSpec();
4794 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) {
4795 thread_spec->SetTID(m_options.m_thread_id);
4798 if (m_options.m_thread_index != UINT32_MAX)
4799 thread_spec->SetIndex(m_options.m_thread_index);
4801 if (!m_options.m_thread_name.empty())
4802 thread_spec->SetName(m_options.m_thread_name.c_str());
4804 if (!m_options.m_queue_name.empty())
4805 thread_spec->SetQueueName(m_options.m_queue_name.c_str());
4807 new_hook_sp->SetThreadSpecifier(thread_spec);
4810 new_hook_sp->SetAutoContinue(m_options.m_auto_continue);
4811 if (m_options.m_use_one_liner) {
4813 for (auto cmd : m_options.m_one_liner)
4814 new_hook_sp->GetCommandPointer()->AppendString(
4816 result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
4817 new_hook_sp->GetID());
4819 m_stop_hook_sp = new_hook_sp;
4820 m_interpreter.GetLLDBCommandsFromIOHandler(
4822 *this, // IOHandlerDelegate
4823 true, // Run IOHandler in async mode
4824 nullptr); // Baton for the "io_handler" that will be passed back
4825 // into our IOHandlerDelegate functions
4827 result.SetStatus(eReturnStatusSuccessFinishNoResult);
4829 result.AppendError("invalid target\n");
4830 result.SetStatus(eReturnStatusFailed);
4833 return result.Succeeded();
4837 CommandOptions m_options;
4838 Target::StopHookSP m_stop_hook_sp;
4841 #pragma mark CommandObjectTargetStopHookDelete
4843 // CommandObjectTargetStopHookDelete
4845 class CommandObjectTargetStopHookDelete : public CommandObjectParsed {
4847 CommandObjectTargetStopHookDelete(CommandInterpreter &interpreter)
4848 : CommandObjectParsed(interpreter, "target stop-hook delete",
4849 "Delete a stop-hook.",
4850 "target stop-hook delete [<idx>]") {}
4852 ~CommandObjectTargetStopHookDelete() override = default;
4855 bool DoExecute(Args &command, CommandReturnObject &result) override {
4856 Target *target = GetSelectedOrDummyTarget();
4858 // FIXME: see if we can use the breakpoint id style parser?
4859 size_t num_args = command.GetArgumentCount();
4860 if (num_args == 0) {
4861 if (!m_interpreter.Confirm("Delete all stop hooks?", true)) {
4862 result.SetStatus(eReturnStatusFailed);
4865 target->RemoveAllStopHooks();
4869 for (size_t i = 0; i < num_args; i++) {
4870 lldb::user_id_t user_id = StringConvert::ToUInt32(
4871 command.GetArgumentAtIndex(i), 0, 0, &success);
4873 result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4874 command.GetArgumentAtIndex(i));
4875 result.SetStatus(eReturnStatusFailed);
4878 success = target->RemoveStopHookByID(user_id);
4880 result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4881 command.GetArgumentAtIndex(i));
4882 result.SetStatus(eReturnStatusFailed);
4887 result.SetStatus(eReturnStatusSuccessFinishNoResult);
4889 result.AppendError("invalid target\n");
4890 result.SetStatus(eReturnStatusFailed);
4893 return result.Succeeded();
4897 #pragma mark CommandObjectTargetStopHookEnableDisable
4899 // CommandObjectTargetStopHookEnableDisable
4901 class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed {
4903 CommandObjectTargetStopHookEnableDisable(CommandInterpreter &interpreter,
4904 bool enable, const char *name,
4905 const char *help, const char *syntax)
4906 : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable) {
4909 ~CommandObjectTargetStopHookEnableDisable() override = default;
4912 bool DoExecute(Args &command, CommandReturnObject &result) override {
4913 Target *target = GetSelectedOrDummyTarget();
4915 // FIXME: see if we can use the breakpoint id style parser?
4916 size_t num_args = command.GetArgumentCount();
4919 if (num_args == 0) {
4920 target->SetAllStopHooksActiveState(m_enable);
4922 for (size_t i = 0; i < num_args; i++) {
4923 lldb::user_id_t user_id = StringConvert::ToUInt32(
4924 command.GetArgumentAtIndex(i), 0, 0, &success);
4926 result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4927 command.GetArgumentAtIndex(i));
4928 result.SetStatus(eReturnStatusFailed);
4931 success = target->SetStopHookActiveStateByID(user_id, m_enable);
4933 result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4934 command.GetArgumentAtIndex(i));
4935 result.SetStatus(eReturnStatusFailed);
4940 result.SetStatus(eReturnStatusSuccessFinishNoResult);
4942 result.AppendError("invalid target\n");
4943 result.SetStatus(eReturnStatusFailed);
4945 return result.Succeeded();
4952 #pragma mark CommandObjectTargetStopHookList
4954 // CommandObjectTargetStopHookList
4956 class CommandObjectTargetStopHookList : public CommandObjectParsed {
4958 CommandObjectTargetStopHookList(CommandInterpreter &interpreter)
4959 : CommandObjectParsed(interpreter, "target stop-hook list",
4960 "List all stop-hooks.",
4961 "target stop-hook list [<type>]") {}
4963 ~CommandObjectTargetStopHookList() override = default;
4966 bool DoExecute(Args &command, CommandReturnObject &result) override {
4967 Target *target = GetSelectedOrDummyTarget();
4969 result.AppendError("invalid target\n");
4970 result.SetStatus(eReturnStatusFailed);
4971 return result.Succeeded();
4974 size_t num_hooks = target->GetNumStopHooks();
4975 if (num_hooks == 0) {
4976 result.GetOutputStream().PutCString("No stop hooks.\n");
4978 for (size_t i = 0; i < num_hooks; i++) {
4979 Target::StopHookSP this_hook = target->GetStopHookAtIndex(i);
4981 result.GetOutputStream().PutCString("\n");
4982 this_hook->GetDescription(&(result.GetOutputStream()),
4983 eDescriptionLevelFull);
4986 result.SetStatus(eReturnStatusSuccessFinishResult);
4987 return result.Succeeded();
4991 #pragma mark CommandObjectMultiwordTargetStopHooks
4993 // CommandObjectMultiwordTargetStopHooks
4995 class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword {
4997 CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter)
4998 : CommandObjectMultiword(
4999 interpreter, "target stop-hook",
5000 "Commands for operating on debugger target stop-hooks.",
5001 "target stop-hook <subcommand> [<subcommand-options>]") {
5002 LoadSubCommand("add", CommandObjectSP(
5003 new CommandObjectTargetStopHookAdd(interpreter)));
5006 CommandObjectSP(new CommandObjectTargetStopHookDelete(interpreter)));
5007 LoadSubCommand("disable",
5008 CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
5009 interpreter, false, "target stop-hook disable [<id>]",
5010 "Disable a stop-hook.", "target stop-hook disable")));
5011 LoadSubCommand("enable",
5012 CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
5013 interpreter, true, "target stop-hook enable [<id>]",
5014 "Enable a stop-hook.", "target stop-hook enable")));
5015 LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetStopHookList(
5019 ~CommandObjectMultiwordTargetStopHooks() override = default;
5022 #pragma mark CommandObjectMultiwordTarget
5024 // CommandObjectMultiwordTarget
5026 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget(
5027 CommandInterpreter &interpreter)
5028 : CommandObjectMultiword(interpreter, "target",
5029 "Commands for operating on debugger targets.",
5030 "target <subcommand> [<subcommand-options>]") {
5031 LoadSubCommand("create",
5032 CommandObjectSP(new CommandObjectTargetCreate(interpreter)));
5033 LoadSubCommand("delete",
5034 CommandObjectSP(new CommandObjectTargetDelete(interpreter)));
5035 LoadSubCommand("list",
5036 CommandObjectSP(new CommandObjectTargetList(interpreter)));
5037 LoadSubCommand("select",
5038 CommandObjectSP(new CommandObjectTargetSelect(interpreter)));
5041 CommandObjectSP(new CommandObjectMultiwordTargetStopHooks(interpreter)));
5042 LoadSubCommand("modules",
5043 CommandObjectSP(new CommandObjectTargetModules(interpreter)));
5044 LoadSubCommand("symbols",
5045 CommandObjectSP(new CommandObjectTargetSymbols(interpreter)));
5046 LoadSubCommand("variable",
5047 CommandObjectSP(new CommandObjectTargetVariable(interpreter)));
5050 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget() = default;