1 //===-- CommandObjectTarget.cpp ---------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "CommandObjectTarget.h"
13 #include "lldb/Core/Debugger.h"
14 #include "lldb/Core/IOHandler.h"
15 #include "lldb/Core/Module.h"
16 #include "lldb/Core/ModuleSpec.h"
17 #include "lldb/Core/Section.h"
18 #include "lldb/Core/State.h"
19 #include "lldb/Core/ValueObjectVariable.h"
20 #include "lldb/DataFormatters/ValueObjectPrinter.h"
21 #include "lldb/Host/OptionParser.h"
22 #include "lldb/Host/StringConvert.h"
23 #include "lldb/Host/Symbols.h"
24 #include "lldb/Interpreter/Args.h"
25 #include "lldb/Interpreter/CommandInterpreter.h"
26 #include "lldb/Interpreter/CommandReturnObject.h"
27 #include "lldb/Interpreter/OptionGroupArchitecture.h"
28 #include "lldb/Interpreter/OptionGroupBoolean.h"
29 #include "lldb/Interpreter/OptionGroupFile.h"
30 #include "lldb/Interpreter/OptionGroupFormat.h"
31 #include "lldb/Interpreter/OptionGroupPlatform.h"
32 #include "lldb/Interpreter/OptionGroupString.h"
33 #include "lldb/Interpreter/OptionGroupUInt64.h"
34 #include "lldb/Interpreter/OptionGroupUUID.h"
35 #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
36 #include "lldb/Interpreter/OptionGroupVariable.h"
37 #include "lldb/Interpreter/Options.h"
38 #include "lldb/Symbol/CompileUnit.h"
39 #include "lldb/Symbol/FuncUnwinders.h"
40 #include "lldb/Symbol/LineTable.h"
41 #include "lldb/Symbol/ObjectFile.h"
42 #include "lldb/Symbol/SymbolFile.h"
43 #include "lldb/Symbol/SymbolVendor.h"
44 #include "lldb/Symbol/UnwindPlan.h"
45 #include "lldb/Symbol/VariableList.h"
46 #include "lldb/Target/ABI.h"
47 #include "lldb/Target/Process.h"
48 #include "lldb/Target/SectionLoadList.h"
49 #include "lldb/Target/StackFrame.h"
50 #include "lldb/Target/Thread.h"
51 #include "lldb/Target/ThreadSpec.h"
52 #include "lldb/Utility/Timer.h"
54 #include "llvm/Support/FileSystem.h"
55 #include "llvm/Support/FormatAdapters.h"
62 using namespace lldb_private;
64 static void DumpTargetInfo(uint32_t target_idx, Target *target,
65 const char *prefix_cstr,
66 bool show_stopped_process_status, Stream &strm) {
67 const ArchSpec &target_arch = target->GetArchitecture();
69 Module *exe_module = target->GetExecutableModulePointer();
70 char exe_path[PATH_MAX];
71 bool exe_valid = false;
73 exe_valid = exe_module->GetFileSpec().GetPath(exe_path, sizeof(exe_path));
76 ::strcpy(exe_path, "<none>");
78 strm.Printf("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx,
81 uint32_t properties = 0;
82 if (target_arch.IsValid()) {
83 strm.Printf("%sarch=", properties++ > 0 ? ", " : " ( ");
84 target_arch.DumpTriple(strm);
87 PlatformSP platform_sp(target->GetPlatform());
89 strm.Printf("%splatform=%s", properties++ > 0 ? ", " : " ( ",
90 platform_sp->GetName().GetCString());
92 ProcessSP process_sp(target->GetProcessSP());
93 bool show_process_status = false;
95 lldb::pid_t pid = process_sp->GetID();
96 StateType state = process_sp->GetState();
97 if (show_stopped_process_status)
98 show_process_status = StateIsStoppedState(state, true);
99 const char *state_cstr = StateAsCString(state);
100 if (pid != LLDB_INVALID_PROCESS_ID)
101 strm.Printf("%spid=%" PRIu64, properties++ > 0 ? ", " : " ( ", pid);
102 strm.Printf("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
105 strm.PutCString(" )\n");
108 if (show_process_status) {
109 const bool only_threads_with_stop_reason = true;
110 const uint32_t start_frame = 0;
111 const uint32_t num_frames = 1;
112 const uint32_t num_frames_with_source = 1;
113 const bool stop_format = false;
114 process_sp->GetStatus(strm);
115 process_sp->GetThreadStatus(strm, only_threads_with_stop_reason,
116 start_frame, num_frames,
117 num_frames_with_source, stop_format);
121 static uint32_t DumpTargetList(TargetList &target_list,
122 bool show_stopped_process_status, Stream &strm) {
123 const uint32_t num_targets = target_list.GetNumTargets();
125 TargetSP selected_target_sp(target_list.GetSelectedTarget());
126 strm.PutCString("Current targets:\n");
127 for (uint32_t i = 0; i < num_targets; ++i) {
128 TargetSP target_sp(target_list.GetTargetAtIndex(i));
130 bool is_selected = target_sp.get() == selected_target_sp.get();
131 DumpTargetInfo(i, target_sp.get(), is_selected ? "* " : " ",
132 show_stopped_process_status, strm);
139 #pragma mark CommandObjectTargetCreate
141 //-------------------------------------------------------------------------
143 //-------------------------------------------------------------------------
145 class CommandObjectTargetCreate : public CommandObjectParsed {
147 CommandObjectTargetCreate(CommandInterpreter &interpreter)
148 : CommandObjectParsed(
149 interpreter, "target create",
150 "Create a target using the argument as the main executable.",
152 m_option_group(), m_arch_option(),
153 m_core_file(LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename,
154 "Fullpath to a core file to use for this target."),
155 m_platform_path(LLDB_OPT_SET_1, false, "platform-path", 'P', 0,
157 "Path to the remote file to use for this target."),
158 m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
159 eArgTypeFilename, "Fullpath to a stand alone debug "
160 "symbols file for when debug symbols "
161 "are not in the executable."),
163 LLDB_OPT_SET_1, false, "remote-file", 'r', 0, eArgTypeFilename,
164 "Fullpath to the file on the remote host if debugging remotely."),
165 m_add_dependents(LLDB_OPT_SET_1, false, "no-dependents", 'd',
166 "Don't load dependent files when creating the target, "
167 "just add the specified executable.",
169 CommandArgumentEntry arg;
170 CommandArgumentData file_arg;
172 // Define the first (and only) variant of this arg.
173 file_arg.arg_type = eArgTypeFilename;
174 file_arg.arg_repetition = eArgRepeatPlain;
176 // There is only one variant this argument could be; put it into the
178 arg.push_back(file_arg);
180 // Push the data for the first argument into the m_arguments vector.
181 m_arguments.push_back(arg);
183 m_option_group.Append(&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
184 m_option_group.Append(&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
185 m_option_group.Append(&m_platform_path, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
186 m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
187 m_option_group.Append(&m_remote_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
188 m_option_group.Append(&m_add_dependents, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
189 m_option_group.Finalize();
192 ~CommandObjectTargetCreate() override = default;
194 Options *GetOptions() override { return &m_option_group; }
196 int HandleArgumentCompletion(Args &input, int &cursor_index,
197 int &cursor_char_position,
198 OptionElementVector &opt_element_vector,
199 int match_start_point, int max_return_elements,
201 StringList &matches) override {
202 std::string completion_str(input.GetArgumentAtIndex(cursor_index));
203 completion_str.erase(cursor_char_position);
205 CommandCompletions::InvokeCommonCompletionCallbacks(
206 GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
207 completion_str.c_str(), match_start_point, max_return_elements, nullptr,
208 word_complete, matches);
209 return matches.GetSize();
213 bool DoExecute(Args &command, CommandReturnObject &result) override {
214 const size_t argc = command.GetArgumentCount();
215 FileSpec core_file(m_core_file.GetOptionValue().GetCurrentValue());
216 FileSpec remote_file(m_remote_file.GetOptionValue().GetCurrentValue());
219 if (!core_file.Exists()) {
220 result.AppendErrorWithFormat("core file '%s' doesn't exist",
221 core_file.GetPath().c_str());
222 result.SetStatus(eReturnStatusFailed);
225 if (!core_file.Readable()) {
226 result.AppendErrorWithFormat("core file '%s' is not readable",
227 core_file.GetPath().c_str());
228 result.SetStatus(eReturnStatusFailed);
233 if (argc == 1 || core_file || remote_file) {
234 FileSpec symfile(m_symbol_file.GetOptionValue().GetCurrentValue());
236 if (symfile.Exists()) {
237 if (!symfile.Readable()) {
238 result.AppendErrorWithFormat("symbol file '%s' is not readable",
239 symfile.GetPath().c_str());
240 result.SetStatus(eReturnStatusFailed);
244 char symfile_path[PATH_MAX];
245 symfile.GetPath(symfile_path, sizeof(symfile_path));
246 result.AppendErrorWithFormat("invalid symbol file path '%s'",
248 result.SetStatus(eReturnStatusFailed);
253 const char *file_path = command.GetArgumentAtIndex(0);
254 static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
255 Timer scoped_timer(func_cat, "(lldb) target create '%s'", file_path);
259 file_spec.SetFile(file_path, true);
261 bool must_set_platform_path = false;
263 Debugger &debugger = m_interpreter.GetDebugger();
266 llvm::StringRef arch_cstr = m_arch_option.GetArchitectureName();
267 const bool get_dependent_files =
268 m_add_dependents.GetOptionValue().GetCurrentValue();
269 Status error(debugger.GetTargetList().CreateTarget(
270 debugger, file_path, arch_cstr, get_dependent_files, nullptr,
274 // Only get the platform after we create the target because we might
276 // switched platforms depending on what the arguments were to
278 // we can't rely on the selected platform.
280 PlatformSP platform_sp = target_sp->GetPlatform();
284 // I have a remote file.. two possible cases
285 if (file_spec && file_spec.Exists()) {
286 // if the remote file does not exist, push it there
287 if (!platform_sp->GetFileExists(remote_file)) {
288 Status err = platform_sp->PutFile(file_spec, remote_file);
290 result.AppendError(err.AsCString());
291 result.SetStatus(eReturnStatusFailed);
296 // there is no local file and we need one
297 // in order to make the remote ---> local transfer we need a
299 // TODO: if the user has passed in a --platform argument, use it
300 // to fetch the right platform
303 "unable to perform remote debugging without a platform");
304 result.SetStatus(eReturnStatusFailed);
308 // copy the remote file to the local file
309 Status err = platform_sp->GetFile(remote_file, file_spec);
311 result.AppendError(err.AsCString());
312 result.SetStatus(eReturnStatusFailed);
316 // make up a local file
317 result.AppendError("remote --> local transfer without local "
318 "path is not implemented yet");
319 result.SetStatus(eReturnStatusFailed);
324 result.AppendError("no platform found for target");
325 result.SetStatus(eReturnStatusFailed);
330 if (symfile || remote_file) {
331 ModuleSP module_sp(target_sp->GetExecutableModule());
334 module_sp->SetSymbolFileFileSpec(symfile);
336 std::string remote_path = remote_file.GetPath();
337 target_sp->SetArg0(remote_path.c_str());
338 module_sp->SetPlatformFileSpec(remote_file);
343 debugger.GetTargetList().SetSelectedTarget(target_sp.get());
344 if (must_set_platform_path) {
345 ModuleSpec main_module_spec(file_spec);
346 ModuleSP module_sp = target_sp->GetSharedModule(main_module_spec);
348 module_sp->SetPlatformFileSpec(remote_file);
351 char core_path[PATH_MAX];
352 core_file.GetPath(core_path, sizeof(core_path));
353 if (core_file.Exists()) {
354 if (!core_file.Readable()) {
355 result.AppendMessageWithFormat(
356 "Core file '%s' is not readable.\n", core_path);
357 result.SetStatus(eReturnStatusFailed);
360 FileSpec core_file_dir;
361 core_file_dir.GetDirectory() = core_file.GetDirectory();
362 target_sp->GetExecutableSearchPaths().Append(core_file_dir);
364 ProcessSP process_sp(target_sp->CreateProcess(
365 m_interpreter.GetDebugger().GetListener(), llvm::StringRef(),
369 // Seems weird that we Launch a core file, but that is
371 error = process_sp->LoadCore();
375 error.AsCString("can't find plug-in for core file"));
376 result.SetStatus(eReturnStatusFailed);
379 result.AppendMessageWithFormat(
380 "Core file '%s' (%s) was loaded.\n", core_path,
381 target_sp->GetArchitecture().GetArchitectureName());
382 result.SetStatus(eReturnStatusSuccessFinishNoResult);
385 result.AppendErrorWithFormat(
386 "Unable to find process plug-in for core file '%s'\n",
388 result.SetStatus(eReturnStatusFailed);
391 result.AppendErrorWithFormat("Core file '%s' does not exist\n",
393 result.SetStatus(eReturnStatusFailed);
396 result.AppendMessageWithFormat(
397 "Current executable set to '%s' (%s).\n", file_path,
398 target_sp->GetArchitecture().GetArchitectureName());
399 result.SetStatus(eReturnStatusSuccessFinishNoResult);
402 result.AppendError(error.AsCString());
403 result.SetStatus(eReturnStatusFailed);
406 result.AppendErrorWithFormat("'%s' takes exactly one executable path "
407 "argument, or use the --core option.\n",
409 result.SetStatus(eReturnStatusFailed);
411 return result.Succeeded();
415 OptionGroupOptions m_option_group;
416 OptionGroupArchitecture m_arch_option;
417 OptionGroupFile m_core_file;
418 OptionGroupFile m_platform_path;
419 OptionGroupFile m_symbol_file;
420 OptionGroupFile m_remote_file;
421 OptionGroupBoolean m_add_dependents;
424 #pragma mark CommandObjectTargetList
426 //----------------------------------------------------------------------
428 //----------------------------------------------------------------------
430 class CommandObjectTargetList : public CommandObjectParsed {
432 CommandObjectTargetList(CommandInterpreter &interpreter)
433 : CommandObjectParsed(
434 interpreter, "target list",
435 "List all current targets in the current debug session.", nullptr) {
438 ~CommandObjectTargetList() override = default;
441 bool DoExecute(Args &args, CommandReturnObject &result) override {
442 if (args.GetArgumentCount() == 0) {
443 Stream &strm = result.GetOutputStream();
445 bool show_stopped_process_status = false;
446 if (DumpTargetList(m_interpreter.GetDebugger().GetTargetList(),
447 show_stopped_process_status, strm) == 0) {
448 strm.PutCString("No targets.\n");
450 result.SetStatus(eReturnStatusSuccessFinishResult);
452 result.AppendError("the 'target list' command takes no arguments\n");
453 result.SetStatus(eReturnStatusFailed);
455 return result.Succeeded();
459 #pragma mark CommandObjectTargetSelect
461 //----------------------------------------------------------------------
463 //----------------------------------------------------------------------
465 class CommandObjectTargetSelect : public CommandObjectParsed {
467 CommandObjectTargetSelect(CommandInterpreter &interpreter)
468 : CommandObjectParsed(
469 interpreter, "target select",
470 "Select a target as the current target by target index.", nullptr) {
473 ~CommandObjectTargetSelect() override = default;
476 bool DoExecute(Args &args, CommandReturnObject &result) override {
477 if (args.GetArgumentCount() == 1) {
478 bool success = false;
479 const char *target_idx_arg = args.GetArgumentAtIndex(0);
480 uint32_t target_idx =
481 StringConvert::ToUInt32(target_idx_arg, UINT32_MAX, 0, &success);
483 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
484 const uint32_t num_targets = target_list.GetNumTargets();
485 if (target_idx < num_targets) {
486 TargetSP target_sp(target_list.GetTargetAtIndex(target_idx));
488 Stream &strm = result.GetOutputStream();
489 target_list.SetSelectedTarget(target_sp.get());
490 bool show_stopped_process_status = false;
491 DumpTargetList(target_list, show_stopped_process_status, strm);
492 result.SetStatus(eReturnStatusSuccessFinishResult);
494 result.AppendErrorWithFormat("target #%u is NULL in target list\n",
496 result.SetStatus(eReturnStatusFailed);
499 if (num_targets > 0) {
500 result.AppendErrorWithFormat(
501 "index %u is out of range, valid target indexes are 0 - %u\n",
502 target_idx, num_targets - 1);
504 result.AppendErrorWithFormat(
505 "index %u is out of range since there are no active targets\n",
508 result.SetStatus(eReturnStatusFailed);
511 result.AppendErrorWithFormat("invalid index string value '%s'\n",
513 result.SetStatus(eReturnStatusFailed);
517 "'target select' takes a single argument: a target index\n");
518 result.SetStatus(eReturnStatusFailed);
520 return result.Succeeded();
524 #pragma mark CommandObjectTargetSelect
526 //----------------------------------------------------------------------
528 //----------------------------------------------------------------------
530 class CommandObjectTargetDelete : public CommandObjectParsed {
532 CommandObjectTargetDelete(CommandInterpreter &interpreter)
533 : CommandObjectParsed(interpreter, "target delete",
534 "Delete one or more targets by target index.",
536 m_option_group(), m_all_option(LLDB_OPT_SET_1, false, "all", 'a',
537 "Delete all targets.", false, true),
539 LLDB_OPT_SET_1, false, "clean", 'c',
540 "Perform extra cleanup to minimize memory consumption after "
541 "deleting the target. "
542 "By default, LLDB will keep in memory any modules previously "
543 "loaded by the target as well "
544 "as all of its debug info. Specifying --clean will unload all of "
545 "these shared modules and "
546 "cause them to be reparsed again the next time the target is run",
548 m_option_group.Append(&m_all_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
549 m_option_group.Append(&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
550 m_option_group.Finalize();
553 ~CommandObjectTargetDelete() override = default;
555 Options *GetOptions() override { return &m_option_group; }
558 bool DoExecute(Args &args, CommandReturnObject &result) override {
559 const size_t argc = args.GetArgumentCount();
560 std::vector<TargetSP> delete_target_list;
561 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
564 if (m_all_option.GetOptionValue()) {
565 for (int i = 0; i < target_list.GetNumTargets(); ++i)
566 delete_target_list.push_back(target_list.GetTargetAtIndex(i));
567 } else if (argc > 0) {
568 const uint32_t num_targets = target_list.GetNumTargets();
569 // Bail out if don't have any targets.
570 if (num_targets == 0) {
571 result.AppendError("no targets to delete");
572 result.SetStatus(eReturnStatusFailed);
576 for (auto &entry : args.entries()) {
578 if (entry.ref.getAsInteger(0, target_idx)) {
579 result.AppendErrorWithFormat("invalid target index '%s'\n",
581 result.SetStatus(eReturnStatusFailed);
584 if (target_idx < num_targets) {
585 target_sp = target_list.GetTargetAtIndex(target_idx);
587 delete_target_list.push_back(target_sp);
592 result.AppendErrorWithFormat("target index %u is out of range, valid "
593 "target indexes are 0 - %u\n",
594 target_idx, num_targets - 1);
596 result.AppendErrorWithFormat(
597 "target index %u is out of range, the only valid index is 0\n",
600 result.SetStatus(eReturnStatusFailed);
604 target_sp = target_list.GetSelectedTarget();
606 result.AppendErrorWithFormat("no target is currently selected\n");
607 result.SetStatus(eReturnStatusFailed);
610 delete_target_list.push_back(target_sp);
613 const size_t num_targets_to_delete = delete_target_list.size();
614 for (size_t idx = 0; idx < num_targets_to_delete; ++idx) {
615 target_sp = delete_target_list[idx];
616 target_list.DeleteTarget(target_sp);
617 target_sp->Destroy();
619 // If "--clean" was specified, prune any orphaned shared modules from
620 // the global shared module list
621 if (m_cleanup_option.GetOptionValue()) {
622 const bool mandatory = true;
623 ModuleList::RemoveOrphanSharedModules(mandatory);
625 result.GetOutputStream().Printf("%u targets deleted.\n",
626 (uint32_t)num_targets_to_delete);
627 result.SetStatus(eReturnStatusSuccessFinishResult);
632 OptionGroupOptions m_option_group;
633 OptionGroupBoolean m_all_option;
634 OptionGroupBoolean m_cleanup_option;
637 #pragma mark CommandObjectTargetVariable
639 //----------------------------------------------------------------------
641 //----------------------------------------------------------------------
643 class CommandObjectTargetVariable : public CommandObjectParsed {
644 static const uint32_t SHORT_OPTION_FILE = 0x66696c65; // 'file'
645 static const uint32_t SHORT_OPTION_SHLB = 0x73686c62; // 'shlb'
648 CommandObjectTargetVariable(CommandInterpreter &interpreter)
649 : CommandObjectParsed(interpreter, "target variable",
650 "Read global variables for the current target, "
651 "before or while running a process.",
652 nullptr, eCommandRequiresTarget),
654 m_option_variable(false), // Don't include frame options
655 m_option_format(eFormatDefault),
656 m_option_compile_units(LLDB_OPT_SET_1, false, "file", SHORT_OPTION_FILE,
658 "A basename or fullpath to a file that contains "
659 "global variables. This option can be "
660 "specified multiple times."),
661 m_option_shared_libraries(
662 LLDB_OPT_SET_1, false, "shlib", SHORT_OPTION_SHLB, 0,
664 "A basename or fullpath to a shared library to use in the search "
666 "variables. This option can be specified multiple times."),
668 CommandArgumentEntry arg;
669 CommandArgumentData var_name_arg;
671 // Define the first (and only) variant of this arg.
672 var_name_arg.arg_type = eArgTypeVarName;
673 var_name_arg.arg_repetition = eArgRepeatPlus;
675 // There is only one variant this argument could be; put it into the
677 arg.push_back(var_name_arg);
679 // Push the data for the first argument into the m_arguments vector.
680 m_arguments.push_back(arg);
682 m_option_group.Append(&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
683 m_option_group.Append(&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
684 m_option_group.Append(&m_option_format,
685 OptionGroupFormat::OPTION_GROUP_FORMAT |
686 OptionGroupFormat::OPTION_GROUP_GDB_FMT,
688 m_option_group.Append(&m_option_compile_units, LLDB_OPT_SET_ALL,
690 m_option_group.Append(&m_option_shared_libraries, LLDB_OPT_SET_ALL,
692 m_option_group.Finalize();
695 ~CommandObjectTargetVariable() override = default;
697 void DumpValueObject(Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp,
698 const char *root_name) {
699 DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions());
701 if (!valobj_sp->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
702 valobj_sp->IsRuntimeSupportValue())
705 switch (var_sp->GetScope()) {
706 case eValueTypeVariableGlobal:
707 if (m_option_variable.show_scope)
708 s.PutCString("GLOBAL: ");
711 case eValueTypeVariableStatic:
712 if (m_option_variable.show_scope)
713 s.PutCString("STATIC: ");
716 case eValueTypeVariableArgument:
717 if (m_option_variable.show_scope)
718 s.PutCString(" ARG: ");
721 case eValueTypeVariableLocal:
722 if (m_option_variable.show_scope)
723 s.PutCString(" LOCAL: ");
726 case eValueTypeVariableThreadLocal:
727 if (m_option_variable.show_scope)
728 s.PutCString("THREAD: ");
735 if (m_option_variable.show_decl) {
736 bool show_fullpaths = false;
737 bool show_module = true;
738 if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
742 const Format format = m_option_format.GetFormat();
743 if (format != eFormatDefault)
744 options.SetFormat(format);
746 options.SetRootValueObjectName(root_name);
748 valobj_sp->Dump(s, options);
751 static size_t GetVariableCallback(void *baton, const char *name,
752 VariableList &variable_list) {
753 Target *target = static_cast<Target *>(baton);
755 return target->GetImages().FindGlobalVariables(ConstString(name), true,
756 UINT32_MAX, variable_list);
761 Options *GetOptions() override { return &m_option_group; }
764 void DumpGlobalVariableList(const ExecutionContext &exe_ctx,
765 const SymbolContext &sc,
766 const VariableList &variable_list, Stream &s) {
767 size_t count = variable_list.GetSize();
771 s.Printf("Global variables for %s in %s:\n",
772 sc.comp_unit->GetPath().c_str(),
773 sc.module_sp->GetFileSpec().GetPath().c_str());
775 s.Printf("Global variables for %s\n",
776 sc.module_sp->GetFileSpec().GetPath().c_str());
778 } else if (sc.comp_unit) {
779 s.Printf("Global variables for %s\n", sc.comp_unit->GetPath().c_str());
782 for (uint32_t i = 0; i < count; ++i) {
783 VariableSP var_sp(variable_list.GetVariableAtIndex(i));
785 ValueObjectSP valobj_sp(ValueObjectVariable::Create(
786 exe_ctx.GetBestExecutionContextScope(), var_sp));
789 DumpValueObject(s, var_sp, valobj_sp,
790 var_sp->GetName().GetCString());
796 bool DoExecute(Args &args, CommandReturnObject &result) override {
797 Target *target = m_exe_ctx.GetTargetPtr();
798 const size_t argc = args.GetArgumentCount();
799 Stream &s = result.GetOutputStream();
803 // TODO: Convert to entry-based iteration. Requires converting
805 for (size_t idx = 0; idx < argc; ++idx) {
806 VariableList variable_list;
807 ValueObjectList valobj_list;
809 const char *arg = args.GetArgumentAtIndex(idx);
811 bool use_var_name = false;
812 if (m_option_variable.use_regex) {
813 RegularExpression regex(llvm::StringRef::withNullAsEmpty(arg));
814 if (!regex.IsValid()) {
815 result.GetErrorStream().Printf(
816 "error: invalid regular expression: '%s'\n", arg);
817 result.SetStatus(eReturnStatusFailed);
821 matches = target->GetImages().FindGlobalVariables(
822 regex, true, UINT32_MAX, variable_list);
824 Status error(Variable::GetValuesForVariableExpressionPath(
825 arg, m_exe_ctx.GetBestExecutionContextScope(),
826 GetVariableCallback, target, variable_list, valobj_list));
827 matches = variable_list.GetSize();
831 result.GetErrorStream().Printf(
832 "error: can't find global variable '%s'\n", arg);
833 result.SetStatus(eReturnStatusFailed);
836 for (uint32_t global_idx = 0; global_idx < matches; ++global_idx) {
837 VariableSP var_sp(variable_list.GetVariableAtIndex(global_idx));
839 ValueObjectSP valobj_sp(
840 valobj_list.GetValueObjectAtIndex(global_idx));
842 valobj_sp = ValueObjectVariable::Create(
843 m_exe_ctx.GetBestExecutionContextScope(), var_sp);
846 DumpValueObject(s, var_sp, valobj_sp,
847 use_var_name ? var_sp->GetName().GetCString()
854 const FileSpecList &compile_units =
855 m_option_compile_units.GetOptionValue().GetCurrentValue();
856 const FileSpecList &shlibs =
857 m_option_shared_libraries.GetOptionValue().GetCurrentValue();
858 SymbolContextList sc_list;
859 const size_t num_compile_units = compile_units.GetSize();
860 const size_t num_shlibs = shlibs.GetSize();
861 if (num_compile_units == 0 && num_shlibs == 0) {
862 bool success = false;
863 StackFrame *frame = m_exe_ctx.GetFramePtr();
864 CompileUnit *comp_unit = nullptr;
866 SymbolContext sc = frame->GetSymbolContext(eSymbolContextCompUnit);
868 const bool can_create = true;
869 VariableListSP comp_unit_varlist_sp(
870 sc.comp_unit->GetVariableList(can_create));
871 if (comp_unit_varlist_sp) {
872 size_t count = comp_unit_varlist_sp->GetSize();
874 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
883 result.AppendErrorWithFormat(
884 "no global variables in current compile unit: %s\n",
885 comp_unit->GetPath().c_str());
887 result.AppendErrorWithFormat(
888 "no debug information for frame %u\n",
889 frame->GetFrameIndex());
891 result.AppendError("'target variable' takes one or more global "
892 "variable names as arguments\n");
893 result.SetStatus(eReturnStatusFailed);
896 SymbolContextList sc_list;
897 const bool append = true;
898 // We have one or more compile unit or shlib
899 if (num_shlibs > 0) {
900 for (size_t shlib_idx = 0; shlib_idx < num_shlibs; ++shlib_idx) {
901 const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx));
902 ModuleSpec module_spec(module_file);
905 target->GetImages().FindFirstModule(module_spec));
907 if (num_compile_units > 0) {
908 for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
909 module_sp->FindCompileUnits(
910 compile_units.GetFileSpecAtIndex(cu_idx), append,
914 sc.module_sp = module_sp;
918 // Didn't find matching shlib/module in target...
919 result.AppendErrorWithFormat(
920 "target doesn't contain the specified shared library: %s\n",
921 module_file.GetPath().c_str());
925 // No shared libraries, we just want to find globals for the compile
926 // units files that were specified
927 for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
928 target->GetImages().FindCompileUnits(
929 compile_units.GetFileSpecAtIndex(cu_idx), append, sc_list);
932 const uint32_t num_scs = sc_list.GetSize();
935 for (uint32_t sc_idx = 0; sc_idx < num_scs; ++sc_idx) {
936 if (sc_list.GetContextAtIndex(sc_idx, sc)) {
938 const bool can_create = true;
939 VariableListSP comp_unit_varlist_sp(
940 sc.comp_unit->GetVariableList(can_create));
941 if (comp_unit_varlist_sp)
942 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp,
944 } else if (sc.module_sp) {
945 // Get all global variables for this module
946 lldb_private::RegularExpression all_globals_regex(
948 ".")); // Any global with at least one character
949 VariableList variable_list;
950 sc.module_sp->FindGlobalVariables(all_globals_regex, append,
951 UINT32_MAX, variable_list);
952 DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s);
960 if (m_interpreter.TruncationWarningNecessary()) {
961 result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(),
963 m_interpreter.TruncationWarningGiven();
966 return result.Succeeded();
969 OptionGroupOptions m_option_group;
970 OptionGroupVariable m_option_variable;
971 OptionGroupFormat m_option_format;
972 OptionGroupFileList m_option_compile_units;
973 OptionGroupFileList m_option_shared_libraries;
974 OptionGroupValueObjectDisplay m_varobj_options;
977 #pragma mark CommandObjectTargetModulesSearchPathsAdd
979 class CommandObjectTargetModulesSearchPathsAdd : public CommandObjectParsed {
981 CommandObjectTargetModulesSearchPathsAdd(CommandInterpreter &interpreter)
982 : CommandObjectParsed(interpreter, "target modules search-paths add",
983 "Add new image search paths substitution pairs to "
984 "the current target.",
986 CommandArgumentEntry arg;
987 CommandArgumentData old_prefix_arg;
988 CommandArgumentData new_prefix_arg;
990 // Define the first variant of this arg pair.
991 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
992 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
994 // Define the first variant of this arg pair.
995 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
996 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
998 // There are two required arguments that must always occur together, i.e. an
999 // argument "pair". Because they
1000 // must always occur together, they are treated as two variants of one
1001 // argument rather than two independent
1002 // arguments. Push them both into the first argument position for
1005 arg.push_back(old_prefix_arg);
1006 arg.push_back(new_prefix_arg);
1008 m_arguments.push_back(arg);
1011 ~CommandObjectTargetModulesSearchPathsAdd() override = default;
1014 bool DoExecute(Args &command, CommandReturnObject &result) override {
1015 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1017 const size_t argc = command.GetArgumentCount();
1019 result.AppendError("add requires an even number of arguments\n");
1020 result.SetStatus(eReturnStatusFailed);
1022 for (size_t i = 0; i < argc; i += 2) {
1023 const char *from = command.GetArgumentAtIndex(i);
1024 const char *to = command.GetArgumentAtIndex(i + 1);
1026 if (from[0] && to[0]) {
1027 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
1029 log->Printf("target modules search path adding ImageSearchPath "
1030 "pair: '%s' -> '%s'",
1033 bool last_pair = ((argc - i) == 2);
1034 target->GetImageSearchPathList().Append(
1035 ConstString(from), ConstString(to),
1036 last_pair); // Notify if this is the last pair
1037 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1040 result.AppendError("<path-prefix> can't be empty\n");
1042 result.AppendError("<new-path-prefix> can't be empty\n");
1043 result.SetStatus(eReturnStatusFailed);
1048 result.AppendError("invalid target\n");
1049 result.SetStatus(eReturnStatusFailed);
1051 return result.Succeeded();
1055 #pragma mark CommandObjectTargetModulesSearchPathsClear
1057 class CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed {
1059 CommandObjectTargetModulesSearchPathsClear(CommandInterpreter &interpreter)
1060 : CommandObjectParsed(interpreter, "target modules search-paths clear",
1061 "Clear all current image search path substitution "
1062 "pairs from the current target.",
1063 "target modules search-paths clear") {}
1065 ~CommandObjectTargetModulesSearchPathsClear() override = default;
1068 bool DoExecute(Args &command, CommandReturnObject &result) override {
1069 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1072 target->GetImageSearchPathList().Clear(notify);
1073 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1075 result.AppendError("invalid target\n");
1076 result.SetStatus(eReturnStatusFailed);
1078 return result.Succeeded();
1082 #pragma mark CommandObjectTargetModulesSearchPathsInsert
1084 class CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed {
1086 CommandObjectTargetModulesSearchPathsInsert(CommandInterpreter &interpreter)
1087 : CommandObjectParsed(interpreter, "target modules search-paths insert",
1088 "Insert a new image search path substitution pair "
1089 "into the current target at the specified index.",
1091 CommandArgumentEntry arg1;
1092 CommandArgumentEntry arg2;
1093 CommandArgumentData index_arg;
1094 CommandArgumentData old_prefix_arg;
1095 CommandArgumentData new_prefix_arg;
1097 // Define the first and only variant of this arg.
1098 index_arg.arg_type = eArgTypeIndex;
1099 index_arg.arg_repetition = eArgRepeatPlain;
1101 // Put the one and only variant into the first arg for m_arguments:
1102 arg1.push_back(index_arg);
1104 // Define the first variant of this arg pair.
1105 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1106 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1108 // Define the first variant of this arg pair.
1109 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1110 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1112 // There are two required arguments that must always occur together, i.e. an
1113 // argument "pair". Because they
1114 // must always occur together, they are treated as two variants of one
1115 // argument rather than two independent
1116 // arguments. Push them both into the same argument position for
1119 arg2.push_back(old_prefix_arg);
1120 arg2.push_back(new_prefix_arg);
1122 // Add arguments to m_arguments.
1123 m_arguments.push_back(arg1);
1124 m_arguments.push_back(arg2);
1127 ~CommandObjectTargetModulesSearchPathsInsert() override = default;
1130 bool DoExecute(Args &command, CommandReturnObject &result) override {
1131 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1133 size_t argc = command.GetArgumentCount();
1134 // check for at least 3 arguments and an odd number of parameters
1135 if (argc >= 3 && argc & 1) {
1136 bool success = false;
1138 uint32_t insert_idx = StringConvert::ToUInt32(
1139 command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);
1142 result.AppendErrorWithFormat(
1143 "<index> parameter is not an integer: '%s'.\n",
1144 command.GetArgumentAtIndex(0));
1145 result.SetStatus(eReturnStatusFailed);
1146 return result.Succeeded();
1149 // shift off the index
1151 argc = command.GetArgumentCount();
1153 for (uint32_t i = 0; i < argc; i += 2, ++insert_idx) {
1154 const char *from = command.GetArgumentAtIndex(i);
1155 const char *to = command.GetArgumentAtIndex(i + 1);
1157 if (from[0] && to[0]) {
1158 bool last_pair = ((argc - i) == 2);
1159 target->GetImageSearchPathList().Insert(
1160 ConstString(from), ConstString(to), insert_idx, last_pair);
1161 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1164 result.AppendError("<path-prefix> can't be empty\n");
1166 result.AppendError("<new-path-prefix> can't be empty\n");
1167 result.SetStatus(eReturnStatusFailed);
1172 result.AppendError("insert requires at least three arguments\n");
1173 result.SetStatus(eReturnStatusFailed);
1174 return result.Succeeded();
1178 result.AppendError("invalid target\n");
1179 result.SetStatus(eReturnStatusFailed);
1181 return result.Succeeded();
1185 #pragma mark CommandObjectTargetModulesSearchPathsList
1187 class CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed {
1189 CommandObjectTargetModulesSearchPathsList(CommandInterpreter &interpreter)
1190 : CommandObjectParsed(interpreter, "target modules search-paths list",
1191 "List all current image search path substitution "
1192 "pairs in the current target.",
1193 "target modules search-paths list") {}
1195 ~CommandObjectTargetModulesSearchPathsList() override = default;
1198 bool DoExecute(Args &command, CommandReturnObject &result) override {
1199 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1201 if (command.GetArgumentCount() != 0) {
1202 result.AppendError("list takes no arguments\n");
1203 result.SetStatus(eReturnStatusFailed);
1204 return result.Succeeded();
1207 target->GetImageSearchPathList().Dump(&result.GetOutputStream());
1208 result.SetStatus(eReturnStatusSuccessFinishResult);
1210 result.AppendError("invalid target\n");
1211 result.SetStatus(eReturnStatusFailed);
1213 return result.Succeeded();
1217 #pragma mark CommandObjectTargetModulesSearchPathsQuery
1219 class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed {
1221 CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter &interpreter)
1222 : CommandObjectParsed(
1223 interpreter, "target modules search-paths query",
1224 "Transform a path using the first applicable image search path.",
1226 CommandArgumentEntry arg;
1227 CommandArgumentData path_arg;
1229 // Define the first (and only) variant of this arg.
1230 path_arg.arg_type = eArgTypeDirectoryName;
1231 path_arg.arg_repetition = eArgRepeatPlain;
1233 // There is only one variant this argument could be; put it into the
1235 arg.push_back(path_arg);
1237 // Push the data for the first argument into the m_arguments vector.
1238 m_arguments.push_back(arg);
1241 ~CommandObjectTargetModulesSearchPathsQuery() override = default;
1244 bool DoExecute(Args &command, CommandReturnObject &result) override {
1245 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1247 if (command.GetArgumentCount() != 1) {
1248 result.AppendError("query requires one argument\n");
1249 result.SetStatus(eReturnStatusFailed);
1250 return result.Succeeded();
1253 ConstString orig(command.GetArgumentAtIndex(0));
1254 ConstString transformed;
1255 if (target->GetImageSearchPathList().RemapPath(orig, transformed))
1256 result.GetOutputStream().Printf("%s\n", transformed.GetCString());
1258 result.GetOutputStream().Printf("%s\n", orig.GetCString());
1260 result.SetStatus(eReturnStatusSuccessFinishResult);
1262 result.AppendError("invalid target\n");
1263 result.SetStatus(eReturnStatusFailed);
1265 return result.Succeeded();
1269 //----------------------------------------------------------------------
1270 // Static Helper functions
1271 //----------------------------------------------------------------------
1272 static void DumpModuleArchitecture(Stream &strm, Module *module,
1273 bool full_triple, uint32_t width) {
1275 StreamString arch_strm;
1278 module->GetArchitecture().DumpTriple(arch_strm);
1280 arch_strm.PutCString(module->GetArchitecture().GetArchitectureName());
1281 std::string arch_str = arch_strm.GetString();
1284 strm.Printf("%-*s", width, arch_str.c_str());
1286 strm.PutCString(arch_str);
1290 static void DumpModuleUUID(Stream &strm, Module *module) {
1291 if (module && module->GetUUID().IsValid())
1292 module->GetUUID().Dump(&strm);
1294 strm.PutCString(" ");
1297 static uint32_t DumpCompileUnitLineTable(CommandInterpreter &interpreter,
1298 Stream &strm, Module *module,
1299 const FileSpec &file_spec,
1300 bool load_addresses) {
1301 uint32_t num_matches = 0;
1303 SymbolContextList sc_list;
1304 num_matches = module->ResolveSymbolContextsForFileSpec(
1305 file_spec, 0, false, eSymbolContextCompUnit, sc_list);
1307 for (uint32_t i = 0; i < num_matches; ++i) {
1309 if (sc_list.GetContextAtIndex(i, sc)) {
1313 strm << "Line table for " << *static_cast<FileSpec *>(sc.comp_unit)
1314 << " in `" << module->GetFileSpec().GetFilename() << "\n";
1315 LineTable *line_table = sc.comp_unit->GetLineTable();
1317 line_table->GetDescription(
1318 &strm, interpreter.GetExecutionContext().GetTargetPtr(),
1319 lldb::eDescriptionLevelBrief);
1321 strm << "No line table";
1328 static void DumpFullpath(Stream &strm, const FileSpec *file_spec_ptr,
1330 if (file_spec_ptr) {
1332 std::string fullpath = file_spec_ptr->GetPath();
1333 strm.Printf("%-*s", width, fullpath.c_str());
1336 file_spec_ptr->Dump(&strm);
1340 // Keep the width spacing correct if things go wrong...
1342 strm.Printf("%-*s", width, "");
1345 static void DumpDirectory(Stream &strm, const FileSpec *file_spec_ptr,
1347 if (file_spec_ptr) {
1349 strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
1351 file_spec_ptr->GetDirectory().Dump(&strm);
1354 // Keep the width spacing correct if things go wrong...
1356 strm.Printf("%-*s", width, "");
1359 static void DumpBasename(Stream &strm, const FileSpec *file_spec_ptr,
1361 if (file_spec_ptr) {
1363 strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
1365 file_spec_ptr->GetFilename().Dump(&strm);
1368 // Keep the width spacing correct if things go wrong...
1370 strm.Printf("%-*s", width, "");
1373 static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) {
1374 size_t num_dumped = 0;
1375 std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
1376 const size_t num_modules = module_list.GetSize();
1377 if (num_modules > 0) {
1378 strm.Printf("Dumping headers for %" PRIu64 " module(s).\n",
1379 static_cast<uint64_t>(num_modules));
1381 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
1382 Module *module = module_list.GetModulePointerAtIndexUnlocked(image_idx);
1384 if (num_dumped++ > 0) {
1388 ObjectFile *objfile = module->GetObjectFile();
1389 objfile->Dump(&strm);
1397 static void DumpModuleSymtab(CommandInterpreter &interpreter, Stream &strm,
1398 Module *module, SortOrder sort_order) {
1400 SymbolVendor *sym_vendor = module->GetSymbolVendor();
1402 Symtab *symtab = sym_vendor->GetSymtab();
1404 symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(),
1410 static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm,
1413 SectionList *section_list = module->GetSectionList();
1415 strm.Printf("Sections for '%s' (%s):\n",
1416 module->GetSpecificationDescription().c_str(),
1417 module->GetArchitecture().GetArchitectureName());
1419 section_list->Dump(&strm,
1420 interpreter.GetExecutionContext().GetTargetPtr(), true,
1427 static bool DumpModuleSymbolVendor(Stream &strm, Module *module) {
1429 SymbolVendor *symbol_vendor = module->GetSymbolVendor(true);
1430 if (symbol_vendor) {
1431 symbol_vendor->Dump(&strm);
1438 static void DumpAddress(ExecutionContextScope *exe_scope,
1439 const Address &so_addr, bool verbose, Stream &strm) {
1441 strm.Indent(" Address: ");
1442 so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
1443 strm.PutCString(" (");
1444 so_addr.Dump(&strm, exe_scope, Address::DumpStyleSectionNameOffset);
1445 strm.PutCString(")\n");
1446 strm.Indent(" Summary: ");
1447 const uint32_t save_indent = strm.GetIndentLevel();
1448 strm.SetIndentLevel(save_indent + 13);
1449 so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription);
1450 strm.SetIndentLevel(save_indent);
1451 // Print out detailed address information when verbose is enabled
1454 so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext);
1459 static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm,
1460 Module *module, uint32_t resolve_mask,
1461 lldb::addr_t raw_addr, lldb::addr_t offset,
1464 lldb::addr_t addr = raw_addr - offset;
1467 Target *target = interpreter.GetExecutionContext().GetTargetPtr();
1468 if (target && !target->GetSectionLoadList().IsEmpty()) {
1469 if (!target->GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
1471 else if (so_addr.GetModule().get() != module)
1474 if (!module->ResolveFileAddress(addr, so_addr))
1478 ExecutionContextScope *exe_scope =
1479 interpreter.GetExecutionContext().GetBestExecutionContextScope();
1480 DumpAddress(exe_scope, so_addr, verbose, strm);
1481 // strm.IndentMore();
1482 // strm.Indent (" Address: ");
1483 // so_addr.Dump (&strm, exe_scope,
1484 // Address::DumpStyleModuleWithFileAddress);
1485 // strm.PutCString (" (");
1486 // so_addr.Dump (&strm, exe_scope,
1487 // Address::DumpStyleSectionNameOffset);
1488 // strm.PutCString (")\n");
1489 // strm.Indent (" Summary: ");
1490 // const uint32_t save_indent = strm.GetIndentLevel ();
1491 // strm.SetIndentLevel (save_indent + 13);
1492 // so_addr.Dump (&strm, exe_scope,
1493 // Address::DumpStyleResolvedDescription);
1494 // strm.SetIndentLevel (save_indent);
1495 // // Print out detailed address information when verbose is enabled
1499 // so_addr.Dump (&strm, exe_scope,
1500 // Address::DumpStyleDetailedSymbolContext);
1502 // strm.IndentLess();
1509 static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
1510 Stream &strm, Module *module,
1511 const char *name, bool name_is_regex,
1516 SymbolVendor *sym_vendor = module->GetSymbolVendor();
1518 Symtab *symtab = sym_vendor->GetSymtab();
1520 std::vector<uint32_t> match_indexes;
1521 ConstString symbol_name(name);
1522 uint32_t num_matches = 0;
1523 if (name_is_regex) {
1524 RegularExpression name_regexp(symbol_name.GetStringRef());
1525 num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType(
1526 name_regexp, eSymbolTypeAny, match_indexes);
1529 symtab->AppendSymbolIndexesWithName(symbol_name, match_indexes);
1532 if (num_matches > 0) {
1534 strm.Printf("%u symbols match %s'%s' in ", num_matches,
1535 name_is_regex ? "the regular expression " : "", name);
1536 DumpFullpath(strm, &module->GetFileSpec(), 0);
1537 strm.PutCString(":\n");
1539 for (uint32_t i = 0; i < num_matches; ++i) {
1540 Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
1541 if (symbol && symbol->ValueIsAddress()) {
1542 DumpAddress(interpreter.GetExecutionContext()
1543 .GetBestExecutionContextScope(),
1544 symbol->GetAddressRef(), verbose, strm);
1556 static void DumpSymbolContextList(ExecutionContextScope *exe_scope,
1557 Stream &strm, SymbolContextList &sc_list,
1561 const uint32_t num_matches = sc_list.GetSize();
1563 for (uint32_t i = 0; i < num_matches; ++i) {
1565 if (sc_list.GetContextAtIndex(i, sc)) {
1568 sc.GetAddressRange(eSymbolContextEverything, 0, true, range);
1570 DumpAddress(exe_scope, range.GetBaseAddress(), verbose, strm);
1576 static size_t LookupFunctionInModule(CommandInterpreter &interpreter,
1577 Stream &strm, Module *module,
1578 const char *name, bool name_is_regex,
1579 bool include_inlines, bool include_symbols,
1581 if (module && name && name[0]) {
1582 SymbolContextList sc_list;
1583 const bool append = true;
1584 size_t num_matches = 0;
1585 if (name_is_regex) {
1586 RegularExpression function_name_regex((llvm::StringRef(name)));
1587 num_matches = module->FindFunctions(function_name_regex, include_symbols,
1588 include_inlines, append, sc_list);
1590 ConstString function_name(name);
1591 num_matches = module->FindFunctions(
1592 function_name, nullptr, eFunctionNameTypeAuto, include_symbols,
1593 include_inlines, append, sc_list);
1598 strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
1599 num_matches > 1 ? "es" : "");
1600 DumpFullpath(strm, &module->GetFileSpec(), 0);
1601 strm.PutCString(":\n");
1602 DumpSymbolContextList(
1603 interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1604 strm, sc_list, verbose);
1611 static size_t LookupTypeInModule(CommandInterpreter &interpreter, Stream &strm,
1612 Module *module, const char *name_cstr,
1613 bool name_is_regex) {
1614 if (module && name_cstr && name_cstr[0]) {
1616 const uint32_t max_num_matches = UINT32_MAX;
1617 size_t num_matches = 0;
1618 bool name_is_fully_qualified = false;
1621 ConstString name(name_cstr);
1622 llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
1624 module->FindTypes(sc, name, name_is_fully_qualified, max_num_matches,
1625 searched_symbol_files, type_list);
1629 strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
1630 num_matches > 1 ? "es" : "");
1631 DumpFullpath(strm, &module->GetFileSpec(), 0);
1632 strm.PutCString(":\n");
1633 for (TypeSP type_sp : type_list.Types()) {
1635 // Resolve the clang type so that any forward references
1636 // to types that haven't yet been parsed will get parsed.
1637 type_sp->GetFullCompilerType();
1638 type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
1639 // Print all typedef chains
1640 TypeSP typedef_type_sp(type_sp);
1641 TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1642 while (typedefed_type_sp) {
1644 strm.Printf(" typedef '%s': ",
1645 typedef_type_sp->GetName().GetCString());
1646 typedefed_type_sp->GetFullCompilerType();
1647 typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull,
1649 typedef_type_sp = typedefed_type_sp;
1650 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1661 static size_t LookupTypeHere(CommandInterpreter &interpreter, Stream &strm,
1662 const SymbolContext &sym_ctx,
1663 const char *name_cstr, bool name_is_regex) {
1664 if (!sym_ctx.module_sp)
1668 const uint32_t max_num_matches = UINT32_MAX;
1669 size_t num_matches = 1;
1670 bool name_is_fully_qualified = false;
1672 ConstString name(name_cstr);
1673 llvm::DenseSet<SymbolFile *> searched_symbol_files;
1674 num_matches = sym_ctx.module_sp->FindTypes(
1675 sym_ctx, name, name_is_fully_qualified, max_num_matches,
1676 searched_symbol_files, type_list);
1680 strm.PutCString("Best match found in ");
1681 DumpFullpath(strm, &sym_ctx.module_sp->GetFileSpec(), 0);
1682 strm.PutCString(":\n");
1684 TypeSP type_sp(type_list.GetTypeAtIndex(0));
1686 // Resolve the clang type so that any forward references
1687 // to types that haven't yet been parsed will get parsed.
1688 type_sp->GetFullCompilerType();
1689 type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
1690 // Print all typedef chains
1691 TypeSP typedef_type_sp(type_sp);
1692 TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1693 while (typedefed_type_sp) {
1695 strm.Printf(" typedef '%s': ",
1696 typedef_type_sp->GetName().GetCString());
1697 typedefed_type_sp->GetFullCompilerType();
1698 typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
1699 typedef_type_sp = typedefed_type_sp;
1700 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1708 static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter,
1709 Stream &strm, Module *module,
1710 const FileSpec &file_spec,
1711 uint32_t line, bool check_inlines,
1713 if (module && file_spec) {
1714 SymbolContextList sc_list;
1715 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(
1716 file_spec, line, check_inlines, eSymbolContextEverything, sc_list);
1717 if (num_matches > 0) {
1719 strm.Printf("%u match%s found in ", num_matches,
1720 num_matches > 1 ? "es" : "");
1723 strm.Printf(":%u", line);
1725 DumpFullpath(strm, &module->GetFileSpec(), 0);
1726 strm.PutCString(":\n");
1727 DumpSymbolContextList(
1728 interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1729 strm, sc_list, verbose);
1736 static size_t FindModulesByName(Target *target, const char *module_name,
1737 ModuleList &module_list,
1738 bool check_global_list) {
1739 FileSpec module_file_spec(module_name, false);
1740 ModuleSpec module_spec(module_file_spec);
1742 const size_t initial_size = module_list.GetSize();
1744 if (check_global_list) {
1745 // Check the global list
1746 std::lock_guard<std::recursive_mutex> guard(
1747 Module::GetAllocationModuleCollectionMutex());
1748 const size_t num_modules = Module::GetNumberAllocatedModules();
1750 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
1751 Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
1754 if (module->MatchesModuleSpec(module_spec)) {
1755 module_sp = module->shared_from_this();
1756 module_list.AppendIfNeeded(module_sp);
1762 const size_t num_matches =
1763 target->GetImages().FindModules(module_spec, module_list);
1765 // Not found in our module list for our target, check the main
1766 // shared module list in case it is a extra file used somewhere
1768 if (num_matches == 0) {
1769 module_spec.GetArchitecture() = target->GetArchitecture();
1770 ModuleList::FindSharedModules(module_spec, module_list);
1773 ModuleList::FindSharedModules(module_spec, module_list);
1777 return module_list.GetSize() - initial_size;
1780 #pragma mark CommandObjectTargetModulesModuleAutoComplete
1782 //----------------------------------------------------------------------
1783 // A base command object class that can auto complete with module file
1785 //----------------------------------------------------------------------
1787 class CommandObjectTargetModulesModuleAutoComplete
1788 : public CommandObjectParsed {
1790 CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter &interpreter,
1794 : CommandObjectParsed(interpreter, name, help, syntax) {
1795 CommandArgumentEntry arg;
1796 CommandArgumentData file_arg;
1798 // Define the first (and only) variant of this arg.
1799 file_arg.arg_type = eArgTypeFilename;
1800 file_arg.arg_repetition = eArgRepeatStar;
1802 // There is only one variant this argument could be; put it into the
1804 arg.push_back(file_arg);
1806 // Push the data for the first argument into the m_arguments vector.
1807 m_arguments.push_back(arg);
1810 ~CommandObjectTargetModulesModuleAutoComplete() override = default;
1812 int HandleArgumentCompletion(Args &input, int &cursor_index,
1813 int &cursor_char_position,
1814 OptionElementVector &opt_element_vector,
1815 int match_start_point, int max_return_elements,
1816 bool &word_complete,
1817 StringList &matches) override {
1818 // Arguments are the standard module completer.
1819 std::string completion_str(input.GetArgumentAtIndex(cursor_index));
1820 completion_str.erase(cursor_char_position);
1822 CommandCompletions::InvokeCommonCompletionCallbacks(
1823 GetCommandInterpreter(), CommandCompletions::eModuleCompletion,
1824 completion_str.c_str(), match_start_point, max_return_elements, nullptr,
1825 word_complete, matches);
1826 return matches.GetSize();
1830 #pragma mark CommandObjectTargetModulesSourceFileAutoComplete
1832 //----------------------------------------------------------------------
1833 // A base command object class that can auto complete with module source
1835 //----------------------------------------------------------------------
1837 class CommandObjectTargetModulesSourceFileAutoComplete
1838 : public CommandObjectParsed {
1840 CommandObjectTargetModulesSourceFileAutoComplete(
1841 CommandInterpreter &interpreter, const char *name, const char *help,
1842 const char *syntax, uint32_t flags)
1843 : CommandObjectParsed(interpreter, name, help, syntax, flags) {
1844 CommandArgumentEntry arg;
1845 CommandArgumentData source_file_arg;
1847 // Define the first (and only) variant of this arg.
1848 source_file_arg.arg_type = eArgTypeSourceFile;
1849 source_file_arg.arg_repetition = eArgRepeatPlus;
1851 // There is only one variant this argument could be; put it into the
1853 arg.push_back(source_file_arg);
1855 // Push the data for the first argument into the m_arguments vector.
1856 m_arguments.push_back(arg);
1859 ~CommandObjectTargetModulesSourceFileAutoComplete() override = default;
1861 int HandleArgumentCompletion(Args &input, int &cursor_index,
1862 int &cursor_char_position,
1863 OptionElementVector &opt_element_vector,
1864 int match_start_point, int max_return_elements,
1865 bool &word_complete,
1866 StringList &matches) override {
1867 // Arguments are the standard source file completer.
1868 std::string completion_str(input.GetArgumentAtIndex(cursor_index));
1869 completion_str.erase(cursor_char_position);
1871 CommandCompletions::InvokeCommonCompletionCallbacks(
1872 GetCommandInterpreter(), CommandCompletions::eSourceFileCompletion,
1873 completion_str.c_str(), match_start_point, max_return_elements, nullptr,
1874 word_complete, matches);
1875 return matches.GetSize();
1879 #pragma mark CommandObjectTargetModulesDumpObjfile
1881 class CommandObjectTargetModulesDumpObjfile
1882 : public CommandObjectTargetModulesModuleAutoComplete {
1884 CommandObjectTargetModulesDumpObjfile(CommandInterpreter &interpreter)
1885 : CommandObjectTargetModulesModuleAutoComplete(
1886 interpreter, "target modules dump objfile",
1887 "Dump the object file headers from one or more target modules.",
1890 ~CommandObjectTargetModulesDumpObjfile() override = default;
1893 bool DoExecute(Args &command, CommandReturnObject &result) override {
1894 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1895 if (target == nullptr) {
1896 result.AppendError("invalid target, create a debug target using the "
1897 "'target create' command");
1898 result.SetStatus(eReturnStatusFailed);
1902 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1903 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1904 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1906 size_t num_dumped = 0;
1907 if (command.GetArgumentCount() == 0) {
1908 // Dump all headers for all modules images
1909 num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(),
1910 target->GetImages());
1911 if (num_dumped == 0) {
1912 result.AppendError("the target has no associated executable images");
1913 result.SetStatus(eReturnStatusFailed);
1916 // Find the modules that match the basename or full path.
1917 ModuleList module_list;
1918 const char *arg_cstr;
1919 for (int arg_idx = 0;
1920 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
1922 size_t num_matched =
1923 FindModulesByName(target, arg_cstr, module_list, true);
1924 if (num_matched == 0) {
1925 result.AppendWarningWithFormat(
1926 "Unable to find an image that matches '%s'.\n", arg_cstr);
1929 // Dump all the modules we found.
1931 DumpModuleObjfileHeaders(result.GetOutputStream(), module_list);
1934 if (num_dumped > 0) {
1935 result.SetStatus(eReturnStatusSuccessFinishResult);
1937 result.AppendError("no matching executable images found");
1938 result.SetStatus(eReturnStatusFailed);
1940 return result.Succeeded();
1944 #pragma mark CommandObjectTargetModulesDumpSymtab
1946 static OptionEnumValueElement g_sort_option_enumeration[4] = {
1947 {eSortOrderNone, "none",
1948 "No sorting, use the original symbol table order."},
1949 {eSortOrderByAddress, "address", "Sort output by symbol address."},
1950 {eSortOrderByName, "name", "Sort output by symbol name."},
1951 {0, nullptr, nullptr}};
1953 static OptionDefinition g_target_modules_dump_symtab_options[] = {
1955 { LLDB_OPT_SET_1, false, "sort", 's', OptionParser::eRequiredArgument, nullptr, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table." }
1959 class CommandObjectTargetModulesDumpSymtab
1960 : public CommandObjectTargetModulesModuleAutoComplete {
1962 CommandObjectTargetModulesDumpSymtab(CommandInterpreter &interpreter)
1963 : CommandObjectTargetModulesModuleAutoComplete(
1964 interpreter, "target modules dump symtab",
1965 "Dump the symbol table from one or more target modules.", nullptr),
1968 ~CommandObjectTargetModulesDumpSymtab() override = default;
1970 Options *GetOptions() override { return &m_options; }
1972 class CommandOptions : public Options {
1974 CommandOptions() : Options(), m_sort_order(eSortOrderNone) {}
1976 ~CommandOptions() override = default;
1978 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1979 ExecutionContext *execution_context) override {
1981 const int short_option = m_getopt_table[option_idx].val;
1983 switch (short_option) {
1985 m_sort_order = (SortOrder)Args::StringToOptionEnum(
1986 option_arg, GetDefinitions()[option_idx].enum_values,
1987 eSortOrderNone, error);
1991 error.SetErrorStringWithFormat("invalid short option character '%c'",
1998 void OptionParsingStarting(ExecutionContext *execution_context) override {
1999 m_sort_order = eSortOrderNone;
2002 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2003 return llvm::makeArrayRef(g_target_modules_dump_symtab_options);
2006 SortOrder m_sort_order;
2010 bool DoExecute(Args &command, CommandReturnObject &result) override {
2011 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2012 if (target == nullptr) {
2013 result.AppendError("invalid target, create a debug target using the "
2014 "'target create' command");
2015 result.SetStatus(eReturnStatusFailed);
2018 uint32_t num_dumped = 0;
2020 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2021 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2022 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2024 if (command.GetArgumentCount() == 0) {
2025 // Dump all sections for all modules images
2026 std::lock_guard<std::recursive_mutex> guard(
2027 target->GetImages().GetMutex());
2028 const size_t num_modules = target->GetImages().GetSize();
2029 if (num_modules > 0) {
2030 result.GetOutputStream().Printf("Dumping symbol table for %" PRIu64
2032 (uint64_t)num_modules);
2033 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2034 if (num_dumped > 0) {
2035 result.GetOutputStream().EOL();
2036 result.GetOutputStream().EOL();
2038 if (m_interpreter.WasInterrupted())
2042 m_interpreter, result.GetOutputStream(),
2043 target->GetImages().GetModulePointerAtIndexUnlocked(image_idx),
2044 m_options.m_sort_order);
2047 result.AppendError("the target has no associated executable images");
2048 result.SetStatus(eReturnStatusFailed);
2052 // Dump specified images (by basename or fullpath)
2053 const char *arg_cstr;
2054 for (int arg_idx = 0;
2055 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2057 ModuleList module_list;
2058 const size_t num_matches =
2059 FindModulesByName(target, arg_cstr, module_list, true);
2060 if (num_matches > 0) {
2061 for (size_t i = 0; i < num_matches; ++i) {
2062 Module *module = module_list.GetModulePointerAtIndex(i);
2064 if (num_dumped > 0) {
2065 result.GetOutputStream().EOL();
2066 result.GetOutputStream().EOL();
2068 if (m_interpreter.WasInterrupted())
2071 DumpModuleSymtab(m_interpreter, result.GetOutputStream(),
2072 module, m_options.m_sort_order);
2076 result.AppendWarningWithFormat(
2077 "Unable to find an image that matches '%s'.\n", arg_cstr);
2082 result.SetStatus(eReturnStatusSuccessFinishResult);
2084 result.AppendError("no matching executable images found");
2085 result.SetStatus(eReturnStatusFailed);
2088 return result.Succeeded();
2091 CommandOptions m_options;
2094 #pragma mark CommandObjectTargetModulesDumpSections
2096 //----------------------------------------------------------------------
2097 // Image section dumping command
2098 //----------------------------------------------------------------------
2100 class CommandObjectTargetModulesDumpSections
2101 : public CommandObjectTargetModulesModuleAutoComplete {
2103 CommandObjectTargetModulesDumpSections(CommandInterpreter &interpreter)
2104 : CommandObjectTargetModulesModuleAutoComplete(
2105 interpreter, "target modules dump sections",
2106 "Dump the sections from one or more target modules.",
2107 //"target modules dump sections [<file1> ...]")
2110 ~CommandObjectTargetModulesDumpSections() override = default;
2113 bool DoExecute(Args &command, CommandReturnObject &result) override {
2114 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2115 if (target == nullptr) {
2116 result.AppendError("invalid target, create a debug target using the "
2117 "'target create' command");
2118 result.SetStatus(eReturnStatusFailed);
2121 uint32_t num_dumped = 0;
2123 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2124 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2125 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2127 if (command.GetArgumentCount() == 0) {
2128 // Dump all sections for all modules images
2129 const size_t num_modules = target->GetImages().GetSize();
2130 if (num_modules > 0) {
2131 result.GetOutputStream().Printf("Dumping sections for %" PRIu64
2133 (uint64_t)num_modules);
2134 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2135 if (m_interpreter.WasInterrupted())
2139 m_interpreter, result.GetOutputStream(),
2140 target->GetImages().GetModulePointerAtIndex(image_idx));
2143 result.AppendError("the target has no associated executable images");
2144 result.SetStatus(eReturnStatusFailed);
2148 // Dump specified images (by basename or fullpath)
2149 const char *arg_cstr;
2150 for (int arg_idx = 0;
2151 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2153 ModuleList module_list;
2154 const size_t num_matches =
2155 FindModulesByName(target, arg_cstr, module_list, true);
2156 if (num_matches > 0) {
2157 for (size_t i = 0; i < num_matches; ++i) {
2158 if (m_interpreter.WasInterrupted())
2160 Module *module = module_list.GetModulePointerAtIndex(i);
2163 DumpModuleSections(m_interpreter, result.GetOutputStream(),
2168 // Check the global list
2169 std::lock_guard<std::recursive_mutex> guard(
2170 Module::GetAllocationModuleCollectionMutex());
2172 result.AppendWarningWithFormat(
2173 "Unable to find an image that matches '%s'.\n", arg_cstr);
2179 result.SetStatus(eReturnStatusSuccessFinishResult);
2181 result.AppendError("no matching executable images found");
2182 result.SetStatus(eReturnStatusFailed);
2185 return result.Succeeded();
2189 #pragma mark CommandObjectTargetModulesDumpSymfile
2191 //----------------------------------------------------------------------
2192 // Image debug symbol dumping command
2193 //----------------------------------------------------------------------
2195 class CommandObjectTargetModulesDumpSymfile
2196 : public CommandObjectTargetModulesModuleAutoComplete {
2198 CommandObjectTargetModulesDumpSymfile(CommandInterpreter &interpreter)
2199 : CommandObjectTargetModulesModuleAutoComplete(
2200 interpreter, "target modules dump symfile",
2201 "Dump the debug symbol file for one or more target modules.",
2202 //"target modules dump symfile [<file1> ...]")
2205 ~CommandObjectTargetModulesDumpSymfile() override = default;
2208 bool DoExecute(Args &command, CommandReturnObject &result) override {
2209 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2210 if (target == nullptr) {
2211 result.AppendError("invalid target, create a debug target using the "
2212 "'target create' command");
2213 result.SetStatus(eReturnStatusFailed);
2216 uint32_t num_dumped = 0;
2218 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2219 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2220 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2222 if (command.GetArgumentCount() == 0) {
2223 // Dump all sections for all modules images
2224 const ModuleList &target_modules = target->GetImages();
2225 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2226 const size_t num_modules = target_modules.GetSize();
2227 if (num_modules > 0) {
2228 result.GetOutputStream().Printf("Dumping debug symbols for %" PRIu64
2230 (uint64_t)num_modules);
2231 for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2232 if (m_interpreter.WasInterrupted())
2234 if (DumpModuleSymbolVendor(
2235 result.GetOutputStream(),
2236 target_modules.GetModulePointerAtIndexUnlocked(image_idx)))
2240 result.AppendError("the target has no associated executable images");
2241 result.SetStatus(eReturnStatusFailed);
2245 // Dump specified images (by basename or fullpath)
2246 const char *arg_cstr;
2247 for (int arg_idx = 0;
2248 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2250 ModuleList module_list;
2251 const size_t num_matches =
2252 FindModulesByName(target, arg_cstr, module_list, true);
2253 if (num_matches > 0) {
2254 for (size_t i = 0; i < num_matches; ++i) {
2255 if (m_interpreter.WasInterrupted())
2257 Module *module = module_list.GetModulePointerAtIndex(i);
2259 if (DumpModuleSymbolVendor(result.GetOutputStream(), module))
2264 result.AppendWarningWithFormat(
2265 "Unable to find an image that matches '%s'.\n", arg_cstr);
2270 result.SetStatus(eReturnStatusSuccessFinishResult);
2272 result.AppendError("no matching executable images found");
2273 result.SetStatus(eReturnStatusFailed);
2276 return result.Succeeded();
2280 #pragma mark CommandObjectTargetModulesDumpLineTable
2282 //----------------------------------------------------------------------
2283 // Image debug line table dumping command
2284 //----------------------------------------------------------------------
2286 class CommandObjectTargetModulesDumpLineTable
2287 : public CommandObjectTargetModulesSourceFileAutoComplete {
2289 CommandObjectTargetModulesDumpLineTable(CommandInterpreter &interpreter)
2290 : CommandObjectTargetModulesSourceFileAutoComplete(
2291 interpreter, "target modules dump line-table",
2292 "Dump the line table for one or more compilation units.", nullptr,
2293 eCommandRequiresTarget) {}
2295 ~CommandObjectTargetModulesDumpLineTable() override = default;
2298 bool DoExecute(Args &command, CommandReturnObject &result) override {
2299 Target *target = m_exe_ctx.GetTargetPtr();
2300 uint32_t total_num_dumped = 0;
2302 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2303 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2304 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2306 if (command.GetArgumentCount() == 0) {
2307 result.AppendError("file option must be specified.");
2308 result.SetStatus(eReturnStatusFailed);
2309 return result.Succeeded();
2311 // Dump specified images (by basename or fullpath)
2312 const char *arg_cstr;
2313 for (int arg_idx = 0;
2314 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2316 FileSpec file_spec(arg_cstr, false);
2318 const ModuleList &target_modules = target->GetImages();
2319 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2320 const size_t num_modules = target_modules.GetSize();
2321 if (num_modules > 0) {
2322 uint32_t num_dumped = 0;
2323 for (uint32_t i = 0; i < num_modules; ++i) {
2324 if (m_interpreter.WasInterrupted())
2326 if (DumpCompileUnitLineTable(
2327 m_interpreter, result.GetOutputStream(),
2328 target_modules.GetModulePointerAtIndexUnlocked(i),
2329 file_spec, m_exe_ctx.GetProcessPtr() &&
2330 m_exe_ctx.GetProcessRef().IsAlive()))
2333 if (num_dumped == 0)
2334 result.AppendWarningWithFormat(
2335 "No source filenames matched '%s'.\n", arg_cstr);
2337 total_num_dumped += num_dumped;
2342 if (total_num_dumped > 0)
2343 result.SetStatus(eReturnStatusSuccessFinishResult);
2345 result.AppendError("no source filenames matched any command arguments");
2346 result.SetStatus(eReturnStatusFailed);
2348 return result.Succeeded();
2352 #pragma mark CommandObjectTargetModulesDump
2354 //----------------------------------------------------------------------
2355 // Dump multi-word command for target modules
2356 //----------------------------------------------------------------------
2358 class CommandObjectTargetModulesDump : public CommandObjectMultiword {
2360 //------------------------------------------------------------------
2361 // Constructors and Destructors
2362 //------------------------------------------------------------------
2363 CommandObjectTargetModulesDump(CommandInterpreter &interpreter)
2364 : CommandObjectMultiword(interpreter, "target modules dump",
2365 "Commands for dumping information about one or "
2366 "more target modules.",
2367 "target modules dump "
2368 "[headers|symtab|sections|symfile|line-table] "
2369 "[<file1> <file2> ...]") {
2370 LoadSubCommand("objfile",
2372 new CommandObjectTargetModulesDumpObjfile(interpreter)));
2375 CommandObjectSP(new CommandObjectTargetModulesDumpSymtab(interpreter)));
2376 LoadSubCommand("sections",
2377 CommandObjectSP(new CommandObjectTargetModulesDumpSections(
2379 LoadSubCommand("symfile",
2381 new CommandObjectTargetModulesDumpSymfile(interpreter)));
2382 LoadSubCommand("line-table",
2383 CommandObjectSP(new CommandObjectTargetModulesDumpLineTable(
2387 ~CommandObjectTargetModulesDump() override = default;
2390 class CommandObjectTargetModulesAdd : public CommandObjectParsed {
2392 CommandObjectTargetModulesAdd(CommandInterpreter &interpreter)
2393 : CommandObjectParsed(interpreter, "target modules add",
2394 "Add a new module to the current target's modules.",
2395 "target modules add [<module>]"),
2397 m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
2398 eArgTypeFilename, "Fullpath to a stand alone debug "
2399 "symbols file for when debug symbols "
2400 "are not in the executable.") {
2401 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
2403 m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2404 m_option_group.Finalize();
2407 ~CommandObjectTargetModulesAdd() override = default;
2409 Options *GetOptions() override { return &m_option_group; }
2411 int HandleArgumentCompletion(Args &input, int &cursor_index,
2412 int &cursor_char_position,
2413 OptionElementVector &opt_element_vector,
2414 int match_start_point, int max_return_elements,
2415 bool &word_complete,
2416 StringList &matches) override {
2417 std::string completion_str(input.GetArgumentAtIndex(cursor_index));
2418 completion_str.erase(cursor_char_position);
2420 CommandCompletions::InvokeCommonCompletionCallbacks(
2421 GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
2422 completion_str.c_str(), match_start_point, max_return_elements, nullptr,
2423 word_complete, matches);
2424 return matches.GetSize();
2428 OptionGroupOptions m_option_group;
2429 OptionGroupUUID m_uuid_option_group;
2430 OptionGroupFile m_symbol_file;
2432 bool DoExecute(Args &args, CommandReturnObject &result) override {
2433 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2434 if (target == nullptr) {
2435 result.AppendError("invalid target, create a debug target using the "
2436 "'target create' command");
2437 result.SetStatus(eReturnStatusFailed);
2442 const size_t argc = args.GetArgumentCount();
2444 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2445 // We are given a UUID only, go locate the file
2446 ModuleSpec module_spec;
2447 module_spec.GetUUID() =
2448 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2449 if (m_symbol_file.GetOptionValue().OptionWasSet())
2450 module_spec.GetSymbolFileSpec() =
2451 m_symbol_file.GetOptionValue().GetCurrentValue();
2452 if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
2453 ModuleSP module_sp(target->GetSharedModule(module_spec));
2455 result.SetStatus(eReturnStatusSuccessFinishResult);
2459 module_spec.GetUUID().Dump(&strm);
2460 if (module_spec.GetFileSpec()) {
2461 if (module_spec.GetSymbolFileSpec()) {
2462 result.AppendErrorWithFormat(
2463 "Unable to create the executable or symbol file with "
2464 "UUID %s with path %s and symbol file %s",
2466 module_spec.GetFileSpec().GetPath().c_str(),
2467 module_spec.GetSymbolFileSpec().GetPath().c_str());
2469 result.AppendErrorWithFormat(
2470 "Unable to create the executable or symbol file with "
2471 "UUID %s with path %s",
2473 module_spec.GetFileSpec().GetPath().c_str());
2476 result.AppendErrorWithFormat("Unable to create the executable "
2477 "or symbol file with UUID %s",
2480 result.SetStatus(eReturnStatusFailed);
2485 module_spec.GetUUID().Dump(&strm);
2486 result.AppendErrorWithFormat(
2487 "Unable to locate the executable or symbol file with UUID %s",
2489 result.SetStatus(eReturnStatusFailed);
2494 "one or more executable image paths must be specified");
2495 result.SetStatus(eReturnStatusFailed);
2499 for (auto &entry : args.entries()) {
2500 if (entry.ref.empty())
2503 FileSpec file_spec(entry.ref, true);
2504 if (file_spec.Exists()) {
2505 ModuleSpec module_spec(file_spec);
2506 if (m_uuid_option_group.GetOptionValue().OptionWasSet())
2507 module_spec.GetUUID() =
2508 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2509 if (m_symbol_file.GetOptionValue().OptionWasSet())
2510 module_spec.GetSymbolFileSpec() =
2511 m_symbol_file.GetOptionValue().GetCurrentValue();
2512 if (!module_spec.GetArchitecture().IsValid())
2513 module_spec.GetArchitecture() = target->GetArchitecture();
2515 ModuleSP module_sp(target->GetSharedModule(module_spec, &error));
2517 const char *error_cstr = error.AsCString();
2519 result.AppendError(error_cstr);
2521 result.AppendErrorWithFormat("unsupported module: %s",
2523 result.SetStatus(eReturnStatusFailed);
2528 result.SetStatus(eReturnStatusSuccessFinishResult);
2530 std::string resolved_path = file_spec.GetPath();
2531 result.SetStatus(eReturnStatusFailed);
2532 if (resolved_path != entry.ref) {
2533 result.AppendErrorWithFormat(
2534 "invalid module path '%s' with resolved path '%s'\n",
2535 entry.ref.str().c_str(), resolved_path.c_str());
2538 result.AppendErrorWithFormat("invalid module path '%s'\n",
2546 ProcessSP process = target->GetProcessSP();
2552 return result.Succeeded();
2556 class CommandObjectTargetModulesLoad
2557 : public CommandObjectTargetModulesModuleAutoComplete {
2559 CommandObjectTargetModulesLoad(CommandInterpreter &interpreter)
2560 : CommandObjectTargetModulesModuleAutoComplete(
2561 interpreter, "target modules load", "Set the load addresses for "
2562 "one or more sections in a "
2564 "target modules load [--file <module> --uuid <uuid>] <sect-name> "
2565 "<address> [<sect-name> <address> ....]"),
2567 m_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName,
2568 "Fullpath or basename for module to load.", ""),
2569 m_load_option(LLDB_OPT_SET_1, false, "load", 'l',
2570 "Write file contents to the memory.", false, true),
2571 m_pc_option(LLDB_OPT_SET_1, false, "set-pc-to-entry", 'p',
2572 "Set PC to the entry point."
2573 " Only applicable with '--load' option.",
2575 m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset,
2576 "Set the load address for all sections to be the "
2577 "virtual address in the file plus the offset.",
2579 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
2581 m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2582 m_option_group.Append(&m_load_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2583 m_option_group.Append(&m_pc_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2584 m_option_group.Append(&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2585 m_option_group.Finalize();
2588 ~CommandObjectTargetModulesLoad() override = default;
2590 Options *GetOptions() override { return &m_option_group; }
2593 bool DoExecute(Args &args, CommandReturnObject &result) override {
2594 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2595 const bool load = m_load_option.GetOptionValue().GetCurrentValue();
2596 const bool set_pc = m_pc_option.GetOptionValue().GetCurrentValue();
2597 if (target == nullptr) {
2598 result.AppendError("invalid target, create a debug target using the "
2599 "'target create' command");
2600 result.SetStatus(eReturnStatusFailed);
2603 const size_t argc = args.GetArgumentCount();
2604 ModuleSpec module_spec;
2605 bool search_using_module_spec = false;
2607 // Allow "load" option to work without --file or --uuid
2610 if (!m_file_option.GetOptionValue().OptionWasSet() &&
2611 !m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2612 ModuleList &module_list = target->GetImages();
2613 if (module_list.GetSize() == 1) {
2614 search_using_module_spec = true;
2615 module_spec.GetFileSpec() =
2616 module_list.GetModuleAtIndex(0)->GetFileSpec();
2621 if (m_file_option.GetOptionValue().OptionWasSet()) {
2622 search_using_module_spec = true;
2623 const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
2624 const bool use_global_module_list = true;
2625 ModuleList module_list;
2626 const size_t num_matches = FindModulesByName(
2627 target, arg_cstr, module_list, use_global_module_list);
2628 if (num_matches == 1) {
2629 module_spec.GetFileSpec() =
2630 module_list.GetModuleAtIndex(0)->GetFileSpec();
2631 } else if (num_matches > 1) {
2632 search_using_module_spec = false;
2633 result.AppendErrorWithFormat(
2634 "more than 1 module matched by name '%s'\n", arg_cstr);
2635 result.SetStatus(eReturnStatusFailed);
2637 search_using_module_spec = false;
2638 result.AppendErrorWithFormat("no object file for module '%s'\n",
2640 result.SetStatus(eReturnStatusFailed);
2644 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2645 search_using_module_spec = true;
2646 module_spec.GetUUID() =
2647 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2650 if (search_using_module_spec) {
2651 ModuleList matching_modules;
2652 const size_t num_matches =
2653 target->GetImages().FindModules(module_spec, matching_modules);
2655 char path[PATH_MAX];
2656 if (num_matches == 1) {
2657 Module *module = matching_modules.GetModulePointerAtIndex(0);
2659 ObjectFile *objfile = module->GetObjectFile();
2661 SectionList *section_list = module->GetSectionList();
2663 bool changed = false;
2665 if (m_slide_option.GetOptionValue().OptionWasSet()) {
2666 const addr_t slide =
2667 m_slide_option.GetOptionValue().GetCurrentValue();
2668 const bool slide_is_offset = true;
2669 module->SetLoadAddress(*target, slide, slide_is_offset,
2672 result.AppendError("one or more section name + load "
2673 "address pair must be specified");
2674 result.SetStatus(eReturnStatusFailed);
2678 if (m_slide_option.GetOptionValue().OptionWasSet()) {
2679 result.AppendError("The \"--slide <offset>\" option can't "
2680 "be used in conjunction with setting "
2681 "section load addresses.\n");
2682 result.SetStatus(eReturnStatusFailed);
2686 for (size_t i = 0; i < argc; i += 2) {
2687 const char *sect_name = args.GetArgumentAtIndex(i);
2688 const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1);
2689 if (sect_name && load_addr_cstr) {
2690 ConstString const_sect_name(sect_name);
2691 bool success = false;
2692 addr_t load_addr = StringConvert::ToUInt64(
2693 load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success);
2695 SectionSP section_sp(
2696 section_list->FindSectionByName(const_sect_name));
2698 if (section_sp->IsThreadSpecific()) {
2699 result.AppendErrorWithFormat(
2700 "thread specific sections are not yet "
2701 "supported (section '%s')\n",
2703 result.SetStatus(eReturnStatusFailed);
2706 if (target->GetSectionLoadList()
2707 .SetSectionLoadAddress(section_sp,
2710 result.AppendMessageWithFormat(
2711 "section '%s' loaded at 0x%" PRIx64 "\n",
2712 sect_name, load_addr);
2715 result.AppendErrorWithFormat("no section found that "
2716 "matches the section "
2719 result.SetStatus(eReturnStatusFailed);
2723 result.AppendErrorWithFormat(
2724 "invalid load address string '%s'\n",
2726 result.SetStatus(eReturnStatusFailed);
2731 result.AppendError("section names must be followed by "
2732 "a load address.\n");
2734 result.AppendError("one or more section name + load "
2735 "address pair must be specified.\n");
2736 result.SetStatus(eReturnStatusFailed);
2743 target->ModulesDidLoad(matching_modules);
2744 Process *process = m_exe_ctx.GetProcessPtr();
2749 Status error = module->LoadInMemory(*target, set_pc);
2751 result.AppendError(error.AsCString());
2756 module->GetFileSpec().GetPath(path, sizeof(path));
2757 result.AppendErrorWithFormat(
2758 "no sections in object file '%s'\n", path);
2759 result.SetStatus(eReturnStatusFailed);
2762 module->GetFileSpec().GetPath(path, sizeof(path));
2763 result.AppendErrorWithFormat("no object file for module '%s'\n",
2765 result.SetStatus(eReturnStatusFailed);
2768 FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
2769 if (module_spec_file) {
2770 module_spec_file->GetPath(path, sizeof(path));
2771 result.AppendErrorWithFormat("invalid module '%s'.\n", path);
2773 result.AppendError("no module spec");
2774 result.SetStatus(eReturnStatusFailed);
2777 std::string uuid_str;
2779 if (module_spec.GetFileSpec())
2780 module_spec.GetFileSpec().GetPath(path, sizeof(path));
2784 if (module_spec.GetUUIDPtr())
2785 uuid_str = module_spec.GetUUID().GetAsString();
2786 if (num_matches > 1) {
2787 result.AppendErrorWithFormat(
2788 "multiple modules match%s%s%s%s:\n", path[0] ? " file=" : "",
2789 path, !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
2790 for (size_t i = 0; i < num_matches; ++i) {
2791 if (matching_modules.GetModulePointerAtIndex(i)
2793 .GetPath(path, sizeof(path)))
2794 result.AppendMessageWithFormat("%s\n", path);
2797 result.AppendErrorWithFormat(
2798 "no modules were found that match%s%s%s%s.\n",
2799 path[0] ? " file=" : "", path,
2800 !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
2802 result.SetStatus(eReturnStatusFailed);
2805 result.AppendError("either the \"--file <module>\" or the \"--uuid "
2806 "<uuid>\" option must be specified.\n");
2807 result.SetStatus(eReturnStatusFailed);
2811 return result.Succeeded();
2814 OptionGroupOptions m_option_group;
2815 OptionGroupUUID m_uuid_option_group;
2816 OptionGroupString m_file_option;
2817 OptionGroupBoolean m_load_option;
2818 OptionGroupBoolean m_pc_option;
2819 OptionGroupUInt64 m_slide_option;
2822 //----------------------------------------------------------------------
2823 // List images with associated information
2824 //----------------------------------------------------------------------
2826 static OptionDefinition g_target_modules_list_options[] = {
2828 { LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Display the image at this address." },
2829 { LLDB_OPT_SET_1, false, "arch", 'A', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the architecture when listing images." },
2830 { LLDB_OPT_SET_1, false, "triple", 't', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the triple when listing images." },
2831 { LLDB_OPT_SET_1, false, "header", 'h', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the image header address as a load address if debugging, a file address otherwise." },
2832 { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the image header address offset from the header file address (the slide amount)." },
2833 { LLDB_OPT_SET_1, false, "uuid", 'u', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the UUID when listing images." },
2834 { LLDB_OPT_SET_1, false, "fullpath", 'f', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the fullpath to the image object file." },
2835 { LLDB_OPT_SET_1, false, "directory", 'd', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the directory with optional width for the image object file." },
2836 { LLDB_OPT_SET_1, false, "basename", 'b', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the basename with optional width for the image object file." },
2837 { LLDB_OPT_SET_1, false, "symfile", 's', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width." },
2838 { LLDB_OPT_SET_1, false, "symfile-unique", 'S', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the symbol file with optional width only if it is different from the executable object file." },
2839 { LLDB_OPT_SET_1, false, "mod-time", 'm', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the modification time with optional width of the module." },
2840 { LLDB_OPT_SET_1, false, "ref-count", 'r', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the reference count if the module is still in the shared module cache." },
2841 { LLDB_OPT_SET_1, false, "pointer", 'p', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the module pointer." },
2842 { LLDB_OPT_SET_1, false, "global", 'g', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the modules from the global module list, not just the current target." }
2846 class CommandObjectTargetModulesList : public CommandObjectParsed {
2848 class CommandOptions : public Options {
2851 : Options(), m_format_array(), m_use_global_module_list(false),
2852 m_module_addr(LLDB_INVALID_ADDRESS) {}
2854 ~CommandOptions() override = default;
2856 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2857 ExecutionContext *execution_context) override {
2860 const int short_option = m_getopt_table[option_idx].val;
2861 if (short_option == 'g') {
2862 m_use_global_module_list = true;
2863 } else if (short_option == 'a') {
2864 m_module_addr = Args::StringToAddress(execution_context, option_arg,
2865 LLDB_INVALID_ADDRESS, &error);
2867 unsigned long width = 0;
2868 option_arg.getAsInteger(0, width);
2869 m_format_array.push_back(std::make_pair(short_option, width));
2874 void OptionParsingStarting(ExecutionContext *execution_context) override {
2875 m_format_array.clear();
2876 m_use_global_module_list = false;
2877 m_module_addr = LLDB_INVALID_ADDRESS;
2880 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2881 return llvm::makeArrayRef(g_target_modules_list_options);
2884 // Instance variables to hold the values for command options.
2885 typedef std::vector<std::pair<char, uint32_t>> FormatWidthCollection;
2886 FormatWidthCollection m_format_array;
2887 bool m_use_global_module_list;
2888 lldb::addr_t m_module_addr;
2891 CommandObjectTargetModulesList(CommandInterpreter &interpreter)
2892 : CommandObjectParsed(
2893 interpreter, "target modules list",
2894 "List current executable and dependent shared library images.",
2895 "target modules list [<cmd-options>]"),
2898 ~CommandObjectTargetModulesList() override = default;
2900 Options *GetOptions() override { return &m_options; }
2903 bool DoExecute(Args &command, CommandReturnObject &result) override {
2904 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2905 const bool use_global_module_list = m_options.m_use_global_module_list;
2906 // Define a local module list here to ensure it lives longer than any
2908 // object which might lock its contents below (through the "module_list_ptr"
2910 ModuleList module_list;
2911 if (target == nullptr && !use_global_module_list) {
2912 result.AppendError("invalid target, create a debug target using the "
2913 "'target create' command");
2914 result.SetStatus(eReturnStatusFailed);
2918 uint32_t addr_byte_size =
2919 target->GetArchitecture().GetAddressByteSize();
2920 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2921 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2923 // Dump all sections for all modules images
2924 Stream &strm = result.GetOutputStream();
2926 if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) {
2928 Address module_address;
2929 if (module_address.SetLoadAddress(m_options.m_module_addr, target)) {
2930 ModuleSP module_sp(module_address.GetModule());
2932 PrintModule(target, module_sp.get(), 0, strm);
2933 result.SetStatus(eReturnStatusSuccessFinishResult);
2935 result.AppendErrorWithFormat(
2936 "Couldn't find module matching address: 0x%" PRIx64 ".",
2937 m_options.m_module_addr);
2938 result.SetStatus(eReturnStatusFailed);
2941 result.AppendErrorWithFormat(
2942 "Couldn't find module containing address: 0x%" PRIx64 ".",
2943 m_options.m_module_addr);
2944 result.SetStatus(eReturnStatusFailed);
2948 "Can only look up modules by address with a valid target.");
2949 result.SetStatus(eReturnStatusFailed);
2951 return result.Succeeded();
2954 size_t num_modules = 0;
2956 // This locker will be locked on the mutex in module_list_ptr if it is
2958 // Otherwise it will lock the AllocationModuleCollectionMutex when
2960 // the global module list directly.
2961 std::unique_lock<std::recursive_mutex> guard(
2962 Module::GetAllocationModuleCollectionMutex(), std::defer_lock);
2964 const ModuleList *module_list_ptr = nullptr;
2965 const size_t argc = command.GetArgumentCount();
2967 if (use_global_module_list) {
2969 num_modules = Module::GetNumberAllocatedModules();
2971 module_list_ptr = &target->GetImages();
2974 // TODO: Convert to entry based iteration. Requires converting
2975 // FindModulesByName.
2976 for (size_t i = 0; i < argc; ++i) {
2977 // Dump specified images (by basename or fullpath)
2978 const char *arg_cstr = command.GetArgumentAtIndex(i);
2979 const size_t num_matches = FindModulesByName(
2980 target, arg_cstr, module_list, use_global_module_list);
2981 if (num_matches == 0) {
2983 result.AppendErrorWithFormat("no modules found that match '%s'",
2985 result.SetStatus(eReturnStatusFailed);
2991 module_list_ptr = &module_list;
2994 std::unique_lock<std::recursive_mutex> lock;
2995 if (module_list_ptr != nullptr) {
2997 std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex());
2999 num_modules = module_list_ptr->GetSize();
3002 if (num_modules > 0) {
3003 for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
3006 if (module_list_ptr) {
3007 module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
3008 module = module_sp.get();
3010 module = Module::GetAllocatedModuleAtIndex(image_idx);
3011 module_sp = module->shared_from_this();
3014 const size_t indent = strm.Printf("[%3u] ", image_idx);
3015 PrintModule(target, module, indent, strm);
3017 result.SetStatus(eReturnStatusSuccessFinishResult);
3020 if (use_global_module_list)
3022 "the global module list has no matching modules");
3024 result.AppendError("the target has no matching modules");
3026 if (use_global_module_list)
3027 result.AppendError("the global module list is empty");
3030 "the target has no associated executable images");
3032 result.SetStatus(eReturnStatusFailed);
3036 return result.Succeeded();
3039 void PrintModule(Target *target, Module *module, int indent, Stream &strm) {
3040 if (module == nullptr) {
3041 strm.PutCString("Null module");
3045 bool dump_object_name = false;
3046 if (m_options.m_format_array.empty()) {
3047 m_options.m_format_array.push_back(std::make_pair('u', 0));
3048 m_options.m_format_array.push_back(std::make_pair('h', 0));
3049 m_options.m_format_array.push_back(std::make_pair('f', 0));
3050 m_options.m_format_array.push_back(std::make_pair('S', 0));
3052 const size_t num_entries = m_options.m_format_array.size();
3053 bool print_space = false;
3054 for (size_t i = 0; i < num_entries; ++i) {
3058 const char format_char = m_options.m_format_array[i].first;
3059 uint32_t width = m_options.m_format_array[i].second;
3060 switch (format_char) {
3062 DumpModuleArchitecture(strm, module, false, width);
3066 DumpModuleArchitecture(strm, module, true, width);
3070 DumpFullpath(strm, &module->GetFileSpec(), width);
3071 dump_object_name = true;
3075 DumpDirectory(strm, &module->GetFileSpec(), width);
3079 DumpBasename(strm, &module->GetFileSpec(), width);
3080 dump_object_name = true;
3085 // Image header address
3087 uint32_t addr_nibble_width =
3088 target ? (target->GetArchitecture().GetAddressByteSize() * 2)
3091 ObjectFile *objfile = module->GetObjectFile();
3093 Address header_addr(objfile->GetHeaderAddress());
3094 if (header_addr.IsValid()) {
3095 if (target && !target->GetSectionLoadList().IsEmpty()) {
3096 lldb::addr_t header_load_addr =
3097 header_addr.GetLoadAddress(target);
3098 if (header_load_addr == LLDB_INVALID_ADDRESS) {
3099 header_addr.Dump(&strm, target,
3100 Address::DumpStyleModuleWithFileAddress,
3101 Address::DumpStyleFileAddress);
3103 if (format_char == 'o') {
3104 // Show the offset of slide for the image
3106 "0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width,
3107 header_load_addr - header_addr.GetFileAddress());
3109 // Show the load address of the image
3110 strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3111 addr_nibble_width, header_load_addr);
3116 // The address was valid, but the image isn't loaded, output the
3117 // address in an appropriate format
3118 header_addr.Dump(&strm, target, Address::DumpStyleFileAddress);
3122 strm.Printf("%*s", addr_nibble_width + 2, "");
3127 size_t ref_count = 0;
3128 ModuleSP module_sp(module->shared_from_this());
3130 // Take one away to make sure we don't count our local "module_sp"
3131 ref_count = module_sp.use_count() - 1;
3134 strm.Printf("{%*" PRIu64 "}", width, (uint64_t)ref_count);
3136 strm.Printf("{%" PRIu64 "}", (uint64_t)ref_count);
3141 const SymbolVendor *symbol_vendor = module->GetSymbolVendor();
3142 if (symbol_vendor) {
3143 const FileSpec symfile_spec = symbol_vendor->GetMainFileSpec();
3144 if (format_char == 'S') {
3145 // Dump symbol file only if different from module file
3146 if (!symfile_spec || symfile_spec == module->GetFileSpec()) {
3147 print_space = false;
3150 // Add a newline and indent past the index
3151 strm.Printf("\n%*s", indent, "");
3153 DumpFullpath(strm, &symfile_spec, width);
3154 dump_object_name = true;
3157 strm.Printf("%.*s", width, "<NONE>");
3161 strm.Format("{0:%c}", llvm::fmt_align(module->GetModificationTime(),
3162 llvm::AlignStyle::Left, width));
3166 strm.Printf("%p", static_cast<void *>(module));
3170 DumpModuleUUID(strm, module);
3177 if (dump_object_name) {
3178 const char *object_name = module->GetObjectName().GetCString();
3180 strm.Printf("(%s)", object_name);
3185 CommandOptions m_options;
3188 #pragma mark CommandObjectTargetModulesShowUnwind
3190 //----------------------------------------------------------------------
3191 // Lookup unwind information in images
3192 //----------------------------------------------------------------------
3194 static OptionDefinition g_target_modules_show_unwind_options[] = {
3196 { LLDB_OPT_SET_1, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionName, "Show unwind instructions for a function or symbol name." },
3197 { LLDB_OPT_SET_2, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address" }
3201 class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {
3204 eLookupTypeInvalid = -1,
3205 eLookupTypeAddress = 0,
3207 eLookupTypeFunction,
3208 eLookupTypeFunctionOrSymbol,
3212 class CommandOptions : public Options {
3215 : Options(), m_type(eLookupTypeInvalid), m_str(),
3216 m_addr(LLDB_INVALID_ADDRESS) {}
3218 ~CommandOptions() override = default;
3220 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3221 ExecutionContext *execution_context) override {
3224 const int short_option = m_getopt_table[option_idx].val;
3226 switch (short_option) {
3229 m_type = eLookupTypeAddress;
3230 m_addr = Args::StringToAddress(execution_context, option_arg,
3231 LLDB_INVALID_ADDRESS, &error);
3232 if (m_addr == LLDB_INVALID_ADDRESS)
3233 error.SetErrorStringWithFormat("invalid address string '%s'",
3234 option_arg.str().c_str());
3240 m_type = eLookupTypeFunctionOrSymbol;
3244 error.SetErrorStringWithFormat("unrecognized option %c.", short_option);
3251 void OptionParsingStarting(ExecutionContext *execution_context) override {
3252 m_type = eLookupTypeInvalid;
3254 m_addr = LLDB_INVALID_ADDRESS;
3257 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3258 return llvm::makeArrayRef(g_target_modules_show_unwind_options);
3261 // Instance variables to hold the values for command options.
3263 int m_type; // Should be a eLookupTypeXXX enum after parsing options
3264 std::string m_str; // Holds name lookup
3265 lldb::addr_t m_addr; // Holds the address to lookup
3268 CommandObjectTargetModulesShowUnwind(CommandInterpreter &interpreter)
3269 : CommandObjectParsed(
3270 interpreter, "target modules show-unwind",
3271 "Show synthesized unwind instructions for a function.", nullptr,
3272 eCommandRequiresTarget | eCommandRequiresProcess |
3273 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
3276 ~CommandObjectTargetModulesShowUnwind() override = default;
3278 Options *GetOptions() override { return &m_options; }
3281 bool DoExecute(Args &command, CommandReturnObject &result) override {
3282 Target *target = m_exe_ctx.GetTargetPtr();
3283 Process *process = m_exe_ctx.GetProcessPtr();
3286 abi = process->GetABI().get();
3288 if (process == nullptr) {
3290 "You must have a process running to use this command.");
3291 result.SetStatus(eReturnStatusFailed);
3295 ThreadList threads(process->GetThreadList());
3296 if (threads.GetSize() == 0) {
3297 result.AppendError("The process must be paused to use this command.");
3298 result.SetStatus(eReturnStatusFailed);
3302 ThreadSP thread(threads.GetThreadAtIndex(0));
3304 result.AppendError("The process must be paused to use this command.");
3305 result.SetStatus(eReturnStatusFailed);
3309 SymbolContextList sc_list;
3311 if (m_options.m_type == eLookupTypeFunctionOrSymbol) {
3312 ConstString function_name(m_options.m_str.c_str());
3313 target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto,
3314 true, false, true, sc_list);
3315 } else if (m_options.m_type == eLookupTypeAddress && target) {
3317 if (target->GetSectionLoadList().ResolveLoadAddress(m_options.m_addr,
3320 ModuleSP module_sp(addr.GetModule());
3321 module_sp->ResolveSymbolContextForAddress(addr,
3322 eSymbolContextEverything, sc);
3323 if (sc.function || sc.symbol) {
3329 "address-expression or function name option must be specified.");
3330 result.SetStatus(eReturnStatusFailed);
3334 size_t num_matches = sc_list.GetSize();
3335 if (num_matches == 0) {
3336 result.AppendErrorWithFormat("no unwind data found that matches '%s'.",
3337 m_options.m_str.c_str());
3338 result.SetStatus(eReturnStatusFailed);
3342 for (uint32_t idx = 0; idx < num_matches; idx++) {
3344 sc_list.GetContextAtIndex(idx, sc);
3345 if (sc.symbol == nullptr && sc.function == nullptr)
3347 if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr)
3350 if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,
3353 if (!range.GetBaseAddress().IsValid())
3355 ConstString funcname(sc.GetFunctionName());
3356 if (funcname.IsEmpty())
3358 addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
3360 start_addr = abi->FixCodeAddress(start_addr);
3362 FuncUnwindersSP func_unwinders_sp(
3363 sc.module_sp->GetObjectFile()
3365 .GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
3366 if (!func_unwinders_sp)
3369 result.GetOutputStream().Printf(
3370 "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n\n",
3371 sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(),
3372 funcname.AsCString(), start_addr);
3374 UnwindPlanSP non_callsite_unwind_plan =
3375 func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread, -1);
3376 if (non_callsite_unwind_plan) {
3377 result.GetOutputStream().Printf(
3378 "Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n",
3379 non_callsite_unwind_plan->GetSourceName().AsCString());
3381 UnwindPlanSP callsite_unwind_plan =
3382 func_unwinders_sp->GetUnwindPlanAtCallSite(*target, -1);
3383 if (callsite_unwind_plan) {
3384 result.GetOutputStream().Printf(
3385 "Synchronous (restricted to call-sites) UnwindPlan is '%s'\n",
3386 callsite_unwind_plan->GetSourceName().AsCString());
3388 UnwindPlanSP fast_unwind_plan =
3389 func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread);
3390 if (fast_unwind_plan) {
3391 result.GetOutputStream().Printf(
3392 "Fast UnwindPlan is '%s'\n",
3393 fast_unwind_plan->GetSourceName().AsCString());
3396 result.GetOutputStream().Printf("\n");
3398 UnwindPlanSP assembly_sp =
3399 func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread, 0);
3401 result.GetOutputStream().Printf(
3402 "Assembly language inspection UnwindPlan:\n");
3403 assembly_sp->Dump(result.GetOutputStream(), thread.get(),
3404 LLDB_INVALID_ADDRESS);
3405 result.GetOutputStream().Printf("\n");
3408 UnwindPlanSP ehframe_sp =
3409 func_unwinders_sp->GetEHFrameUnwindPlan(*target, 0);
3411 result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
3412 ehframe_sp->Dump(result.GetOutputStream(), thread.get(),
3413 LLDB_INVALID_ADDRESS);
3414 result.GetOutputStream().Printf("\n");
3417 UnwindPlanSP ehframe_augmented_sp =
3418 func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread, 0);
3419 if (ehframe_augmented_sp) {
3420 result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
3421 ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
3422 LLDB_INVALID_ADDRESS);
3423 result.GetOutputStream().Printf("\n");
3426 if (UnwindPlanSP plan_sp =
3427 func_unwinders_sp->GetDebugFrameUnwindPlan(*target, 0)) {
3428 result.GetOutputStream().Printf("debug_frame UnwindPlan:\n");
3429 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3430 LLDB_INVALID_ADDRESS);
3431 result.GetOutputStream().Printf("\n");
3434 if (UnwindPlanSP plan_sp =
3435 func_unwinders_sp->GetDebugFrameAugmentedUnwindPlan(*target,
3437 result.GetOutputStream().Printf("debug_frame augmented UnwindPlan:\n");
3438 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3439 LLDB_INVALID_ADDRESS);
3440 result.GetOutputStream().Printf("\n");
3443 UnwindPlanSP arm_unwind_sp =
3444 func_unwinders_sp->GetArmUnwindUnwindPlan(*target, 0);
3445 if (arm_unwind_sp) {
3446 result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
3447 arm_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3448 LLDB_INVALID_ADDRESS);
3449 result.GetOutputStream().Printf("\n");
3452 UnwindPlanSP compact_unwind_sp =
3453 func_unwinders_sp->GetCompactUnwindUnwindPlan(*target, 0);
3454 if (compact_unwind_sp) {
3455 result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
3456 compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3457 LLDB_INVALID_ADDRESS);
3458 result.GetOutputStream().Printf("\n");
3461 if (fast_unwind_plan) {
3462 result.GetOutputStream().Printf("Fast UnwindPlan:\n");
3463 fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(),
3464 LLDB_INVALID_ADDRESS);
3465 result.GetOutputStream().Printf("\n");
3468 ABISP abi_sp = process->GetABI();
3470 UnwindPlan arch_default(lldb::eRegisterKindGeneric);
3471 if (abi_sp->CreateDefaultUnwindPlan(arch_default)) {
3472 result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
3473 arch_default.Dump(result.GetOutputStream(), thread.get(),
3474 LLDB_INVALID_ADDRESS);
3475 result.GetOutputStream().Printf("\n");
3478 UnwindPlan arch_entry(lldb::eRegisterKindGeneric);
3479 if (abi_sp->CreateFunctionEntryUnwindPlan(arch_entry)) {
3480 result.GetOutputStream().Printf(
3481 "Arch default at entry point UnwindPlan:\n");
3482 arch_entry.Dump(result.GetOutputStream(), thread.get(),
3483 LLDB_INVALID_ADDRESS);
3484 result.GetOutputStream().Printf("\n");
3488 result.GetOutputStream().Printf("\n");
3490 return result.Succeeded();
3493 CommandOptions m_options;
3496 //----------------------------------------------------------------------
3497 // Lookup information in images
3498 //----------------------------------------------------------------------
3500 static OptionDefinition g_target_modules_lookup_options[] = {
3502 { LLDB_OPT_SET_1, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules." },
3503 { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOffset, "When looking up an address subtract <offset> from any addresses before doing the lookup." },
3504 /* FIXME: re-enable regex for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */
3505 { LLDB_OPT_SET_2 | LLDB_OPT_SET_4 | LLDB_OPT_SET_5, false, "regex", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "The <name> argument for name lookups are regular expressions." },
3506 { LLDB_OPT_SET_2, true, "symbol", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeSymbol, "Lookup a symbol by name in the symbol tables in one or more target modules." },
3507 { LLDB_OPT_SET_3, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFilename, "Lookup a file by fullpath or basename in one or more target modules." },
3508 { LLDB_OPT_SET_3, false, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "Lookup a line number in a file (must be used in conjunction with --file)." },
3509 { LLDB_OPT_SET_FROM_TO(3,5), false, "no-inlines", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Ignore inline entries (must be used in conjunction with --file or --function)." },
3510 { LLDB_OPT_SET_4, true, "function", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionName, "Lookup a function by name in the debug symbols in one or more target modules." },
3511 { LLDB_OPT_SET_5, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionOrSymbol, "Lookup a function or symbol by name in one or more target modules." },
3512 { LLDB_OPT_SET_6, true, "type", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Lookup a type by name in the debug symbols in one or more target modules." },
3513 { LLDB_OPT_SET_ALL, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable verbose lookup information." },
3514 { LLDB_OPT_SET_ALL, false, "all", 'A', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Print all matches, not just the best match, if a best match is available." },
3518 class CommandObjectTargetModulesLookup : public CommandObjectParsed {
3521 eLookupTypeInvalid = -1,
3522 eLookupTypeAddress = 0,
3524 eLookupTypeFileLine, // Line is optional
3525 eLookupTypeFunction,
3526 eLookupTypeFunctionOrSymbol,
3531 class CommandOptions : public Options {
3533 CommandOptions() : Options() { OptionParsingStarting(nullptr); }
3535 ~CommandOptions() override = default;
3537 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3538 ExecutionContext *execution_context) override {
3541 const int short_option = m_getopt_table[option_idx].val;
3543 switch (short_option) {
3545 m_type = eLookupTypeAddress;
3546 m_addr = Args::StringToAddress(execution_context, option_arg,
3547 LLDB_INVALID_ADDRESS, &error);
3551 if (option_arg.getAsInteger(0, m_offset))
3552 error.SetErrorStringWithFormat("invalid offset string '%s'",
3553 option_arg.str().c_str());
3558 m_type = eLookupTypeSymbol;
3562 m_file.SetFile(option_arg, false);
3563 m_type = eLookupTypeFileLine;
3567 m_include_inlines = false;
3571 if (option_arg.getAsInteger(0, m_line_number))
3572 error.SetErrorStringWithFormat("invalid line number string '%s'",
3573 option_arg.str().c_str());
3574 else if (m_line_number == 0)
3575 error.SetErrorString("zero is an invalid line number");
3576 m_type = eLookupTypeFileLine;
3581 m_type = eLookupTypeFunction;
3586 m_type = eLookupTypeFunctionOrSymbol;
3591 m_type = eLookupTypeType;
3610 void OptionParsingStarting(ExecutionContext *execution_context) override {
3611 m_type = eLookupTypeInvalid;
3614 m_addr = LLDB_INVALID_ADDRESS;
3617 m_use_regex = false;
3618 m_include_inlines = true;
3620 m_print_all = false;
3623 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3624 return llvm::makeArrayRef(g_target_modules_lookup_options);
3627 int m_type; // Should be a eLookupTypeXXX enum after parsing options
3628 std::string m_str; // Holds name lookup
3629 FileSpec m_file; // Files for file lookups
3630 lldb::addr_t m_addr; // Holds the address to lookup
3632 m_offset; // Subtract this offset from m_addr before doing lookups.
3633 uint32_t m_line_number; // Line number for file+line lookups
3634 bool m_use_regex; // Name lookups in m_str are regular expressions.
3635 bool m_include_inlines; // Check for inline entries when looking up by
3637 bool m_verbose; // Enable verbose lookup info
3638 bool m_print_all; // Print all matches, even in cases where there's a best
3642 CommandObjectTargetModulesLookup(CommandInterpreter &interpreter)
3643 : CommandObjectParsed(interpreter, "target modules lookup",
3644 "Look up information within executable and "
3645 "dependent shared library images.",
3646 nullptr, eCommandRequiresTarget),
3648 CommandArgumentEntry arg;
3649 CommandArgumentData file_arg;
3651 // Define the first (and only) variant of this arg.
3652 file_arg.arg_type = eArgTypeFilename;
3653 file_arg.arg_repetition = eArgRepeatStar;
3655 // There is only one variant this argument could be; put it into the
3657 arg.push_back(file_arg);
3659 // Push the data for the first argument into the m_arguments vector.
3660 m_arguments.push_back(arg);
3663 ~CommandObjectTargetModulesLookup() override = default;
3665 Options *GetOptions() override { return &m_options; }
3667 bool LookupHere(CommandInterpreter &interpreter, CommandReturnObject &result,
3668 bool &syntax_error) {
3669 switch (m_options.m_type) {
3670 case eLookupTypeAddress:
3671 case eLookupTypeFileLine:
3672 case eLookupTypeFunction:
3673 case eLookupTypeFunctionOrSymbol:
3674 case eLookupTypeSymbol:
3677 case eLookupTypeType:
3681 StackFrameSP frame = m_exe_ctx.GetFrameSP();
3686 const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
3688 if (!sym_ctx.module_sp)
3691 switch (m_options.m_type) {
3694 case eLookupTypeType:
3695 if (!m_options.m_str.empty()) {
3696 if (LookupTypeHere(m_interpreter, result.GetOutputStream(), sym_ctx,
3697 m_options.m_str.c_str(), m_options.m_use_regex)) {
3698 result.SetStatus(eReturnStatusSuccessFinishResult);
3708 bool LookupInModule(CommandInterpreter &interpreter, Module *module,
3709 CommandReturnObject &result, bool &syntax_error) {
3710 switch (m_options.m_type) {
3711 case eLookupTypeAddress:
3712 if (m_options.m_addr != LLDB_INVALID_ADDRESS) {
3713 if (LookupAddressInModule(
3714 m_interpreter, result.GetOutputStream(), module,
3715 eSymbolContextEverything |
3716 (m_options.m_verbose
3717 ? static_cast<int>(eSymbolContextVariable)
3719 m_options.m_addr, m_options.m_offset, m_options.m_verbose)) {
3720 result.SetStatus(eReturnStatusSuccessFinishResult);
3726 case eLookupTypeSymbol:
3727 if (!m_options.m_str.empty()) {
3728 if (LookupSymbolInModule(m_interpreter, result.GetOutputStream(),
3729 module, m_options.m_str.c_str(),
3730 m_options.m_use_regex, m_options.m_verbose)) {
3731 result.SetStatus(eReturnStatusSuccessFinishResult);
3737 case eLookupTypeFileLine:
3738 if (m_options.m_file) {
3739 if (LookupFileAndLineInModule(
3740 m_interpreter, result.GetOutputStream(), module,
3741 m_options.m_file, m_options.m_line_number,
3742 m_options.m_include_inlines, m_options.m_verbose)) {
3743 result.SetStatus(eReturnStatusSuccessFinishResult);
3749 case eLookupTypeFunctionOrSymbol:
3750 case eLookupTypeFunction:
3751 if (!m_options.m_str.empty()) {
3752 if (LookupFunctionInModule(
3753 m_interpreter, result.GetOutputStream(), module,
3754 m_options.m_str.c_str(), m_options.m_use_regex,
3755 m_options.m_include_inlines,
3757 eLookupTypeFunctionOrSymbol, // include symbols
3758 m_options.m_verbose)) {
3759 result.SetStatus(eReturnStatusSuccessFinishResult);
3765 case eLookupTypeType:
3766 if (!m_options.m_str.empty()) {
3767 if (LookupTypeInModule(m_interpreter, result.GetOutputStream(), module,
3768 m_options.m_str.c_str(),
3769 m_options.m_use_regex)) {
3770 result.SetStatus(eReturnStatusSuccessFinishResult);
3777 m_options.GenerateOptionUsage(
3778 result.GetErrorStream(), this,
3779 GetCommandInterpreter().GetDebugger().GetTerminalWidth());
3780 syntax_error = true;
3784 result.SetStatus(eReturnStatusFailed);
3789 bool DoExecute(Args &command, CommandReturnObject &result) override {
3790 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3791 if (target == nullptr) {
3792 result.AppendError("invalid target, create a debug target using the "
3793 "'target create' command");
3794 result.SetStatus(eReturnStatusFailed);
3797 bool syntax_error = false;
3799 uint32_t num_successful_lookups = 0;
3800 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
3801 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3802 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3803 // Dump all sections for all modules images
3805 if (command.GetArgumentCount() == 0) {
3806 ModuleSP current_module;
3808 // Where it is possible to look in the current symbol context
3809 // first, try that. If this search was successful and --all
3810 // was not passed, don't print anything else.
3811 if (LookupHere(m_interpreter, result, syntax_error)) {
3812 result.GetOutputStream().EOL();
3813 num_successful_lookups++;
3814 if (!m_options.m_print_all) {
3815 result.SetStatus(eReturnStatusSuccessFinishResult);
3816 return result.Succeeded();
3820 // Dump all sections for all other modules
3822 const ModuleList &target_modules = target->GetImages();
3823 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
3824 const size_t num_modules = target_modules.GetSize();
3825 if (num_modules > 0) {
3826 for (i = 0; i < num_modules && !syntax_error; ++i) {
3827 Module *module_pointer =
3828 target_modules.GetModulePointerAtIndexUnlocked(i);
3830 if (module_pointer != current_module.get() &&
3833 target_modules.GetModulePointerAtIndexUnlocked(i), result,
3835 result.GetOutputStream().EOL();
3836 num_successful_lookups++;
3840 result.AppendError("the target has no associated executable images");
3841 result.SetStatus(eReturnStatusFailed);
3845 // Dump specified images (by basename or fullpath)
3846 const char *arg_cstr;
3847 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr &&
3850 ModuleList module_list;
3851 const size_t num_matches =
3852 FindModulesByName(target, arg_cstr, module_list, false);
3853 if (num_matches > 0) {
3854 for (size_t j = 0; j < num_matches; ++j) {
3855 Module *module = module_list.GetModulePointerAtIndex(j);
3857 if (LookupInModule(m_interpreter, module, result,
3859 result.GetOutputStream().EOL();
3860 num_successful_lookups++;
3865 result.AppendWarningWithFormat(
3866 "Unable to find an image that matches '%s'.\n", arg_cstr);
3870 if (num_successful_lookups > 0)
3871 result.SetStatus(eReturnStatusSuccessFinishResult);
3873 result.SetStatus(eReturnStatusFailed);
3875 return result.Succeeded();
3878 CommandOptions m_options;
3881 #pragma mark CommandObjectMultiwordImageSearchPaths
3883 //-------------------------------------------------------------------------
3884 // CommandObjectMultiwordImageSearchPaths
3885 //-------------------------------------------------------------------------
3887 class CommandObjectTargetModulesImageSearchPaths
3888 : public CommandObjectMultiword {
3890 CommandObjectTargetModulesImageSearchPaths(CommandInterpreter &interpreter)
3891 : CommandObjectMultiword(
3892 interpreter, "target modules search-paths",
3893 "Commands for managing module search paths for a target.",
3894 "target modules search-paths <subcommand> [<subcommand-options>]") {
3896 "add", CommandObjectSP(
3897 new CommandObjectTargetModulesSearchPathsAdd(interpreter)));
3899 "clear", CommandObjectSP(new CommandObjectTargetModulesSearchPathsClear(
3904 new CommandObjectTargetModulesSearchPathsInsert(interpreter)));
3906 "list", CommandObjectSP(new CommandObjectTargetModulesSearchPathsList(
3909 "query", CommandObjectSP(new CommandObjectTargetModulesSearchPathsQuery(
3913 ~CommandObjectTargetModulesImageSearchPaths() override = default;
3916 #pragma mark CommandObjectTargetModules
3918 //-------------------------------------------------------------------------
3919 // CommandObjectTargetModules
3920 //-------------------------------------------------------------------------
3922 class CommandObjectTargetModules : public CommandObjectMultiword {
3924 //------------------------------------------------------------------
3925 // Constructors and Destructors
3926 //------------------------------------------------------------------
3927 CommandObjectTargetModules(CommandInterpreter &interpreter)
3928 : CommandObjectMultiword(interpreter, "target modules",
3929 "Commands for accessing information for one or "
3930 "more target modules.",
3931 "target modules <sub-command> ...") {
3933 "add", CommandObjectSP(new CommandObjectTargetModulesAdd(interpreter)));
3934 LoadSubCommand("load", CommandObjectSP(new CommandObjectTargetModulesLoad(
3936 LoadSubCommand("dump", CommandObjectSP(new CommandObjectTargetModulesDump(
3938 LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetModulesList(
3942 CommandObjectSP(new CommandObjectTargetModulesLookup(interpreter)));
3946 new CommandObjectTargetModulesImageSearchPaths(interpreter)));
3949 CommandObjectSP(new CommandObjectTargetModulesShowUnwind(interpreter)));
3952 ~CommandObjectTargetModules() override = default;
3955 //------------------------------------------------------------------
3956 // For CommandObjectTargetModules only
3957 //------------------------------------------------------------------
3958 DISALLOW_COPY_AND_ASSIGN(CommandObjectTargetModules);
3961 class CommandObjectTargetSymbolsAdd : public CommandObjectParsed {
3963 CommandObjectTargetSymbolsAdd(CommandInterpreter &interpreter)
3964 : CommandObjectParsed(
3965 interpreter, "target symbols add",
3966 "Add a debug symbol file to one of the target's current modules by "
3967 "specifying a path to a debug symbols file, or using the options "
3968 "to specify a module to download symbols for.",
3969 "target symbols add <cmd-options> [<symfile>]",
3970 eCommandRequiresTarget),
3973 LLDB_OPT_SET_1, false, "shlib", 's',
3974 CommandCompletions::eModuleCompletion, eArgTypeShlibName,
3975 "Fullpath or basename for module to find debug symbols for."),
3976 m_current_frame_option(
3977 LLDB_OPT_SET_2, false, "frame", 'F',
3978 "Locate the debug symbols the currently selected frame.", false,
3982 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
3984 m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
3985 m_option_group.Append(&m_current_frame_option, LLDB_OPT_SET_2,
3987 m_option_group.Finalize();
3990 ~CommandObjectTargetSymbolsAdd() override = default;
3992 int HandleArgumentCompletion(Args &input, int &cursor_index,
3993 int &cursor_char_position,
3994 OptionElementVector &opt_element_vector,
3995 int match_start_point, int max_return_elements,
3996 bool &word_complete,
3997 StringList &matches) override {
3998 std::string completion_str(input.GetArgumentAtIndex(cursor_index));
3999 completion_str.erase(cursor_char_position);
4001 CommandCompletions::InvokeCommonCompletionCallbacks(
4002 GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
4003 completion_str.c_str(), match_start_point, max_return_elements, nullptr,
4004 word_complete, matches);
4005 return matches.GetSize();
4008 Options *GetOptions() override { return &m_option_group; }
4011 bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush,
4012 CommandReturnObject &result) {
4013 const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
4015 char symfile_path[PATH_MAX];
4016 symbol_fspec.GetPath(symfile_path, sizeof(symfile_path));
4018 if (!module_spec.GetUUID().IsValid()) {
4019 if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
4020 module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename();
4022 // We now have a module that represents a symbol file
4023 // that can be used for a module that might exist in the
4024 // current target, so we need to find that module in the
4026 ModuleList matching_module_list;
4028 size_t num_matches = 0;
4029 // First extract all module specs from the symbol file
4030 lldb_private::ModuleSpecList symfile_module_specs;
4031 if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(),
4032 0, 0, symfile_module_specs)) {
4033 // Now extract the module spec that matches the target architecture
4034 ModuleSpec target_arch_module_spec;
4035 ModuleSpec symfile_module_spec;
4036 target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
4037 if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec,
4038 symfile_module_spec)) {
4039 // See if it has a UUID?
4040 if (symfile_module_spec.GetUUID().IsValid()) {
4041 // It has a UUID, look for this UUID in the target modules
4042 ModuleSpec symfile_uuid_module_spec;
4043 symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
4044 num_matches = target->GetImages().FindModules(
4045 symfile_uuid_module_spec, matching_module_list);
4049 if (num_matches == 0) {
4050 // No matches yet, iterate through the module specs to find a UUID
4052 // we can match up to an image in our target
4053 const size_t num_symfile_module_specs =
4054 symfile_module_specs.GetSize();
4055 for (size_t i = 0; i < num_symfile_module_specs && num_matches == 0;
4057 if (symfile_module_specs.GetModuleSpecAtIndex(
4058 i, symfile_module_spec)) {
4059 if (symfile_module_spec.GetUUID().IsValid()) {
4060 // It has a UUID, look for this UUID in the target modules
4061 ModuleSpec symfile_uuid_module_spec;
4062 symfile_uuid_module_spec.GetUUID() =
4063 symfile_module_spec.GetUUID();
4064 num_matches = target->GetImages().FindModules(
4065 symfile_uuid_module_spec, matching_module_list);
4072 // Just try to match up the file by basename if we have no matches at this
4074 if (num_matches == 0)
4076 target->GetImages().FindModules(module_spec, matching_module_list);
4078 while (num_matches == 0) {
4079 ConstString filename_no_extension(
4080 module_spec.GetFileSpec().GetFileNameStrippingExtension());
4081 // Empty string returned, lets bail
4082 if (!filename_no_extension)
4085 // Check if there was no extension to strip and the basename is the same
4086 if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
4089 // Replace basename with one less extension
4090 module_spec.GetFileSpec().GetFilename() = filename_no_extension;
4093 target->GetImages().FindModules(module_spec, matching_module_list);
4096 if (num_matches > 1) {
4097 result.AppendErrorWithFormat("multiple modules match symbol file '%s', "
4098 "use the --uuid option to resolve the "
4101 } else if (num_matches == 1) {
4102 ModuleSP module_sp(matching_module_list.GetModuleAtIndex(0));
4104 // The module has not yet created its symbol vendor, we can just
4105 // give the existing target module the symfile path to use for
4106 // when it decides to create it!
4107 module_sp->SetSymbolFileFileSpec(symbol_fspec);
4109 SymbolVendor *symbol_vendor =
4110 module_sp->GetSymbolVendor(true, &result.GetErrorStream());
4111 if (symbol_vendor) {
4112 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
4115 ObjectFile *object_file = symbol_file->GetObjectFile();
4117 if (object_file && object_file->GetFileSpec() == symbol_fspec) {
4118 // Provide feedback that the symfile has been successfully added.
4119 const FileSpec &module_fs = module_sp->GetFileSpec();
4120 result.AppendMessageWithFormat(
4121 "symbol file '%s' has been added to '%s'\n", symfile_path,
4122 module_fs.GetPath().c_str());
4124 // Let clients know something changed in the module
4125 // if it is currently loaded
4126 ModuleList module_list;
4127 module_list.Append(module_sp);
4128 target->SymbolsDidLoad(module_list);
4130 // Make sure we load any scripting resources that may be embedded
4131 // in the debug info files in case the platform supports that.
4133 StreamString feedback_stream;
4134 module_sp->LoadScriptingResourceInTarget(target, error,
4136 if (error.Fail() && error.AsCString())
4137 result.AppendWarningWithFormat(
4138 "unable to load scripting data for module %s - error "
4140 module_sp->GetFileSpec()
4141 .GetFileNameStrippingExtension()
4144 else if (feedback_stream.GetSize())
4145 result.AppendWarningWithFormat("%s", feedback_stream.GetData());
4148 result.SetStatus(eReturnStatusSuccessFinishResult);
4153 // Clear the symbol file spec if anything went wrong
4154 module_sp->SetSymbolFileFileSpec(FileSpec());
4157 namespace fs = llvm::sys::fs;
4158 if (module_spec.GetUUID().IsValid()) {
4159 StreamString ss_symfile_uuid;
4160 module_spec.GetUUID().Dump(&ss_symfile_uuid);
4161 result.AppendErrorWithFormat(
4162 "symbol file '%s' (%s) does not match any existing module%s\n",
4163 symfile_path, ss_symfile_uuid.GetData(),
4164 !fs::is_regular_file(symbol_fspec.GetPath())
4165 ? "\n please specify the full path to the symbol file"
4168 result.AppendErrorWithFormat(
4169 "symbol file '%s' does not match any existing module%s\n",
4171 !fs::is_regular_file(symbol_fspec.GetPath())
4172 ? "\n please specify the full path to the symbol file"
4177 "one or more executable image paths must be specified");
4179 result.SetStatus(eReturnStatusFailed);
4183 bool DoExecute(Args &args, CommandReturnObject &result) override {
4184 Target *target = m_exe_ctx.GetTargetPtr();
4185 result.SetStatus(eReturnStatusFailed);
4187 ModuleSpec module_spec;
4188 const bool uuid_option_set =
4189 m_uuid_option_group.GetOptionValue().OptionWasSet();
4190 const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
4191 const bool frame_option_set =
4192 m_current_frame_option.GetOptionValue().OptionWasSet();
4193 const size_t argc = args.GetArgumentCount();
4196 if (uuid_option_set || file_option_set || frame_option_set) {
4197 bool success = false;
4198 bool error_set = false;
4199 if (frame_option_set) {
4200 Process *process = m_exe_ctx.GetProcessPtr();
4202 const StateType process_state = process->GetState();
4203 if (StateIsStoppedState(process_state, true)) {
4204 StackFrame *frame = m_exe_ctx.GetFramePtr();
4206 ModuleSP frame_module_sp(
4207 frame->GetSymbolContext(eSymbolContextModule).module_sp);
4208 if (frame_module_sp) {
4209 if (frame_module_sp->GetPlatformFileSpec().Exists()) {
4210 module_spec.GetArchitecture() =
4211 frame_module_sp->GetArchitecture();
4212 module_spec.GetFileSpec() =
4213 frame_module_sp->GetPlatformFileSpec();
4215 module_spec.GetUUID() = frame_module_sp->GetUUID();
4216 success = module_spec.GetUUID().IsValid() ||
4217 module_spec.GetFileSpec();
4219 result.AppendError("frame has no module");
4223 result.AppendError("invalid current frame");
4227 result.AppendErrorWithFormat("process is not stopped: %s",
4228 StateAsCString(process_state));
4233 "a process must exist in order to use the --frame option");
4237 if (uuid_option_set) {
4238 module_spec.GetUUID() =
4239 m_uuid_option_group.GetOptionValue().GetCurrentValue();
4240 success |= module_spec.GetUUID().IsValid();
4241 } else if (file_option_set) {
4242 module_spec.GetFileSpec() =
4243 m_file_option.GetOptionValue().GetCurrentValue();
4245 target->GetImages().FindFirstModule(module_spec));
4247 module_spec.GetFileSpec() = module_sp->GetFileSpec();
4248 module_spec.GetPlatformFileSpec() =
4249 module_sp->GetPlatformFileSpec();
4250 module_spec.GetUUID() = module_sp->GetUUID();
4251 module_spec.GetArchitecture() = module_sp->GetArchitecture();
4253 module_spec.GetArchitecture() = target->GetArchitecture();
4255 success |= module_spec.GetUUID().IsValid() ||
4256 module_spec.GetFileSpec().Exists();
4261 if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
4262 if (module_spec.GetSymbolFileSpec())
4263 success = AddModuleSymbols(target, module_spec, flush, result);
4267 if (!success && !error_set) {
4268 StreamString error_strm;
4269 if (uuid_option_set) {
4270 error_strm.PutCString("unable to find debug symbols for UUID ");
4271 module_spec.GetUUID().Dump(&error_strm);
4272 } else if (file_option_set) {
4273 error_strm.PutCString(
4274 "unable to find debug symbols for the executable file ");
4275 error_strm << module_spec.GetFileSpec();
4276 } else if (frame_option_set) {
4277 error_strm.PutCString(
4278 "unable to find debug symbols for the current frame");
4280 result.AppendError(error_strm.GetString());
4283 result.AppendError("one or more symbol file paths must be specified, "
4284 "or options must be specified");
4287 if (uuid_option_set) {
4288 result.AppendError("specify either one or more paths to symbol files "
4289 "or use the --uuid option without arguments");
4290 } else if (frame_option_set) {
4291 result.AppendError("specify either one or more paths to symbol files "
4292 "or use the --frame option without arguments");
4293 } else if (file_option_set && argc > 1) {
4294 result.AppendError("specify at most one symbol file path when "
4295 "--shlib option is set");
4297 PlatformSP platform_sp(target->GetPlatform());
4299 for (auto &entry : args.entries()) {
4300 if (!entry.ref.empty()) {
4301 module_spec.GetSymbolFileSpec().SetFile(entry.ref, true);
4302 if (file_option_set) {
4303 module_spec.GetFileSpec() =
4304 m_file_option.GetOptionValue().GetCurrentValue();
4307 FileSpec symfile_spec;
4309 ->ResolveSymbolFile(*target, module_spec, symfile_spec)
4311 module_spec.GetSymbolFileSpec() = symfile_spec;
4315 bool symfile_exists = module_spec.GetSymbolFileSpec().Exists();
4317 if (symfile_exists) {
4318 if (!AddModuleSymbols(target, module_spec, flush, result))
4321 std::string resolved_symfile_path =
4322 module_spec.GetSymbolFileSpec().GetPath();
4323 if (resolved_symfile_path != entry.ref) {
4324 result.AppendErrorWithFormat(
4325 "invalid module path '%s' with resolved path '%s'\n",
4326 entry.c_str(), resolved_symfile_path.c_str());
4329 result.AppendErrorWithFormat("invalid module path '%s'\n",
4339 Process *process = m_exe_ctx.GetProcessPtr();
4343 return result.Succeeded();
4346 OptionGroupOptions m_option_group;
4347 OptionGroupUUID m_uuid_option_group;
4348 OptionGroupFile m_file_option;
4349 OptionGroupBoolean m_current_frame_option;
4352 #pragma mark CommandObjectTargetSymbols
4354 //-------------------------------------------------------------------------
4355 // CommandObjectTargetSymbols
4356 //-------------------------------------------------------------------------
4358 class CommandObjectTargetSymbols : public CommandObjectMultiword {
4360 //------------------------------------------------------------------
4361 // Constructors and Destructors
4362 //------------------------------------------------------------------
4363 CommandObjectTargetSymbols(CommandInterpreter &interpreter)
4364 : CommandObjectMultiword(
4365 interpreter, "target symbols",
4366 "Commands for adding and managing debug symbol files.",
4367 "target symbols <sub-command> ...") {
4369 "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter)));
4372 ~CommandObjectTargetSymbols() override = default;
4375 //------------------------------------------------------------------
4376 // For CommandObjectTargetModules only
4377 //------------------------------------------------------------------
4378 DISALLOW_COPY_AND_ASSIGN(CommandObjectTargetSymbols);
4381 #pragma mark CommandObjectTargetStopHookAdd
4383 //-------------------------------------------------------------------------
4384 // CommandObjectTargetStopHookAdd
4385 //-------------------------------------------------------------------------
4387 static OptionDefinition g_target_stop_hook_add_options[] = {
4389 { LLDB_OPT_SET_ALL, false, "one-liner", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOneLiner, "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." },
4390 { LLDB_OPT_SET_ALL, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Set the module within which the stop-hook is to be run." },
4391 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "The stop hook is run only for the thread whose index matches this argument." },
4392 { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID, "The stop hook is run only for the thread whose TID matches this argument." },
4393 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName, "The stop hook is run only for the thread whose thread name matches this argument." },
4394 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName, "The stop hook is run only for threads in the queue whose name is given by this argument." },
4395 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specify the source file within which the stop-hook is to be run." },
4396 { LLDB_OPT_SET_1, false, "start-line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "Set the start of the line range for which the stop-hook is to be run." },
4397 { LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "Set the end of the line range for which the stop-hook is to be run." },
4398 { LLDB_OPT_SET_2, false, "classname", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeClassName, "Specify the class within which the stop-hook is to be run." },
4399 { LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the function name within which the stop hook will be run." },
4403 class CommandObjectTargetStopHookAdd : public CommandObjectParsed,
4404 public IOHandlerDelegateMultiline {
4406 class CommandOptions : public Options {
4409 : Options(), m_line_start(0), m_line_end(UINT_MAX),
4410 m_func_name_type_mask(eFunctionNameTypeAuto),
4411 m_sym_ctx_specified(false), m_thread_specified(false),
4412 m_use_one_liner(false), m_one_liner() {}
4414 ~CommandOptions() override = default;
4416 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
4417 return llvm::makeArrayRef(g_target_stop_hook_add_options);
4420 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
4421 ExecutionContext *execution_context) override {
4423 const int short_option = m_getopt_table[option_idx].val;
4425 switch (short_option) {
4427 m_class_name = option_arg;
4428 m_sym_ctx_specified = true;
4432 if (option_arg.getAsInteger(0, m_line_end)) {
4433 error.SetErrorStringWithFormat("invalid end line number: \"%s\"",
4434 option_arg.str().c_str());
4437 m_sym_ctx_specified = true;
4441 if (option_arg.getAsInteger(0, m_line_start)) {
4442 error.SetErrorStringWithFormat("invalid start line number: \"%s\"",
4443 option_arg.str().c_str());
4446 m_sym_ctx_specified = true;
4450 m_no_inlines = true;
4454 m_function_name = option_arg;
4455 m_func_name_type_mask |= eFunctionNameTypeAuto;
4456 m_sym_ctx_specified = true;
4460 m_file_name = option_arg;
4461 m_sym_ctx_specified = true;
4465 m_module_name = option_arg;
4466 m_sym_ctx_specified = true;
4470 if (option_arg.getAsInteger(0, m_thread_id))
4471 error.SetErrorStringWithFormat("invalid thread id string '%s'",
4472 option_arg.str().c_str());
4473 m_thread_specified = true;
4477 m_thread_name = option_arg;
4478 m_thread_specified = true;
4482 m_queue_name = option_arg;
4483 m_thread_specified = true;
4487 if (option_arg.getAsInteger(0, m_thread_index))
4488 error.SetErrorStringWithFormat("invalid thread index string '%s'",
4489 option_arg.str().c_str());
4490 m_thread_specified = true;
4494 m_use_one_liner = true;
4495 m_one_liner = option_arg;
4499 error.SetErrorStringWithFormat("unrecognized option %c.", short_option);
4505 void OptionParsingStarting(ExecutionContext *execution_context) override {
4506 m_class_name.clear();
4507 m_function_name.clear();
4509 m_line_end = UINT_MAX;
4510 m_file_name.clear();
4511 m_module_name.clear();
4512 m_func_name_type_mask = eFunctionNameTypeAuto;
4513 m_thread_id = LLDB_INVALID_THREAD_ID;
4514 m_thread_index = UINT32_MAX;
4515 m_thread_name.clear();
4516 m_queue_name.clear();
4518 m_no_inlines = false;
4519 m_sym_ctx_specified = false;
4520 m_thread_specified = false;
4522 m_use_one_liner = false;
4523 m_one_liner.clear();
4526 std::string m_class_name;
4527 std::string m_function_name;
4528 uint32_t m_line_start;
4529 uint32_t m_line_end;
4530 std::string m_file_name;
4531 std::string m_module_name;
4532 uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType.
4533 lldb::tid_t m_thread_id;
4534 uint32_t m_thread_index;
4535 std::string m_thread_name;
4536 std::string m_queue_name;
4537 bool m_sym_ctx_specified;
4539 bool m_thread_specified;
4540 // Instance variables to hold the values for one_liner options.
4541 bool m_use_one_liner;
4542 std::string m_one_liner;
4545 CommandObjectTargetStopHookAdd(CommandInterpreter &interpreter)
4546 : CommandObjectParsed(interpreter, "target stop-hook add",
4547 "Add a hook to be executed when the target stops.",
4548 "target stop-hook add"),
4549 IOHandlerDelegateMultiline("DONE",
4550 IOHandlerDelegate::Completion::LLDBCommand),
4553 ~CommandObjectTargetStopHookAdd() override = default;
4555 Options *GetOptions() override { return &m_options; }
4558 void IOHandlerActivated(IOHandler &io_handler) override {
4559 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
4561 output_sp->PutCString(
4562 "Enter your stop hook command(s). Type 'DONE' to end.\n");
4567 void IOHandlerInputComplete(IOHandler &io_handler,
4568 std::string &line) override {
4569 if (m_stop_hook_sp) {
4571 StreamFileSP error_sp(io_handler.GetErrorStreamFile());
4573 error_sp->Printf("error: stop hook #%" PRIu64
4574 " aborted, no commands.\n",
4575 m_stop_hook_sp->GetID());
4578 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
4580 target->RemoveStopHookByID(m_stop_hook_sp->GetID());
4582 m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line);
4583 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
4585 output_sp->Printf("Stop hook #%" PRIu64 " added.\n",
4586 m_stop_hook_sp->GetID());
4590 m_stop_hook_sp.reset();
4592 io_handler.SetIsDone(true);
4595 bool DoExecute(Args &command, CommandReturnObject &result) override {
4596 m_stop_hook_sp.reset();
4598 Target *target = GetSelectedOrDummyTarget();
4600 Target::StopHookSP new_hook_sp = target->CreateStopHook();
4602 // First step, make the specifier.
4603 std::unique_ptr<SymbolContextSpecifier> specifier_ap;
4604 if (m_options.m_sym_ctx_specified) {
4605 specifier_ap.reset(new SymbolContextSpecifier(
4606 m_interpreter.GetDebugger().GetSelectedTarget()));
4608 if (!m_options.m_module_name.empty()) {
4609 specifier_ap->AddSpecification(
4610 m_options.m_module_name.c_str(),
4611 SymbolContextSpecifier::eModuleSpecified);
4614 if (!m_options.m_class_name.empty()) {
4615 specifier_ap->AddSpecification(
4616 m_options.m_class_name.c_str(),
4617 SymbolContextSpecifier::eClassOrNamespaceSpecified);
4620 if (!m_options.m_file_name.empty()) {
4621 specifier_ap->AddSpecification(
4622 m_options.m_file_name.c_str(),
4623 SymbolContextSpecifier::eFileSpecified);
4626 if (m_options.m_line_start != 0) {
4627 specifier_ap->AddLineSpecification(
4628 m_options.m_line_start,
4629 SymbolContextSpecifier::eLineStartSpecified);
4632 if (m_options.m_line_end != UINT_MAX) {
4633 specifier_ap->AddLineSpecification(
4634 m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
4637 if (!m_options.m_function_name.empty()) {
4638 specifier_ap->AddSpecification(
4639 m_options.m_function_name.c_str(),
4640 SymbolContextSpecifier::eFunctionSpecified);
4645 new_hook_sp->SetSpecifier(specifier_ap.release());
4647 // Next see if any of the thread options have been entered:
4649 if (m_options.m_thread_specified) {
4650 ThreadSpec *thread_spec = new ThreadSpec();
4652 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) {
4653 thread_spec->SetTID(m_options.m_thread_id);
4656 if (m_options.m_thread_index != UINT32_MAX)
4657 thread_spec->SetIndex(m_options.m_thread_index);
4659 if (!m_options.m_thread_name.empty())
4660 thread_spec->SetName(m_options.m_thread_name.c_str());
4662 if (!m_options.m_queue_name.empty())
4663 thread_spec->SetQueueName(m_options.m_queue_name.c_str());
4665 new_hook_sp->SetThreadSpecifier(thread_spec);
4667 if (m_options.m_use_one_liner) {
4669 new_hook_sp->GetCommandPointer()->AppendString(
4670 m_options.m_one_liner.c_str());
4671 result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
4672 new_hook_sp->GetID());
4674 m_stop_hook_sp = new_hook_sp;
4675 m_interpreter.GetLLDBCommandsFromIOHandler(
4677 *this, // IOHandlerDelegate
4678 true, // Run IOHandler in async mode
4679 nullptr); // Baton for the "io_handler" that will be passed back
4680 // into our IOHandlerDelegate functions
4682 result.SetStatus(eReturnStatusSuccessFinishNoResult);
4684 result.AppendError("invalid target\n");
4685 result.SetStatus(eReturnStatusFailed);
4688 return result.Succeeded();
4692 CommandOptions m_options;
4693 Target::StopHookSP m_stop_hook_sp;
4696 #pragma mark CommandObjectTargetStopHookDelete
4698 //-------------------------------------------------------------------------
4699 // CommandObjectTargetStopHookDelete
4700 //-------------------------------------------------------------------------
4702 class CommandObjectTargetStopHookDelete : public CommandObjectParsed {
4704 CommandObjectTargetStopHookDelete(CommandInterpreter &interpreter)
4705 : CommandObjectParsed(interpreter, "target stop-hook delete",
4706 "Delete a stop-hook.",
4707 "target stop-hook delete [<idx>]") {}
4709 ~CommandObjectTargetStopHookDelete() override = default;
4712 bool DoExecute(Args &command, CommandReturnObject &result) override {
4713 Target *target = GetSelectedOrDummyTarget();
4715 // FIXME: see if we can use the breakpoint id style parser?
4716 size_t num_args = command.GetArgumentCount();
4717 if (num_args == 0) {
4718 if (!m_interpreter.Confirm("Delete all stop hooks?", true)) {
4719 result.SetStatus(eReturnStatusFailed);
4722 target->RemoveAllStopHooks();
4726 for (size_t i = 0; i < num_args; i++) {
4727 lldb::user_id_t user_id = StringConvert::ToUInt32(
4728 command.GetArgumentAtIndex(i), 0, 0, &success);
4730 result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4731 command.GetArgumentAtIndex(i));
4732 result.SetStatus(eReturnStatusFailed);
4735 success = target->RemoveStopHookByID(user_id);
4737 result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4738 command.GetArgumentAtIndex(i));
4739 result.SetStatus(eReturnStatusFailed);
4744 result.SetStatus(eReturnStatusSuccessFinishNoResult);
4746 result.AppendError("invalid target\n");
4747 result.SetStatus(eReturnStatusFailed);
4750 return result.Succeeded();
4754 #pragma mark CommandObjectTargetStopHookEnableDisable
4756 //-------------------------------------------------------------------------
4757 // CommandObjectTargetStopHookEnableDisable
4758 //-------------------------------------------------------------------------
4760 class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed {
4762 CommandObjectTargetStopHookEnableDisable(CommandInterpreter &interpreter,
4763 bool enable, const char *name,
4764 const char *help, const char *syntax)
4765 : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable) {
4768 ~CommandObjectTargetStopHookEnableDisable() override = default;
4771 bool DoExecute(Args &command, CommandReturnObject &result) override {
4772 Target *target = GetSelectedOrDummyTarget();
4774 // FIXME: see if we can use the breakpoint id style parser?
4775 size_t num_args = command.GetArgumentCount();
4778 if (num_args == 0) {
4779 target->SetAllStopHooksActiveState(m_enable);
4781 for (size_t i = 0; i < num_args; i++) {
4782 lldb::user_id_t user_id = StringConvert::ToUInt32(
4783 command.GetArgumentAtIndex(i), 0, 0, &success);
4785 result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4786 command.GetArgumentAtIndex(i));
4787 result.SetStatus(eReturnStatusFailed);
4790 success = target->SetStopHookActiveStateByID(user_id, m_enable);
4792 result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4793 command.GetArgumentAtIndex(i));
4794 result.SetStatus(eReturnStatusFailed);
4799 result.SetStatus(eReturnStatusSuccessFinishNoResult);
4801 result.AppendError("invalid target\n");
4802 result.SetStatus(eReturnStatusFailed);
4804 return result.Succeeded();
4811 #pragma mark CommandObjectTargetStopHookList
4813 //-------------------------------------------------------------------------
4814 // CommandObjectTargetStopHookList
4815 //-------------------------------------------------------------------------
4817 class CommandObjectTargetStopHookList : public CommandObjectParsed {
4819 CommandObjectTargetStopHookList(CommandInterpreter &interpreter)
4820 : CommandObjectParsed(interpreter, "target stop-hook list",
4821 "List all stop-hooks.",
4822 "target stop-hook list [<type>]") {}
4824 ~CommandObjectTargetStopHookList() override = default;
4827 bool DoExecute(Args &command, CommandReturnObject &result) override {
4828 Target *target = GetSelectedOrDummyTarget();
4830 result.AppendError("invalid target\n");
4831 result.SetStatus(eReturnStatusFailed);
4832 return result.Succeeded();
4835 size_t num_hooks = target->GetNumStopHooks();
4836 if (num_hooks == 0) {
4837 result.GetOutputStream().PutCString("No stop hooks.\n");
4839 for (size_t i = 0; i < num_hooks; i++) {
4840 Target::StopHookSP this_hook = target->GetStopHookAtIndex(i);
4842 result.GetOutputStream().PutCString("\n");
4843 this_hook->GetDescription(&(result.GetOutputStream()),
4844 eDescriptionLevelFull);
4847 result.SetStatus(eReturnStatusSuccessFinishResult);
4848 return result.Succeeded();
4852 #pragma mark CommandObjectMultiwordTargetStopHooks
4854 //-------------------------------------------------------------------------
4855 // CommandObjectMultiwordTargetStopHooks
4856 //-------------------------------------------------------------------------
4858 class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword {
4860 CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter)
4861 : CommandObjectMultiword(
4862 interpreter, "target stop-hook",
4863 "Commands for operating on debugger target stop-hooks.",
4864 "target stop-hook <subcommand> [<subcommand-options>]") {
4865 LoadSubCommand("add", CommandObjectSP(
4866 new CommandObjectTargetStopHookAdd(interpreter)));
4869 CommandObjectSP(new CommandObjectTargetStopHookDelete(interpreter)));
4870 LoadSubCommand("disable",
4871 CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
4872 interpreter, false, "target stop-hook disable [<id>]",
4873 "Disable a stop-hook.", "target stop-hook disable")));
4874 LoadSubCommand("enable",
4875 CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
4876 interpreter, true, "target stop-hook enable [<id>]",
4877 "Enable a stop-hook.", "target stop-hook enable")));
4878 LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetStopHookList(
4882 ~CommandObjectMultiwordTargetStopHooks() override = default;
4885 #pragma mark CommandObjectMultiwordTarget
4887 //-------------------------------------------------------------------------
4888 // CommandObjectMultiwordTarget
4889 //-------------------------------------------------------------------------
4891 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget(
4892 CommandInterpreter &interpreter)
4893 : CommandObjectMultiword(interpreter, "target",
4894 "Commands for operating on debugger targets.",
4895 "target <subcommand> [<subcommand-options>]") {
4896 LoadSubCommand("create",
4897 CommandObjectSP(new CommandObjectTargetCreate(interpreter)));
4898 LoadSubCommand("delete",
4899 CommandObjectSP(new CommandObjectTargetDelete(interpreter)));
4900 LoadSubCommand("list",
4901 CommandObjectSP(new CommandObjectTargetList(interpreter)));
4902 LoadSubCommand("select",
4903 CommandObjectSP(new CommandObjectTargetSelect(interpreter)));
4906 CommandObjectSP(new CommandObjectMultiwordTargetStopHooks(interpreter)));
4907 LoadSubCommand("modules",
4908 CommandObjectSP(new CommandObjectTargetModules(interpreter)));
4909 LoadSubCommand("symbols",
4910 CommandObjectSP(new CommandObjectTargetSymbols(interpreter)));
4911 LoadSubCommand("variable",
4912 CommandObjectSP(new CommandObjectTargetVariable(interpreter)));
4915 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget() = default;