1 //===-- CommandObjectTarget.cpp -------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "CommandObjectTarget.h"
11 #include "lldb/Core/Debugger.h"
12 #include "lldb/Core/IOHandler.h"
13 #include "lldb/Core/Module.h"
14 #include "lldb/Core/ModuleSpec.h"
15 #include "lldb/Core/Section.h"
16 #include "lldb/Core/ValueObjectVariable.h"
17 #include "lldb/DataFormatters/ValueObjectPrinter.h"
18 #include "lldb/Host/OptionParser.h"
19 #include "lldb/Interpreter/CommandInterpreter.h"
20 #include "lldb/Interpreter/CommandReturnObject.h"
21 #include "lldb/Interpreter/OptionArgParser.h"
22 #include "lldb/Interpreter/OptionGroupArchitecture.h"
23 #include "lldb/Interpreter/OptionGroupBoolean.h"
24 #include "lldb/Interpreter/OptionGroupFile.h"
25 #include "lldb/Interpreter/OptionGroupFormat.h"
26 #include "lldb/Interpreter/OptionGroupString.h"
27 #include "lldb/Interpreter/OptionGroupUInt64.h"
28 #include "lldb/Interpreter/OptionGroupUUID.h"
29 #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
30 #include "lldb/Interpreter/OptionGroupVariable.h"
31 #include "lldb/Interpreter/Options.h"
32 #include "lldb/Symbol/CompileUnit.h"
33 #include "lldb/Symbol/FuncUnwinders.h"
34 #include "lldb/Symbol/LineTable.h"
35 #include "lldb/Symbol/LocateSymbolFile.h"
36 #include "lldb/Symbol/ObjectFile.h"
37 #include "lldb/Symbol/SymbolFile.h"
38 #include "lldb/Symbol/UnwindPlan.h"
39 #include "lldb/Symbol/VariableList.h"
40 #include "lldb/Target/ABI.h"
41 #include "lldb/Target/Process.h"
42 #include "lldb/Target/RegisterContext.h"
43 #include "lldb/Target/SectionLoadList.h"
44 #include "lldb/Target/StackFrame.h"
45 #include "lldb/Target/Thread.h"
46 #include "lldb/Target/ThreadSpec.h"
47 #include "lldb/Utility/Args.h"
48 #include "lldb/Utility/State.h"
49 #include "lldb/Utility/Timer.h"
51 #include "llvm/Support/FileSystem.h"
52 #include "llvm/Support/FormatAdapters.h"
56 using namespace lldb_private;
58 static void DumpTargetInfo(uint32_t target_idx, Target *target,
59 const char *prefix_cstr,
60 bool show_stopped_process_status, Stream &strm) {
61 const ArchSpec &target_arch = target->GetArchitecture();
63 Module *exe_module = target->GetExecutableModulePointer();
64 char exe_path[PATH_MAX];
65 bool exe_valid = false;
67 exe_valid = exe_module->GetFileSpec().GetPath(exe_path, sizeof(exe_path));
70 ::strcpy(exe_path, "<none>");
72 strm.Printf("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx,
75 uint32_t properties = 0;
76 if (target_arch.IsValid()) {
77 strm.Printf("%sarch=", properties++ > 0 ? ", " : " ( ");
78 target_arch.DumpTriple(strm.AsRawOstream());
81 PlatformSP platform_sp(target->GetPlatform());
83 strm.Printf("%splatform=%s", properties++ > 0 ? ", " : " ( ",
84 platform_sp->GetName().GetCString());
86 ProcessSP process_sp(target->GetProcessSP());
87 bool show_process_status = false;
89 lldb::pid_t pid = process_sp->GetID();
90 StateType state = process_sp->GetState();
91 if (show_stopped_process_status)
92 show_process_status = StateIsStoppedState(state, true);
93 const char *state_cstr = StateAsCString(state);
94 if (pid != LLDB_INVALID_PROCESS_ID)
95 strm.Printf("%spid=%" PRIu64, properties++ > 0 ? ", " : " ( ", pid);
96 strm.Printf("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
99 strm.PutCString(" )\n");
102 if (show_process_status) {
103 const bool only_threads_with_stop_reason = true;
104 const uint32_t start_frame = 0;
105 const uint32_t num_frames = 1;
106 const uint32_t num_frames_with_source = 1;
107 const bool stop_format = false;
108 process_sp->GetStatus(strm);
109 process_sp->GetThreadStatus(strm, only_threads_with_stop_reason,
110 start_frame, num_frames, num_frames_with_source,
115 static uint32_t DumpTargetList(TargetList &target_list,
116 bool show_stopped_process_status, Stream &strm) {
117 const uint32_t num_targets = target_list.GetNumTargets();
119 TargetSP selected_target_sp(target_list.GetSelectedTarget());
120 strm.PutCString("Current targets:\n");
121 for (uint32_t i = 0; i < num_targets; ++i) {
122 TargetSP target_sp(target_list.GetTargetAtIndex(i));
124 bool is_selected = target_sp.get() == selected_target_sp.get();
125 DumpTargetInfo(i, target_sp.get(), is_selected ? "* " : " ",
126 show_stopped_process_status, strm);
133 // Note that the negation in the argument name causes a slightly confusing
134 // mapping of the enum values.
135 static constexpr OptionEnumValueElement g_dependents_enumaration[] = {
137 eLoadDependentsDefault,
139 "Only load dependents when the target is an executable.",
144 "Don't load dependents, even if the target is an executable.",
149 "Load dependents, even if the target is not an executable.",
153 #define LLDB_OPTIONS_target_dependents
154 #include "CommandOptions.inc"
156 class OptionGroupDependents : public OptionGroup {
158 OptionGroupDependents() {}
160 ~OptionGroupDependents() override {}
162 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
163 return llvm::makeArrayRef(g_target_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 =
177 g_target_dependents_options[option_idx].short_option;
178 if (short_option == 'd') {
179 LoadDependentFiles tmp_load_dependents;
180 tmp_load_dependents = (LoadDependentFiles)OptionArgParser::ToOptionEnum(
181 option_value, g_target_dependents_options[option_idx].enum_values, 0,
184 m_load_dependent_files = tmp_load_dependents;
186 error.SetErrorStringWithFormat("unrecognized short option '%c'",
193 Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete;
195 void OptionParsingStarting(ExecutionContext *execution_context) override {
196 m_load_dependent_files = eLoadDependentsDefault;
199 LoadDependentFiles m_load_dependent_files;
202 OptionGroupDependents(const OptionGroupDependents &) = delete;
203 const OptionGroupDependents &
204 operator=(const OptionGroupDependents &) = delete;
207 #pragma mark CommandObjectTargetCreate
211 class CommandObjectTargetCreate : public CommandObjectParsed {
213 CommandObjectTargetCreate(CommandInterpreter &interpreter)
214 : CommandObjectParsed(
215 interpreter, "target create",
216 "Create a target using the argument as the main executable.",
218 m_option_group(), m_arch_option(),
219 m_core_file(LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename,
220 "Fullpath to a core file to use for this target."),
221 m_platform_path(LLDB_OPT_SET_1, false, "platform-path", 'P', 0,
223 "Path to the remote file to use for this target."),
224 m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
226 "Fullpath to a stand alone debug "
227 "symbols file for when debug symbols "
228 "are not in the executable."),
230 LLDB_OPT_SET_1, false, "remote-file", 'r', 0, eArgTypeFilename,
231 "Fullpath to the file on the remote host if debugging remotely."),
233 CommandArgumentEntry arg;
234 CommandArgumentData file_arg;
236 // Define the first (and only) variant of this arg.
237 file_arg.arg_type = eArgTypeFilename;
238 file_arg.arg_repetition = eArgRepeatPlain;
240 // There is only one variant this argument could be; put it into the
242 arg.push_back(file_arg);
244 // Push the data for the first argument into the m_arguments vector.
245 m_arguments.push_back(arg);
247 m_option_group.Append(&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
248 m_option_group.Append(&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
249 m_option_group.Append(&m_platform_path, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
250 m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
251 m_option_group.Append(&m_remote_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
252 m_option_group.Append(&m_add_dependents, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
253 m_option_group.Finalize();
256 ~CommandObjectTargetCreate() override = default;
258 Options *GetOptions() override { return &m_option_group; }
261 HandleArgumentCompletion(CompletionRequest &request,
262 OptionElementVector &opt_element_vector) override {
263 CommandCompletions::InvokeCommonCompletionCallbacks(
264 GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
269 bool DoExecute(Args &command, CommandReturnObject &result) override {
270 const size_t argc = command.GetArgumentCount();
271 FileSpec core_file(m_core_file.GetOptionValue().GetCurrentValue());
272 FileSpec remote_file(m_remote_file.GetOptionValue().GetCurrentValue());
275 auto file = FileSystem::Instance().Open(
276 core_file, lldb_private::File::eOpenOptionRead);
279 result.AppendErrorWithFormatv("Cannot open '{0}': {1}.",
281 llvm::toString(file.takeError()));
282 result.SetStatus(eReturnStatusFailed);
287 if (argc == 1 || core_file || remote_file) {
288 FileSpec symfile(m_symbol_file.GetOptionValue().GetCurrentValue());
290 auto file = FileSystem::Instance().Open(
291 symfile, lldb_private::File::eOpenOptionRead);
294 result.AppendErrorWithFormatv("Cannot open '{0}': {1}.",
296 llvm::toString(file.takeError()));
297 result.SetStatus(eReturnStatusFailed);
302 const char *file_path = command.GetArgumentAtIndex(0);
303 static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
304 Timer scoped_timer(func_cat, "(lldb) target create '%s'", file_path);
308 file_spec.SetFile(file_path, FileSpec::Style::native);
309 FileSystem::Instance().Resolve(file_spec);
312 bool must_set_platform_path = false;
314 Debugger &debugger = GetDebugger();
317 llvm::StringRef arch_cstr = m_arch_option.GetArchitectureName();
318 Status error(debugger.GetTargetList().CreateTarget(
319 debugger, file_path, arch_cstr,
320 m_add_dependents.m_load_dependent_files, nullptr, target_sp));
323 // Only get the platform after we create the target because we might
324 // have switched platforms depending on what the arguments were to
325 // CreateTarget() we can't rely on the selected platform.
327 PlatformSP platform_sp = target_sp->GetPlatform();
331 // I have a remote file.. two possible cases
332 if (file_spec && FileSystem::Instance().Exists(file_spec)) {
333 // if the remote file does not exist, push it there
334 if (!platform_sp->GetFileExists(remote_file)) {
335 Status err = platform_sp->PutFile(file_spec, remote_file);
337 result.AppendError(err.AsCString());
338 result.SetStatus(eReturnStatusFailed);
343 // there is no local file and we need one
344 // in order to make the remote ---> local transfer we need a
346 // TODO: if the user has passed in a --platform argument, use it
347 // to fetch the right platform
350 "unable to perform remote debugging without a platform");
351 result.SetStatus(eReturnStatusFailed);
355 // copy the remote file to the local file
356 Status err = platform_sp->GetFile(remote_file, file_spec);
358 result.AppendError(err.AsCString());
359 result.SetStatus(eReturnStatusFailed);
363 // make up a local file
364 result.AppendError("remote --> local transfer without local "
365 "path is not implemented yet");
366 result.SetStatus(eReturnStatusFailed);
371 result.AppendError("no platform found for target");
372 result.SetStatus(eReturnStatusFailed);
377 if (symfile || remote_file) {
378 ModuleSP module_sp(target_sp->GetExecutableModule());
381 module_sp->SetSymbolFileFileSpec(symfile);
383 std::string remote_path = remote_file.GetPath();
384 target_sp->SetArg0(remote_path.c_str());
385 module_sp->SetPlatformFileSpec(remote_file);
390 debugger.GetTargetList().SetSelectedTarget(target_sp.get());
391 if (must_set_platform_path) {
392 ModuleSpec main_module_spec(file_spec);
394 target_sp->GetOrCreateModule(main_module_spec, true /* notify */);
396 module_sp->SetPlatformFileSpec(remote_file);
400 FileSpec core_file_dir;
401 core_file_dir.GetDirectory() = core_file.GetDirectory();
402 target_sp->AppendExecutableSearchPaths(core_file_dir);
404 ProcessSP process_sp(target_sp->CreateProcess(
405 GetDebugger().GetListener(), llvm::StringRef(), &core_file));
408 // Seems weird that we Launch a core file, but that is what we
410 error = process_sp->LoadCore();
414 error.AsCString("can't find plug-in for core file"));
415 result.SetStatus(eReturnStatusFailed);
418 result.AppendMessageWithFormatv("Core file '{0}' ({1}) was loaded.\n", core_file.GetPath(),
419 target_sp->GetArchitecture().GetArchitectureName());
420 result.SetStatus(eReturnStatusSuccessFinishNoResult);
423 result.AppendErrorWithFormatv(
424 "Unable to find process plug-in for core file '{0}'\n",
425 core_file.GetPath());
426 result.SetStatus(eReturnStatusFailed);
429 result.AppendMessageWithFormat(
430 "Current executable set to '%s' (%s).\n",
431 file_spec.GetPath().c_str(),
432 target_sp->GetArchitecture().GetArchitectureName());
433 result.SetStatus(eReturnStatusSuccessFinishNoResult);
436 result.AppendError(error.AsCString());
437 result.SetStatus(eReturnStatusFailed);
440 result.AppendErrorWithFormat("'%s' takes exactly one executable path "
441 "argument, or use the --core option.\n",
443 result.SetStatus(eReturnStatusFailed);
445 return result.Succeeded();
449 OptionGroupOptions m_option_group;
450 OptionGroupArchitecture m_arch_option;
451 OptionGroupFile m_core_file;
452 OptionGroupFile m_platform_path;
453 OptionGroupFile m_symbol_file;
454 OptionGroupFile m_remote_file;
455 OptionGroupDependents m_add_dependents;
458 #pragma mark CommandObjectTargetList
462 class CommandObjectTargetList : public CommandObjectParsed {
464 CommandObjectTargetList(CommandInterpreter &interpreter)
465 : CommandObjectParsed(
466 interpreter, "target list",
467 "List all current targets in the current debug session.", nullptr) {
470 ~CommandObjectTargetList() override = default;
473 bool DoExecute(Args &args, CommandReturnObject &result) override {
474 if (args.GetArgumentCount() == 0) {
475 Stream &strm = result.GetOutputStream();
477 bool show_stopped_process_status = false;
478 if (DumpTargetList(GetDebugger().GetTargetList(),
479 show_stopped_process_status, strm) == 0) {
480 strm.PutCString("No targets.\n");
482 result.SetStatus(eReturnStatusSuccessFinishResult);
484 result.AppendError("the 'target list' command takes no arguments\n");
485 result.SetStatus(eReturnStatusFailed);
487 return result.Succeeded();
491 #pragma mark CommandObjectTargetSelect
495 class CommandObjectTargetSelect : public CommandObjectParsed {
497 CommandObjectTargetSelect(CommandInterpreter &interpreter)
498 : CommandObjectParsed(
499 interpreter, "target select",
500 "Select a target as the current target by target index.", nullptr) {
503 ~CommandObjectTargetSelect() override = default;
506 bool DoExecute(Args &args, CommandReturnObject &result) override {
507 if (args.GetArgumentCount() == 1) {
508 const char *target_idx_arg = args.GetArgumentAtIndex(0);
510 if (llvm::to_integer(target_idx_arg, target_idx)) {
511 TargetList &target_list = GetDebugger().GetTargetList();
512 const uint32_t num_targets = target_list.GetNumTargets();
513 if (target_idx < num_targets) {
514 TargetSP target_sp(target_list.GetTargetAtIndex(target_idx));
516 Stream &strm = result.GetOutputStream();
517 target_list.SetSelectedTarget(target_sp.get());
518 bool show_stopped_process_status = false;
519 DumpTargetList(target_list, show_stopped_process_status, strm);
520 result.SetStatus(eReturnStatusSuccessFinishResult);
522 result.AppendErrorWithFormat("target #%u is NULL in target list\n",
524 result.SetStatus(eReturnStatusFailed);
527 if (num_targets > 0) {
528 result.AppendErrorWithFormat(
529 "index %u is out of range, valid target indexes are 0 - %u\n",
530 target_idx, num_targets - 1);
532 result.AppendErrorWithFormat(
533 "index %u is out of range since there are no active targets\n",
536 result.SetStatus(eReturnStatusFailed);
539 result.AppendErrorWithFormat("invalid index string value '%s'\n",
541 result.SetStatus(eReturnStatusFailed);
545 "'target select' takes a single argument: a target index\n");
546 result.SetStatus(eReturnStatusFailed);
548 return result.Succeeded();
552 #pragma mark CommandObjectTargetDelete
556 class CommandObjectTargetDelete : public CommandObjectParsed {
558 CommandObjectTargetDelete(CommandInterpreter &interpreter)
559 : CommandObjectParsed(interpreter, "target delete",
560 "Delete one or more targets by target index.",
562 m_option_group(), m_all_option(LLDB_OPT_SET_1, false, "all", 'a',
563 "Delete all targets.", false, true),
565 LLDB_OPT_SET_1, false, "clean", 'c',
566 "Perform extra cleanup to minimize memory consumption after "
567 "deleting the target. "
568 "By default, LLDB will keep in memory any modules previously "
569 "loaded by the target as well "
570 "as all of its debug info. Specifying --clean will unload all of "
571 "these shared modules and "
572 "cause them to be reparsed again the next time the target is run",
574 m_option_group.Append(&m_all_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
575 m_option_group.Append(&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
576 m_option_group.Finalize();
579 ~CommandObjectTargetDelete() override = default;
581 Options *GetOptions() override { return &m_option_group; }
584 bool DoExecute(Args &args, CommandReturnObject &result) override {
585 const size_t argc = args.GetArgumentCount();
586 std::vector<TargetSP> delete_target_list;
587 TargetList &target_list = GetDebugger().GetTargetList();
590 if (m_all_option.GetOptionValue()) {
591 for (int i = 0; i < target_list.GetNumTargets(); ++i)
592 delete_target_list.push_back(target_list.GetTargetAtIndex(i));
593 } else if (argc > 0) {
594 const uint32_t num_targets = target_list.GetNumTargets();
595 // Bail out if don't have any targets.
596 if (num_targets == 0) {
597 result.AppendError("no targets to delete");
598 result.SetStatus(eReturnStatusFailed);
602 for (auto &entry : args.entries()) {
604 if (entry.ref().getAsInteger(0, target_idx)) {
605 result.AppendErrorWithFormat("invalid target index '%s'\n",
607 result.SetStatus(eReturnStatusFailed);
610 if (target_idx < num_targets) {
611 target_sp = target_list.GetTargetAtIndex(target_idx);
613 delete_target_list.push_back(target_sp);
618 result.AppendErrorWithFormat("target index %u is out of range, valid "
619 "target indexes are 0 - %u\n",
620 target_idx, num_targets - 1);
622 result.AppendErrorWithFormat(
623 "target index %u is out of range, the only valid index is 0\n",
626 result.SetStatus(eReturnStatusFailed);
630 target_sp = target_list.GetSelectedTarget();
632 result.AppendErrorWithFormat("no target is currently selected\n");
633 result.SetStatus(eReturnStatusFailed);
636 delete_target_list.push_back(target_sp);
639 const size_t num_targets_to_delete = delete_target_list.size();
640 for (size_t idx = 0; idx < num_targets_to_delete; ++idx) {
641 target_sp = delete_target_list[idx];
642 target_list.DeleteTarget(target_sp);
643 target_sp->Destroy();
645 // If "--clean" was specified, prune any orphaned shared modules from the
646 // global shared module list
647 if (m_cleanup_option.GetOptionValue()) {
648 const bool mandatory = true;
649 ModuleList::RemoveOrphanSharedModules(mandatory);
651 result.GetOutputStream().Printf("%u targets deleted.\n",
652 (uint32_t)num_targets_to_delete);
653 result.SetStatus(eReturnStatusSuccessFinishResult);
658 OptionGroupOptions m_option_group;
659 OptionGroupBoolean m_all_option;
660 OptionGroupBoolean m_cleanup_option;
663 class CommandObjectTargetShowLaunchEnvironment : public CommandObjectParsed {
665 CommandObjectTargetShowLaunchEnvironment(CommandInterpreter &interpreter)
666 : CommandObjectParsed(
667 interpreter, "target show-launch-environment",
668 "Shows the environment being passed to the process when launched, "
669 "taking info account 3 settings: target.env-vars, "
670 "target.inherit-env and target.unset-env-vars.",
671 nullptr, eCommandRequiresTarget) {}
673 ~CommandObjectTargetShowLaunchEnvironment() override = default;
676 bool DoExecute(Args &args, CommandReturnObject &result) override {
677 Target *target = m_exe_ctx.GetTargetPtr();
678 Environment env = target->GetEnvironment();
680 std::vector<Environment::value_type *> env_vector;
681 env_vector.reserve(env.size());
683 env_vector.push_back(&KV);
684 std::sort(env_vector.begin(), env_vector.end(),
685 [](Environment::value_type *a, Environment::value_type *b) {
686 return a->first() < b->first();
689 auto &strm = result.GetOutputStream();
690 for (auto &KV : env_vector)
691 strm.Format("{0}={1}\n", KV->first(), KV->second);
693 result.SetStatus(eReturnStatusSuccessFinishResult);
694 return result.Succeeded();
698 #pragma mark CommandObjectTargetVariable
702 class CommandObjectTargetVariable : public CommandObjectParsed {
703 static const uint32_t SHORT_OPTION_FILE = 0x66696c65; // 'file'
704 static const uint32_t SHORT_OPTION_SHLB = 0x73686c62; // 'shlb'
707 CommandObjectTargetVariable(CommandInterpreter &interpreter)
708 : CommandObjectParsed(interpreter, "target variable",
709 "Read global variables for the current target, "
710 "before or while running a process.",
711 nullptr, eCommandRequiresTarget),
713 m_option_variable(false), // Don't include frame options
714 m_option_format(eFormatDefault),
715 m_option_compile_units(LLDB_OPT_SET_1, false, "file", SHORT_OPTION_FILE,
717 "A basename or fullpath to a file that contains "
718 "global variables. This option can be "
719 "specified multiple times."),
720 m_option_shared_libraries(
721 LLDB_OPT_SET_1, false, "shlib", SHORT_OPTION_SHLB, 0,
723 "A basename or fullpath to a shared library to use in the search "
725 "variables. This option can be specified multiple times."),
727 CommandArgumentEntry arg;
728 CommandArgumentData var_name_arg;
730 // Define the first (and only) variant of this arg.
731 var_name_arg.arg_type = eArgTypeVarName;
732 var_name_arg.arg_repetition = eArgRepeatPlus;
734 // There is only one variant this argument could be; put it into the
736 arg.push_back(var_name_arg);
738 // Push the data for the first argument into the m_arguments vector.
739 m_arguments.push_back(arg);
741 m_option_group.Append(&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
742 m_option_group.Append(&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
743 m_option_group.Append(&m_option_format,
744 OptionGroupFormat::OPTION_GROUP_FORMAT |
745 OptionGroupFormat::OPTION_GROUP_GDB_FMT,
747 m_option_group.Append(&m_option_compile_units, LLDB_OPT_SET_ALL,
749 m_option_group.Append(&m_option_shared_libraries, LLDB_OPT_SET_ALL,
751 m_option_group.Finalize();
754 ~CommandObjectTargetVariable() override = default;
756 void DumpValueObject(Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp,
757 const char *root_name) {
758 DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions());
760 if (!valobj_sp->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
761 valobj_sp->IsRuntimeSupportValue())
764 switch (var_sp->GetScope()) {
765 case eValueTypeVariableGlobal:
766 if (m_option_variable.show_scope)
767 s.PutCString("GLOBAL: ");
770 case eValueTypeVariableStatic:
771 if (m_option_variable.show_scope)
772 s.PutCString("STATIC: ");
775 case eValueTypeVariableArgument:
776 if (m_option_variable.show_scope)
777 s.PutCString(" ARG: ");
780 case eValueTypeVariableLocal:
781 if (m_option_variable.show_scope)
782 s.PutCString(" LOCAL: ");
785 case eValueTypeVariableThreadLocal:
786 if (m_option_variable.show_scope)
787 s.PutCString("THREAD: ");
794 if (m_option_variable.show_decl) {
795 bool show_fullpaths = false;
796 bool show_module = true;
797 if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
801 const Format format = m_option_format.GetFormat();
802 if (format != eFormatDefault)
803 options.SetFormat(format);
805 options.SetRootValueObjectName(root_name);
807 valobj_sp->Dump(s, options);
810 static size_t GetVariableCallback(void *baton, const char *name,
811 VariableList &variable_list) {
812 size_t old_size = variable_list.GetSize();
813 Target *target = static_cast<Target *>(baton);
815 target->GetImages().FindGlobalVariables(ConstString(name), UINT32_MAX,
817 return variable_list.GetSize() - old_size;
820 Options *GetOptions() override { return &m_option_group; }
823 void DumpGlobalVariableList(const ExecutionContext &exe_ctx,
824 const SymbolContext &sc,
825 const VariableList &variable_list, Stream &s) {
826 if (variable_list.Empty())
830 s.Format("Global variables for {0} in {1}:\n",
831 sc.comp_unit->GetPrimaryFile(), sc.module_sp->GetFileSpec());
833 s.Printf("Global variables for %s\n",
834 sc.module_sp->GetFileSpec().GetPath().c_str());
836 } else if (sc.comp_unit) {
837 s.Format("Global variables for {0}\n", sc.comp_unit->GetPrimaryFile());
840 for (VariableSP var_sp : variable_list) {
843 ValueObjectSP valobj_sp(ValueObjectVariable::Create(
844 exe_ctx.GetBestExecutionContextScope(), var_sp));
847 DumpValueObject(s, var_sp, valobj_sp, var_sp->GetName().GetCString());
851 bool DoExecute(Args &args, CommandReturnObject &result) override {
852 Target *target = m_exe_ctx.GetTargetPtr();
853 const size_t argc = args.GetArgumentCount();
854 Stream &s = result.GetOutputStream();
857 for (const Args::ArgEntry &arg : args) {
858 VariableList variable_list;
859 ValueObjectList valobj_list;
862 bool use_var_name = false;
863 if (m_option_variable.use_regex) {
864 RegularExpression regex(
865 llvm::StringRef::withNullAsEmpty(arg.c_str()));
866 if (!regex.IsValid()) {
867 result.GetErrorStream().Printf(
868 "error: invalid regular expression: '%s'\n", arg.c_str());
869 result.SetStatus(eReturnStatusFailed);
873 target->GetImages().FindGlobalVariables(regex, UINT32_MAX,
875 matches = variable_list.GetSize();
877 Status error(Variable::GetValuesForVariableExpressionPath(
878 arg.c_str(), 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.c_str());
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.AppendErrorWithFormatv(
937 "no global variables in current compile unit: {0}\n",
938 comp_unit->GetPrimaryFile());
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 // We have one or more compile unit or shlib
951 if (num_shlibs > 0) {
952 for (size_t shlib_idx = 0; shlib_idx < num_shlibs; ++shlib_idx) {
953 const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx));
954 ModuleSpec module_spec(module_file);
957 target->GetImages().FindFirstModule(module_spec));
959 if (num_compile_units > 0) {
960 for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
961 module_sp->FindCompileUnits(
962 compile_units.GetFileSpecAtIndex(cu_idx), sc_list);
965 sc.module_sp = module_sp;
969 // Didn't find matching shlib/module in target...
970 result.AppendErrorWithFormat(
971 "target doesn't contain the specified shared library: %s\n",
972 module_file.GetPath().c_str());
976 // No shared libraries, we just want to find globals for the compile
977 // units files that were specified
978 for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
979 target->GetImages().FindCompileUnits(
980 compile_units.GetFileSpecAtIndex(cu_idx), sc_list);
983 const uint32_t num_scs = sc_list.GetSize();
986 for (uint32_t sc_idx = 0; sc_idx < num_scs; ++sc_idx) {
987 if (sc_list.GetContextAtIndex(sc_idx, sc)) {
989 const bool can_create = true;
990 VariableListSP comp_unit_varlist_sp(
991 sc.comp_unit->GetVariableList(can_create));
992 if (comp_unit_varlist_sp)
993 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp,
995 } else if (sc.module_sp) {
996 // Get all global variables for this module
997 lldb_private::RegularExpression all_globals_regex(
999 ".")); // Any global with at least one character
1000 VariableList variable_list;
1001 sc.module_sp->FindGlobalVariables(all_globals_regex, UINT32_MAX,
1003 DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s);
1011 if (m_interpreter.TruncationWarningNecessary()) {
1012 result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(),
1013 m_cmd_name.c_str());
1014 m_interpreter.TruncationWarningGiven();
1017 return result.Succeeded();
1020 OptionGroupOptions m_option_group;
1021 OptionGroupVariable m_option_variable;
1022 OptionGroupFormat m_option_format;
1023 OptionGroupFileList m_option_compile_units;
1024 OptionGroupFileList m_option_shared_libraries;
1025 OptionGroupValueObjectDisplay m_varobj_options;
1028 #pragma mark CommandObjectTargetModulesSearchPathsAdd
1030 class CommandObjectTargetModulesSearchPathsAdd : public CommandObjectParsed {
1032 CommandObjectTargetModulesSearchPathsAdd(CommandInterpreter &interpreter)
1033 : CommandObjectParsed(interpreter, "target modules search-paths add",
1034 "Add new image search paths substitution pairs to "
1035 "the current target.",
1036 nullptr, eCommandRequiresTarget) {
1037 CommandArgumentEntry arg;
1038 CommandArgumentData old_prefix_arg;
1039 CommandArgumentData new_prefix_arg;
1041 // Define the first variant of this arg pair.
1042 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1043 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1045 // Define the first variant of this arg pair.
1046 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1047 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1049 // There are two required arguments that must always occur together, i.e.
1050 // an argument "pair". Because they must always occur together, they are
1051 // treated as two variants of one argument rather than two independent
1052 // arguments. Push them both into the first argument position for
1055 arg.push_back(old_prefix_arg);
1056 arg.push_back(new_prefix_arg);
1058 m_arguments.push_back(arg);
1061 ~CommandObjectTargetModulesSearchPathsAdd() override = default;
1064 bool DoExecute(Args &command, CommandReturnObject &result) override {
1065 Target *target = &GetSelectedTarget();
1066 const size_t argc = command.GetArgumentCount();
1068 result.AppendError("add requires an even number of arguments\n");
1069 result.SetStatus(eReturnStatusFailed);
1071 for (size_t i = 0; i < argc; i += 2) {
1072 const char *from = command.GetArgumentAtIndex(i);
1073 const char *to = command.GetArgumentAtIndex(i + 1);
1075 if (from[0] && to[0]) {
1076 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
1079 "target modules search path adding ImageSearchPath "
1080 "pair: '%s' -> '%s'",
1083 bool last_pair = ((argc - i) == 2);
1084 target->GetImageSearchPathList().Append(
1085 ConstString(from), ConstString(to),
1086 last_pair); // Notify if this is the last pair
1087 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1090 result.AppendError("<path-prefix> can't be empty\n");
1092 result.AppendError("<new-path-prefix> can't be empty\n");
1093 result.SetStatus(eReturnStatusFailed);
1097 return result.Succeeded();
1101 #pragma mark CommandObjectTargetModulesSearchPathsClear
1103 class CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed {
1105 CommandObjectTargetModulesSearchPathsClear(CommandInterpreter &interpreter)
1106 : CommandObjectParsed(interpreter, "target modules search-paths clear",
1107 "Clear all current image search path substitution "
1108 "pairs from the current target.",
1109 "target modules search-paths clear",
1110 eCommandRequiresTarget) {}
1112 ~CommandObjectTargetModulesSearchPathsClear() override = default;
1115 bool DoExecute(Args &command, CommandReturnObject &result) override {
1116 Target *target = &GetSelectedTarget();
1118 target->GetImageSearchPathList().Clear(notify);
1119 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1120 return result.Succeeded();
1124 #pragma mark CommandObjectTargetModulesSearchPathsInsert
1126 class CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed {
1128 CommandObjectTargetModulesSearchPathsInsert(CommandInterpreter &interpreter)
1129 : CommandObjectParsed(interpreter, "target modules search-paths insert",
1130 "Insert a new image search path substitution pair "
1131 "into the current target at the specified index.",
1132 nullptr, eCommandRequiresTarget) {
1133 CommandArgumentEntry arg1;
1134 CommandArgumentEntry arg2;
1135 CommandArgumentData index_arg;
1136 CommandArgumentData old_prefix_arg;
1137 CommandArgumentData new_prefix_arg;
1139 // Define the first and only variant of this arg.
1140 index_arg.arg_type = eArgTypeIndex;
1141 index_arg.arg_repetition = eArgRepeatPlain;
1143 // Put the one and only variant into the first arg for m_arguments:
1144 arg1.push_back(index_arg);
1146 // Define the first variant of this arg pair.
1147 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1148 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1150 // Define the first variant of this arg pair.
1151 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1152 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1154 // There are two required arguments that must always occur together, i.e.
1155 // an argument "pair". Because they must always occur together, they are
1156 // treated as two variants of one argument rather than two independent
1157 // arguments. Push them both into the same argument position for
1160 arg2.push_back(old_prefix_arg);
1161 arg2.push_back(new_prefix_arg);
1163 // Add arguments to m_arguments.
1164 m_arguments.push_back(arg1);
1165 m_arguments.push_back(arg2);
1168 ~CommandObjectTargetModulesSearchPathsInsert() override = default;
1171 bool DoExecute(Args &command, CommandReturnObject &result) override {
1172 Target *target = &GetSelectedTarget();
1173 size_t argc = command.GetArgumentCount();
1174 // check for at least 3 arguments and an odd number of parameters
1175 if (argc >= 3 && argc & 1) {
1176 uint32_t insert_idx;
1178 if (!llvm::to_integer(command.GetArgumentAtIndex(0), insert_idx)) {
1179 result.AppendErrorWithFormat(
1180 "<index> parameter is not an integer: '%s'.\n",
1181 command.GetArgumentAtIndex(0));
1182 result.SetStatus(eReturnStatusFailed);
1183 return result.Succeeded();
1186 // shift off the index
1188 argc = command.GetArgumentCount();
1190 for (uint32_t i = 0; i < argc; i += 2, ++insert_idx) {
1191 const char *from = command.GetArgumentAtIndex(i);
1192 const char *to = command.GetArgumentAtIndex(i + 1);
1194 if (from[0] && to[0]) {
1195 bool last_pair = ((argc - i) == 2);
1196 target->GetImageSearchPathList().Insert(
1197 ConstString(from), ConstString(to), insert_idx, last_pair);
1198 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1201 result.AppendError("<path-prefix> can't be empty\n");
1203 result.AppendError("<new-path-prefix> can't be empty\n");
1204 result.SetStatus(eReturnStatusFailed);
1209 result.AppendError("insert requires at least three arguments\n");
1210 result.SetStatus(eReturnStatusFailed);
1211 return result.Succeeded();
1213 return result.Succeeded();
1217 #pragma mark CommandObjectTargetModulesSearchPathsList
1219 class CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed {
1221 CommandObjectTargetModulesSearchPathsList(CommandInterpreter &interpreter)
1222 : CommandObjectParsed(interpreter, "target modules search-paths list",
1223 "List all current image search path substitution "
1224 "pairs in the current target.",
1225 "target modules search-paths list",
1226 eCommandRequiresTarget) {}
1228 ~CommandObjectTargetModulesSearchPathsList() override = default;
1231 bool DoExecute(Args &command, CommandReturnObject &result) override {
1232 Target *target = &GetSelectedTarget();
1233 if (command.GetArgumentCount() != 0) {
1234 result.AppendError("list takes no arguments\n");
1235 result.SetStatus(eReturnStatusFailed);
1236 return result.Succeeded();
1239 target->GetImageSearchPathList().Dump(&result.GetOutputStream());
1240 result.SetStatus(eReturnStatusSuccessFinishResult);
1241 return result.Succeeded();
1245 #pragma mark CommandObjectTargetModulesSearchPathsQuery
1247 class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed {
1249 CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter &interpreter)
1250 : CommandObjectParsed(
1251 interpreter, "target modules search-paths query",
1252 "Transform a path using the first applicable image search path.",
1253 nullptr, eCommandRequiresTarget) {
1254 CommandArgumentEntry arg;
1255 CommandArgumentData path_arg;
1257 // Define the first (and only) variant of this arg.
1258 path_arg.arg_type = eArgTypeDirectoryName;
1259 path_arg.arg_repetition = eArgRepeatPlain;
1261 // There is only one variant this argument could be; put it into the
1263 arg.push_back(path_arg);
1265 // Push the data for the first argument into the m_arguments vector.
1266 m_arguments.push_back(arg);
1269 ~CommandObjectTargetModulesSearchPathsQuery() override = default;
1272 bool DoExecute(Args &command, CommandReturnObject &result) override {
1273 Target *target = &GetSelectedTarget();
1274 if (command.GetArgumentCount() != 1) {
1275 result.AppendError("query requires one argument\n");
1276 result.SetStatus(eReturnStatusFailed);
1277 return result.Succeeded();
1280 ConstString orig(command.GetArgumentAtIndex(0));
1281 ConstString transformed;
1282 if (target->GetImageSearchPathList().RemapPath(orig, transformed))
1283 result.GetOutputStream().Printf("%s\n", transformed.GetCString());
1285 result.GetOutputStream().Printf("%s\n", orig.GetCString());
1287 result.SetStatus(eReturnStatusSuccessFinishResult);
1288 return result.Succeeded();
1292 // Static Helper functions
1293 static void DumpModuleArchitecture(Stream &strm, Module *module,
1294 bool full_triple, uint32_t width) {
1296 StreamString arch_strm;
1299 module->GetArchitecture().DumpTriple(arch_strm.AsRawOstream());
1301 arch_strm.PutCString(module->GetArchitecture().GetArchitectureName());
1302 std::string arch_str = std::string(arch_strm.GetString());
1305 strm.Printf("%-*s", width, arch_str.c_str());
1307 strm.PutCString(arch_str);
1311 static void DumpModuleUUID(Stream &strm, Module *module) {
1312 if (module && module->GetUUID().IsValid())
1313 module->GetUUID().Dump(&strm);
1315 strm.PutCString(" ");
1318 static uint32_t DumpCompileUnitLineTable(CommandInterpreter &interpreter,
1319 Stream &strm, Module *module,
1320 const FileSpec &file_spec,
1321 lldb::DescriptionLevel desc_level) {
1322 uint32_t num_matches = 0;
1324 SymbolContextList sc_list;
1325 num_matches = module->ResolveSymbolContextsForFileSpec(
1326 file_spec, 0, false, eSymbolContextCompUnit, sc_list);
1328 for (uint32_t i = 0; i < num_matches; ++i) {
1330 if (sc_list.GetContextAtIndex(i, sc)) {
1334 strm << "Line table for " << sc.comp_unit->GetPrimaryFile() << " in `"
1335 << module->GetFileSpec().GetFilename() << "\n";
1336 LineTable *line_table = sc.comp_unit->GetLineTable();
1338 line_table->GetDescription(
1339 &strm, interpreter.GetExecutionContext().GetTargetPtr(),
1342 strm << "No line table";
1349 static void DumpFullpath(Stream &strm, const FileSpec *file_spec_ptr,
1351 if (file_spec_ptr) {
1353 std::string fullpath = file_spec_ptr->GetPath();
1354 strm.Printf("%-*s", width, fullpath.c_str());
1357 file_spec_ptr->Dump(strm.AsRawOstream());
1361 // Keep the width spacing correct if things go wrong...
1363 strm.Printf("%-*s", width, "");
1366 static void DumpDirectory(Stream &strm, const FileSpec *file_spec_ptr,
1368 if (file_spec_ptr) {
1370 strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
1372 file_spec_ptr->GetDirectory().Dump(&strm);
1375 // Keep the width spacing correct if things go wrong...
1377 strm.Printf("%-*s", width, "");
1380 static void DumpBasename(Stream &strm, const FileSpec *file_spec_ptr,
1382 if (file_spec_ptr) {
1384 strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
1386 file_spec_ptr->GetFilename().Dump(&strm);
1389 // Keep the width spacing correct if things go wrong...
1391 strm.Printf("%-*s", width, "");
1394 static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) {
1395 size_t num_dumped = 0;
1396 std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
1397 const size_t num_modules = module_list.GetSize();
1398 if (num_modules > 0) {
1399 strm.Printf("Dumping headers for %" PRIu64 " module(s).\n",
1400 static_cast<uint64_t>(num_modules));
1402 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
1403 Module *module = module_list.GetModulePointerAtIndexUnlocked(image_idx);
1405 if (num_dumped++ > 0) {
1409 ObjectFile *objfile = module->GetObjectFile();
1411 objfile->Dump(&strm);
1413 strm.Format("No object file for module: {0:F}\n",
1414 module->GetFileSpec());
1423 static void DumpModuleSymtab(CommandInterpreter &interpreter, Stream &strm,
1424 Module *module, SortOrder sort_order,
1425 Mangled::NamePreference name_preference) {
1428 if (Symtab *symtab = module->GetSymtab())
1429 symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(),
1430 sort_order, name_preference);
1433 static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm,
1436 SectionList *section_list = module->GetSectionList();
1438 strm.Printf("Sections for '%s' (%s):\n",
1439 module->GetSpecificationDescription().c_str(),
1440 module->GetArchitecture().GetArchitectureName());
1441 section_list->Dump(strm.AsRawOstream(), strm.GetIndentLevel() + 2,
1442 interpreter.GetExecutionContext().GetTargetPtr(), true,
1448 static bool DumpModuleSymbolFile(Stream &strm, Module *module) {
1450 if (SymbolFile *symbol_file = module->GetSymbolFile(true)) {
1451 symbol_file->Dump(strm);
1458 static void DumpAddress(ExecutionContextScope *exe_scope,
1459 const Address &so_addr, bool verbose, Stream &strm) {
1461 strm.Indent(" Address: ");
1462 so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
1463 strm.PutCString(" (");
1464 so_addr.Dump(&strm, exe_scope, Address::DumpStyleSectionNameOffset);
1465 strm.PutCString(")\n");
1466 strm.Indent(" Summary: ");
1467 const uint32_t save_indent = strm.GetIndentLevel();
1468 strm.SetIndentLevel(save_indent + 13);
1469 so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription);
1470 strm.SetIndentLevel(save_indent);
1471 // Print out detailed address information when verbose is enabled
1474 so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext);
1479 static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm,
1480 Module *module, uint32_t resolve_mask,
1481 lldb::addr_t raw_addr, lldb::addr_t offset,
1484 lldb::addr_t addr = raw_addr - offset;
1487 Target *target = interpreter.GetExecutionContext().GetTargetPtr();
1488 if (target && !target->GetSectionLoadList().IsEmpty()) {
1489 if (!target->GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
1491 else if (so_addr.GetModule().get() != module)
1494 if (!module->ResolveFileAddress(addr, so_addr))
1498 ExecutionContextScope *exe_scope =
1499 interpreter.GetExecutionContext().GetBestExecutionContextScope();
1500 DumpAddress(exe_scope, so_addr, verbose, strm);
1501 // strm.IndentMore();
1502 // strm.Indent (" Address: ");
1503 // so_addr.Dump (&strm, exe_scope,
1504 // Address::DumpStyleModuleWithFileAddress);
1505 // strm.PutCString (" (");
1506 // so_addr.Dump (&strm, exe_scope,
1507 // Address::DumpStyleSectionNameOffset);
1508 // strm.PutCString (")\n");
1509 // strm.Indent (" Summary: ");
1510 // const uint32_t save_indent = strm.GetIndentLevel ();
1511 // strm.SetIndentLevel (save_indent + 13);
1512 // so_addr.Dump (&strm, exe_scope,
1513 // Address::DumpStyleResolvedDescription);
1514 // strm.SetIndentLevel (save_indent);
1515 // // Print out detailed address information when verbose is enabled
1519 // so_addr.Dump (&strm, exe_scope,
1520 // Address::DumpStyleDetailedSymbolContext);
1522 // strm.IndentLess();
1529 static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
1530 Stream &strm, Module *module,
1531 const char *name, bool name_is_regex,
1536 Symtab *symtab = module->GetSymtab();
1541 std::vector<uint32_t> match_indexes;
1542 ConstString symbol_name(name);
1543 uint32_t num_matches = 0;
1544 if (name_is_regex) {
1545 RegularExpression name_regexp(symbol_name.GetStringRef());
1546 num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType(
1547 name_regexp, eSymbolTypeAny, match_indexes);
1550 symtab->AppendSymbolIndexesWithName(symbol_name, match_indexes);
1553 if (num_matches > 0) {
1555 strm.Printf("%u symbols match %s'%s' in ", num_matches,
1556 name_is_regex ? "the regular expression " : "", name);
1557 DumpFullpath(strm, &module->GetFileSpec(), 0);
1558 strm.PutCString(":\n");
1560 for (uint32_t i = 0; i < num_matches; ++i) {
1561 Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
1562 if (symbol && symbol->ValueIsAddress()) {
1564 interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1565 symbol->GetAddressRef(), verbose, strm);
1573 static void DumpSymbolContextList(ExecutionContextScope *exe_scope,
1574 Stream &strm, SymbolContextList &sc_list,
1578 const uint32_t num_matches = sc_list.GetSize();
1580 for (uint32_t i = 0; i < num_matches; ++i) {
1582 if (sc_list.GetContextAtIndex(i, sc)) {
1585 sc.GetAddressRange(eSymbolContextEverything, 0, true, range);
1587 DumpAddress(exe_scope, range.GetBaseAddress(), verbose, strm);
1593 static size_t LookupFunctionInModule(CommandInterpreter &interpreter,
1594 Stream &strm, Module *module,
1595 const char *name, bool name_is_regex,
1596 bool include_inlines, bool include_symbols,
1598 if (module && name && name[0]) {
1599 SymbolContextList sc_list;
1600 size_t num_matches = 0;
1601 if (name_is_regex) {
1602 RegularExpression function_name_regex((llvm::StringRef(name)));
1603 module->FindFunctions(function_name_regex, include_symbols,
1604 include_inlines, sc_list);
1606 ConstString function_name(name);
1607 module->FindFunctions(function_name, CompilerDeclContext(),
1608 eFunctionNameTypeAuto, include_symbols,
1609 include_inlines, sc_list);
1611 num_matches = sc_list.GetSize();
1614 strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
1615 num_matches > 1 ? "es" : "");
1616 DumpFullpath(strm, &module->GetFileSpec(), 0);
1617 strm.PutCString(":\n");
1618 DumpSymbolContextList(
1619 interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1620 strm, sc_list, verbose);
1627 static size_t LookupTypeInModule(CommandInterpreter &interpreter, Stream &strm,
1628 Module *module, const char *name_cstr,
1629 bool name_is_regex) {
1631 if (module && name_cstr && name_cstr[0]) {
1632 const uint32_t max_num_matches = UINT32_MAX;
1633 size_t num_matches = 0;
1634 bool name_is_fully_qualified = false;
1636 ConstString name(name_cstr);
1637 llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
1638 module->FindTypes(name, name_is_fully_qualified, max_num_matches,
1639 searched_symbol_files, type_list);
1641 if (type_list.Empty())
1645 strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
1646 num_matches > 1 ? "es" : "");
1647 DumpFullpath(strm, &module->GetFileSpec(), 0);
1648 strm.PutCString(":\n");
1649 for (TypeSP type_sp : type_list.Types()) {
1652 // Resolve the clang type so that any forward references to types
1653 // that haven't yet been parsed will get parsed.
1654 type_sp->GetFullCompilerType();
1655 type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
1656 // Print all typedef chains
1657 TypeSP typedef_type_sp(type_sp);
1658 TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1659 while (typedefed_type_sp) {
1661 strm.Printf(" typedef '%s': ",
1662 typedef_type_sp->GetName().GetCString());
1663 typedefed_type_sp->GetFullCompilerType();
1664 typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
1665 typedef_type_sp = typedefed_type_sp;
1666 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1671 return type_list.GetSize();
1674 static size_t LookupTypeHere(CommandInterpreter &interpreter, Stream &strm,
1675 Module &module, const char *name_cstr,
1676 bool name_is_regex) {
1678 const uint32_t max_num_matches = UINT32_MAX;
1679 bool name_is_fully_qualified = false;
1681 ConstString name(name_cstr);
1682 llvm::DenseSet<SymbolFile *> searched_symbol_files;
1683 module.FindTypes(name, name_is_fully_qualified, max_num_matches,
1684 searched_symbol_files, type_list);
1686 if (type_list.Empty())
1690 strm.PutCString("Best match found in ");
1691 DumpFullpath(strm, &module.GetFileSpec(), 0);
1692 strm.PutCString(":\n");
1694 TypeSP type_sp(type_list.GetTypeAtIndex(0));
1696 // Resolve the clang type so that any forward references to types that
1697 // haven't yet been parsed will get parsed.
1698 type_sp->GetFullCompilerType();
1699 type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
1700 // Print all typedef chains
1701 TypeSP typedef_type_sp(type_sp);
1702 TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1703 while (typedefed_type_sp) {
1705 strm.Printf(" typedef '%s': ",
1706 typedef_type_sp->GetName().GetCString());
1707 typedefed_type_sp->GetFullCompilerType();
1708 typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
1709 typedef_type_sp = typedefed_type_sp;
1710 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1714 return type_list.GetSize();
1717 static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter,
1718 Stream &strm, Module *module,
1719 const FileSpec &file_spec,
1720 uint32_t line, bool check_inlines,
1722 if (module && file_spec) {
1723 SymbolContextList sc_list;
1724 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(
1725 file_spec, line, check_inlines, eSymbolContextEverything, sc_list);
1726 if (num_matches > 0) {
1728 strm.Printf("%u match%s found in ", num_matches,
1729 num_matches > 1 ? "es" : "");
1732 strm.Printf(":%u", line);
1734 DumpFullpath(strm, &module->GetFileSpec(), 0);
1735 strm.PutCString(":\n");
1736 DumpSymbolContextList(
1737 interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1738 strm, sc_list, verbose);
1745 static size_t FindModulesByName(Target *target, const char *module_name,
1746 ModuleList &module_list,
1747 bool check_global_list) {
1748 FileSpec module_file_spec(module_name);
1749 ModuleSpec module_spec(module_file_spec);
1751 const size_t initial_size = module_list.GetSize();
1753 if (check_global_list) {
1754 // Check the global list
1755 std::lock_guard<std::recursive_mutex> guard(
1756 Module::GetAllocationModuleCollectionMutex());
1757 const size_t num_modules = Module::GetNumberAllocatedModules();
1759 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
1760 Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
1763 if (module->MatchesModuleSpec(module_spec)) {
1764 module_sp = module->shared_from_this();
1765 module_list.AppendIfNeeded(module_sp);
1771 target->GetImages().FindModules(module_spec, module_list);
1772 const size_t num_matches = module_list.GetSize();
1774 // Not found in our module list for our target, check the main shared
1775 // module list in case it is a extra file used somewhere else
1776 if (num_matches == 0) {
1777 module_spec.GetArchitecture() = target->GetArchitecture();
1778 ModuleList::FindSharedModules(module_spec, module_list);
1781 ModuleList::FindSharedModules(module_spec, module_list);
1785 return module_list.GetSize() - initial_size;
1788 #pragma mark CommandObjectTargetModulesModuleAutoComplete
1790 // A base command object class that can auto complete with module file
1793 class CommandObjectTargetModulesModuleAutoComplete
1794 : public CommandObjectParsed {
1796 CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter &interpreter,
1801 : CommandObjectParsed(interpreter, name, help, syntax, flags) {
1802 CommandArgumentEntry arg;
1803 CommandArgumentData file_arg;
1805 // Define the first (and only) variant of this arg.
1806 file_arg.arg_type = eArgTypeFilename;
1807 file_arg.arg_repetition = eArgRepeatStar;
1809 // There is only one variant this argument could be; put it into the
1811 arg.push_back(file_arg);
1813 // Push the data for the first argument into the m_arguments vector.
1814 m_arguments.push_back(arg);
1817 ~CommandObjectTargetModulesModuleAutoComplete() override = default;
1820 HandleArgumentCompletion(CompletionRequest &request,
1821 OptionElementVector &opt_element_vector) override {
1822 CommandCompletions::InvokeCommonCompletionCallbacks(
1823 GetCommandInterpreter(), CommandCompletions::eModuleCompletion, request,
1828 #pragma mark CommandObjectTargetModulesSourceFileAutoComplete
1830 // A base command object class that can auto complete with module source
1833 class CommandObjectTargetModulesSourceFileAutoComplete
1834 : public CommandObjectParsed {
1836 CommandObjectTargetModulesSourceFileAutoComplete(
1837 CommandInterpreter &interpreter, const char *name, const char *help,
1838 const char *syntax, uint32_t flags)
1839 : CommandObjectParsed(interpreter, name, help, syntax, flags) {
1840 CommandArgumentEntry arg;
1841 CommandArgumentData source_file_arg;
1843 // Define the first (and only) variant of this arg.
1844 source_file_arg.arg_type = eArgTypeSourceFile;
1845 source_file_arg.arg_repetition = eArgRepeatPlus;
1847 // There is only one variant this argument could be; put it into the
1849 arg.push_back(source_file_arg);
1851 // Push the data for the first argument into the m_arguments vector.
1852 m_arguments.push_back(arg);
1855 ~CommandObjectTargetModulesSourceFileAutoComplete() override = default;
1858 HandleArgumentCompletion(CompletionRequest &request,
1859 OptionElementVector &opt_element_vector) override {
1860 CommandCompletions::InvokeCommonCompletionCallbacks(
1861 GetCommandInterpreter(), CommandCompletions::eSourceFileCompletion,
1866 #pragma mark CommandObjectTargetModulesDumpObjfile
1868 class CommandObjectTargetModulesDumpObjfile
1869 : public CommandObjectTargetModulesModuleAutoComplete {
1871 CommandObjectTargetModulesDumpObjfile(CommandInterpreter &interpreter)
1872 : CommandObjectTargetModulesModuleAutoComplete(
1873 interpreter, "target modules dump objfile",
1874 "Dump the object file headers from one or more target modules.",
1875 nullptr, eCommandRequiresTarget) {}
1877 ~CommandObjectTargetModulesDumpObjfile() override = default;
1880 bool DoExecute(Args &command, CommandReturnObject &result) override {
1881 Target *target = &GetSelectedTarget();
1883 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1884 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1885 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1887 size_t num_dumped = 0;
1888 if (command.GetArgumentCount() == 0) {
1889 // Dump all headers for all modules images
1890 num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(),
1891 target->GetImages());
1892 if (num_dumped == 0) {
1893 result.AppendError("the target has no associated executable images");
1894 result.SetStatus(eReturnStatusFailed);
1897 // Find the modules that match the basename or full path.
1898 ModuleList module_list;
1899 const char *arg_cstr;
1900 for (int arg_idx = 0;
1901 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
1903 size_t num_matched =
1904 FindModulesByName(target, arg_cstr, module_list, true);
1905 if (num_matched == 0) {
1906 result.AppendWarningWithFormat(
1907 "Unable to find an image that matches '%s'.\n", arg_cstr);
1910 // Dump all the modules we found.
1912 DumpModuleObjfileHeaders(result.GetOutputStream(), module_list);
1915 if (num_dumped > 0) {
1916 result.SetStatus(eReturnStatusSuccessFinishResult);
1918 result.AppendError("no matching executable images found");
1919 result.SetStatus(eReturnStatusFailed);
1921 return result.Succeeded();
1925 #pragma mark CommandObjectTargetModulesDumpSymtab
1927 static constexpr OptionEnumValueElement g_sort_option_enumeration[] = {
1931 "No sorting, use the original symbol table order.",
1934 eSortOrderByAddress,
1936 "Sort output by symbol address.",
1941 "Sort output by symbol name.",
1945 #define LLDB_OPTIONS_target_modules_dump_symtab
1946 #include "CommandOptions.inc"
1948 class CommandObjectTargetModulesDumpSymtab
1949 : public CommandObjectTargetModulesModuleAutoComplete {
1951 CommandObjectTargetModulesDumpSymtab(CommandInterpreter &interpreter)
1952 : CommandObjectTargetModulesModuleAutoComplete(
1953 interpreter, "target modules dump symtab",
1954 "Dump the symbol table from one or more target modules.", nullptr,
1955 eCommandRequiresTarget),
1958 ~CommandObjectTargetModulesDumpSymtab() override = default;
1960 Options *GetOptions() override { return &m_options; }
1962 class CommandOptions : public Options {
1964 CommandOptions() : Options(), m_sort_order(eSortOrderNone) {}
1966 ~CommandOptions() override = default;
1968 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1969 ExecutionContext *execution_context) override {
1971 const int short_option = m_getopt_table[option_idx].val;
1973 switch (short_option) {
1975 m_prefer_mangled.SetCurrentValue(true);
1976 m_prefer_mangled.SetOptionWasSet();
1980 m_sort_order = (SortOrder)OptionArgParser::ToOptionEnum(
1981 option_arg, GetDefinitions()[option_idx].enum_values,
1982 eSortOrderNone, error);
1986 llvm_unreachable("Unimplemented option");
1991 void OptionParsingStarting(ExecutionContext *execution_context) override {
1992 m_sort_order = eSortOrderNone;
1993 m_prefer_mangled.Clear();
1996 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1997 return llvm::makeArrayRef(g_target_modules_dump_symtab_options);
2000 SortOrder m_sort_order;
2001 OptionValueBoolean m_prefer_mangled = {false, false};
2005 bool DoExecute(Args &command, CommandReturnObject &result) override {
2006 Target *target = &GetSelectedTarget();
2007 uint32_t num_dumped = 0;
2008 Mangled::NamePreference name_preference =
2009 (m_options.m_prefer_mangled ? Mangled::ePreferMangled
2010 : Mangled::ePreferDemangled);
2012 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2013 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2014 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2016 if (command.GetArgumentCount() == 0) {
2017 // Dump all sections for all modules images
2018 std::lock_guard<std::recursive_mutex> guard(
2019 target->GetImages().GetMutex());
2020 const size_t num_modules = target->GetImages().GetSize();
2021 if (num_modules > 0) {
2022 result.GetOutputStream().Printf("Dumping symbol table for %" PRIu64
2024 (uint64_t)num_modules);
2025 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2026 if (num_dumped > 0) {
2027 result.GetOutputStream().EOL();
2028 result.GetOutputStream().EOL();
2030 if (m_interpreter.WasInterrupted())
2034 m_interpreter, result.GetOutputStream(),
2035 target->GetImages().GetModulePointerAtIndexUnlocked(image_idx),
2036 m_options.m_sort_order, name_preference);
2039 result.AppendError("the target has no associated executable images");
2040 result.SetStatus(eReturnStatusFailed);
2044 // Dump specified images (by basename or fullpath)
2045 const char *arg_cstr;
2046 for (int arg_idx = 0;
2047 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2049 ModuleList module_list;
2050 const size_t num_matches =
2051 FindModulesByName(target, arg_cstr, module_list, true);
2052 if (num_matches > 0) {
2053 for (size_t i = 0; i < num_matches; ++i) {
2054 Module *module = module_list.GetModulePointerAtIndex(i);
2056 if (num_dumped > 0) {
2057 result.GetOutputStream().EOL();
2058 result.GetOutputStream().EOL();
2060 if (m_interpreter.WasInterrupted())
2063 DumpModuleSymtab(m_interpreter, result.GetOutputStream(), module,
2064 m_options.m_sort_order, name_preference);
2068 result.AppendWarningWithFormat(
2069 "Unable to find an image that matches '%s'.\n", arg_cstr);
2074 result.SetStatus(eReturnStatusSuccessFinishResult);
2076 result.AppendError("no matching executable images found");
2077 result.SetStatus(eReturnStatusFailed);
2079 return result.Succeeded();
2082 CommandOptions m_options;
2085 #pragma mark CommandObjectTargetModulesDumpSections
2087 // Image section dumping command
2089 class CommandObjectTargetModulesDumpSections
2090 : public CommandObjectTargetModulesModuleAutoComplete {
2092 CommandObjectTargetModulesDumpSections(CommandInterpreter &interpreter)
2093 : CommandObjectTargetModulesModuleAutoComplete(
2094 interpreter, "target modules dump sections",
2095 "Dump the sections from one or more target modules.",
2096 //"target modules dump sections [<file1> ...]")
2097 nullptr, eCommandRequiresTarget) {}
2099 ~CommandObjectTargetModulesDumpSections() override = default;
2102 bool DoExecute(Args &command, CommandReturnObject &result) override {
2103 Target *target = &GetSelectedTarget();
2104 uint32_t num_dumped = 0;
2106 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2107 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2108 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2110 if (command.GetArgumentCount() == 0) {
2111 // Dump all sections for all modules images
2112 const size_t num_modules = target->GetImages().GetSize();
2113 if (num_modules > 0) {
2114 result.GetOutputStream().Printf("Dumping sections for %" PRIu64
2116 (uint64_t)num_modules);
2117 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2118 if (m_interpreter.WasInterrupted())
2122 m_interpreter, result.GetOutputStream(),
2123 target->GetImages().GetModulePointerAtIndex(image_idx));
2126 result.AppendError("the target has no associated executable images");
2127 result.SetStatus(eReturnStatusFailed);
2131 // Dump specified images (by basename or fullpath)
2132 const char *arg_cstr;
2133 for (int arg_idx = 0;
2134 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2136 ModuleList module_list;
2137 const size_t num_matches =
2138 FindModulesByName(target, arg_cstr, module_list, true);
2139 if (num_matches > 0) {
2140 for (size_t i = 0; i < num_matches; ++i) {
2141 if (m_interpreter.WasInterrupted())
2143 Module *module = module_list.GetModulePointerAtIndex(i);
2146 DumpModuleSections(m_interpreter, result.GetOutputStream(),
2151 // Check the global list
2152 std::lock_guard<std::recursive_mutex> guard(
2153 Module::GetAllocationModuleCollectionMutex());
2155 result.AppendWarningWithFormat(
2156 "Unable to find an image that matches '%s'.\n", arg_cstr);
2162 result.SetStatus(eReturnStatusSuccessFinishResult);
2164 result.AppendError("no matching executable images found");
2165 result.SetStatus(eReturnStatusFailed);
2167 return result.Succeeded();
2171 #pragma mark CommandObjectTargetModulesDumpClangAST
2173 // Clang AST dumping command
2175 class CommandObjectTargetModulesDumpClangAST
2176 : public CommandObjectTargetModulesModuleAutoComplete {
2178 CommandObjectTargetModulesDumpClangAST(CommandInterpreter &interpreter)
2179 : CommandObjectTargetModulesModuleAutoComplete(
2180 interpreter, "target modules dump ast",
2181 "Dump the clang ast for a given module's symbol file.",
2182 //"target modules dump ast [<file1> ...]")
2183 nullptr, eCommandRequiresTarget) {}
2185 ~CommandObjectTargetModulesDumpClangAST() override = default;
2188 bool DoExecute(Args &command, CommandReturnObject &result) override {
2189 Target *target = &GetSelectedTarget();
2191 const size_t num_modules = target->GetImages().GetSize();
2192 if (num_modules == 0) {
2193 result.AppendError("the target has no associated executable images");
2194 result.SetStatus(eReturnStatusFailed);
2198 if (command.GetArgumentCount() == 0) {
2199 // Dump all ASTs for all modules images
2200 result.GetOutputStream().Printf("Dumping clang ast for %" PRIu64
2202 (uint64_t)num_modules);
2203 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2204 if (m_interpreter.WasInterrupted())
2206 Module *m = target->GetImages().GetModulePointerAtIndex(image_idx);
2207 if (SymbolFile *sf = m->GetSymbolFile())
2208 sf->DumpClangAST(result.GetOutputStream());
2210 result.SetStatus(eReturnStatusSuccessFinishResult);
2214 // Dump specified ASTs (by basename or fullpath)
2215 for (const Args::ArgEntry &arg : command.entries()) {
2216 ModuleList module_list;
2217 const size_t num_matches =
2218 FindModulesByName(target, arg.c_str(), module_list, true);
2219 if (num_matches == 0) {
2220 // Check the global list
2221 std::lock_guard<std::recursive_mutex> guard(
2222 Module::GetAllocationModuleCollectionMutex());
2224 result.AppendWarningWithFormat(
2225 "Unable to find an image that matches '%s'.\n", arg.c_str());
2229 for (size_t i = 0; i < num_matches; ++i) {
2230 if (m_interpreter.WasInterrupted())
2232 Module *m = module_list.GetModulePointerAtIndex(i);
2233 if (SymbolFile *sf = m->GetSymbolFile())
2234 sf->DumpClangAST(result.GetOutputStream());
2237 result.SetStatus(eReturnStatusSuccessFinishResult);
2242 #pragma mark CommandObjectTargetModulesDumpSymfile
2244 // Image debug symbol dumping command
2246 class CommandObjectTargetModulesDumpSymfile
2247 : public CommandObjectTargetModulesModuleAutoComplete {
2249 CommandObjectTargetModulesDumpSymfile(CommandInterpreter &interpreter)
2250 : CommandObjectTargetModulesModuleAutoComplete(
2251 interpreter, "target modules dump symfile",
2252 "Dump the debug symbol file for one or more target modules.",
2253 //"target modules dump symfile [<file1> ...]")
2254 nullptr, eCommandRequiresTarget) {}
2256 ~CommandObjectTargetModulesDumpSymfile() override = default;
2259 bool DoExecute(Args &command, CommandReturnObject &result) override {
2260 Target *target = &GetSelectedTarget();
2261 uint32_t num_dumped = 0;
2263 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2264 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2265 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2267 if (command.GetArgumentCount() == 0) {
2268 // Dump all sections for all modules images
2269 const ModuleList &target_modules = target->GetImages();
2270 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2271 const size_t num_modules = target_modules.GetSize();
2272 if (num_modules > 0) {
2273 result.GetOutputStream().Printf("Dumping debug symbols for %" PRIu64
2275 (uint64_t)num_modules);
2276 for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2277 if (m_interpreter.WasInterrupted())
2279 if (DumpModuleSymbolFile(
2280 result.GetOutputStream(),
2281 target_modules.GetModulePointerAtIndexUnlocked(image_idx)))
2285 result.AppendError("the target has no associated executable images");
2286 result.SetStatus(eReturnStatusFailed);
2290 // Dump specified images (by basename or fullpath)
2291 const char *arg_cstr;
2292 for (int arg_idx = 0;
2293 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2295 ModuleList module_list;
2296 const size_t num_matches =
2297 FindModulesByName(target, arg_cstr, module_list, true);
2298 if (num_matches > 0) {
2299 for (size_t i = 0; i < num_matches; ++i) {
2300 if (m_interpreter.WasInterrupted())
2302 Module *module = module_list.GetModulePointerAtIndex(i);
2304 if (DumpModuleSymbolFile(result.GetOutputStream(), module))
2309 result.AppendWarningWithFormat(
2310 "Unable to find an image that matches '%s'.\n", arg_cstr);
2315 result.SetStatus(eReturnStatusSuccessFinishResult);
2317 result.AppendError("no matching executable images found");
2318 result.SetStatus(eReturnStatusFailed);
2320 return result.Succeeded();
2324 #pragma mark CommandObjectTargetModulesDumpLineTable
2325 #define LLDB_OPTIONS_target_modules_dump
2326 #include "CommandOptions.inc"
2328 // Image debug line table dumping command
2330 class CommandObjectTargetModulesDumpLineTable
2331 : public CommandObjectTargetModulesSourceFileAutoComplete {
2333 CommandObjectTargetModulesDumpLineTable(CommandInterpreter &interpreter)
2334 : CommandObjectTargetModulesSourceFileAutoComplete(
2335 interpreter, "target modules dump line-table",
2336 "Dump the line table for one or more compilation units.", nullptr,
2337 eCommandRequiresTarget) {}
2339 ~CommandObjectTargetModulesDumpLineTable() override = default;
2341 Options *GetOptions() override { return &m_options; }
2344 bool DoExecute(Args &command, CommandReturnObject &result) override {
2345 Target *target = m_exe_ctx.GetTargetPtr();
2346 uint32_t total_num_dumped = 0;
2348 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2349 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2350 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2352 if (command.GetArgumentCount() == 0) {
2353 result.AppendError("file option must be specified.");
2354 result.SetStatus(eReturnStatusFailed);
2355 return result.Succeeded();
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 FileSpec file_spec(arg_cstr);
2364 const ModuleList &target_modules = target->GetImages();
2365 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2366 const size_t num_modules = target_modules.GetSize();
2367 if (num_modules > 0) {
2368 uint32_t num_dumped = 0;
2369 for (uint32_t i = 0; i < num_modules; ++i) {
2370 if (m_interpreter.WasInterrupted())
2372 if (DumpCompileUnitLineTable(
2373 m_interpreter, result.GetOutputStream(),
2374 target_modules.GetModulePointerAtIndexUnlocked(i),
2376 m_options.m_verbose ? eDescriptionLevelFull
2377 : eDescriptionLevelBrief))
2380 if (num_dumped == 0)
2381 result.AppendWarningWithFormat(
2382 "No source filenames matched '%s'.\n", arg_cstr);
2384 total_num_dumped += num_dumped;
2389 if (total_num_dumped > 0)
2390 result.SetStatus(eReturnStatusSuccessFinishResult);
2392 result.AppendError("no source filenames matched any command arguments");
2393 result.SetStatus(eReturnStatusFailed);
2395 return result.Succeeded();
2398 class CommandOptions : public Options {
2400 CommandOptions() : Options() { OptionParsingStarting(nullptr); }
2402 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2403 ExecutionContext *execution_context) override {
2404 assert(option_idx == 0 && "We only have one option.");
2410 void OptionParsingStarting(ExecutionContext *execution_context) override {
2414 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2415 return llvm::makeArrayRef(g_target_modules_dump_options);
2421 CommandOptions m_options;
2424 #pragma mark CommandObjectTargetModulesDump
2426 // Dump multi-word command for target modules
2428 class CommandObjectTargetModulesDump : public CommandObjectMultiword {
2430 // Constructors and Destructors
2431 CommandObjectTargetModulesDump(CommandInterpreter &interpreter)
2432 : CommandObjectMultiword(
2433 interpreter, "target modules dump",
2434 "Commands for dumping information about one or "
2435 "more target modules.",
2436 "target modules dump "
2437 "[headers|symtab|sections|ast|symfile|line-table] "
2438 "[<file1> <file2> ...]") {
2439 LoadSubCommand("objfile",
2441 new CommandObjectTargetModulesDumpObjfile(interpreter)));
2444 CommandObjectSP(new CommandObjectTargetModulesDumpSymtab(interpreter)));
2445 LoadSubCommand("sections",
2446 CommandObjectSP(new CommandObjectTargetModulesDumpSections(
2448 LoadSubCommand("symfile",
2450 new CommandObjectTargetModulesDumpSymfile(interpreter)));
2452 "ast", CommandObjectSP(
2453 new CommandObjectTargetModulesDumpClangAST(interpreter)));
2454 LoadSubCommand("line-table",
2455 CommandObjectSP(new CommandObjectTargetModulesDumpLineTable(
2459 ~CommandObjectTargetModulesDump() override = default;
2462 class CommandObjectTargetModulesAdd : public CommandObjectParsed {
2464 CommandObjectTargetModulesAdd(CommandInterpreter &interpreter)
2465 : CommandObjectParsed(interpreter, "target modules add",
2466 "Add a new module to the current target's modules.",
2467 "target modules add [<module>]",
2468 eCommandRequiresTarget),
2469 m_option_group(), m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's',
2470 0, eArgTypeFilename,
2471 "Fullpath to a stand alone debug "
2472 "symbols file for when debug symbols "
2473 "are not in the executable.") {
2474 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
2476 m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2477 m_option_group.Finalize();
2480 ~CommandObjectTargetModulesAdd() override = default;
2482 Options *GetOptions() override { return &m_option_group; }
2485 HandleArgumentCompletion(CompletionRequest &request,
2486 OptionElementVector &opt_element_vector) override {
2487 CommandCompletions::InvokeCommonCompletionCallbacks(
2488 GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
2493 OptionGroupOptions m_option_group;
2494 OptionGroupUUID m_uuid_option_group;
2495 OptionGroupFile m_symbol_file;
2497 bool DoExecute(Args &args, CommandReturnObject &result) override {
2498 Target *target = &GetSelectedTarget();
2501 const size_t argc = args.GetArgumentCount();
2503 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2504 // We are given a UUID only, go locate the file
2505 ModuleSpec module_spec;
2506 module_spec.GetUUID() =
2507 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2508 if (m_symbol_file.GetOptionValue().OptionWasSet())
2509 module_spec.GetSymbolFileSpec() =
2510 m_symbol_file.GetOptionValue().GetCurrentValue();
2511 if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
2513 target->GetOrCreateModule(module_spec, true /* notify */));
2515 result.SetStatus(eReturnStatusSuccessFinishResult);
2519 module_spec.GetUUID().Dump(&strm);
2520 if (module_spec.GetFileSpec()) {
2521 if (module_spec.GetSymbolFileSpec()) {
2522 result.AppendErrorWithFormat(
2523 "Unable to create the executable or symbol file with "
2524 "UUID %s with path %s and symbol file %s",
2525 strm.GetData(), module_spec.GetFileSpec().GetPath().c_str(),
2526 module_spec.GetSymbolFileSpec().GetPath().c_str());
2528 result.AppendErrorWithFormat(
2529 "Unable to create the executable or symbol file with "
2530 "UUID %s with path %s",
2532 module_spec.GetFileSpec().GetPath().c_str());
2535 result.AppendErrorWithFormat("Unable to create the executable "
2536 "or symbol file with UUID %s",
2539 result.SetStatus(eReturnStatusFailed);
2544 module_spec.GetUUID().Dump(&strm);
2545 result.AppendErrorWithFormat(
2546 "Unable to locate the executable or symbol file with UUID %s",
2548 result.SetStatus(eReturnStatusFailed);
2553 "one or more executable image paths must be specified");
2554 result.SetStatus(eReturnStatusFailed);
2558 for (auto &entry : args.entries()) {
2559 if (entry.ref().empty())
2562 FileSpec file_spec(entry.ref());
2563 if (FileSystem::Instance().Exists(file_spec)) {
2564 ModuleSpec module_spec(file_spec);
2565 if (m_uuid_option_group.GetOptionValue().OptionWasSet())
2566 module_spec.GetUUID() =
2567 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2568 if (m_symbol_file.GetOptionValue().OptionWasSet())
2569 module_spec.GetSymbolFileSpec() =
2570 m_symbol_file.GetOptionValue().GetCurrentValue();
2571 if (!module_spec.GetArchitecture().IsValid())
2572 module_spec.GetArchitecture() = target->GetArchitecture();
2574 ModuleSP module_sp(target->GetOrCreateModule(
2575 module_spec, true /* notify */, &error));
2577 const char *error_cstr = error.AsCString();
2579 result.AppendError(error_cstr);
2581 result.AppendErrorWithFormat("unsupported module: %s",
2583 result.SetStatus(eReturnStatusFailed);
2588 result.SetStatus(eReturnStatusSuccessFinishResult);
2590 std::string resolved_path = file_spec.GetPath();
2591 result.SetStatus(eReturnStatusFailed);
2592 if (resolved_path != entry.ref()) {
2593 result.AppendErrorWithFormat(
2594 "invalid module path '%s' with resolved path '%s'\n",
2595 entry.ref().str().c_str(), resolved_path.c_str());
2598 result.AppendErrorWithFormat("invalid module path '%s'\n",
2606 ProcessSP process = target->GetProcessSP();
2611 return result.Succeeded();
2615 class CommandObjectTargetModulesLoad
2616 : public CommandObjectTargetModulesModuleAutoComplete {
2618 CommandObjectTargetModulesLoad(CommandInterpreter &interpreter)
2619 : CommandObjectTargetModulesModuleAutoComplete(
2620 interpreter, "target modules load",
2621 "Set the load addresses for one or more sections in a target "
2623 "target modules load [--file <module> --uuid <uuid>] <sect-name> "
2624 "<address> [<sect-name> <address> ....]",
2625 eCommandRequiresTarget),
2627 m_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName,
2628 "Fullpath or basename for module to load.", ""),
2629 m_load_option(LLDB_OPT_SET_1, false, "load", 'l',
2630 "Write file contents to the memory.", false, true),
2631 m_pc_option(LLDB_OPT_SET_1, false, "set-pc-to-entry", 'p',
2632 "Set PC to the entry point."
2633 " Only applicable with '--load' option.",
2635 m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset,
2636 "Set the load address for all sections to be the "
2637 "virtual address in the file plus the offset.",
2639 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
2641 m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2642 m_option_group.Append(&m_load_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2643 m_option_group.Append(&m_pc_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2644 m_option_group.Append(&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2645 m_option_group.Finalize();
2648 ~CommandObjectTargetModulesLoad() override = default;
2650 Options *GetOptions() override { return &m_option_group; }
2653 bool DoExecute(Args &args, CommandReturnObject &result) override {
2654 Target *target = &GetSelectedTarget();
2655 const bool load = m_load_option.GetOptionValue().GetCurrentValue();
2656 const bool set_pc = m_pc_option.GetOptionValue().GetCurrentValue();
2658 const size_t argc = args.GetArgumentCount();
2659 ModuleSpec module_spec;
2660 bool search_using_module_spec = false;
2662 // Allow "load" option to work without --file or --uuid option.
2664 if (!m_file_option.GetOptionValue().OptionWasSet() &&
2665 !m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2666 ModuleList &module_list = target->GetImages();
2667 if (module_list.GetSize() == 1) {
2668 search_using_module_spec = true;
2669 module_spec.GetFileSpec() =
2670 module_list.GetModuleAtIndex(0)->GetFileSpec();
2675 if (m_file_option.GetOptionValue().OptionWasSet()) {
2676 search_using_module_spec = true;
2677 const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
2678 const bool use_global_module_list = true;
2679 ModuleList module_list;
2680 const size_t num_matches = FindModulesByName(
2681 target, arg_cstr, module_list, use_global_module_list);
2682 if (num_matches == 1) {
2683 module_spec.GetFileSpec() =
2684 module_list.GetModuleAtIndex(0)->GetFileSpec();
2685 } else if (num_matches > 1) {
2686 search_using_module_spec = false;
2687 result.AppendErrorWithFormat(
2688 "more than 1 module matched by name '%s'\n", arg_cstr);
2689 result.SetStatus(eReturnStatusFailed);
2691 search_using_module_spec = false;
2692 result.AppendErrorWithFormat("no object file for module '%s'\n",
2694 result.SetStatus(eReturnStatusFailed);
2698 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2699 search_using_module_spec = true;
2700 module_spec.GetUUID() =
2701 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2704 if (search_using_module_spec) {
2705 ModuleList matching_modules;
2706 target->GetImages().FindModules(module_spec, matching_modules);
2707 const size_t num_matches = matching_modules.GetSize();
2709 char path[PATH_MAX];
2710 if (num_matches == 1) {
2711 Module *module = matching_modules.GetModulePointerAtIndex(0);
2713 ObjectFile *objfile = module->GetObjectFile();
2715 SectionList *section_list = module->GetSectionList();
2717 bool changed = false;
2719 if (m_slide_option.GetOptionValue().OptionWasSet()) {
2720 const addr_t slide =
2721 m_slide_option.GetOptionValue().GetCurrentValue();
2722 const bool slide_is_offset = true;
2723 module->SetLoadAddress(*target, slide, slide_is_offset,
2726 result.AppendError("one or more section name + load "
2727 "address pair must be specified");
2728 result.SetStatus(eReturnStatusFailed);
2732 if (m_slide_option.GetOptionValue().OptionWasSet()) {
2733 result.AppendError("The \"--slide <offset>\" option can't "
2734 "be used in conjunction with setting "
2735 "section load addresses.\n");
2736 result.SetStatus(eReturnStatusFailed);
2740 for (size_t i = 0; i < argc; i += 2) {
2741 const char *sect_name = args.GetArgumentAtIndex(i);
2742 const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1);
2743 if (sect_name && load_addr_cstr) {
2744 ConstString const_sect_name(sect_name);
2746 if (llvm::to_integer(load_addr_cstr, load_addr)) {
2747 SectionSP section_sp(
2748 section_list->FindSectionByName(const_sect_name));
2750 if (section_sp->IsThreadSpecific()) {
2751 result.AppendErrorWithFormat(
2752 "thread specific sections are not yet "
2753 "supported (section '%s')\n",
2755 result.SetStatus(eReturnStatusFailed);
2758 if (target->GetSectionLoadList()
2759 .SetSectionLoadAddress(section_sp, load_addr))
2761 result.AppendMessageWithFormat(
2762 "section '%s' loaded at 0x%" PRIx64 "\n",
2763 sect_name, load_addr);
2766 result.AppendErrorWithFormat("no section found that "
2767 "matches the section "
2770 result.SetStatus(eReturnStatusFailed);
2774 result.AppendErrorWithFormat(
2775 "invalid load address string '%s'\n", load_addr_cstr);
2776 result.SetStatus(eReturnStatusFailed);
2781 result.AppendError("section names must be followed by "
2782 "a load address.\n");
2784 result.AppendError("one or more section name + load "
2785 "address pair must be specified.\n");
2786 result.SetStatus(eReturnStatusFailed);
2793 target->ModulesDidLoad(matching_modules);
2794 Process *process = m_exe_ctx.GetProcessPtr();
2799 ProcessSP process = target->CalculateProcess();
2800 Address file_entry = objfile->GetEntryPointAddress();
2802 result.AppendError("No process");
2805 if (set_pc && !file_entry.IsValid()) {
2806 result.AppendError("No entry address in object file");
2809 std::vector<ObjectFile::LoadableData> loadables(
2810 objfile->GetLoadableData(*target));
2811 if (loadables.size() == 0) {
2812 result.AppendError("No loadable sections");
2815 Status error = process->WriteObjectFile(std::move(loadables));
2817 result.AppendError(error.AsCString());
2821 ThreadList &thread_list = process->GetThreadList();
2822 RegisterContextSP reg_context(
2823 thread_list.GetSelectedThread()->GetRegisterContext());
2824 addr_t file_entry_addr = file_entry.GetLoadAddress(target);
2825 if (!reg_context->SetPC(file_entry_addr)) {
2826 result.AppendErrorWithFormat("failed to set PC value to "
2829 result.SetStatus(eReturnStatusFailed);
2834 module->GetFileSpec().GetPath(path, sizeof(path));
2835 result.AppendErrorWithFormat("no sections in object file '%s'\n",
2837 result.SetStatus(eReturnStatusFailed);
2840 module->GetFileSpec().GetPath(path, sizeof(path));
2841 result.AppendErrorWithFormat("no object file for module '%s'\n",
2843 result.SetStatus(eReturnStatusFailed);
2846 FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
2847 if (module_spec_file) {
2848 module_spec_file->GetPath(path, sizeof(path));
2849 result.AppendErrorWithFormat("invalid module '%s'.\n", path);
2851 result.AppendError("no module spec");
2852 result.SetStatus(eReturnStatusFailed);
2855 std::string uuid_str;
2857 if (module_spec.GetFileSpec())
2858 module_spec.GetFileSpec().GetPath(path, sizeof(path));
2862 if (module_spec.GetUUIDPtr())
2863 uuid_str = module_spec.GetUUID().GetAsString();
2864 if (num_matches > 1) {
2865 result.AppendErrorWithFormat(
2866 "multiple modules match%s%s%s%s:\n", path[0] ? " file=" : "",
2867 path, !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
2868 for (size_t i = 0; i < num_matches; ++i) {
2869 if (matching_modules.GetModulePointerAtIndex(i)
2871 .GetPath(path, sizeof(path)))
2872 result.AppendMessageWithFormat("%s\n", path);
2875 result.AppendErrorWithFormat(
2876 "no modules were found that match%s%s%s%s.\n",
2877 path[0] ? " file=" : "", path, !uuid_str.empty() ? " uuid=" : "",
2880 result.SetStatus(eReturnStatusFailed);
2883 result.AppendError("either the \"--file <module>\" or the \"--uuid "
2884 "<uuid>\" option must be specified.\n");
2885 result.SetStatus(eReturnStatusFailed);
2888 return result.Succeeded();
2891 OptionGroupOptions m_option_group;
2892 OptionGroupUUID m_uuid_option_group;
2893 OptionGroupString m_file_option;
2894 OptionGroupBoolean m_load_option;
2895 OptionGroupBoolean m_pc_option;
2896 OptionGroupUInt64 m_slide_option;
2899 // List images with associated information
2900 #define LLDB_OPTIONS_target_modules_list
2901 #include "CommandOptions.inc"
2903 class CommandObjectTargetModulesList : public CommandObjectParsed {
2905 class CommandOptions : public Options {
2908 : Options(), m_format_array(), m_use_global_module_list(false),
2909 m_module_addr(LLDB_INVALID_ADDRESS) {}
2911 ~CommandOptions() override = default;
2913 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2914 ExecutionContext *execution_context) override {
2917 const int short_option = m_getopt_table[option_idx].val;
2918 if (short_option == 'g') {
2919 m_use_global_module_list = true;
2920 } else if (short_option == 'a') {
2921 m_module_addr = OptionArgParser::ToAddress(
2922 execution_context, option_arg, LLDB_INVALID_ADDRESS, &error);
2924 unsigned long width = 0;
2925 option_arg.getAsInteger(0, width);
2926 m_format_array.push_back(std::make_pair(short_option, width));
2931 void OptionParsingStarting(ExecutionContext *execution_context) override {
2932 m_format_array.clear();
2933 m_use_global_module_list = false;
2934 m_module_addr = LLDB_INVALID_ADDRESS;
2937 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2938 return llvm::makeArrayRef(g_target_modules_list_options);
2941 // Instance variables to hold the values for command options.
2942 typedef std::vector<std::pair<char, uint32_t>> FormatWidthCollection;
2943 FormatWidthCollection m_format_array;
2944 bool m_use_global_module_list;
2945 lldb::addr_t m_module_addr;
2948 CommandObjectTargetModulesList(CommandInterpreter &interpreter)
2949 : CommandObjectParsed(
2950 interpreter, "target modules list",
2951 "List current executable and dependent shared library images.",
2952 "target modules list [<cmd-options>]"),
2955 ~CommandObjectTargetModulesList() override = default;
2957 Options *GetOptions() override { return &m_options; }
2960 bool DoExecute(Args &command, CommandReturnObject &result) override {
2961 Target *target = GetDebugger().GetSelectedTarget().get();
2962 const bool use_global_module_list = m_options.m_use_global_module_list;
2963 // Define a local module list here to ensure it lives longer than any
2964 // "locker" object which might lock its contents below (through the
2965 // "module_list_ptr" variable).
2966 ModuleList module_list;
2967 if (target == nullptr && !use_global_module_list) {
2968 result.AppendError("invalid target, create a debug target using the "
2969 "'target create' command");
2970 result.SetStatus(eReturnStatusFailed);
2974 uint32_t addr_byte_size =
2975 target->GetArchitecture().GetAddressByteSize();
2976 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2977 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2979 // Dump all sections for all modules images
2980 Stream &strm = result.GetOutputStream();
2982 if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) {
2984 Address module_address;
2985 if (module_address.SetLoadAddress(m_options.m_module_addr, target)) {
2986 ModuleSP module_sp(module_address.GetModule());
2988 PrintModule(target, module_sp.get(), 0, strm);
2989 result.SetStatus(eReturnStatusSuccessFinishResult);
2991 result.AppendErrorWithFormat(
2992 "Couldn't find module matching address: 0x%" PRIx64 ".",
2993 m_options.m_module_addr);
2994 result.SetStatus(eReturnStatusFailed);
2997 result.AppendErrorWithFormat(
2998 "Couldn't find module containing address: 0x%" PRIx64 ".",
2999 m_options.m_module_addr);
3000 result.SetStatus(eReturnStatusFailed);
3004 "Can only look up modules by address with a valid target.");
3005 result.SetStatus(eReturnStatusFailed);
3007 return result.Succeeded();
3010 size_t num_modules = 0;
3012 // This locker will be locked on the mutex in module_list_ptr if it is
3013 // non-nullptr. Otherwise it will lock the
3014 // AllocationModuleCollectionMutex when accessing the global module list
3016 std::unique_lock<std::recursive_mutex> guard(
3017 Module::GetAllocationModuleCollectionMutex(), std::defer_lock);
3019 const ModuleList *module_list_ptr = nullptr;
3020 const size_t argc = command.GetArgumentCount();
3022 if (use_global_module_list) {
3024 num_modules = Module::GetNumberAllocatedModules();
3026 module_list_ptr = &target->GetImages();
3029 for (const Args::ArgEntry &arg : command) {
3030 // Dump specified images (by basename or fullpath)
3031 const size_t num_matches = FindModulesByName(
3032 target, arg.c_str(), module_list, use_global_module_list);
3033 if (num_matches == 0) {
3035 result.AppendErrorWithFormat("no modules found that match '%s'",
3037 result.SetStatus(eReturnStatusFailed);
3043 module_list_ptr = &module_list;
3046 std::unique_lock<std::recursive_mutex> lock;
3047 if (module_list_ptr != nullptr) {
3049 std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex());
3051 num_modules = module_list_ptr->GetSize();
3054 if (num_modules > 0) {
3055 for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
3058 if (module_list_ptr) {
3059 module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
3060 module = module_sp.get();
3062 module = Module::GetAllocatedModuleAtIndex(image_idx);
3063 module_sp = module->shared_from_this();
3066 const size_t indent = strm.Printf("[%3u] ", image_idx);
3067 PrintModule(target, module, indent, strm);
3069 result.SetStatus(eReturnStatusSuccessFinishResult);
3072 if (use_global_module_list)
3074 "the global module list has no matching modules");
3076 result.AppendError("the target has no matching modules");
3078 if (use_global_module_list)
3079 result.AppendError("the global module list is empty");
3082 "the target has no associated executable images");
3084 result.SetStatus(eReturnStatusFailed);
3088 return result.Succeeded();
3091 void PrintModule(Target *target, Module *module, int indent, Stream &strm) {
3092 if (module == nullptr) {
3093 strm.PutCString("Null module");
3097 bool dump_object_name = false;
3098 if (m_options.m_format_array.empty()) {
3099 m_options.m_format_array.push_back(std::make_pair('u', 0));
3100 m_options.m_format_array.push_back(std::make_pair('h', 0));
3101 m_options.m_format_array.push_back(std::make_pair('f', 0));
3102 m_options.m_format_array.push_back(std::make_pair('S', 0));
3104 const size_t num_entries = m_options.m_format_array.size();
3105 bool print_space = false;
3106 for (size_t i = 0; i < num_entries; ++i) {
3110 const char format_char = m_options.m_format_array[i].first;
3111 uint32_t width = m_options.m_format_array[i].second;
3112 switch (format_char) {
3114 DumpModuleArchitecture(strm, module, false, width);
3118 DumpModuleArchitecture(strm, module, true, width);
3122 DumpFullpath(strm, &module->GetFileSpec(), width);
3123 dump_object_name = true;
3127 DumpDirectory(strm, &module->GetFileSpec(), width);
3131 DumpBasename(strm, &module->GetFileSpec(), width);
3132 dump_object_name = true;
3137 // Image header address
3139 uint32_t addr_nibble_width =
3140 target ? (target->GetArchitecture().GetAddressByteSize() * 2)
3143 ObjectFile *objfile = module->GetObjectFile();
3145 Address base_addr(objfile->GetBaseAddress());
3146 if (base_addr.IsValid()) {
3147 if (target && !target->GetSectionLoadList().IsEmpty()) {
3148 lldb::addr_t load_addr = base_addr.GetLoadAddress(target);
3149 if (load_addr == LLDB_INVALID_ADDRESS) {
3150 base_addr.Dump(&strm, target,
3151 Address::DumpStyleModuleWithFileAddress,
3152 Address::DumpStyleFileAddress);
3154 if (format_char == 'o') {
3155 // Show the offset of slide for the image
3156 strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3158 load_addr - base_addr.GetFileAddress());
3160 // Show the load address of the image
3161 strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3162 addr_nibble_width, load_addr);
3167 // The address was valid, but the image isn't loaded, output the
3168 // address in an appropriate format
3169 base_addr.Dump(&strm, target, Address::DumpStyleFileAddress);
3173 strm.Printf("%*s", addr_nibble_width + 2, "");
3178 size_t ref_count = 0;
3179 ModuleSP module_sp(module->shared_from_this());
3181 // Take one away to make sure we don't count our local "module_sp"
3182 ref_count = module_sp.use_count() - 1;
3185 strm.Printf("{%*" PRIu64 "}", width, (uint64_t)ref_count);
3187 strm.Printf("{%" PRIu64 "}", (uint64_t)ref_count);
3192 if (const SymbolFile *symbol_file = module->GetSymbolFile()) {
3193 const FileSpec symfile_spec =
3194 symbol_file->GetObjectFile()->GetFileSpec();
3195 if (format_char == 'S') {
3196 // Dump symbol file only if different from module file
3197 if (!symfile_spec || symfile_spec == module->GetFileSpec()) {
3198 print_space = false;
3201 // Add a newline and indent past the index
3202 strm.Printf("\n%*s", indent, "");
3204 DumpFullpath(strm, &symfile_spec, width);
3205 dump_object_name = true;
3208 strm.Printf("%.*s", width, "<NONE>");
3212 strm.Format("{0:%c}", llvm::fmt_align(module->GetModificationTime(),
3213 llvm::AlignStyle::Left, width));
3217 strm.Printf("%p", static_cast<void *>(module));
3221 DumpModuleUUID(strm, module);
3228 if (dump_object_name) {
3229 const char *object_name = module->GetObjectName().GetCString();
3231 strm.Printf("(%s)", object_name);
3236 CommandOptions m_options;
3239 #pragma mark CommandObjectTargetModulesShowUnwind
3241 // Lookup unwind information in images
3242 #define LLDB_OPTIONS_target_modules_show_unwind
3243 #include "CommandOptions.inc"
3245 class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {
3248 eLookupTypeInvalid = -1,
3249 eLookupTypeAddress = 0,
3251 eLookupTypeFunction,
3252 eLookupTypeFunctionOrSymbol,
3256 class CommandOptions : public Options {
3259 : Options(), m_type(eLookupTypeInvalid), m_str(),
3260 m_addr(LLDB_INVALID_ADDRESS) {}
3262 ~CommandOptions() override = default;
3264 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3265 ExecutionContext *execution_context) override {
3268 const int short_option = m_getopt_table[option_idx].val;
3270 switch (short_option) {
3272 m_str = std::string(option_arg);
3273 m_type = eLookupTypeAddress;
3274 m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
3275 LLDB_INVALID_ADDRESS, &error);
3276 if (m_addr == LLDB_INVALID_ADDRESS)
3277 error.SetErrorStringWithFormat("invalid address string '%s'",
3278 option_arg.str().c_str());
3283 m_str = std::string(option_arg);
3284 m_type = eLookupTypeFunctionOrSymbol;
3288 llvm_unreachable("Unimplemented option");
3294 void OptionParsingStarting(ExecutionContext *execution_context) override {
3295 m_type = eLookupTypeInvalid;
3297 m_addr = LLDB_INVALID_ADDRESS;
3300 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3301 return llvm::makeArrayRef(g_target_modules_show_unwind_options);
3304 // Instance variables to hold the values for command options.
3306 int m_type; // Should be a eLookupTypeXXX enum after parsing options
3307 std::string m_str; // Holds name lookup
3308 lldb::addr_t m_addr; // Holds the address to lookup
3311 CommandObjectTargetModulesShowUnwind(CommandInterpreter &interpreter)
3312 : CommandObjectParsed(
3313 interpreter, "target modules show-unwind",
3314 "Show synthesized unwind instructions for a function.", nullptr,
3315 eCommandRequiresTarget | eCommandRequiresProcess |
3316 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
3319 ~CommandObjectTargetModulesShowUnwind() override = default;
3321 Options *GetOptions() override { return &m_options; }
3324 bool DoExecute(Args &command, CommandReturnObject &result) override {
3325 Target *target = m_exe_ctx.GetTargetPtr();
3326 Process *process = m_exe_ctx.GetProcessPtr();
3329 abi = process->GetABI().get();
3331 if (process == nullptr) {
3333 "You must have a process running to use this command.");
3334 result.SetStatus(eReturnStatusFailed);
3338 ThreadList threads(process->GetThreadList());
3339 if (threads.GetSize() == 0) {
3340 result.AppendError("The process must be paused to use this command.");
3341 result.SetStatus(eReturnStatusFailed);
3345 ThreadSP thread(threads.GetThreadAtIndex(0));
3347 result.AppendError("The process must be paused to use this command.");
3348 result.SetStatus(eReturnStatusFailed);
3352 SymbolContextList sc_list;
3354 if (m_options.m_type == eLookupTypeFunctionOrSymbol) {
3355 ConstString function_name(m_options.m_str.c_str());
3356 target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto,
3357 true, false, sc_list);
3358 } else if (m_options.m_type == eLookupTypeAddress && target) {
3360 if (target->GetSectionLoadList().ResolveLoadAddress(m_options.m_addr,
3363 ModuleSP module_sp(addr.GetModule());
3364 module_sp->ResolveSymbolContextForAddress(addr,
3365 eSymbolContextEverything, sc);
3366 if (sc.function || sc.symbol) {
3372 "address-expression or function name option must be specified.");
3373 result.SetStatus(eReturnStatusFailed);
3377 size_t num_matches = sc_list.GetSize();
3378 if (num_matches == 0) {
3379 result.AppendErrorWithFormat("no unwind data found that matches '%s'.",
3380 m_options.m_str.c_str());
3381 result.SetStatus(eReturnStatusFailed);
3385 for (uint32_t idx = 0; idx < num_matches; idx++) {
3387 sc_list.GetContextAtIndex(idx, sc);
3388 if (sc.symbol == nullptr && sc.function == nullptr)
3390 if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr)
3393 if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,
3396 if (!range.GetBaseAddress().IsValid())
3398 ConstString funcname(sc.GetFunctionName());
3399 if (funcname.IsEmpty())
3401 addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
3403 start_addr = abi->FixCodeAddress(start_addr);
3405 FuncUnwindersSP func_unwinders_sp(
3406 sc.module_sp->GetUnwindTable()
3407 .GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
3408 if (!func_unwinders_sp)
3411 result.GetOutputStream().Printf(
3412 "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n\n",
3413 sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(),
3414 funcname.AsCString(), start_addr);
3416 UnwindPlanSP non_callsite_unwind_plan =
3417 func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread);
3418 if (non_callsite_unwind_plan) {
3419 result.GetOutputStream().Printf(
3420 "Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n",
3421 non_callsite_unwind_plan->GetSourceName().AsCString());
3423 UnwindPlanSP callsite_unwind_plan =
3424 func_unwinders_sp->GetUnwindPlanAtCallSite(*target, *thread);
3425 if (callsite_unwind_plan) {
3426 result.GetOutputStream().Printf(
3427 "Synchronous (restricted to call-sites) UnwindPlan is '%s'\n",
3428 callsite_unwind_plan->GetSourceName().AsCString());
3430 UnwindPlanSP fast_unwind_plan =
3431 func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread);
3432 if (fast_unwind_plan) {
3433 result.GetOutputStream().Printf(
3434 "Fast UnwindPlan is '%s'\n",
3435 fast_unwind_plan->GetSourceName().AsCString());
3438 result.GetOutputStream().Printf("\n");
3440 UnwindPlanSP assembly_sp =
3441 func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread);
3443 result.GetOutputStream().Printf(
3444 "Assembly language inspection UnwindPlan:\n");
3445 assembly_sp->Dump(result.GetOutputStream(), thread.get(),
3446 LLDB_INVALID_ADDRESS);
3447 result.GetOutputStream().Printf("\n");
3450 UnwindPlanSP of_unwind_sp =
3451 func_unwinders_sp->GetObjectFileUnwindPlan(*target);
3453 result.GetOutputStream().Printf("object file UnwindPlan:\n");
3454 of_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3455 LLDB_INVALID_ADDRESS);
3456 result.GetOutputStream().Printf("\n");
3459 UnwindPlanSP of_unwind_augmented_sp =
3460 func_unwinders_sp->GetObjectFileAugmentedUnwindPlan(*target, *thread);
3461 if (of_unwind_augmented_sp) {
3462 result.GetOutputStream().Printf("object file augmented UnwindPlan:\n");
3463 of_unwind_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
3464 LLDB_INVALID_ADDRESS);
3465 result.GetOutputStream().Printf("\n");
3468 UnwindPlanSP ehframe_sp =
3469 func_unwinders_sp->GetEHFrameUnwindPlan(*target);
3471 result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
3472 ehframe_sp->Dump(result.GetOutputStream(), thread.get(),
3473 LLDB_INVALID_ADDRESS);
3474 result.GetOutputStream().Printf("\n");
3477 UnwindPlanSP ehframe_augmented_sp =
3478 func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread);
3479 if (ehframe_augmented_sp) {
3480 result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
3481 ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
3482 LLDB_INVALID_ADDRESS);
3483 result.GetOutputStream().Printf("\n");
3486 if (UnwindPlanSP plan_sp =
3487 func_unwinders_sp->GetDebugFrameUnwindPlan(*target)) {
3488 result.GetOutputStream().Printf("debug_frame UnwindPlan:\n");
3489 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3490 LLDB_INVALID_ADDRESS);
3491 result.GetOutputStream().Printf("\n");
3494 if (UnwindPlanSP plan_sp =
3495 func_unwinders_sp->GetDebugFrameAugmentedUnwindPlan(*target,
3497 result.GetOutputStream().Printf("debug_frame augmented UnwindPlan:\n");
3498 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3499 LLDB_INVALID_ADDRESS);
3500 result.GetOutputStream().Printf("\n");
3503 UnwindPlanSP arm_unwind_sp =
3504 func_unwinders_sp->GetArmUnwindUnwindPlan(*target);
3505 if (arm_unwind_sp) {
3506 result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
3507 arm_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3508 LLDB_INVALID_ADDRESS);
3509 result.GetOutputStream().Printf("\n");
3512 if (UnwindPlanSP symfile_plan_sp =
3513 func_unwinders_sp->GetSymbolFileUnwindPlan(*thread)) {
3514 result.GetOutputStream().Printf("Symbol file UnwindPlan:\n");
3515 symfile_plan_sp->Dump(result.GetOutputStream(), thread.get(),
3516 LLDB_INVALID_ADDRESS);
3517 result.GetOutputStream().Printf("\n");
3520 UnwindPlanSP compact_unwind_sp =
3521 func_unwinders_sp->GetCompactUnwindUnwindPlan(*target);
3522 if (compact_unwind_sp) {
3523 result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
3524 compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3525 LLDB_INVALID_ADDRESS);
3526 result.GetOutputStream().Printf("\n");
3529 if (fast_unwind_plan) {
3530 result.GetOutputStream().Printf("Fast UnwindPlan:\n");
3531 fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(),
3532 LLDB_INVALID_ADDRESS);
3533 result.GetOutputStream().Printf("\n");
3536 ABISP abi_sp = process->GetABI();
3538 UnwindPlan arch_default(lldb::eRegisterKindGeneric);
3539 if (abi_sp->CreateDefaultUnwindPlan(arch_default)) {
3540 result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
3541 arch_default.Dump(result.GetOutputStream(), thread.get(),
3542 LLDB_INVALID_ADDRESS);
3543 result.GetOutputStream().Printf("\n");
3546 UnwindPlan arch_entry(lldb::eRegisterKindGeneric);
3547 if (abi_sp->CreateFunctionEntryUnwindPlan(arch_entry)) {
3548 result.GetOutputStream().Printf(
3549 "Arch default at entry point UnwindPlan:\n");
3550 arch_entry.Dump(result.GetOutputStream(), thread.get(),
3551 LLDB_INVALID_ADDRESS);
3552 result.GetOutputStream().Printf("\n");
3556 result.GetOutputStream().Printf("\n");
3558 return result.Succeeded();
3561 CommandOptions m_options;
3564 // Lookup information in images
3565 #define LLDB_OPTIONS_target_modules_lookup
3566 #include "CommandOptions.inc"
3568 class CommandObjectTargetModulesLookup : public CommandObjectParsed {
3571 eLookupTypeInvalid = -1,
3572 eLookupTypeAddress = 0,
3574 eLookupTypeFileLine, // Line is optional
3575 eLookupTypeFunction,
3576 eLookupTypeFunctionOrSymbol,
3581 class CommandOptions : public Options {
3583 CommandOptions() : Options() { OptionParsingStarting(nullptr); }
3585 ~CommandOptions() override = default;
3587 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3588 ExecutionContext *execution_context) override {
3591 const int short_option = m_getopt_table[option_idx].val;
3593 switch (short_option) {
3595 m_type = eLookupTypeAddress;
3596 m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
3597 LLDB_INVALID_ADDRESS, &error);
3601 if (option_arg.getAsInteger(0, m_offset))
3602 error.SetErrorStringWithFormat("invalid offset string '%s'",
3603 option_arg.str().c_str());
3607 m_str = std::string(option_arg);
3608 m_type = eLookupTypeSymbol;
3612 m_file.SetFile(option_arg, FileSpec::Style::native);
3613 m_type = eLookupTypeFileLine;
3617 m_include_inlines = false;
3621 if (option_arg.getAsInteger(0, m_line_number))
3622 error.SetErrorStringWithFormat("invalid line number string '%s'",
3623 option_arg.str().c_str());
3624 else if (m_line_number == 0)
3625 error.SetErrorString("zero is an invalid line number");
3626 m_type = eLookupTypeFileLine;
3630 m_str = std::string(option_arg);
3631 m_type = eLookupTypeFunction;
3635 m_str = std::string(option_arg);
3636 m_type = eLookupTypeFunctionOrSymbol;
3640 m_str = std::string(option_arg);
3641 m_type = eLookupTypeType;
3656 llvm_unreachable("Unimplemented option");
3662 void OptionParsingStarting(ExecutionContext *execution_context) override {
3663 m_type = eLookupTypeInvalid;
3666 m_addr = LLDB_INVALID_ADDRESS;
3669 m_use_regex = false;
3670 m_include_inlines = true;
3672 m_print_all = false;
3675 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3676 return llvm::makeArrayRef(g_target_modules_lookup_options);
3679 int m_type; // Should be a eLookupTypeXXX enum after parsing options
3680 std::string m_str; // Holds name lookup
3681 FileSpec m_file; // Files for file lookups
3682 lldb::addr_t m_addr; // Holds the address to lookup
3684 m_offset; // Subtract this offset from m_addr before doing lookups.
3685 uint32_t m_line_number; // Line number for file+line lookups
3686 bool m_use_regex; // Name lookups in m_str are regular expressions.
3687 bool m_include_inlines; // Check for inline entries when looking up by
3689 bool m_verbose; // Enable verbose lookup info
3690 bool m_print_all; // Print all matches, even in cases where there's a best
3694 CommandObjectTargetModulesLookup(CommandInterpreter &interpreter)
3695 : CommandObjectParsed(interpreter, "target modules lookup",
3696 "Look up information within executable and "
3697 "dependent shared library images.",
3698 nullptr, eCommandRequiresTarget),
3700 CommandArgumentEntry arg;
3701 CommandArgumentData file_arg;
3703 // Define the first (and only) variant of this arg.
3704 file_arg.arg_type = eArgTypeFilename;
3705 file_arg.arg_repetition = eArgRepeatStar;
3707 // There is only one variant this argument could be; put it into the
3709 arg.push_back(file_arg);
3711 // Push the data for the first argument into the m_arguments vector.
3712 m_arguments.push_back(arg);
3715 ~CommandObjectTargetModulesLookup() override = default;
3717 Options *GetOptions() override { return &m_options; }
3719 bool LookupHere(CommandInterpreter &interpreter, CommandReturnObject &result,
3720 bool &syntax_error) {
3721 switch (m_options.m_type) {
3722 case eLookupTypeAddress:
3723 case eLookupTypeFileLine:
3724 case eLookupTypeFunction:
3725 case eLookupTypeFunctionOrSymbol:
3726 case eLookupTypeSymbol:
3729 case eLookupTypeType:
3733 StackFrameSP frame = m_exe_ctx.GetFrameSP();
3738 const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
3740 if (!sym_ctx.module_sp)
3743 switch (m_options.m_type) {
3746 case eLookupTypeType:
3747 if (!m_options.m_str.empty()) {
3748 if (LookupTypeHere(m_interpreter, result.GetOutputStream(),
3749 *sym_ctx.module_sp, m_options.m_str.c_str(),
3750 m_options.m_use_regex)) {
3751 result.SetStatus(eReturnStatusSuccessFinishResult);
3761 bool LookupInModule(CommandInterpreter &interpreter, Module *module,
3762 CommandReturnObject &result, bool &syntax_error) {
3763 switch (m_options.m_type) {
3764 case eLookupTypeAddress:
3765 if (m_options.m_addr != LLDB_INVALID_ADDRESS) {
3766 if (LookupAddressInModule(
3767 m_interpreter, result.GetOutputStream(), module,
3768 eSymbolContextEverything |
3769 (m_options.m_verbose
3770 ? static_cast<int>(eSymbolContextVariable)
3772 m_options.m_addr, m_options.m_offset, m_options.m_verbose)) {
3773 result.SetStatus(eReturnStatusSuccessFinishResult);
3779 case eLookupTypeSymbol:
3780 if (!m_options.m_str.empty()) {
3781 if (LookupSymbolInModule(m_interpreter, result.GetOutputStream(),
3782 module, m_options.m_str.c_str(),
3783 m_options.m_use_regex, m_options.m_verbose)) {
3784 result.SetStatus(eReturnStatusSuccessFinishResult);
3790 case eLookupTypeFileLine:
3791 if (m_options.m_file) {
3792 if (LookupFileAndLineInModule(
3793 m_interpreter, result.GetOutputStream(), module,
3794 m_options.m_file, m_options.m_line_number,
3795 m_options.m_include_inlines, m_options.m_verbose)) {
3796 result.SetStatus(eReturnStatusSuccessFinishResult);
3802 case eLookupTypeFunctionOrSymbol:
3803 case eLookupTypeFunction:
3804 if (!m_options.m_str.empty()) {
3805 if (LookupFunctionInModule(
3806 m_interpreter, result.GetOutputStream(), module,
3807 m_options.m_str.c_str(), m_options.m_use_regex,
3808 m_options.m_include_inlines,
3810 eLookupTypeFunctionOrSymbol, // include symbols
3811 m_options.m_verbose)) {
3812 result.SetStatus(eReturnStatusSuccessFinishResult);
3818 case eLookupTypeType:
3819 if (!m_options.m_str.empty()) {
3820 if (LookupTypeInModule(m_interpreter, result.GetOutputStream(), module,
3821 m_options.m_str.c_str(),
3822 m_options.m_use_regex)) {
3823 result.SetStatus(eReturnStatusSuccessFinishResult);
3830 m_options.GenerateOptionUsage(
3831 result.GetErrorStream(), this,
3832 GetCommandInterpreter().GetDebugger().GetTerminalWidth());
3833 syntax_error = true;
3837 result.SetStatus(eReturnStatusFailed);
3842 bool DoExecute(Args &command, CommandReturnObject &result) override {
3843 Target *target = &GetSelectedTarget();
3844 bool syntax_error = false;
3846 uint32_t num_successful_lookups = 0;
3847 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
3848 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3849 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3850 // Dump all sections for all modules images
3852 if (command.GetArgumentCount() == 0) {
3853 ModuleSP current_module;
3855 // Where it is possible to look in the current symbol context first,
3856 // try that. If this search was successful and --all was not passed,
3857 // don't print anything else.
3858 if (LookupHere(m_interpreter, result, syntax_error)) {
3859 result.GetOutputStream().EOL();
3860 num_successful_lookups++;
3861 if (!m_options.m_print_all) {
3862 result.SetStatus(eReturnStatusSuccessFinishResult);
3863 return result.Succeeded();
3867 // Dump all sections for all other modules
3869 const ModuleList &target_modules = target->GetImages();
3870 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
3871 const size_t num_modules = target_modules.GetSize();
3872 if (num_modules > 0) {
3873 for (i = 0; i < num_modules && !syntax_error; ++i) {
3874 Module *module_pointer =
3875 target_modules.GetModulePointerAtIndexUnlocked(i);
3877 if (module_pointer != current_module.get() &&
3878 LookupInModule(m_interpreter,
3879 target_modules.GetModulePointerAtIndexUnlocked(i),
3880 result, syntax_error)) {
3881 result.GetOutputStream().EOL();
3882 num_successful_lookups++;
3886 result.AppendError("the target has no associated executable images");
3887 result.SetStatus(eReturnStatusFailed);
3891 // Dump specified images (by basename or fullpath)
3892 const char *arg_cstr;
3893 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr &&
3896 ModuleList module_list;
3897 const size_t num_matches =
3898 FindModulesByName(target, arg_cstr, module_list, false);
3899 if (num_matches > 0) {
3900 for (size_t j = 0; j < num_matches; ++j) {
3901 Module *module = module_list.GetModulePointerAtIndex(j);
3903 if (LookupInModule(m_interpreter, module, result, syntax_error)) {
3904 result.GetOutputStream().EOL();
3905 num_successful_lookups++;
3910 result.AppendWarningWithFormat(
3911 "Unable to find an image that matches '%s'.\n", arg_cstr);
3915 if (num_successful_lookups > 0)
3916 result.SetStatus(eReturnStatusSuccessFinishResult);
3918 result.SetStatus(eReturnStatusFailed);
3919 return result.Succeeded();
3922 CommandOptions m_options;
3925 #pragma mark CommandObjectMultiwordImageSearchPaths
3927 // CommandObjectMultiwordImageSearchPaths
3929 class CommandObjectTargetModulesImageSearchPaths
3930 : public CommandObjectMultiword {
3932 CommandObjectTargetModulesImageSearchPaths(CommandInterpreter &interpreter)
3933 : CommandObjectMultiword(
3934 interpreter, "target modules search-paths",
3935 "Commands for managing module search paths for a target.",
3936 "target modules search-paths <subcommand> [<subcommand-options>]") {
3938 "add", CommandObjectSP(
3939 new CommandObjectTargetModulesSearchPathsAdd(interpreter)));
3941 "clear", CommandObjectSP(new CommandObjectTargetModulesSearchPathsClear(
3946 new CommandObjectTargetModulesSearchPathsInsert(interpreter)));
3948 "list", CommandObjectSP(new CommandObjectTargetModulesSearchPathsList(
3951 "query", CommandObjectSP(new CommandObjectTargetModulesSearchPathsQuery(
3955 ~CommandObjectTargetModulesImageSearchPaths() override = default;
3958 #pragma mark CommandObjectTargetModules
3960 // CommandObjectTargetModules
3962 class CommandObjectTargetModules : public CommandObjectMultiword {
3964 // Constructors and Destructors
3965 CommandObjectTargetModules(CommandInterpreter &interpreter)
3966 : CommandObjectMultiword(interpreter, "target modules",
3967 "Commands for accessing information for one or "
3968 "more target modules.",
3969 "target modules <sub-command> ...") {
3971 "add", CommandObjectSP(new CommandObjectTargetModulesAdd(interpreter)));
3972 LoadSubCommand("load", CommandObjectSP(new CommandObjectTargetModulesLoad(
3974 LoadSubCommand("dump", CommandObjectSP(new CommandObjectTargetModulesDump(
3976 LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetModulesList(
3980 CommandObjectSP(new CommandObjectTargetModulesLookup(interpreter)));
3984 new CommandObjectTargetModulesImageSearchPaths(interpreter)));
3987 CommandObjectSP(new CommandObjectTargetModulesShowUnwind(interpreter)));
3990 ~CommandObjectTargetModules() override = default;
3993 // For CommandObjectTargetModules only
3994 CommandObjectTargetModules(const CommandObjectTargetModules &) = delete;
3995 const CommandObjectTargetModules &
3996 operator=(const CommandObjectTargetModules &) = delete;
3999 class CommandObjectTargetSymbolsAdd : public CommandObjectParsed {
4001 CommandObjectTargetSymbolsAdd(CommandInterpreter &interpreter)
4002 : CommandObjectParsed(
4003 interpreter, "target symbols add",
4004 "Add a debug symbol file to one of the target's current modules by "
4005 "specifying a path to a debug symbols file or by using the options "
4006 "to specify a module.",
4007 "target symbols add <cmd-options> [<symfile>]",
4008 eCommandRequiresTarget),
4011 LLDB_OPT_SET_1, false, "shlib", 's',
4012 CommandCompletions::eModuleCompletion, eArgTypeShlibName,
4013 "Locate the debug symbols for the shared library specified by "
4015 m_current_frame_option(
4016 LLDB_OPT_SET_2, false, "frame", 'F',
4017 "Locate the debug symbols for the currently selected frame.",
4021 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
4023 m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
4024 m_option_group.Append(&m_current_frame_option, LLDB_OPT_SET_2,
4026 m_option_group.Finalize();
4029 ~CommandObjectTargetSymbolsAdd() override = default;
4032 HandleArgumentCompletion(CompletionRequest &request,
4033 OptionElementVector &opt_element_vector) override {
4034 CommandCompletions::InvokeCommonCompletionCallbacks(
4035 GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
4039 Options *GetOptions() override { return &m_option_group; }
4042 bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush,
4043 CommandReturnObject &result) {
4044 const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
4045 if (!symbol_fspec) {
4047 "one or more executable image paths must be specified");
4048 result.SetStatus(eReturnStatusFailed);
4052 char symfile_path[PATH_MAX];
4053 symbol_fspec.GetPath(symfile_path, sizeof(symfile_path));
4055 if (!module_spec.GetUUID().IsValid()) {
4056 if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
4057 module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename();
4060 // Now module_spec represents a symbol file for a module that might exist
4061 // in the current target. Let's find possible matches.
4062 ModuleList matching_modules;
4064 // First extract all module specs from the symbol file
4065 lldb_private::ModuleSpecList symfile_module_specs;
4066 if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(),
4067 0, 0, symfile_module_specs)) {
4068 // Now extract the module spec that matches the target architecture
4069 ModuleSpec target_arch_module_spec;
4070 ModuleSpec symfile_module_spec;
4071 target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
4072 if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec,
4073 symfile_module_spec)) {
4074 if (symfile_module_spec.GetUUID().IsValid()) {
4075 // It has a UUID, look for this UUID in the target modules
4076 ModuleSpec symfile_uuid_module_spec;
4077 symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
4078 target->GetImages().FindModules(symfile_uuid_module_spec,
4083 if (matching_modules.IsEmpty()) {
4084 // No matches yet. Iterate through the module specs to find a UUID
4085 // value that we can match up to an image in our target.
4086 const size_t num_symfile_module_specs = symfile_module_specs.GetSize();
4088 i < num_symfile_module_specs && matching_modules.IsEmpty(); ++i) {
4089 if (symfile_module_specs.GetModuleSpecAtIndex(
4090 i, symfile_module_spec)) {
4091 if (symfile_module_spec.GetUUID().IsValid()) {
4092 // It has a UUID. Look for this UUID in the target modules.
4093 ModuleSpec symfile_uuid_module_spec;
4094 symfile_uuid_module_spec.GetUUID() =
4095 symfile_module_spec.GetUUID();
4096 target->GetImages().FindModules(symfile_uuid_module_spec,
4104 // Just try to match up the file by basename if we have no matches at
4105 // this point. For example, module foo might have symbols in foo.debug.
4106 if (matching_modules.IsEmpty())
4107 target->GetImages().FindModules(module_spec, matching_modules);
4109 while (matching_modules.IsEmpty()) {
4110 ConstString filename_no_extension(
4111 module_spec.GetFileSpec().GetFileNameStrippingExtension());
4112 // Empty string returned, let's bail
4113 if (!filename_no_extension)
4116 // Check if there was no extension to strip and the basename is the same
4117 if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
4120 // Replace basename with one fewer extension
4121 module_spec.GetFileSpec().GetFilename() = filename_no_extension;
4122 target->GetImages().FindModules(module_spec, matching_modules);
4125 if (matching_modules.GetSize() > 1) {
4126 result.AppendErrorWithFormat("multiple modules match symbol file '%s', "
4127 "use the --uuid option to resolve the "
4130 result.SetStatus(eReturnStatusFailed);
4134 if (matching_modules.GetSize() == 1) {
4135 ModuleSP module_sp(matching_modules.GetModuleAtIndex(0));
4137 // The module has not yet created its symbol vendor, we can just give
4138 // the existing target module the symfile path to use for when it
4139 // decides to create it!
4140 module_sp->SetSymbolFileFileSpec(symbol_fspec);
4142 SymbolFile *symbol_file =
4143 module_sp->GetSymbolFile(true, &result.GetErrorStream());
4145 ObjectFile *object_file = symbol_file->GetObjectFile();
4146 if (object_file && object_file->GetFileSpec() == symbol_fspec) {
4147 // Provide feedback that the symfile has been successfully added.
4148 const FileSpec &module_fs = module_sp->GetFileSpec();
4149 result.AppendMessageWithFormat(
4150 "symbol file '%s' has been added to '%s'\n", symfile_path,
4151 module_fs.GetPath().c_str());
4153 // Let clients know something changed in the module if it is
4155 ModuleList module_list;
4156 module_list.Append(module_sp);
4157 target->SymbolsDidLoad(module_list);
4159 // Make sure we load any scripting resources that may be embedded
4160 // in the debug info files in case the platform supports that.
4162 StreamString feedback_stream;
4163 module_sp->LoadScriptingResourceInTarget(target, error,
4165 if (error.Fail() && error.AsCString())
4166 result.AppendWarningWithFormat(
4167 "unable to load scripting data for module %s - error "
4169 module_sp->GetFileSpec()
4170 .GetFileNameStrippingExtension()
4173 else if (feedback_stream.GetSize())
4174 result.AppendWarning(feedback_stream.GetData());
4177 result.SetStatus(eReturnStatusSuccessFinishResult);
4181 // Clear the symbol file spec if anything went wrong
4182 module_sp->SetSymbolFileFileSpec(FileSpec());
4185 StreamString ss_symfile_uuid;
4186 if (module_spec.GetUUID().IsValid()) {
4187 ss_symfile_uuid << " (";
4188 module_spec.GetUUID().Dump(&ss_symfile_uuid);
4189 ss_symfile_uuid << ')';
4191 result.AppendErrorWithFormat(
4192 "symbol file '%s'%s does not match any existing module%s\n",
4193 symfile_path, ss_symfile_uuid.GetData(),
4194 !llvm::sys::fs::is_regular_file(symbol_fspec.GetPath())
4195 ? "\n please specify the full path to the symbol file"
4197 result.SetStatus(eReturnStatusFailed);
4201 bool DoExecute(Args &args, CommandReturnObject &result) override {
4202 Target *target = m_exe_ctx.GetTargetPtr();
4203 result.SetStatus(eReturnStatusFailed);
4205 ModuleSpec module_spec;
4206 const bool uuid_option_set =
4207 m_uuid_option_group.GetOptionValue().OptionWasSet();
4208 const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
4209 const bool frame_option_set =
4210 m_current_frame_option.GetOptionValue().OptionWasSet();
4211 const size_t argc = args.GetArgumentCount();
4214 if (uuid_option_set || file_option_set || frame_option_set) {
4215 bool success = false;
4216 bool error_set = false;
4217 if (frame_option_set) {
4218 Process *process = m_exe_ctx.GetProcessPtr();
4220 const StateType process_state = process->GetState();
4221 if (StateIsStoppedState(process_state, true)) {
4222 StackFrame *frame = m_exe_ctx.GetFramePtr();
4224 ModuleSP frame_module_sp(
4225 frame->GetSymbolContext(eSymbolContextModule).module_sp);
4226 if (frame_module_sp) {
4227 if (FileSystem::Instance().Exists(
4228 frame_module_sp->GetPlatformFileSpec())) {
4229 module_spec.GetArchitecture() =
4230 frame_module_sp->GetArchitecture();
4231 module_spec.GetFileSpec() =
4232 frame_module_sp->GetPlatformFileSpec();
4234 module_spec.GetUUID() = frame_module_sp->GetUUID();
4235 success = module_spec.GetUUID().IsValid() ||
4236 module_spec.GetFileSpec();
4238 result.AppendError("frame has no module");
4242 result.AppendError("invalid current frame");
4246 result.AppendErrorWithFormat("process is not stopped: %s",
4247 StateAsCString(process_state));
4252 "a process must exist in order to use the --frame option");
4256 if (uuid_option_set) {
4257 module_spec.GetUUID() =
4258 m_uuid_option_group.GetOptionValue().GetCurrentValue();
4259 success |= module_spec.GetUUID().IsValid();
4260 } else if (file_option_set) {
4261 module_spec.GetFileSpec() =
4262 m_file_option.GetOptionValue().GetCurrentValue();
4264 target->GetImages().FindFirstModule(module_spec));
4266 module_spec.GetFileSpec() = module_sp->GetFileSpec();
4267 module_spec.GetPlatformFileSpec() =
4268 module_sp->GetPlatformFileSpec();
4269 module_spec.GetUUID() = module_sp->GetUUID();
4270 module_spec.GetArchitecture() = module_sp->GetArchitecture();
4272 module_spec.GetArchitecture() = target->GetArchitecture();
4274 success |= module_spec.GetUUID().IsValid() ||
4275 FileSystem::Instance().Exists(module_spec.GetFileSpec());
4280 if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
4281 if (module_spec.GetSymbolFileSpec())
4282 success = AddModuleSymbols(target, module_spec, flush, result);
4286 if (!success && !error_set) {
4287 StreamString error_strm;
4288 if (uuid_option_set) {
4289 error_strm.PutCString("unable to find debug symbols for UUID ");
4290 module_spec.GetUUID().Dump(&error_strm);
4291 } else if (file_option_set) {
4292 error_strm.PutCString(
4293 "unable to find debug symbols for the executable file ");
4294 error_strm << module_spec.GetFileSpec();
4295 } else if (frame_option_set) {
4296 error_strm.PutCString(
4297 "unable to find debug symbols for the current frame");
4299 result.AppendError(error_strm.GetString());
4302 result.AppendError("one or more symbol file paths must be specified, "
4303 "or options must be specified");
4306 if (uuid_option_set) {
4307 result.AppendError("specify either one or more paths to symbol files "
4308 "or use the --uuid option without arguments");
4309 } else if (frame_option_set) {
4310 result.AppendError("specify either one or more paths to symbol files "
4311 "or use the --frame option without arguments");
4312 } else if (file_option_set && argc > 1) {
4313 result.AppendError("specify at most one symbol file path when "
4314 "--shlib option is set");
4316 PlatformSP platform_sp(target->GetPlatform());
4318 for (auto &entry : args.entries()) {
4319 if (!entry.ref().empty()) {
4320 auto &symbol_file_spec = module_spec.GetSymbolFileSpec();
4321 symbol_file_spec.SetFile(entry.ref(), FileSpec::Style::native);
4322 FileSystem::Instance().Resolve(symbol_file_spec);
4323 if (file_option_set) {
4324 module_spec.GetFileSpec() =
4325 m_file_option.GetOptionValue().GetCurrentValue();
4328 FileSpec symfile_spec;
4330 ->ResolveSymbolFile(*target, module_spec, symfile_spec)
4332 module_spec.GetSymbolFileSpec() = symfile_spec;
4336 bool symfile_exists =
4337 FileSystem::Instance().Exists(module_spec.GetSymbolFileSpec());
4339 if (symfile_exists) {
4340 if (!AddModuleSymbols(target, module_spec, flush, result))
4343 std::string resolved_symfile_path =
4344 module_spec.GetSymbolFileSpec().GetPath();
4345 if (resolved_symfile_path != entry.ref()) {
4346 result.AppendErrorWithFormat(
4347 "invalid module path '%s' with resolved path '%s'\n",
4348 entry.c_str(), resolved_symfile_path.c_str());
4351 result.AppendErrorWithFormat("invalid module path '%s'\n",
4361 Process *process = m_exe_ctx.GetProcessPtr();
4365 return result.Succeeded();
4368 OptionGroupOptions m_option_group;
4369 OptionGroupUUID m_uuid_option_group;
4370 OptionGroupFile m_file_option;
4371 OptionGroupBoolean m_current_frame_option;
4374 #pragma mark CommandObjectTargetSymbols
4376 // CommandObjectTargetSymbols
4378 class CommandObjectTargetSymbols : public CommandObjectMultiword {
4380 // Constructors and Destructors
4381 CommandObjectTargetSymbols(CommandInterpreter &interpreter)
4382 : CommandObjectMultiword(
4383 interpreter, "target symbols",
4384 "Commands for adding and managing debug symbol files.",
4385 "target symbols <sub-command> ...") {
4387 "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter)));
4390 ~CommandObjectTargetSymbols() override = default;
4393 // For CommandObjectTargetModules only
4394 CommandObjectTargetSymbols(const CommandObjectTargetSymbols &) = delete;
4395 const CommandObjectTargetSymbols &
4396 operator=(const CommandObjectTargetSymbols &) = delete;
4399 #pragma mark CommandObjectTargetStopHookAdd
4401 // CommandObjectTargetStopHookAdd
4402 #define LLDB_OPTIONS_target_stop_hook_add
4403 #include "CommandOptions.inc"
4405 class CommandObjectTargetStopHookAdd : public CommandObjectParsed,
4406 public IOHandlerDelegateMultiline {
4408 class CommandOptions : public Options {
4411 : Options(), m_line_start(0), m_line_end(UINT_MAX),
4412 m_func_name_type_mask(eFunctionNameTypeAuto),
4413 m_sym_ctx_specified(false), m_thread_specified(false),
4414 m_use_one_liner(false), m_one_liner() {}
4416 ~CommandOptions() override = default;
4418 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
4419 return llvm::makeArrayRef(g_target_stop_hook_add_options);
4422 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
4423 ExecutionContext *execution_context) override {
4425 const int short_option = m_getopt_table[option_idx].val;
4427 switch (short_option) {
4429 m_class_name = std::string(option_arg);
4430 m_sym_ctx_specified = true;
4434 if (option_arg.getAsInteger(0, m_line_end)) {
4435 error.SetErrorStringWithFormat("invalid end line number: \"%s\"",
4436 option_arg.str().c_str());
4439 m_sym_ctx_specified = true;
4443 bool value, success;
4444 value = OptionArgParser::ToBoolean(option_arg, false, &success);
4446 m_auto_continue = value;
4448 error.SetErrorStringWithFormat(
4449 "invalid boolean value '%s' passed for -G option",
4450 option_arg.str().c_str());
4453 if (option_arg.getAsInteger(0, m_line_start)) {
4454 error.SetErrorStringWithFormat("invalid start line number: \"%s\"",
4455 option_arg.str().c_str());
4458 m_sym_ctx_specified = true;
4462 m_no_inlines = true;
4466 m_function_name = std::string(option_arg);
4467 m_func_name_type_mask |= eFunctionNameTypeAuto;
4468 m_sym_ctx_specified = true;
4472 m_file_name = std::string(option_arg);
4473 m_sym_ctx_specified = true;
4477 m_module_name = std::string(option_arg);
4478 m_sym_ctx_specified = true;
4482 if (option_arg.getAsInteger(0, m_thread_id))
4483 error.SetErrorStringWithFormat("invalid thread id string '%s'",
4484 option_arg.str().c_str());
4485 m_thread_specified = true;
4489 m_thread_name = std::string(option_arg);
4490 m_thread_specified = true;
4494 m_queue_name = std::string(option_arg);
4495 m_thread_specified = true;
4499 if (option_arg.getAsInteger(0, m_thread_index))
4500 error.SetErrorStringWithFormat("invalid thread index string '%s'",
4501 option_arg.str().c_str());
4502 m_thread_specified = true;
4506 m_use_one_liner = true;
4507 m_one_liner.push_back(std::string(option_arg));
4511 llvm_unreachable("Unimplemented option");
4516 void OptionParsingStarting(ExecutionContext *execution_context) override {
4517 m_class_name.clear();
4518 m_function_name.clear();
4520 m_line_end = UINT_MAX;
4521 m_file_name.clear();
4522 m_module_name.clear();
4523 m_func_name_type_mask = eFunctionNameTypeAuto;
4524 m_thread_id = LLDB_INVALID_THREAD_ID;
4525 m_thread_index = UINT32_MAX;
4526 m_thread_name.clear();
4527 m_queue_name.clear();
4529 m_no_inlines = false;
4530 m_sym_ctx_specified = false;
4531 m_thread_specified = false;
4533 m_use_one_liner = false;
4534 m_one_liner.clear();
4535 m_auto_continue = false;
4538 std::string m_class_name;
4539 std::string m_function_name;
4540 uint32_t m_line_start;
4541 uint32_t m_line_end;
4542 std::string m_file_name;
4543 std::string m_module_name;
4544 uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType.
4545 lldb::tid_t m_thread_id;
4546 uint32_t m_thread_index;
4547 std::string m_thread_name;
4548 std::string m_queue_name;
4549 bool m_sym_ctx_specified;
4551 bool m_thread_specified;
4552 // Instance variables to hold the values for one_liner options.
4553 bool m_use_one_liner;
4554 std::vector<std::string> m_one_liner;
4555 bool m_auto_continue;
4558 CommandObjectTargetStopHookAdd(CommandInterpreter &interpreter)
4559 : CommandObjectParsed(interpreter, "target stop-hook add",
4560 "Add a hook to be executed when the target stops.",
4561 "target stop-hook add"),
4562 IOHandlerDelegateMultiline("DONE",
4563 IOHandlerDelegate::Completion::LLDBCommand),
4566 ~CommandObjectTargetStopHookAdd() override = default;
4568 Options *GetOptions() override { return &m_options; }
4571 void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
4572 StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
4573 if (output_sp && interactive) {
4574 output_sp->PutCString(
4575 "Enter your stop hook command(s). Type 'DONE' to end.\n");
4580 void IOHandlerInputComplete(IOHandler &io_handler,
4581 std::string &line) override {
4582 if (m_stop_hook_sp) {
4584 StreamFileSP error_sp(io_handler.GetErrorStreamFileSP());
4586 error_sp->Printf("error: stop hook #%" PRIu64
4587 " aborted, no commands.\n",
4588 m_stop_hook_sp->GetID());
4591 Target *target = GetDebugger().GetSelectedTarget().get();
4593 target->RemoveStopHookByID(m_stop_hook_sp->GetID());
4595 m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line);
4596 StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
4598 output_sp->Printf("Stop hook #%" PRIu64 " added.\n",
4599 m_stop_hook_sp->GetID());
4603 m_stop_hook_sp.reset();
4605 io_handler.SetIsDone(true);
4608 bool DoExecute(Args &command, CommandReturnObject &result) override {
4609 m_stop_hook_sp.reset();
4611 Target &target = GetSelectedOrDummyTarget();
4612 Target::StopHookSP new_hook_sp = target.CreateStopHook();
4614 // First step, make the specifier.
4615 std::unique_ptr<SymbolContextSpecifier> specifier_up;
4616 if (m_options.m_sym_ctx_specified) {
4617 specifier_up = std::make_unique<SymbolContextSpecifier>(
4618 GetDebugger().GetSelectedTarget());
4620 if (!m_options.m_module_name.empty()) {
4621 specifier_up->AddSpecification(
4622 m_options.m_module_name.c_str(),
4623 SymbolContextSpecifier::eModuleSpecified);
4626 if (!m_options.m_class_name.empty()) {
4627 specifier_up->AddSpecification(
4628 m_options.m_class_name.c_str(),
4629 SymbolContextSpecifier::eClassOrNamespaceSpecified);
4632 if (!m_options.m_file_name.empty()) {
4633 specifier_up->AddSpecification(m_options.m_file_name.c_str(),
4634 SymbolContextSpecifier::eFileSpecified);
4637 if (m_options.m_line_start != 0) {
4638 specifier_up->AddLineSpecification(
4639 m_options.m_line_start,
4640 SymbolContextSpecifier::eLineStartSpecified);
4643 if (m_options.m_line_end != UINT_MAX) {
4644 specifier_up->AddLineSpecification(
4645 m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
4648 if (!m_options.m_function_name.empty()) {
4649 specifier_up->AddSpecification(
4650 m_options.m_function_name.c_str(),
4651 SymbolContextSpecifier::eFunctionSpecified);
4656 new_hook_sp->SetSpecifier(specifier_up.release());
4658 // Next see if any of the thread options have been entered:
4660 if (m_options.m_thread_specified) {
4661 ThreadSpec *thread_spec = new ThreadSpec();
4663 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) {
4664 thread_spec->SetTID(m_options.m_thread_id);
4667 if (m_options.m_thread_index != UINT32_MAX)
4668 thread_spec->SetIndex(m_options.m_thread_index);
4670 if (!m_options.m_thread_name.empty())
4671 thread_spec->SetName(m_options.m_thread_name.c_str());
4673 if (!m_options.m_queue_name.empty())
4674 thread_spec->SetQueueName(m_options.m_queue_name.c_str());
4676 new_hook_sp->SetThreadSpecifier(thread_spec);
4679 new_hook_sp->SetAutoContinue(m_options.m_auto_continue);
4680 if (m_options.m_use_one_liner) {
4682 for (auto cmd : m_options.m_one_liner)
4683 new_hook_sp->GetCommandPointer()->AppendString(cmd.c_str());
4684 result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
4685 new_hook_sp->GetID());
4687 m_stop_hook_sp = new_hook_sp;
4688 m_interpreter.GetLLDBCommandsFromIOHandler("> ", // Prompt
4689 *this); // IOHandlerDelegate
4691 result.SetStatus(eReturnStatusSuccessFinishNoResult);
4693 return result.Succeeded();
4697 CommandOptions m_options;
4698 Target::StopHookSP m_stop_hook_sp;
4701 #pragma mark CommandObjectTargetStopHookDelete
4703 // CommandObjectTargetStopHookDelete
4705 class CommandObjectTargetStopHookDelete : public CommandObjectParsed {
4707 CommandObjectTargetStopHookDelete(CommandInterpreter &interpreter)
4708 : CommandObjectParsed(interpreter, "target stop-hook delete",
4709 "Delete a stop-hook.",
4710 "target stop-hook delete [<idx>]") {}
4712 ~CommandObjectTargetStopHookDelete() override = default;
4715 bool DoExecute(Args &command, CommandReturnObject &result) override {
4716 Target &target = GetSelectedOrDummyTarget();
4717 // FIXME: see if we can use the breakpoint id style parser?
4718 size_t num_args = command.GetArgumentCount();
4719 if (num_args == 0) {
4720 if (!m_interpreter.Confirm("Delete all stop hooks?", true)) {
4721 result.SetStatus(eReturnStatusFailed);
4724 target.RemoveAllStopHooks();
4727 for (size_t i = 0; i < num_args; i++) {
4728 lldb::user_id_t user_id;
4729 if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
4730 result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4731 command.GetArgumentAtIndex(i));
4732 result.SetStatus(eReturnStatusFailed);
4735 if (!target.RemoveStopHookByID(user_id)) {
4736 result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4737 command.GetArgumentAtIndex(i));
4738 result.SetStatus(eReturnStatusFailed);
4743 result.SetStatus(eReturnStatusSuccessFinishNoResult);
4744 return result.Succeeded();
4748 #pragma mark CommandObjectTargetStopHookEnableDisable
4750 // CommandObjectTargetStopHookEnableDisable
4752 class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed {
4754 CommandObjectTargetStopHookEnableDisable(CommandInterpreter &interpreter,
4755 bool enable, const char *name,
4756 const char *help, const char *syntax)
4757 : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable) {
4760 ~CommandObjectTargetStopHookEnableDisable() override = default;
4763 bool DoExecute(Args &command, CommandReturnObject &result) override {
4764 Target &target = GetSelectedOrDummyTarget();
4765 // FIXME: see if we can use the breakpoint id style parser?
4766 size_t num_args = command.GetArgumentCount();
4769 if (num_args == 0) {
4770 target.SetAllStopHooksActiveState(m_enable);
4772 for (size_t i = 0; i < num_args; i++) {
4773 lldb::user_id_t user_id;
4774 if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
4775 result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4776 command.GetArgumentAtIndex(i));
4777 result.SetStatus(eReturnStatusFailed);
4780 success = target.SetStopHookActiveStateByID(user_id, m_enable);
4782 result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4783 command.GetArgumentAtIndex(i));
4784 result.SetStatus(eReturnStatusFailed);
4789 result.SetStatus(eReturnStatusSuccessFinishNoResult);
4790 return result.Succeeded();
4797 #pragma mark CommandObjectTargetStopHookList
4799 // CommandObjectTargetStopHookList
4801 class CommandObjectTargetStopHookList : public CommandObjectParsed {
4803 CommandObjectTargetStopHookList(CommandInterpreter &interpreter)
4804 : CommandObjectParsed(interpreter, "target stop-hook list",
4805 "List all stop-hooks.",
4806 "target stop-hook list [<type>]") {}
4808 ~CommandObjectTargetStopHookList() override = default;
4811 bool DoExecute(Args &command, CommandReturnObject &result) override {
4812 Target &target = GetSelectedOrDummyTarget();
4814 size_t num_hooks = target.GetNumStopHooks();
4815 if (num_hooks == 0) {
4816 result.GetOutputStream().PutCString("No stop hooks.\n");
4818 for (size_t i = 0; i < num_hooks; i++) {
4819 Target::StopHookSP this_hook = target.GetStopHookAtIndex(i);
4821 result.GetOutputStream().PutCString("\n");
4822 this_hook->GetDescription(&(result.GetOutputStream()),
4823 eDescriptionLevelFull);
4826 result.SetStatus(eReturnStatusSuccessFinishResult);
4827 return result.Succeeded();
4831 #pragma mark CommandObjectMultiwordTargetStopHooks
4833 // CommandObjectMultiwordTargetStopHooks
4835 class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword {
4837 CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter)
4838 : CommandObjectMultiword(
4839 interpreter, "target stop-hook",
4840 "Commands for operating on debugger target stop-hooks.",
4841 "target stop-hook <subcommand> [<subcommand-options>]") {
4842 LoadSubCommand("add", CommandObjectSP(
4843 new CommandObjectTargetStopHookAdd(interpreter)));
4846 CommandObjectSP(new CommandObjectTargetStopHookDelete(interpreter)));
4847 LoadSubCommand("disable",
4848 CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
4849 interpreter, false, "target stop-hook disable [<id>]",
4850 "Disable a stop-hook.", "target stop-hook disable")));
4851 LoadSubCommand("enable",
4852 CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
4853 interpreter, true, "target stop-hook enable [<id>]",
4854 "Enable a stop-hook.", "target stop-hook enable")));
4855 LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetStopHookList(
4859 ~CommandObjectMultiwordTargetStopHooks() override = default;
4862 #pragma mark CommandObjectMultiwordTarget
4864 // CommandObjectMultiwordTarget
4866 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget(
4867 CommandInterpreter &interpreter)
4868 : CommandObjectMultiword(interpreter, "target",
4869 "Commands for operating on debugger targets.",
4870 "target <subcommand> [<subcommand-options>]") {
4871 LoadSubCommand("create",
4872 CommandObjectSP(new CommandObjectTargetCreate(interpreter)));
4873 LoadSubCommand("delete",
4874 CommandObjectSP(new CommandObjectTargetDelete(interpreter)));
4875 LoadSubCommand("list",
4876 CommandObjectSP(new CommandObjectTargetList(interpreter)));
4877 LoadSubCommand("select",
4878 CommandObjectSP(new CommandObjectTargetSelect(interpreter)));
4879 LoadSubCommand("show-launch-environment",
4880 CommandObjectSP(new CommandObjectTargetShowLaunchEnvironment(
4884 CommandObjectSP(new CommandObjectMultiwordTargetStopHooks(interpreter)));
4885 LoadSubCommand("modules",
4886 CommandObjectSP(new CommandObjectTargetModules(interpreter)));
4887 LoadSubCommand("symbols",
4888 CommandObjectSP(new CommandObjectTargetSymbols(interpreter)));
4889 LoadSubCommand("variable",
4890 CommandObjectSP(new CommandObjectTargetVariable(interpreter)));
4893 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget() = default;