1 //===-- CommandObjectTarget.cpp ---------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "CommandObjectTarget.h"
12 #include "lldb/Core/Debugger.h"
13 #include "lldb/Core/IOHandler.h"
14 #include "lldb/Core/Module.h"
15 #include "lldb/Core/ModuleSpec.h"
16 #include "lldb/Core/Section.h"
17 #include "lldb/Core/ValueObjectVariable.h"
18 #include "lldb/DataFormatters/ValueObjectPrinter.h"
19 #include "lldb/Host/OptionParser.h"
20 #include "lldb/Host/StringConvert.h"
21 #include "lldb/Host/Symbols.h"
22 #include "lldb/Interpreter/CommandInterpreter.h"
23 #include "lldb/Interpreter/CommandReturnObject.h"
24 #include "lldb/Interpreter/OptionArgParser.h"
25 #include "lldb/Interpreter/OptionGroupArchitecture.h"
26 #include "lldb/Interpreter/OptionGroupBoolean.h"
27 #include "lldb/Interpreter/OptionGroupFile.h"
28 #include "lldb/Interpreter/OptionGroupFormat.h"
29 #include "lldb/Interpreter/OptionGroupPlatform.h"
30 #include "lldb/Interpreter/OptionGroupString.h"
31 #include "lldb/Interpreter/OptionGroupUInt64.h"
32 #include "lldb/Interpreter/OptionGroupUUID.h"
33 #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
34 #include "lldb/Interpreter/OptionGroupVariable.h"
35 #include "lldb/Interpreter/Options.h"
36 #include "lldb/Symbol/CompileUnit.h"
37 #include "lldb/Symbol/FuncUnwinders.h"
38 #include "lldb/Symbol/LineTable.h"
39 #include "lldb/Symbol/ObjectFile.h"
40 #include "lldb/Symbol/SymbolFile.h"
41 #include "lldb/Symbol/SymbolVendor.h"
42 #include "lldb/Symbol/UnwindPlan.h"
43 #include "lldb/Symbol/VariableList.h"
44 #include "lldb/Target/ABI.h"
45 #include "lldb/Target/Process.h"
46 #include "lldb/Target/RegisterContext.h"
47 #include "lldb/Target/SectionLoadList.h"
48 #include "lldb/Target/StackFrame.h"
49 #include "lldb/Target/Thread.h"
50 #include "lldb/Target/ThreadSpec.h"
51 #include "lldb/Utility/Args.h"
52 #include "lldb/Utility/State.h"
53 #include "lldb/Utility/Timer.h"
55 #include "llvm/Support/FileSystem.h"
56 #include "llvm/Support/FormatAdapters.h"
61 using namespace lldb_private;
63 static void DumpTargetInfo(uint32_t target_idx, Target *target,
64 const char *prefix_cstr,
65 bool show_stopped_process_status, Stream &strm) {
66 const ArchSpec &target_arch = target->GetArchitecture();
68 Module *exe_module = target->GetExecutableModulePointer();
69 char exe_path[PATH_MAX];
70 bool exe_valid = false;
72 exe_valid = exe_module->GetFileSpec().GetPath(exe_path, sizeof(exe_path));
75 ::strcpy(exe_path, "<none>");
77 strm.Printf("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx,
80 uint32_t properties = 0;
81 if (target_arch.IsValid()) {
82 strm.Printf("%sarch=", properties++ > 0 ? ", " : " ( ");
83 target_arch.DumpTriple(strm);
86 PlatformSP platform_sp(target->GetPlatform());
88 strm.Printf("%splatform=%s", properties++ > 0 ? ", " : " ( ",
89 platform_sp->GetName().GetCString());
91 ProcessSP process_sp(target->GetProcessSP());
92 bool show_process_status = false;
94 lldb::pid_t pid = process_sp->GetID();
95 StateType state = process_sp->GetState();
96 if (show_stopped_process_status)
97 show_process_status = StateIsStoppedState(state, true);
98 const char *state_cstr = StateAsCString(state);
99 if (pid != LLDB_INVALID_PROCESS_ID)
100 strm.Printf("%spid=%" PRIu64, properties++ > 0 ? ", " : " ( ", pid);
101 strm.Printf("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
104 strm.PutCString(" )\n");
107 if (show_process_status) {
108 const bool only_threads_with_stop_reason = true;
109 const uint32_t start_frame = 0;
110 const uint32_t num_frames = 1;
111 const uint32_t num_frames_with_source = 1;
112 const bool stop_format = false;
113 process_sp->GetStatus(strm);
114 process_sp->GetThreadStatus(strm, only_threads_with_stop_reason,
115 start_frame, num_frames,
116 num_frames_with_source, stop_format);
120 static uint32_t DumpTargetList(TargetList &target_list,
121 bool show_stopped_process_status, Stream &strm) {
122 const uint32_t num_targets = target_list.GetNumTargets();
124 TargetSP selected_target_sp(target_list.GetSelectedTarget());
125 strm.PutCString("Current targets:\n");
126 for (uint32_t i = 0; i < num_targets; ++i) {
127 TargetSP target_sp(target_list.GetTargetAtIndex(i));
129 bool is_selected = target_sp.get() == selected_target_sp.get();
130 DumpTargetInfo(i, target_sp.get(), is_selected ? "* " : " ",
131 show_stopped_process_status, strm);
138 // Note that the negation in the argument name causes a slightly confusing
139 // mapping of the enum values,
140 static constexpr OptionEnumValueElement g_dependents_enumaration[] = {
141 {eLoadDependentsDefault, "default",
142 "Only load dependents when the target is an executable."},
143 {eLoadDependentsNo, "true",
144 "Don't load dependents, even if the target is an executable."},
145 {eLoadDependentsYes, "false",
146 "Load dependents, even if the target is not an executable."}};
148 static constexpr OptionDefinition g_dependents_options[] = {
149 {LLDB_OPT_SET_1, false, "no-dependents", 'd',
150 OptionParser::eOptionalArgument, nullptr,
151 OptionEnumValues(g_dependents_enumaration), 0, eArgTypeValue,
152 "Whether or not to load dependents when creating a target. If the option "
153 "is not specified, the value is implicitly 'default'. If the option is "
154 "specified but without a value, the value is implicitly 'true'."}};
156 class OptionGroupDependents : public OptionGroup {
158 OptionGroupDependents() {}
160 ~OptionGroupDependents() override {}
162 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
163 return llvm::makeArrayRef(g_dependents_options);
166 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
167 ExecutionContext *execution_context) override {
170 // For compatibility no value means don't load dependents.
171 if (option_value.empty()) {
172 m_load_dependent_files = eLoadDependentsNo;
176 const char short_option = g_dependents_options[option_idx].short_option;
177 if (short_option == 'd') {
178 LoadDependentFiles tmp_load_dependents;
179 tmp_load_dependents = (LoadDependentFiles)OptionArgParser::ToOptionEnum(
180 option_value, g_dependents_options[option_idx].enum_values, 0, error);
182 m_load_dependent_files = tmp_load_dependents;
184 error.SetErrorStringWithFormat("unrecognized short option '%c'",
191 Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete;
193 void OptionParsingStarting(ExecutionContext *execution_context) override {
194 m_load_dependent_files = eLoadDependentsDefault;
197 LoadDependentFiles m_load_dependent_files;
200 DISALLOW_COPY_AND_ASSIGN(OptionGroupDependents);
203 #pragma mark CommandObjectTargetCreate
205 //-------------------------------------------------------------------------
207 //-------------------------------------------------------------------------
209 class CommandObjectTargetCreate : public CommandObjectParsed {
211 CommandObjectTargetCreate(CommandInterpreter &interpreter)
212 : CommandObjectParsed(
213 interpreter, "target create",
214 "Create a target using the argument as the main executable.",
216 m_option_group(), m_arch_option(),
217 m_core_file(LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename,
218 "Fullpath to a core file to use for this target."),
219 m_platform_path(LLDB_OPT_SET_1, false, "platform-path", 'P', 0,
221 "Path to the remote file to use for this target."),
222 m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
224 "Fullpath to a stand alone debug "
225 "symbols file for when debug symbols "
226 "are not in the executable."),
228 LLDB_OPT_SET_1, false, "remote-file", 'r', 0, eArgTypeFilename,
229 "Fullpath to the file on the remote host if debugging remotely."),
231 CommandArgumentEntry arg;
232 CommandArgumentData file_arg;
234 // Define the first (and only) variant of this arg.
235 file_arg.arg_type = eArgTypeFilename;
236 file_arg.arg_repetition = eArgRepeatPlain;
238 // There is only one variant this argument could be; put it into the
240 arg.push_back(file_arg);
242 // Push the data for the first argument into the m_arguments vector.
243 m_arguments.push_back(arg);
245 m_option_group.Append(&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
246 m_option_group.Append(&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
247 m_option_group.Append(&m_platform_path, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
248 m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
249 m_option_group.Append(&m_remote_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
250 m_option_group.Append(&m_add_dependents, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
251 m_option_group.Finalize();
254 ~CommandObjectTargetCreate() override = default;
256 Options *GetOptions() override { return &m_option_group; }
258 int HandleArgumentCompletion(
259 CompletionRequest &request,
260 OptionElementVector &opt_element_vector) override {
261 CommandCompletions::InvokeCommonCompletionCallbacks(
262 GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
264 return request.GetNumberOfMatches();
268 bool DoExecute(Args &command, CommandReturnObject &result) override {
269 const size_t argc = command.GetArgumentCount();
270 FileSpec core_file(m_core_file.GetOptionValue().GetCurrentValue());
271 FileSpec remote_file(m_remote_file.GetOptionValue().GetCurrentValue());
274 if (!FileSystem::Instance().Exists(core_file)) {
275 result.AppendErrorWithFormat("core file '%s' doesn't exist",
276 core_file.GetPath().c_str());
277 result.SetStatus(eReturnStatusFailed);
280 if (!FileSystem::Instance().Readable(core_file)) {
281 result.AppendErrorWithFormat("core file '%s' is not readable",
282 core_file.GetPath().c_str());
283 result.SetStatus(eReturnStatusFailed);
288 if (argc == 1 || core_file || remote_file) {
289 FileSpec symfile(m_symbol_file.GetOptionValue().GetCurrentValue());
291 if (FileSystem::Instance().Exists(symfile)) {
292 if (!FileSystem::Instance().Readable(symfile)) {
293 result.AppendErrorWithFormat("symbol file '%s' is not readable",
294 symfile.GetPath().c_str());
295 result.SetStatus(eReturnStatusFailed);
299 char symfile_path[PATH_MAX];
300 symfile.GetPath(symfile_path, sizeof(symfile_path));
301 result.AppendErrorWithFormat("invalid symbol file path '%s'",
303 result.SetStatus(eReturnStatusFailed);
308 const char *file_path = command.GetArgumentAtIndex(0);
309 static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
310 Timer scoped_timer(func_cat, "(lldb) target create '%s'", file_path);
314 file_spec.SetFile(file_path, FileSpec::Style::native);
315 FileSystem::Instance().Resolve(file_spec);
318 bool must_set_platform_path = false;
320 Debugger &debugger = m_interpreter.GetDebugger();
323 llvm::StringRef arch_cstr = m_arch_option.GetArchitectureName();
324 Status error(debugger.GetTargetList().CreateTarget(
325 debugger, file_path, arch_cstr,
326 m_add_dependents.m_load_dependent_files, nullptr, target_sp));
329 // Only get the platform after we create the target because we might
330 // have switched platforms depending on what the arguments were to
331 // CreateTarget() we can't rely on the selected platform.
333 PlatformSP platform_sp = target_sp->GetPlatform();
337 // I have a remote file.. two possible cases
338 if (file_spec && FileSystem::Instance().Exists(file_spec)) {
339 // if the remote file does not exist, push it there
340 if (!platform_sp->GetFileExists(remote_file)) {
341 Status err = platform_sp->PutFile(file_spec, remote_file);
343 result.AppendError(err.AsCString());
344 result.SetStatus(eReturnStatusFailed);
349 // there is no local file and we need one
350 // in order to make the remote ---> local transfer we need a
352 // TODO: if the user has passed in a --platform argument, use it
353 // to fetch the right platform
356 "unable to perform remote debugging without a platform");
357 result.SetStatus(eReturnStatusFailed);
361 // copy the remote file to the local file
362 Status err = platform_sp->GetFile(remote_file, file_spec);
364 result.AppendError(err.AsCString());
365 result.SetStatus(eReturnStatusFailed);
369 // make up a local file
370 result.AppendError("remote --> local transfer without local "
371 "path is not implemented yet");
372 result.SetStatus(eReturnStatusFailed);
377 result.AppendError("no platform found for target");
378 result.SetStatus(eReturnStatusFailed);
383 if (symfile || remote_file) {
384 ModuleSP module_sp(target_sp->GetExecutableModule());
387 module_sp->SetSymbolFileFileSpec(symfile);
389 std::string remote_path = remote_file.GetPath();
390 target_sp->SetArg0(remote_path.c_str());
391 module_sp->SetPlatformFileSpec(remote_file);
396 debugger.GetTargetList().SetSelectedTarget(target_sp.get());
397 if (must_set_platform_path) {
398 ModuleSpec main_module_spec(file_spec);
399 ModuleSP module_sp = target_sp->GetSharedModule(main_module_spec);
401 module_sp->SetPlatformFileSpec(remote_file);
404 char core_path[PATH_MAX];
405 core_file.GetPath(core_path, sizeof(core_path));
406 if (FileSystem::Instance().Exists(core_file)) {
407 if (!FileSystem::Instance().Readable(core_file)) {
408 result.AppendMessageWithFormat(
409 "Core file '%s' is not readable.\n", core_path);
410 result.SetStatus(eReturnStatusFailed);
413 FileSpec core_file_dir;
414 core_file_dir.GetDirectory() = core_file.GetDirectory();
415 target_sp->GetExecutableSearchPaths().Append(core_file_dir);
417 ProcessSP process_sp(target_sp->CreateProcess(
418 m_interpreter.GetDebugger().GetListener(), llvm::StringRef(),
422 // Seems weird that we Launch a core file, but that is what we
424 error = process_sp->LoadCore();
428 error.AsCString("can't find plug-in for core file"));
429 result.SetStatus(eReturnStatusFailed);
432 result.AppendMessageWithFormat(
433 "Core file '%s' (%s) was loaded.\n", core_path,
434 target_sp->GetArchitecture().GetArchitectureName());
435 result.SetStatus(eReturnStatusSuccessFinishNoResult);
438 result.AppendErrorWithFormat(
439 "Unable to find process plug-in for core file '%s'\n",
441 result.SetStatus(eReturnStatusFailed);
444 result.AppendErrorWithFormat("Core file '%s' does not exist\n",
446 result.SetStatus(eReturnStatusFailed);
449 result.AppendMessageWithFormat(
450 "Current executable set to '%s' (%s).\n", file_path,
451 target_sp->GetArchitecture().GetArchitectureName());
452 result.SetStatus(eReturnStatusSuccessFinishNoResult);
455 result.AppendError(error.AsCString());
456 result.SetStatus(eReturnStatusFailed);
459 result.AppendErrorWithFormat("'%s' takes exactly one executable path "
460 "argument, or use the --core option.\n",
462 result.SetStatus(eReturnStatusFailed);
464 return result.Succeeded();
468 OptionGroupOptions m_option_group;
469 OptionGroupArchitecture m_arch_option;
470 OptionGroupFile m_core_file;
471 OptionGroupFile m_platform_path;
472 OptionGroupFile m_symbol_file;
473 OptionGroupFile m_remote_file;
474 OptionGroupDependents m_add_dependents;
477 #pragma mark CommandObjectTargetList
479 //----------------------------------------------------------------------
481 //----------------------------------------------------------------------
483 class CommandObjectTargetList : public CommandObjectParsed {
485 CommandObjectTargetList(CommandInterpreter &interpreter)
486 : CommandObjectParsed(
487 interpreter, "target list",
488 "List all current targets in the current debug session.", nullptr) {
491 ~CommandObjectTargetList() override = default;
494 bool DoExecute(Args &args, CommandReturnObject &result) override {
495 if (args.GetArgumentCount() == 0) {
496 Stream &strm = result.GetOutputStream();
498 bool show_stopped_process_status = false;
499 if (DumpTargetList(m_interpreter.GetDebugger().GetTargetList(),
500 show_stopped_process_status, strm) == 0) {
501 strm.PutCString("No targets.\n");
503 result.SetStatus(eReturnStatusSuccessFinishResult);
505 result.AppendError("the 'target list' command takes no arguments\n");
506 result.SetStatus(eReturnStatusFailed);
508 return result.Succeeded();
512 #pragma mark CommandObjectTargetSelect
514 //----------------------------------------------------------------------
516 //----------------------------------------------------------------------
518 class CommandObjectTargetSelect : public CommandObjectParsed {
520 CommandObjectTargetSelect(CommandInterpreter &interpreter)
521 : CommandObjectParsed(
522 interpreter, "target select",
523 "Select a target as the current target by target index.", nullptr) {
526 ~CommandObjectTargetSelect() override = default;
529 bool DoExecute(Args &args, CommandReturnObject &result) override {
530 if (args.GetArgumentCount() == 1) {
531 bool success = false;
532 const char *target_idx_arg = args.GetArgumentAtIndex(0);
533 uint32_t target_idx =
534 StringConvert::ToUInt32(target_idx_arg, UINT32_MAX, 0, &success);
536 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
537 const uint32_t num_targets = target_list.GetNumTargets();
538 if (target_idx < num_targets) {
539 TargetSP target_sp(target_list.GetTargetAtIndex(target_idx));
541 Stream &strm = result.GetOutputStream();
542 target_list.SetSelectedTarget(target_sp.get());
543 bool show_stopped_process_status = false;
544 DumpTargetList(target_list, show_stopped_process_status, strm);
545 result.SetStatus(eReturnStatusSuccessFinishResult);
547 result.AppendErrorWithFormat("target #%u is NULL in target list\n",
549 result.SetStatus(eReturnStatusFailed);
552 if (num_targets > 0) {
553 result.AppendErrorWithFormat(
554 "index %u is out of range, valid target indexes are 0 - %u\n",
555 target_idx, num_targets - 1);
557 result.AppendErrorWithFormat(
558 "index %u is out of range since there are no active targets\n",
561 result.SetStatus(eReturnStatusFailed);
564 result.AppendErrorWithFormat("invalid index string value '%s'\n",
566 result.SetStatus(eReturnStatusFailed);
570 "'target select' takes a single argument: a target index\n");
571 result.SetStatus(eReturnStatusFailed);
573 return result.Succeeded();
577 #pragma mark CommandObjectTargetSelect
579 //----------------------------------------------------------------------
581 //----------------------------------------------------------------------
583 class CommandObjectTargetDelete : public CommandObjectParsed {
585 CommandObjectTargetDelete(CommandInterpreter &interpreter)
586 : CommandObjectParsed(interpreter, "target delete",
587 "Delete one or more targets by target index.",
589 m_option_group(), m_all_option(LLDB_OPT_SET_1, false, "all", 'a',
590 "Delete all targets.", false, true),
592 LLDB_OPT_SET_1, false, "clean", 'c',
593 "Perform extra cleanup to minimize memory consumption after "
594 "deleting the target. "
595 "By default, LLDB will keep in memory any modules previously "
596 "loaded by the target as well "
597 "as all of its debug info. Specifying --clean will unload all of "
598 "these shared modules and "
599 "cause them to be reparsed again the next time the target is run",
601 m_option_group.Append(&m_all_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
602 m_option_group.Append(&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
603 m_option_group.Finalize();
606 ~CommandObjectTargetDelete() override = default;
608 Options *GetOptions() override { return &m_option_group; }
611 bool DoExecute(Args &args, CommandReturnObject &result) override {
612 const size_t argc = args.GetArgumentCount();
613 std::vector<TargetSP> delete_target_list;
614 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
617 if (m_all_option.GetOptionValue()) {
618 for (int i = 0; i < target_list.GetNumTargets(); ++i)
619 delete_target_list.push_back(target_list.GetTargetAtIndex(i));
620 } else if (argc > 0) {
621 const uint32_t num_targets = target_list.GetNumTargets();
622 // Bail out if don't have any targets.
623 if (num_targets == 0) {
624 result.AppendError("no targets to delete");
625 result.SetStatus(eReturnStatusFailed);
629 for (auto &entry : args.entries()) {
631 if (entry.ref.getAsInteger(0, target_idx)) {
632 result.AppendErrorWithFormat("invalid target index '%s'\n",
634 result.SetStatus(eReturnStatusFailed);
637 if (target_idx < num_targets) {
638 target_sp = target_list.GetTargetAtIndex(target_idx);
640 delete_target_list.push_back(target_sp);
645 result.AppendErrorWithFormat("target index %u is out of range, valid "
646 "target indexes are 0 - %u\n",
647 target_idx, num_targets - 1);
649 result.AppendErrorWithFormat(
650 "target index %u is out of range, the only valid index is 0\n",
653 result.SetStatus(eReturnStatusFailed);
657 target_sp = target_list.GetSelectedTarget();
659 result.AppendErrorWithFormat("no target is currently selected\n");
660 result.SetStatus(eReturnStatusFailed);
663 delete_target_list.push_back(target_sp);
666 const size_t num_targets_to_delete = delete_target_list.size();
667 for (size_t idx = 0; idx < num_targets_to_delete; ++idx) {
668 target_sp = delete_target_list[idx];
669 target_list.DeleteTarget(target_sp);
670 target_sp->Destroy();
672 // If "--clean" was specified, prune any orphaned shared modules from the
673 // global shared module list
674 if (m_cleanup_option.GetOptionValue()) {
675 const bool mandatory = true;
676 ModuleList::RemoveOrphanSharedModules(mandatory);
678 result.GetOutputStream().Printf("%u targets deleted.\n",
679 (uint32_t)num_targets_to_delete);
680 result.SetStatus(eReturnStatusSuccessFinishResult);
685 OptionGroupOptions m_option_group;
686 OptionGroupBoolean m_all_option;
687 OptionGroupBoolean m_cleanup_option;
690 #pragma mark CommandObjectTargetVariable
692 //----------------------------------------------------------------------
694 //----------------------------------------------------------------------
696 class CommandObjectTargetVariable : public CommandObjectParsed {
697 static const uint32_t SHORT_OPTION_FILE = 0x66696c65; // 'file'
698 static const uint32_t SHORT_OPTION_SHLB = 0x73686c62; // 'shlb'
701 CommandObjectTargetVariable(CommandInterpreter &interpreter)
702 : CommandObjectParsed(interpreter, "target variable",
703 "Read global variables for the current target, "
704 "before or while running a process.",
705 nullptr, eCommandRequiresTarget),
707 m_option_variable(false), // Don't include frame options
708 m_option_format(eFormatDefault),
709 m_option_compile_units(LLDB_OPT_SET_1, false, "file", SHORT_OPTION_FILE,
711 "A basename or fullpath to a file that contains "
712 "global variables. This option can be "
713 "specified multiple times."),
714 m_option_shared_libraries(
715 LLDB_OPT_SET_1, false, "shlib", SHORT_OPTION_SHLB, 0,
717 "A basename or fullpath to a shared library to use in the search "
719 "variables. This option can be specified multiple times."),
721 CommandArgumentEntry arg;
722 CommandArgumentData var_name_arg;
724 // Define the first (and only) variant of this arg.
725 var_name_arg.arg_type = eArgTypeVarName;
726 var_name_arg.arg_repetition = eArgRepeatPlus;
728 // There is only one variant this argument could be; put it into the
730 arg.push_back(var_name_arg);
732 // Push the data for the first argument into the m_arguments vector.
733 m_arguments.push_back(arg);
735 m_option_group.Append(&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
736 m_option_group.Append(&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
737 m_option_group.Append(&m_option_format,
738 OptionGroupFormat::OPTION_GROUP_FORMAT |
739 OptionGroupFormat::OPTION_GROUP_GDB_FMT,
741 m_option_group.Append(&m_option_compile_units, LLDB_OPT_SET_ALL,
743 m_option_group.Append(&m_option_shared_libraries, LLDB_OPT_SET_ALL,
745 m_option_group.Finalize();
748 ~CommandObjectTargetVariable() override = default;
750 void DumpValueObject(Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp,
751 const char *root_name) {
752 DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions());
754 if (!valobj_sp->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
755 valobj_sp->IsRuntimeSupportValue())
758 switch (var_sp->GetScope()) {
759 case eValueTypeVariableGlobal:
760 if (m_option_variable.show_scope)
761 s.PutCString("GLOBAL: ");
764 case eValueTypeVariableStatic:
765 if (m_option_variable.show_scope)
766 s.PutCString("STATIC: ");
769 case eValueTypeVariableArgument:
770 if (m_option_variable.show_scope)
771 s.PutCString(" ARG: ");
774 case eValueTypeVariableLocal:
775 if (m_option_variable.show_scope)
776 s.PutCString(" LOCAL: ");
779 case eValueTypeVariableThreadLocal:
780 if (m_option_variable.show_scope)
781 s.PutCString("THREAD: ");
788 if (m_option_variable.show_decl) {
789 bool show_fullpaths = false;
790 bool show_module = true;
791 if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
795 const Format format = m_option_format.GetFormat();
796 if (format != eFormatDefault)
797 options.SetFormat(format);
799 options.SetRootValueObjectName(root_name);
801 valobj_sp->Dump(s, options);
804 static size_t GetVariableCallback(void *baton, const char *name,
805 VariableList &variable_list) {
806 Target *target = static_cast<Target *>(baton);
808 return target->GetImages().FindGlobalVariables(ConstString(name),
809 UINT32_MAX, variable_list);
814 Options *GetOptions() override { return &m_option_group; }
817 void DumpGlobalVariableList(const ExecutionContext &exe_ctx,
818 const SymbolContext &sc,
819 const VariableList &variable_list, Stream &s) {
820 size_t count = variable_list.GetSize();
824 s.Printf("Global variables for %s in %s:\n",
825 sc.comp_unit->GetPath().c_str(),
826 sc.module_sp->GetFileSpec().GetPath().c_str());
828 s.Printf("Global variables for %s\n",
829 sc.module_sp->GetFileSpec().GetPath().c_str());
831 } else if (sc.comp_unit) {
832 s.Printf("Global variables for %s\n", sc.comp_unit->GetPath().c_str());
835 for (uint32_t i = 0; i < count; ++i) {
836 VariableSP var_sp(variable_list.GetVariableAtIndex(i));
838 ValueObjectSP valobj_sp(ValueObjectVariable::Create(
839 exe_ctx.GetBestExecutionContextScope(), var_sp));
842 DumpValueObject(s, var_sp, valobj_sp,
843 var_sp->GetName().GetCString());
849 bool DoExecute(Args &args, CommandReturnObject &result) override {
850 Target *target = m_exe_ctx.GetTargetPtr();
851 const size_t argc = args.GetArgumentCount();
852 Stream &s = result.GetOutputStream();
856 // TODO: Convert to entry-based iteration. Requires converting
858 for (size_t idx = 0; idx < argc; ++idx) {
859 VariableList variable_list;
860 ValueObjectList valobj_list;
862 const char *arg = args.GetArgumentAtIndex(idx);
864 bool use_var_name = false;
865 if (m_option_variable.use_regex) {
866 RegularExpression regex(llvm::StringRef::withNullAsEmpty(arg));
867 if (!regex.IsValid()) {
868 result.GetErrorStream().Printf(
869 "error: invalid regular expression: '%s'\n", arg);
870 result.SetStatus(eReturnStatusFailed);
874 matches = target->GetImages().FindGlobalVariables(regex, UINT32_MAX,
877 Status error(Variable::GetValuesForVariableExpressionPath(
878 arg, m_exe_ctx.GetBestExecutionContextScope(),
879 GetVariableCallback, target, variable_list, valobj_list));
880 matches = variable_list.GetSize();
884 result.GetErrorStream().Printf(
885 "error: can't find global variable '%s'\n", arg);
886 result.SetStatus(eReturnStatusFailed);
889 for (uint32_t global_idx = 0; global_idx < matches; ++global_idx) {
890 VariableSP var_sp(variable_list.GetVariableAtIndex(global_idx));
892 ValueObjectSP valobj_sp(
893 valobj_list.GetValueObjectAtIndex(global_idx));
895 valobj_sp = ValueObjectVariable::Create(
896 m_exe_ctx.GetBestExecutionContextScope(), var_sp);
899 DumpValueObject(s, var_sp, valobj_sp,
900 use_var_name ? var_sp->GetName().GetCString()
907 const FileSpecList &compile_units =
908 m_option_compile_units.GetOptionValue().GetCurrentValue();
909 const FileSpecList &shlibs =
910 m_option_shared_libraries.GetOptionValue().GetCurrentValue();
911 SymbolContextList sc_list;
912 const size_t num_compile_units = compile_units.GetSize();
913 const size_t num_shlibs = shlibs.GetSize();
914 if (num_compile_units == 0 && num_shlibs == 0) {
915 bool success = false;
916 StackFrame *frame = m_exe_ctx.GetFramePtr();
917 CompileUnit *comp_unit = nullptr;
919 SymbolContext sc = frame->GetSymbolContext(eSymbolContextCompUnit);
921 const bool can_create = true;
922 VariableListSP comp_unit_varlist_sp(
923 sc.comp_unit->GetVariableList(can_create));
924 if (comp_unit_varlist_sp) {
925 size_t count = comp_unit_varlist_sp->GetSize();
927 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
936 result.AppendErrorWithFormat(
937 "no global variables in current compile unit: %s\n",
938 comp_unit->GetPath().c_str());
940 result.AppendErrorWithFormat(
941 "no debug information for frame %u\n",
942 frame->GetFrameIndex());
944 result.AppendError("'target variable' takes one or more global "
945 "variable names as arguments\n");
946 result.SetStatus(eReturnStatusFailed);
949 SymbolContextList sc_list;
950 const bool append = true;
951 // We have one or more compile unit or shlib
952 if (num_shlibs > 0) {
953 for (size_t shlib_idx = 0; shlib_idx < num_shlibs; ++shlib_idx) {
954 const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx));
955 ModuleSpec module_spec(module_file);
958 target->GetImages().FindFirstModule(module_spec));
960 if (num_compile_units > 0) {
961 for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
962 module_sp->FindCompileUnits(
963 compile_units.GetFileSpecAtIndex(cu_idx), append,
967 sc.module_sp = module_sp;
971 // Didn't find matching shlib/module in target...
972 result.AppendErrorWithFormat(
973 "target doesn't contain the specified shared library: %s\n",
974 module_file.GetPath().c_str());
978 // No shared libraries, we just want to find globals for the compile
979 // units files that were specified
980 for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
981 target->GetImages().FindCompileUnits(
982 compile_units.GetFileSpecAtIndex(cu_idx), append, sc_list);
985 const uint32_t num_scs = sc_list.GetSize();
988 for (uint32_t sc_idx = 0; sc_idx < num_scs; ++sc_idx) {
989 if (sc_list.GetContextAtIndex(sc_idx, sc)) {
991 const bool can_create = true;
992 VariableListSP comp_unit_varlist_sp(
993 sc.comp_unit->GetVariableList(can_create));
994 if (comp_unit_varlist_sp)
995 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp,
997 } else if (sc.module_sp) {
998 // Get all global variables for this module
999 lldb_private::RegularExpression all_globals_regex(
1001 ".")); // Any global with at least one character
1002 VariableList variable_list;
1003 sc.module_sp->FindGlobalVariables(all_globals_regex, UINT32_MAX,
1005 DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s);
1013 if (m_interpreter.TruncationWarningNecessary()) {
1014 result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(),
1015 m_cmd_name.c_str());
1016 m_interpreter.TruncationWarningGiven();
1019 return result.Succeeded();
1022 OptionGroupOptions m_option_group;
1023 OptionGroupVariable m_option_variable;
1024 OptionGroupFormat m_option_format;
1025 OptionGroupFileList m_option_compile_units;
1026 OptionGroupFileList m_option_shared_libraries;
1027 OptionGroupValueObjectDisplay m_varobj_options;
1030 #pragma mark CommandObjectTargetModulesSearchPathsAdd
1032 class CommandObjectTargetModulesSearchPathsAdd : public CommandObjectParsed {
1034 CommandObjectTargetModulesSearchPathsAdd(CommandInterpreter &interpreter)
1035 : CommandObjectParsed(interpreter, "target modules search-paths add",
1036 "Add new image search paths substitution pairs to "
1037 "the current target.",
1039 CommandArgumentEntry arg;
1040 CommandArgumentData old_prefix_arg;
1041 CommandArgumentData new_prefix_arg;
1043 // Define the first variant of this arg pair.
1044 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1045 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1047 // Define the first variant of this arg pair.
1048 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1049 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1051 // There are two required arguments that must always occur together, i.e.
1052 // an argument "pair". Because they must always occur together, they are
1053 // treated as two variants of one argument rather than two independent
1054 // arguments. Push them both into the first argument position for
1057 arg.push_back(old_prefix_arg);
1058 arg.push_back(new_prefix_arg);
1060 m_arguments.push_back(arg);
1063 ~CommandObjectTargetModulesSearchPathsAdd() override = default;
1066 bool DoExecute(Args &command, CommandReturnObject &result) override {
1067 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1069 const size_t argc = command.GetArgumentCount();
1071 result.AppendError("add requires an even number of arguments\n");
1072 result.SetStatus(eReturnStatusFailed);
1074 for (size_t i = 0; i < argc; i += 2) {
1075 const char *from = command.GetArgumentAtIndex(i);
1076 const char *to = command.GetArgumentAtIndex(i + 1);
1078 if (from[0] && to[0]) {
1079 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
1081 log->Printf("target modules search path adding ImageSearchPath "
1082 "pair: '%s' -> '%s'",
1085 bool last_pair = ((argc - i) == 2);
1086 target->GetImageSearchPathList().Append(
1087 ConstString(from), ConstString(to),
1088 last_pair); // Notify if this is the last pair
1089 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1092 result.AppendError("<path-prefix> can't be empty\n");
1094 result.AppendError("<new-path-prefix> can't be empty\n");
1095 result.SetStatus(eReturnStatusFailed);
1100 result.AppendError("invalid target\n");
1101 result.SetStatus(eReturnStatusFailed);
1103 return result.Succeeded();
1107 #pragma mark CommandObjectTargetModulesSearchPathsClear
1109 class CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed {
1111 CommandObjectTargetModulesSearchPathsClear(CommandInterpreter &interpreter)
1112 : CommandObjectParsed(interpreter, "target modules search-paths clear",
1113 "Clear all current image search path substitution "
1114 "pairs from the current target.",
1115 "target modules search-paths clear") {}
1117 ~CommandObjectTargetModulesSearchPathsClear() override = default;
1120 bool DoExecute(Args &command, CommandReturnObject &result) override {
1121 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1124 target->GetImageSearchPathList().Clear(notify);
1125 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1127 result.AppendError("invalid target\n");
1128 result.SetStatus(eReturnStatusFailed);
1130 return result.Succeeded();
1134 #pragma mark CommandObjectTargetModulesSearchPathsInsert
1136 class CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed {
1138 CommandObjectTargetModulesSearchPathsInsert(CommandInterpreter &interpreter)
1139 : CommandObjectParsed(interpreter, "target modules search-paths insert",
1140 "Insert a new image search path substitution pair "
1141 "into the current target at the specified index.",
1143 CommandArgumentEntry arg1;
1144 CommandArgumentEntry arg2;
1145 CommandArgumentData index_arg;
1146 CommandArgumentData old_prefix_arg;
1147 CommandArgumentData new_prefix_arg;
1149 // Define the first and only variant of this arg.
1150 index_arg.arg_type = eArgTypeIndex;
1151 index_arg.arg_repetition = eArgRepeatPlain;
1153 // Put the one and only variant into the first arg for m_arguments:
1154 arg1.push_back(index_arg);
1156 // Define the first variant of this arg pair.
1157 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1158 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1160 // Define the first variant of this arg pair.
1161 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1162 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1164 // There are two required arguments that must always occur together, i.e.
1165 // an argument "pair". Because they must always occur together, they are
1166 // treated as two variants of one argument rather than two independent
1167 // arguments. Push them both into the same argument position for
1170 arg2.push_back(old_prefix_arg);
1171 arg2.push_back(new_prefix_arg);
1173 // Add arguments to m_arguments.
1174 m_arguments.push_back(arg1);
1175 m_arguments.push_back(arg2);
1178 ~CommandObjectTargetModulesSearchPathsInsert() override = default;
1181 bool DoExecute(Args &command, CommandReturnObject &result) override {
1182 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1184 size_t argc = command.GetArgumentCount();
1185 // check for at least 3 arguments and an odd number of parameters
1186 if (argc >= 3 && argc & 1) {
1187 bool success = false;
1189 uint32_t insert_idx = StringConvert::ToUInt32(
1190 command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);
1193 result.AppendErrorWithFormat(
1194 "<index> parameter is not an integer: '%s'.\n",
1195 command.GetArgumentAtIndex(0));
1196 result.SetStatus(eReturnStatusFailed);
1197 return result.Succeeded();
1200 // shift off the index
1202 argc = command.GetArgumentCount();
1204 for (uint32_t i = 0; i < argc; i += 2, ++insert_idx) {
1205 const char *from = command.GetArgumentAtIndex(i);
1206 const char *to = command.GetArgumentAtIndex(i + 1);
1208 if (from[0] && to[0]) {
1209 bool last_pair = ((argc - i) == 2);
1210 target->GetImageSearchPathList().Insert(
1211 ConstString(from), ConstString(to), insert_idx, last_pair);
1212 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1215 result.AppendError("<path-prefix> can't be empty\n");
1217 result.AppendError("<new-path-prefix> can't be empty\n");
1218 result.SetStatus(eReturnStatusFailed);
1223 result.AppendError("insert requires at least three arguments\n");
1224 result.SetStatus(eReturnStatusFailed);
1225 return result.Succeeded();
1229 result.AppendError("invalid target\n");
1230 result.SetStatus(eReturnStatusFailed);
1232 return result.Succeeded();
1236 #pragma mark CommandObjectTargetModulesSearchPathsList
1238 class CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed {
1240 CommandObjectTargetModulesSearchPathsList(CommandInterpreter &interpreter)
1241 : CommandObjectParsed(interpreter, "target modules search-paths list",
1242 "List all current image search path substitution "
1243 "pairs in the current target.",
1244 "target modules search-paths list") {}
1246 ~CommandObjectTargetModulesSearchPathsList() override = default;
1249 bool DoExecute(Args &command, CommandReturnObject &result) override {
1250 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1252 if (command.GetArgumentCount() != 0) {
1253 result.AppendError("list takes no arguments\n");
1254 result.SetStatus(eReturnStatusFailed);
1255 return result.Succeeded();
1258 target->GetImageSearchPathList().Dump(&result.GetOutputStream());
1259 result.SetStatus(eReturnStatusSuccessFinishResult);
1261 result.AppendError("invalid target\n");
1262 result.SetStatus(eReturnStatusFailed);
1264 return result.Succeeded();
1268 #pragma mark CommandObjectTargetModulesSearchPathsQuery
1270 class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed {
1272 CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter &interpreter)
1273 : CommandObjectParsed(
1274 interpreter, "target modules search-paths query",
1275 "Transform a path using the first applicable image search path.",
1277 CommandArgumentEntry arg;
1278 CommandArgumentData path_arg;
1280 // Define the first (and only) variant of this arg.
1281 path_arg.arg_type = eArgTypeDirectoryName;
1282 path_arg.arg_repetition = eArgRepeatPlain;
1284 // There is only one variant this argument could be; put it into the
1286 arg.push_back(path_arg);
1288 // Push the data for the first argument into the m_arguments vector.
1289 m_arguments.push_back(arg);
1292 ~CommandObjectTargetModulesSearchPathsQuery() override = default;
1295 bool DoExecute(Args &command, CommandReturnObject &result) override {
1296 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1298 if (command.GetArgumentCount() != 1) {
1299 result.AppendError("query requires one argument\n");
1300 result.SetStatus(eReturnStatusFailed);
1301 return result.Succeeded();
1304 ConstString orig(command.GetArgumentAtIndex(0));
1305 ConstString transformed;
1306 if (target->GetImageSearchPathList().RemapPath(orig, transformed))
1307 result.GetOutputStream().Printf("%s\n", transformed.GetCString());
1309 result.GetOutputStream().Printf("%s\n", orig.GetCString());
1311 result.SetStatus(eReturnStatusSuccessFinishResult);
1313 result.AppendError("invalid target\n");
1314 result.SetStatus(eReturnStatusFailed);
1316 return result.Succeeded();
1320 //----------------------------------------------------------------------
1321 // Static Helper functions
1322 //----------------------------------------------------------------------
1323 static void DumpModuleArchitecture(Stream &strm, Module *module,
1324 bool full_triple, uint32_t width) {
1326 StreamString arch_strm;
1329 module->GetArchitecture().DumpTriple(arch_strm);
1331 arch_strm.PutCString(module->GetArchitecture().GetArchitectureName());
1332 std::string arch_str = arch_strm.GetString();
1335 strm.Printf("%-*s", width, arch_str.c_str());
1337 strm.PutCString(arch_str);
1341 static void DumpModuleUUID(Stream &strm, Module *module) {
1342 if (module && module->GetUUID().IsValid())
1343 module->GetUUID().Dump(&strm);
1345 strm.PutCString(" ");
1348 static uint32_t DumpCompileUnitLineTable(CommandInterpreter &interpreter,
1349 Stream &strm, Module *module,
1350 const FileSpec &file_spec,
1351 bool load_addresses) {
1352 uint32_t num_matches = 0;
1354 SymbolContextList sc_list;
1355 num_matches = module->ResolveSymbolContextsForFileSpec(
1356 file_spec, 0, false, eSymbolContextCompUnit, sc_list);
1358 for (uint32_t i = 0; i < num_matches; ++i) {
1360 if (sc_list.GetContextAtIndex(i, sc)) {
1364 strm << "Line table for " << *static_cast<FileSpec *>(sc.comp_unit)
1365 << " in `" << module->GetFileSpec().GetFilename() << "\n";
1366 LineTable *line_table = sc.comp_unit->GetLineTable();
1368 line_table->GetDescription(
1369 &strm, interpreter.GetExecutionContext().GetTargetPtr(),
1370 lldb::eDescriptionLevelBrief);
1372 strm << "No line table";
1379 static void DumpFullpath(Stream &strm, const FileSpec *file_spec_ptr,
1381 if (file_spec_ptr) {
1383 std::string fullpath = file_spec_ptr->GetPath();
1384 strm.Printf("%-*s", width, fullpath.c_str());
1387 file_spec_ptr->Dump(&strm);
1391 // Keep the width spacing correct if things go wrong...
1393 strm.Printf("%-*s", width, "");
1396 static void DumpDirectory(Stream &strm, const FileSpec *file_spec_ptr,
1398 if (file_spec_ptr) {
1400 strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
1402 file_spec_ptr->GetDirectory().Dump(&strm);
1405 // Keep the width spacing correct if things go wrong...
1407 strm.Printf("%-*s", width, "");
1410 static void DumpBasename(Stream &strm, const FileSpec *file_spec_ptr,
1412 if (file_spec_ptr) {
1414 strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
1416 file_spec_ptr->GetFilename().Dump(&strm);
1419 // Keep the width spacing correct if things go wrong...
1421 strm.Printf("%-*s", width, "");
1424 static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) {
1425 size_t num_dumped = 0;
1426 std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
1427 const size_t num_modules = module_list.GetSize();
1428 if (num_modules > 0) {
1429 strm.Printf("Dumping headers for %" PRIu64 " module(s).\n",
1430 static_cast<uint64_t>(num_modules));
1432 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
1433 Module *module = module_list.GetModulePointerAtIndexUnlocked(image_idx);
1435 if (num_dumped++ > 0) {
1439 ObjectFile *objfile = module->GetObjectFile();
1441 objfile->Dump(&strm);
1443 strm.Format("No object file for module: {0:F}\n",
1444 module->GetFileSpec());
1453 static void DumpModuleSymtab(CommandInterpreter &interpreter, Stream &strm,
1454 Module *module, SortOrder sort_order) {
1456 SymbolVendor *sym_vendor = module->GetSymbolVendor();
1458 Symtab *symtab = sym_vendor->GetSymtab();
1460 symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(),
1466 static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm,
1469 SectionList *section_list = module->GetSectionList();
1471 strm.Printf("Sections for '%s' (%s):\n",
1472 module->GetSpecificationDescription().c_str(),
1473 module->GetArchitecture().GetArchitectureName());
1475 section_list->Dump(&strm,
1476 interpreter.GetExecutionContext().GetTargetPtr(), true,
1483 static bool DumpModuleSymbolVendor(Stream &strm, Module *module) {
1485 SymbolVendor *symbol_vendor = module->GetSymbolVendor(true);
1486 if (symbol_vendor) {
1487 symbol_vendor->Dump(&strm);
1494 static void DumpAddress(ExecutionContextScope *exe_scope,
1495 const Address &so_addr, bool verbose, Stream &strm) {
1497 strm.Indent(" Address: ");
1498 so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
1499 strm.PutCString(" (");
1500 so_addr.Dump(&strm, exe_scope, Address::DumpStyleSectionNameOffset);
1501 strm.PutCString(")\n");
1502 strm.Indent(" Summary: ");
1503 const uint32_t save_indent = strm.GetIndentLevel();
1504 strm.SetIndentLevel(save_indent + 13);
1505 so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription);
1506 strm.SetIndentLevel(save_indent);
1507 // Print out detailed address information when verbose is enabled
1510 so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext);
1515 static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm,
1516 Module *module, uint32_t resolve_mask,
1517 lldb::addr_t raw_addr, lldb::addr_t offset,
1520 lldb::addr_t addr = raw_addr - offset;
1523 Target *target = interpreter.GetExecutionContext().GetTargetPtr();
1524 if (target && !target->GetSectionLoadList().IsEmpty()) {
1525 if (!target->GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
1527 else if (so_addr.GetModule().get() != module)
1530 if (!module->ResolveFileAddress(addr, so_addr))
1534 ExecutionContextScope *exe_scope =
1535 interpreter.GetExecutionContext().GetBestExecutionContextScope();
1536 DumpAddress(exe_scope, so_addr, verbose, strm);
1537 // strm.IndentMore();
1538 // strm.Indent (" Address: ");
1539 // so_addr.Dump (&strm, exe_scope,
1540 // Address::DumpStyleModuleWithFileAddress);
1541 // strm.PutCString (" (");
1542 // so_addr.Dump (&strm, exe_scope,
1543 // Address::DumpStyleSectionNameOffset);
1544 // strm.PutCString (")\n");
1545 // strm.Indent (" Summary: ");
1546 // const uint32_t save_indent = strm.GetIndentLevel ();
1547 // strm.SetIndentLevel (save_indent + 13);
1548 // so_addr.Dump (&strm, exe_scope,
1549 // Address::DumpStyleResolvedDescription);
1550 // strm.SetIndentLevel (save_indent);
1551 // // Print out detailed address information when verbose is enabled
1555 // so_addr.Dump (&strm, exe_scope,
1556 // Address::DumpStyleDetailedSymbolContext);
1558 // strm.IndentLess();
1565 static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
1566 Stream &strm, Module *module,
1567 const char *name, bool name_is_regex,
1572 SymbolVendor *sym_vendor = module->GetSymbolVendor();
1574 Symtab *symtab = sym_vendor->GetSymtab();
1576 std::vector<uint32_t> match_indexes;
1577 ConstString symbol_name(name);
1578 uint32_t num_matches = 0;
1579 if (name_is_regex) {
1580 RegularExpression name_regexp(symbol_name.GetStringRef());
1581 num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType(
1582 name_regexp, eSymbolTypeAny, match_indexes);
1585 symtab->AppendSymbolIndexesWithName(symbol_name, match_indexes);
1588 if (num_matches > 0) {
1590 strm.Printf("%u symbols match %s'%s' in ", num_matches,
1591 name_is_regex ? "the regular expression " : "", name);
1592 DumpFullpath(strm, &module->GetFileSpec(), 0);
1593 strm.PutCString(":\n");
1595 for (uint32_t i = 0; i < num_matches; ++i) {
1596 Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
1597 if (symbol && symbol->ValueIsAddress()) {
1598 DumpAddress(interpreter.GetExecutionContext()
1599 .GetBestExecutionContextScope(),
1600 symbol->GetAddressRef(), verbose, strm);
1612 static void DumpSymbolContextList(ExecutionContextScope *exe_scope,
1613 Stream &strm, SymbolContextList &sc_list,
1617 const uint32_t num_matches = sc_list.GetSize();
1619 for (uint32_t i = 0; i < num_matches; ++i) {
1621 if (sc_list.GetContextAtIndex(i, sc)) {
1624 sc.GetAddressRange(eSymbolContextEverything, 0, true, range);
1626 DumpAddress(exe_scope, range.GetBaseAddress(), verbose, strm);
1632 static size_t LookupFunctionInModule(CommandInterpreter &interpreter,
1633 Stream &strm, Module *module,
1634 const char *name, bool name_is_regex,
1635 bool include_inlines, bool include_symbols,
1637 if (module && name && name[0]) {
1638 SymbolContextList sc_list;
1639 const bool append = true;
1640 size_t num_matches = 0;
1641 if (name_is_regex) {
1642 RegularExpression function_name_regex((llvm::StringRef(name)));
1643 num_matches = module->FindFunctions(function_name_regex, include_symbols,
1644 include_inlines, append, sc_list);
1646 ConstString function_name(name);
1647 num_matches = module->FindFunctions(
1648 function_name, nullptr, eFunctionNameTypeAuto, include_symbols,
1649 include_inlines, append, sc_list);
1654 strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
1655 num_matches > 1 ? "es" : "");
1656 DumpFullpath(strm, &module->GetFileSpec(), 0);
1657 strm.PutCString(":\n");
1658 DumpSymbolContextList(
1659 interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1660 strm, sc_list, verbose);
1667 static size_t LookupTypeInModule(CommandInterpreter &interpreter, Stream &strm,
1668 Module *module, const char *name_cstr,
1669 bool name_is_regex) {
1670 if (module && name_cstr && name_cstr[0]) {
1672 const uint32_t max_num_matches = UINT32_MAX;
1673 size_t num_matches = 0;
1674 bool name_is_fully_qualified = false;
1676 ConstString name(name_cstr);
1677 llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
1679 module->FindTypes(name, name_is_fully_qualified, max_num_matches,
1680 searched_symbol_files, type_list);
1684 strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
1685 num_matches > 1 ? "es" : "");
1686 DumpFullpath(strm, &module->GetFileSpec(), 0);
1687 strm.PutCString(":\n");
1688 for (TypeSP type_sp : type_list.Types()) {
1690 // Resolve the clang type so that any forward references to types
1691 // that haven't yet been parsed will get parsed.
1692 type_sp->GetFullCompilerType();
1693 type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
1694 // Print all typedef chains
1695 TypeSP typedef_type_sp(type_sp);
1696 TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1697 while (typedefed_type_sp) {
1699 strm.Printf(" typedef '%s': ",
1700 typedef_type_sp->GetName().GetCString());
1701 typedefed_type_sp->GetFullCompilerType();
1702 typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull,
1704 typedef_type_sp = typedefed_type_sp;
1705 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1716 static size_t LookupTypeHere(CommandInterpreter &interpreter, Stream &strm,
1717 Module &module, const char *name_cstr,
1718 bool name_is_regex) {
1720 const uint32_t max_num_matches = UINT32_MAX;
1721 size_t num_matches = 1;
1722 bool name_is_fully_qualified = false;
1724 ConstString name(name_cstr);
1725 llvm::DenseSet<SymbolFile *> searched_symbol_files;
1726 num_matches = module.FindTypes(name, name_is_fully_qualified, max_num_matches,
1727 searched_symbol_files, type_list);
1731 strm.PutCString("Best match found in ");
1732 DumpFullpath(strm, &module.GetFileSpec(), 0);
1733 strm.PutCString(":\n");
1735 TypeSP type_sp(type_list.GetTypeAtIndex(0));
1737 // Resolve the clang type so that any forward references to types that
1738 // haven't yet been parsed will get parsed.
1739 type_sp->GetFullCompilerType();
1740 type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
1741 // Print all typedef chains
1742 TypeSP typedef_type_sp(type_sp);
1743 TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1744 while (typedefed_type_sp) {
1746 strm.Printf(" typedef '%s': ",
1747 typedef_type_sp->GetName().GetCString());
1748 typedefed_type_sp->GetFullCompilerType();
1749 typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
1750 typedef_type_sp = typedefed_type_sp;
1751 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1759 static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter,
1760 Stream &strm, Module *module,
1761 const FileSpec &file_spec,
1762 uint32_t line, bool check_inlines,
1764 if (module && file_spec) {
1765 SymbolContextList sc_list;
1766 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(
1767 file_spec, line, check_inlines, eSymbolContextEverything, sc_list);
1768 if (num_matches > 0) {
1770 strm.Printf("%u match%s found in ", num_matches,
1771 num_matches > 1 ? "es" : "");
1774 strm.Printf(":%u", line);
1776 DumpFullpath(strm, &module->GetFileSpec(), 0);
1777 strm.PutCString(":\n");
1778 DumpSymbolContextList(
1779 interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1780 strm, sc_list, verbose);
1787 static size_t FindModulesByName(Target *target, const char *module_name,
1788 ModuleList &module_list,
1789 bool check_global_list) {
1790 FileSpec module_file_spec(module_name);
1791 ModuleSpec module_spec(module_file_spec);
1793 const size_t initial_size = module_list.GetSize();
1795 if (check_global_list) {
1796 // Check the global list
1797 std::lock_guard<std::recursive_mutex> guard(
1798 Module::GetAllocationModuleCollectionMutex());
1799 const size_t num_modules = Module::GetNumberAllocatedModules();
1801 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
1802 Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
1805 if (module->MatchesModuleSpec(module_spec)) {
1806 module_sp = module->shared_from_this();
1807 module_list.AppendIfNeeded(module_sp);
1813 const size_t num_matches =
1814 target->GetImages().FindModules(module_spec, module_list);
1816 // Not found in our module list for our target, check the main shared
1817 // module list in case it is a extra file used somewhere else
1818 if (num_matches == 0) {
1819 module_spec.GetArchitecture() = target->GetArchitecture();
1820 ModuleList::FindSharedModules(module_spec, module_list);
1823 ModuleList::FindSharedModules(module_spec, module_list);
1827 return module_list.GetSize() - initial_size;
1830 #pragma mark CommandObjectTargetModulesModuleAutoComplete
1832 //----------------------------------------------------------------------
1833 // A base command object class that can auto complete with module file
1835 //----------------------------------------------------------------------
1837 class CommandObjectTargetModulesModuleAutoComplete
1838 : public CommandObjectParsed {
1840 CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter &interpreter,
1844 : CommandObjectParsed(interpreter, name, help, syntax) {
1845 CommandArgumentEntry arg;
1846 CommandArgumentData file_arg;
1848 // Define the first (and only) variant of this arg.
1849 file_arg.arg_type = eArgTypeFilename;
1850 file_arg.arg_repetition = eArgRepeatStar;
1852 // There is only one variant this argument could be; put it into the
1854 arg.push_back(file_arg);
1856 // Push the data for the first argument into the m_arguments vector.
1857 m_arguments.push_back(arg);
1860 ~CommandObjectTargetModulesModuleAutoComplete() override = default;
1862 int HandleArgumentCompletion(
1863 CompletionRequest &request,
1864 OptionElementVector &opt_element_vector) override {
1865 CommandCompletions::InvokeCommonCompletionCallbacks(
1866 GetCommandInterpreter(), CommandCompletions::eModuleCompletion, request,
1868 return request.GetNumberOfMatches();
1872 #pragma mark CommandObjectTargetModulesSourceFileAutoComplete
1874 //----------------------------------------------------------------------
1875 // A base command object class that can auto complete with module source
1877 //----------------------------------------------------------------------
1879 class CommandObjectTargetModulesSourceFileAutoComplete
1880 : public CommandObjectParsed {
1882 CommandObjectTargetModulesSourceFileAutoComplete(
1883 CommandInterpreter &interpreter, const char *name, const char *help,
1884 const char *syntax, uint32_t flags)
1885 : CommandObjectParsed(interpreter, name, help, syntax, flags) {
1886 CommandArgumentEntry arg;
1887 CommandArgumentData source_file_arg;
1889 // Define the first (and only) variant of this arg.
1890 source_file_arg.arg_type = eArgTypeSourceFile;
1891 source_file_arg.arg_repetition = eArgRepeatPlus;
1893 // There is only one variant this argument could be; put it into the
1895 arg.push_back(source_file_arg);
1897 // Push the data for the first argument into the m_arguments vector.
1898 m_arguments.push_back(arg);
1901 ~CommandObjectTargetModulesSourceFileAutoComplete() override = default;
1903 int HandleArgumentCompletion(
1904 CompletionRequest &request,
1905 OptionElementVector &opt_element_vector) override {
1906 CommandCompletions::InvokeCommonCompletionCallbacks(
1907 GetCommandInterpreter(), CommandCompletions::eSourceFileCompletion,
1909 return request.GetNumberOfMatches();
1913 #pragma mark CommandObjectTargetModulesDumpObjfile
1915 class CommandObjectTargetModulesDumpObjfile
1916 : public CommandObjectTargetModulesModuleAutoComplete {
1918 CommandObjectTargetModulesDumpObjfile(CommandInterpreter &interpreter)
1919 : CommandObjectTargetModulesModuleAutoComplete(
1920 interpreter, "target modules dump objfile",
1921 "Dump the object file headers from one or more target modules.",
1924 ~CommandObjectTargetModulesDumpObjfile() override = default;
1927 bool DoExecute(Args &command, CommandReturnObject &result) override {
1928 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1929 if (target == nullptr) {
1930 result.AppendError("invalid target, create a debug target using the "
1931 "'target create' command");
1932 result.SetStatus(eReturnStatusFailed);
1936 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1937 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1938 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1940 size_t num_dumped = 0;
1941 if (command.GetArgumentCount() == 0) {
1942 // Dump all headers for all modules images
1943 num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(),
1944 target->GetImages());
1945 if (num_dumped == 0) {
1946 result.AppendError("the target has no associated executable images");
1947 result.SetStatus(eReturnStatusFailed);
1950 // Find the modules that match the basename or full path.
1951 ModuleList module_list;
1952 const char *arg_cstr;
1953 for (int arg_idx = 0;
1954 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
1956 size_t num_matched =
1957 FindModulesByName(target, arg_cstr, module_list, true);
1958 if (num_matched == 0) {
1959 result.AppendWarningWithFormat(
1960 "Unable to find an image that matches '%s'.\n", arg_cstr);
1963 // Dump all the modules we found.
1965 DumpModuleObjfileHeaders(result.GetOutputStream(), module_list);
1968 if (num_dumped > 0) {
1969 result.SetStatus(eReturnStatusSuccessFinishResult);
1971 result.AppendError("no matching executable images found");
1972 result.SetStatus(eReturnStatusFailed);
1974 return result.Succeeded();
1978 #pragma mark CommandObjectTargetModulesDumpSymtab
1980 static constexpr OptionEnumValueElement g_sort_option_enumeration[] = {
1981 {eSortOrderNone, "none",
1982 "No sorting, use the original symbol table order."},
1983 {eSortOrderByAddress, "address", "Sort output by symbol address."},
1984 {eSortOrderByName, "name", "Sort output by symbol name."} };
1986 static constexpr OptionDefinition g_target_modules_dump_symtab_options[] = {
1988 { LLDB_OPT_SET_1, false, "sort", 's', OptionParser::eRequiredArgument, nullptr, OptionEnumValues(g_sort_option_enumeration), 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table." }
1992 class CommandObjectTargetModulesDumpSymtab
1993 : public CommandObjectTargetModulesModuleAutoComplete {
1995 CommandObjectTargetModulesDumpSymtab(CommandInterpreter &interpreter)
1996 : CommandObjectTargetModulesModuleAutoComplete(
1997 interpreter, "target modules dump symtab",
1998 "Dump the symbol table from one or more target modules.", nullptr),
2001 ~CommandObjectTargetModulesDumpSymtab() override = default;
2003 Options *GetOptions() override { return &m_options; }
2005 class CommandOptions : public Options {
2007 CommandOptions() : Options(), m_sort_order(eSortOrderNone) {}
2009 ~CommandOptions() override = default;
2011 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2012 ExecutionContext *execution_context) override {
2014 const int short_option = m_getopt_table[option_idx].val;
2016 switch (short_option) {
2018 m_sort_order = (SortOrder)OptionArgParser::ToOptionEnum(
2019 option_arg, GetDefinitions()[option_idx].enum_values,
2020 eSortOrderNone, error);
2024 error.SetErrorStringWithFormat("invalid short option character '%c'",
2031 void OptionParsingStarting(ExecutionContext *execution_context) override {
2032 m_sort_order = eSortOrderNone;
2035 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2036 return llvm::makeArrayRef(g_target_modules_dump_symtab_options);
2039 SortOrder m_sort_order;
2043 bool DoExecute(Args &command, CommandReturnObject &result) override {
2044 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2045 if (target == nullptr) {
2046 result.AppendError("invalid target, create a debug target using the "
2047 "'target create' command");
2048 result.SetStatus(eReturnStatusFailed);
2051 uint32_t num_dumped = 0;
2053 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2054 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2055 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2057 if (command.GetArgumentCount() == 0) {
2058 // Dump all sections for all modules images
2059 std::lock_guard<std::recursive_mutex> guard(
2060 target->GetImages().GetMutex());
2061 const size_t num_modules = target->GetImages().GetSize();
2062 if (num_modules > 0) {
2063 result.GetOutputStream().Printf("Dumping symbol table for %" PRIu64
2065 (uint64_t)num_modules);
2066 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2067 if (num_dumped > 0) {
2068 result.GetOutputStream().EOL();
2069 result.GetOutputStream().EOL();
2071 if (m_interpreter.WasInterrupted())
2075 m_interpreter, result.GetOutputStream(),
2076 target->GetImages().GetModulePointerAtIndexUnlocked(image_idx),
2077 m_options.m_sort_order);
2080 result.AppendError("the target has no associated executable images");
2081 result.SetStatus(eReturnStatusFailed);
2085 // Dump specified images (by basename or fullpath)
2086 const char *arg_cstr;
2087 for (int arg_idx = 0;
2088 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2090 ModuleList module_list;
2091 const size_t num_matches =
2092 FindModulesByName(target, arg_cstr, module_list, true);
2093 if (num_matches > 0) {
2094 for (size_t i = 0; i < num_matches; ++i) {
2095 Module *module = module_list.GetModulePointerAtIndex(i);
2097 if (num_dumped > 0) {
2098 result.GetOutputStream().EOL();
2099 result.GetOutputStream().EOL();
2101 if (m_interpreter.WasInterrupted())
2104 DumpModuleSymtab(m_interpreter, result.GetOutputStream(),
2105 module, m_options.m_sort_order);
2109 result.AppendWarningWithFormat(
2110 "Unable to find an image that matches '%s'.\n", arg_cstr);
2115 result.SetStatus(eReturnStatusSuccessFinishResult);
2117 result.AppendError("no matching executable images found");
2118 result.SetStatus(eReturnStatusFailed);
2121 return result.Succeeded();
2124 CommandOptions m_options;
2127 #pragma mark CommandObjectTargetModulesDumpSections
2129 //----------------------------------------------------------------------
2130 // Image section dumping command
2131 //----------------------------------------------------------------------
2133 class CommandObjectTargetModulesDumpSections
2134 : public CommandObjectTargetModulesModuleAutoComplete {
2136 CommandObjectTargetModulesDumpSections(CommandInterpreter &interpreter)
2137 : CommandObjectTargetModulesModuleAutoComplete(
2138 interpreter, "target modules dump sections",
2139 "Dump the sections from one or more target modules.",
2140 //"target modules dump sections [<file1> ...]")
2143 ~CommandObjectTargetModulesDumpSections() override = default;
2146 bool DoExecute(Args &command, CommandReturnObject &result) override {
2147 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2148 if (target == nullptr) {
2149 result.AppendError("invalid target, create a debug target using the "
2150 "'target create' command");
2151 result.SetStatus(eReturnStatusFailed);
2154 uint32_t num_dumped = 0;
2156 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2157 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2158 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2160 if (command.GetArgumentCount() == 0) {
2161 // Dump all sections for all modules images
2162 const size_t num_modules = target->GetImages().GetSize();
2163 if (num_modules > 0) {
2164 result.GetOutputStream().Printf("Dumping sections for %" PRIu64
2166 (uint64_t)num_modules);
2167 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2168 if (m_interpreter.WasInterrupted())
2172 m_interpreter, result.GetOutputStream(),
2173 target->GetImages().GetModulePointerAtIndex(image_idx));
2176 result.AppendError("the target has no associated executable images");
2177 result.SetStatus(eReturnStatusFailed);
2181 // Dump specified images (by basename or fullpath)
2182 const char *arg_cstr;
2183 for (int arg_idx = 0;
2184 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2186 ModuleList module_list;
2187 const size_t num_matches =
2188 FindModulesByName(target, arg_cstr, module_list, true);
2189 if (num_matches > 0) {
2190 for (size_t i = 0; i < num_matches; ++i) {
2191 if (m_interpreter.WasInterrupted())
2193 Module *module = module_list.GetModulePointerAtIndex(i);
2196 DumpModuleSections(m_interpreter, result.GetOutputStream(),
2201 // Check the global list
2202 std::lock_guard<std::recursive_mutex> guard(
2203 Module::GetAllocationModuleCollectionMutex());
2205 result.AppendWarningWithFormat(
2206 "Unable to find an image that matches '%s'.\n", arg_cstr);
2212 result.SetStatus(eReturnStatusSuccessFinishResult);
2214 result.AppendError("no matching executable images found");
2215 result.SetStatus(eReturnStatusFailed);
2218 return result.Succeeded();
2222 #pragma mark CommandObjectTargetModulesDumpSections
2224 //----------------------------------------------------------------------
2225 // Clang AST dumping command
2226 //----------------------------------------------------------------------
2228 class CommandObjectTargetModulesDumpClangAST
2229 : public CommandObjectTargetModulesModuleAutoComplete {
2231 CommandObjectTargetModulesDumpClangAST(CommandInterpreter &interpreter)
2232 : CommandObjectTargetModulesModuleAutoComplete(
2233 interpreter, "target modules dump ast",
2234 "Dump the clang ast for a given module's symbol file.",
2235 //"target modules dump ast [<file1> ...]")
2238 ~CommandObjectTargetModulesDumpClangAST() override = default;
2241 bool DoExecute(Args &command, CommandReturnObject &result) override {
2242 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2243 if (target == nullptr) {
2244 result.AppendError("invalid target, create a debug target using the "
2245 "'target create' command");
2246 result.SetStatus(eReturnStatusFailed);
2250 const size_t num_modules = target->GetImages().GetSize();
2251 if (num_modules == 0) {
2252 result.AppendError("the target has no associated executable images");
2253 result.SetStatus(eReturnStatusFailed);
2257 if (command.GetArgumentCount() == 0) {
2258 // Dump all ASTs for all modules images
2259 result.GetOutputStream().Printf("Dumping clang ast for %" PRIu64
2261 (uint64_t)num_modules);
2262 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2263 if (m_interpreter.WasInterrupted())
2265 Module *m = target->GetImages().GetModulePointerAtIndex(image_idx);
2266 SymbolFile *sf = m->GetSymbolVendor()->GetSymbolFile();
2267 sf->DumpClangAST(result.GetOutputStream());
2269 result.SetStatus(eReturnStatusSuccessFinishResult);
2273 // Dump specified ASTs (by basename or fullpath)
2274 for (const Args::ArgEntry &arg : command.entries()) {
2275 ModuleList module_list;
2276 const size_t num_matches =
2277 FindModulesByName(target, arg.c_str(), module_list, true);
2278 if (num_matches == 0) {
2279 // Check the global list
2280 std::lock_guard<std::recursive_mutex> guard(
2281 Module::GetAllocationModuleCollectionMutex());
2283 result.AppendWarningWithFormat(
2284 "Unable to find an image that matches '%s'.\n", arg.c_str());
2288 for (size_t i = 0; i < num_matches; ++i) {
2289 if (m_interpreter.WasInterrupted())
2291 Module *m = module_list.GetModulePointerAtIndex(i);
2292 SymbolFile *sf = m->GetSymbolVendor()->GetSymbolFile();
2293 sf->DumpClangAST(result.GetOutputStream());
2296 result.SetStatus(eReturnStatusSuccessFinishResult);
2301 #pragma mark CommandObjectTargetModulesDumpSymfile
2303 //----------------------------------------------------------------------
2304 // Image debug symbol dumping command
2305 //----------------------------------------------------------------------
2307 class CommandObjectTargetModulesDumpSymfile
2308 : public CommandObjectTargetModulesModuleAutoComplete {
2310 CommandObjectTargetModulesDumpSymfile(CommandInterpreter &interpreter)
2311 : CommandObjectTargetModulesModuleAutoComplete(
2312 interpreter, "target modules dump symfile",
2313 "Dump the debug symbol file for one or more target modules.",
2314 //"target modules dump symfile [<file1> ...]")
2317 ~CommandObjectTargetModulesDumpSymfile() override = default;
2320 bool DoExecute(Args &command, CommandReturnObject &result) override {
2321 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2322 if (target == nullptr) {
2323 result.AppendError("invalid target, create a debug target using the "
2324 "'target create' command");
2325 result.SetStatus(eReturnStatusFailed);
2328 uint32_t num_dumped = 0;
2330 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2331 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2332 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2334 if (command.GetArgumentCount() == 0) {
2335 // Dump all sections for all modules images
2336 const ModuleList &target_modules = target->GetImages();
2337 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2338 const size_t num_modules = target_modules.GetSize();
2339 if (num_modules > 0) {
2340 result.GetOutputStream().Printf("Dumping debug symbols for %" PRIu64
2342 (uint64_t)num_modules);
2343 for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2344 if (m_interpreter.WasInterrupted())
2346 if (DumpModuleSymbolVendor(
2347 result.GetOutputStream(),
2348 target_modules.GetModulePointerAtIndexUnlocked(image_idx)))
2352 result.AppendError("the target has no associated executable images");
2353 result.SetStatus(eReturnStatusFailed);
2357 // Dump specified images (by basename or fullpath)
2358 const char *arg_cstr;
2359 for (int arg_idx = 0;
2360 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2362 ModuleList module_list;
2363 const size_t num_matches =
2364 FindModulesByName(target, arg_cstr, module_list, true);
2365 if (num_matches > 0) {
2366 for (size_t i = 0; i < num_matches; ++i) {
2367 if (m_interpreter.WasInterrupted())
2369 Module *module = module_list.GetModulePointerAtIndex(i);
2371 if (DumpModuleSymbolVendor(result.GetOutputStream(), module))
2376 result.AppendWarningWithFormat(
2377 "Unable to find an image that matches '%s'.\n", arg_cstr);
2382 result.SetStatus(eReturnStatusSuccessFinishResult);
2384 result.AppendError("no matching executable images found");
2385 result.SetStatus(eReturnStatusFailed);
2388 return result.Succeeded();
2392 #pragma mark CommandObjectTargetModulesDumpLineTable
2394 //----------------------------------------------------------------------
2395 // Image debug line table dumping command
2396 //----------------------------------------------------------------------
2398 class CommandObjectTargetModulesDumpLineTable
2399 : public CommandObjectTargetModulesSourceFileAutoComplete {
2401 CommandObjectTargetModulesDumpLineTable(CommandInterpreter &interpreter)
2402 : CommandObjectTargetModulesSourceFileAutoComplete(
2403 interpreter, "target modules dump line-table",
2404 "Dump the line table for one or more compilation units.", nullptr,
2405 eCommandRequiresTarget) {}
2407 ~CommandObjectTargetModulesDumpLineTable() override = default;
2410 bool DoExecute(Args &command, CommandReturnObject &result) override {
2411 Target *target = m_exe_ctx.GetTargetPtr();
2412 uint32_t total_num_dumped = 0;
2414 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2415 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2416 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2418 if (command.GetArgumentCount() == 0) {
2419 result.AppendError("file option must be specified.");
2420 result.SetStatus(eReturnStatusFailed);
2421 return result.Succeeded();
2423 // Dump specified images (by basename or fullpath)
2424 const char *arg_cstr;
2425 for (int arg_idx = 0;
2426 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2428 FileSpec file_spec(arg_cstr);
2430 const ModuleList &target_modules = target->GetImages();
2431 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2432 const size_t num_modules = target_modules.GetSize();
2433 if (num_modules > 0) {
2434 uint32_t num_dumped = 0;
2435 for (uint32_t i = 0; i < num_modules; ++i) {
2436 if (m_interpreter.WasInterrupted())
2438 if (DumpCompileUnitLineTable(
2439 m_interpreter, result.GetOutputStream(),
2440 target_modules.GetModulePointerAtIndexUnlocked(i),
2441 file_spec, m_exe_ctx.GetProcessPtr() &&
2442 m_exe_ctx.GetProcessRef().IsAlive()))
2445 if (num_dumped == 0)
2446 result.AppendWarningWithFormat(
2447 "No source filenames matched '%s'.\n", arg_cstr);
2449 total_num_dumped += num_dumped;
2454 if (total_num_dumped > 0)
2455 result.SetStatus(eReturnStatusSuccessFinishResult);
2457 result.AppendError("no source filenames matched any command arguments");
2458 result.SetStatus(eReturnStatusFailed);
2460 return result.Succeeded();
2464 #pragma mark CommandObjectTargetModulesDump
2466 //----------------------------------------------------------------------
2467 // Dump multi-word command for target modules
2468 //----------------------------------------------------------------------
2470 class CommandObjectTargetModulesDump : public CommandObjectMultiword {
2472 //------------------------------------------------------------------
2473 // Constructors and Destructors
2474 //------------------------------------------------------------------
2475 CommandObjectTargetModulesDump(CommandInterpreter &interpreter)
2476 : CommandObjectMultiword(
2477 interpreter, "target modules dump",
2478 "Commands for dumping information about one or "
2479 "more target modules.",
2480 "target modules dump "
2481 "[headers|symtab|sections|ast|symfile|line-table] "
2482 "[<file1> <file2> ...]") {
2483 LoadSubCommand("objfile",
2485 new CommandObjectTargetModulesDumpObjfile(interpreter)));
2488 CommandObjectSP(new CommandObjectTargetModulesDumpSymtab(interpreter)));
2489 LoadSubCommand("sections",
2490 CommandObjectSP(new CommandObjectTargetModulesDumpSections(
2492 LoadSubCommand("symfile",
2494 new CommandObjectTargetModulesDumpSymfile(interpreter)));
2496 "ast", CommandObjectSP(
2497 new CommandObjectTargetModulesDumpClangAST(interpreter)));
2498 LoadSubCommand("line-table",
2499 CommandObjectSP(new CommandObjectTargetModulesDumpLineTable(
2503 ~CommandObjectTargetModulesDump() override = default;
2506 class CommandObjectTargetModulesAdd : public CommandObjectParsed {
2508 CommandObjectTargetModulesAdd(CommandInterpreter &interpreter)
2509 : CommandObjectParsed(interpreter, "target modules add",
2510 "Add a new module to the current target's modules.",
2511 "target modules add [<module>]"),
2513 m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
2514 eArgTypeFilename, "Fullpath to a stand alone debug "
2515 "symbols file for when debug symbols "
2516 "are not in the executable.") {
2517 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
2519 m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2520 m_option_group.Finalize();
2523 ~CommandObjectTargetModulesAdd() override = default;
2525 Options *GetOptions() override { return &m_option_group; }
2527 int HandleArgumentCompletion(
2528 CompletionRequest &request,
2529 OptionElementVector &opt_element_vector) override {
2530 CommandCompletions::InvokeCommonCompletionCallbacks(
2531 GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
2533 return request.GetNumberOfMatches();
2537 OptionGroupOptions m_option_group;
2538 OptionGroupUUID m_uuid_option_group;
2539 OptionGroupFile m_symbol_file;
2541 bool DoExecute(Args &args, CommandReturnObject &result) override {
2542 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2543 if (target == nullptr) {
2544 result.AppendError("invalid target, create a debug target using the "
2545 "'target create' command");
2546 result.SetStatus(eReturnStatusFailed);
2551 const size_t argc = args.GetArgumentCount();
2553 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2554 // We are given a UUID only, go locate the file
2555 ModuleSpec module_spec;
2556 module_spec.GetUUID() =
2557 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2558 if (m_symbol_file.GetOptionValue().OptionWasSet())
2559 module_spec.GetSymbolFileSpec() =
2560 m_symbol_file.GetOptionValue().GetCurrentValue();
2561 if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
2562 ModuleSP module_sp(target->GetSharedModule(module_spec));
2564 result.SetStatus(eReturnStatusSuccessFinishResult);
2568 module_spec.GetUUID().Dump(&strm);
2569 if (module_spec.GetFileSpec()) {
2570 if (module_spec.GetSymbolFileSpec()) {
2571 result.AppendErrorWithFormat(
2572 "Unable to create the executable or symbol file with "
2573 "UUID %s with path %s and symbol file %s",
2575 module_spec.GetFileSpec().GetPath().c_str(),
2576 module_spec.GetSymbolFileSpec().GetPath().c_str());
2578 result.AppendErrorWithFormat(
2579 "Unable to create the executable or symbol file with "
2580 "UUID %s with path %s",
2582 module_spec.GetFileSpec().GetPath().c_str());
2585 result.AppendErrorWithFormat("Unable to create the executable "
2586 "or symbol file with UUID %s",
2589 result.SetStatus(eReturnStatusFailed);
2594 module_spec.GetUUID().Dump(&strm);
2595 result.AppendErrorWithFormat(
2596 "Unable to locate the executable or symbol file with UUID %s",
2598 result.SetStatus(eReturnStatusFailed);
2603 "one or more executable image paths must be specified");
2604 result.SetStatus(eReturnStatusFailed);
2608 for (auto &entry : args.entries()) {
2609 if (entry.ref.empty())
2612 FileSpec file_spec(entry.ref);
2613 if (FileSystem::Instance().Exists(file_spec)) {
2614 ModuleSpec module_spec(file_spec);
2615 if (m_uuid_option_group.GetOptionValue().OptionWasSet())
2616 module_spec.GetUUID() =
2617 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2618 if (m_symbol_file.GetOptionValue().OptionWasSet())
2619 module_spec.GetSymbolFileSpec() =
2620 m_symbol_file.GetOptionValue().GetCurrentValue();
2621 if (!module_spec.GetArchitecture().IsValid())
2622 module_spec.GetArchitecture() = target->GetArchitecture();
2624 ModuleSP module_sp(target->GetSharedModule(module_spec, &error));
2626 const char *error_cstr = error.AsCString();
2628 result.AppendError(error_cstr);
2630 result.AppendErrorWithFormat("unsupported module: %s",
2632 result.SetStatus(eReturnStatusFailed);
2637 result.SetStatus(eReturnStatusSuccessFinishResult);
2639 std::string resolved_path = file_spec.GetPath();
2640 result.SetStatus(eReturnStatusFailed);
2641 if (resolved_path != entry.ref) {
2642 result.AppendErrorWithFormat(
2643 "invalid module path '%s' with resolved path '%s'\n",
2644 entry.ref.str().c_str(), resolved_path.c_str());
2647 result.AppendErrorWithFormat("invalid module path '%s'\n",
2655 ProcessSP process = target->GetProcessSP();
2661 return result.Succeeded();
2665 class CommandObjectTargetModulesLoad
2666 : public CommandObjectTargetModulesModuleAutoComplete {
2668 CommandObjectTargetModulesLoad(CommandInterpreter &interpreter)
2669 : CommandObjectTargetModulesModuleAutoComplete(
2670 interpreter, "target modules load", "Set the load addresses for "
2671 "one or more sections in a "
2673 "target modules load [--file <module> --uuid <uuid>] <sect-name> "
2674 "<address> [<sect-name> <address> ....]"),
2676 m_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName,
2677 "Fullpath or basename for module to load.", ""),
2678 m_load_option(LLDB_OPT_SET_1, false, "load", 'l',
2679 "Write file contents to the memory.", false, true),
2680 m_pc_option(LLDB_OPT_SET_1, false, "set-pc-to-entry", 'p',
2681 "Set PC to the entry point."
2682 " Only applicable with '--load' option.",
2684 m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset,
2685 "Set the load address for all sections to be the "
2686 "virtual address in the file plus the offset.",
2688 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
2690 m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2691 m_option_group.Append(&m_load_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2692 m_option_group.Append(&m_pc_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2693 m_option_group.Append(&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2694 m_option_group.Finalize();
2697 ~CommandObjectTargetModulesLoad() override = default;
2699 Options *GetOptions() override { return &m_option_group; }
2702 bool DoExecute(Args &args, CommandReturnObject &result) override {
2703 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2704 const bool load = m_load_option.GetOptionValue().GetCurrentValue();
2705 const bool set_pc = m_pc_option.GetOptionValue().GetCurrentValue();
2706 if (target == nullptr) {
2707 result.AppendError("invalid target, create a debug target using the "
2708 "'target create' command");
2709 result.SetStatus(eReturnStatusFailed);
2712 const size_t argc = args.GetArgumentCount();
2713 ModuleSpec module_spec;
2714 bool search_using_module_spec = false;
2716 // Allow "load" option to work without --file or --uuid option.
2718 if (!m_file_option.GetOptionValue().OptionWasSet() &&
2719 !m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2720 ModuleList &module_list = target->GetImages();
2721 if (module_list.GetSize() == 1) {
2722 search_using_module_spec = true;
2723 module_spec.GetFileSpec() =
2724 module_list.GetModuleAtIndex(0)->GetFileSpec();
2729 if (m_file_option.GetOptionValue().OptionWasSet()) {
2730 search_using_module_spec = true;
2731 const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
2732 const bool use_global_module_list = true;
2733 ModuleList module_list;
2734 const size_t num_matches = FindModulesByName(
2735 target, arg_cstr, module_list, use_global_module_list);
2736 if (num_matches == 1) {
2737 module_spec.GetFileSpec() =
2738 module_list.GetModuleAtIndex(0)->GetFileSpec();
2739 } else if (num_matches > 1) {
2740 search_using_module_spec = false;
2741 result.AppendErrorWithFormat(
2742 "more than 1 module matched by name '%s'\n", arg_cstr);
2743 result.SetStatus(eReturnStatusFailed);
2745 search_using_module_spec = false;
2746 result.AppendErrorWithFormat("no object file for module '%s'\n",
2748 result.SetStatus(eReturnStatusFailed);
2752 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2753 search_using_module_spec = true;
2754 module_spec.GetUUID() =
2755 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2758 if (search_using_module_spec) {
2759 ModuleList matching_modules;
2760 const size_t num_matches =
2761 target->GetImages().FindModules(module_spec, matching_modules);
2763 char path[PATH_MAX];
2764 if (num_matches == 1) {
2765 Module *module = matching_modules.GetModulePointerAtIndex(0);
2767 ObjectFile *objfile = module->GetObjectFile();
2769 SectionList *section_list = module->GetSectionList();
2771 bool changed = false;
2773 if (m_slide_option.GetOptionValue().OptionWasSet()) {
2774 const addr_t slide =
2775 m_slide_option.GetOptionValue().GetCurrentValue();
2776 const bool slide_is_offset = true;
2777 module->SetLoadAddress(*target, slide, slide_is_offset,
2780 result.AppendError("one or more section name + load "
2781 "address pair must be specified");
2782 result.SetStatus(eReturnStatusFailed);
2786 if (m_slide_option.GetOptionValue().OptionWasSet()) {
2787 result.AppendError("The \"--slide <offset>\" option can't "
2788 "be used in conjunction with setting "
2789 "section load addresses.\n");
2790 result.SetStatus(eReturnStatusFailed);
2794 for (size_t i = 0; i < argc; i += 2) {
2795 const char *sect_name = args.GetArgumentAtIndex(i);
2796 const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1);
2797 if (sect_name && load_addr_cstr) {
2798 ConstString const_sect_name(sect_name);
2799 bool success = false;
2800 addr_t load_addr = StringConvert::ToUInt64(
2801 load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success);
2803 SectionSP section_sp(
2804 section_list->FindSectionByName(const_sect_name));
2806 if (section_sp->IsThreadSpecific()) {
2807 result.AppendErrorWithFormat(
2808 "thread specific sections are not yet "
2809 "supported (section '%s')\n",
2811 result.SetStatus(eReturnStatusFailed);
2814 if (target->GetSectionLoadList()
2815 .SetSectionLoadAddress(section_sp,
2818 result.AppendMessageWithFormat(
2819 "section '%s' loaded at 0x%" PRIx64 "\n",
2820 sect_name, load_addr);
2823 result.AppendErrorWithFormat("no section found that "
2824 "matches the section "
2827 result.SetStatus(eReturnStatusFailed);
2831 result.AppendErrorWithFormat(
2832 "invalid load address string '%s'\n",
2834 result.SetStatus(eReturnStatusFailed);
2839 result.AppendError("section names must be followed by "
2840 "a load address.\n");
2842 result.AppendError("one or more section name + load "
2843 "address pair must be specified.\n");
2844 result.SetStatus(eReturnStatusFailed);
2851 target->ModulesDidLoad(matching_modules);
2852 Process *process = m_exe_ctx.GetProcessPtr();
2857 ProcessSP process = target->CalculateProcess();
2858 Address file_entry = objfile->GetEntryPointAddress();
2860 result.AppendError("No process");
2863 if (set_pc && !file_entry.IsValid()) {
2864 result.AppendError("No entry address in object file");
2867 std::vector<ObjectFile::LoadableData> loadables(
2868 objfile->GetLoadableData(*target));
2869 if (loadables.size() == 0) {
2870 result.AppendError("No loadable sections");
2873 Status error = process->WriteObjectFile(std::move(loadables));
2875 result.AppendError(error.AsCString());
2879 ThreadList &thread_list = process->GetThreadList();
2880 RegisterContextSP reg_context(
2881 thread_list.GetSelectedThread()->GetRegisterContext());
2882 addr_t file_entry_addr = file_entry.GetLoadAddress(target);
2883 if (!reg_context->SetPC(file_entry_addr)) {
2884 result.AppendErrorWithFormat("failed to set PC value to "
2887 result.SetStatus(eReturnStatusFailed);
2892 module->GetFileSpec().GetPath(path, sizeof(path));
2893 result.AppendErrorWithFormat(
2894 "no sections in object file '%s'\n", path);
2895 result.SetStatus(eReturnStatusFailed);
2898 module->GetFileSpec().GetPath(path, sizeof(path));
2899 result.AppendErrorWithFormat("no object file for module '%s'\n",
2901 result.SetStatus(eReturnStatusFailed);
2904 FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
2905 if (module_spec_file) {
2906 module_spec_file->GetPath(path, sizeof(path));
2907 result.AppendErrorWithFormat("invalid module '%s'.\n", path);
2909 result.AppendError("no module spec");
2910 result.SetStatus(eReturnStatusFailed);
2913 std::string uuid_str;
2915 if (module_spec.GetFileSpec())
2916 module_spec.GetFileSpec().GetPath(path, sizeof(path));
2920 if (module_spec.GetUUIDPtr())
2921 uuid_str = module_spec.GetUUID().GetAsString();
2922 if (num_matches > 1) {
2923 result.AppendErrorWithFormat(
2924 "multiple modules match%s%s%s%s:\n", path[0] ? " file=" : "",
2925 path, !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
2926 for (size_t i = 0; i < num_matches; ++i) {
2927 if (matching_modules.GetModulePointerAtIndex(i)
2929 .GetPath(path, sizeof(path)))
2930 result.AppendMessageWithFormat("%s\n", path);
2933 result.AppendErrorWithFormat(
2934 "no modules were found that match%s%s%s%s.\n",
2935 path[0] ? " file=" : "", path,
2936 !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
2938 result.SetStatus(eReturnStatusFailed);
2941 result.AppendError("either the \"--file <module>\" or the \"--uuid "
2942 "<uuid>\" option must be specified.\n");
2943 result.SetStatus(eReturnStatusFailed);
2947 return result.Succeeded();
2950 OptionGroupOptions m_option_group;
2951 OptionGroupUUID m_uuid_option_group;
2952 OptionGroupString m_file_option;
2953 OptionGroupBoolean m_load_option;
2954 OptionGroupBoolean m_pc_option;
2955 OptionGroupUInt64 m_slide_option;
2958 //----------------------------------------------------------------------
2959 // List images with associated information
2960 //----------------------------------------------------------------------
2962 static constexpr OptionDefinition g_target_modules_list_options[] = {
2964 { LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Display the image at this address." },
2965 { LLDB_OPT_SET_1, false, "arch", 'A', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the architecture when listing images." },
2966 { LLDB_OPT_SET_1, false, "triple", 't', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the triple when listing images." },
2967 { 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." },
2968 { 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)." },
2969 { LLDB_OPT_SET_1, false, "uuid", 'u', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display the UUID when listing images." },
2970 { LLDB_OPT_SET_1, false, "fullpath", 'f', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the fullpath to the image object file." },
2971 { LLDB_OPT_SET_1, false, "directory", 'd', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the directory with optional width for the image object file." },
2972 { LLDB_OPT_SET_1, false, "basename", 'b', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the basename with optional width for the image object file." },
2973 { LLDB_OPT_SET_1, false, "symfile", 's', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width." },
2974 { 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." },
2975 { LLDB_OPT_SET_1, false, "mod-time", 'm', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the modification time with optional width of the module." },
2976 { 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." },
2977 { LLDB_OPT_SET_1, false, "pointer", 'p', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeNone, "Display the module pointer." },
2978 { 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." }
2982 class CommandObjectTargetModulesList : public CommandObjectParsed {
2984 class CommandOptions : public Options {
2987 : Options(), m_format_array(), m_use_global_module_list(false),
2988 m_module_addr(LLDB_INVALID_ADDRESS) {}
2990 ~CommandOptions() override = default;
2992 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2993 ExecutionContext *execution_context) override {
2996 const int short_option = m_getopt_table[option_idx].val;
2997 if (short_option == 'g') {
2998 m_use_global_module_list = true;
2999 } else if (short_option == 'a') {
3000 m_module_addr = OptionArgParser::ToAddress(
3001 execution_context, option_arg, LLDB_INVALID_ADDRESS, &error);
3003 unsigned long width = 0;
3004 option_arg.getAsInteger(0, width);
3005 m_format_array.push_back(std::make_pair(short_option, width));
3010 void OptionParsingStarting(ExecutionContext *execution_context) override {
3011 m_format_array.clear();
3012 m_use_global_module_list = false;
3013 m_module_addr = LLDB_INVALID_ADDRESS;
3016 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3017 return llvm::makeArrayRef(g_target_modules_list_options);
3020 // Instance variables to hold the values for command options.
3021 typedef std::vector<std::pair<char, uint32_t>> FormatWidthCollection;
3022 FormatWidthCollection m_format_array;
3023 bool m_use_global_module_list;
3024 lldb::addr_t m_module_addr;
3027 CommandObjectTargetModulesList(CommandInterpreter &interpreter)
3028 : CommandObjectParsed(
3029 interpreter, "target modules list",
3030 "List current executable and dependent shared library images.",
3031 "target modules list [<cmd-options>]"),
3034 ~CommandObjectTargetModulesList() override = default;
3036 Options *GetOptions() override { return &m_options; }
3039 bool DoExecute(Args &command, CommandReturnObject &result) override {
3040 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3041 const bool use_global_module_list = m_options.m_use_global_module_list;
3042 // Define a local module list here to ensure it lives longer than any
3043 // "locker" object which might lock its contents below (through the
3044 // "module_list_ptr" variable).
3045 ModuleList module_list;
3046 if (target == nullptr && !use_global_module_list) {
3047 result.AppendError("invalid target, create a debug target using the "
3048 "'target create' command");
3049 result.SetStatus(eReturnStatusFailed);
3053 uint32_t addr_byte_size =
3054 target->GetArchitecture().GetAddressByteSize();
3055 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3056 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3058 // Dump all sections for all modules images
3059 Stream &strm = result.GetOutputStream();
3061 if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) {
3063 Address module_address;
3064 if (module_address.SetLoadAddress(m_options.m_module_addr, target)) {
3065 ModuleSP module_sp(module_address.GetModule());
3067 PrintModule(target, module_sp.get(), 0, strm);
3068 result.SetStatus(eReturnStatusSuccessFinishResult);
3070 result.AppendErrorWithFormat(
3071 "Couldn't find module matching address: 0x%" PRIx64 ".",
3072 m_options.m_module_addr);
3073 result.SetStatus(eReturnStatusFailed);
3076 result.AppendErrorWithFormat(
3077 "Couldn't find module containing address: 0x%" PRIx64 ".",
3078 m_options.m_module_addr);
3079 result.SetStatus(eReturnStatusFailed);
3083 "Can only look up modules by address with a valid target.");
3084 result.SetStatus(eReturnStatusFailed);
3086 return result.Succeeded();
3089 size_t num_modules = 0;
3091 // This locker will be locked on the mutex in module_list_ptr if it is
3092 // non-nullptr. Otherwise it will lock the
3093 // AllocationModuleCollectionMutex when accessing the global module list
3095 std::unique_lock<std::recursive_mutex> guard(
3096 Module::GetAllocationModuleCollectionMutex(), std::defer_lock);
3098 const ModuleList *module_list_ptr = nullptr;
3099 const size_t argc = command.GetArgumentCount();
3101 if (use_global_module_list) {
3103 num_modules = Module::GetNumberAllocatedModules();
3105 module_list_ptr = &target->GetImages();
3108 // TODO: Convert to entry based iteration. Requires converting
3109 // FindModulesByName.
3110 for (size_t i = 0; i < argc; ++i) {
3111 // Dump specified images (by basename or fullpath)
3112 const char *arg_cstr = command.GetArgumentAtIndex(i);
3113 const size_t num_matches = FindModulesByName(
3114 target, arg_cstr, module_list, use_global_module_list);
3115 if (num_matches == 0) {
3117 result.AppendErrorWithFormat("no modules found that match '%s'",
3119 result.SetStatus(eReturnStatusFailed);
3125 module_list_ptr = &module_list;
3128 std::unique_lock<std::recursive_mutex> lock;
3129 if (module_list_ptr != nullptr) {
3131 std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex());
3133 num_modules = module_list_ptr->GetSize();
3136 if (num_modules > 0) {
3137 for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
3140 if (module_list_ptr) {
3141 module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
3142 module = module_sp.get();
3144 module = Module::GetAllocatedModuleAtIndex(image_idx);
3145 module_sp = module->shared_from_this();
3148 const size_t indent = strm.Printf("[%3u] ", image_idx);
3149 PrintModule(target, module, indent, strm);
3151 result.SetStatus(eReturnStatusSuccessFinishResult);
3154 if (use_global_module_list)
3156 "the global module list has no matching modules");
3158 result.AppendError("the target has no matching modules");
3160 if (use_global_module_list)
3161 result.AppendError("the global module list is empty");
3164 "the target has no associated executable images");
3166 result.SetStatus(eReturnStatusFailed);
3170 return result.Succeeded();
3173 void PrintModule(Target *target, Module *module, int indent, Stream &strm) {
3174 if (module == nullptr) {
3175 strm.PutCString("Null module");
3179 bool dump_object_name = false;
3180 if (m_options.m_format_array.empty()) {
3181 m_options.m_format_array.push_back(std::make_pair('u', 0));
3182 m_options.m_format_array.push_back(std::make_pair('h', 0));
3183 m_options.m_format_array.push_back(std::make_pair('f', 0));
3184 m_options.m_format_array.push_back(std::make_pair('S', 0));
3186 const size_t num_entries = m_options.m_format_array.size();
3187 bool print_space = false;
3188 for (size_t i = 0; i < num_entries; ++i) {
3192 const char format_char = m_options.m_format_array[i].first;
3193 uint32_t width = m_options.m_format_array[i].second;
3194 switch (format_char) {
3196 DumpModuleArchitecture(strm, module, false, width);
3200 DumpModuleArchitecture(strm, module, true, width);
3204 DumpFullpath(strm, &module->GetFileSpec(), width);
3205 dump_object_name = true;
3209 DumpDirectory(strm, &module->GetFileSpec(), width);
3213 DumpBasename(strm, &module->GetFileSpec(), width);
3214 dump_object_name = true;
3219 // Image header address
3221 uint32_t addr_nibble_width =
3222 target ? (target->GetArchitecture().GetAddressByteSize() * 2)
3225 ObjectFile *objfile = module->GetObjectFile();
3227 Address base_addr(objfile->GetBaseAddress());
3228 if (base_addr.IsValid()) {
3229 if (target && !target->GetSectionLoadList().IsEmpty()) {
3230 lldb::addr_t load_addr =
3231 base_addr.GetLoadAddress(target);
3232 if (load_addr == LLDB_INVALID_ADDRESS) {
3233 base_addr.Dump(&strm, target,
3234 Address::DumpStyleModuleWithFileAddress,
3235 Address::DumpStyleFileAddress);
3237 if (format_char == 'o') {
3238 // Show the offset of slide for the image
3240 "0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width,
3241 load_addr - base_addr.GetFileAddress());
3243 // Show the load address of the image
3244 strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3245 addr_nibble_width, load_addr);
3250 // The address was valid, but the image isn't loaded, output the
3251 // address in an appropriate format
3252 base_addr.Dump(&strm, target, Address::DumpStyleFileAddress);
3256 strm.Printf("%*s", addr_nibble_width + 2, "");
3261 size_t ref_count = 0;
3262 ModuleSP module_sp(module->shared_from_this());
3264 // Take one away to make sure we don't count our local "module_sp"
3265 ref_count = module_sp.use_count() - 1;
3268 strm.Printf("{%*" PRIu64 "}", width, (uint64_t)ref_count);
3270 strm.Printf("{%" PRIu64 "}", (uint64_t)ref_count);
3275 const SymbolVendor *symbol_vendor = module->GetSymbolVendor();
3276 if (symbol_vendor) {
3277 const FileSpec symfile_spec = symbol_vendor->GetMainFileSpec();
3278 if (format_char == 'S') {
3279 // Dump symbol file only if different from module file
3280 if (!symfile_spec || symfile_spec == module->GetFileSpec()) {
3281 print_space = false;
3284 // Add a newline and indent past the index
3285 strm.Printf("\n%*s", indent, "");
3287 DumpFullpath(strm, &symfile_spec, width);
3288 dump_object_name = true;
3291 strm.Printf("%.*s", width, "<NONE>");
3295 strm.Format("{0:%c}", llvm::fmt_align(module->GetModificationTime(),
3296 llvm::AlignStyle::Left, width));
3300 strm.Printf("%p", static_cast<void *>(module));
3304 DumpModuleUUID(strm, module);
3311 if (dump_object_name) {
3312 const char *object_name = module->GetObjectName().GetCString();
3314 strm.Printf("(%s)", object_name);
3319 CommandOptions m_options;
3322 #pragma mark CommandObjectTargetModulesShowUnwind
3324 //----------------------------------------------------------------------
3325 // Lookup unwind information in images
3326 //----------------------------------------------------------------------
3328 static constexpr OptionDefinition g_target_modules_show_unwind_options[] = {
3330 { LLDB_OPT_SET_1, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFunctionName, "Show unwind instructions for a function or symbol name." },
3331 { LLDB_OPT_SET_2, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address" }
3335 class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {
3338 eLookupTypeInvalid = -1,
3339 eLookupTypeAddress = 0,
3341 eLookupTypeFunction,
3342 eLookupTypeFunctionOrSymbol,
3346 class CommandOptions : public Options {
3349 : Options(), m_type(eLookupTypeInvalid), m_str(),
3350 m_addr(LLDB_INVALID_ADDRESS) {}
3352 ~CommandOptions() override = default;
3354 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3355 ExecutionContext *execution_context) override {
3358 const int short_option = m_getopt_table[option_idx].val;
3360 switch (short_option) {
3363 m_type = eLookupTypeAddress;
3364 m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
3365 LLDB_INVALID_ADDRESS, &error);
3366 if (m_addr == LLDB_INVALID_ADDRESS)
3367 error.SetErrorStringWithFormat("invalid address string '%s'",
3368 option_arg.str().c_str());
3374 m_type = eLookupTypeFunctionOrSymbol;
3378 error.SetErrorStringWithFormat("unrecognized option %c.", short_option);
3385 void OptionParsingStarting(ExecutionContext *execution_context) override {
3386 m_type = eLookupTypeInvalid;
3388 m_addr = LLDB_INVALID_ADDRESS;
3391 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3392 return llvm::makeArrayRef(g_target_modules_show_unwind_options);
3395 // Instance variables to hold the values for command options.
3397 int m_type; // Should be a eLookupTypeXXX enum after parsing options
3398 std::string m_str; // Holds name lookup
3399 lldb::addr_t m_addr; // Holds the address to lookup
3402 CommandObjectTargetModulesShowUnwind(CommandInterpreter &interpreter)
3403 : CommandObjectParsed(
3404 interpreter, "target modules show-unwind",
3405 "Show synthesized unwind instructions for a function.", nullptr,
3406 eCommandRequiresTarget | eCommandRequiresProcess |
3407 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
3410 ~CommandObjectTargetModulesShowUnwind() override = default;
3412 Options *GetOptions() override { return &m_options; }
3415 bool DoExecute(Args &command, CommandReturnObject &result) override {
3416 Target *target = m_exe_ctx.GetTargetPtr();
3417 Process *process = m_exe_ctx.GetProcessPtr();
3420 abi = process->GetABI().get();
3422 if (process == nullptr) {
3424 "You must have a process running to use this command.");
3425 result.SetStatus(eReturnStatusFailed);
3429 ThreadList threads(process->GetThreadList());
3430 if (threads.GetSize() == 0) {
3431 result.AppendError("The process must be paused to use this command.");
3432 result.SetStatus(eReturnStatusFailed);
3436 ThreadSP thread(threads.GetThreadAtIndex(0));
3438 result.AppendError("The process must be paused to use this command.");
3439 result.SetStatus(eReturnStatusFailed);
3443 SymbolContextList sc_list;
3445 if (m_options.m_type == eLookupTypeFunctionOrSymbol) {
3446 ConstString function_name(m_options.m_str.c_str());
3447 target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto,
3448 true, false, true, sc_list);
3449 } else if (m_options.m_type == eLookupTypeAddress && target) {
3451 if (target->GetSectionLoadList().ResolveLoadAddress(m_options.m_addr,
3454 ModuleSP module_sp(addr.GetModule());
3455 module_sp->ResolveSymbolContextForAddress(addr,
3456 eSymbolContextEverything, sc);
3457 if (sc.function || sc.symbol) {
3463 "address-expression or function name option must be specified.");
3464 result.SetStatus(eReturnStatusFailed);
3468 size_t num_matches = sc_list.GetSize();
3469 if (num_matches == 0) {
3470 result.AppendErrorWithFormat("no unwind data found that matches '%s'.",
3471 m_options.m_str.c_str());
3472 result.SetStatus(eReturnStatusFailed);
3476 for (uint32_t idx = 0; idx < num_matches; idx++) {
3478 sc_list.GetContextAtIndex(idx, sc);
3479 if (sc.symbol == nullptr && sc.function == nullptr)
3481 if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr)
3484 if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,
3487 if (!range.GetBaseAddress().IsValid())
3489 ConstString funcname(sc.GetFunctionName());
3490 if (funcname.IsEmpty())
3492 addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
3494 start_addr = abi->FixCodeAddress(start_addr);
3496 FuncUnwindersSP func_unwinders_sp(
3497 sc.module_sp->GetObjectFile()
3499 .GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
3500 if (!func_unwinders_sp)
3503 result.GetOutputStream().Printf(
3504 "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n\n",
3505 sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(),
3506 funcname.AsCString(), start_addr);
3508 UnwindPlanSP non_callsite_unwind_plan =
3509 func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread, -1);
3510 if (non_callsite_unwind_plan) {
3511 result.GetOutputStream().Printf(
3512 "Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n",
3513 non_callsite_unwind_plan->GetSourceName().AsCString());
3515 UnwindPlanSP callsite_unwind_plan =
3516 func_unwinders_sp->GetUnwindPlanAtCallSite(*target, -1);
3517 if (callsite_unwind_plan) {
3518 result.GetOutputStream().Printf(
3519 "Synchronous (restricted to call-sites) UnwindPlan is '%s'\n",
3520 callsite_unwind_plan->GetSourceName().AsCString());
3522 UnwindPlanSP fast_unwind_plan =
3523 func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread);
3524 if (fast_unwind_plan) {
3525 result.GetOutputStream().Printf(
3526 "Fast UnwindPlan is '%s'\n",
3527 fast_unwind_plan->GetSourceName().AsCString());
3530 result.GetOutputStream().Printf("\n");
3532 UnwindPlanSP assembly_sp =
3533 func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread, 0);
3535 result.GetOutputStream().Printf(
3536 "Assembly language inspection UnwindPlan:\n");
3537 assembly_sp->Dump(result.GetOutputStream(), thread.get(),
3538 LLDB_INVALID_ADDRESS);
3539 result.GetOutputStream().Printf("\n");
3542 UnwindPlanSP ehframe_sp =
3543 func_unwinders_sp->GetEHFrameUnwindPlan(*target, 0);
3545 result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
3546 ehframe_sp->Dump(result.GetOutputStream(), thread.get(),
3547 LLDB_INVALID_ADDRESS);
3548 result.GetOutputStream().Printf("\n");
3551 UnwindPlanSP ehframe_augmented_sp =
3552 func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread, 0);
3553 if (ehframe_augmented_sp) {
3554 result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
3555 ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
3556 LLDB_INVALID_ADDRESS);
3557 result.GetOutputStream().Printf("\n");
3560 if (UnwindPlanSP plan_sp =
3561 func_unwinders_sp->GetDebugFrameUnwindPlan(*target, 0)) {
3562 result.GetOutputStream().Printf("debug_frame UnwindPlan:\n");
3563 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3564 LLDB_INVALID_ADDRESS);
3565 result.GetOutputStream().Printf("\n");
3568 if (UnwindPlanSP plan_sp =
3569 func_unwinders_sp->GetDebugFrameAugmentedUnwindPlan(*target,
3571 result.GetOutputStream().Printf("debug_frame augmented UnwindPlan:\n");
3572 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3573 LLDB_INVALID_ADDRESS);
3574 result.GetOutputStream().Printf("\n");
3577 UnwindPlanSP arm_unwind_sp =
3578 func_unwinders_sp->GetArmUnwindUnwindPlan(*target, 0);
3579 if (arm_unwind_sp) {
3580 result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
3581 arm_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3582 LLDB_INVALID_ADDRESS);
3583 result.GetOutputStream().Printf("\n");
3586 UnwindPlanSP compact_unwind_sp =
3587 func_unwinders_sp->GetCompactUnwindUnwindPlan(*target, 0);
3588 if (compact_unwind_sp) {
3589 result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
3590 compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3591 LLDB_INVALID_ADDRESS);
3592 result.GetOutputStream().Printf("\n");
3595 if (fast_unwind_plan) {
3596 result.GetOutputStream().Printf("Fast UnwindPlan:\n");
3597 fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(),
3598 LLDB_INVALID_ADDRESS);
3599 result.GetOutputStream().Printf("\n");
3602 ABISP abi_sp = process->GetABI();
3604 UnwindPlan arch_default(lldb::eRegisterKindGeneric);
3605 if (abi_sp->CreateDefaultUnwindPlan(arch_default)) {
3606 result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
3607 arch_default.Dump(result.GetOutputStream(), thread.get(),
3608 LLDB_INVALID_ADDRESS);
3609 result.GetOutputStream().Printf("\n");
3612 UnwindPlan arch_entry(lldb::eRegisterKindGeneric);
3613 if (abi_sp->CreateFunctionEntryUnwindPlan(arch_entry)) {
3614 result.GetOutputStream().Printf(
3615 "Arch default at entry point UnwindPlan:\n");
3616 arch_entry.Dump(result.GetOutputStream(), thread.get(),
3617 LLDB_INVALID_ADDRESS);
3618 result.GetOutputStream().Printf("\n");
3622 result.GetOutputStream().Printf("\n");
3624 return result.Succeeded();
3627 CommandOptions m_options;
3630 //----------------------------------------------------------------------
3631 // Lookup information in images
3632 //----------------------------------------------------------------------
3634 static constexpr OptionDefinition g_target_modules_lookup_options[] = {
3636 { LLDB_OPT_SET_1, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules." },
3637 { 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." },
3638 /* FIXME: re-enable regex for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */
3639 { 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." },
3640 { 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." },
3641 { 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." },
3642 { 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)." },
3643 { 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)." },
3644 { 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." },
3645 { 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." },
3646 { 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." },
3647 { LLDB_OPT_SET_ALL, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Enable verbose lookup information." },
3648 { 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." },
3652 class CommandObjectTargetModulesLookup : public CommandObjectParsed {
3655 eLookupTypeInvalid = -1,
3656 eLookupTypeAddress = 0,
3658 eLookupTypeFileLine, // Line is optional
3659 eLookupTypeFunction,
3660 eLookupTypeFunctionOrSymbol,
3665 class CommandOptions : public Options {
3667 CommandOptions() : Options() { OptionParsingStarting(nullptr); }
3669 ~CommandOptions() override = default;
3671 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3672 ExecutionContext *execution_context) override {
3675 const int short_option = m_getopt_table[option_idx].val;
3677 switch (short_option) {
3679 m_type = eLookupTypeAddress;
3680 m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
3681 LLDB_INVALID_ADDRESS, &error);
3685 if (option_arg.getAsInteger(0, m_offset))
3686 error.SetErrorStringWithFormat("invalid offset string '%s'",
3687 option_arg.str().c_str());
3692 m_type = eLookupTypeSymbol;
3696 m_file.SetFile(option_arg, FileSpec::Style::native);
3697 m_type = eLookupTypeFileLine;
3701 m_include_inlines = false;
3705 if (option_arg.getAsInteger(0, m_line_number))
3706 error.SetErrorStringWithFormat("invalid line number string '%s'",
3707 option_arg.str().c_str());
3708 else if (m_line_number == 0)
3709 error.SetErrorString("zero is an invalid line number");
3710 m_type = eLookupTypeFileLine;
3715 m_type = eLookupTypeFunction;
3720 m_type = eLookupTypeFunctionOrSymbol;
3725 m_type = eLookupTypeType;
3744 void OptionParsingStarting(ExecutionContext *execution_context) override {
3745 m_type = eLookupTypeInvalid;
3748 m_addr = LLDB_INVALID_ADDRESS;
3751 m_use_regex = false;
3752 m_include_inlines = true;
3754 m_print_all = false;
3757 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3758 return llvm::makeArrayRef(g_target_modules_lookup_options);
3761 int m_type; // Should be a eLookupTypeXXX enum after parsing options
3762 std::string m_str; // Holds name lookup
3763 FileSpec m_file; // Files for file lookups
3764 lldb::addr_t m_addr; // Holds the address to lookup
3766 m_offset; // Subtract this offset from m_addr before doing lookups.
3767 uint32_t m_line_number; // Line number for file+line lookups
3768 bool m_use_regex; // Name lookups in m_str are regular expressions.
3769 bool m_include_inlines; // Check for inline entries when looking up by
3771 bool m_verbose; // Enable verbose lookup info
3772 bool m_print_all; // Print all matches, even in cases where there's a best
3776 CommandObjectTargetModulesLookup(CommandInterpreter &interpreter)
3777 : CommandObjectParsed(interpreter, "target modules lookup",
3778 "Look up information within executable and "
3779 "dependent shared library images.",
3780 nullptr, eCommandRequiresTarget),
3782 CommandArgumentEntry arg;
3783 CommandArgumentData file_arg;
3785 // Define the first (and only) variant of this arg.
3786 file_arg.arg_type = eArgTypeFilename;
3787 file_arg.arg_repetition = eArgRepeatStar;
3789 // There is only one variant this argument could be; put it into the
3791 arg.push_back(file_arg);
3793 // Push the data for the first argument into the m_arguments vector.
3794 m_arguments.push_back(arg);
3797 ~CommandObjectTargetModulesLookup() override = default;
3799 Options *GetOptions() override { return &m_options; }
3801 bool LookupHere(CommandInterpreter &interpreter, CommandReturnObject &result,
3802 bool &syntax_error) {
3803 switch (m_options.m_type) {
3804 case eLookupTypeAddress:
3805 case eLookupTypeFileLine:
3806 case eLookupTypeFunction:
3807 case eLookupTypeFunctionOrSymbol:
3808 case eLookupTypeSymbol:
3811 case eLookupTypeType:
3815 StackFrameSP frame = m_exe_ctx.GetFrameSP();
3820 const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
3822 if (!sym_ctx.module_sp)
3825 switch (m_options.m_type) {
3828 case eLookupTypeType:
3829 if (!m_options.m_str.empty()) {
3830 if (LookupTypeHere(m_interpreter, result.GetOutputStream(),
3831 *sym_ctx.module_sp, m_options.m_str.c_str(),
3832 m_options.m_use_regex)) {
3833 result.SetStatus(eReturnStatusSuccessFinishResult);
3843 bool LookupInModule(CommandInterpreter &interpreter, Module *module,
3844 CommandReturnObject &result, bool &syntax_error) {
3845 switch (m_options.m_type) {
3846 case eLookupTypeAddress:
3847 if (m_options.m_addr != LLDB_INVALID_ADDRESS) {
3848 if (LookupAddressInModule(
3849 m_interpreter, result.GetOutputStream(), module,
3850 eSymbolContextEverything |
3851 (m_options.m_verbose
3852 ? static_cast<int>(eSymbolContextVariable)
3854 m_options.m_addr, m_options.m_offset, m_options.m_verbose)) {
3855 result.SetStatus(eReturnStatusSuccessFinishResult);
3861 case eLookupTypeSymbol:
3862 if (!m_options.m_str.empty()) {
3863 if (LookupSymbolInModule(m_interpreter, result.GetOutputStream(),
3864 module, m_options.m_str.c_str(),
3865 m_options.m_use_regex, m_options.m_verbose)) {
3866 result.SetStatus(eReturnStatusSuccessFinishResult);
3872 case eLookupTypeFileLine:
3873 if (m_options.m_file) {
3874 if (LookupFileAndLineInModule(
3875 m_interpreter, result.GetOutputStream(), module,
3876 m_options.m_file, m_options.m_line_number,
3877 m_options.m_include_inlines, m_options.m_verbose)) {
3878 result.SetStatus(eReturnStatusSuccessFinishResult);
3884 case eLookupTypeFunctionOrSymbol:
3885 case eLookupTypeFunction:
3886 if (!m_options.m_str.empty()) {
3887 if (LookupFunctionInModule(
3888 m_interpreter, result.GetOutputStream(), module,
3889 m_options.m_str.c_str(), m_options.m_use_regex,
3890 m_options.m_include_inlines,
3892 eLookupTypeFunctionOrSymbol, // include symbols
3893 m_options.m_verbose)) {
3894 result.SetStatus(eReturnStatusSuccessFinishResult);
3900 case eLookupTypeType:
3901 if (!m_options.m_str.empty()) {
3902 if (LookupTypeInModule(m_interpreter, result.GetOutputStream(), module,
3903 m_options.m_str.c_str(),
3904 m_options.m_use_regex)) {
3905 result.SetStatus(eReturnStatusSuccessFinishResult);
3912 m_options.GenerateOptionUsage(
3913 result.GetErrorStream(), this,
3914 GetCommandInterpreter().GetDebugger().GetTerminalWidth());
3915 syntax_error = true;
3919 result.SetStatus(eReturnStatusFailed);
3924 bool DoExecute(Args &command, CommandReturnObject &result) override {
3925 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3926 if (target == nullptr) {
3927 result.AppendError("invalid target, create a debug target using the "
3928 "'target create' command");
3929 result.SetStatus(eReturnStatusFailed);
3932 bool syntax_error = false;
3934 uint32_t num_successful_lookups = 0;
3935 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
3936 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3937 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3938 // Dump all sections for all modules images
3940 if (command.GetArgumentCount() == 0) {
3941 ModuleSP current_module;
3943 // Where it is possible to look in the current symbol context first,
3944 // try that. If this search was successful and --all was not passed,
3945 // don't print anything else.
3946 if (LookupHere(m_interpreter, result, syntax_error)) {
3947 result.GetOutputStream().EOL();
3948 num_successful_lookups++;
3949 if (!m_options.m_print_all) {
3950 result.SetStatus(eReturnStatusSuccessFinishResult);
3951 return result.Succeeded();
3955 // Dump all sections for all other modules
3957 const ModuleList &target_modules = target->GetImages();
3958 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
3959 const size_t num_modules = target_modules.GetSize();
3960 if (num_modules > 0) {
3961 for (i = 0; i < num_modules && !syntax_error; ++i) {
3962 Module *module_pointer =
3963 target_modules.GetModulePointerAtIndexUnlocked(i);
3965 if (module_pointer != current_module.get() &&
3968 target_modules.GetModulePointerAtIndexUnlocked(i), result,
3970 result.GetOutputStream().EOL();
3971 num_successful_lookups++;
3975 result.AppendError("the target has no associated executable images");
3976 result.SetStatus(eReturnStatusFailed);
3980 // Dump specified images (by basename or fullpath)
3981 const char *arg_cstr;
3982 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr &&
3985 ModuleList module_list;
3986 const size_t num_matches =
3987 FindModulesByName(target, arg_cstr, module_list, false);
3988 if (num_matches > 0) {
3989 for (size_t j = 0; j < num_matches; ++j) {
3990 Module *module = module_list.GetModulePointerAtIndex(j);
3992 if (LookupInModule(m_interpreter, module, result,
3994 result.GetOutputStream().EOL();
3995 num_successful_lookups++;
4000 result.AppendWarningWithFormat(
4001 "Unable to find an image that matches '%s'.\n", arg_cstr);
4005 if (num_successful_lookups > 0)
4006 result.SetStatus(eReturnStatusSuccessFinishResult);
4008 result.SetStatus(eReturnStatusFailed);
4010 return result.Succeeded();
4013 CommandOptions m_options;
4016 #pragma mark CommandObjectMultiwordImageSearchPaths
4018 //-------------------------------------------------------------------------
4019 // CommandObjectMultiwordImageSearchPaths
4020 //-------------------------------------------------------------------------
4022 class CommandObjectTargetModulesImageSearchPaths
4023 : public CommandObjectMultiword {
4025 CommandObjectTargetModulesImageSearchPaths(CommandInterpreter &interpreter)
4026 : CommandObjectMultiword(
4027 interpreter, "target modules search-paths",
4028 "Commands for managing module search paths for a target.",
4029 "target modules search-paths <subcommand> [<subcommand-options>]") {
4031 "add", CommandObjectSP(
4032 new CommandObjectTargetModulesSearchPathsAdd(interpreter)));
4034 "clear", CommandObjectSP(new CommandObjectTargetModulesSearchPathsClear(
4039 new CommandObjectTargetModulesSearchPathsInsert(interpreter)));
4041 "list", CommandObjectSP(new CommandObjectTargetModulesSearchPathsList(
4044 "query", CommandObjectSP(new CommandObjectTargetModulesSearchPathsQuery(
4048 ~CommandObjectTargetModulesImageSearchPaths() override = default;
4051 #pragma mark CommandObjectTargetModules
4053 //-------------------------------------------------------------------------
4054 // CommandObjectTargetModules
4055 //-------------------------------------------------------------------------
4057 class CommandObjectTargetModules : public CommandObjectMultiword {
4059 //------------------------------------------------------------------
4060 // Constructors and Destructors
4061 //------------------------------------------------------------------
4062 CommandObjectTargetModules(CommandInterpreter &interpreter)
4063 : CommandObjectMultiword(interpreter, "target modules",
4064 "Commands for accessing information for one or "
4065 "more target modules.",
4066 "target modules <sub-command> ...") {
4068 "add", CommandObjectSP(new CommandObjectTargetModulesAdd(interpreter)));
4069 LoadSubCommand("load", CommandObjectSP(new CommandObjectTargetModulesLoad(
4071 LoadSubCommand("dump", CommandObjectSP(new CommandObjectTargetModulesDump(
4073 LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetModulesList(
4077 CommandObjectSP(new CommandObjectTargetModulesLookup(interpreter)));
4081 new CommandObjectTargetModulesImageSearchPaths(interpreter)));
4084 CommandObjectSP(new CommandObjectTargetModulesShowUnwind(interpreter)));
4087 ~CommandObjectTargetModules() override = default;
4090 //------------------------------------------------------------------
4091 // For CommandObjectTargetModules only
4092 //------------------------------------------------------------------
4093 DISALLOW_COPY_AND_ASSIGN(CommandObjectTargetModules);
4096 class CommandObjectTargetSymbolsAdd : public CommandObjectParsed {
4098 CommandObjectTargetSymbolsAdd(CommandInterpreter &interpreter)
4099 : CommandObjectParsed(
4100 interpreter, "target symbols add",
4101 "Add a debug symbol file to one of the target's current modules by "
4102 "specifying a path to a debug symbols file, or using the options "
4103 "to specify a module to download symbols for.",
4104 "target symbols add <cmd-options> [<symfile>]",
4105 eCommandRequiresTarget),
4108 LLDB_OPT_SET_1, false, "shlib", 's',
4109 CommandCompletions::eModuleCompletion, eArgTypeShlibName,
4110 "Fullpath or basename for module to find debug symbols for."),
4111 m_current_frame_option(
4112 LLDB_OPT_SET_2, false, "frame", 'F',
4113 "Locate the debug symbols the currently selected frame.", false,
4117 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
4119 m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
4120 m_option_group.Append(&m_current_frame_option, LLDB_OPT_SET_2,
4122 m_option_group.Finalize();
4125 ~CommandObjectTargetSymbolsAdd() override = default;
4127 int HandleArgumentCompletion(
4128 CompletionRequest &request,
4129 OptionElementVector &opt_element_vector) override {
4130 CommandCompletions::InvokeCommonCompletionCallbacks(
4131 GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
4133 return request.GetNumberOfMatches();
4136 Options *GetOptions() override { return &m_option_group; }
4139 bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush,
4140 CommandReturnObject &result) {
4141 const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
4143 char symfile_path[PATH_MAX];
4144 symbol_fspec.GetPath(symfile_path, sizeof(symfile_path));
4146 if (!module_spec.GetUUID().IsValid()) {
4147 if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
4148 module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename();
4150 // We now have a module that represents a symbol file that can be used
4151 // for a module that might exist in the current target, so we need to
4152 // find that module in the target
4153 ModuleList matching_module_list;
4155 size_t num_matches = 0;
4156 // First extract all module specs from the symbol file
4157 lldb_private::ModuleSpecList symfile_module_specs;
4158 if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(),
4159 0, 0, symfile_module_specs)) {
4160 // Now extract the module spec that matches the target architecture
4161 ModuleSpec target_arch_module_spec;
4162 ModuleSpec symfile_module_spec;
4163 target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
4164 if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec,
4165 symfile_module_spec)) {
4166 // See if it has a UUID?
4167 if (symfile_module_spec.GetUUID().IsValid()) {
4168 // It has a UUID, look for this UUID in the target modules
4169 ModuleSpec symfile_uuid_module_spec;
4170 symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
4171 num_matches = target->GetImages().FindModules(
4172 symfile_uuid_module_spec, matching_module_list);
4176 if (num_matches == 0) {
4177 // No matches yet, iterate through the module specs to find a UUID
4178 // value that we can match up to an image in our target
4179 const size_t num_symfile_module_specs =
4180 symfile_module_specs.GetSize();
4181 for (size_t i = 0; i < num_symfile_module_specs && num_matches == 0;
4183 if (symfile_module_specs.GetModuleSpecAtIndex(
4184 i, symfile_module_spec)) {
4185 if (symfile_module_spec.GetUUID().IsValid()) {
4186 // It has a UUID, look for this UUID in the target modules
4187 ModuleSpec symfile_uuid_module_spec;
4188 symfile_uuid_module_spec.GetUUID() =
4189 symfile_module_spec.GetUUID();
4190 num_matches = target->GetImages().FindModules(
4191 symfile_uuid_module_spec, matching_module_list);
4198 // Just try to match up the file by basename if we have no matches at
4200 if (num_matches == 0)
4202 target->GetImages().FindModules(module_spec, matching_module_list);
4204 while (num_matches == 0) {
4205 ConstString filename_no_extension(
4206 module_spec.GetFileSpec().GetFileNameStrippingExtension());
4207 // Empty string returned, lets bail
4208 if (!filename_no_extension)
4211 // Check if there was no extension to strip and the basename is the
4213 if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
4216 // Replace basename with one less extension
4217 module_spec.GetFileSpec().GetFilename() = filename_no_extension;
4220 target->GetImages().FindModules(module_spec, matching_module_list);
4223 if (num_matches > 1) {
4224 result.AppendErrorWithFormat("multiple modules match symbol file '%s', "
4225 "use the --uuid option to resolve the "
4228 } else if (num_matches == 1) {
4229 ModuleSP module_sp(matching_module_list.GetModuleAtIndex(0));
4231 // The module has not yet created its symbol vendor, we can just give
4232 // the existing target module the symfile path to use for when it
4233 // decides to create it!
4234 module_sp->SetSymbolFileFileSpec(symbol_fspec);
4236 SymbolVendor *symbol_vendor =
4237 module_sp->GetSymbolVendor(true, &result.GetErrorStream());
4238 if (symbol_vendor) {
4239 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
4242 ObjectFile *object_file = symbol_file->GetObjectFile();
4244 if (object_file && object_file->GetFileSpec() == symbol_fspec) {
4245 // Provide feedback that the symfile has been successfully added.
4246 const FileSpec &module_fs = module_sp->GetFileSpec();
4247 result.AppendMessageWithFormat(
4248 "symbol file '%s' has been added to '%s'\n", symfile_path,
4249 module_fs.GetPath().c_str());
4251 // Let clients know something changed in the module if it is
4253 ModuleList module_list;
4254 module_list.Append(module_sp);
4255 target->SymbolsDidLoad(module_list);
4257 // Make sure we load any scripting resources that may be embedded
4258 // in the debug info files in case the platform supports that.
4260 StreamString feedback_stream;
4261 module_sp->LoadScriptingResourceInTarget(target, error,
4263 if (error.Fail() && error.AsCString())
4264 result.AppendWarningWithFormat(
4265 "unable to load scripting data for module %s - error "
4267 module_sp->GetFileSpec()
4268 .GetFileNameStrippingExtension()
4271 else if (feedback_stream.GetSize())
4272 result.AppendWarningWithFormat("%s", feedback_stream.GetData());
4275 result.SetStatus(eReturnStatusSuccessFinishResult);
4280 // Clear the symbol file spec if anything went wrong
4281 module_sp->SetSymbolFileFileSpec(FileSpec());
4284 namespace fs = llvm::sys::fs;
4285 if (module_spec.GetUUID().IsValid()) {
4286 StreamString ss_symfile_uuid;
4287 module_spec.GetUUID().Dump(&ss_symfile_uuid);
4288 result.AppendErrorWithFormat(
4289 "symbol file '%s' (%s) does not match any existing module%s\n",
4290 symfile_path, ss_symfile_uuid.GetData(),
4291 !fs::is_regular_file(symbol_fspec.GetPath())
4292 ? "\n please specify the full path to the symbol file"
4295 result.AppendErrorWithFormat(
4296 "symbol file '%s' does not match any existing module%s\n",
4298 !fs::is_regular_file(symbol_fspec.GetPath())
4299 ? "\n please specify the full path to the symbol file"
4304 "one or more executable image paths must be specified");
4306 result.SetStatus(eReturnStatusFailed);
4310 bool DoExecute(Args &args, CommandReturnObject &result) override {
4311 Target *target = m_exe_ctx.GetTargetPtr();
4312 result.SetStatus(eReturnStatusFailed);
4314 ModuleSpec module_spec;
4315 const bool uuid_option_set =
4316 m_uuid_option_group.GetOptionValue().OptionWasSet();
4317 const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
4318 const bool frame_option_set =
4319 m_current_frame_option.GetOptionValue().OptionWasSet();
4320 const size_t argc = args.GetArgumentCount();
4323 if (uuid_option_set || file_option_set || frame_option_set) {
4324 bool success = false;
4325 bool error_set = false;
4326 if (frame_option_set) {
4327 Process *process = m_exe_ctx.GetProcessPtr();
4329 const StateType process_state = process->GetState();
4330 if (StateIsStoppedState(process_state, true)) {
4331 StackFrame *frame = m_exe_ctx.GetFramePtr();
4333 ModuleSP frame_module_sp(
4334 frame->GetSymbolContext(eSymbolContextModule).module_sp);
4335 if (frame_module_sp) {
4336 if (FileSystem::Instance().Exists(
4337 frame_module_sp->GetPlatformFileSpec())) {
4338 module_spec.GetArchitecture() =
4339 frame_module_sp->GetArchitecture();
4340 module_spec.GetFileSpec() =
4341 frame_module_sp->GetPlatformFileSpec();
4343 module_spec.GetUUID() = frame_module_sp->GetUUID();
4344 success = module_spec.GetUUID().IsValid() ||
4345 module_spec.GetFileSpec();
4347 result.AppendError("frame has no module");
4351 result.AppendError("invalid current frame");
4355 result.AppendErrorWithFormat("process is not stopped: %s",
4356 StateAsCString(process_state));
4361 "a process must exist in order to use the --frame option");
4365 if (uuid_option_set) {
4366 module_spec.GetUUID() =
4367 m_uuid_option_group.GetOptionValue().GetCurrentValue();
4368 success |= module_spec.GetUUID().IsValid();
4369 } else if (file_option_set) {
4370 module_spec.GetFileSpec() =
4371 m_file_option.GetOptionValue().GetCurrentValue();
4373 target->GetImages().FindFirstModule(module_spec));
4375 module_spec.GetFileSpec() = module_sp->GetFileSpec();
4376 module_spec.GetPlatformFileSpec() =
4377 module_sp->GetPlatformFileSpec();
4378 module_spec.GetUUID() = module_sp->GetUUID();
4379 module_spec.GetArchitecture() = module_sp->GetArchitecture();
4381 module_spec.GetArchitecture() = target->GetArchitecture();
4383 success |= module_spec.GetUUID().IsValid() ||
4384 FileSystem::Instance().Exists(module_spec.GetFileSpec());
4389 if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
4390 if (module_spec.GetSymbolFileSpec())
4391 success = AddModuleSymbols(target, module_spec, flush, result);
4395 if (!success && !error_set) {
4396 StreamString error_strm;
4397 if (uuid_option_set) {
4398 error_strm.PutCString("unable to find debug symbols for UUID ");
4399 module_spec.GetUUID().Dump(&error_strm);
4400 } else if (file_option_set) {
4401 error_strm.PutCString(
4402 "unable to find debug symbols for the executable file ");
4403 error_strm << module_spec.GetFileSpec();
4404 } else if (frame_option_set) {
4405 error_strm.PutCString(
4406 "unable to find debug symbols for the current frame");
4408 result.AppendError(error_strm.GetString());
4411 result.AppendError("one or more symbol file paths must be specified, "
4412 "or options must be specified");
4415 if (uuid_option_set) {
4416 result.AppendError("specify either one or more paths to symbol files "
4417 "or use the --uuid option without arguments");
4418 } else if (frame_option_set) {
4419 result.AppendError("specify either one or more paths to symbol files "
4420 "or use the --frame option without arguments");
4421 } else if (file_option_set && argc > 1) {
4422 result.AppendError("specify at most one symbol file path when "
4423 "--shlib option is set");
4425 PlatformSP platform_sp(target->GetPlatform());
4427 for (auto &entry : args.entries()) {
4428 if (!entry.ref.empty()) {
4429 auto &symbol_file_spec = module_spec.GetSymbolFileSpec();
4430 symbol_file_spec.SetFile(entry.ref, FileSpec::Style::native);
4431 FileSystem::Instance().Resolve(symbol_file_spec);
4432 if (file_option_set) {
4433 module_spec.GetFileSpec() =
4434 m_file_option.GetOptionValue().GetCurrentValue();
4437 FileSpec symfile_spec;
4439 ->ResolveSymbolFile(*target, module_spec, symfile_spec)
4441 module_spec.GetSymbolFileSpec() = symfile_spec;
4445 bool symfile_exists =
4446 FileSystem::Instance().Exists(module_spec.GetSymbolFileSpec());
4448 if (symfile_exists) {
4449 if (!AddModuleSymbols(target, module_spec, flush, result))
4452 std::string resolved_symfile_path =
4453 module_spec.GetSymbolFileSpec().GetPath();
4454 if (resolved_symfile_path != entry.ref) {
4455 result.AppendErrorWithFormat(
4456 "invalid module path '%s' with resolved path '%s'\n",
4457 entry.c_str(), resolved_symfile_path.c_str());
4460 result.AppendErrorWithFormat("invalid module path '%s'\n",
4470 Process *process = m_exe_ctx.GetProcessPtr();
4474 return result.Succeeded();
4477 OptionGroupOptions m_option_group;
4478 OptionGroupUUID m_uuid_option_group;
4479 OptionGroupFile m_file_option;
4480 OptionGroupBoolean m_current_frame_option;
4483 #pragma mark CommandObjectTargetSymbols
4485 //-------------------------------------------------------------------------
4486 // CommandObjectTargetSymbols
4487 //-------------------------------------------------------------------------
4489 class CommandObjectTargetSymbols : public CommandObjectMultiword {
4491 //------------------------------------------------------------------
4492 // Constructors and Destructors
4493 //------------------------------------------------------------------
4494 CommandObjectTargetSymbols(CommandInterpreter &interpreter)
4495 : CommandObjectMultiword(
4496 interpreter, "target symbols",
4497 "Commands for adding and managing debug symbol files.",
4498 "target symbols <sub-command> ...") {
4500 "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter)));
4503 ~CommandObjectTargetSymbols() override = default;
4506 //------------------------------------------------------------------
4507 // For CommandObjectTargetModules only
4508 //------------------------------------------------------------------
4509 DISALLOW_COPY_AND_ASSIGN(CommandObjectTargetSymbols);
4512 #pragma mark CommandObjectTargetStopHookAdd
4514 //-------------------------------------------------------------------------
4515 // CommandObjectTargetStopHookAdd
4516 //-------------------------------------------------------------------------
4518 static constexpr OptionDefinition g_target_stop_hook_add_options[] = {
4520 { LLDB_OPT_SET_ALL, false, "one-liner", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOneLiner, "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." },
4521 { 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." },
4522 { 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." },
4523 { 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." },
4524 { 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." },
4525 { 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." },
4526 { 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." },
4527 { 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." },
4528 { 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." },
4529 { LLDB_OPT_SET_2, false, "classname", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeClassName, "Specify the class within which the stop-hook is to be run." },
4530 { 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." },
4534 class CommandObjectTargetStopHookAdd : public CommandObjectParsed,
4535 public IOHandlerDelegateMultiline {
4537 class CommandOptions : public Options {
4540 : Options(), m_line_start(0), m_line_end(UINT_MAX),
4541 m_func_name_type_mask(eFunctionNameTypeAuto),
4542 m_sym_ctx_specified(false), m_thread_specified(false),
4543 m_use_one_liner(false), m_one_liner() {}
4545 ~CommandOptions() override = default;
4547 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
4548 return llvm::makeArrayRef(g_target_stop_hook_add_options);
4551 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
4552 ExecutionContext *execution_context) override {
4554 const int short_option = m_getopt_table[option_idx].val;
4556 switch (short_option) {
4558 m_class_name = option_arg;
4559 m_sym_ctx_specified = true;
4563 if (option_arg.getAsInteger(0, m_line_end)) {
4564 error.SetErrorStringWithFormat("invalid end line number: \"%s\"",
4565 option_arg.str().c_str());
4568 m_sym_ctx_specified = true;
4572 if (option_arg.getAsInteger(0, m_line_start)) {
4573 error.SetErrorStringWithFormat("invalid start line number: \"%s\"",
4574 option_arg.str().c_str());
4577 m_sym_ctx_specified = true;
4581 m_no_inlines = true;
4585 m_function_name = option_arg;
4586 m_func_name_type_mask |= eFunctionNameTypeAuto;
4587 m_sym_ctx_specified = true;
4591 m_file_name = option_arg;
4592 m_sym_ctx_specified = true;
4596 m_module_name = option_arg;
4597 m_sym_ctx_specified = true;
4601 if (option_arg.getAsInteger(0, m_thread_id))
4602 error.SetErrorStringWithFormat("invalid thread id string '%s'",
4603 option_arg.str().c_str());
4604 m_thread_specified = true;
4608 m_thread_name = option_arg;
4609 m_thread_specified = true;
4613 m_queue_name = option_arg;
4614 m_thread_specified = true;
4618 if (option_arg.getAsInteger(0, m_thread_index))
4619 error.SetErrorStringWithFormat("invalid thread index string '%s'",
4620 option_arg.str().c_str());
4621 m_thread_specified = true;
4625 m_use_one_liner = true;
4626 m_one_liner = option_arg;
4630 error.SetErrorStringWithFormat("unrecognized option %c.", short_option);
4636 void OptionParsingStarting(ExecutionContext *execution_context) override {
4637 m_class_name.clear();
4638 m_function_name.clear();
4640 m_line_end = UINT_MAX;
4641 m_file_name.clear();
4642 m_module_name.clear();
4643 m_func_name_type_mask = eFunctionNameTypeAuto;
4644 m_thread_id = LLDB_INVALID_THREAD_ID;
4645 m_thread_index = UINT32_MAX;
4646 m_thread_name.clear();
4647 m_queue_name.clear();
4649 m_no_inlines = false;
4650 m_sym_ctx_specified = false;
4651 m_thread_specified = false;
4653 m_use_one_liner = false;
4654 m_one_liner.clear();
4657 std::string m_class_name;
4658 std::string m_function_name;
4659 uint32_t m_line_start;
4660 uint32_t m_line_end;
4661 std::string m_file_name;
4662 std::string m_module_name;
4663 uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType.
4664 lldb::tid_t m_thread_id;
4665 uint32_t m_thread_index;
4666 std::string m_thread_name;
4667 std::string m_queue_name;
4668 bool m_sym_ctx_specified;
4670 bool m_thread_specified;
4671 // Instance variables to hold the values for one_liner options.
4672 bool m_use_one_liner;
4673 std::string m_one_liner;
4676 CommandObjectTargetStopHookAdd(CommandInterpreter &interpreter)
4677 : CommandObjectParsed(interpreter, "target stop-hook add",
4678 "Add a hook to be executed when the target stops.",
4679 "target stop-hook add"),
4680 IOHandlerDelegateMultiline("DONE",
4681 IOHandlerDelegate::Completion::LLDBCommand),
4684 ~CommandObjectTargetStopHookAdd() override = default;
4686 Options *GetOptions() override { return &m_options; }
4689 void IOHandlerActivated(IOHandler &io_handler) override {
4690 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
4692 output_sp->PutCString(
4693 "Enter your stop hook command(s). Type 'DONE' to end.\n");
4698 void IOHandlerInputComplete(IOHandler &io_handler,
4699 std::string &line) override {
4700 if (m_stop_hook_sp) {
4702 StreamFileSP error_sp(io_handler.GetErrorStreamFile());
4704 error_sp->Printf("error: stop hook #%" PRIu64
4705 " aborted, no commands.\n",
4706 m_stop_hook_sp->GetID());
4709 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
4711 target->RemoveStopHookByID(m_stop_hook_sp->GetID());
4713 m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line);
4714 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
4716 output_sp->Printf("Stop hook #%" PRIu64 " added.\n",
4717 m_stop_hook_sp->GetID());
4721 m_stop_hook_sp.reset();
4723 io_handler.SetIsDone(true);
4726 bool DoExecute(Args &command, CommandReturnObject &result) override {
4727 m_stop_hook_sp.reset();
4729 Target *target = GetSelectedOrDummyTarget();
4731 Target::StopHookSP new_hook_sp = target->CreateStopHook();
4733 // First step, make the specifier.
4734 std::unique_ptr<SymbolContextSpecifier> specifier_ap;
4735 if (m_options.m_sym_ctx_specified) {
4736 specifier_ap.reset(new SymbolContextSpecifier(
4737 m_interpreter.GetDebugger().GetSelectedTarget()));
4739 if (!m_options.m_module_name.empty()) {
4740 specifier_ap->AddSpecification(
4741 m_options.m_module_name.c_str(),
4742 SymbolContextSpecifier::eModuleSpecified);
4745 if (!m_options.m_class_name.empty()) {
4746 specifier_ap->AddSpecification(
4747 m_options.m_class_name.c_str(),
4748 SymbolContextSpecifier::eClassOrNamespaceSpecified);
4751 if (!m_options.m_file_name.empty()) {
4752 specifier_ap->AddSpecification(
4753 m_options.m_file_name.c_str(),
4754 SymbolContextSpecifier::eFileSpecified);
4757 if (m_options.m_line_start != 0) {
4758 specifier_ap->AddLineSpecification(
4759 m_options.m_line_start,
4760 SymbolContextSpecifier::eLineStartSpecified);
4763 if (m_options.m_line_end != UINT_MAX) {
4764 specifier_ap->AddLineSpecification(
4765 m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
4768 if (!m_options.m_function_name.empty()) {
4769 specifier_ap->AddSpecification(
4770 m_options.m_function_name.c_str(),
4771 SymbolContextSpecifier::eFunctionSpecified);
4776 new_hook_sp->SetSpecifier(specifier_ap.release());
4778 // Next see if any of the thread options have been entered:
4780 if (m_options.m_thread_specified) {
4781 ThreadSpec *thread_spec = new ThreadSpec();
4783 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) {
4784 thread_spec->SetTID(m_options.m_thread_id);
4787 if (m_options.m_thread_index != UINT32_MAX)
4788 thread_spec->SetIndex(m_options.m_thread_index);
4790 if (!m_options.m_thread_name.empty())
4791 thread_spec->SetName(m_options.m_thread_name.c_str());
4793 if (!m_options.m_queue_name.empty())
4794 thread_spec->SetQueueName(m_options.m_queue_name.c_str());
4796 new_hook_sp->SetThreadSpecifier(thread_spec);
4798 if (m_options.m_use_one_liner) {
4800 new_hook_sp->GetCommandPointer()->AppendString(
4801 m_options.m_one_liner.c_str());
4802 result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
4803 new_hook_sp->GetID());
4805 m_stop_hook_sp = new_hook_sp;
4806 m_interpreter.GetLLDBCommandsFromIOHandler(
4808 *this, // IOHandlerDelegate
4809 true, // Run IOHandler in async mode
4810 nullptr); // Baton for the "io_handler" that will be passed back
4811 // into our IOHandlerDelegate functions
4813 result.SetStatus(eReturnStatusSuccessFinishNoResult);
4815 result.AppendError("invalid target\n");
4816 result.SetStatus(eReturnStatusFailed);
4819 return result.Succeeded();
4823 CommandOptions m_options;
4824 Target::StopHookSP m_stop_hook_sp;
4827 #pragma mark CommandObjectTargetStopHookDelete
4829 //-------------------------------------------------------------------------
4830 // CommandObjectTargetStopHookDelete
4831 //-------------------------------------------------------------------------
4833 class CommandObjectTargetStopHookDelete : public CommandObjectParsed {
4835 CommandObjectTargetStopHookDelete(CommandInterpreter &interpreter)
4836 : CommandObjectParsed(interpreter, "target stop-hook delete",
4837 "Delete a stop-hook.",
4838 "target stop-hook delete [<idx>]") {}
4840 ~CommandObjectTargetStopHookDelete() override = default;
4843 bool DoExecute(Args &command, CommandReturnObject &result) override {
4844 Target *target = GetSelectedOrDummyTarget();
4846 // FIXME: see if we can use the breakpoint id style parser?
4847 size_t num_args = command.GetArgumentCount();
4848 if (num_args == 0) {
4849 if (!m_interpreter.Confirm("Delete all stop hooks?", true)) {
4850 result.SetStatus(eReturnStatusFailed);
4853 target->RemoveAllStopHooks();
4857 for (size_t i = 0; i < num_args; i++) {
4858 lldb::user_id_t user_id = StringConvert::ToUInt32(
4859 command.GetArgumentAtIndex(i), 0, 0, &success);
4861 result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4862 command.GetArgumentAtIndex(i));
4863 result.SetStatus(eReturnStatusFailed);
4866 success = target->RemoveStopHookByID(user_id);
4868 result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4869 command.GetArgumentAtIndex(i));
4870 result.SetStatus(eReturnStatusFailed);
4875 result.SetStatus(eReturnStatusSuccessFinishNoResult);
4877 result.AppendError("invalid target\n");
4878 result.SetStatus(eReturnStatusFailed);
4881 return result.Succeeded();
4885 #pragma mark CommandObjectTargetStopHookEnableDisable
4887 //-------------------------------------------------------------------------
4888 // CommandObjectTargetStopHookEnableDisable
4889 //-------------------------------------------------------------------------
4891 class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed {
4893 CommandObjectTargetStopHookEnableDisable(CommandInterpreter &interpreter,
4894 bool enable, const char *name,
4895 const char *help, const char *syntax)
4896 : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable) {
4899 ~CommandObjectTargetStopHookEnableDisable() override = default;
4902 bool DoExecute(Args &command, CommandReturnObject &result) override {
4903 Target *target = GetSelectedOrDummyTarget();
4905 // FIXME: see if we can use the breakpoint id style parser?
4906 size_t num_args = command.GetArgumentCount();
4909 if (num_args == 0) {
4910 target->SetAllStopHooksActiveState(m_enable);
4912 for (size_t i = 0; i < num_args; i++) {
4913 lldb::user_id_t user_id = StringConvert::ToUInt32(
4914 command.GetArgumentAtIndex(i), 0, 0, &success);
4916 result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4917 command.GetArgumentAtIndex(i));
4918 result.SetStatus(eReturnStatusFailed);
4921 success = target->SetStopHookActiveStateByID(user_id, m_enable);
4923 result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4924 command.GetArgumentAtIndex(i));
4925 result.SetStatus(eReturnStatusFailed);
4930 result.SetStatus(eReturnStatusSuccessFinishNoResult);
4932 result.AppendError("invalid target\n");
4933 result.SetStatus(eReturnStatusFailed);
4935 return result.Succeeded();
4942 #pragma mark CommandObjectTargetStopHookList
4944 //-------------------------------------------------------------------------
4945 // CommandObjectTargetStopHookList
4946 //-------------------------------------------------------------------------
4948 class CommandObjectTargetStopHookList : public CommandObjectParsed {
4950 CommandObjectTargetStopHookList(CommandInterpreter &interpreter)
4951 : CommandObjectParsed(interpreter, "target stop-hook list",
4952 "List all stop-hooks.",
4953 "target stop-hook list [<type>]") {}
4955 ~CommandObjectTargetStopHookList() override = default;
4958 bool DoExecute(Args &command, CommandReturnObject &result) override {
4959 Target *target = GetSelectedOrDummyTarget();
4961 result.AppendError("invalid target\n");
4962 result.SetStatus(eReturnStatusFailed);
4963 return result.Succeeded();
4966 size_t num_hooks = target->GetNumStopHooks();
4967 if (num_hooks == 0) {
4968 result.GetOutputStream().PutCString("No stop hooks.\n");
4970 for (size_t i = 0; i < num_hooks; i++) {
4971 Target::StopHookSP this_hook = target->GetStopHookAtIndex(i);
4973 result.GetOutputStream().PutCString("\n");
4974 this_hook->GetDescription(&(result.GetOutputStream()),
4975 eDescriptionLevelFull);
4978 result.SetStatus(eReturnStatusSuccessFinishResult);
4979 return result.Succeeded();
4983 #pragma mark CommandObjectMultiwordTargetStopHooks
4985 //-------------------------------------------------------------------------
4986 // CommandObjectMultiwordTargetStopHooks
4987 //-------------------------------------------------------------------------
4989 class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword {
4991 CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter)
4992 : CommandObjectMultiword(
4993 interpreter, "target stop-hook",
4994 "Commands for operating on debugger target stop-hooks.",
4995 "target stop-hook <subcommand> [<subcommand-options>]") {
4996 LoadSubCommand("add", CommandObjectSP(
4997 new CommandObjectTargetStopHookAdd(interpreter)));
5000 CommandObjectSP(new CommandObjectTargetStopHookDelete(interpreter)));
5001 LoadSubCommand("disable",
5002 CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
5003 interpreter, false, "target stop-hook disable [<id>]",
5004 "Disable a stop-hook.", "target stop-hook disable")));
5005 LoadSubCommand("enable",
5006 CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
5007 interpreter, true, "target stop-hook enable [<id>]",
5008 "Enable a stop-hook.", "target stop-hook enable")));
5009 LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetStopHookList(
5013 ~CommandObjectMultiwordTargetStopHooks() override = default;
5016 #pragma mark CommandObjectMultiwordTarget
5018 //-------------------------------------------------------------------------
5019 // CommandObjectMultiwordTarget
5020 //-------------------------------------------------------------------------
5022 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget(
5023 CommandInterpreter &interpreter)
5024 : CommandObjectMultiword(interpreter, "target",
5025 "Commands for operating on debugger targets.",
5026 "target <subcommand> [<subcommand-options>]") {
5027 LoadSubCommand("create",
5028 CommandObjectSP(new CommandObjectTargetCreate(interpreter)));
5029 LoadSubCommand("delete",
5030 CommandObjectSP(new CommandObjectTargetDelete(interpreter)));
5031 LoadSubCommand("list",
5032 CommandObjectSP(new CommandObjectTargetList(interpreter)));
5033 LoadSubCommand("select",
5034 CommandObjectSP(new CommandObjectTargetSelect(interpreter)));
5037 CommandObjectSP(new CommandObjectMultiwordTargetStopHooks(interpreter)));
5038 LoadSubCommand("modules",
5039 CommandObjectSP(new CommandObjectTargetModules(interpreter)));
5040 LoadSubCommand("symbols",
5041 CommandObjectSP(new CommandObjectTargetSymbols(interpreter)));
5042 LoadSubCommand("variable",
5043 CommandObjectSP(new CommandObjectTargetVariable(interpreter)));
5046 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget() = default;