1 //===-- CommandObjectTarget.cpp ---------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "CommandObjectTarget.h"
11 #include "lldb/Core/Debugger.h"
12 #include "lldb/Core/IOHandler.h"
13 #include "lldb/Core/Module.h"
14 #include "lldb/Core/ModuleSpec.h"
15 #include "lldb/Core/Section.h"
16 #include "lldb/Core/ValueObjectVariable.h"
17 #include "lldb/DataFormatters/ValueObjectPrinter.h"
18 #include "lldb/Host/OptionParser.h"
19 #include "lldb/Host/StringConvert.h"
20 #include "lldb/Interpreter/CommandInterpreter.h"
21 #include "lldb/Interpreter/CommandReturnObject.h"
22 #include "lldb/Interpreter/OptionArgParser.h"
23 #include "lldb/Interpreter/OptionGroupArchitecture.h"
24 #include "lldb/Interpreter/OptionGroupBoolean.h"
25 #include "lldb/Interpreter/OptionGroupFile.h"
26 #include "lldb/Interpreter/OptionGroupFormat.h"
27 #include "lldb/Interpreter/OptionGroupString.h"
28 #include "lldb/Interpreter/OptionGroupUInt64.h"
29 #include "lldb/Interpreter/OptionGroupUUID.h"
30 #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
31 #include "lldb/Interpreter/OptionGroupVariable.h"
32 #include "lldb/Interpreter/Options.h"
33 #include "lldb/Symbol/CompileUnit.h"
34 #include "lldb/Symbol/FuncUnwinders.h"
35 #include "lldb/Symbol/LineTable.h"
36 #include "lldb/Symbol/LocateSymbolFile.h"
37 #include "lldb/Symbol/ObjectFile.h"
38 #include "lldb/Symbol/SymbolFile.h"
39 #include "lldb/Symbol/UnwindPlan.h"
40 #include "lldb/Symbol/VariableList.h"
41 #include "lldb/Target/ABI.h"
42 #include "lldb/Target/Process.h"
43 #include "lldb/Target/RegisterContext.h"
44 #include "lldb/Target/SectionLoadList.h"
45 #include "lldb/Target/StackFrame.h"
46 #include "lldb/Target/Thread.h"
47 #include "lldb/Target/ThreadSpec.h"
48 #include "lldb/Utility/Args.h"
49 #include "lldb/Utility/State.h"
50 #include "lldb/Utility/Timer.h"
52 #include "llvm/Support/FileSystem.h"
53 #include "llvm/Support/FormatAdapters.h"
57 using namespace lldb_private
;
59 static void DumpTargetInfo(uint32_t target_idx
, Target
*target
,
60 const char *prefix_cstr
,
61 bool show_stopped_process_status
, Stream
&strm
) {
62 const ArchSpec
&target_arch
= target
->GetArchitecture();
64 Module
*exe_module
= target
->GetExecutableModulePointer();
65 char exe_path
[PATH_MAX
];
66 bool exe_valid
= false;
68 exe_valid
= exe_module
->GetFileSpec().GetPath(exe_path
, sizeof(exe_path
));
71 ::strcpy(exe_path
, "<none>");
73 strm
.Printf("%starget #%u: %s", prefix_cstr
? prefix_cstr
: "", target_idx
,
76 uint32_t properties
= 0;
77 if (target_arch
.IsValid()) {
78 strm
.Printf("%sarch=", properties
++ > 0 ? ", " : " ( ");
79 target_arch
.DumpTriple(strm
.AsRawOstream());
82 PlatformSP
platform_sp(target
->GetPlatform());
84 strm
.Printf("%splatform=%s", properties
++ > 0 ? ", " : " ( ",
85 platform_sp
->GetName().GetCString());
87 ProcessSP
process_sp(target
->GetProcessSP());
88 bool show_process_status
= false;
90 lldb::pid_t pid
= process_sp
->GetID();
91 StateType state
= process_sp
->GetState();
92 if (show_stopped_process_status
)
93 show_process_status
= StateIsStoppedState(state
, true);
94 const char *state_cstr
= StateAsCString(state
);
95 if (pid
!= LLDB_INVALID_PROCESS_ID
)
96 strm
.Printf("%spid=%" PRIu64
, properties
++ > 0 ? ", " : " ( ", pid
);
97 strm
.Printf("%sstate=%s", properties
++ > 0 ? ", " : " ( ", state_cstr
);
100 strm
.PutCString(" )\n");
103 if (show_process_status
) {
104 const bool only_threads_with_stop_reason
= true;
105 const uint32_t start_frame
= 0;
106 const uint32_t num_frames
= 1;
107 const uint32_t num_frames_with_source
= 1;
108 const bool stop_format
= false;
109 process_sp
->GetStatus(strm
);
110 process_sp
->GetThreadStatus(strm
, only_threads_with_stop_reason
,
111 start_frame
, num_frames
, num_frames_with_source
,
116 static uint32_t DumpTargetList(TargetList
&target_list
,
117 bool show_stopped_process_status
, Stream
&strm
) {
118 const uint32_t num_targets
= target_list
.GetNumTargets();
120 TargetSP
selected_target_sp(target_list
.GetSelectedTarget());
121 strm
.PutCString("Current targets:\n");
122 for (uint32_t i
= 0; i
< num_targets
; ++i
) {
123 TargetSP
target_sp(target_list
.GetTargetAtIndex(i
));
125 bool is_selected
= target_sp
.get() == selected_target_sp
.get();
126 DumpTargetInfo(i
, target_sp
.get(), is_selected
? "* " : " ",
127 show_stopped_process_status
, strm
);
134 // Note that the negation in the argument name causes a slightly confusing
135 // mapping of the enum values.
136 static constexpr OptionEnumValueElement g_dependents_enumaration
[] = {
138 eLoadDependentsDefault
,
140 "Only load dependents when the target is an executable.",
145 "Don't load dependents, even if the target is an executable.",
150 "Load dependents, even if the target is not an executable.",
154 #define LLDB_OPTIONS_target_dependents
155 #include "CommandOptions.inc"
157 class OptionGroupDependents
: public OptionGroup
{
159 OptionGroupDependents() {}
161 ~OptionGroupDependents() override
{}
163 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
164 return llvm::makeArrayRef(g_target_dependents_options
);
167 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_value
,
168 ExecutionContext
*execution_context
) override
{
171 // For compatibility no value means don't load dependents.
172 if (option_value
.empty()) {
173 m_load_dependent_files
= eLoadDependentsNo
;
177 const char short_option
=
178 g_target_dependents_options
[option_idx
].short_option
;
179 if (short_option
== 'd') {
180 LoadDependentFiles tmp_load_dependents
;
181 tmp_load_dependents
= (LoadDependentFiles
)OptionArgParser::ToOptionEnum(
182 option_value
, g_target_dependents_options
[option_idx
].enum_values
, 0,
185 m_load_dependent_files
= tmp_load_dependents
;
187 error
.SetErrorStringWithFormat("unrecognized short option '%c'",
194 Status
SetOptionValue(uint32_t, const char *, ExecutionContext
*) = delete;
196 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
197 m_load_dependent_files
= eLoadDependentsDefault
;
200 LoadDependentFiles m_load_dependent_files
;
203 DISALLOW_COPY_AND_ASSIGN(OptionGroupDependents
);
206 #pragma mark CommandObjectTargetCreate
210 class CommandObjectTargetCreate
: public CommandObjectParsed
{
212 CommandObjectTargetCreate(CommandInterpreter
&interpreter
)
213 : CommandObjectParsed(
214 interpreter
, "target create",
215 "Create a target using the argument as the main executable.",
217 m_option_group(), m_arch_option(),
218 m_core_file(LLDB_OPT_SET_1
, false, "core", 'c', 0, eArgTypeFilename
,
219 "Fullpath to a core file to use for this target."),
220 m_platform_path(LLDB_OPT_SET_1
, false, "platform-path", 'P', 0,
222 "Path to the remote file to use for this target."),
223 m_symbol_file(LLDB_OPT_SET_1
, false, "symfile", 's', 0,
225 "Fullpath to a stand alone debug "
226 "symbols file for when debug symbols "
227 "are not in the executable."),
229 LLDB_OPT_SET_1
, false, "remote-file", 'r', 0, eArgTypeFilename
,
230 "Fullpath to the file on the remote host if debugging remotely."),
232 CommandArgumentEntry arg
;
233 CommandArgumentData file_arg
;
235 // Define the first (and only) variant of this arg.
236 file_arg
.arg_type
= eArgTypeFilename
;
237 file_arg
.arg_repetition
= eArgRepeatPlain
;
239 // There is only one variant this argument could be; put it into the
241 arg
.push_back(file_arg
);
243 // Push the data for the first argument into the m_arguments vector.
244 m_arguments
.push_back(arg
);
246 m_option_group
.Append(&m_arch_option
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
247 m_option_group
.Append(&m_core_file
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
248 m_option_group
.Append(&m_platform_path
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
249 m_option_group
.Append(&m_symbol_file
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
250 m_option_group
.Append(&m_remote_file
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
251 m_option_group
.Append(&m_add_dependents
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
252 m_option_group
.Finalize();
255 ~CommandObjectTargetCreate() override
= default;
257 Options
*GetOptions() override
{ return &m_option_group
; }
260 HandleArgumentCompletion(CompletionRequest
&request
,
261 OptionElementVector
&opt_element_vector
) override
{
262 CommandCompletions::InvokeCommonCompletionCallbacks(
263 GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion
,
268 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
269 const size_t argc
= command
.GetArgumentCount();
270 FileSpec
core_file(m_core_file
.GetOptionValue().GetCurrentValue());
271 FileSpec
remote_file(m_remote_file
.GetOptionValue().GetCurrentValue());
274 if (!FileSystem::Instance().Exists(core_file
)) {
275 result
.AppendErrorWithFormat("core file '%s' doesn't exist",
276 core_file
.GetPath().c_str());
277 result
.SetStatus(eReturnStatusFailed
);
280 if (!FileSystem::Instance().Readable(core_file
)) {
281 result
.AppendErrorWithFormat("core file '%s' is not readable",
282 core_file
.GetPath().c_str());
283 result
.SetStatus(eReturnStatusFailed
);
288 if (argc
== 1 || core_file
|| remote_file
) {
289 FileSpec
symfile(m_symbol_file
.GetOptionValue().GetCurrentValue());
291 if (FileSystem::Instance().Exists(symfile
)) {
292 if (!FileSystem::Instance().Readable(symfile
)) {
293 result
.AppendErrorWithFormat("symbol file '%s' is not readable",
294 symfile
.GetPath().c_str());
295 result
.SetStatus(eReturnStatusFailed
);
299 char symfile_path
[PATH_MAX
];
300 symfile
.GetPath(symfile_path
, sizeof(symfile_path
));
301 result
.AppendErrorWithFormat("invalid symbol file path '%s'",
303 result
.SetStatus(eReturnStatusFailed
);
308 const char *file_path
= command
.GetArgumentAtIndex(0);
309 static Timer::Category
func_cat(LLVM_PRETTY_FUNCTION
);
310 Timer
scoped_timer(func_cat
, "(lldb) target create '%s'", file_path
);
314 file_spec
.SetFile(file_path
, FileSpec::Style::native
);
315 FileSystem::Instance().Resolve(file_spec
);
318 bool must_set_platform_path
= false;
320 Debugger
&debugger
= GetDebugger();
323 llvm::StringRef arch_cstr
= m_arch_option
.GetArchitectureName();
324 Status
error(debugger
.GetTargetList().CreateTarget(
325 debugger
, file_path
, arch_cstr
,
326 m_add_dependents
.m_load_dependent_files
, nullptr, target_sp
));
329 // Only get the platform after we create the target because we might
330 // have switched platforms depending on what the arguments were to
331 // CreateTarget() we can't rely on the selected platform.
333 PlatformSP platform_sp
= target_sp
->GetPlatform();
337 // I have a remote file.. two possible cases
338 if (file_spec
&& FileSystem::Instance().Exists(file_spec
)) {
339 // if the remote file does not exist, push it there
340 if (!platform_sp
->GetFileExists(remote_file
)) {
341 Status err
= platform_sp
->PutFile(file_spec
, remote_file
);
343 result
.AppendError(err
.AsCString());
344 result
.SetStatus(eReturnStatusFailed
);
349 // there is no local file and we need one
350 // in order to make the remote ---> local transfer we need a
352 // TODO: if the user has passed in a --platform argument, use it
353 // to fetch the right platform
356 "unable to perform remote debugging without a platform");
357 result
.SetStatus(eReturnStatusFailed
);
361 // copy the remote file to the local file
362 Status err
= platform_sp
->GetFile(remote_file
, file_spec
);
364 result
.AppendError(err
.AsCString());
365 result
.SetStatus(eReturnStatusFailed
);
369 // make up a local file
370 result
.AppendError("remote --> local transfer without local "
371 "path is not implemented yet");
372 result
.SetStatus(eReturnStatusFailed
);
377 result
.AppendError("no platform found for target");
378 result
.SetStatus(eReturnStatusFailed
);
383 if (symfile
|| remote_file
) {
384 ModuleSP
module_sp(target_sp
->GetExecutableModule());
387 module_sp
->SetSymbolFileFileSpec(symfile
);
389 std::string remote_path
= remote_file
.GetPath();
390 target_sp
->SetArg0(remote_path
.c_str());
391 module_sp
->SetPlatformFileSpec(remote_file
);
396 debugger
.GetTargetList().SetSelectedTarget(target_sp
.get());
397 if (must_set_platform_path
) {
398 ModuleSpec
main_module_spec(file_spec
);
400 target_sp
->GetOrCreateModule(main_module_spec
, true /* notify */);
402 module_sp
->SetPlatformFileSpec(remote_file
);
405 char core_path
[PATH_MAX
];
406 core_file
.GetPath(core_path
, sizeof(core_path
));
407 if (FileSystem::Instance().Exists(core_file
)) {
408 if (!FileSystem::Instance().Readable(core_file
)) {
409 result
.AppendMessageWithFormat(
410 "Core file '%s' is not readable.\n", core_path
);
411 result
.SetStatus(eReturnStatusFailed
);
414 FileSpec core_file_dir
;
415 core_file_dir
.GetDirectory() = core_file
.GetDirectory();
416 target_sp
->AppendExecutableSearchPaths(core_file_dir
);
418 ProcessSP
process_sp(target_sp
->CreateProcess(
419 GetDebugger().GetListener(), llvm::StringRef(), &core_file
));
422 // Seems weird that we Launch a core file, but that is what we
424 error
= process_sp
->LoadCore();
428 error
.AsCString("can't find plug-in for core file"));
429 result
.SetStatus(eReturnStatusFailed
);
432 result
.AppendMessageWithFormat(
433 "Core file '%s' (%s) was loaded.\n", core_path
,
434 target_sp
->GetArchitecture().GetArchitectureName());
435 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
438 result
.AppendErrorWithFormat(
439 "Unable to find process plug-in for core file '%s'\n",
441 result
.SetStatus(eReturnStatusFailed
);
444 result
.AppendErrorWithFormat("Core file '%s' does not exist\n",
446 result
.SetStatus(eReturnStatusFailed
);
449 result
.AppendMessageWithFormat(
450 "Current executable set to '%s' (%s).\n",
451 file_spec
.GetPath().c_str(),
452 target_sp
->GetArchitecture().GetArchitectureName());
453 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
456 result
.AppendError(error
.AsCString());
457 result
.SetStatus(eReturnStatusFailed
);
460 result
.AppendErrorWithFormat("'%s' takes exactly one executable path "
461 "argument, or use the --core option.\n",
463 result
.SetStatus(eReturnStatusFailed
);
465 return result
.Succeeded();
469 OptionGroupOptions m_option_group
;
470 OptionGroupArchitecture m_arch_option
;
471 OptionGroupFile m_core_file
;
472 OptionGroupFile m_platform_path
;
473 OptionGroupFile m_symbol_file
;
474 OptionGroupFile m_remote_file
;
475 OptionGroupDependents m_add_dependents
;
478 #pragma mark CommandObjectTargetList
482 class CommandObjectTargetList
: public CommandObjectParsed
{
484 CommandObjectTargetList(CommandInterpreter
&interpreter
)
485 : CommandObjectParsed(
486 interpreter
, "target list",
487 "List all current targets in the current debug session.", nullptr) {
490 ~CommandObjectTargetList() override
= default;
493 bool DoExecute(Args
&args
, CommandReturnObject
&result
) override
{
494 if (args
.GetArgumentCount() == 0) {
495 Stream
&strm
= result
.GetOutputStream();
497 bool show_stopped_process_status
= false;
498 if (DumpTargetList(GetDebugger().GetTargetList(),
499 show_stopped_process_status
, strm
) == 0) {
500 strm
.PutCString("No targets.\n");
502 result
.SetStatus(eReturnStatusSuccessFinishResult
);
504 result
.AppendError("the 'target list' command takes no arguments\n");
505 result
.SetStatus(eReturnStatusFailed
);
507 return result
.Succeeded();
511 #pragma mark CommandObjectTargetSelect
515 class CommandObjectTargetSelect
: public CommandObjectParsed
{
517 CommandObjectTargetSelect(CommandInterpreter
&interpreter
)
518 : CommandObjectParsed(
519 interpreter
, "target select",
520 "Select a target as the current target by target index.", nullptr) {
523 ~CommandObjectTargetSelect() override
= default;
526 bool DoExecute(Args
&args
, CommandReturnObject
&result
) override
{
527 if (args
.GetArgumentCount() == 1) {
528 bool success
= false;
529 const char *target_idx_arg
= args
.GetArgumentAtIndex(0);
530 uint32_t target_idx
=
531 StringConvert::ToUInt32(target_idx_arg
, UINT32_MAX
, 0, &success
);
533 TargetList
&target_list
= GetDebugger().GetTargetList();
534 const uint32_t num_targets
= target_list
.GetNumTargets();
535 if (target_idx
< num_targets
) {
536 TargetSP
target_sp(target_list
.GetTargetAtIndex(target_idx
));
538 Stream
&strm
= result
.GetOutputStream();
539 target_list
.SetSelectedTarget(target_sp
.get());
540 bool show_stopped_process_status
= false;
541 DumpTargetList(target_list
, show_stopped_process_status
, strm
);
542 result
.SetStatus(eReturnStatusSuccessFinishResult
);
544 result
.AppendErrorWithFormat("target #%u is NULL in target list\n",
546 result
.SetStatus(eReturnStatusFailed
);
549 if (num_targets
> 0) {
550 result
.AppendErrorWithFormat(
551 "index %u is out of range, valid target indexes are 0 - %u\n",
552 target_idx
, num_targets
- 1);
554 result
.AppendErrorWithFormat(
555 "index %u is out of range since there are no active targets\n",
558 result
.SetStatus(eReturnStatusFailed
);
561 result
.AppendErrorWithFormat("invalid index string value '%s'\n",
563 result
.SetStatus(eReturnStatusFailed
);
567 "'target select' takes a single argument: a target index\n");
568 result
.SetStatus(eReturnStatusFailed
);
570 return result
.Succeeded();
574 #pragma mark CommandObjectTargetSelect
578 class CommandObjectTargetDelete
: public CommandObjectParsed
{
580 CommandObjectTargetDelete(CommandInterpreter
&interpreter
)
581 : CommandObjectParsed(interpreter
, "target delete",
582 "Delete one or more targets by target index.",
584 m_option_group(), m_all_option(LLDB_OPT_SET_1
, false, "all", 'a',
585 "Delete all targets.", false, true),
587 LLDB_OPT_SET_1
, false, "clean", 'c',
588 "Perform extra cleanup to minimize memory consumption after "
589 "deleting the target. "
590 "By default, LLDB will keep in memory any modules previously "
591 "loaded by the target as well "
592 "as all of its debug info. Specifying --clean will unload all of "
593 "these shared modules and "
594 "cause them to be reparsed again the next time the target is run",
596 m_option_group
.Append(&m_all_option
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
597 m_option_group
.Append(&m_cleanup_option
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
598 m_option_group
.Finalize();
601 ~CommandObjectTargetDelete() override
= default;
603 Options
*GetOptions() override
{ return &m_option_group
; }
606 bool DoExecute(Args
&args
, CommandReturnObject
&result
) override
{
607 const size_t argc
= args
.GetArgumentCount();
608 std::vector
<TargetSP
> delete_target_list
;
609 TargetList
&target_list
= GetDebugger().GetTargetList();
612 if (m_all_option
.GetOptionValue()) {
613 for (int i
= 0; i
< target_list
.GetNumTargets(); ++i
)
614 delete_target_list
.push_back(target_list
.GetTargetAtIndex(i
));
615 } else if (argc
> 0) {
616 const uint32_t num_targets
= target_list
.GetNumTargets();
617 // Bail out if don't have any targets.
618 if (num_targets
== 0) {
619 result
.AppendError("no targets to delete");
620 result
.SetStatus(eReturnStatusFailed
);
624 for (auto &entry
: args
.entries()) {
626 if (entry
.ref().getAsInteger(0, target_idx
)) {
627 result
.AppendErrorWithFormat("invalid target index '%s'\n",
629 result
.SetStatus(eReturnStatusFailed
);
632 if (target_idx
< num_targets
) {
633 target_sp
= target_list
.GetTargetAtIndex(target_idx
);
635 delete_target_list
.push_back(target_sp
);
640 result
.AppendErrorWithFormat("target index %u is out of range, valid "
641 "target indexes are 0 - %u\n",
642 target_idx
, num_targets
- 1);
644 result
.AppendErrorWithFormat(
645 "target index %u is out of range, the only valid index is 0\n",
648 result
.SetStatus(eReturnStatusFailed
);
652 target_sp
= target_list
.GetSelectedTarget();
654 result
.AppendErrorWithFormat("no target is currently selected\n");
655 result
.SetStatus(eReturnStatusFailed
);
658 delete_target_list
.push_back(target_sp
);
661 const size_t num_targets_to_delete
= delete_target_list
.size();
662 for (size_t idx
= 0; idx
< num_targets_to_delete
; ++idx
) {
663 target_sp
= delete_target_list
[idx
];
664 target_list
.DeleteTarget(target_sp
);
665 target_sp
->Destroy();
667 // If "--clean" was specified, prune any orphaned shared modules from the
668 // global shared module list
669 if (m_cleanup_option
.GetOptionValue()) {
670 const bool mandatory
= true;
671 ModuleList::RemoveOrphanSharedModules(mandatory
);
673 result
.GetOutputStream().Printf("%u targets deleted.\n",
674 (uint32_t)num_targets_to_delete
);
675 result
.SetStatus(eReturnStatusSuccessFinishResult
);
680 OptionGroupOptions m_option_group
;
681 OptionGroupBoolean m_all_option
;
682 OptionGroupBoolean m_cleanup_option
;
685 #pragma mark CommandObjectTargetVariable
689 class CommandObjectTargetVariable
: public CommandObjectParsed
{
690 static const uint32_t SHORT_OPTION_FILE
= 0x66696c65; // 'file'
691 static const uint32_t SHORT_OPTION_SHLB
= 0x73686c62; // 'shlb'
694 CommandObjectTargetVariable(CommandInterpreter
&interpreter
)
695 : CommandObjectParsed(interpreter
, "target variable",
696 "Read global variables for the current target, "
697 "before or while running a process.",
698 nullptr, eCommandRequiresTarget
),
700 m_option_variable(false), // Don't include frame options
701 m_option_format(eFormatDefault
),
702 m_option_compile_units(LLDB_OPT_SET_1
, false, "file", SHORT_OPTION_FILE
,
704 "A basename or fullpath to a file that contains "
705 "global variables. This option can be "
706 "specified multiple times."),
707 m_option_shared_libraries(
708 LLDB_OPT_SET_1
, false, "shlib", SHORT_OPTION_SHLB
, 0,
710 "A basename or fullpath to a shared library to use in the search "
712 "variables. This option can be specified multiple times."),
714 CommandArgumentEntry arg
;
715 CommandArgumentData var_name_arg
;
717 // Define the first (and only) variant of this arg.
718 var_name_arg
.arg_type
= eArgTypeVarName
;
719 var_name_arg
.arg_repetition
= eArgRepeatPlus
;
721 // There is only one variant this argument could be; put it into the
723 arg
.push_back(var_name_arg
);
725 // Push the data for the first argument into the m_arguments vector.
726 m_arguments
.push_back(arg
);
728 m_option_group
.Append(&m_varobj_options
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
729 m_option_group
.Append(&m_option_variable
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
730 m_option_group
.Append(&m_option_format
,
731 OptionGroupFormat::OPTION_GROUP_FORMAT
|
732 OptionGroupFormat::OPTION_GROUP_GDB_FMT
,
734 m_option_group
.Append(&m_option_compile_units
, LLDB_OPT_SET_ALL
,
736 m_option_group
.Append(&m_option_shared_libraries
, LLDB_OPT_SET_ALL
,
738 m_option_group
.Finalize();
741 ~CommandObjectTargetVariable() override
= default;
743 void DumpValueObject(Stream
&s
, VariableSP
&var_sp
, ValueObjectSP
&valobj_sp
,
744 const char *root_name
) {
745 DumpValueObjectOptions
options(m_varobj_options
.GetAsDumpOptions());
747 if (!valobj_sp
->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
748 valobj_sp
->IsRuntimeSupportValue())
751 switch (var_sp
->GetScope()) {
752 case eValueTypeVariableGlobal
:
753 if (m_option_variable
.show_scope
)
754 s
.PutCString("GLOBAL: ");
757 case eValueTypeVariableStatic
:
758 if (m_option_variable
.show_scope
)
759 s
.PutCString("STATIC: ");
762 case eValueTypeVariableArgument
:
763 if (m_option_variable
.show_scope
)
764 s
.PutCString(" ARG: ");
767 case eValueTypeVariableLocal
:
768 if (m_option_variable
.show_scope
)
769 s
.PutCString(" LOCAL: ");
772 case eValueTypeVariableThreadLocal
:
773 if (m_option_variable
.show_scope
)
774 s
.PutCString("THREAD: ");
781 if (m_option_variable
.show_decl
) {
782 bool show_fullpaths
= false;
783 bool show_module
= true;
784 if (var_sp
->DumpDeclaration(&s
, show_fullpaths
, show_module
))
788 const Format format
= m_option_format
.GetFormat();
789 if (format
!= eFormatDefault
)
790 options
.SetFormat(format
);
792 options
.SetRootValueObjectName(root_name
);
794 valobj_sp
->Dump(s
, options
);
797 static size_t GetVariableCallback(void *baton
, const char *name
,
798 VariableList
&variable_list
) {
799 size_t old_size
= variable_list
.GetSize();
800 Target
*target
= static_cast<Target
*>(baton
);
802 target
->GetImages().FindGlobalVariables(ConstString(name
), UINT32_MAX
,
804 return variable_list
.GetSize() - old_size
;
807 Options
*GetOptions() override
{ return &m_option_group
; }
810 void DumpGlobalVariableList(const ExecutionContext
&exe_ctx
,
811 const SymbolContext
&sc
,
812 const VariableList
&variable_list
, Stream
&s
) {
813 if (variable_list
.Empty())
817 s
.Format("Global variables for {0} in {1}:\n",
818 sc
.comp_unit
->GetPrimaryFile(), sc
.module_sp
->GetFileSpec());
820 s
.Printf("Global variables for %s\n",
821 sc
.module_sp
->GetFileSpec().GetPath().c_str());
823 } else if (sc
.comp_unit
) {
824 s
.Format("Global variables for {0}\n", sc
.comp_unit
->GetPrimaryFile());
827 for (VariableSP var_sp
: variable_list
) {
830 ValueObjectSP
valobj_sp(ValueObjectVariable::Create(
831 exe_ctx
.GetBestExecutionContextScope(), var_sp
));
834 DumpValueObject(s
, var_sp
, valobj_sp
, var_sp
->GetName().GetCString());
838 bool DoExecute(Args
&args
, CommandReturnObject
&result
) override
{
839 Target
*target
= m_exe_ctx
.GetTargetPtr();
840 const size_t argc
= args
.GetArgumentCount();
841 Stream
&s
= result
.GetOutputStream();
845 // TODO: Convert to entry-based iteration. Requires converting
847 for (size_t idx
= 0; idx
< argc
; ++idx
) {
848 VariableList variable_list
;
849 ValueObjectList valobj_list
;
851 const char *arg
= args
.GetArgumentAtIndex(idx
);
853 bool use_var_name
= false;
854 if (m_option_variable
.use_regex
) {
855 RegularExpression
regex(llvm::StringRef::withNullAsEmpty(arg
));
856 if (!regex
.IsValid()) {
857 result
.GetErrorStream().Printf(
858 "error: invalid regular expression: '%s'\n", arg
);
859 result
.SetStatus(eReturnStatusFailed
);
863 target
->GetImages().FindGlobalVariables(regex
, UINT32_MAX
,
865 matches
= variable_list
.GetSize();
867 Status
error(Variable::GetValuesForVariableExpressionPath(
868 arg
, m_exe_ctx
.GetBestExecutionContextScope(),
869 GetVariableCallback
, target
, variable_list
, valobj_list
));
870 matches
= variable_list
.GetSize();
874 result
.GetErrorStream().Printf(
875 "error: can't find global variable '%s'\n", arg
);
876 result
.SetStatus(eReturnStatusFailed
);
879 for (uint32_t global_idx
= 0; global_idx
< matches
; ++global_idx
) {
880 VariableSP
var_sp(variable_list
.GetVariableAtIndex(global_idx
));
882 ValueObjectSP
valobj_sp(
883 valobj_list
.GetValueObjectAtIndex(global_idx
));
885 valobj_sp
= ValueObjectVariable::Create(
886 m_exe_ctx
.GetBestExecutionContextScope(), var_sp
);
889 DumpValueObject(s
, var_sp
, valobj_sp
,
890 use_var_name
? var_sp
->GetName().GetCString()
897 const FileSpecList
&compile_units
=
898 m_option_compile_units
.GetOptionValue().GetCurrentValue();
899 const FileSpecList
&shlibs
=
900 m_option_shared_libraries
.GetOptionValue().GetCurrentValue();
901 SymbolContextList sc_list
;
902 const size_t num_compile_units
= compile_units
.GetSize();
903 const size_t num_shlibs
= shlibs
.GetSize();
904 if (num_compile_units
== 0 && num_shlibs
== 0) {
905 bool success
= false;
906 StackFrame
*frame
= m_exe_ctx
.GetFramePtr();
907 CompileUnit
*comp_unit
= nullptr;
909 SymbolContext sc
= frame
->GetSymbolContext(eSymbolContextCompUnit
);
911 const bool can_create
= true;
912 VariableListSP
comp_unit_varlist_sp(
913 sc
.comp_unit
->GetVariableList(can_create
));
914 if (comp_unit_varlist_sp
) {
915 size_t count
= comp_unit_varlist_sp
->GetSize();
917 DumpGlobalVariableList(m_exe_ctx
, sc
, *comp_unit_varlist_sp
, s
);
926 result
.AppendErrorWithFormatv(
927 "no global variables in current compile unit: {0}\n",
928 comp_unit
->GetPrimaryFile());
930 result
.AppendErrorWithFormat(
931 "no debug information for frame %u\n",
932 frame
->GetFrameIndex());
934 result
.AppendError("'target variable' takes one or more global "
935 "variable names as arguments\n");
936 result
.SetStatus(eReturnStatusFailed
);
939 SymbolContextList sc_list
;
940 // We have one or more compile unit or shlib
941 if (num_shlibs
> 0) {
942 for (size_t shlib_idx
= 0; shlib_idx
< num_shlibs
; ++shlib_idx
) {
943 const FileSpec
module_file(shlibs
.GetFileSpecAtIndex(shlib_idx
));
944 ModuleSpec
module_spec(module_file
);
947 target
->GetImages().FindFirstModule(module_spec
));
949 if (num_compile_units
> 0) {
950 for (size_t cu_idx
= 0; cu_idx
< num_compile_units
; ++cu_idx
)
951 module_sp
->FindCompileUnits(
952 compile_units
.GetFileSpecAtIndex(cu_idx
), sc_list
);
955 sc
.module_sp
= module_sp
;
959 // Didn't find matching shlib/module in target...
960 result
.AppendErrorWithFormat(
961 "target doesn't contain the specified shared library: %s\n",
962 module_file
.GetPath().c_str());
966 // No shared libraries, we just want to find globals for the compile
967 // units files that were specified
968 for (size_t cu_idx
= 0; cu_idx
< num_compile_units
; ++cu_idx
)
969 target
->GetImages().FindCompileUnits(
970 compile_units
.GetFileSpecAtIndex(cu_idx
), sc_list
);
973 const uint32_t num_scs
= sc_list
.GetSize();
976 for (uint32_t sc_idx
= 0; sc_idx
< num_scs
; ++sc_idx
) {
977 if (sc_list
.GetContextAtIndex(sc_idx
, sc
)) {
979 const bool can_create
= true;
980 VariableListSP
comp_unit_varlist_sp(
981 sc
.comp_unit
->GetVariableList(can_create
));
982 if (comp_unit_varlist_sp
)
983 DumpGlobalVariableList(m_exe_ctx
, sc
, *comp_unit_varlist_sp
,
985 } else if (sc
.module_sp
) {
986 // Get all global variables for this module
987 lldb_private::RegularExpression
all_globals_regex(
989 ".")); // Any global with at least one character
990 VariableList variable_list
;
991 sc
.module_sp
->FindGlobalVariables(all_globals_regex
, UINT32_MAX
,
993 DumpGlobalVariableList(m_exe_ctx
, sc
, variable_list
, s
);
1001 if (m_interpreter
.TruncationWarningNecessary()) {
1002 result
.GetOutputStream().Printf(m_interpreter
.TruncationWarningText(),
1003 m_cmd_name
.c_str());
1004 m_interpreter
.TruncationWarningGiven();
1007 return result
.Succeeded();
1010 OptionGroupOptions m_option_group
;
1011 OptionGroupVariable m_option_variable
;
1012 OptionGroupFormat m_option_format
;
1013 OptionGroupFileList m_option_compile_units
;
1014 OptionGroupFileList m_option_shared_libraries
;
1015 OptionGroupValueObjectDisplay m_varobj_options
;
1018 #pragma mark CommandObjectTargetModulesSearchPathsAdd
1020 class CommandObjectTargetModulesSearchPathsAdd
: public CommandObjectParsed
{
1022 CommandObjectTargetModulesSearchPathsAdd(CommandInterpreter
&interpreter
)
1023 : CommandObjectParsed(interpreter
, "target modules search-paths add",
1024 "Add new image search paths substitution pairs to "
1025 "the current target.",
1026 nullptr, eCommandRequiresTarget
) {
1027 CommandArgumentEntry arg
;
1028 CommandArgumentData old_prefix_arg
;
1029 CommandArgumentData new_prefix_arg
;
1031 // Define the first variant of this arg pair.
1032 old_prefix_arg
.arg_type
= eArgTypeOldPathPrefix
;
1033 old_prefix_arg
.arg_repetition
= eArgRepeatPairPlus
;
1035 // Define the first variant of this arg pair.
1036 new_prefix_arg
.arg_type
= eArgTypeNewPathPrefix
;
1037 new_prefix_arg
.arg_repetition
= eArgRepeatPairPlus
;
1039 // There are two required arguments that must always occur together, i.e.
1040 // an argument "pair". Because they must always occur together, they are
1041 // treated as two variants of one argument rather than two independent
1042 // arguments. Push them both into the first argument position for
1045 arg
.push_back(old_prefix_arg
);
1046 arg
.push_back(new_prefix_arg
);
1048 m_arguments
.push_back(arg
);
1051 ~CommandObjectTargetModulesSearchPathsAdd() override
= default;
1054 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1055 Target
*target
= &GetSelectedTarget();
1056 const size_t argc
= command
.GetArgumentCount();
1058 result
.AppendError("add requires an even number of arguments\n");
1059 result
.SetStatus(eReturnStatusFailed
);
1061 for (size_t i
= 0; i
< argc
; i
+= 2) {
1062 const char *from
= command
.GetArgumentAtIndex(i
);
1063 const char *to
= command
.GetArgumentAtIndex(i
+ 1);
1065 if (from
[0] && to
[0]) {
1066 Log
*log
= lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST
);
1069 "target modules search path adding ImageSearchPath "
1070 "pair: '%s' -> '%s'",
1073 bool last_pair
= ((argc
- i
) == 2);
1074 target
->GetImageSearchPathList().Append(
1075 ConstString(from
), ConstString(to
),
1076 last_pair
); // Notify if this is the last pair
1077 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
1080 result
.AppendError("<path-prefix> can't be empty\n");
1082 result
.AppendError("<new-path-prefix> can't be empty\n");
1083 result
.SetStatus(eReturnStatusFailed
);
1087 return result
.Succeeded();
1091 #pragma mark CommandObjectTargetModulesSearchPathsClear
1093 class CommandObjectTargetModulesSearchPathsClear
: public CommandObjectParsed
{
1095 CommandObjectTargetModulesSearchPathsClear(CommandInterpreter
&interpreter
)
1096 : CommandObjectParsed(interpreter
, "target modules search-paths clear",
1097 "Clear all current image search path substitution "
1098 "pairs from the current target.",
1099 "target modules search-paths clear",
1100 eCommandRequiresTarget
) {}
1102 ~CommandObjectTargetModulesSearchPathsClear() override
= default;
1105 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1106 Target
*target
= &GetSelectedTarget();
1108 target
->GetImageSearchPathList().Clear(notify
);
1109 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
1110 return result
.Succeeded();
1114 #pragma mark CommandObjectTargetModulesSearchPathsInsert
1116 class CommandObjectTargetModulesSearchPathsInsert
: public CommandObjectParsed
{
1118 CommandObjectTargetModulesSearchPathsInsert(CommandInterpreter
&interpreter
)
1119 : CommandObjectParsed(interpreter
, "target modules search-paths insert",
1120 "Insert a new image search path substitution pair "
1121 "into the current target at the specified index.",
1122 nullptr, eCommandRequiresTarget
) {
1123 CommandArgumentEntry arg1
;
1124 CommandArgumentEntry arg2
;
1125 CommandArgumentData index_arg
;
1126 CommandArgumentData old_prefix_arg
;
1127 CommandArgumentData new_prefix_arg
;
1129 // Define the first and only variant of this arg.
1130 index_arg
.arg_type
= eArgTypeIndex
;
1131 index_arg
.arg_repetition
= eArgRepeatPlain
;
1133 // Put the one and only variant into the first arg for m_arguments:
1134 arg1
.push_back(index_arg
);
1136 // Define the first variant of this arg pair.
1137 old_prefix_arg
.arg_type
= eArgTypeOldPathPrefix
;
1138 old_prefix_arg
.arg_repetition
= eArgRepeatPairPlus
;
1140 // Define the first variant of this arg pair.
1141 new_prefix_arg
.arg_type
= eArgTypeNewPathPrefix
;
1142 new_prefix_arg
.arg_repetition
= eArgRepeatPairPlus
;
1144 // There are two required arguments that must always occur together, i.e.
1145 // an argument "pair". Because they must always occur together, they are
1146 // treated as two variants of one argument rather than two independent
1147 // arguments. Push them both into the same argument position for
1150 arg2
.push_back(old_prefix_arg
);
1151 arg2
.push_back(new_prefix_arg
);
1153 // Add arguments to m_arguments.
1154 m_arguments
.push_back(arg1
);
1155 m_arguments
.push_back(arg2
);
1158 ~CommandObjectTargetModulesSearchPathsInsert() override
= default;
1161 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1162 Target
*target
= &GetSelectedTarget();
1163 size_t argc
= command
.GetArgumentCount();
1164 // check for at least 3 arguments and an odd number of parameters
1165 if (argc
>= 3 && argc
& 1) {
1166 bool success
= false;
1168 uint32_t insert_idx
= StringConvert::ToUInt32(
1169 command
.GetArgumentAtIndex(0), UINT32_MAX
, 0, &success
);
1172 result
.AppendErrorWithFormat(
1173 "<index> parameter is not an integer: '%s'.\n",
1174 command
.GetArgumentAtIndex(0));
1175 result
.SetStatus(eReturnStatusFailed
);
1176 return result
.Succeeded();
1179 // shift off the index
1181 argc
= command
.GetArgumentCount();
1183 for (uint32_t i
= 0; i
< argc
; i
+= 2, ++insert_idx
) {
1184 const char *from
= command
.GetArgumentAtIndex(i
);
1185 const char *to
= command
.GetArgumentAtIndex(i
+ 1);
1187 if (from
[0] && to
[0]) {
1188 bool last_pair
= ((argc
- i
) == 2);
1189 target
->GetImageSearchPathList().Insert(
1190 ConstString(from
), ConstString(to
), insert_idx
, last_pair
);
1191 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
1194 result
.AppendError("<path-prefix> can't be empty\n");
1196 result
.AppendError("<new-path-prefix> can't be empty\n");
1197 result
.SetStatus(eReturnStatusFailed
);
1202 result
.AppendError("insert requires at least three arguments\n");
1203 result
.SetStatus(eReturnStatusFailed
);
1204 return result
.Succeeded();
1206 return result
.Succeeded();
1210 #pragma mark CommandObjectTargetModulesSearchPathsList
1212 class CommandObjectTargetModulesSearchPathsList
: public CommandObjectParsed
{
1214 CommandObjectTargetModulesSearchPathsList(CommandInterpreter
&interpreter
)
1215 : CommandObjectParsed(interpreter
, "target modules search-paths list",
1216 "List all current image search path substitution "
1217 "pairs in the current target.",
1218 "target modules search-paths list",
1219 eCommandRequiresTarget
) {}
1221 ~CommandObjectTargetModulesSearchPathsList() override
= default;
1224 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1225 Target
*target
= &GetSelectedTarget();
1226 if (command
.GetArgumentCount() != 0) {
1227 result
.AppendError("list takes no arguments\n");
1228 result
.SetStatus(eReturnStatusFailed
);
1229 return result
.Succeeded();
1232 target
->GetImageSearchPathList().Dump(&result
.GetOutputStream());
1233 result
.SetStatus(eReturnStatusSuccessFinishResult
);
1234 return result
.Succeeded();
1238 #pragma mark CommandObjectTargetModulesSearchPathsQuery
1240 class CommandObjectTargetModulesSearchPathsQuery
: public CommandObjectParsed
{
1242 CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter
&interpreter
)
1243 : CommandObjectParsed(
1244 interpreter
, "target modules search-paths query",
1245 "Transform a path using the first applicable image search path.",
1246 nullptr, eCommandRequiresTarget
) {
1247 CommandArgumentEntry arg
;
1248 CommandArgumentData path_arg
;
1250 // Define the first (and only) variant of this arg.
1251 path_arg
.arg_type
= eArgTypeDirectoryName
;
1252 path_arg
.arg_repetition
= eArgRepeatPlain
;
1254 // There is only one variant this argument could be; put it into the
1256 arg
.push_back(path_arg
);
1258 // Push the data for the first argument into the m_arguments vector.
1259 m_arguments
.push_back(arg
);
1262 ~CommandObjectTargetModulesSearchPathsQuery() override
= default;
1265 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1266 Target
*target
= &GetSelectedTarget();
1267 if (command
.GetArgumentCount() != 1) {
1268 result
.AppendError("query requires one argument\n");
1269 result
.SetStatus(eReturnStatusFailed
);
1270 return result
.Succeeded();
1273 ConstString
orig(command
.GetArgumentAtIndex(0));
1274 ConstString transformed
;
1275 if (target
->GetImageSearchPathList().RemapPath(orig
, transformed
))
1276 result
.GetOutputStream().Printf("%s\n", transformed
.GetCString());
1278 result
.GetOutputStream().Printf("%s\n", orig
.GetCString());
1280 result
.SetStatus(eReturnStatusSuccessFinishResult
);
1281 return result
.Succeeded();
1285 // Static Helper functions
1286 static void DumpModuleArchitecture(Stream
&strm
, Module
*module
,
1287 bool full_triple
, uint32_t width
) {
1289 StreamString arch_strm
;
1292 module
->GetArchitecture().DumpTriple(arch_strm
.AsRawOstream());
1294 arch_strm
.PutCString(module
->GetArchitecture().GetArchitectureName());
1295 std::string arch_str
= arch_strm
.GetString();
1298 strm
.Printf("%-*s", width
, arch_str
.c_str());
1300 strm
.PutCString(arch_str
);
1304 static void DumpModuleUUID(Stream
&strm
, Module
*module
) {
1305 if (module
&& module
->GetUUID().IsValid())
1306 module
->GetUUID().Dump(&strm
);
1308 strm
.PutCString(" ");
1311 static uint32_t DumpCompileUnitLineTable(CommandInterpreter
&interpreter
,
1312 Stream
&strm
, Module
*module
,
1313 const FileSpec
&file_spec
,
1314 lldb::DescriptionLevel desc_level
) {
1315 uint32_t num_matches
= 0;
1317 SymbolContextList sc_list
;
1318 num_matches
= module
->ResolveSymbolContextsForFileSpec(
1319 file_spec
, 0, false, eSymbolContextCompUnit
, sc_list
);
1321 for (uint32_t i
= 0; i
< num_matches
; ++i
) {
1323 if (sc_list
.GetContextAtIndex(i
, sc
)) {
1327 strm
<< "Line table for " << sc
.comp_unit
->GetPrimaryFile() << " in `"
1328 << module
->GetFileSpec().GetFilename() << "\n";
1329 LineTable
*line_table
= sc
.comp_unit
->GetLineTable();
1331 line_table
->GetDescription(
1332 &strm
, interpreter
.GetExecutionContext().GetTargetPtr(),
1335 strm
<< "No line table";
1342 static void DumpFullpath(Stream
&strm
, const FileSpec
*file_spec_ptr
,
1344 if (file_spec_ptr
) {
1346 std::string fullpath
= file_spec_ptr
->GetPath();
1347 strm
.Printf("%-*s", width
, fullpath
.c_str());
1350 file_spec_ptr
->Dump(strm
.AsRawOstream());
1354 // Keep the width spacing correct if things go wrong...
1356 strm
.Printf("%-*s", width
, "");
1359 static void DumpDirectory(Stream
&strm
, const FileSpec
*file_spec_ptr
,
1361 if (file_spec_ptr
) {
1363 strm
.Printf("%-*s", width
, file_spec_ptr
->GetDirectory().AsCString(""));
1365 file_spec_ptr
->GetDirectory().Dump(&strm
);
1368 // Keep the width spacing correct if things go wrong...
1370 strm
.Printf("%-*s", width
, "");
1373 static void DumpBasename(Stream
&strm
, const FileSpec
*file_spec_ptr
,
1375 if (file_spec_ptr
) {
1377 strm
.Printf("%-*s", width
, file_spec_ptr
->GetFilename().AsCString(""));
1379 file_spec_ptr
->GetFilename().Dump(&strm
);
1382 // Keep the width spacing correct if things go wrong...
1384 strm
.Printf("%-*s", width
, "");
1387 static size_t DumpModuleObjfileHeaders(Stream
&strm
, ModuleList
&module_list
) {
1388 size_t num_dumped
= 0;
1389 std::lock_guard
<std::recursive_mutex
> guard(module_list
.GetMutex());
1390 const size_t num_modules
= module_list
.GetSize();
1391 if (num_modules
> 0) {
1392 strm
.Printf("Dumping headers for %" PRIu64
" module(s).\n",
1393 static_cast<uint64_t>(num_modules
));
1395 for (size_t image_idx
= 0; image_idx
< num_modules
; ++image_idx
) {
1396 Module
*module
= module_list
.GetModulePointerAtIndexUnlocked(image_idx
);
1398 if (num_dumped
++ > 0) {
1402 ObjectFile
*objfile
= module
->GetObjectFile();
1404 objfile
->Dump(&strm
);
1406 strm
.Format("No object file for module: {0:F}\n",
1407 module
->GetFileSpec());
1416 static void DumpModuleSymtab(CommandInterpreter
&interpreter
, Stream
&strm
,
1417 Module
*module
, SortOrder sort_order
,
1418 Mangled::NamePreference name_preference
) {
1421 if (Symtab
*symtab
= module
->GetSymtab())
1422 symtab
->Dump(&strm
, interpreter
.GetExecutionContext().GetTargetPtr(),
1423 sort_order
, name_preference
);
1426 static void DumpModuleSections(CommandInterpreter
&interpreter
, Stream
&strm
,
1429 SectionList
*section_list
= module
->GetSectionList();
1431 strm
.Printf("Sections for '%s' (%s):\n",
1432 module
->GetSpecificationDescription().c_str(),
1433 module
->GetArchitecture().GetArchitectureName());
1435 section_list
->Dump(&strm
,
1436 interpreter
.GetExecutionContext().GetTargetPtr(), true,
1443 static bool DumpModuleSymbolFile(Stream
&strm
, Module
*module
) {
1445 if (SymbolFile
*symbol_file
= module
->GetSymbolFile(true)) {
1446 symbol_file
->Dump(strm
);
1453 static void DumpAddress(ExecutionContextScope
*exe_scope
,
1454 const Address
&so_addr
, bool verbose
, Stream
&strm
) {
1456 strm
.Indent(" Address: ");
1457 so_addr
.Dump(&strm
, exe_scope
, Address::DumpStyleModuleWithFileAddress
);
1458 strm
.PutCString(" (");
1459 so_addr
.Dump(&strm
, exe_scope
, Address::DumpStyleSectionNameOffset
);
1460 strm
.PutCString(")\n");
1461 strm
.Indent(" Summary: ");
1462 const uint32_t save_indent
= strm
.GetIndentLevel();
1463 strm
.SetIndentLevel(save_indent
+ 13);
1464 so_addr
.Dump(&strm
, exe_scope
, Address::DumpStyleResolvedDescription
);
1465 strm
.SetIndentLevel(save_indent
);
1466 // Print out detailed address information when verbose is enabled
1469 so_addr
.Dump(&strm
, exe_scope
, Address::DumpStyleDetailedSymbolContext
);
1474 static bool LookupAddressInModule(CommandInterpreter
&interpreter
, Stream
&strm
,
1475 Module
*module
, uint32_t resolve_mask
,
1476 lldb::addr_t raw_addr
, lldb::addr_t offset
,
1479 lldb::addr_t addr
= raw_addr
- offset
;
1482 Target
*target
= interpreter
.GetExecutionContext().GetTargetPtr();
1483 if (target
&& !target
->GetSectionLoadList().IsEmpty()) {
1484 if (!target
->GetSectionLoadList().ResolveLoadAddress(addr
, so_addr
))
1486 else if (so_addr
.GetModule().get() != module
)
1489 if (!module
->ResolveFileAddress(addr
, so_addr
))
1493 ExecutionContextScope
*exe_scope
=
1494 interpreter
.GetExecutionContext().GetBestExecutionContextScope();
1495 DumpAddress(exe_scope
, so_addr
, verbose
, strm
);
1496 // strm.IndentMore();
1497 // strm.Indent (" Address: ");
1498 // so_addr.Dump (&strm, exe_scope,
1499 // Address::DumpStyleModuleWithFileAddress);
1500 // strm.PutCString (" (");
1501 // so_addr.Dump (&strm, exe_scope,
1502 // Address::DumpStyleSectionNameOffset);
1503 // strm.PutCString (")\n");
1504 // strm.Indent (" Summary: ");
1505 // const uint32_t save_indent = strm.GetIndentLevel ();
1506 // strm.SetIndentLevel (save_indent + 13);
1507 // so_addr.Dump (&strm, exe_scope,
1508 // Address::DumpStyleResolvedDescription);
1509 // strm.SetIndentLevel (save_indent);
1510 // // Print out detailed address information when verbose is enabled
1514 // so_addr.Dump (&strm, exe_scope,
1515 // Address::DumpStyleDetailedSymbolContext);
1517 // strm.IndentLess();
1524 static uint32_t LookupSymbolInModule(CommandInterpreter
&interpreter
,
1525 Stream
&strm
, Module
*module
,
1526 const char *name
, bool name_is_regex
,
1531 Symtab
*symtab
= module
->GetSymtab();
1536 std::vector
<uint32_t> match_indexes
;
1537 ConstString
symbol_name(name
);
1538 uint32_t num_matches
= 0;
1539 if (name_is_regex
) {
1540 RegularExpression
name_regexp(symbol_name
.GetStringRef());
1541 num_matches
= symtab
->AppendSymbolIndexesMatchingRegExAndType(
1542 name_regexp
, eSymbolTypeAny
, match_indexes
);
1545 symtab
->AppendSymbolIndexesWithName(symbol_name
, match_indexes
);
1548 if (num_matches
> 0) {
1550 strm
.Printf("%u symbols match %s'%s' in ", num_matches
,
1551 name_is_regex
? "the regular expression " : "", name
);
1552 DumpFullpath(strm
, &module
->GetFileSpec(), 0);
1553 strm
.PutCString(":\n");
1555 for (uint32_t i
= 0; i
< num_matches
; ++i
) {
1556 Symbol
*symbol
= symtab
->SymbolAtIndex(match_indexes
[i
]);
1557 if (symbol
&& symbol
->ValueIsAddress()) {
1559 interpreter
.GetExecutionContext().GetBestExecutionContextScope(),
1560 symbol
->GetAddressRef(), verbose
, strm
);
1568 static void DumpSymbolContextList(ExecutionContextScope
*exe_scope
,
1569 Stream
&strm
, SymbolContextList
&sc_list
,
1573 const uint32_t num_matches
= sc_list
.GetSize();
1575 for (uint32_t i
= 0; i
< num_matches
; ++i
) {
1577 if (sc_list
.GetContextAtIndex(i
, sc
)) {
1580 sc
.GetAddressRange(eSymbolContextEverything
, 0, true, range
);
1582 DumpAddress(exe_scope
, range
.GetBaseAddress(), verbose
, strm
);
1588 static size_t LookupFunctionInModule(CommandInterpreter
&interpreter
,
1589 Stream
&strm
, Module
*module
,
1590 const char *name
, bool name_is_regex
,
1591 bool include_inlines
, bool include_symbols
,
1593 if (module
&& name
&& name
[0]) {
1594 SymbolContextList sc_list
;
1595 size_t num_matches
= 0;
1596 if (name_is_regex
) {
1597 RegularExpression
function_name_regex((llvm::StringRef(name
)));
1598 module
->FindFunctions(function_name_regex
, include_symbols
,
1599 include_inlines
, sc_list
);
1601 ConstString
function_name(name
);
1602 module
->FindFunctions(function_name
, nullptr, eFunctionNameTypeAuto
,
1603 include_symbols
, include_inlines
, sc_list
);
1605 num_matches
= sc_list
.GetSize();
1608 strm
.Printf("%" PRIu64
" match%s found in ", (uint64_t)num_matches
,
1609 num_matches
> 1 ? "es" : "");
1610 DumpFullpath(strm
, &module
->GetFileSpec(), 0);
1611 strm
.PutCString(":\n");
1612 DumpSymbolContextList(
1613 interpreter
.GetExecutionContext().GetBestExecutionContextScope(),
1614 strm
, sc_list
, verbose
);
1621 static size_t LookupTypeInModule(CommandInterpreter
&interpreter
, Stream
&strm
,
1622 Module
*module
, const char *name_cstr
,
1623 bool name_is_regex
) {
1625 if (module
&& name_cstr
&& name_cstr
[0]) {
1626 const uint32_t max_num_matches
= UINT32_MAX
;
1627 size_t num_matches
= 0;
1628 bool name_is_fully_qualified
= false;
1630 ConstString
name(name_cstr
);
1631 llvm::DenseSet
<lldb_private::SymbolFile
*> searched_symbol_files
;
1632 module
->FindTypes(name
, name_is_fully_qualified
, max_num_matches
,
1633 searched_symbol_files
, type_list
);
1635 if (type_list
.Empty())
1639 strm
.Printf("%" PRIu64
" match%s found in ", (uint64_t)num_matches
,
1640 num_matches
> 1 ? "es" : "");
1641 DumpFullpath(strm
, &module
->GetFileSpec(), 0);
1642 strm
.PutCString(":\n");
1643 for (TypeSP type_sp
: type_list
.Types()) {
1646 // Resolve the clang type so that any forward references to types
1647 // that haven't yet been parsed will get parsed.
1648 type_sp
->GetFullCompilerType();
1649 type_sp
->GetDescription(&strm
, eDescriptionLevelFull
, true);
1650 // Print all typedef chains
1651 TypeSP
typedef_type_sp(type_sp
);
1652 TypeSP
typedefed_type_sp(typedef_type_sp
->GetTypedefType());
1653 while (typedefed_type_sp
) {
1655 strm
.Printf(" typedef '%s': ",
1656 typedef_type_sp
->GetName().GetCString());
1657 typedefed_type_sp
->GetFullCompilerType();
1658 typedefed_type_sp
->GetDescription(&strm
, eDescriptionLevelFull
, true);
1659 typedef_type_sp
= typedefed_type_sp
;
1660 typedefed_type_sp
= typedef_type_sp
->GetTypedefType();
1665 return type_list
.GetSize();
1668 static size_t LookupTypeHere(CommandInterpreter
&interpreter
, Stream
&strm
,
1669 Module
&module
, const char *name_cstr
,
1670 bool name_is_regex
) {
1672 const uint32_t max_num_matches
= UINT32_MAX
;
1673 bool name_is_fully_qualified
= false;
1675 ConstString
name(name_cstr
);
1676 llvm::DenseSet
<SymbolFile
*> searched_symbol_files
;
1677 module
.FindTypes(name
, name_is_fully_qualified
, max_num_matches
,
1678 searched_symbol_files
, type_list
);
1680 if (type_list
.Empty())
1684 strm
.PutCString("Best match found in ");
1685 DumpFullpath(strm
, &module
.GetFileSpec(), 0);
1686 strm
.PutCString(":\n");
1688 TypeSP
type_sp(type_list
.GetTypeAtIndex(0));
1690 // Resolve the clang type so that any forward references to types that
1691 // haven't yet been parsed will get parsed.
1692 type_sp
->GetFullCompilerType();
1693 type_sp
->GetDescription(&strm
, eDescriptionLevelFull
, true);
1694 // Print all typedef chains
1695 TypeSP
typedef_type_sp(type_sp
);
1696 TypeSP
typedefed_type_sp(typedef_type_sp
->GetTypedefType());
1697 while (typedefed_type_sp
) {
1699 strm
.Printf(" typedef '%s': ",
1700 typedef_type_sp
->GetName().GetCString());
1701 typedefed_type_sp
->GetFullCompilerType();
1702 typedefed_type_sp
->GetDescription(&strm
, eDescriptionLevelFull
, true);
1703 typedef_type_sp
= typedefed_type_sp
;
1704 typedefed_type_sp
= typedef_type_sp
->GetTypedefType();
1708 return type_list
.GetSize();
1711 static uint32_t LookupFileAndLineInModule(CommandInterpreter
&interpreter
,
1712 Stream
&strm
, Module
*module
,
1713 const FileSpec
&file_spec
,
1714 uint32_t line
, bool check_inlines
,
1716 if (module
&& file_spec
) {
1717 SymbolContextList sc_list
;
1718 const uint32_t num_matches
= module
->ResolveSymbolContextsForFileSpec(
1719 file_spec
, line
, check_inlines
, eSymbolContextEverything
, sc_list
);
1720 if (num_matches
> 0) {
1722 strm
.Printf("%u match%s found in ", num_matches
,
1723 num_matches
> 1 ? "es" : "");
1726 strm
.Printf(":%u", line
);
1728 DumpFullpath(strm
, &module
->GetFileSpec(), 0);
1729 strm
.PutCString(":\n");
1730 DumpSymbolContextList(
1731 interpreter
.GetExecutionContext().GetBestExecutionContextScope(),
1732 strm
, sc_list
, verbose
);
1739 static size_t FindModulesByName(Target
*target
, const char *module_name
,
1740 ModuleList
&module_list
,
1741 bool check_global_list
) {
1742 FileSpec
module_file_spec(module_name
);
1743 ModuleSpec
module_spec(module_file_spec
);
1745 const size_t initial_size
= module_list
.GetSize();
1747 if (check_global_list
) {
1748 // Check the global list
1749 std::lock_guard
<std::recursive_mutex
> guard(
1750 Module::GetAllocationModuleCollectionMutex());
1751 const size_t num_modules
= Module::GetNumberAllocatedModules();
1753 for (size_t image_idx
= 0; image_idx
< num_modules
; ++image_idx
) {
1754 Module
*module
= Module::GetAllocatedModuleAtIndex(image_idx
);
1757 if (module
->MatchesModuleSpec(module_spec
)) {
1758 module_sp
= module
->shared_from_this();
1759 module_list
.AppendIfNeeded(module_sp
);
1765 target
->GetImages().FindModules(module_spec
, module_list
);
1766 const size_t num_matches
= module_list
.GetSize();
1768 // Not found in our module list for our target, check the main shared
1769 // module list in case it is a extra file used somewhere else
1770 if (num_matches
== 0) {
1771 module_spec
.GetArchitecture() = target
->GetArchitecture();
1772 ModuleList::FindSharedModules(module_spec
, module_list
);
1775 ModuleList::FindSharedModules(module_spec
, module_list
);
1779 return module_list
.GetSize() - initial_size
;
1782 #pragma mark CommandObjectTargetModulesModuleAutoComplete
1784 // A base command object class that can auto complete with module file
1787 class CommandObjectTargetModulesModuleAutoComplete
1788 : public CommandObjectParsed
{
1790 CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter
&interpreter
,
1795 : CommandObjectParsed(interpreter
, name
, help
, syntax
, flags
) {
1796 CommandArgumentEntry arg
;
1797 CommandArgumentData file_arg
;
1799 // Define the first (and only) variant of this arg.
1800 file_arg
.arg_type
= eArgTypeFilename
;
1801 file_arg
.arg_repetition
= eArgRepeatStar
;
1803 // There is only one variant this argument could be; put it into the
1805 arg
.push_back(file_arg
);
1807 // Push the data for the first argument into the m_arguments vector.
1808 m_arguments
.push_back(arg
);
1811 ~CommandObjectTargetModulesModuleAutoComplete() override
= default;
1814 HandleArgumentCompletion(CompletionRequest
&request
,
1815 OptionElementVector
&opt_element_vector
) override
{
1816 CommandCompletions::InvokeCommonCompletionCallbacks(
1817 GetCommandInterpreter(), CommandCompletions::eModuleCompletion
, request
,
1822 #pragma mark CommandObjectTargetModulesSourceFileAutoComplete
1824 // A base command object class that can auto complete with module source
1827 class CommandObjectTargetModulesSourceFileAutoComplete
1828 : public CommandObjectParsed
{
1830 CommandObjectTargetModulesSourceFileAutoComplete(
1831 CommandInterpreter
&interpreter
, const char *name
, const char *help
,
1832 const char *syntax
, uint32_t flags
)
1833 : CommandObjectParsed(interpreter
, name
, help
, syntax
, flags
) {
1834 CommandArgumentEntry arg
;
1835 CommandArgumentData source_file_arg
;
1837 // Define the first (and only) variant of this arg.
1838 source_file_arg
.arg_type
= eArgTypeSourceFile
;
1839 source_file_arg
.arg_repetition
= eArgRepeatPlus
;
1841 // There is only one variant this argument could be; put it into the
1843 arg
.push_back(source_file_arg
);
1845 // Push the data for the first argument into the m_arguments vector.
1846 m_arguments
.push_back(arg
);
1849 ~CommandObjectTargetModulesSourceFileAutoComplete() override
= default;
1852 HandleArgumentCompletion(CompletionRequest
&request
,
1853 OptionElementVector
&opt_element_vector
) override
{
1854 CommandCompletions::InvokeCommonCompletionCallbacks(
1855 GetCommandInterpreter(), CommandCompletions::eSourceFileCompletion
,
1860 #pragma mark CommandObjectTargetModulesDumpObjfile
1862 class CommandObjectTargetModulesDumpObjfile
1863 : public CommandObjectTargetModulesModuleAutoComplete
{
1865 CommandObjectTargetModulesDumpObjfile(CommandInterpreter
&interpreter
)
1866 : CommandObjectTargetModulesModuleAutoComplete(
1867 interpreter
, "target modules dump objfile",
1868 "Dump the object file headers from one or more target modules.",
1869 nullptr, eCommandRequiresTarget
) {}
1871 ~CommandObjectTargetModulesDumpObjfile() override
= default;
1874 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
1875 Target
*target
= &GetSelectedTarget();
1877 uint32_t addr_byte_size
= target
->GetArchitecture().GetAddressByteSize();
1878 result
.GetOutputStream().SetAddressByteSize(addr_byte_size
);
1879 result
.GetErrorStream().SetAddressByteSize(addr_byte_size
);
1881 size_t num_dumped
= 0;
1882 if (command
.GetArgumentCount() == 0) {
1883 // Dump all headers for all modules images
1884 num_dumped
= DumpModuleObjfileHeaders(result
.GetOutputStream(),
1885 target
->GetImages());
1886 if (num_dumped
== 0) {
1887 result
.AppendError("the target has no associated executable images");
1888 result
.SetStatus(eReturnStatusFailed
);
1891 // Find the modules that match the basename or full path.
1892 ModuleList module_list
;
1893 const char *arg_cstr
;
1894 for (int arg_idx
= 0;
1895 (arg_cstr
= command
.GetArgumentAtIndex(arg_idx
)) != nullptr;
1897 size_t num_matched
=
1898 FindModulesByName(target
, arg_cstr
, module_list
, true);
1899 if (num_matched
== 0) {
1900 result
.AppendWarningWithFormat(
1901 "Unable to find an image that matches '%s'.\n", arg_cstr
);
1904 // Dump all the modules we found.
1906 DumpModuleObjfileHeaders(result
.GetOutputStream(), module_list
);
1909 if (num_dumped
> 0) {
1910 result
.SetStatus(eReturnStatusSuccessFinishResult
);
1912 result
.AppendError("no matching executable images found");
1913 result
.SetStatus(eReturnStatusFailed
);
1915 return result
.Succeeded();
1919 #pragma mark CommandObjectTargetModulesDumpSymtab
1921 static constexpr OptionEnumValueElement g_sort_option_enumeration
[] = {
1925 "No sorting, use the original symbol table order.",
1928 eSortOrderByAddress
,
1930 "Sort output by symbol address.",
1935 "Sort output by symbol name.",
1939 #define LLDB_OPTIONS_target_modules_dump_symtab
1940 #include "CommandOptions.inc"
1942 class CommandObjectTargetModulesDumpSymtab
1943 : public CommandObjectTargetModulesModuleAutoComplete
{
1945 CommandObjectTargetModulesDumpSymtab(CommandInterpreter
&interpreter
)
1946 : CommandObjectTargetModulesModuleAutoComplete(
1947 interpreter
, "target modules dump symtab",
1948 "Dump the symbol table from one or more target modules.", nullptr,
1949 eCommandRequiresTarget
),
1952 ~CommandObjectTargetModulesDumpSymtab() override
= default;
1954 Options
*GetOptions() override
{ return &m_options
; }
1956 class CommandOptions
: public Options
{
1958 CommandOptions() : Options(), m_sort_order(eSortOrderNone
) {}
1960 ~CommandOptions() override
= default;
1962 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
1963 ExecutionContext
*execution_context
) override
{
1965 const int short_option
= m_getopt_table
[option_idx
].val
;
1967 switch (short_option
) {
1969 m_prefer_mangled
.SetCurrentValue(true);
1970 m_prefer_mangled
.SetOptionWasSet();
1974 m_sort_order
= (SortOrder
)OptionArgParser::ToOptionEnum(
1975 option_arg
, GetDefinitions()[option_idx
].enum_values
,
1976 eSortOrderNone
, error
);
1980 llvm_unreachable("Unimplemented option");
1985 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
1986 m_sort_order
= eSortOrderNone
;
1987 m_prefer_mangled
.Clear();
1990 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
1991 return llvm::makeArrayRef(g_target_modules_dump_symtab_options
);
1994 SortOrder m_sort_order
;
1995 OptionValueBoolean m_prefer_mangled
= {false, false};
1999 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
2000 Target
*target
= &GetSelectedTarget();
2001 uint32_t num_dumped
= 0;
2002 Mangled::NamePreference name_preference
=
2003 (m_options
.m_prefer_mangled
? Mangled::ePreferMangled
2004 : Mangled::ePreferDemangled
);
2006 uint32_t addr_byte_size
= target
->GetArchitecture().GetAddressByteSize();
2007 result
.GetOutputStream().SetAddressByteSize(addr_byte_size
);
2008 result
.GetErrorStream().SetAddressByteSize(addr_byte_size
);
2010 if (command
.GetArgumentCount() == 0) {
2011 // Dump all sections for all modules images
2012 std::lock_guard
<std::recursive_mutex
> guard(
2013 target
->GetImages().GetMutex());
2014 const size_t num_modules
= target
->GetImages().GetSize();
2015 if (num_modules
> 0) {
2016 result
.GetOutputStream().Printf("Dumping symbol table for %" PRIu64
2018 (uint64_t)num_modules
);
2019 for (size_t image_idx
= 0; image_idx
< num_modules
; ++image_idx
) {
2020 if (num_dumped
> 0) {
2021 result
.GetOutputStream().EOL();
2022 result
.GetOutputStream().EOL();
2024 if (m_interpreter
.WasInterrupted())
2028 m_interpreter
, result
.GetOutputStream(),
2029 target
->GetImages().GetModulePointerAtIndexUnlocked(image_idx
),
2030 m_options
.m_sort_order
, name_preference
);
2033 result
.AppendError("the target has no associated executable images");
2034 result
.SetStatus(eReturnStatusFailed
);
2038 // Dump specified images (by basename or fullpath)
2039 const char *arg_cstr
;
2040 for (int arg_idx
= 0;
2041 (arg_cstr
= command
.GetArgumentAtIndex(arg_idx
)) != nullptr;
2043 ModuleList module_list
;
2044 const size_t num_matches
=
2045 FindModulesByName(target
, arg_cstr
, module_list
, true);
2046 if (num_matches
> 0) {
2047 for (size_t i
= 0; i
< num_matches
; ++i
) {
2048 Module
*module
= module_list
.GetModulePointerAtIndex(i
);
2050 if (num_dumped
> 0) {
2051 result
.GetOutputStream().EOL();
2052 result
.GetOutputStream().EOL();
2054 if (m_interpreter
.WasInterrupted())
2057 DumpModuleSymtab(m_interpreter
, result
.GetOutputStream(), module
,
2058 m_options
.m_sort_order
, name_preference
);
2062 result
.AppendWarningWithFormat(
2063 "Unable to find an image that matches '%s'.\n", arg_cstr
);
2068 result
.SetStatus(eReturnStatusSuccessFinishResult
);
2070 result
.AppendError("no matching executable images found");
2071 result
.SetStatus(eReturnStatusFailed
);
2073 return result
.Succeeded();
2076 CommandOptions m_options
;
2079 #pragma mark CommandObjectTargetModulesDumpSections
2081 // Image section dumping command
2083 class CommandObjectTargetModulesDumpSections
2084 : public CommandObjectTargetModulesModuleAutoComplete
{
2086 CommandObjectTargetModulesDumpSections(CommandInterpreter
&interpreter
)
2087 : CommandObjectTargetModulesModuleAutoComplete(
2088 interpreter
, "target modules dump sections",
2089 "Dump the sections from one or more target modules.",
2090 //"target modules dump sections [<file1> ...]")
2091 nullptr, eCommandRequiresTarget
) {}
2093 ~CommandObjectTargetModulesDumpSections() override
= default;
2096 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
2097 Target
*target
= &GetSelectedTarget();
2098 uint32_t num_dumped
= 0;
2100 uint32_t addr_byte_size
= target
->GetArchitecture().GetAddressByteSize();
2101 result
.GetOutputStream().SetAddressByteSize(addr_byte_size
);
2102 result
.GetErrorStream().SetAddressByteSize(addr_byte_size
);
2104 if (command
.GetArgumentCount() == 0) {
2105 // Dump all sections for all modules images
2106 const size_t num_modules
= target
->GetImages().GetSize();
2107 if (num_modules
> 0) {
2108 result
.GetOutputStream().Printf("Dumping sections for %" PRIu64
2110 (uint64_t)num_modules
);
2111 for (size_t image_idx
= 0; image_idx
< num_modules
; ++image_idx
) {
2112 if (m_interpreter
.WasInterrupted())
2116 m_interpreter
, result
.GetOutputStream(),
2117 target
->GetImages().GetModulePointerAtIndex(image_idx
));
2120 result
.AppendError("the target has no associated executable images");
2121 result
.SetStatus(eReturnStatusFailed
);
2125 // Dump specified images (by basename or fullpath)
2126 const char *arg_cstr
;
2127 for (int arg_idx
= 0;
2128 (arg_cstr
= command
.GetArgumentAtIndex(arg_idx
)) != nullptr;
2130 ModuleList module_list
;
2131 const size_t num_matches
=
2132 FindModulesByName(target
, arg_cstr
, module_list
, true);
2133 if (num_matches
> 0) {
2134 for (size_t i
= 0; i
< num_matches
; ++i
) {
2135 if (m_interpreter
.WasInterrupted())
2137 Module
*module
= module_list
.GetModulePointerAtIndex(i
);
2140 DumpModuleSections(m_interpreter
, result
.GetOutputStream(),
2145 // Check the global list
2146 std::lock_guard
<std::recursive_mutex
> guard(
2147 Module::GetAllocationModuleCollectionMutex());
2149 result
.AppendWarningWithFormat(
2150 "Unable to find an image that matches '%s'.\n", arg_cstr
);
2156 result
.SetStatus(eReturnStatusSuccessFinishResult
);
2158 result
.AppendError("no matching executable images found");
2159 result
.SetStatus(eReturnStatusFailed
);
2161 return result
.Succeeded();
2165 #pragma mark CommandObjectTargetModulesDumpSections
2167 // Clang AST dumping command
2169 class CommandObjectTargetModulesDumpClangAST
2170 : public CommandObjectTargetModulesModuleAutoComplete
{
2172 CommandObjectTargetModulesDumpClangAST(CommandInterpreter
&interpreter
)
2173 : CommandObjectTargetModulesModuleAutoComplete(
2174 interpreter
, "target modules dump ast",
2175 "Dump the clang ast for a given module's symbol file.",
2176 //"target modules dump ast [<file1> ...]")
2177 nullptr, eCommandRequiresTarget
) {}
2179 ~CommandObjectTargetModulesDumpClangAST() override
= default;
2182 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
2183 Target
*target
= &GetSelectedTarget();
2185 const size_t num_modules
= target
->GetImages().GetSize();
2186 if (num_modules
== 0) {
2187 result
.AppendError("the target has no associated executable images");
2188 result
.SetStatus(eReturnStatusFailed
);
2192 if (command
.GetArgumentCount() == 0) {
2193 // Dump all ASTs for all modules images
2194 result
.GetOutputStream().Printf("Dumping clang ast for %" PRIu64
2196 (uint64_t)num_modules
);
2197 for (size_t image_idx
= 0; image_idx
< num_modules
; ++image_idx
) {
2198 if (m_interpreter
.WasInterrupted())
2200 Module
*m
= target
->GetImages().GetModulePointerAtIndex(image_idx
);
2201 if (SymbolFile
*sf
= m
->GetSymbolFile())
2202 sf
->DumpClangAST(result
.GetOutputStream());
2204 result
.SetStatus(eReturnStatusSuccessFinishResult
);
2208 // Dump specified ASTs (by basename or fullpath)
2209 for (const Args::ArgEntry
&arg
: command
.entries()) {
2210 ModuleList module_list
;
2211 const size_t num_matches
=
2212 FindModulesByName(target
, arg
.c_str(), module_list
, true);
2213 if (num_matches
== 0) {
2214 // Check the global list
2215 std::lock_guard
<std::recursive_mutex
> guard(
2216 Module::GetAllocationModuleCollectionMutex());
2218 result
.AppendWarningWithFormat(
2219 "Unable to find an image that matches '%s'.\n", arg
.c_str());
2223 for (size_t i
= 0; i
< num_matches
; ++i
) {
2224 if (m_interpreter
.WasInterrupted())
2226 Module
*m
= module_list
.GetModulePointerAtIndex(i
);
2227 if (SymbolFile
*sf
= m
->GetSymbolFile())
2228 sf
->DumpClangAST(result
.GetOutputStream());
2231 result
.SetStatus(eReturnStatusSuccessFinishResult
);
2236 #pragma mark CommandObjectTargetModulesDumpSymfile
2238 // Image debug symbol dumping command
2240 class CommandObjectTargetModulesDumpSymfile
2241 : public CommandObjectTargetModulesModuleAutoComplete
{
2243 CommandObjectTargetModulesDumpSymfile(CommandInterpreter
&interpreter
)
2244 : CommandObjectTargetModulesModuleAutoComplete(
2245 interpreter
, "target modules dump symfile",
2246 "Dump the debug symbol file for one or more target modules.",
2247 //"target modules dump symfile [<file1> ...]")
2248 nullptr, eCommandRequiresTarget
) {}
2250 ~CommandObjectTargetModulesDumpSymfile() override
= default;
2253 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
2254 Target
*target
= &GetSelectedTarget();
2255 uint32_t num_dumped
= 0;
2257 uint32_t addr_byte_size
= target
->GetArchitecture().GetAddressByteSize();
2258 result
.GetOutputStream().SetAddressByteSize(addr_byte_size
);
2259 result
.GetErrorStream().SetAddressByteSize(addr_byte_size
);
2261 if (command
.GetArgumentCount() == 0) {
2262 // Dump all sections for all modules images
2263 const ModuleList
&target_modules
= target
->GetImages();
2264 std::lock_guard
<std::recursive_mutex
> guard(target_modules
.GetMutex());
2265 const size_t num_modules
= target_modules
.GetSize();
2266 if (num_modules
> 0) {
2267 result
.GetOutputStream().Printf("Dumping debug symbols for %" PRIu64
2269 (uint64_t)num_modules
);
2270 for (uint32_t image_idx
= 0; image_idx
< num_modules
; ++image_idx
) {
2271 if (m_interpreter
.WasInterrupted())
2273 if (DumpModuleSymbolFile(
2274 result
.GetOutputStream(),
2275 target_modules
.GetModulePointerAtIndexUnlocked(image_idx
)))
2279 result
.AppendError("the target has no associated executable images");
2280 result
.SetStatus(eReturnStatusFailed
);
2284 // Dump specified images (by basename or fullpath)
2285 const char *arg_cstr
;
2286 for (int arg_idx
= 0;
2287 (arg_cstr
= command
.GetArgumentAtIndex(arg_idx
)) != nullptr;
2289 ModuleList module_list
;
2290 const size_t num_matches
=
2291 FindModulesByName(target
, arg_cstr
, module_list
, true);
2292 if (num_matches
> 0) {
2293 for (size_t i
= 0; i
< num_matches
; ++i
) {
2294 if (m_interpreter
.WasInterrupted())
2296 Module
*module
= module_list
.GetModulePointerAtIndex(i
);
2298 if (DumpModuleSymbolFile(result
.GetOutputStream(), module
))
2303 result
.AppendWarningWithFormat(
2304 "Unable to find an image that matches '%s'.\n", arg_cstr
);
2309 result
.SetStatus(eReturnStatusSuccessFinishResult
);
2311 result
.AppendError("no matching executable images found");
2312 result
.SetStatus(eReturnStatusFailed
);
2314 return result
.Succeeded();
2318 #pragma mark CommandObjectTargetModulesDumpLineTable
2319 #define LLDB_OPTIONS_target_modules_dump
2320 #include "CommandOptions.inc"
2322 // Image debug line table dumping command
2324 class CommandObjectTargetModulesDumpLineTable
2325 : public CommandObjectTargetModulesSourceFileAutoComplete
{
2327 CommandObjectTargetModulesDumpLineTable(CommandInterpreter
&interpreter
)
2328 : CommandObjectTargetModulesSourceFileAutoComplete(
2329 interpreter
, "target modules dump line-table",
2330 "Dump the line table for one or more compilation units.", nullptr,
2331 eCommandRequiresTarget
) {}
2333 ~CommandObjectTargetModulesDumpLineTable() override
= default;
2335 Options
*GetOptions() override
{ return &m_options
; }
2338 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
2339 Target
*target
= m_exe_ctx
.GetTargetPtr();
2340 uint32_t total_num_dumped
= 0;
2342 uint32_t addr_byte_size
= target
->GetArchitecture().GetAddressByteSize();
2343 result
.GetOutputStream().SetAddressByteSize(addr_byte_size
);
2344 result
.GetErrorStream().SetAddressByteSize(addr_byte_size
);
2346 if (command
.GetArgumentCount() == 0) {
2347 result
.AppendError("file option must be specified.");
2348 result
.SetStatus(eReturnStatusFailed
);
2349 return result
.Succeeded();
2351 // Dump specified images (by basename or fullpath)
2352 const char *arg_cstr
;
2353 for (int arg_idx
= 0;
2354 (arg_cstr
= command
.GetArgumentAtIndex(arg_idx
)) != nullptr;
2356 FileSpec
file_spec(arg_cstr
);
2358 const ModuleList
&target_modules
= target
->GetImages();
2359 std::lock_guard
<std::recursive_mutex
> guard(target_modules
.GetMutex());
2360 const size_t num_modules
= target_modules
.GetSize();
2361 if (num_modules
> 0) {
2362 uint32_t num_dumped
= 0;
2363 for (uint32_t i
= 0; i
< num_modules
; ++i
) {
2364 if (m_interpreter
.WasInterrupted())
2366 if (DumpCompileUnitLineTable(
2367 m_interpreter
, result
.GetOutputStream(),
2368 target_modules
.GetModulePointerAtIndexUnlocked(i
),
2370 m_options
.m_verbose
? eDescriptionLevelFull
2371 : eDescriptionLevelBrief
))
2374 if (num_dumped
== 0)
2375 result
.AppendWarningWithFormat(
2376 "No source filenames matched '%s'.\n", arg_cstr
);
2378 total_num_dumped
+= num_dumped
;
2383 if (total_num_dumped
> 0)
2384 result
.SetStatus(eReturnStatusSuccessFinishResult
);
2386 result
.AppendError("no source filenames matched any command arguments");
2387 result
.SetStatus(eReturnStatusFailed
);
2389 return result
.Succeeded();
2392 class CommandOptions
: public Options
{
2394 CommandOptions() : Options() { OptionParsingStarting(nullptr); }
2396 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
2397 ExecutionContext
*execution_context
) override
{
2398 assert(option_idx
== 0 && "We only have one option.");
2404 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
2408 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
2409 return llvm::makeArrayRef(g_target_modules_dump_options
);
2415 CommandOptions m_options
;
2418 #pragma mark CommandObjectTargetModulesDump
2420 // Dump multi-word command for target modules
2422 class CommandObjectTargetModulesDump
: public CommandObjectMultiword
{
2424 // Constructors and Destructors
2425 CommandObjectTargetModulesDump(CommandInterpreter
&interpreter
)
2426 : CommandObjectMultiword(
2427 interpreter
, "target modules dump",
2428 "Commands for dumping information about one or "
2429 "more target modules.",
2430 "target modules dump "
2431 "[headers|symtab|sections|ast|symfile|line-table] "
2432 "[<file1> <file2> ...]") {
2433 LoadSubCommand("objfile",
2435 new CommandObjectTargetModulesDumpObjfile(interpreter
)));
2438 CommandObjectSP(new CommandObjectTargetModulesDumpSymtab(interpreter
)));
2439 LoadSubCommand("sections",
2440 CommandObjectSP(new CommandObjectTargetModulesDumpSections(
2442 LoadSubCommand("symfile",
2444 new CommandObjectTargetModulesDumpSymfile(interpreter
)));
2446 "ast", CommandObjectSP(
2447 new CommandObjectTargetModulesDumpClangAST(interpreter
)));
2448 LoadSubCommand("line-table",
2449 CommandObjectSP(new CommandObjectTargetModulesDumpLineTable(
2453 ~CommandObjectTargetModulesDump() override
= default;
2456 class CommandObjectTargetModulesAdd
: public CommandObjectParsed
{
2458 CommandObjectTargetModulesAdd(CommandInterpreter
&interpreter
)
2459 : CommandObjectParsed(interpreter
, "target modules add",
2460 "Add a new module to the current target's modules.",
2461 "target modules add [<module>]",
2462 eCommandRequiresTarget
),
2463 m_option_group(), m_symbol_file(LLDB_OPT_SET_1
, false, "symfile", 's',
2464 0, eArgTypeFilename
,
2465 "Fullpath to a stand alone debug "
2466 "symbols file for when debug symbols "
2467 "are not in the executable.") {
2468 m_option_group
.Append(&m_uuid_option_group
, LLDB_OPT_SET_ALL
,
2470 m_option_group
.Append(&m_symbol_file
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
2471 m_option_group
.Finalize();
2474 ~CommandObjectTargetModulesAdd() override
= default;
2476 Options
*GetOptions() override
{ return &m_option_group
; }
2479 HandleArgumentCompletion(CompletionRequest
&request
,
2480 OptionElementVector
&opt_element_vector
) override
{
2481 CommandCompletions::InvokeCommonCompletionCallbacks(
2482 GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion
,
2487 OptionGroupOptions m_option_group
;
2488 OptionGroupUUID m_uuid_option_group
;
2489 OptionGroupFile m_symbol_file
;
2491 bool DoExecute(Args
&args
, CommandReturnObject
&result
) override
{
2492 Target
*target
= &GetSelectedTarget();
2495 const size_t argc
= args
.GetArgumentCount();
2497 if (m_uuid_option_group
.GetOptionValue().OptionWasSet()) {
2498 // We are given a UUID only, go locate the file
2499 ModuleSpec module_spec
;
2500 module_spec
.GetUUID() =
2501 m_uuid_option_group
.GetOptionValue().GetCurrentValue();
2502 if (m_symbol_file
.GetOptionValue().OptionWasSet())
2503 module_spec
.GetSymbolFileSpec() =
2504 m_symbol_file
.GetOptionValue().GetCurrentValue();
2505 if (Symbols::DownloadObjectAndSymbolFile(module_spec
)) {
2507 target
->GetOrCreateModule(module_spec
, true /* notify */));
2509 result
.SetStatus(eReturnStatusSuccessFinishResult
);
2513 module_spec
.GetUUID().Dump(&strm
);
2514 if (module_spec
.GetFileSpec()) {
2515 if (module_spec
.GetSymbolFileSpec()) {
2516 result
.AppendErrorWithFormat(
2517 "Unable to create the executable or symbol file with "
2518 "UUID %s with path %s and symbol file %s",
2519 strm
.GetData(), module_spec
.GetFileSpec().GetPath().c_str(),
2520 module_spec
.GetSymbolFileSpec().GetPath().c_str());
2522 result
.AppendErrorWithFormat(
2523 "Unable to create the executable or symbol file with "
2524 "UUID %s with path %s",
2526 module_spec
.GetFileSpec().GetPath().c_str());
2529 result
.AppendErrorWithFormat("Unable to create the executable "
2530 "or symbol file with UUID %s",
2533 result
.SetStatus(eReturnStatusFailed
);
2538 module_spec
.GetUUID().Dump(&strm
);
2539 result
.AppendErrorWithFormat(
2540 "Unable to locate the executable or symbol file with UUID %s",
2542 result
.SetStatus(eReturnStatusFailed
);
2547 "one or more executable image paths must be specified");
2548 result
.SetStatus(eReturnStatusFailed
);
2552 for (auto &entry
: args
.entries()) {
2553 if (entry
.ref().empty())
2556 FileSpec
file_spec(entry
.ref());
2557 if (FileSystem::Instance().Exists(file_spec
)) {
2558 ModuleSpec
module_spec(file_spec
);
2559 if (m_uuid_option_group
.GetOptionValue().OptionWasSet())
2560 module_spec
.GetUUID() =
2561 m_uuid_option_group
.GetOptionValue().GetCurrentValue();
2562 if (m_symbol_file
.GetOptionValue().OptionWasSet())
2563 module_spec
.GetSymbolFileSpec() =
2564 m_symbol_file
.GetOptionValue().GetCurrentValue();
2565 if (!module_spec
.GetArchitecture().IsValid())
2566 module_spec
.GetArchitecture() = target
->GetArchitecture();
2568 ModuleSP
module_sp(target
->GetOrCreateModule(
2569 module_spec
, true /* notify */, &error
));
2571 const char *error_cstr
= error
.AsCString();
2573 result
.AppendError(error_cstr
);
2575 result
.AppendErrorWithFormat("unsupported module: %s",
2577 result
.SetStatus(eReturnStatusFailed
);
2582 result
.SetStatus(eReturnStatusSuccessFinishResult
);
2584 std::string resolved_path
= file_spec
.GetPath();
2585 result
.SetStatus(eReturnStatusFailed
);
2586 if (resolved_path
!= entry
.ref()) {
2587 result
.AppendErrorWithFormat(
2588 "invalid module path '%s' with resolved path '%s'\n",
2589 entry
.ref().str().c_str(), resolved_path
.c_str());
2592 result
.AppendErrorWithFormat("invalid module path '%s'\n",
2600 ProcessSP process
= target
->GetProcessSP();
2605 return result
.Succeeded();
2609 class CommandObjectTargetModulesLoad
2610 : public CommandObjectTargetModulesModuleAutoComplete
{
2612 CommandObjectTargetModulesLoad(CommandInterpreter
&interpreter
)
2613 : CommandObjectTargetModulesModuleAutoComplete(
2614 interpreter
, "target modules load",
2615 "Set the load addresses for one or more sections in a target "
2617 "target modules load [--file <module> --uuid <uuid>] <sect-name> "
2618 "<address> [<sect-name> <address> ....]",
2619 eCommandRequiresTarget
),
2621 m_file_option(LLDB_OPT_SET_1
, false, "file", 'f', 0, eArgTypeName
,
2622 "Fullpath or basename for module to load.", ""),
2623 m_load_option(LLDB_OPT_SET_1
, false, "load", 'l',
2624 "Write file contents to the memory.", false, true),
2625 m_pc_option(LLDB_OPT_SET_1
, false, "set-pc-to-entry", 'p',
2626 "Set PC to the entry point."
2627 " Only applicable with '--load' option.",
2629 m_slide_option(LLDB_OPT_SET_1
, false, "slide", 's', 0, eArgTypeOffset
,
2630 "Set the load address for all sections to be the "
2631 "virtual address in the file plus the offset.",
2633 m_option_group
.Append(&m_uuid_option_group
, LLDB_OPT_SET_ALL
,
2635 m_option_group
.Append(&m_file_option
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
2636 m_option_group
.Append(&m_load_option
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
2637 m_option_group
.Append(&m_pc_option
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
2638 m_option_group
.Append(&m_slide_option
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
2639 m_option_group
.Finalize();
2642 ~CommandObjectTargetModulesLoad() override
= default;
2644 Options
*GetOptions() override
{ return &m_option_group
; }
2647 bool DoExecute(Args
&args
, CommandReturnObject
&result
) override
{
2648 Target
*target
= &GetSelectedTarget();
2649 const bool load
= m_load_option
.GetOptionValue().GetCurrentValue();
2650 const bool set_pc
= m_pc_option
.GetOptionValue().GetCurrentValue();
2652 const size_t argc
= args
.GetArgumentCount();
2653 ModuleSpec module_spec
;
2654 bool search_using_module_spec
= false;
2656 // Allow "load" option to work without --file or --uuid option.
2658 if (!m_file_option
.GetOptionValue().OptionWasSet() &&
2659 !m_uuid_option_group
.GetOptionValue().OptionWasSet()) {
2660 ModuleList
&module_list
= target
->GetImages();
2661 if (module_list
.GetSize() == 1) {
2662 search_using_module_spec
= true;
2663 module_spec
.GetFileSpec() =
2664 module_list
.GetModuleAtIndex(0)->GetFileSpec();
2669 if (m_file_option
.GetOptionValue().OptionWasSet()) {
2670 search_using_module_spec
= true;
2671 const char *arg_cstr
= m_file_option
.GetOptionValue().GetCurrentValue();
2672 const bool use_global_module_list
= true;
2673 ModuleList module_list
;
2674 const size_t num_matches
= FindModulesByName(
2675 target
, arg_cstr
, module_list
, use_global_module_list
);
2676 if (num_matches
== 1) {
2677 module_spec
.GetFileSpec() =
2678 module_list
.GetModuleAtIndex(0)->GetFileSpec();
2679 } else if (num_matches
> 1) {
2680 search_using_module_spec
= false;
2681 result
.AppendErrorWithFormat(
2682 "more than 1 module matched by name '%s'\n", arg_cstr
);
2683 result
.SetStatus(eReturnStatusFailed
);
2685 search_using_module_spec
= false;
2686 result
.AppendErrorWithFormat("no object file for module '%s'\n",
2688 result
.SetStatus(eReturnStatusFailed
);
2692 if (m_uuid_option_group
.GetOptionValue().OptionWasSet()) {
2693 search_using_module_spec
= true;
2694 module_spec
.GetUUID() =
2695 m_uuid_option_group
.GetOptionValue().GetCurrentValue();
2698 if (search_using_module_spec
) {
2699 ModuleList matching_modules
;
2700 target
->GetImages().FindModules(module_spec
, matching_modules
);
2701 const size_t num_matches
= matching_modules
.GetSize();
2703 char path
[PATH_MAX
];
2704 if (num_matches
== 1) {
2705 Module
*module
= matching_modules
.GetModulePointerAtIndex(0);
2707 ObjectFile
*objfile
= module
->GetObjectFile();
2709 SectionList
*section_list
= module
->GetSectionList();
2711 bool changed
= false;
2713 if (m_slide_option
.GetOptionValue().OptionWasSet()) {
2714 const addr_t slide
=
2715 m_slide_option
.GetOptionValue().GetCurrentValue();
2716 const bool slide_is_offset
= true;
2717 module
->SetLoadAddress(*target
, slide
, slide_is_offset
,
2720 result
.AppendError("one or more section name + load "
2721 "address pair must be specified");
2722 result
.SetStatus(eReturnStatusFailed
);
2726 if (m_slide_option
.GetOptionValue().OptionWasSet()) {
2727 result
.AppendError("The \"--slide <offset>\" option can't "
2728 "be used in conjunction with setting "
2729 "section load addresses.\n");
2730 result
.SetStatus(eReturnStatusFailed
);
2734 for (size_t i
= 0; i
< argc
; i
+= 2) {
2735 const char *sect_name
= args
.GetArgumentAtIndex(i
);
2736 const char *load_addr_cstr
= args
.GetArgumentAtIndex(i
+ 1);
2737 if (sect_name
&& load_addr_cstr
) {
2738 ConstString
const_sect_name(sect_name
);
2739 bool success
= false;
2740 addr_t load_addr
= StringConvert::ToUInt64(
2741 load_addr_cstr
, LLDB_INVALID_ADDRESS
, 0, &success
);
2743 SectionSP
section_sp(
2744 section_list
->FindSectionByName(const_sect_name
));
2746 if (section_sp
->IsThreadSpecific()) {
2747 result
.AppendErrorWithFormat(
2748 "thread specific sections are not yet "
2749 "supported (section '%s')\n",
2751 result
.SetStatus(eReturnStatusFailed
);
2754 if (target
->GetSectionLoadList()
2755 .SetSectionLoadAddress(section_sp
, load_addr
))
2757 result
.AppendMessageWithFormat(
2758 "section '%s' loaded at 0x%" PRIx64
"\n",
2759 sect_name
, load_addr
);
2762 result
.AppendErrorWithFormat("no section found that "
2763 "matches the section "
2766 result
.SetStatus(eReturnStatusFailed
);
2770 result
.AppendErrorWithFormat(
2771 "invalid load address string '%s'\n", load_addr_cstr
);
2772 result
.SetStatus(eReturnStatusFailed
);
2777 result
.AppendError("section names must be followed by "
2778 "a load address.\n");
2780 result
.AppendError("one or more section name + load "
2781 "address pair must be specified.\n");
2782 result
.SetStatus(eReturnStatusFailed
);
2789 target
->ModulesDidLoad(matching_modules
);
2790 Process
*process
= m_exe_ctx
.GetProcessPtr();
2795 ProcessSP process
= target
->CalculateProcess();
2796 Address file_entry
= objfile
->GetEntryPointAddress();
2798 result
.AppendError("No process");
2801 if (set_pc
&& !file_entry
.IsValid()) {
2802 result
.AppendError("No entry address in object file");
2805 std::vector
<ObjectFile::LoadableData
> loadables(
2806 objfile
->GetLoadableData(*target
));
2807 if (loadables
.size() == 0) {
2808 result
.AppendError("No loadable sections");
2811 Status error
= process
->WriteObjectFile(std::move(loadables
));
2813 result
.AppendError(error
.AsCString());
2817 ThreadList
&thread_list
= process
->GetThreadList();
2818 RegisterContextSP
reg_context(
2819 thread_list
.GetSelectedThread()->GetRegisterContext());
2820 addr_t file_entry_addr
= file_entry
.GetLoadAddress(target
);
2821 if (!reg_context
->SetPC(file_entry_addr
)) {
2822 result
.AppendErrorWithFormat("failed to set PC value to "
2825 result
.SetStatus(eReturnStatusFailed
);
2830 module
->GetFileSpec().GetPath(path
, sizeof(path
));
2831 result
.AppendErrorWithFormat("no sections in object file '%s'\n",
2833 result
.SetStatus(eReturnStatusFailed
);
2836 module
->GetFileSpec().GetPath(path
, sizeof(path
));
2837 result
.AppendErrorWithFormat("no object file for module '%s'\n",
2839 result
.SetStatus(eReturnStatusFailed
);
2842 FileSpec
*module_spec_file
= module_spec
.GetFileSpecPtr();
2843 if (module_spec_file
) {
2844 module_spec_file
->GetPath(path
, sizeof(path
));
2845 result
.AppendErrorWithFormat("invalid module '%s'.\n", path
);
2847 result
.AppendError("no module spec");
2848 result
.SetStatus(eReturnStatusFailed
);
2851 std::string uuid_str
;
2853 if (module_spec
.GetFileSpec())
2854 module_spec
.GetFileSpec().GetPath(path
, sizeof(path
));
2858 if (module_spec
.GetUUIDPtr())
2859 uuid_str
= module_spec
.GetUUID().GetAsString();
2860 if (num_matches
> 1) {
2861 result
.AppendErrorWithFormat(
2862 "multiple modules match%s%s%s%s:\n", path
[0] ? " file=" : "",
2863 path
, !uuid_str
.empty() ? " uuid=" : "", uuid_str
.c_str());
2864 for (size_t i
= 0; i
< num_matches
; ++i
) {
2865 if (matching_modules
.GetModulePointerAtIndex(i
)
2867 .GetPath(path
, sizeof(path
)))
2868 result
.AppendMessageWithFormat("%s\n", path
);
2871 result
.AppendErrorWithFormat(
2872 "no modules were found that match%s%s%s%s.\n",
2873 path
[0] ? " file=" : "", path
, !uuid_str
.empty() ? " uuid=" : "",
2876 result
.SetStatus(eReturnStatusFailed
);
2879 result
.AppendError("either the \"--file <module>\" or the \"--uuid "
2880 "<uuid>\" option must be specified.\n");
2881 result
.SetStatus(eReturnStatusFailed
);
2884 return result
.Succeeded();
2887 OptionGroupOptions m_option_group
;
2888 OptionGroupUUID m_uuid_option_group
;
2889 OptionGroupString m_file_option
;
2890 OptionGroupBoolean m_load_option
;
2891 OptionGroupBoolean m_pc_option
;
2892 OptionGroupUInt64 m_slide_option
;
2895 // List images with associated information
2896 #define LLDB_OPTIONS_target_modules_list
2897 #include "CommandOptions.inc"
2899 class CommandObjectTargetModulesList
: public CommandObjectParsed
{
2901 class CommandOptions
: public Options
{
2904 : Options(), m_format_array(), m_use_global_module_list(false),
2905 m_module_addr(LLDB_INVALID_ADDRESS
) {}
2907 ~CommandOptions() override
= default;
2909 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
2910 ExecutionContext
*execution_context
) override
{
2913 const int short_option
= m_getopt_table
[option_idx
].val
;
2914 if (short_option
== 'g') {
2915 m_use_global_module_list
= true;
2916 } else if (short_option
== 'a') {
2917 m_module_addr
= OptionArgParser::ToAddress(
2918 execution_context
, option_arg
, LLDB_INVALID_ADDRESS
, &error
);
2920 unsigned long width
= 0;
2921 option_arg
.getAsInteger(0, width
);
2922 m_format_array
.push_back(std::make_pair(short_option
, width
));
2927 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
2928 m_format_array
.clear();
2929 m_use_global_module_list
= false;
2930 m_module_addr
= LLDB_INVALID_ADDRESS
;
2933 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
2934 return llvm::makeArrayRef(g_target_modules_list_options
);
2937 // Instance variables to hold the values for command options.
2938 typedef std::vector
<std::pair
<char, uint32_t>> FormatWidthCollection
;
2939 FormatWidthCollection m_format_array
;
2940 bool m_use_global_module_list
;
2941 lldb::addr_t m_module_addr
;
2944 CommandObjectTargetModulesList(CommandInterpreter
&interpreter
)
2945 : CommandObjectParsed(
2946 interpreter
, "target modules list",
2947 "List current executable and dependent shared library images.",
2948 "target modules list [<cmd-options>]"),
2951 ~CommandObjectTargetModulesList() override
= default;
2953 Options
*GetOptions() override
{ return &m_options
; }
2956 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
2957 Target
*target
= GetDebugger().GetSelectedTarget().get();
2958 const bool use_global_module_list
= m_options
.m_use_global_module_list
;
2959 // Define a local module list here to ensure it lives longer than any
2960 // "locker" object which might lock its contents below (through the
2961 // "module_list_ptr" variable).
2962 ModuleList module_list
;
2963 if (target
== nullptr && !use_global_module_list
) {
2964 result
.AppendError("invalid target, create a debug target using the "
2965 "'target create' command");
2966 result
.SetStatus(eReturnStatusFailed
);
2970 uint32_t addr_byte_size
=
2971 target
->GetArchitecture().GetAddressByteSize();
2972 result
.GetOutputStream().SetAddressByteSize(addr_byte_size
);
2973 result
.GetErrorStream().SetAddressByteSize(addr_byte_size
);
2975 // Dump all sections for all modules images
2976 Stream
&strm
= result
.GetOutputStream();
2978 if (m_options
.m_module_addr
!= LLDB_INVALID_ADDRESS
) {
2980 Address module_address
;
2981 if (module_address
.SetLoadAddress(m_options
.m_module_addr
, target
)) {
2982 ModuleSP
module_sp(module_address
.GetModule());
2984 PrintModule(target
, module_sp
.get(), 0, strm
);
2985 result
.SetStatus(eReturnStatusSuccessFinishResult
);
2987 result
.AppendErrorWithFormat(
2988 "Couldn't find module matching address: 0x%" PRIx64
".",
2989 m_options
.m_module_addr
);
2990 result
.SetStatus(eReturnStatusFailed
);
2993 result
.AppendErrorWithFormat(
2994 "Couldn't find module containing address: 0x%" PRIx64
".",
2995 m_options
.m_module_addr
);
2996 result
.SetStatus(eReturnStatusFailed
);
3000 "Can only look up modules by address with a valid target.");
3001 result
.SetStatus(eReturnStatusFailed
);
3003 return result
.Succeeded();
3006 size_t num_modules
= 0;
3008 // This locker will be locked on the mutex in module_list_ptr if it is
3009 // non-nullptr. Otherwise it will lock the
3010 // AllocationModuleCollectionMutex when accessing the global module list
3012 std::unique_lock
<std::recursive_mutex
> guard(
3013 Module::GetAllocationModuleCollectionMutex(), std::defer_lock
);
3015 const ModuleList
*module_list_ptr
= nullptr;
3016 const size_t argc
= command
.GetArgumentCount();
3018 if (use_global_module_list
) {
3020 num_modules
= Module::GetNumberAllocatedModules();
3022 module_list_ptr
= &target
->GetImages();
3025 // TODO: Convert to entry based iteration. Requires converting
3026 // FindModulesByName.
3027 for (size_t i
= 0; i
< argc
; ++i
) {
3028 // Dump specified images (by basename or fullpath)
3029 const char *arg_cstr
= command
.GetArgumentAtIndex(i
);
3030 const size_t num_matches
= FindModulesByName(
3031 target
, arg_cstr
, module_list
, use_global_module_list
);
3032 if (num_matches
== 0) {
3034 result
.AppendErrorWithFormat("no modules found that match '%s'",
3036 result
.SetStatus(eReturnStatusFailed
);
3042 module_list_ptr
= &module_list
;
3045 std::unique_lock
<std::recursive_mutex
> lock
;
3046 if (module_list_ptr
!= nullptr) {
3048 std::unique_lock
<std::recursive_mutex
>(module_list_ptr
->GetMutex());
3050 num_modules
= module_list_ptr
->GetSize();
3053 if (num_modules
> 0) {
3054 for (uint32_t image_idx
= 0; image_idx
< num_modules
; ++image_idx
) {
3057 if (module_list_ptr
) {
3058 module_sp
= module_list_ptr
->GetModuleAtIndexUnlocked(image_idx
);
3059 module
= module_sp
.get();
3061 module
= Module::GetAllocatedModuleAtIndex(image_idx
);
3062 module_sp
= module
->shared_from_this();
3065 const size_t indent
= strm
.Printf("[%3u] ", image_idx
);
3066 PrintModule(target
, module
, indent
, strm
);
3068 result
.SetStatus(eReturnStatusSuccessFinishResult
);
3071 if (use_global_module_list
)
3073 "the global module list has no matching modules");
3075 result
.AppendError("the target has no matching modules");
3077 if (use_global_module_list
)
3078 result
.AppendError("the global module list is empty");
3081 "the target has no associated executable images");
3083 result
.SetStatus(eReturnStatusFailed
);
3087 return result
.Succeeded();
3090 void PrintModule(Target
*target
, Module
*module
, int indent
, Stream
&strm
) {
3091 if (module
== nullptr) {
3092 strm
.PutCString("Null module");
3096 bool dump_object_name
= false;
3097 if (m_options
.m_format_array
.empty()) {
3098 m_options
.m_format_array
.push_back(std::make_pair('u', 0));
3099 m_options
.m_format_array
.push_back(std::make_pair('h', 0));
3100 m_options
.m_format_array
.push_back(std::make_pair('f', 0));
3101 m_options
.m_format_array
.push_back(std::make_pair('S', 0));
3103 const size_t num_entries
= m_options
.m_format_array
.size();
3104 bool print_space
= false;
3105 for (size_t i
= 0; i
< num_entries
; ++i
) {
3109 const char format_char
= m_options
.m_format_array
[i
].first
;
3110 uint32_t width
= m_options
.m_format_array
[i
].second
;
3111 switch (format_char
) {
3113 DumpModuleArchitecture(strm
, module
, false, width
);
3117 DumpModuleArchitecture(strm
, module
, true, width
);
3121 DumpFullpath(strm
, &module
->GetFileSpec(), width
);
3122 dump_object_name
= true;
3126 DumpDirectory(strm
, &module
->GetFileSpec(), width
);
3130 DumpBasename(strm
, &module
->GetFileSpec(), width
);
3131 dump_object_name
= true;
3136 // Image header address
3138 uint32_t addr_nibble_width
=
3139 target
? (target
->GetArchitecture().GetAddressByteSize() * 2)
3142 ObjectFile
*objfile
= module
->GetObjectFile();
3144 Address
base_addr(objfile
->GetBaseAddress());
3145 if (base_addr
.IsValid()) {
3146 if (target
&& !target
->GetSectionLoadList().IsEmpty()) {
3147 lldb::addr_t load_addr
= base_addr
.GetLoadAddress(target
);
3148 if (load_addr
== LLDB_INVALID_ADDRESS
) {
3149 base_addr
.Dump(&strm
, target
,
3150 Address::DumpStyleModuleWithFileAddress
,
3151 Address::DumpStyleFileAddress
);
3153 if (format_char
== 'o') {
3154 // Show the offset of slide for the image
3155 strm
.Printf("0x%*.*" PRIx64
, addr_nibble_width
,
3157 load_addr
- base_addr
.GetFileAddress());
3159 // Show the load address of the image
3160 strm
.Printf("0x%*.*" PRIx64
, addr_nibble_width
,
3161 addr_nibble_width
, load_addr
);
3166 // The address was valid, but the image isn't loaded, output the
3167 // address in an appropriate format
3168 base_addr
.Dump(&strm
, target
, Address::DumpStyleFileAddress
);
3172 strm
.Printf("%*s", addr_nibble_width
+ 2, "");
3177 size_t ref_count
= 0;
3178 ModuleSP
module_sp(module
->shared_from_this());
3180 // Take one away to make sure we don't count our local "module_sp"
3181 ref_count
= module_sp
.use_count() - 1;
3184 strm
.Printf("{%*" PRIu64
"}", width
, (uint64_t)ref_count
);
3186 strm
.Printf("{%" PRIu64
"}", (uint64_t)ref_count
);
3191 if (const SymbolFile
*symbol_file
= module
->GetSymbolFile()) {
3192 const FileSpec symfile_spec
=
3193 symbol_file
->GetObjectFile()->GetFileSpec();
3194 if (format_char
== 'S') {
3195 // Dump symbol file only if different from module file
3196 if (!symfile_spec
|| symfile_spec
== module
->GetFileSpec()) {
3197 print_space
= false;
3200 // Add a newline and indent past the index
3201 strm
.Printf("\n%*s", indent
, "");
3203 DumpFullpath(strm
, &symfile_spec
, width
);
3204 dump_object_name
= true;
3207 strm
.Printf("%.*s", width
, "<NONE>");
3211 strm
.Format("{0:%c}", llvm::fmt_align(module
->GetModificationTime(),
3212 llvm::AlignStyle::Left
, width
));
3216 strm
.Printf("%p", static_cast<void *>(module
));
3220 DumpModuleUUID(strm
, module
);
3227 if (dump_object_name
) {
3228 const char *object_name
= module
->GetObjectName().GetCString();
3230 strm
.Printf("(%s)", object_name
);
3235 CommandOptions m_options
;
3238 #pragma mark CommandObjectTargetModulesShowUnwind
3240 // Lookup unwind information in images
3241 #define LLDB_OPTIONS_target_modules_show_unwind
3242 #include "CommandOptions.inc"
3244 class CommandObjectTargetModulesShowUnwind
: public CommandObjectParsed
{
3247 eLookupTypeInvalid
= -1,
3248 eLookupTypeAddress
= 0,
3250 eLookupTypeFunction
,
3251 eLookupTypeFunctionOrSymbol
,
3255 class CommandOptions
: public Options
{
3258 : Options(), m_type(eLookupTypeInvalid
), m_str(),
3259 m_addr(LLDB_INVALID_ADDRESS
) {}
3261 ~CommandOptions() override
= default;
3263 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
3264 ExecutionContext
*execution_context
) override
{
3267 const int short_option
= m_getopt_table
[option_idx
].val
;
3269 switch (short_option
) {
3272 m_type
= eLookupTypeAddress
;
3273 m_addr
= OptionArgParser::ToAddress(execution_context
, option_arg
,
3274 LLDB_INVALID_ADDRESS
, &error
);
3275 if (m_addr
== LLDB_INVALID_ADDRESS
)
3276 error
.SetErrorStringWithFormat("invalid address string '%s'",
3277 option_arg
.str().c_str());
3283 m_type
= eLookupTypeFunctionOrSymbol
;
3287 llvm_unreachable("Unimplemented option");
3293 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
3294 m_type
= eLookupTypeInvalid
;
3296 m_addr
= LLDB_INVALID_ADDRESS
;
3299 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
3300 return llvm::makeArrayRef(g_target_modules_show_unwind_options
);
3303 // Instance variables to hold the values for command options.
3305 int m_type
; // Should be a eLookupTypeXXX enum after parsing options
3306 std::string m_str
; // Holds name lookup
3307 lldb::addr_t m_addr
; // Holds the address to lookup
3310 CommandObjectTargetModulesShowUnwind(CommandInterpreter
&interpreter
)
3311 : CommandObjectParsed(
3312 interpreter
, "target modules show-unwind",
3313 "Show synthesized unwind instructions for a function.", nullptr,
3314 eCommandRequiresTarget
| eCommandRequiresProcess
|
3315 eCommandProcessMustBeLaunched
| eCommandProcessMustBePaused
),
3318 ~CommandObjectTargetModulesShowUnwind() override
= default;
3320 Options
*GetOptions() override
{ return &m_options
; }
3323 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
3324 Target
*target
= m_exe_ctx
.GetTargetPtr();
3325 Process
*process
= m_exe_ctx
.GetProcessPtr();
3328 abi
= process
->GetABI().get();
3330 if (process
== nullptr) {
3332 "You must have a process running to use this command.");
3333 result
.SetStatus(eReturnStatusFailed
);
3337 ThreadList
threads(process
->GetThreadList());
3338 if (threads
.GetSize() == 0) {
3339 result
.AppendError("The process must be paused to use this command.");
3340 result
.SetStatus(eReturnStatusFailed
);
3344 ThreadSP
thread(threads
.GetThreadAtIndex(0));
3346 result
.AppendError("The process must be paused to use this command.");
3347 result
.SetStatus(eReturnStatusFailed
);
3351 SymbolContextList sc_list
;
3353 if (m_options
.m_type
== eLookupTypeFunctionOrSymbol
) {
3354 ConstString
function_name(m_options
.m_str
.c_str());
3355 target
->GetImages().FindFunctions(function_name
, eFunctionNameTypeAuto
,
3356 true, false, sc_list
);
3357 } else if (m_options
.m_type
== eLookupTypeAddress
&& target
) {
3359 if (target
->GetSectionLoadList().ResolveLoadAddress(m_options
.m_addr
,
3362 ModuleSP
module_sp(addr
.GetModule());
3363 module_sp
->ResolveSymbolContextForAddress(addr
,
3364 eSymbolContextEverything
, sc
);
3365 if (sc
.function
|| sc
.symbol
) {
3371 "address-expression or function name option must be specified.");
3372 result
.SetStatus(eReturnStatusFailed
);
3376 size_t num_matches
= sc_list
.GetSize();
3377 if (num_matches
== 0) {
3378 result
.AppendErrorWithFormat("no unwind data found that matches '%s'.",
3379 m_options
.m_str
.c_str());
3380 result
.SetStatus(eReturnStatusFailed
);
3384 for (uint32_t idx
= 0; idx
< num_matches
; idx
++) {
3386 sc_list
.GetContextAtIndex(idx
, sc
);
3387 if (sc
.symbol
== nullptr && sc
.function
== nullptr)
3389 if (!sc
.module_sp
|| sc
.module_sp
->GetObjectFile() == nullptr)
3392 if (!sc
.GetAddressRange(eSymbolContextFunction
| eSymbolContextSymbol
, 0,
3395 if (!range
.GetBaseAddress().IsValid())
3397 ConstString
funcname(sc
.GetFunctionName());
3398 if (funcname
.IsEmpty())
3400 addr_t start_addr
= range
.GetBaseAddress().GetLoadAddress(target
);
3402 start_addr
= abi
->FixCodeAddress(start_addr
);
3404 FuncUnwindersSP
func_unwinders_sp(
3405 sc
.module_sp
->GetUnwindTable()
3406 .GetUncachedFuncUnwindersContainingAddress(start_addr
, sc
));
3407 if (!func_unwinders_sp
)
3410 result
.GetOutputStream().Printf(
3411 "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64
")\n\n",
3412 sc
.module_sp
->GetPlatformFileSpec().GetFilename().AsCString(),
3413 funcname
.AsCString(), start_addr
);
3415 UnwindPlanSP non_callsite_unwind_plan
=
3416 func_unwinders_sp
->GetUnwindPlanAtNonCallSite(*target
, *thread
);
3417 if (non_callsite_unwind_plan
) {
3418 result
.GetOutputStream().Printf(
3419 "Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n",
3420 non_callsite_unwind_plan
->GetSourceName().AsCString());
3422 UnwindPlanSP callsite_unwind_plan
=
3423 func_unwinders_sp
->GetUnwindPlanAtCallSite(*target
, *thread
);
3424 if (callsite_unwind_plan
) {
3425 result
.GetOutputStream().Printf(
3426 "Synchronous (restricted to call-sites) UnwindPlan is '%s'\n",
3427 callsite_unwind_plan
->GetSourceName().AsCString());
3429 UnwindPlanSP fast_unwind_plan
=
3430 func_unwinders_sp
->GetUnwindPlanFastUnwind(*target
, *thread
);
3431 if (fast_unwind_plan
) {
3432 result
.GetOutputStream().Printf(
3433 "Fast UnwindPlan is '%s'\n",
3434 fast_unwind_plan
->GetSourceName().AsCString());
3437 result
.GetOutputStream().Printf("\n");
3439 UnwindPlanSP assembly_sp
=
3440 func_unwinders_sp
->GetAssemblyUnwindPlan(*target
, *thread
);
3442 result
.GetOutputStream().Printf(
3443 "Assembly language inspection UnwindPlan:\n");
3444 assembly_sp
->Dump(result
.GetOutputStream(), thread
.get(),
3445 LLDB_INVALID_ADDRESS
);
3446 result
.GetOutputStream().Printf("\n");
3449 UnwindPlanSP of_unwind_sp
=
3450 func_unwinders_sp
->GetObjectFileUnwindPlan(*target
);
3452 result
.GetOutputStream().Printf("object file UnwindPlan:\n");
3453 of_unwind_sp
->Dump(result
.GetOutputStream(), thread
.get(),
3454 LLDB_INVALID_ADDRESS
);
3455 result
.GetOutputStream().Printf("\n");
3458 UnwindPlanSP of_unwind_augmented_sp
=
3459 func_unwinders_sp
->GetObjectFileAugmentedUnwindPlan(*target
, *thread
);
3460 if (of_unwind_augmented_sp
) {
3461 result
.GetOutputStream().Printf("object file augmented UnwindPlan:\n");
3462 of_unwind_augmented_sp
->Dump(result
.GetOutputStream(), thread
.get(),
3463 LLDB_INVALID_ADDRESS
);
3464 result
.GetOutputStream().Printf("\n");
3467 UnwindPlanSP ehframe_sp
=
3468 func_unwinders_sp
->GetEHFrameUnwindPlan(*target
);
3470 result
.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
3471 ehframe_sp
->Dump(result
.GetOutputStream(), thread
.get(),
3472 LLDB_INVALID_ADDRESS
);
3473 result
.GetOutputStream().Printf("\n");
3476 UnwindPlanSP ehframe_augmented_sp
=
3477 func_unwinders_sp
->GetEHFrameAugmentedUnwindPlan(*target
, *thread
);
3478 if (ehframe_augmented_sp
) {
3479 result
.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
3480 ehframe_augmented_sp
->Dump(result
.GetOutputStream(), thread
.get(),
3481 LLDB_INVALID_ADDRESS
);
3482 result
.GetOutputStream().Printf("\n");
3485 if (UnwindPlanSP plan_sp
=
3486 func_unwinders_sp
->GetDebugFrameUnwindPlan(*target
)) {
3487 result
.GetOutputStream().Printf("debug_frame UnwindPlan:\n");
3488 plan_sp
->Dump(result
.GetOutputStream(), thread
.get(),
3489 LLDB_INVALID_ADDRESS
);
3490 result
.GetOutputStream().Printf("\n");
3493 if (UnwindPlanSP plan_sp
=
3494 func_unwinders_sp
->GetDebugFrameAugmentedUnwindPlan(*target
,
3496 result
.GetOutputStream().Printf("debug_frame augmented UnwindPlan:\n");
3497 plan_sp
->Dump(result
.GetOutputStream(), thread
.get(),
3498 LLDB_INVALID_ADDRESS
);
3499 result
.GetOutputStream().Printf("\n");
3502 UnwindPlanSP arm_unwind_sp
=
3503 func_unwinders_sp
->GetArmUnwindUnwindPlan(*target
);
3504 if (arm_unwind_sp
) {
3505 result
.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
3506 arm_unwind_sp
->Dump(result
.GetOutputStream(), thread
.get(),
3507 LLDB_INVALID_ADDRESS
);
3508 result
.GetOutputStream().Printf("\n");
3511 if (UnwindPlanSP symfile_plan_sp
=
3512 func_unwinders_sp
->GetSymbolFileUnwindPlan(*thread
)) {
3513 result
.GetOutputStream().Printf("Symbol file UnwindPlan:\n");
3514 symfile_plan_sp
->Dump(result
.GetOutputStream(), thread
.get(),
3515 LLDB_INVALID_ADDRESS
);
3516 result
.GetOutputStream().Printf("\n");
3519 UnwindPlanSP compact_unwind_sp
=
3520 func_unwinders_sp
->GetCompactUnwindUnwindPlan(*target
);
3521 if (compact_unwind_sp
) {
3522 result
.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
3523 compact_unwind_sp
->Dump(result
.GetOutputStream(), thread
.get(),
3524 LLDB_INVALID_ADDRESS
);
3525 result
.GetOutputStream().Printf("\n");
3528 if (fast_unwind_plan
) {
3529 result
.GetOutputStream().Printf("Fast UnwindPlan:\n");
3530 fast_unwind_plan
->Dump(result
.GetOutputStream(), thread
.get(),
3531 LLDB_INVALID_ADDRESS
);
3532 result
.GetOutputStream().Printf("\n");
3535 ABISP abi_sp
= process
->GetABI();
3537 UnwindPlan
arch_default(lldb::eRegisterKindGeneric
);
3538 if (abi_sp
->CreateDefaultUnwindPlan(arch_default
)) {
3539 result
.GetOutputStream().Printf("Arch default UnwindPlan:\n");
3540 arch_default
.Dump(result
.GetOutputStream(), thread
.get(),
3541 LLDB_INVALID_ADDRESS
);
3542 result
.GetOutputStream().Printf("\n");
3545 UnwindPlan
arch_entry(lldb::eRegisterKindGeneric
);
3546 if (abi_sp
->CreateFunctionEntryUnwindPlan(arch_entry
)) {
3547 result
.GetOutputStream().Printf(
3548 "Arch default at entry point UnwindPlan:\n");
3549 arch_entry
.Dump(result
.GetOutputStream(), thread
.get(),
3550 LLDB_INVALID_ADDRESS
);
3551 result
.GetOutputStream().Printf("\n");
3555 result
.GetOutputStream().Printf("\n");
3557 return result
.Succeeded();
3560 CommandOptions m_options
;
3563 // Lookup information in images
3564 #define LLDB_OPTIONS_target_modules_lookup
3565 #include "CommandOptions.inc"
3567 class CommandObjectTargetModulesLookup
: public CommandObjectParsed
{
3570 eLookupTypeInvalid
= -1,
3571 eLookupTypeAddress
= 0,
3573 eLookupTypeFileLine
, // Line is optional
3574 eLookupTypeFunction
,
3575 eLookupTypeFunctionOrSymbol
,
3580 class CommandOptions
: public Options
{
3582 CommandOptions() : Options() { OptionParsingStarting(nullptr); }
3584 ~CommandOptions() override
= default;
3586 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
3587 ExecutionContext
*execution_context
) override
{
3590 const int short_option
= m_getopt_table
[option_idx
].val
;
3592 switch (short_option
) {
3594 m_type
= eLookupTypeAddress
;
3595 m_addr
= OptionArgParser::ToAddress(execution_context
, option_arg
,
3596 LLDB_INVALID_ADDRESS
, &error
);
3600 if (option_arg
.getAsInteger(0, m_offset
))
3601 error
.SetErrorStringWithFormat("invalid offset string '%s'",
3602 option_arg
.str().c_str());
3607 m_type
= eLookupTypeSymbol
;
3611 m_file
.SetFile(option_arg
, FileSpec::Style::native
);
3612 m_type
= eLookupTypeFileLine
;
3616 m_include_inlines
= false;
3620 if (option_arg
.getAsInteger(0, m_line_number
))
3621 error
.SetErrorStringWithFormat("invalid line number string '%s'",
3622 option_arg
.str().c_str());
3623 else if (m_line_number
== 0)
3624 error
.SetErrorString("zero is an invalid line number");
3625 m_type
= eLookupTypeFileLine
;
3630 m_type
= eLookupTypeFunction
;
3635 m_type
= eLookupTypeFunctionOrSymbol
;
3640 m_type
= eLookupTypeType
;
3655 llvm_unreachable("Unimplemented option");
3661 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
3662 m_type
= eLookupTypeInvalid
;
3665 m_addr
= LLDB_INVALID_ADDRESS
;
3668 m_use_regex
= false;
3669 m_include_inlines
= true;
3671 m_print_all
= false;
3674 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
3675 return llvm::makeArrayRef(g_target_modules_lookup_options
);
3678 int m_type
; // Should be a eLookupTypeXXX enum after parsing options
3679 std::string m_str
; // Holds name lookup
3680 FileSpec m_file
; // Files for file lookups
3681 lldb::addr_t m_addr
; // Holds the address to lookup
3683 m_offset
; // Subtract this offset from m_addr before doing lookups.
3684 uint32_t m_line_number
; // Line number for file+line lookups
3685 bool m_use_regex
; // Name lookups in m_str are regular expressions.
3686 bool m_include_inlines
; // Check for inline entries when looking up by
3688 bool m_verbose
; // Enable verbose lookup info
3689 bool m_print_all
; // Print all matches, even in cases where there's a best
3693 CommandObjectTargetModulesLookup(CommandInterpreter
&interpreter
)
3694 : CommandObjectParsed(interpreter
, "target modules lookup",
3695 "Look up information within executable and "
3696 "dependent shared library images.",
3697 nullptr, eCommandRequiresTarget
),
3699 CommandArgumentEntry arg
;
3700 CommandArgumentData file_arg
;
3702 // Define the first (and only) variant of this arg.
3703 file_arg
.arg_type
= eArgTypeFilename
;
3704 file_arg
.arg_repetition
= eArgRepeatStar
;
3706 // There is only one variant this argument could be; put it into the
3708 arg
.push_back(file_arg
);
3710 // Push the data for the first argument into the m_arguments vector.
3711 m_arguments
.push_back(arg
);
3714 ~CommandObjectTargetModulesLookup() override
= default;
3716 Options
*GetOptions() override
{ return &m_options
; }
3718 bool LookupHere(CommandInterpreter
&interpreter
, CommandReturnObject
&result
,
3719 bool &syntax_error
) {
3720 switch (m_options
.m_type
) {
3721 case eLookupTypeAddress
:
3722 case eLookupTypeFileLine
:
3723 case eLookupTypeFunction
:
3724 case eLookupTypeFunctionOrSymbol
:
3725 case eLookupTypeSymbol
:
3728 case eLookupTypeType
:
3732 StackFrameSP frame
= m_exe_ctx
.GetFrameSP();
3737 const SymbolContext
&sym_ctx(frame
->GetSymbolContext(eSymbolContextModule
));
3739 if (!sym_ctx
.module_sp
)
3742 switch (m_options
.m_type
) {
3745 case eLookupTypeType
:
3746 if (!m_options
.m_str
.empty()) {
3747 if (LookupTypeHere(m_interpreter
, result
.GetOutputStream(),
3748 *sym_ctx
.module_sp
, m_options
.m_str
.c_str(),
3749 m_options
.m_use_regex
)) {
3750 result
.SetStatus(eReturnStatusSuccessFinishResult
);
3760 bool LookupInModule(CommandInterpreter
&interpreter
, Module
*module
,
3761 CommandReturnObject
&result
, bool &syntax_error
) {
3762 switch (m_options
.m_type
) {
3763 case eLookupTypeAddress
:
3764 if (m_options
.m_addr
!= LLDB_INVALID_ADDRESS
) {
3765 if (LookupAddressInModule(
3766 m_interpreter
, result
.GetOutputStream(), module
,
3767 eSymbolContextEverything
|
3768 (m_options
.m_verbose
3769 ? static_cast<int>(eSymbolContextVariable
)
3771 m_options
.m_addr
, m_options
.m_offset
, m_options
.m_verbose
)) {
3772 result
.SetStatus(eReturnStatusSuccessFinishResult
);
3778 case eLookupTypeSymbol
:
3779 if (!m_options
.m_str
.empty()) {
3780 if (LookupSymbolInModule(m_interpreter
, result
.GetOutputStream(),
3781 module
, m_options
.m_str
.c_str(),
3782 m_options
.m_use_regex
, m_options
.m_verbose
)) {
3783 result
.SetStatus(eReturnStatusSuccessFinishResult
);
3789 case eLookupTypeFileLine
:
3790 if (m_options
.m_file
) {
3791 if (LookupFileAndLineInModule(
3792 m_interpreter
, result
.GetOutputStream(), module
,
3793 m_options
.m_file
, m_options
.m_line_number
,
3794 m_options
.m_include_inlines
, m_options
.m_verbose
)) {
3795 result
.SetStatus(eReturnStatusSuccessFinishResult
);
3801 case eLookupTypeFunctionOrSymbol
:
3802 case eLookupTypeFunction
:
3803 if (!m_options
.m_str
.empty()) {
3804 if (LookupFunctionInModule(
3805 m_interpreter
, result
.GetOutputStream(), module
,
3806 m_options
.m_str
.c_str(), m_options
.m_use_regex
,
3807 m_options
.m_include_inlines
,
3809 eLookupTypeFunctionOrSymbol
, // include symbols
3810 m_options
.m_verbose
)) {
3811 result
.SetStatus(eReturnStatusSuccessFinishResult
);
3817 case eLookupTypeType
:
3818 if (!m_options
.m_str
.empty()) {
3819 if (LookupTypeInModule(m_interpreter
, result
.GetOutputStream(), module
,
3820 m_options
.m_str
.c_str(),
3821 m_options
.m_use_regex
)) {
3822 result
.SetStatus(eReturnStatusSuccessFinishResult
);
3829 m_options
.GenerateOptionUsage(
3830 result
.GetErrorStream(), this,
3831 GetCommandInterpreter().GetDebugger().GetTerminalWidth());
3832 syntax_error
= true;
3836 result
.SetStatus(eReturnStatusFailed
);
3841 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
3842 Target
*target
= &GetSelectedTarget();
3843 bool syntax_error
= false;
3845 uint32_t num_successful_lookups
= 0;
3846 uint32_t addr_byte_size
= target
->GetArchitecture().GetAddressByteSize();
3847 result
.GetOutputStream().SetAddressByteSize(addr_byte_size
);
3848 result
.GetErrorStream().SetAddressByteSize(addr_byte_size
);
3849 // Dump all sections for all modules images
3851 if (command
.GetArgumentCount() == 0) {
3852 ModuleSP current_module
;
3854 // Where it is possible to look in the current symbol context first,
3855 // try that. If this search was successful and --all was not passed,
3856 // don't print anything else.
3857 if (LookupHere(m_interpreter
, result
, syntax_error
)) {
3858 result
.GetOutputStream().EOL();
3859 num_successful_lookups
++;
3860 if (!m_options
.m_print_all
) {
3861 result
.SetStatus(eReturnStatusSuccessFinishResult
);
3862 return result
.Succeeded();
3866 // Dump all sections for all other modules
3868 const ModuleList
&target_modules
= target
->GetImages();
3869 std::lock_guard
<std::recursive_mutex
> guard(target_modules
.GetMutex());
3870 const size_t num_modules
= target_modules
.GetSize();
3871 if (num_modules
> 0) {
3872 for (i
= 0; i
< num_modules
&& !syntax_error
; ++i
) {
3873 Module
*module_pointer
=
3874 target_modules
.GetModulePointerAtIndexUnlocked(i
);
3876 if (module_pointer
!= current_module
.get() &&
3877 LookupInModule(m_interpreter
,
3878 target_modules
.GetModulePointerAtIndexUnlocked(i
),
3879 result
, syntax_error
)) {
3880 result
.GetOutputStream().EOL();
3881 num_successful_lookups
++;
3885 result
.AppendError("the target has no associated executable images");
3886 result
.SetStatus(eReturnStatusFailed
);
3890 // Dump specified images (by basename or fullpath)
3891 const char *arg_cstr
;
3892 for (i
= 0; (arg_cstr
= command
.GetArgumentAtIndex(i
)) != nullptr &&
3895 ModuleList module_list
;
3896 const size_t num_matches
=
3897 FindModulesByName(target
, arg_cstr
, module_list
, false);
3898 if (num_matches
> 0) {
3899 for (size_t j
= 0; j
< num_matches
; ++j
) {
3900 Module
*module
= module_list
.GetModulePointerAtIndex(j
);
3902 if (LookupInModule(m_interpreter
, module
, result
, syntax_error
)) {
3903 result
.GetOutputStream().EOL();
3904 num_successful_lookups
++;
3909 result
.AppendWarningWithFormat(
3910 "Unable to find an image that matches '%s'.\n", arg_cstr
);
3914 if (num_successful_lookups
> 0)
3915 result
.SetStatus(eReturnStatusSuccessFinishResult
);
3917 result
.SetStatus(eReturnStatusFailed
);
3918 return result
.Succeeded();
3921 CommandOptions m_options
;
3924 #pragma mark CommandObjectMultiwordImageSearchPaths
3926 // CommandObjectMultiwordImageSearchPaths
3928 class CommandObjectTargetModulesImageSearchPaths
3929 : public CommandObjectMultiword
{
3931 CommandObjectTargetModulesImageSearchPaths(CommandInterpreter
&interpreter
)
3932 : CommandObjectMultiword(
3933 interpreter
, "target modules search-paths",
3934 "Commands for managing module search paths for a target.",
3935 "target modules search-paths <subcommand> [<subcommand-options>]") {
3937 "add", CommandObjectSP(
3938 new CommandObjectTargetModulesSearchPathsAdd(interpreter
)));
3940 "clear", CommandObjectSP(new CommandObjectTargetModulesSearchPathsClear(
3945 new CommandObjectTargetModulesSearchPathsInsert(interpreter
)));
3947 "list", CommandObjectSP(new CommandObjectTargetModulesSearchPathsList(
3950 "query", CommandObjectSP(new CommandObjectTargetModulesSearchPathsQuery(
3954 ~CommandObjectTargetModulesImageSearchPaths() override
= default;
3957 #pragma mark CommandObjectTargetModules
3959 // CommandObjectTargetModules
3961 class CommandObjectTargetModules
: public CommandObjectMultiword
{
3963 // Constructors and Destructors
3964 CommandObjectTargetModules(CommandInterpreter
&interpreter
)
3965 : CommandObjectMultiword(interpreter
, "target modules",
3966 "Commands for accessing information for one or "
3967 "more target modules.",
3968 "target modules <sub-command> ...") {
3970 "add", CommandObjectSP(new CommandObjectTargetModulesAdd(interpreter
)));
3971 LoadSubCommand("load", CommandObjectSP(new CommandObjectTargetModulesLoad(
3973 LoadSubCommand("dump", CommandObjectSP(new CommandObjectTargetModulesDump(
3975 LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetModulesList(
3979 CommandObjectSP(new CommandObjectTargetModulesLookup(interpreter
)));
3983 new CommandObjectTargetModulesImageSearchPaths(interpreter
)));
3986 CommandObjectSP(new CommandObjectTargetModulesShowUnwind(interpreter
)));
3989 ~CommandObjectTargetModules() override
= default;
3992 // For CommandObjectTargetModules only
3993 DISALLOW_COPY_AND_ASSIGN(CommandObjectTargetModules
);
3996 class CommandObjectTargetSymbolsAdd
: public CommandObjectParsed
{
3998 CommandObjectTargetSymbolsAdd(CommandInterpreter
&interpreter
)
3999 : CommandObjectParsed(
4000 interpreter
, "target symbols add",
4001 "Add a debug symbol file to one of the target's current modules by "
4002 "specifying a path to a debug symbols file, or using the options "
4003 "to specify a module to download symbols for.",
4004 "target symbols add <cmd-options> [<symfile>]",
4005 eCommandRequiresTarget
),
4008 LLDB_OPT_SET_1
, false, "shlib", 's',
4009 CommandCompletions::eModuleCompletion
, eArgTypeShlibName
,
4010 "Fullpath or basename for module to find debug symbols for."),
4011 m_current_frame_option(
4012 LLDB_OPT_SET_2
, false, "frame", 'F',
4013 "Locate the debug symbols the currently selected frame.", false,
4017 m_option_group
.Append(&m_uuid_option_group
, LLDB_OPT_SET_ALL
,
4019 m_option_group
.Append(&m_file_option
, LLDB_OPT_SET_ALL
, LLDB_OPT_SET_1
);
4020 m_option_group
.Append(&m_current_frame_option
, LLDB_OPT_SET_2
,
4022 m_option_group
.Finalize();
4025 ~CommandObjectTargetSymbolsAdd() override
= default;
4028 HandleArgumentCompletion(CompletionRequest
&request
,
4029 OptionElementVector
&opt_element_vector
) override
{
4030 CommandCompletions::InvokeCommonCompletionCallbacks(
4031 GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion
,
4035 Options
*GetOptions() override
{ return &m_option_group
; }
4038 bool AddModuleSymbols(Target
*target
, ModuleSpec
&module_spec
, bool &flush
,
4039 CommandReturnObject
&result
) {
4040 const FileSpec
&symbol_fspec
= module_spec
.GetSymbolFileSpec();
4041 if (!symbol_fspec
) {
4043 "one or more executable image paths must be specified");
4044 result
.SetStatus(eReturnStatusFailed
);
4048 char symfile_path
[PATH_MAX
];
4049 symbol_fspec
.GetPath(symfile_path
, sizeof(symfile_path
));
4051 if (!module_spec
.GetUUID().IsValid()) {
4052 if (!module_spec
.GetFileSpec() && !module_spec
.GetPlatformFileSpec())
4053 module_spec
.GetFileSpec().GetFilename() = symbol_fspec
.GetFilename();
4056 // We now have a module that represents a symbol file that can be used
4057 // for a module that might exist in the current target, so we need to
4058 // find that module in the target
4059 ModuleList matching_module_list
;
4061 size_t num_matches
= 0;
4062 // First extract all module specs from the symbol file
4063 lldb_private::ModuleSpecList symfile_module_specs
;
4064 if (ObjectFile::GetModuleSpecifications(module_spec
.GetSymbolFileSpec(),
4065 0, 0, symfile_module_specs
)) {
4066 // Now extract the module spec that matches the target architecture
4067 ModuleSpec target_arch_module_spec
;
4068 ModuleSpec symfile_module_spec
;
4069 target_arch_module_spec
.GetArchitecture() = target
->GetArchitecture();
4070 if (symfile_module_specs
.FindMatchingModuleSpec(target_arch_module_spec
,
4071 symfile_module_spec
)) {
4072 // See if it has a UUID?
4073 if (symfile_module_spec
.GetUUID().IsValid()) {
4074 // It has a UUID, look for this UUID in the target modules
4075 ModuleSpec symfile_uuid_module_spec
;
4076 symfile_uuid_module_spec
.GetUUID() = symfile_module_spec
.GetUUID();
4077 target
->GetImages().FindModules(symfile_uuid_module_spec
,
4078 matching_module_list
);
4079 num_matches
= matching_module_list
.GetSize();
4083 if (num_matches
== 0) {
4084 // No matches yet, iterate through the module specs to find a UUID
4085 // value that we can match up to an image in our target
4086 const size_t num_symfile_module_specs
=
4087 symfile_module_specs
.GetSize();
4088 for (size_t i
= 0; i
< num_symfile_module_specs
&& num_matches
== 0;
4090 if (symfile_module_specs
.GetModuleSpecAtIndex(
4091 i
, symfile_module_spec
)) {
4092 if (symfile_module_spec
.GetUUID().IsValid()) {
4093 // It has a UUID, look for this UUID in the target modules
4094 ModuleSpec symfile_uuid_module_spec
;
4095 symfile_uuid_module_spec
.GetUUID() =
4096 symfile_module_spec
.GetUUID();
4097 target
->GetImages().FindModules(symfile_uuid_module_spec
,
4098 matching_module_list
);
4099 num_matches
= matching_module_list
.GetSize();
4106 // Just try to match up the file by basename if we have no matches at
4108 if (num_matches
== 0) {
4109 target
->GetImages().FindModules(module_spec
, matching_module_list
);
4110 num_matches
= matching_module_list
.GetSize();
4113 while (num_matches
== 0) {
4114 ConstString
filename_no_extension(
4115 module_spec
.GetFileSpec().GetFileNameStrippingExtension());
4116 // Empty string returned, let's bail
4117 if (!filename_no_extension
)
4120 // Check if there was no extension to strip and the basename is the same
4121 if (filename_no_extension
== module_spec
.GetFileSpec().GetFilename())
4124 // Replace basename with one fewer extension
4125 module_spec
.GetFileSpec().GetFilename() = filename_no_extension
;
4126 target
->GetImages().FindModules(module_spec
, matching_module_list
);
4127 num_matches
= matching_module_list
.GetSize();
4130 if (num_matches
> 1) {
4131 result
.AppendErrorWithFormat("multiple modules match symbol file '%s', "
4132 "use the --uuid option to resolve the "
4135 } else if (num_matches
== 1) {
4136 ModuleSP
module_sp(matching_module_list
.GetModuleAtIndex(0));
4138 // The module has not yet created its symbol vendor, we can just give
4139 // the existing target module the symfile path to use for when it
4140 // decides to create it!
4141 module_sp
->SetSymbolFileFileSpec(symbol_fspec
);
4143 SymbolFile
*symbol_file
=
4144 module_sp
->GetSymbolFile(true, &result
.GetErrorStream());
4146 ObjectFile
*object_file
= symbol_file
->GetObjectFile();
4148 if (object_file
&& object_file
->GetFileSpec() == symbol_fspec
) {
4149 // Provide feedback that the symfile has been successfully added.
4150 const FileSpec
&module_fs
= module_sp
->GetFileSpec();
4151 result
.AppendMessageWithFormat(
4152 "symbol file '%s' has been added to '%s'\n", symfile_path
,
4153 module_fs
.GetPath().c_str());
4155 // Let clients know something changed in the module if it is
4157 ModuleList module_list
;
4158 module_list
.Append(module_sp
);
4159 target
->SymbolsDidLoad(module_list
);
4161 // Make sure we load any scripting resources that may be embedded
4162 // in the debug info files in case the platform supports that.
4164 StreamString feedback_stream
;
4165 module_sp
->LoadScriptingResourceInTarget(target
, error
,
4167 if (error
.Fail() && error
.AsCString())
4168 result
.AppendWarningWithFormat(
4169 "unable to load scripting data for module %s - error "
4171 module_sp
->GetFileSpec()
4172 .GetFileNameStrippingExtension()
4175 else if (feedback_stream
.GetSize())
4176 result
.AppendWarningWithFormat("%s", feedback_stream
.GetData());
4179 result
.SetStatus(eReturnStatusSuccessFinishResult
);
4183 // Clear the symbol file spec if anything went wrong
4184 module_sp
->SetSymbolFileFileSpec(FileSpec());
4187 namespace fs
= llvm::sys::fs
;
4188 StreamString ss_symfile_uuid
;
4189 if (module_spec
.GetUUID().IsValid()) {
4190 ss_symfile_uuid
<< " (";
4191 module_spec
.GetUUID().Dump(&ss_symfile_uuid
);
4192 ss_symfile_uuid
<< ')';
4194 result
.AppendErrorWithFormat(
4195 "symbol file '%s'%s does not match any existing module%s\n",
4196 symfile_path
, ss_symfile_uuid
.GetData(),
4197 !fs::is_regular_file(symbol_fspec
.GetPath())
4198 ? "\n please specify the full path to the symbol file"
4200 result
.SetStatus(eReturnStatusFailed
);
4204 bool DoExecute(Args
&args
, CommandReturnObject
&result
) override
{
4205 Target
*target
= m_exe_ctx
.GetTargetPtr();
4206 result
.SetStatus(eReturnStatusFailed
);
4208 ModuleSpec module_spec
;
4209 const bool uuid_option_set
=
4210 m_uuid_option_group
.GetOptionValue().OptionWasSet();
4211 const bool file_option_set
= m_file_option
.GetOptionValue().OptionWasSet();
4212 const bool frame_option_set
=
4213 m_current_frame_option
.GetOptionValue().OptionWasSet();
4214 const size_t argc
= args
.GetArgumentCount();
4217 if (uuid_option_set
|| file_option_set
|| frame_option_set
) {
4218 bool success
= false;
4219 bool error_set
= false;
4220 if (frame_option_set
) {
4221 Process
*process
= m_exe_ctx
.GetProcessPtr();
4223 const StateType process_state
= process
->GetState();
4224 if (StateIsStoppedState(process_state
, true)) {
4225 StackFrame
*frame
= m_exe_ctx
.GetFramePtr();
4227 ModuleSP
frame_module_sp(
4228 frame
->GetSymbolContext(eSymbolContextModule
).module_sp
);
4229 if (frame_module_sp
) {
4230 if (FileSystem::Instance().Exists(
4231 frame_module_sp
->GetPlatformFileSpec())) {
4232 module_spec
.GetArchitecture() =
4233 frame_module_sp
->GetArchitecture();
4234 module_spec
.GetFileSpec() =
4235 frame_module_sp
->GetPlatformFileSpec();
4237 module_spec
.GetUUID() = frame_module_sp
->GetUUID();
4238 success
= module_spec
.GetUUID().IsValid() ||
4239 module_spec
.GetFileSpec();
4241 result
.AppendError("frame has no module");
4245 result
.AppendError("invalid current frame");
4249 result
.AppendErrorWithFormat("process is not stopped: %s",
4250 StateAsCString(process_state
));
4255 "a process must exist in order to use the --frame option");
4259 if (uuid_option_set
) {
4260 module_spec
.GetUUID() =
4261 m_uuid_option_group
.GetOptionValue().GetCurrentValue();
4262 success
|= module_spec
.GetUUID().IsValid();
4263 } else if (file_option_set
) {
4264 module_spec
.GetFileSpec() =
4265 m_file_option
.GetOptionValue().GetCurrentValue();
4267 target
->GetImages().FindFirstModule(module_spec
));
4269 module_spec
.GetFileSpec() = module_sp
->GetFileSpec();
4270 module_spec
.GetPlatformFileSpec() =
4271 module_sp
->GetPlatformFileSpec();
4272 module_spec
.GetUUID() = module_sp
->GetUUID();
4273 module_spec
.GetArchitecture() = module_sp
->GetArchitecture();
4275 module_spec
.GetArchitecture() = target
->GetArchitecture();
4277 success
|= module_spec
.GetUUID().IsValid() ||
4278 FileSystem::Instance().Exists(module_spec
.GetFileSpec());
4283 if (Symbols::DownloadObjectAndSymbolFile(module_spec
)) {
4284 if (module_spec
.GetSymbolFileSpec())
4285 success
= AddModuleSymbols(target
, module_spec
, flush
, result
);
4289 if (!success
&& !error_set
) {
4290 StreamString error_strm
;
4291 if (uuid_option_set
) {
4292 error_strm
.PutCString("unable to find debug symbols for UUID ");
4293 module_spec
.GetUUID().Dump(&error_strm
);
4294 } else if (file_option_set
) {
4295 error_strm
.PutCString(
4296 "unable to find debug symbols for the executable file ");
4297 error_strm
<< module_spec
.GetFileSpec();
4298 } else if (frame_option_set
) {
4299 error_strm
.PutCString(
4300 "unable to find debug symbols for the current frame");
4302 result
.AppendError(error_strm
.GetString());
4305 result
.AppendError("one or more symbol file paths must be specified, "
4306 "or options must be specified");
4309 if (uuid_option_set
) {
4310 result
.AppendError("specify either one or more paths to symbol files "
4311 "or use the --uuid option without arguments");
4312 } else if (frame_option_set
) {
4313 result
.AppendError("specify either one or more paths to symbol files "
4314 "or use the --frame option without arguments");
4315 } else if (file_option_set
&& argc
> 1) {
4316 result
.AppendError("specify at most one symbol file path when "
4317 "--shlib option is set");
4319 PlatformSP
platform_sp(target
->GetPlatform());
4321 for (auto &entry
: args
.entries()) {
4322 if (!entry
.ref().empty()) {
4323 auto &symbol_file_spec
= module_spec
.GetSymbolFileSpec();
4324 symbol_file_spec
.SetFile(entry
.ref(), FileSpec::Style::native
);
4325 FileSystem::Instance().Resolve(symbol_file_spec
);
4326 if (file_option_set
) {
4327 module_spec
.GetFileSpec() =
4328 m_file_option
.GetOptionValue().GetCurrentValue();
4331 FileSpec symfile_spec
;
4333 ->ResolveSymbolFile(*target
, module_spec
, symfile_spec
)
4335 module_spec
.GetSymbolFileSpec() = symfile_spec
;
4339 bool symfile_exists
=
4340 FileSystem::Instance().Exists(module_spec
.GetSymbolFileSpec());
4342 if (symfile_exists
) {
4343 if (!AddModuleSymbols(target
, module_spec
, flush
, result
))
4346 std::string resolved_symfile_path
=
4347 module_spec
.GetSymbolFileSpec().GetPath();
4348 if (resolved_symfile_path
!= entry
.ref()) {
4349 result
.AppendErrorWithFormat(
4350 "invalid module path '%s' with resolved path '%s'\n",
4351 entry
.c_str(), resolved_symfile_path
.c_str());
4354 result
.AppendErrorWithFormat("invalid module path '%s'\n",
4364 Process
*process
= m_exe_ctx
.GetProcessPtr();
4368 return result
.Succeeded();
4371 OptionGroupOptions m_option_group
;
4372 OptionGroupUUID m_uuid_option_group
;
4373 OptionGroupFile m_file_option
;
4374 OptionGroupBoolean m_current_frame_option
;
4377 #pragma mark CommandObjectTargetSymbols
4379 // CommandObjectTargetSymbols
4381 class CommandObjectTargetSymbols
: public CommandObjectMultiword
{
4383 // Constructors and Destructors
4384 CommandObjectTargetSymbols(CommandInterpreter
&interpreter
)
4385 : CommandObjectMultiword(
4386 interpreter
, "target symbols",
4387 "Commands for adding and managing debug symbol files.",
4388 "target symbols <sub-command> ...") {
4390 "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter
)));
4393 ~CommandObjectTargetSymbols() override
= default;
4396 // For CommandObjectTargetModules only
4397 DISALLOW_COPY_AND_ASSIGN(CommandObjectTargetSymbols
);
4400 #pragma mark CommandObjectTargetStopHookAdd
4402 // CommandObjectTargetStopHookAdd
4403 #define LLDB_OPTIONS_target_stop_hook_add
4404 #include "CommandOptions.inc"
4406 class CommandObjectTargetStopHookAdd
: public CommandObjectParsed
,
4407 public IOHandlerDelegateMultiline
{
4409 class CommandOptions
: public Options
{
4412 : Options(), m_line_start(0), m_line_end(UINT_MAX
),
4413 m_func_name_type_mask(eFunctionNameTypeAuto
),
4414 m_sym_ctx_specified(false), m_thread_specified(false),
4415 m_use_one_liner(false), m_one_liner() {}
4417 ~CommandOptions() override
= default;
4419 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
4420 return llvm::makeArrayRef(g_target_stop_hook_add_options
);
4423 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_arg
,
4424 ExecutionContext
*execution_context
) override
{
4426 const int short_option
= m_getopt_table
[option_idx
].val
;
4428 switch (short_option
) {
4430 m_class_name
= option_arg
;
4431 m_sym_ctx_specified
= true;
4435 if (option_arg
.getAsInteger(0, m_line_end
)) {
4436 error
.SetErrorStringWithFormat("invalid end line number: \"%s\"",
4437 option_arg
.str().c_str());
4440 m_sym_ctx_specified
= true;
4444 bool value
, success
;
4445 value
= OptionArgParser::ToBoolean(option_arg
, false, &success
);
4447 m_auto_continue
= value
;
4449 error
.SetErrorStringWithFormat(
4450 "invalid boolean value '%s' passed for -G option",
4451 option_arg
.str().c_str());
4454 if (option_arg
.getAsInteger(0, m_line_start
)) {
4455 error
.SetErrorStringWithFormat("invalid start line number: \"%s\"",
4456 option_arg
.str().c_str());
4459 m_sym_ctx_specified
= true;
4463 m_no_inlines
= true;
4467 m_function_name
= option_arg
;
4468 m_func_name_type_mask
|= eFunctionNameTypeAuto
;
4469 m_sym_ctx_specified
= true;
4473 m_file_name
= option_arg
;
4474 m_sym_ctx_specified
= true;
4478 m_module_name
= option_arg
;
4479 m_sym_ctx_specified
= true;
4483 if (option_arg
.getAsInteger(0, m_thread_id
))
4484 error
.SetErrorStringWithFormat("invalid thread id string '%s'",
4485 option_arg
.str().c_str());
4486 m_thread_specified
= true;
4490 m_thread_name
= option_arg
;
4491 m_thread_specified
= true;
4495 m_queue_name
= option_arg
;
4496 m_thread_specified
= true;
4500 if (option_arg
.getAsInteger(0, m_thread_index
))
4501 error
.SetErrorStringWithFormat("invalid thread index string '%s'",
4502 option_arg
.str().c_str());
4503 m_thread_specified
= true;
4507 m_use_one_liner
= true;
4508 m_one_liner
.push_back(option_arg
);
4512 llvm_unreachable("Unimplemented option");
4517 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
4518 m_class_name
.clear();
4519 m_function_name
.clear();
4521 m_line_end
= UINT_MAX
;
4522 m_file_name
.clear();
4523 m_module_name
.clear();
4524 m_func_name_type_mask
= eFunctionNameTypeAuto
;
4525 m_thread_id
= LLDB_INVALID_THREAD_ID
;
4526 m_thread_index
= UINT32_MAX
;
4527 m_thread_name
.clear();
4528 m_queue_name
.clear();
4530 m_no_inlines
= false;
4531 m_sym_ctx_specified
= false;
4532 m_thread_specified
= false;
4534 m_use_one_liner
= false;
4535 m_one_liner
.clear();
4536 m_auto_continue
= false;
4539 std::string m_class_name
;
4540 std::string m_function_name
;
4541 uint32_t m_line_start
;
4542 uint32_t m_line_end
;
4543 std::string m_file_name
;
4544 std::string m_module_name
;
4545 uint32_t m_func_name_type_mask
; // A pick from lldb::FunctionNameType.
4546 lldb::tid_t m_thread_id
;
4547 uint32_t m_thread_index
;
4548 std::string m_thread_name
;
4549 std::string m_queue_name
;
4550 bool m_sym_ctx_specified
;
4552 bool m_thread_specified
;
4553 // Instance variables to hold the values for one_liner options.
4554 bool m_use_one_liner
;
4555 std::vector
<std::string
> m_one_liner
;
4556 bool m_auto_continue
;
4559 CommandObjectTargetStopHookAdd(CommandInterpreter
&interpreter
)
4560 : CommandObjectParsed(interpreter
, "target stop-hook add",
4561 "Add a hook to be executed when the target stops.",
4562 "target stop-hook add"),
4563 IOHandlerDelegateMultiline("DONE",
4564 IOHandlerDelegate::Completion::LLDBCommand
),
4567 ~CommandObjectTargetStopHookAdd() override
= default;
4569 Options
*GetOptions() override
{ return &m_options
; }
4572 void IOHandlerActivated(IOHandler
&io_handler
, bool interactive
) override
{
4573 StreamFileSP
output_sp(io_handler
.GetOutputStreamFileSP());
4574 if (output_sp
&& interactive
) {
4575 output_sp
->PutCString(
4576 "Enter your stop hook command(s). Type 'DONE' to end.\n");
4581 void IOHandlerInputComplete(IOHandler
&io_handler
,
4582 std::string
&line
) override
{
4583 if (m_stop_hook_sp
) {
4585 StreamFileSP
error_sp(io_handler
.GetErrorStreamFileSP());
4587 error_sp
->Printf("error: stop hook #%" PRIu64
4588 " aborted, no commands.\n",
4589 m_stop_hook_sp
->GetID());
4592 Target
*target
= GetDebugger().GetSelectedTarget().get();
4594 target
->RemoveStopHookByID(m_stop_hook_sp
->GetID());
4596 m_stop_hook_sp
->GetCommandPointer()->SplitIntoLines(line
);
4597 StreamFileSP
output_sp(io_handler
.GetOutputStreamFileSP());
4599 output_sp
->Printf("Stop hook #%" PRIu64
" added.\n",
4600 m_stop_hook_sp
->GetID());
4604 m_stop_hook_sp
.reset();
4606 io_handler
.SetIsDone(true);
4609 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
4610 m_stop_hook_sp
.reset();
4612 Target
&target
= GetSelectedOrDummyTarget();
4613 Target::StopHookSP new_hook_sp
= target
.CreateStopHook();
4615 // First step, make the specifier.
4616 std::unique_ptr
<SymbolContextSpecifier
> specifier_up
;
4617 if (m_options
.m_sym_ctx_specified
) {
4619 new SymbolContextSpecifier(GetDebugger().GetSelectedTarget()));
4621 if (!m_options
.m_module_name
.empty()) {
4622 specifier_up
->AddSpecification(
4623 m_options
.m_module_name
.c_str(),
4624 SymbolContextSpecifier::eModuleSpecified
);
4627 if (!m_options
.m_class_name
.empty()) {
4628 specifier_up
->AddSpecification(
4629 m_options
.m_class_name
.c_str(),
4630 SymbolContextSpecifier::eClassOrNamespaceSpecified
);
4633 if (!m_options
.m_file_name
.empty()) {
4634 specifier_up
->AddSpecification(m_options
.m_file_name
.c_str(),
4635 SymbolContextSpecifier::eFileSpecified
);
4638 if (m_options
.m_line_start
!= 0) {
4639 specifier_up
->AddLineSpecification(
4640 m_options
.m_line_start
,
4641 SymbolContextSpecifier::eLineStartSpecified
);
4644 if (m_options
.m_line_end
!= UINT_MAX
) {
4645 specifier_up
->AddLineSpecification(
4646 m_options
.m_line_end
, SymbolContextSpecifier::eLineEndSpecified
);
4649 if (!m_options
.m_function_name
.empty()) {
4650 specifier_up
->AddSpecification(
4651 m_options
.m_function_name
.c_str(),
4652 SymbolContextSpecifier::eFunctionSpecified
);
4657 new_hook_sp
->SetSpecifier(specifier_up
.release());
4659 // Next see if any of the thread options have been entered:
4661 if (m_options
.m_thread_specified
) {
4662 ThreadSpec
*thread_spec
= new ThreadSpec();
4664 if (m_options
.m_thread_id
!= LLDB_INVALID_THREAD_ID
) {
4665 thread_spec
->SetTID(m_options
.m_thread_id
);
4668 if (m_options
.m_thread_index
!= UINT32_MAX
)
4669 thread_spec
->SetIndex(m_options
.m_thread_index
);
4671 if (!m_options
.m_thread_name
.empty())
4672 thread_spec
->SetName(m_options
.m_thread_name
.c_str());
4674 if (!m_options
.m_queue_name
.empty())
4675 thread_spec
->SetQueueName(m_options
.m_queue_name
.c_str());
4677 new_hook_sp
->SetThreadSpecifier(thread_spec
);
4680 new_hook_sp
->SetAutoContinue(m_options
.m_auto_continue
);
4681 if (m_options
.m_use_one_liner
) {
4683 for (auto cmd
: m_options
.m_one_liner
)
4684 new_hook_sp
->GetCommandPointer()->AppendString(cmd
.c_str());
4685 result
.AppendMessageWithFormat("Stop hook #%" PRIu64
" added.\n",
4686 new_hook_sp
->GetID());
4688 m_stop_hook_sp
= new_hook_sp
;
4689 m_interpreter
.GetLLDBCommandsFromIOHandler("> ", // Prompt
4690 *this); // IOHandlerDelegate
4692 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
4694 return result
.Succeeded();
4698 CommandOptions m_options
;
4699 Target::StopHookSP m_stop_hook_sp
;
4702 #pragma mark CommandObjectTargetStopHookDelete
4704 // CommandObjectTargetStopHookDelete
4706 class CommandObjectTargetStopHookDelete
: public CommandObjectParsed
{
4708 CommandObjectTargetStopHookDelete(CommandInterpreter
&interpreter
)
4709 : CommandObjectParsed(interpreter
, "target stop-hook delete",
4710 "Delete a stop-hook.",
4711 "target stop-hook delete [<idx>]") {}
4713 ~CommandObjectTargetStopHookDelete() override
= default;
4716 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
4717 Target
&target
= GetSelectedOrDummyTarget();
4718 // FIXME: see if we can use the breakpoint id style parser?
4719 size_t num_args
= command
.GetArgumentCount();
4720 if (num_args
== 0) {
4721 if (!m_interpreter
.Confirm("Delete all stop hooks?", true)) {
4722 result
.SetStatus(eReturnStatusFailed
);
4725 target
.RemoveAllStopHooks();
4729 for (size_t i
= 0; i
< num_args
; i
++) {
4730 lldb::user_id_t user_id
= StringConvert::ToUInt32(
4731 command
.GetArgumentAtIndex(i
), 0, 0, &success
);
4733 result
.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4734 command
.GetArgumentAtIndex(i
));
4735 result
.SetStatus(eReturnStatusFailed
);
4738 success
= target
.RemoveStopHookByID(user_id
);
4740 result
.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4741 command
.GetArgumentAtIndex(i
));
4742 result
.SetStatus(eReturnStatusFailed
);
4747 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
4748 return result
.Succeeded();
4752 #pragma mark CommandObjectTargetStopHookEnableDisable
4754 // CommandObjectTargetStopHookEnableDisable
4756 class CommandObjectTargetStopHookEnableDisable
: public CommandObjectParsed
{
4758 CommandObjectTargetStopHookEnableDisable(CommandInterpreter
&interpreter
,
4759 bool enable
, const char *name
,
4760 const char *help
, const char *syntax
)
4761 : CommandObjectParsed(interpreter
, name
, help
, syntax
), m_enable(enable
) {
4764 ~CommandObjectTargetStopHookEnableDisable() override
= default;
4767 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
4768 Target
&target
= GetSelectedOrDummyTarget();
4769 // FIXME: see if we can use the breakpoint id style parser?
4770 size_t num_args
= command
.GetArgumentCount();
4773 if (num_args
== 0) {
4774 target
.SetAllStopHooksActiveState(m_enable
);
4776 for (size_t i
= 0; i
< num_args
; i
++) {
4777 lldb::user_id_t user_id
= StringConvert::ToUInt32(
4778 command
.GetArgumentAtIndex(i
), 0, 0, &success
);
4780 result
.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4781 command
.GetArgumentAtIndex(i
));
4782 result
.SetStatus(eReturnStatusFailed
);
4785 success
= target
.SetStopHookActiveStateByID(user_id
, m_enable
);
4787 result
.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4788 command
.GetArgumentAtIndex(i
));
4789 result
.SetStatus(eReturnStatusFailed
);
4794 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
4795 return result
.Succeeded();
4802 #pragma mark CommandObjectTargetStopHookList
4804 // CommandObjectTargetStopHookList
4806 class CommandObjectTargetStopHookList
: public CommandObjectParsed
{
4808 CommandObjectTargetStopHookList(CommandInterpreter
&interpreter
)
4809 : CommandObjectParsed(interpreter
, "target stop-hook list",
4810 "List all stop-hooks.",
4811 "target stop-hook list [<type>]") {}
4813 ~CommandObjectTargetStopHookList() override
= default;
4816 bool DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
4817 Target
&target
= GetSelectedOrDummyTarget();
4819 size_t num_hooks
= target
.GetNumStopHooks();
4820 if (num_hooks
== 0) {
4821 result
.GetOutputStream().PutCString("No stop hooks.\n");
4823 for (size_t i
= 0; i
< num_hooks
; i
++) {
4824 Target::StopHookSP this_hook
= target
.GetStopHookAtIndex(i
);
4826 result
.GetOutputStream().PutCString("\n");
4827 this_hook
->GetDescription(&(result
.GetOutputStream()),
4828 eDescriptionLevelFull
);
4831 result
.SetStatus(eReturnStatusSuccessFinishResult
);
4832 return result
.Succeeded();
4836 #pragma mark CommandObjectMultiwordTargetStopHooks
4838 // CommandObjectMultiwordTargetStopHooks
4840 class CommandObjectMultiwordTargetStopHooks
: public CommandObjectMultiword
{
4842 CommandObjectMultiwordTargetStopHooks(CommandInterpreter
&interpreter
)
4843 : CommandObjectMultiword(
4844 interpreter
, "target stop-hook",
4845 "Commands for operating on debugger target stop-hooks.",
4846 "target stop-hook <subcommand> [<subcommand-options>]") {
4847 LoadSubCommand("add", CommandObjectSP(
4848 new CommandObjectTargetStopHookAdd(interpreter
)));
4851 CommandObjectSP(new CommandObjectTargetStopHookDelete(interpreter
)));
4852 LoadSubCommand("disable",
4853 CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
4854 interpreter
, false, "target stop-hook disable [<id>]",
4855 "Disable a stop-hook.", "target stop-hook disable")));
4856 LoadSubCommand("enable",
4857 CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
4858 interpreter
, true, "target stop-hook enable [<id>]",
4859 "Enable a stop-hook.", "target stop-hook enable")));
4860 LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetStopHookList(
4864 ~CommandObjectMultiwordTargetStopHooks() override
= default;
4867 #pragma mark CommandObjectMultiwordTarget
4869 // CommandObjectMultiwordTarget
4871 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget(
4872 CommandInterpreter
&interpreter
)
4873 : CommandObjectMultiword(interpreter
, "target",
4874 "Commands for operating on debugger targets.",
4875 "target <subcommand> [<subcommand-options>]") {
4876 LoadSubCommand("create",
4877 CommandObjectSP(new CommandObjectTargetCreate(interpreter
)));
4878 LoadSubCommand("delete",
4879 CommandObjectSP(new CommandObjectTargetDelete(interpreter
)));
4880 LoadSubCommand("list",
4881 CommandObjectSP(new CommandObjectTargetList(interpreter
)));
4882 LoadSubCommand("select",
4883 CommandObjectSP(new CommandObjectTargetSelect(interpreter
)));
4886 CommandObjectSP(new CommandObjectMultiwordTargetStopHooks(interpreter
)));
4887 LoadSubCommand("modules",
4888 CommandObjectSP(new CommandObjectTargetModules(interpreter
)));
4889 LoadSubCommand("symbols",
4890 CommandObjectSP(new CommandObjectTargetSymbols(interpreter
)));
4891 LoadSubCommand("variable",
4892 CommandObjectSP(new CommandObjectTargetVariable(interpreter
)));
4895 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget() = default;