LLDB mainline
CommandObjectTarget.cpp
Go to the documentation of this file.
1//===-- CommandObjectTarget.cpp -------------------------------------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
10
11#include "lldb/Core/Debugger.h"
12#include "lldb/Core/IOHandler.h"
13#include "lldb/Core/Module.h"
15#include "lldb/Core/Section.h"
43#include "lldb/Target/ABI.h"
44#include "lldb/Target/Process.h"
48#include "lldb/Target/Thread.h"
50#include "lldb/Utility/Args.h"
54#include "lldb/Utility/State.h"
55#include "lldb/Utility/Timer.h"
58
59#include "clang/CodeGen/ObjectFilePCHContainerOperations.h"
60#include "clang/Frontend/CompilerInstance.h"
61#include "clang/Frontend/CompilerInvocation.h"
62#include "clang/Frontend/FrontendActions.h"
63#include "llvm/ADT/ScopeExit.h"
64#include "llvm/Support/FileSystem.h"
65#include "llvm/Support/FormatAdapters.h"
66
67
68using namespace lldb;
69using namespace lldb_private;
70
71static void DumpTargetInfo(uint32_t target_idx, Target *target,
72 const char *prefix_cstr,
73 bool show_stopped_process_status, Stream &strm) {
74 const ArchSpec &target_arch = target->GetArchitecture();
75
76 Module *exe_module = target->GetExecutableModulePointer();
77 char exe_path[PATH_MAX];
78 bool exe_valid = false;
79 if (exe_module)
80 exe_valid = exe_module->GetFileSpec().GetPath(exe_path, sizeof(exe_path));
81
82 if (!exe_valid)
83 ::strcpy(exe_path, "<none>");
84
85 strm.Printf("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx,
86 exe_path);
87
88 uint32_t properties = 0;
89 if (target_arch.IsValid()) {
90 strm.Printf("%sarch=", properties++ > 0 ? ", " : " ( ");
91 target_arch.DumpTriple(strm.AsRawOstream());
92 properties++;
93 }
94 PlatformSP platform_sp(target->GetPlatform());
95 if (platform_sp)
96 strm.Format("{0}platform={1}", properties++ > 0 ? ", " : " ( ",
97 platform_sp->GetName());
98
99 ProcessSP process_sp(target->GetProcessSP());
100 bool show_process_status = false;
101 if (process_sp) {
102 lldb::pid_t pid = process_sp->GetID();
103 StateType state = process_sp->GetState();
104 if (show_stopped_process_status)
105 show_process_status = StateIsStoppedState(state, true);
106 const char *state_cstr = StateAsCString(state);
107 if (pid != LLDB_INVALID_PROCESS_ID)
108 strm.Printf("%spid=%" PRIu64, properties++ > 0 ? ", " : " ( ", pid);
109 strm.Printf("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
110 }
111 if (properties > 0)
112 strm.PutCString(" )\n");
113 else
114 strm.EOL();
115 if (show_process_status) {
116 const bool only_threads_with_stop_reason = true;
117 const uint32_t start_frame = 0;
118 const uint32_t num_frames = 1;
119 const uint32_t num_frames_with_source = 1;
120 const bool stop_format = false;
121 process_sp->GetStatus(strm);
122 process_sp->GetThreadStatus(strm, only_threads_with_stop_reason,
123 start_frame, num_frames, num_frames_with_source,
124 stop_format);
125 }
126}
127
129 bool show_stopped_process_status, Stream &strm) {
130 const uint32_t num_targets = target_list.GetNumTargets();
131 if (num_targets) {
132 TargetSP selected_target_sp(target_list.GetSelectedTarget());
133 strm.PutCString("Current targets:\n");
134 for (uint32_t i = 0; i < num_targets; ++i) {
135 TargetSP target_sp(target_list.GetTargetAtIndex(i));
136 if (target_sp) {
137 bool is_selected = target_sp.get() == selected_target_sp.get();
138 DumpTargetInfo(i, target_sp.get(), is_selected ? "* " : " ",
139 show_stopped_process_status, strm);
140 }
141 }
142 }
143 return num_targets;
144}
145
146#define LLDB_OPTIONS_target_dependents
147#include "CommandOptions.inc"
148
150public:
152
153 ~OptionGroupDependents() override = default;
154
155 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
156 return llvm::ArrayRef(g_target_dependents_options);
157 }
158
159 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
160 ExecutionContext *execution_context) override {
162
163 // For compatibility no value means don't load dependents.
164 if (option_value.empty()) {
166 return error;
167 }
168
169 const char short_option =
170 g_target_dependents_options[option_idx].short_option;
171 if (short_option == 'd') {
172 LoadDependentFiles tmp_load_dependents;
174 option_value, g_target_dependents_options[option_idx].enum_values, 0,
175 error);
176 if (error.Success())
177 m_load_dependent_files = tmp_load_dependents;
178 } else {
179 error.SetErrorStringWithFormat("unrecognized short option '%c'",
180 short_option);
181 }
182
183 return error;
184 }
185
186 Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete;
187
188 void OptionParsingStarting(ExecutionContext *execution_context) override {
190 }
191
193
194private:
198};
199
200#pragma mark CommandObjectTargetCreate
201
203public:
206 interpreter, "target create",
207 "Create a target using the argument as the main executable.",
208 nullptr),
209 m_platform_options(true), // Include the --platform option.
210 m_core_file(LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename,
211 "Fullpath to a core file to use for this target."),
212 m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
214 "Fullpath to a stand alone debug "
215 "symbols file for when debug symbols "
216 "are not in the executable."),
218 LLDB_OPT_SET_1, false, "remote-file", 'r', 0, eArgTypeFilename,
219 "Fullpath to the file on the remote host if debugging remotely.") {
221 CommandArgumentData file_arg;
222
223 // Define the first (and only) variant of this arg.
224 file_arg.arg_type = eArgTypeFilename;
226
227 // There is only one variant this argument could be; put it into the
228 // argument entry.
229 arg.push_back(file_arg);
230
231 // Push the data for the first argument into the m_arguments vector.
232 m_arguments.push_back(arg);
233
241 }
242
243 ~CommandObjectTargetCreate() override = default;
244
245 Options *GetOptions() override { return &m_option_group; }
246
247 void
249 OptionElementVector &opt_element_vector) override {
252 request, nullptr);
253 }
254
255protected:
256 bool DoExecute(Args &command, CommandReturnObject &result) override {
257 const size_t argc = command.GetArgumentCount();
260
261 if (core_file) {
262 auto file = FileSystem::Instance().Open(
264
265 if (!file) {
266 result.AppendErrorWithFormatv("Cannot open '{0}': {1}.",
267 core_file.GetPath(),
268 llvm::toString(file.takeError()));
269 return false;
270 }
271 }
272
273 if (argc == 1 || core_file || remote_file) {
275 if (symfile) {
276 auto file = FileSystem::Instance().Open(
278
279 if (!file) {
280 result.AppendErrorWithFormatv("Cannot open '{0}': {1}.",
281 symfile.GetPath(),
282 llvm::toString(file.takeError()));
283 return false;
284 }
285 }
286
287 const char *file_path = command.GetArgumentAtIndex(0);
288 LLDB_SCOPED_TIMERF("(lldb) target create '%s'", file_path);
289
290 bool must_set_platform_path = false;
291
292 Debugger &debugger = GetDebugger();
293
294 TargetSP target_sp;
295 llvm::StringRef arch_cstr = m_arch_option.GetArchitectureName();
297 debugger, file_path, arch_cstr,
299 target_sp));
300
301 if (!target_sp) {
302 result.AppendError(error.AsCString());
303 return false;
304 }
305
306 auto on_error = llvm::make_scope_exit(
307 [&target_list = debugger.GetTargetList(), &target_sp]() {
308 target_list.DeleteTarget(target_sp);
309 });
310
311 // Only get the platform after we create the target because we might
312 // have switched platforms depending on what the arguments were to
313 // CreateTarget() we can't rely on the selected platform.
314
315 PlatformSP platform_sp = target_sp->GetPlatform();
316
317 FileSpec file_spec;
318 if (file_path) {
319 file_spec.SetFile(file_path, FileSpec::Style::native);
320 FileSystem::Instance().Resolve(file_spec);
321
322 // Try to resolve the exe based on PATH and/or platform-specific
323 // suffixes, but only if using the host platform.
324 if (platform_sp && platform_sp->IsHost() &&
325 !FileSystem::Instance().Exists(file_spec))
327 }
328
329 if (remote_file) {
330 if (platform_sp) {
331 // I have a remote file.. two possible cases
332 if (file_spec && FileSystem::Instance().Exists(file_spec)) {
333 // if the remote file does not exist, push it there
334 if (!platform_sp->GetFileExists(remote_file)) {
335 Status err = platform_sp->PutFile(file_spec, remote_file);
336 if (err.Fail()) {
337 result.AppendError(err.AsCString());
338 return false;
339 }
340 }
341 } else {
342 // there is no local file and we need one
343 // in order to make the remote ---> local transfer we need a
344 // platform
345 // TODO: if the user has passed in a --platform argument, use it
346 // to fetch the right platform
347 if (file_path) {
348 // copy the remote file to the local file
349 Status err = platform_sp->GetFile(remote_file, file_spec);
350 if (err.Fail()) {
351 result.AppendError(err.AsCString());
352 return false;
353 }
354 } else {
355 // If the remote file exists, we can debug reading that out of
356 // memory. If the platform is already connected to an lldb-server
357 // then we can at least check the file exists remotely. Otherwise
358 // we'll just have to trust that it will be there when we do
359 // process connect.
360 // I don't do this for the host platform because it seems odd to
361 // support supplying a remote file but no local file for a local
362 // debug session.
363 if (platform_sp->IsHost()) {
364 result.AppendError("Supply a local file, not a remote file, "
365 "when debugging on the host.");
366 return false;
367 }
368 if (platform_sp->IsConnected() && !platform_sp->GetFileExists(remote_file)) {
369 result.AppendError("remote --> local transfer without local "
370 "path is not implemented yet");
371 return false;
372 }
373 // Since there's only a remote file, we need to set the executable
374 // file spec to the remote one.
375 ProcessLaunchInfo launch_info = target_sp->GetProcessLaunchInfo();
376 launch_info.SetExecutableFile(FileSpec(remote_file), true);
377 target_sp->SetProcessLaunchInfo(launch_info);
378 }
379 }
380 } else {
381 result.AppendError("no platform found for target");
382 return false;
383 }
384 }
385
386 if (symfile || remote_file) {
387 ModuleSP module_sp(target_sp->GetExecutableModule());
388 if (module_sp) {
389 if (symfile)
390 module_sp->SetSymbolFileFileSpec(symfile);
391 if (remote_file) {
392 std::string remote_path = remote_file.GetPath();
393 target_sp->SetArg0(remote_path.c_str());
394 module_sp->SetPlatformFileSpec(remote_file);
395 }
396 }
397 }
398
399 if (must_set_platform_path) {
400 ModuleSpec main_module_spec(file_spec);
401 ModuleSP module_sp =
402 target_sp->GetOrCreateModule(main_module_spec, true /* notify */);
403 if (module_sp)
404 module_sp->SetPlatformFileSpec(remote_file);
405 }
406
407 if (core_file) {
408 FileSpec core_file_dir;
409 core_file_dir.SetDirectory(core_file.GetDirectory());
410 target_sp->AppendExecutableSearchPaths(core_file_dir);
411
412 ProcessSP process_sp(target_sp->CreateProcess(
413 GetDebugger().GetListener(), llvm::StringRef(), &core_file, false));
414
415 if (process_sp) {
416 // Seems weird that we Launch a core file, but that is what we
417 // do!
418 error = process_sp->LoadCore();
419
420 if (error.Fail()) {
421 result.AppendError(
422 error.AsCString("can't find plug-in for core file"));
423 return false;
424 } else {
426 "Core file '{0}' ({1}) was loaded.\n", core_file.GetPath(),
427 target_sp->GetArchitecture().GetArchitectureName());
429 on_error.release();
430 }
431 } else {
433 "Unable to find process plug-in for core file '{0}'\n",
434 core_file.GetPath());
435 }
436 } else {
438 "Current executable set to '%s' (%s).\n",
439 file_spec.GetPath().c_str(),
440 target_sp->GetArchitecture().GetArchitectureName());
442 on_error.release();
443 }
444 } else {
445 result.AppendErrorWithFormat("'%s' takes exactly one executable path "
446 "argument, or use the --core option.\n",
447 m_cmd_name.c_str());
448 }
449
450 return result.Succeeded();
451 }
452
453private:
461};
462
463#pragma mark CommandObjectTargetList
464
466public:
469 interpreter, "target list",
470 "List all current targets in the current debug session.", nullptr) {
471 }
472
473 ~CommandObjectTargetList() override = default;
474
475protected:
476 bool DoExecute(Args &args, CommandReturnObject &result) override {
477 Stream &strm = result.GetOutputStream();
478
479 bool show_stopped_process_status = false;
480 if (DumpTargetList(GetDebugger().GetTargetList(),
481 show_stopped_process_status, strm) == 0) {
482 strm.PutCString("No targets.\n");
483 }
485 return result.Succeeded();
486 }
487};
488
489#pragma mark CommandObjectTargetSelect
490
492public:
495 interpreter, "target select",
496 "Select a target as the current target by target index.", nullptr) {
498 m_arguments.push_back({target_arg});
499 }
500
501 ~CommandObjectTargetSelect() override = default;
502
503protected:
504 bool DoExecute(Args &args, CommandReturnObject &result) override {
505 if (args.GetArgumentCount() == 1) {
506 const char *target_idx_arg = args.GetArgumentAtIndex(0);
507 uint32_t target_idx;
508 if (llvm::to_integer(target_idx_arg, target_idx)) {
509 TargetList &target_list = GetDebugger().GetTargetList();
510 const uint32_t num_targets = target_list.GetNumTargets();
511 if (target_idx < num_targets) {
512 target_list.SetSelectedTarget(target_idx);
513 Stream &strm = result.GetOutputStream();
514 bool show_stopped_process_status = false;
515 DumpTargetList(target_list, show_stopped_process_status, strm);
517 } else {
518 if (num_targets > 0) {
520 "index %u is out of range, valid target indexes are 0 - %u\n",
521 target_idx, num_targets - 1);
522 } else {
524 "index %u is out of range since there are no active targets\n",
525 target_idx);
526 }
527 }
528 } else {
529 result.AppendErrorWithFormat("invalid index string value '%s'\n",
530 target_idx_arg);
531 }
532 } else {
533 result.AppendError(
534 "'target select' takes a single argument: a target index\n");
535 }
536 return result.Succeeded();
537 }
538};
539
540#pragma mark CommandObjectTargetDelete
541
543public:
545 : CommandObjectParsed(interpreter, "target delete",
546 "Delete one or more targets by target index.",
547 nullptr),
548 m_all_option(LLDB_OPT_SET_1, false, "all", 'a', "Delete all targets.",
549 false, true),
551 LLDB_OPT_SET_1, false, "clean", 'c',
552 "Perform extra cleanup to minimize memory consumption after "
553 "deleting the target. "
554 "By default, LLDB will keep in memory any modules previously "
555 "loaded by the target as well "
556 "as all of its debug info. Specifying --clean will unload all of "
557 "these shared modules and "
558 "cause them to be reparsed again the next time the target is run",
559 false, true) {
564 m_arguments.push_back({target_arg});
565 }
566
567 ~CommandObjectTargetDelete() override = default;
568
569 Options *GetOptions() override { return &m_option_group; }
570
571protected:
572 bool DoExecute(Args &args, CommandReturnObject &result) override {
573 const size_t argc = args.GetArgumentCount();
574 std::vector<TargetSP> delete_target_list;
575 TargetList &target_list = GetDebugger().GetTargetList();
576 TargetSP target_sp;
577
579 for (int i = 0; i < target_list.GetNumTargets(); ++i)
580 delete_target_list.push_back(target_list.GetTargetAtIndex(i));
581 } else if (argc > 0) {
582 const uint32_t num_targets = target_list.GetNumTargets();
583 // Bail out if don't have any targets.
584 if (num_targets == 0) {
585 result.AppendError("no targets to delete");
586 return false;
587 }
588
589 for (auto &entry : args.entries()) {
590 uint32_t target_idx;
591 if (entry.ref().getAsInteger(0, target_idx)) {
592 result.AppendErrorWithFormat("invalid target index '%s'\n",
593 entry.c_str());
594 return false;
595 }
596 if (target_idx < num_targets) {
597 target_sp = target_list.GetTargetAtIndex(target_idx);
598 if (target_sp) {
599 delete_target_list.push_back(target_sp);
600 continue;
601 }
602 }
603 if (num_targets > 1)
604 result.AppendErrorWithFormat("target index %u is out of range, valid "
605 "target indexes are 0 - %u\n",
606 target_idx, num_targets - 1);
607 else
609 "target index %u is out of range, the only valid index is 0\n",
610 target_idx);
611
612 return false;
613 }
614 } else {
615 target_sp = target_list.GetSelectedTarget();
616 if (!target_sp) {
617 result.AppendErrorWithFormat("no target is currently selected\n");
618 return false;
619 }
620 delete_target_list.push_back(target_sp);
621 }
622
623 const size_t num_targets_to_delete = delete_target_list.size();
624 for (size_t idx = 0; idx < num_targets_to_delete; ++idx) {
625 target_sp = delete_target_list[idx];
626 target_list.DeleteTarget(target_sp);
627 target_sp->Destroy();
628 }
629 // If "--clean" was specified, prune any orphaned shared modules from the
630 // global shared module list
632 const bool mandatory = true;
634 }
635 result.GetOutputStream().Printf("%u targets deleted.\n",
636 (uint32_t)num_targets_to_delete);
638
639 return true;
640 }
641
645};
646
648public:
651 interpreter, "target show-launch-environment",
652 "Shows the environment being passed to the process when launched, "
653 "taking info account 3 settings: target.env-vars, "
654 "target.inherit-env and target.unset-env-vars.",
655 nullptr, eCommandRequiresTarget) {}
656
658
659protected:
660 bool DoExecute(Args &args, CommandReturnObject &result) override {
661 Target *target = m_exe_ctx.GetTargetPtr();
662 Environment env = target->GetEnvironment();
663
664 std::vector<Environment::value_type *> env_vector;
665 env_vector.reserve(env.size());
666 for (auto &KV : env)
667 env_vector.push_back(&KV);
668 std::sort(env_vector.begin(), env_vector.end(),
669 [](Environment::value_type *a, Environment::value_type *b) {
670 return a->first() < b->first();
671 });
672
673 auto &strm = result.GetOutputStream();
674 for (auto &KV : env_vector)
675 strm.Format("{0}={1}\n", KV->first(), KV->second);
676
678 return result.Succeeded();
679 }
680};
681
682#pragma mark CommandObjectTargetVariable
683
685 static const uint32_t SHORT_OPTION_FILE = 0x66696c65; // 'file'
686 static const uint32_t SHORT_OPTION_SHLB = 0x73686c62; // 'shlb'
687
688public:
690 : CommandObjectParsed(interpreter, "target variable",
691 "Read global variables for the current target, "
692 "before or while running a process.",
693 nullptr, eCommandRequiresTarget),
694 m_option_variable(false), // Don't include frame options
698 "A basename or fullpath to a file that contains "
699 "global variables. This option can be "
700 "specified multiple times."),
702 LLDB_OPT_SET_1, false, "shlib", SHORT_OPTION_SHLB, 0,
704 "A basename or fullpath to a shared library to use in the search "
705 "for global "
706 "variables. This option can be specified multiple times.") {
708 CommandArgumentData var_name_arg;
709
710 // Define the first (and only) variant of this arg.
711 var_name_arg.arg_type = eArgTypeVarName;
712 var_name_arg.arg_repetition = eArgRepeatPlus;
713
714 // There is only one variant this argument could be; put it into the
715 // argument entry.
716 arg.push_back(var_name_arg);
717
718 // Push the data for the first argument into the m_arguments vector.
719 m_arguments.push_back(arg);
720
732 }
733
734 ~CommandObjectTargetVariable() override = default;
735
736 void DumpValueObject(Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp,
737 const char *root_name) {
739
740 if (!valobj_sp->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
741 valobj_sp->IsRuntimeSupportValue())
742 return;
743
744 switch (var_sp->GetScope()) {
747 s.PutCString("GLOBAL: ");
748 break;
749
752 s.PutCString("STATIC: ");
753 break;
754
757 s.PutCString(" ARG: ");
758 break;
759
762 s.PutCString(" LOCAL: ");
763 break;
764
767 s.PutCString("THREAD: ");
768 break;
769
770 default:
771 break;
772 }
773
775 bool show_fullpaths = false;
776 bool show_module = true;
777 if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
778 s.PutCString(": ");
779 }
780
781 const Format format = m_option_format.GetFormat();
782 if (format != eFormatDefault)
783 options.SetFormat(format);
784
785 options.SetRootValueObjectName(root_name);
786
787 valobj_sp->Dump(s, options);
788 }
789
790 static size_t GetVariableCallback(void *baton, const char *name,
791 VariableList &variable_list) {
792 size_t old_size = variable_list.GetSize();
793 Target *target = static_cast<Target *>(baton);
794 if (target)
796 variable_list);
797 return variable_list.GetSize() - old_size;
798 }
799
800 Options *GetOptions() override { return &m_option_group; }
801
802protected:
804 const SymbolContext &sc,
805 const VariableList &variable_list, Stream &s) {
806 if (variable_list.Empty())
807 return;
808 if (sc.module_sp) {
809 if (sc.comp_unit) {
810 s.Format("Global variables for {0} in {1}:\n",
811 sc.comp_unit->GetPrimaryFile(), sc.module_sp->GetFileSpec());
812 } else {
813 s.Printf("Global variables for %s\n",
814 sc.module_sp->GetFileSpec().GetPath().c_str());
815 }
816 } else if (sc.comp_unit) {
817 s.Format("Global variables for {0}\n", sc.comp_unit->GetPrimaryFile());
818 }
819
820 for (VariableSP var_sp : variable_list) {
821 if (!var_sp)
822 continue;
823 ValueObjectSP valobj_sp(ValueObjectVariable::Create(
824 exe_ctx.GetBestExecutionContextScope(), var_sp));
825
826 if (valobj_sp)
827 DumpValueObject(s, var_sp, valobj_sp, var_sp->GetName().GetCString());
828 }
829 }
830
831 bool DoExecute(Args &args, CommandReturnObject &result) override {
832 Target *target = m_exe_ctx.GetTargetPtr();
833 const size_t argc = args.GetArgumentCount();
834 Stream &s = result.GetOutputStream();
835
836 if (argc > 0) {
837 for (const Args::ArgEntry &arg : args) {
838 VariableList variable_list;
839 ValueObjectList valobj_list;
840
841 size_t matches = 0;
842 bool use_var_name = false;
844 RegularExpression regex(arg.ref());
845 if (!regex.IsValid()) {
846 result.GetErrorStream().Printf(
847 "error: invalid regular expression: '%s'\n", arg.c_str());
848 return false;
849 }
850 use_var_name = true;
852 variable_list);
853 matches = variable_list.GetSize();
854 } else {
857 GetVariableCallback, target, variable_list, valobj_list));
858 matches = variable_list.GetSize();
859 }
860
861 if (matches == 0) {
862 result.AppendErrorWithFormat("can't find global variable '%s'",
863 arg.c_str());
864 return false;
865 } else {
866 for (uint32_t global_idx = 0; global_idx < matches; ++global_idx) {
867 VariableSP var_sp(variable_list.GetVariableAtIndex(global_idx));
868 if (var_sp) {
869 ValueObjectSP valobj_sp(
870 valobj_list.GetValueObjectAtIndex(global_idx));
871 if (!valobj_sp)
872 valobj_sp = ValueObjectVariable::Create(
874
875 if (valobj_sp)
876 DumpValueObject(s, var_sp, valobj_sp,
877 use_var_name ? var_sp->GetName().GetCString()
878 : arg.c_str());
879 }
880 }
881 }
882 }
883 } else {
884 const FileSpecList &compile_units =
886 const FileSpecList &shlibs =
888 SymbolContextList sc_list;
889 const size_t num_compile_units = compile_units.GetSize();
890 const size_t num_shlibs = shlibs.GetSize();
891 if (num_compile_units == 0 && num_shlibs == 0) {
892 bool success = false;
894 CompileUnit *comp_unit = nullptr;
895 if (frame) {
896 SymbolContext sc = frame->GetSymbolContext(eSymbolContextCompUnit);
897 comp_unit = sc.comp_unit;
898 if (sc.comp_unit) {
899 const bool can_create = true;
900 VariableListSP comp_unit_varlist_sp(
901 sc.comp_unit->GetVariableList(can_create));
902 if (comp_unit_varlist_sp) {
903 size_t count = comp_unit_varlist_sp->GetSize();
904 if (count > 0) {
905 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
906 success = true;
907 }
908 }
909 }
910 }
911 if (!success) {
912 if (frame) {
913 if (comp_unit)
915 "no global variables in current compile unit: {0}\n",
916 comp_unit->GetPrimaryFile());
917 else
919 "no debug information for frame %u\n",
920 frame->GetFrameIndex());
921 } else
922 result.AppendError("'target variable' takes one or more global "
923 "variable names as arguments\n");
924 }
925 } else {
926 SymbolContextList sc_list;
927 // We have one or more compile unit or shlib
928 if (num_shlibs > 0) {
929 for (size_t shlib_idx = 0; shlib_idx < num_shlibs; ++shlib_idx) {
930 const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx));
931 ModuleSpec module_spec(module_file);
932
933 ModuleSP module_sp(
934 target->GetImages().FindFirstModule(module_spec));
935 if (module_sp) {
936 if (num_compile_units > 0) {
937 for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
938 module_sp->FindCompileUnits(
939 compile_units.GetFileSpecAtIndex(cu_idx), sc_list);
940 } else {
941 SymbolContext sc;
942 sc.module_sp = module_sp;
943 sc_list.Append(sc);
944 }
945 } else {
946 // Didn't find matching shlib/module in target...
948 "target doesn't contain the specified shared library: %s\n",
949 module_file.GetPath().c_str());
950 }
951 }
952 } else {
953 // No shared libraries, we just want to find globals for the compile
954 // units files that were specified
955 for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
956 target->GetImages().FindCompileUnits(
957 compile_units.GetFileSpecAtIndex(cu_idx), sc_list);
958 }
959
960 const uint32_t num_scs = sc_list.GetSize();
961 if (num_scs > 0) {
962 SymbolContext sc;
963 for (uint32_t sc_idx = 0; sc_idx < num_scs; ++sc_idx) {
964 if (sc_list.GetContextAtIndex(sc_idx, sc)) {
965 if (sc.comp_unit) {
966 const bool can_create = true;
967 VariableListSP comp_unit_varlist_sp(
968 sc.comp_unit->GetVariableList(can_create));
969 if (comp_unit_varlist_sp)
970 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp,
971 s);
972 } else if (sc.module_sp) {
973 // Get all global variables for this module
974 lldb_private::RegularExpression all_globals_regex(
975 llvm::StringRef(
976 ".")); // Any global with at least one character
977 VariableList variable_list;
978 sc.module_sp->FindGlobalVariables(all_globals_regex, UINT32_MAX,
979 variable_list);
980 DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s);
981 }
982 }
983 }
984 }
985 }
986 }
987
989 m_cmd_name);
990
991 return result.Succeeded();
992 }
993
1000};
1001
1002#pragma mark CommandObjectTargetModulesSearchPathsAdd
1003
1005public:
1007 : CommandObjectParsed(interpreter, "target modules search-paths add",
1008 "Add new image search paths substitution pairs to "
1009 "the current target.",
1010 nullptr, eCommandRequiresTarget) {
1012 CommandArgumentData old_prefix_arg;
1013 CommandArgumentData new_prefix_arg;
1014
1015 // Define the first variant of this arg pair.
1016 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1017 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1018
1019 // Define the first variant of this arg pair.
1020 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1021 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1022
1023 // There are two required arguments that must always occur together, i.e.
1024 // an argument "pair". Because they must always occur together, they are
1025 // treated as two variants of one argument rather than two independent
1026 // arguments. Push them both into the first argument position for
1027 // m_arguments...
1028
1029 arg.push_back(old_prefix_arg);
1030 arg.push_back(new_prefix_arg);
1031
1032 m_arguments.push_back(arg);
1033 }
1034
1036
1037protected:
1038 bool DoExecute(Args &command, CommandReturnObject &result) override {
1039 Target *target = &GetSelectedTarget();
1040 const size_t argc = command.GetArgumentCount();
1041 if (argc & 1) {
1042 result.AppendError("add requires an even number of arguments\n");
1043 } else {
1044 for (size_t i = 0; i < argc; i += 2) {
1045 const char *from = command.GetArgumentAtIndex(i);
1046 const char *to = command.GetArgumentAtIndex(i + 1);
1047
1048 if (from[0] && to[0]) {
1049 Log *log = GetLog(LLDBLog::Host);
1050 if (log) {
1051 LLDB_LOGF(log,
1052 "target modules search path adding ImageSearchPath "
1053 "pair: '%s' -> '%s'",
1054 from, to);
1055 }
1056 bool last_pair = ((argc - i) == 2);
1058 from, to, last_pair); // Notify if this is the last pair
1060 } else {
1061 if (from[0])
1062 result.AppendError("<path-prefix> can't be empty\n");
1063 else
1064 result.AppendError("<new-path-prefix> can't be empty\n");
1065 }
1066 }
1067 }
1068 return result.Succeeded();
1069 }
1070};
1071
1072#pragma mark CommandObjectTargetModulesSearchPathsClear
1073
1075public:
1077 : CommandObjectParsed(interpreter, "target modules search-paths clear",
1078 "Clear all current image search path substitution "
1079 "pairs from the current target.",
1080 "target modules search-paths clear",
1081 eCommandRequiresTarget) {}
1082
1084
1085protected:
1086 bool DoExecute(Args &command, CommandReturnObject &result) override {
1087 Target *target = &GetSelectedTarget();
1088 bool notify = true;
1089 target->GetImageSearchPathList().Clear(notify);
1091 return result.Succeeded();
1092 }
1093};
1094
1095#pragma mark CommandObjectTargetModulesSearchPathsInsert
1096
1098public:
1100 : CommandObjectParsed(interpreter, "target modules search-paths insert",
1101 "Insert a new image search path substitution pair "
1102 "into the current target at the specified index.",
1103 nullptr, eCommandRequiresTarget) {
1106 CommandArgumentData index_arg;
1107 CommandArgumentData old_prefix_arg;
1108 CommandArgumentData new_prefix_arg;
1109
1110 // Define the first and only variant of this arg.
1111 index_arg.arg_type = eArgTypeIndex;
1112 index_arg.arg_repetition = eArgRepeatPlain;
1113
1114 // Put the one and only variant into the first arg for m_arguments:
1115 arg1.push_back(index_arg);
1116
1117 // Define the first variant of this arg pair.
1118 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1119 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1120
1121 // Define the first variant of this arg pair.
1122 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1123 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1124
1125 // There are two required arguments that must always occur together, i.e.
1126 // an argument "pair". Because they must always occur together, they are
1127 // treated as two variants of one argument rather than two independent
1128 // arguments. Push them both into the same argument position for
1129 // m_arguments...
1130
1131 arg2.push_back(old_prefix_arg);
1132 arg2.push_back(new_prefix_arg);
1133
1134 // Add arguments to m_arguments.
1135 m_arguments.push_back(arg1);
1136 m_arguments.push_back(arg2);
1137 }
1138
1140
1141 void
1143 OptionElementVector &opt_element_vector) override {
1144 if (!m_exe_ctx.HasTargetScope() || request.GetCursorIndex() != 0)
1145 return;
1146
1147 Target *target = m_exe_ctx.GetTargetPtr();
1148 const PathMappingList &list = target->GetImageSearchPathList();
1149 const size_t num = list.GetSize();
1150 ConstString old_path, new_path;
1151 for (size_t i = 0; i < num; ++i) {
1152 if (!list.GetPathsAtIndex(i, old_path, new_path))
1153 break;
1154 StreamString strm;
1155 strm << old_path << " -> " << new_path;
1156 request.TryCompleteCurrentArg(std::to_string(i), strm.GetString());
1157 }
1158 }
1159
1160protected:
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 uint32_t insert_idx;
1167
1168 if (!llvm::to_integer(command.GetArgumentAtIndex(0), insert_idx)) {
1169 result.AppendErrorWithFormat(
1170 "<index> parameter is not an integer: '%s'.\n",
1171 command.GetArgumentAtIndex(0));
1172 return result.Succeeded();
1173 }
1174
1175 // shift off the index
1176 command.Shift();
1177 argc = command.GetArgumentCount();
1178
1179 for (uint32_t i = 0; i < argc; i += 2, ++insert_idx) {
1180 const char *from = command.GetArgumentAtIndex(i);
1181 const char *to = command.GetArgumentAtIndex(i + 1);
1182
1183 if (from[0] && to[0]) {
1184 bool last_pair = ((argc - i) == 2);
1185 target->GetImageSearchPathList().Insert(from, to, insert_idx,
1186 last_pair);
1188 } else {
1189 if (from[0])
1190 result.AppendError("<path-prefix> can't be empty\n");
1191 else
1192 result.AppendError("<new-path-prefix> can't be empty\n");
1193 return false;
1194 }
1195 }
1196 } else {
1197 result.AppendError("insert requires at least three arguments\n");
1198 return result.Succeeded();
1199 }
1200 return result.Succeeded();
1201 }
1202};
1203
1204#pragma mark CommandObjectTargetModulesSearchPathsList
1205
1207public:
1209 : CommandObjectParsed(interpreter, "target modules search-paths list",
1210 "List all current image search path substitution "
1211 "pairs in the current target.",
1212 "target modules search-paths list",
1213 eCommandRequiresTarget) {}
1214
1216
1217protected:
1218 bool DoExecute(Args &command, CommandReturnObject &result) override {
1219 Target *target = &GetSelectedTarget();
1220
1221 target->GetImageSearchPathList().Dump(&result.GetOutputStream());
1223 return result.Succeeded();
1224 }
1225};
1226
1227#pragma mark CommandObjectTargetModulesSearchPathsQuery
1228
1230public:
1233 interpreter, "target modules search-paths query",
1234 "Transform a path using the first applicable image search path.",
1235 nullptr, eCommandRequiresTarget) {
1237 CommandArgumentData path_arg;
1238
1239 // Define the first (and only) variant of this arg.
1242
1243 // There is only one variant this argument could be; put it into the
1244 // argument entry.
1245 arg.push_back(path_arg);
1246
1247 // Push the data for the first argument into the m_arguments vector.
1248 m_arguments.push_back(arg);
1249 }
1250
1252
1253protected:
1254 bool DoExecute(Args &command, CommandReturnObject &result) override {
1255 Target *target = &GetSelectedTarget();
1256 if (command.GetArgumentCount() != 1) {
1257 result.AppendError("query requires one argument\n");
1258 return result.Succeeded();
1259 }
1260
1261 ConstString orig(command.GetArgumentAtIndex(0));
1262 ConstString transformed;
1263 if (target->GetImageSearchPathList().RemapPath(orig, transformed))
1264 result.GetOutputStream().Printf("%s\n", transformed.GetCString());
1265 else
1266 result.GetOutputStream().Printf("%s\n", orig.GetCString());
1267
1269 return result.Succeeded();
1270 }
1271};
1272
1273// Static Helper functions
1274static void DumpModuleArchitecture(Stream &strm, Module *module,
1275 bool full_triple, uint32_t width) {
1276 if (module) {
1277 StreamString arch_strm;
1278
1279 if (full_triple)
1280 module->GetArchitecture().DumpTriple(arch_strm.AsRawOstream());
1281 else
1282 arch_strm.PutCString(module->GetArchitecture().GetArchitectureName());
1283 std::string arch_str = std::string(arch_strm.GetString());
1284
1285 if (width)
1286 strm.Printf("%-*s", width, arch_str.c_str());
1287 else
1288 strm.PutCString(arch_str);
1289 }
1290}
1291
1292static void DumpModuleUUID(Stream &strm, Module *module) {
1293 if (module && module->GetUUID().IsValid())
1294 module->GetUUID().Dump(&strm);
1295 else
1296 strm.PutCString(" ");
1297}
1298
1300 Stream &strm, Module *module,
1301 const FileSpec &file_spec,
1302 lldb::DescriptionLevel desc_level) {
1303 uint32_t num_matches = 0;
1304 if (module) {
1305 SymbolContextList sc_list;
1306 num_matches = module->ResolveSymbolContextsForFileSpec(
1307 file_spec, 0, false, eSymbolContextCompUnit, sc_list);
1308
1309 for (uint32_t i = 0; i < num_matches; ++i) {
1310 SymbolContext sc;
1311 if (sc_list.GetContextAtIndex(i, sc)) {
1312 if (i > 0)
1313 strm << "\n\n";
1314
1315 strm << "Line table for " << sc.comp_unit->GetPrimaryFile() << " in `"
1316 << module->GetFileSpec().GetFilename() << "\n";
1317 LineTable *line_table = sc.comp_unit->GetLineTable();
1318 if (line_table)
1319 line_table->GetDescription(
1320 &strm, interpreter.GetExecutionContext().GetTargetPtr(),
1321 desc_level);
1322 else
1323 strm << "No line table";
1324 }
1325 }
1326 }
1327 return num_matches;
1328}
1329
1330static void DumpFullpath(Stream &strm, const FileSpec *file_spec_ptr,
1331 uint32_t width) {
1332 if (file_spec_ptr) {
1333 if (width > 0) {
1334 std::string fullpath = file_spec_ptr->GetPath();
1335 strm.Printf("%-*s", width, fullpath.c_str());
1336 return;
1337 } else {
1338 file_spec_ptr->Dump(strm.AsRawOstream());
1339 return;
1340 }
1341 }
1342 // Keep the width spacing correct if things go wrong...
1343 if (width > 0)
1344 strm.Printf("%-*s", width, "");
1345}
1346
1347static void DumpDirectory(Stream &strm, const FileSpec *file_spec_ptr,
1348 uint32_t width) {
1349 if (file_spec_ptr) {
1350 if (width > 0)
1351 strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
1352 else
1353 file_spec_ptr->GetDirectory().Dump(&strm);
1354 return;
1355 }
1356 // Keep the width spacing correct if things go wrong...
1357 if (width > 0)
1358 strm.Printf("%-*s", width, "");
1359}
1360
1361static void DumpBasename(Stream &strm, const FileSpec *file_spec_ptr,
1362 uint32_t width) {
1363 if (file_spec_ptr) {
1364 if (width > 0)
1365 strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
1366 else
1367 file_spec_ptr->GetFilename().Dump(&strm);
1368 return;
1369 }
1370 // Keep the width spacing correct if things go wrong...
1371 if (width > 0)
1372 strm.Printf("%-*s", width, "");
1373}
1374
1375static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) {
1376 std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
1377 const size_t num_modules = module_list.GetSize();
1378 if (num_modules == 0)
1379 return 0;
1380
1381 size_t num_dumped = 0;
1382 strm.Format("Dumping headers for {0} module(s).\n", num_modules);
1383 strm.IndentMore();
1384 for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
1385 if (module_sp) {
1386 if (num_dumped++ > 0) {
1387 strm.EOL();
1388 strm.EOL();
1389 }
1390 ObjectFile *objfile = module_sp->GetObjectFile();
1391 if (objfile)
1392 objfile->Dump(&strm);
1393 else {
1394 strm.Format("No object file for module: {0:F}\n",
1395 module_sp->GetFileSpec());
1396 }
1397 }
1398 }
1399 strm.IndentLess();
1400 return num_dumped;
1401}
1402
1403static void DumpModuleSymtab(CommandInterpreter &interpreter, Stream &strm,
1404 Module *module, SortOrder sort_order,
1405 Mangled::NamePreference name_preference) {
1406 if (!module)
1407 return;
1408 if (Symtab *symtab = module->GetSymtab())
1409 symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(),
1410 sort_order, name_preference);
1411}
1412
1413static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm,
1414 Module *module) {
1415 if (module) {
1416 SectionList *section_list = module->GetSectionList();
1417 if (section_list) {
1418 strm.Printf("Sections for '%s' (%s):\n",
1419 module->GetSpecificationDescription().c_str(),
1421 section_list->Dump(strm.AsRawOstream(), strm.GetIndentLevel() + 2,
1422 interpreter.GetExecutionContext().GetTargetPtr(), true,
1423 UINT32_MAX);
1424 }
1425 }
1426}
1427
1428static bool DumpModuleSymbolFile(Stream &strm, Module *module) {
1429 if (module) {
1430 if (SymbolFile *symbol_file = module->GetSymbolFile(true)) {
1431 symbol_file->Dump(strm);
1432 return true;
1433 }
1434 }
1435 return false;
1436}
1437
1438static void DumpAddress(ExecutionContextScope *exe_scope,
1439 const Address &so_addr, bool verbose, bool all_ranges,
1440 Stream &strm) {
1441 strm.IndentMore();
1442 strm.Indent(" Address: ");
1443 so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
1444 strm.PutCString(" (");
1445 so_addr.Dump(&strm, exe_scope, Address::DumpStyleSectionNameOffset);
1446 strm.PutCString(")\n");
1447 strm.Indent(" Summary: ");
1448 const uint32_t save_indent = strm.GetIndentLevel();
1449 strm.SetIndentLevel(save_indent + 13);
1450 so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription);
1451 strm.SetIndentLevel(save_indent);
1452 // Print out detailed address information when verbose is enabled
1453 if (verbose) {
1454 strm.EOL();
1455 so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext,
1457 }
1458 strm.IndentLess();
1459}
1460
1461static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm,
1462 Module *module, uint32_t resolve_mask,
1463 lldb::addr_t raw_addr, lldb::addr_t offset,
1464 bool verbose, bool all_ranges) {
1465 if (module) {
1466 lldb::addr_t addr = raw_addr - offset;
1467 Address so_addr;
1468 SymbolContext sc;
1469 Target *target = interpreter.GetExecutionContext().GetTargetPtr();
1470 if (target && !target->GetSectionLoadList().IsEmpty()) {
1471 if (!target->GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
1472 return false;
1473 else if (so_addr.GetModule().get() != module)
1474 return false;
1475 } else {
1476 if (!module->ResolveFileAddress(addr, so_addr))
1477 return false;
1478 }
1479
1480 ExecutionContextScope *exe_scope =
1482 DumpAddress(exe_scope, so_addr, verbose, all_ranges, strm);
1483 // strm.IndentMore();
1484 // strm.Indent (" Address: ");
1485 // so_addr.Dump (&strm, exe_scope,
1486 // Address::DumpStyleModuleWithFileAddress);
1487 // strm.PutCString (" (");
1488 // so_addr.Dump (&strm, exe_scope,
1489 // Address::DumpStyleSectionNameOffset);
1490 // strm.PutCString (")\n");
1491 // strm.Indent (" Summary: ");
1492 // const uint32_t save_indent = strm.GetIndentLevel ();
1493 // strm.SetIndentLevel (save_indent + 13);
1494 // so_addr.Dump (&strm, exe_scope,
1495 // Address::DumpStyleResolvedDescription);
1496 // strm.SetIndentLevel (save_indent);
1497 // // Print out detailed address information when verbose is enabled
1498 // if (verbose)
1499 // {
1500 // strm.EOL();
1501 // so_addr.Dump (&strm, exe_scope,
1502 // Address::DumpStyleDetailedSymbolContext);
1503 // }
1504 // strm.IndentLess();
1505 return true;
1506 }
1507
1508 return false;
1509}
1510
1512 Stream &strm, Module *module,
1513 const char *name, bool name_is_regex,
1514 bool verbose, bool all_ranges) {
1515 if (!module)
1516 return 0;
1517
1518 Symtab *symtab = module->GetSymtab();
1519 if (!symtab)
1520 return 0;
1521
1522 SymbolContext sc;
1523 std::vector<uint32_t> match_indexes;
1524 ConstString symbol_name(name);
1525 uint32_t num_matches = 0;
1526 if (name_is_regex) {
1527 RegularExpression name_regexp(symbol_name.GetStringRef());
1528 num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType(
1529 name_regexp, eSymbolTypeAny, match_indexes);
1530 } else {
1531 num_matches =
1532 symtab->AppendSymbolIndexesWithName(symbol_name, match_indexes);
1533 }
1534
1535 if (num_matches > 0) {
1536 strm.Indent();
1537 strm.Printf("%u symbols match %s'%s' in ", num_matches,
1538 name_is_regex ? "the regular expression " : "", name);
1539 DumpFullpath(strm, &module->GetFileSpec(), 0);
1540 strm.PutCString(":\n");
1541 strm.IndentMore();
1542 for (uint32_t i = 0; i < num_matches; ++i) {
1543 Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
1544 if (symbol) {
1545 if (symbol->ValueIsAddress()) {
1548 symbol->GetAddressRef(), verbose, all_ranges, strm);
1549 strm.EOL();
1550 } else {
1551 strm.IndentMore();
1552 strm.Indent(" Name: ");
1553 strm.PutCString(symbol->GetDisplayName().GetStringRef());
1554 strm.EOL();
1555 strm.Indent(" Value: ");
1556 strm.Printf("0x%16.16" PRIx64 "\n", symbol->GetRawValue());
1557 if (symbol->GetByteSizeIsValid()) {
1558 strm.Indent(" Size: ");
1559 strm.Printf("0x%16.16" PRIx64 "\n", symbol->GetByteSize());
1560 }
1561 strm.IndentLess();
1562 }
1563 }
1564 }
1565 strm.IndentLess();
1566 }
1567 return num_matches;
1568}
1569
1571 Stream &strm, SymbolContextList &sc_list,
1572 bool verbose, bool all_ranges) {
1573 strm.IndentMore();
1574
1575 const uint32_t num_matches = sc_list.GetSize();
1576
1577 for (uint32_t i = 0; i < num_matches; ++i) {
1578 SymbolContext sc;
1579 if (sc_list.GetContextAtIndex(i, sc)) {
1580 AddressRange range;
1581
1582 sc.GetAddressRange(eSymbolContextEverything, 0, true, range);
1583
1584 DumpAddress(exe_scope, range.GetBaseAddress(), verbose, all_ranges, strm);
1585 if (i != (num_matches - 1))
1586 strm.EOL();
1587 }
1588 }
1589 strm.IndentLess();
1590}
1591
1593 Stream &strm, Module *module,
1594 const char *name, bool name_is_regex,
1595 const ModuleFunctionSearchOptions &options,
1596 bool verbose, bool all_ranges) {
1597 if (module && name && name[0]) {
1598 SymbolContextList sc_list;
1599 size_t num_matches = 0;
1600 if (name_is_regex) {
1601 RegularExpression function_name_regex((llvm::StringRef(name)));
1602 module->FindFunctions(function_name_regex, options, sc_list);
1603 } else {
1604 ConstString function_name(name);
1605 module->FindFunctions(function_name, CompilerDeclContext(),
1606 eFunctionNameTypeAuto, options, sc_list);
1607 }
1608 num_matches = sc_list.GetSize();
1609 if (num_matches) {
1610 strm.Indent();
1611 strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
1612 num_matches > 1 ? "es" : "");
1613 DumpFullpath(strm, &module->GetFileSpec(), 0);
1614 strm.PutCString(":\n");
1617 strm, sc_list, verbose, all_ranges);
1618 }
1619 return num_matches;
1620 }
1621 return 0;
1622}
1623
1624static size_t LookupTypeInModule(Target *target,
1625 CommandInterpreter &interpreter, Stream &strm,
1626 Module *module, const char *name_cstr,
1627 bool name_is_regex) {
1628 TypeList type_list;
1629 if (module && name_cstr && name_cstr[0]) {
1630 const uint32_t max_num_matches = UINT32_MAX;
1631 bool name_is_fully_qualified = false;
1632
1633 ConstString name(name_cstr);
1634 llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
1635 module->FindTypes(name, name_is_fully_qualified, max_num_matches,
1636 searched_symbol_files, type_list);
1637
1638 if (type_list.Empty())
1639 return 0;
1640
1641 const uint64_t num_matches = type_list.GetSize();
1642
1643 strm.Indent();
1644 strm.Printf("%" PRIu64 " match%s found in ", num_matches,
1645 num_matches > 1 ? "es" : "");
1646 DumpFullpath(strm, &module->GetFileSpec(), 0);
1647 strm.PutCString(":\n");
1648 for (TypeSP type_sp : type_list.Types()) {
1649 if (!type_sp)
1650 continue;
1651 // Resolve the clang type so that any forward references to types
1652 // that haven't yet been parsed will get parsed.
1653 type_sp->GetFullCompilerType();
1654 type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target);
1655 // Print all typedef chains
1656 TypeSP typedef_type_sp(type_sp);
1657 TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1658 while (typedefed_type_sp) {
1659 strm.EOL();
1660 strm.Printf(" typedef '%s': ",
1661 typedef_type_sp->GetName().GetCString());
1662 typedefed_type_sp->GetFullCompilerType();
1663 typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true,
1664 target);
1665 typedef_type_sp = typedefed_type_sp;
1666 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1667 }
1668 strm.EOL();
1669 }
1670 }
1671 return type_list.GetSize();
1672}
1673
1674static size_t LookupTypeHere(Target *target, CommandInterpreter &interpreter,
1675 Stream &strm, Module &module,
1676 const char *name_cstr, bool name_is_regex) {
1677 TypeList type_list;
1678 const uint32_t max_num_matches = UINT32_MAX;
1679 bool name_is_fully_qualified = false;
1680
1681 ConstString name(name_cstr);
1682 llvm::DenseSet<SymbolFile *> searched_symbol_files;
1683 module.FindTypes(name, name_is_fully_qualified, max_num_matches,
1684 searched_symbol_files, type_list);
1685
1686 if (type_list.Empty())
1687 return 0;
1688
1689 strm.Indent();
1690 strm.PutCString("Best match found in ");
1691 DumpFullpath(strm, &module.GetFileSpec(), 0);
1692 strm.PutCString(":\n");
1693
1694 TypeSP type_sp(type_list.GetTypeAtIndex(0));
1695 if (type_sp) {
1696 // Resolve the clang type so that any forward references to types that
1697 // haven't yet been parsed will get parsed.
1698 type_sp->GetFullCompilerType();
1699 type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target);
1700 // Print all typedef chains.
1701 TypeSP typedef_type_sp(type_sp);
1702 TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1703 while (typedefed_type_sp) {
1704 strm.EOL();
1705 strm.Printf(" typedef '%s': ",
1706 typedef_type_sp->GetName().GetCString());
1707 typedefed_type_sp->GetFullCompilerType();
1708 typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true,
1709 target);
1710 typedef_type_sp = typedefed_type_sp;
1711 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1712 }
1713 }
1714 strm.EOL();
1715 return type_list.GetSize();
1716}
1717
1719 Stream &strm, Module *module,
1720 const FileSpec &file_spec,
1721 uint32_t line, bool check_inlines,
1722 bool verbose, bool all_ranges) {
1723 if (module && file_spec) {
1724 SymbolContextList sc_list;
1725 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(
1726 file_spec, line, check_inlines, eSymbolContextEverything, sc_list);
1727 if (num_matches > 0) {
1728 strm.Indent();
1729 strm.Printf("%u match%s found in ", num_matches,
1730 num_matches > 1 ? "es" : "");
1731 strm << file_spec;
1732 if (line > 0)
1733 strm.Printf(":%u", line);
1734 strm << " in ";
1735 DumpFullpath(strm, &module->GetFileSpec(), 0);
1736 strm.PutCString(":\n");
1739 strm, sc_list, verbose, all_ranges);
1740 return num_matches;
1741 }
1742 }
1743 return 0;
1744}
1745
1746static size_t FindModulesByName(Target *target, const char *module_name,
1747 ModuleList &module_list,
1748 bool check_global_list) {
1749 FileSpec module_file_spec(module_name);
1750 ModuleSpec module_spec(module_file_spec);
1751
1752 const size_t initial_size = module_list.GetSize();
1753
1754 if (check_global_list) {
1755 // Check the global list
1756 std::lock_guard<std::recursive_mutex> guard(
1758 const size_t num_modules = Module::GetNumberAllocatedModules();
1759 ModuleSP module_sp;
1760 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
1761 Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
1762
1763 if (module) {
1764 if (module->MatchesModuleSpec(module_spec)) {
1765 module_sp = module->shared_from_this();
1766 module_list.AppendIfNeeded(module_sp);
1767 }
1768 }
1769 }
1770 } else {
1771 if (target) {
1772 target->GetImages().FindModules(module_spec, module_list);
1773 const size_t num_matches = module_list.GetSize();
1774
1775 // Not found in our module list for our target, check the main shared
1776 // module list in case it is a extra file used somewhere else
1777 if (num_matches == 0) {
1778 module_spec.GetArchitecture() = target->GetArchitecture();
1779 ModuleList::FindSharedModules(module_spec, module_list);
1780 }
1781 } else {
1782 ModuleList::FindSharedModules(module_spec, module_list);
1783 }
1784 }
1785
1786 return module_list.GetSize() - initial_size;
1787}
1788
1789#pragma mark CommandObjectTargetModulesModuleAutoComplete
1790
1791// A base command object class that can auto complete with module file
1792// paths
1793
1795 : public CommandObjectParsed {
1796public:
1798 const char *name,
1799 const char *help,
1800 const char *syntax,
1801 uint32_t flags = 0)
1802 : CommandObjectParsed(interpreter, name, help, syntax, flags) {
1804 CommandArgumentData file_arg;
1805
1806 // Define the first (and only) variant of this arg.
1807 file_arg.arg_type = eArgTypeFilename;
1808 file_arg.arg_repetition = eArgRepeatStar;
1809
1810 // There is only one variant this argument could be; put it into the
1811 // argument entry.
1812 arg.push_back(file_arg);
1813
1814 // Push the data for the first argument into the m_arguments vector.
1815 m_arguments.push_back(arg);
1816 }
1817
1819
1820 void
1822 OptionElementVector &opt_element_vector) override {
1825 nullptr);
1826 }
1827};
1828
1829#pragma mark CommandObjectTargetModulesSourceFileAutoComplete
1830
1831// A base command object class that can auto complete with module source
1832// file paths
1833
1835 : public CommandObjectParsed {
1836public:
1838 CommandInterpreter &interpreter, const char *name, const char *help,
1839 const char *syntax, uint32_t flags)
1840 : CommandObjectParsed(interpreter, name, help, syntax, flags) {
1842 CommandArgumentData source_file_arg;
1843
1844 // Define the first (and only) variant of this arg.
1845 source_file_arg.arg_type = eArgTypeSourceFile;
1846 source_file_arg.arg_repetition = eArgRepeatPlus;
1847
1848 // There is only one variant this argument could be; put it into the
1849 // argument entry.
1850 arg.push_back(source_file_arg);
1851
1852 // Push the data for the first argument into the m_arguments vector.
1853 m_arguments.push_back(arg);
1854 }
1855
1857
1858 void
1860 OptionElementVector &opt_element_vector) override {
1863 request, nullptr);
1864 }
1865};
1866
1867#pragma mark CommandObjectTargetModulesDumpObjfile
1868
1871public:
1874 interpreter, "target modules dump objfile",
1875 "Dump the object file headers from one or more target modules.",
1876 nullptr, eCommandRequiresTarget) {}
1877
1879
1880protected:
1881 bool DoExecute(Args &command, CommandReturnObject &result) override {
1882 Target *target = &GetSelectedTarget();
1883
1884 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1885 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1886 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1887
1888 size_t num_dumped = 0;
1889 if (command.GetArgumentCount() == 0) {
1890 // Dump all headers for all modules images
1891 num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(),
1892 target->GetImages());
1893 if (num_dumped == 0) {
1894 result.AppendError("the target has no associated executable images");
1895 }
1896 } else {
1897 // Find the modules that match the basename or full path.
1898 ModuleList module_list;
1899 const char *arg_cstr;
1900 for (int arg_idx = 0;
1901 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
1902 ++arg_idx) {
1903 size_t num_matched =
1904 FindModulesByName(target, arg_cstr, module_list, true);
1905 if (num_matched == 0) {
1907 "Unable to find an image that matches '%s'.\n", arg_cstr);
1908 }
1909 }
1910 // Dump all the modules we found.
1911 num_dumped =
1912 DumpModuleObjfileHeaders(result.GetOutputStream(), module_list);
1913 }
1914
1915 if (num_dumped > 0) {
1917 } else {
1918 result.AppendError("no matching executable images found");
1919 }
1920 return result.Succeeded();
1921 }
1922};
1923
1924#define LLDB_OPTIONS_target_modules_dump_symtab
1925#include "CommandOptions.inc"
1926
1929public:
1932 interpreter, "target modules dump symtab",
1933 "Dump the symbol table from one or more target modules.", nullptr,
1934 eCommandRequiresTarget) {}
1935
1937
1938 Options *GetOptions() override { return &m_options; }
1939
1940 class CommandOptions : public Options {
1941 public:
1942 CommandOptions() = default;
1943
1944 ~CommandOptions() override = default;
1945
1946 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1947 ExecutionContext *execution_context) override {
1948 Status error;
1949 const int short_option = m_getopt_table[option_idx].val;
1950
1951 switch (short_option) {
1952 case 'm':
1955 break;
1956
1957 case 's':
1959 option_arg, GetDefinitions()[option_idx].enum_values,
1961 break;
1962
1963 default:
1964 llvm_unreachable("Unimplemented option");
1965 }
1966 return error;
1967 }
1968
1969 void OptionParsingStarting(ExecutionContext *execution_context) override {
1972 }
1973
1974 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1975 return llvm::ArrayRef(g_target_modules_dump_symtab_options);
1976 }
1977
1980 };
1981
1982protected:
1983 bool DoExecute(Args &command, CommandReturnObject &result) override {
1984 Target *target = &GetSelectedTarget();
1985 uint32_t num_dumped = 0;
1986 Mangled::NamePreference name_preference =
1987 (m_options.m_prefer_mangled ? Mangled::ePreferMangled
1988 : Mangled::ePreferDemangled);
1989
1990 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1991 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1992 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1993
1994 if (command.GetArgumentCount() == 0) {
1995 // Dump all sections for all modules images
1996 const ModuleList &module_list = target->GetImages();
1997 std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
1998 const size_t num_modules = module_list.GetSize();
1999 if (num_modules > 0) {
2000 result.GetOutputStream().Format(
2001 "Dumping symbol table for {0} modules.\n", num_modules);
2002 for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
2003 if (num_dumped > 0) {
2004 result.GetOutputStream().EOL();
2005 result.GetOutputStream().EOL();
2006 }
2007 if (GetDebugger().InterruptRequested())
2008 break;
2009 num_dumped++;
2011 module_sp.get(), m_options.m_sort_order,
2012 name_preference);
2013 }
2014 } else {
2015 result.AppendError("the target has no associated executable images");
2016 return false;
2017 }
2018 } else {
2019 // Dump specified images (by basename or fullpath)
2020 const char *arg_cstr;
2021 for (int arg_idx = 0;
2022 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2023 ++arg_idx) {
2024 ModuleList module_list;
2025 const size_t num_matches =
2026 FindModulesByName(target, arg_cstr, module_list, true);
2027 if (num_matches > 0) {
2028 for (ModuleSP module_sp : module_list.Modules()) {
2029 if (module_sp) {
2030 if (num_dumped > 0) {
2031 result.GetOutputStream().EOL();
2032 result.GetOutputStream().EOL();
2033 }
2034 if (GetDebugger().InterruptRequested())
2035 break;
2036 num_dumped++;
2038 module_sp.get(), m_options.m_sort_order,
2039 name_preference);
2040 }
2041 }
2042 } else
2044 "Unable to find an image that matches '%s'.\n", arg_cstr);
2045 }
2046 }
2047
2048 if (num_dumped > 0)
2050 else {
2051 result.AppendError("no matching executable images found");
2052 }
2053 return result.Succeeded();
2054 }
2055
2057};
2058
2059#pragma mark CommandObjectTargetModulesDumpSections
2060
2061// Image section dumping command
2062
2065public:
2068 interpreter, "target modules dump sections",
2069 "Dump the sections from one or more target modules.",
2070 //"target modules dump sections [<file1> ...]")
2071 nullptr, eCommandRequiresTarget) {}
2072
2074
2075protected:
2076 bool DoExecute(Args &command, CommandReturnObject &result) override {
2077 Target *target = &GetSelectedTarget();
2078 uint32_t num_dumped = 0;
2079
2080 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2081 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2082 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2083
2084 if (command.GetArgumentCount() == 0) {
2085 // Dump all sections for all modules images
2086 const size_t num_modules = target->GetImages().GetSize();
2087 if (num_modules == 0) {
2088 result.AppendError("the target has no associated executable images");
2089 return false;
2090 }
2091
2092 result.GetOutputStream().Format("Dumping sections for {0} modules.\n",
2093 num_modules);
2094 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2095 if (GetDebugger().InterruptRequested())
2096 break;
2097 num_dumped++;
2100 target->GetImages().GetModulePointerAtIndex(image_idx));
2101 }
2102 } else {
2103 // Dump specified images (by basename or fullpath)
2104 const char *arg_cstr;
2105 for (int arg_idx = 0;
2106 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2107 ++arg_idx) {
2108 ModuleList module_list;
2109 const size_t num_matches =
2110 FindModulesByName(target, arg_cstr, module_list, true);
2111 if (num_matches > 0) {
2112 for (size_t i = 0; i < num_matches; ++i) {
2113 if (GetDebugger().InterruptRequested())
2114 break;
2115 Module *module = module_list.GetModulePointerAtIndex(i);
2116 if (module) {
2117 num_dumped++;
2119 module);
2120 }
2121 }
2122 } else {
2123 // Check the global list
2124 std::lock_guard<std::recursive_mutex> guard(
2126
2128 "Unable to find an image that matches '%s'.\n", arg_cstr);
2129 }
2130 }
2131 }
2132
2133 if (num_dumped > 0)
2135 else {
2136 result.AppendError("no matching executable images found");
2137 }
2138 return result.Succeeded();
2139 }
2140};
2141
2143public:
2146 interpreter, "target modules dump pcm-info",
2147 "Dump information about the given clang module (pcm).") {
2148 // Take a single file argument.
2150 m_arguments.push_back({arg});
2151 }
2152
2154
2155protected:
2156 bool DoExecute(Args &command, CommandReturnObject &result) override {
2157 if (command.GetArgumentCount() != 1) {
2158 result.AppendErrorWithFormat("'%s' takes exactly one pcm path argument.",
2159 m_cmd_name.c_str());
2160 return false;
2161 }
2162
2163 const char *pcm_path = command.GetArgumentAtIndex(0);
2164 FileSpec pcm_file{pcm_path};
2165
2166 if (pcm_file.GetFileNameExtension().GetStringRef() != ".pcm") {
2167 result.AppendError("file must have a .pcm extension");
2168 return false;
2169 }
2170
2171 if (!FileSystem::Instance().Exists(pcm_file)) {
2172 result.AppendError("pcm file does not exist");
2173 return false;
2174 }
2175
2176 clang::CompilerInstance compiler;
2177 compiler.createDiagnostics();
2178
2179 const char *clang_args[] = {"clang", pcm_path};
2180 compiler.setInvocation(clang::createInvocation(clang_args));
2181
2182 clang::DumpModuleInfoAction dump_module_info;
2183 dump_module_info.OutputStream = &result.GetOutputStream().AsRawOstream();
2184 // DumpModuleInfoAction requires ObjectFilePCHContainerReader.
2185 compiler.getPCHContainerOperations()->registerReader(
2186 std::make_unique<clang::ObjectFilePCHContainerReader>());
2187
2188 if (compiler.ExecuteAction(dump_module_info))
2190
2191 return result.Succeeded();
2192 }
2193};
2194
2195#pragma mark CommandObjectTargetModulesDumpClangAST
2196
2197// Clang AST dumping command
2198
2201public:
2204 interpreter, "target modules dump ast",
2205 "Dump the clang ast for a given module's symbol file.",
2206 //"target modules dump ast [<file1> ...]")
2207 nullptr, eCommandRequiresTarget) {}
2208
2210
2211protected:
2212 bool DoExecute(Args &command, CommandReturnObject &result) override {
2213 Target *target = &GetSelectedTarget();
2214
2215 const ModuleList &module_list = target->GetImages();
2216 const size_t num_modules = module_list.GetSize();
2217 if (num_modules == 0) {
2218 result.AppendError("the target has no associated executable images");
2219 return false;
2220 }
2221
2222 if (command.GetArgumentCount() == 0) {
2223 // Dump all ASTs for all modules images
2224 result.GetOutputStream().Format("Dumping clang ast for {0} modules.\n",
2225 num_modules);
2226 for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
2227 if (GetDebugger().InterruptRequested())
2228 break;
2229 if (SymbolFile *sf = module_sp->GetSymbolFile())
2230 sf->DumpClangAST(result.GetOutputStream());
2231 }
2233 return true;
2234 }
2235
2236 // Dump specified ASTs (by basename or fullpath)
2237 for (const Args::ArgEntry &arg : command.entries()) {
2238 ModuleList module_list;
2239 const size_t num_matches =
2240 FindModulesByName(target, arg.c_str(), module_list, true);
2241 if (num_matches == 0) {
2242 // Check the global list
2243 std::lock_guard<std::recursive_mutex> guard(
2245
2247 "Unable to find an image that matches '%s'.\n", arg.c_str());
2248 continue;
2249 }
2250
2251 for (size_t i = 0; i < num_matches; ++i) {
2252 if (GetDebugger().InterruptRequested())
2253 break;
2254 Module *m = module_list.GetModulePointerAtIndex(i);
2255 if (SymbolFile *sf = m->GetSymbolFile())
2256 sf->DumpClangAST(result.GetOutputStream());
2257 }
2258 }
2260 return true;
2261 }
2262};
2263
2264#pragma mark CommandObjectTargetModulesDumpSymfile
2265
2266// Image debug symbol dumping command
2267
2270public:
2273 interpreter, "target modules dump symfile",
2274 "Dump the debug symbol file for one or more target modules.",
2275 //"target modules dump symfile [<file1> ...]")
2276 nullptr, eCommandRequiresTarget) {}
2277
2279
2280protected:
2281 bool DoExecute(Args &command, CommandReturnObject &result) override {
2282 Target *target = &GetSelectedTarget();
2283 uint32_t num_dumped = 0;
2284
2285 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2286 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2287 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2288
2289 if (command.GetArgumentCount() == 0) {
2290 // Dump all sections for all modules images
2291 const ModuleList &target_modules = target->GetImages();
2292 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2293 const size_t num_modules = target_modules.GetSize();
2294 if (num_modules == 0) {
2295 result.AppendError("the target has no associated executable images");
2296 return false;
2297 }
2298 result.GetOutputStream().Format(
2299 "Dumping debug symbols for {0} modules.\n", num_modules);
2300 for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
2301 if (GetDebugger().InterruptRequested())
2302 break;
2303 if (DumpModuleSymbolFile(result.GetOutputStream(), module_sp.get()))
2304 num_dumped++;
2305 }
2306 } else {
2307 // Dump specified images (by basename or fullpath)
2308 const char *arg_cstr;
2309 for (int arg_idx = 0;
2310 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2311 ++arg_idx) {
2312 ModuleList module_list;
2313 const size_t num_matches =
2314 FindModulesByName(target, arg_cstr, module_list, true);
2315 if (num_matches > 0) {
2316 for (size_t i = 0; i < num_matches; ++i) {
2317 if (GetDebugger().InterruptRequested())
2318 break;
2319 Module *module = module_list.GetModulePointerAtIndex(i);
2320 if (module) {
2321 if (DumpModuleSymbolFile(result.GetOutputStream(), module))
2322 num_dumped++;
2323 }
2324 }
2325 } else
2327 "Unable to find an image that matches '%s'.\n", arg_cstr);
2328 }
2329 }
2330
2331 if (num_dumped > 0)
2333 else {
2334 result.AppendError("no matching executable images found");
2335 }
2336 return result.Succeeded();
2337 }
2338};
2339
2340#pragma mark CommandObjectTargetModulesDumpLineTable
2341#define LLDB_OPTIONS_target_modules_dump
2342#include "CommandOptions.inc"
2343
2344// Image debug line table dumping command
2345
2348public:
2351 interpreter, "target modules dump line-table",
2352 "Dump the line table for one or more compilation units.", nullptr,
2353 eCommandRequiresTarget) {}
2354
2356
2357 Options *GetOptions() override { return &m_options; }
2358
2359protected:
2360 bool DoExecute(Args &command, CommandReturnObject &result) override {
2361 Target *target = m_exe_ctx.GetTargetPtr();
2362 uint32_t total_num_dumped = 0;
2363
2364 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2365 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2366 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2367
2368 if (command.GetArgumentCount() == 0) {
2369 result.AppendError("file option must be specified.");
2370 return result.Succeeded();
2371 } else {
2372 // Dump specified images (by basename or fullpath)
2373 const char *arg_cstr;
2374 for (int arg_idx = 0;
2375 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2376 ++arg_idx) {
2377 FileSpec file_spec(arg_cstr);
2378
2379 const ModuleList &target_modules = target->GetImages();
2380 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2381 if (target_modules.GetSize() > 0) {
2382 uint32_t num_dumped = 0;
2383 for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
2384 if (GetDebugger().InterruptRequested())
2385 break;
2387 m_interpreter, result.GetOutputStream(), module_sp.get(),
2388 file_spec,
2391 num_dumped++;
2392 }
2393 if (num_dumped == 0)
2395 "No source filenames matched '%s'.\n", arg_cstr);
2396 else
2397 total_num_dumped += num_dumped;
2398 }
2399 }
2400 }
2401
2402 if (total_num_dumped > 0)
2404 else {
2405 result.AppendError("no source filenames matched any command arguments");
2406 }
2407 return result.Succeeded();
2408 }
2409
2410 class CommandOptions : public Options {
2411 public:
2413
2414 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2415 ExecutionContext *execution_context) override {
2416 assert(option_idx == 0 && "We only have one option.");
2417 m_verbose = true;
2418
2419 return Status();
2420 }
2421
2422 void OptionParsingStarting(ExecutionContext *execution_context) override {
2423 m_verbose = false;
2424 }
2425
2426 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2427 return llvm::ArrayRef(g_target_modules_dump_options);
2428 }
2429
2431 };
2432
2434};
2435
2436#pragma mark CommandObjectTargetModulesDump
2437
2438// Dump multi-word command for target modules
2439
2441public:
2442 // Constructors and Destructors
2445 interpreter, "target modules dump",
2446 "Commands for dumping information about one or more target "
2447 "modules.",
2448 "target modules dump "
2449 "[objfile|symtab|sections|ast|symfile|line-table|pcm-info] "
2450 "[<file1> <file2> ...]") {
2451 LoadSubCommand("objfile",
2452 CommandObjectSP(
2453 new CommandObjectTargetModulesDumpObjfile(interpreter)));
2455 "symtab",
2456 CommandObjectSP(new CommandObjectTargetModulesDumpSymtab(interpreter)));
2457 LoadSubCommand("sections",
2458 CommandObjectSP(new CommandObjectTargetModulesDumpSections(
2459 interpreter)));
2460 LoadSubCommand("symfile",
2461 CommandObjectSP(
2462 new CommandObjectTargetModulesDumpSymfile(interpreter)));
2464 "ast", CommandObjectSP(
2465 new CommandObjectTargetModulesDumpClangAST(interpreter)));
2466 LoadSubCommand("line-table",
2467 CommandObjectSP(new CommandObjectTargetModulesDumpLineTable(
2468 interpreter)));
2470 "pcm-info",
2471 CommandObjectSP(
2473 }
2474
2476};
2477
2479public:
2481 : CommandObjectParsed(interpreter, "target modules add",
2482 "Add a new module to the current target's modules.",
2483 "target modules add [<module>]",
2484 eCommandRequiresTarget),
2485 m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
2487 "Fullpath to a stand alone debug "
2488 "symbols file for when debug symbols "
2489 "are not in the executable.") {
2495 m_arguments.push_back({module_arg});
2496 }
2497
2499
2500 Options *GetOptions() override { return &m_option_group; }
2501
2502 void
2504 OptionElementVector &opt_element_vector) override {
2507 request, nullptr);
2508 }
2509
2510protected:
2514
2515 bool DoExecute(Args &args, CommandReturnObject &result) override {
2516 Target *target = &GetSelectedTarget();
2517 bool flush = false;
2518
2519 const size_t argc = args.GetArgumentCount();
2520 if (argc == 0) {
2522 // We are given a UUID only, go locate the file
2523 ModuleSpec module_spec;
2524 module_spec.GetUUID() =
2527 module_spec.GetSymbolFileSpec() =
2529 Status error;
2530 if (Symbols::DownloadObjectAndSymbolFile(module_spec, error)) {
2531 ModuleSP module_sp(
2532 target->GetOrCreateModule(module_spec, true /* notify */));
2533 if (module_sp) {
2535 return true;
2536 } else {
2537 StreamString strm;
2538 module_spec.GetUUID().Dump(&strm);
2539 if (module_spec.GetFileSpec()) {
2540 if (module_spec.GetSymbolFileSpec()) {
2541 result.AppendErrorWithFormat(
2542 "Unable to create the executable or symbol file with "
2543 "UUID %s with path %s and symbol file %s",
2544 strm.GetData(), module_spec.GetFileSpec().GetPath().c_str(),
2545 module_spec.GetSymbolFileSpec().GetPath().c_str());
2546 } else {
2547 result.AppendErrorWithFormat(
2548 "Unable to create the executable or symbol file with "
2549 "UUID %s with path %s",
2550 strm.GetData(),
2551 module_spec.GetFileSpec().GetPath().c_str());
2552 }
2553 } else {
2554 result.AppendErrorWithFormat("Unable to create the executable "
2555 "or symbol file with UUID %s",
2556 strm.GetData());
2557 }
2558 return false;
2559 }
2560 } else {
2561 StreamString strm;
2562 module_spec.GetUUID().Dump(&strm);
2563 result.AppendErrorWithFormat(
2564 "Unable to locate the executable or symbol file with UUID %s",
2565 strm.GetData());
2566 result.SetError(error);
2567 return false;
2568 }
2569 } else {
2570 result.AppendError(
2571 "one or more executable image paths must be specified");
2572 return false;
2573 }
2574 } else {
2575 for (auto &entry : args.entries()) {
2576 if (entry.ref().empty())
2577 continue;
2578
2579 FileSpec file_spec(entry.ref());
2580 if (FileSystem::Instance().Exists(file_spec)) {
2581 ModuleSpec module_spec(file_spec);
2583 module_spec.GetUUID() =
2586 module_spec.GetSymbolFileSpec() =
2588 if (!module_spec.GetArchitecture().IsValid())
2589 module_spec.GetArchitecture() = target->GetArchitecture();
2590 Status error;
2591 ModuleSP module_sp(target->GetOrCreateModule(
2592 module_spec, true /* notify */, &error));
2593 if (!module_sp) {
2594 const char *error_cstr = error.AsCString();
2595 if (error_cstr)
2596 result.AppendError(error_cstr);
2597 else
2598 result.AppendErrorWithFormat("unsupported module: %s",
2599 entry.c_str());
2600 return false;
2601 } else {
2602 flush = true;
2603 }
2605 } else {
2606 std::string resolved_path = file_spec.GetPath();
2607 if (resolved_path != entry.ref()) {
2608 result.AppendErrorWithFormat(
2609 "invalid module path '%s' with resolved path '%s'\n",
2610 entry.ref().str().c_str(), resolved_path.c_str());
2611 break;
2612 }
2613 result.AppendErrorWithFormat("invalid module path '%s'\n",
2614 entry.c_str());
2615 break;
2616 }
2617 }
2618 }
2619
2620 if (flush) {
2621 ProcessSP process = target->GetProcessSP();
2622 if (process)
2623 process->Flush();
2624 }
2625
2626 return result.Succeeded();
2627 }
2628};
2629
2632public:
2635 interpreter, "target modules load",
2636 "Set the load addresses for one or more sections in a target "
2637 "module.",
2638 "target modules load [--file <module> --uuid <uuid>] <sect-name> "
2639 "<address> [<sect-name> <address> ....]",
2640 eCommandRequiresTarget),
2641 m_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName,
2642 "Fullpath or basename for module to load.", ""),
2643 m_load_option(LLDB_OPT_SET_1, false, "load", 'l',
2644 "Write file contents to the memory.", false, true),
2645 m_pc_option(LLDB_OPT_SET_1, false, "set-pc-to-entry", 'p',
2646 "Set PC to the entry point."
2647 " Only applicable with '--load' option.",
2648 false, true),
2649 m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset,
2650 "Set the load address for all sections to be the "
2651 "virtual address in the file plus the offset.",
2652 0) {
2660 }
2661
2663
2664 Options *GetOptions() override { return &m_option_group; }
2665
2666protected:
2667 bool DoExecute(Args &args, CommandReturnObject &result) override {
2668 Target *target = &GetSelectedTarget();
2669 const bool load = m_load_option.GetOptionValue().GetCurrentValue();
2670 const bool set_pc = m_pc_option.GetOptionValue().GetCurrentValue();
2671
2672 const size_t argc = args.GetArgumentCount();
2673 ModuleSpec module_spec;
2674 bool search_using_module_spec = false;
2675
2676 // Allow "load" option to work without --file or --uuid option.
2677 if (load) {
2680 ModuleList &module_list = target->GetImages();
2681 if (module_list.GetSize() == 1) {
2682 search_using_module_spec = true;
2683 module_spec.GetFileSpec() =
2684 module_list.GetModuleAtIndex(0)->GetFileSpec();
2685 }
2686 }
2687 }
2688
2690 search_using_module_spec = true;
2691 const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
2692 const bool use_global_module_list = true;
2693 ModuleList module_list;
2694 const size_t num_matches = FindModulesByName(
2695 target, arg_cstr, module_list, use_global_module_list);
2696 if (num_matches == 1) {
2697 module_spec.GetFileSpec() =
2698 module_list.GetModuleAtIndex(0)->GetFileSpec();
2699 } else if (num_matches > 1) {
2700 search_using_module_spec = false;
2701 result.AppendErrorWithFormat(
2702 "more than 1 module matched by name '%s'\n", arg_cstr);
2703 } else {
2704 search_using_module_spec = false;
2705 result.AppendErrorWithFormat("no object file for module '%s'\n",
2706 arg_cstr);
2707 }
2708 }
2709
2711 search_using_module_spec = true;
2712 module_spec.GetUUID() =
2714 }
2715
2716 if (search_using_module_spec) {
2717 ModuleList matching_modules;
2718 target->GetImages().FindModules(module_spec, matching_modules);
2719 const size_t num_matches = matching_modules.GetSize();
2720
2721 char path[PATH_MAX];
2722 if (num_matches == 1) {
2723 Module *module = matching_modules.GetModulePointerAtIndex(0);
2724 if (module) {
2725 ObjectFile *objfile = module->GetObjectFile();
2726 if (objfile) {
2727 SectionList *section_list = module->GetSectionList();
2728 if (section_list) {
2729 bool changed = false;
2730 if (argc == 0) {
2732 const addr_t slide =
2734 const bool slide_is_offset = true;
2735 module->SetLoadAddress(*target, slide, slide_is_offset,
2736 changed);
2737 } else {
2738 result.AppendError("one or more section name + load "
2739 "address pair must be specified");
2740 return false;
2741 }
2742 } else {
2744 result.AppendError("The \"--slide <offset>\" option can't "
2745 "be used in conjunction with setting "
2746 "section load addresses.\n");
2747 return false;
2748 }
2749
2750 for (size_t i = 0; i < argc; i += 2) {
2751 const char *sect_name = args.GetArgumentAtIndex(i);
2752 const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1);
2753 if (sect_name && load_addr_cstr) {
2754 ConstString const_sect_name(sect_name);
2755 addr_t load_addr;
2756 if (llvm::to_integer(load_addr_cstr, load_addr)) {
2757 SectionSP section_sp(
2758 section_list->FindSectionByName(const_sect_name));
2759 if (section_sp) {
2760 if (section_sp->IsThreadSpecific()) {
2761 result.AppendErrorWithFormat(
2762 "thread specific sections are not yet "
2763 "supported (section '%s')\n",
2764 sect_name);
2765 break;
2766 } else {
2767 if (target->GetSectionLoadList()
2768 .SetSectionLoadAddress(section_sp, load_addr))
2769 changed = true;
2771 "section '%s' loaded at 0x%" PRIx64 "\n",
2772 sect_name, load_addr);
2773 }
2774 } else {
2775 result.AppendErrorWithFormat("no section found that "
2776 "matches the section "
2777 "name '%s'\n",
2778 sect_name);
2779 break;
2780 }
2781 } else {
2782 result.AppendErrorWithFormat(
2783 "invalid load address string '%s'\n", load_addr_cstr);
2784 break;
2785 }
2786 } else {
2787 if (sect_name)
2788 result.AppendError("section names must be followed by "
2789 "a load address.\n");
2790 else
2791 result.AppendError("one or more section name + load "
2792 "address pair must be specified.\n");
2793 break;
2794 }
2795 }
2796 }
2797
2798 if (changed) {
2799 target->ModulesDidLoad(matching_modules);
2800 Process *process = m_exe_ctx.GetProcessPtr();
2801 if (process)
2802 process->Flush();
2803 }
2804 if (load) {
2805 ProcessSP process = target->CalculateProcess();
2806 Address file_entry = objfile->GetEntryPointAddress();
2807 if (!process) {
2808 result.AppendError("No process");
2809 return false;
2810 }
2811 if (set_pc && !file_entry.IsValid()) {
2812 result.AppendError("No entry address in object file");
2813 return false;
2814 }
2815 std::vector<ObjectFile::LoadableData> loadables(
2816 objfile->GetLoadableData(*target));
2817 if (loadables.size() == 0) {
2818 result.AppendError("No loadable sections");
2819 return false;
2820 }
2821 Status error = process->WriteObjectFile(std::move(loadables));
2822 if (error.Fail()) {
2823 result.AppendError(error.AsCString());
2824 return false;
2825 }
2826 if (set_pc) {
2827 ThreadList &thread_list = process->GetThreadList();
2828 RegisterContextSP reg_context(
2829 thread_list.GetSelectedThread()->GetRegisterContext());
2830 addr_t file_entry_addr = file_entry.GetLoadAddress(target);
2831 if (!reg_context->SetPC(file_entry_addr)) {
2832 result.AppendErrorWithFormat("failed to set PC value to "
2833 "0x%" PRIx64 "\n",
2834 file_entry_addr);
2835 }
2836 }
2837 }
2838 } else {
2839 module->GetFileSpec().GetPath(path, sizeof(path));
2840 result.AppendErrorWithFormat("no sections in object file '%s'\n",
2841 path);
2842 }
2843 } else {
2844 module->GetFileSpec().GetPath(path, sizeof(path));
2845 result.AppendErrorWithFormat("no object file for module '%s'\n",
2846 path);
2847 }
2848 } else {
2849 FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
2850 if (module_spec_file) {
2851 module_spec_file->GetPath(path, sizeof(path));
2852 result.AppendErrorWithFormat("invalid module '%s'.\n", path);
2853 } else
2854 result.AppendError("no module spec");
2855 }
2856 } else {
2857 std::string uuid_str;
2858
2859 if (module_spec.GetFileSpec())
2860 module_spec.GetFileSpec().GetPath(path, sizeof(path));
2861 else
2862 path[0] = '\0';
2863
2864 if (module_spec.GetUUIDPtr())
2865 uuid_str = module_spec.GetUUID().GetAsString();
2866 if (num_matches > 1) {
2867 result.AppendErrorWithFormat(
2868 "multiple modules match%s%s%s%s:\n", path[0] ? " file=" : "",
2869 path, !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
2870 for (size_t i = 0; i < num_matches; ++i) {
2871 if (matching_modules.GetModulePointerAtIndex(i)
2872 ->GetFileSpec()
2873 .GetPath(path, sizeof(path)))
2874 result.AppendMessageWithFormat("%s\n", path);
2875 }
2876 } else {
2877 result.AppendErrorWithFormat(
2878 "no modules were found that match%s%s%s%s.\n",
2879 path[0] ? " file=" : "", path, !uuid_str.empty() ? " uuid=" : "",
2880 uuid_str.c_str());
2881 }
2882 }
2883 } else {
2884 result.AppendError("either the \"--file <module>\" or the \"--uuid "
2885 "<uuid>\" option must be specified.\n");
2886 return false;
2887 }
2888 return result.Succeeded();
2889 }
2890
2897};
2898
2899#pragma mark CommandObjectTargetModulesList
2900// List images with associated information
2901#define LLDB_OPTIONS_target_modules_list
2902#include "CommandOptions.inc"
2903
2905public:
2906 class CommandOptions : public Options {
2907 public:
2908 CommandOptions() = default;
2909
2910 ~CommandOptions() override = default;
2911
2912 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2913 ExecutionContext *execution_context) override {
2914 Status error;
2915
2916 const int short_option = m_getopt_table[option_idx].val;
2917 if (short_option == 'g') {
2919 } else if (short_option == 'a') {
2921 execution_context, option_arg, LLDB_INVALID_ADDRESS, &error);
2922 } else {
2923 unsigned long width = 0;
2924 option_arg.getAsInteger(0, width);
2925 m_format_array.push_back(std::make_pair(short_option, width));
2926 }
2927 return error;
2928 }
2929
2930 void OptionParsingStarting(ExecutionContext *execution_context) override {
2931 m_format_array.clear();
2934 }
2935
2936 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2937 return llvm::ArrayRef(g_target_modules_list_options);
2938 }
2939
2940 // Instance variables to hold the values for command options.
2941 typedef std::vector<std::pair<char, uint32_t>> FormatWidthCollection;
2945 };
2946
2949 interpreter, "target modules list",
2950 "List current executable and dependent shared library images.") {
2952 m_arguments.push_back({module_arg});
2953 }
2954
2956
2957 Options *GetOptions() override { return &m_options; }
2958
2959protected:
2960 bool DoExecute(Args &command, CommandReturnObject &result) override {
2961 Target *target = GetDebugger().GetSelectedTarget().get();
2962 const bool use_global_module_list = m_options.m_use_global_module_list;
2963 // Define a local module list here to ensure it lives longer than any
2964 // "locker" object which might lock its contents below (through the
2965 // "module_list_ptr" variable).
2966 ModuleList module_list;
2967 if (target == nullptr && !use_global_module_list) {
2968 result.AppendError("invalid target, create a debug target using the "
2969 "'target create' command");
2970 return false;
2971 } else {
2972 if (target) {
2973 uint32_t addr_byte_size =
2975 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2976 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2977 }
2978 // Dump all sections for all modules images
2979 Stream &strm = result.GetOutputStream();
2980
2982 if (target) {
2983 Address module_address;
2984 if (module_address.SetLoadAddress(m_options.m_module_addr, target)) {
2985 ModuleSP module_sp(module_address.GetModule());
2986 if (module_sp) {
2987 PrintModule(target, module_sp.get(), 0, strm);
2989 } else {
2990 result.AppendErrorWithFormat(
2991 "Couldn't find module matching address: 0x%" PRIx64 ".",
2993 }
2994 } else {
2995 result.AppendErrorWithFormat(
2996 "Couldn't find module containing address: 0x%" PRIx64 ".",
2998 }
2999 } else {
3000 result.AppendError(
3001 "Can only look up modules by address with a valid target.");
3002 }
3003 return result.Succeeded();
3004 }
3005
3006 size_t num_modules = 0;
3007
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
3011 // directly.
3012 std::unique_lock<std::recursive_mutex> guard(
3014
3015 const ModuleList *module_list_ptr = nullptr;
3016 const size_t argc = command.GetArgumentCount();
3017 if (argc == 0) {
3018 if (use_global_module_list) {
3019 guard.lock();
3020 num_modules = Module::GetNumberAllocatedModules();
3021 } else {
3022 module_list_ptr = &target->GetImages();
3023 }
3024 } else {
3025 for (const Args::ArgEntry &arg : command) {
3026 // Dump specified images (by basename or fullpath)
3027 const size_t num_matches = FindModulesByName(
3028 target, arg.c_str(), module_list, use_global_module_list);
3029 if (num_matches == 0) {
3030 if (argc == 1) {
3031 result.AppendErrorWithFormat("no modules found that match '%s'",
3032 arg.c_str());
3033 return false;
3034 }
3035 }
3036 }
3037
3038 module_list_ptr = &module_list;
3039 }
3040
3041 std::unique_lock<std::recursive_mutex> lock;
3042 if (module_list_ptr != nullptr) {
3043 lock =
3044 std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex());
3045
3046 num_modules = module_list_ptr->GetSize();
3047 }
3048
3049 if (num_modules > 0) {
3050 for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
3051 ModuleSP module_sp;
3052 Module *module;
3053 if (module_list_ptr) {
3054 module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
3055 module = module_sp.get();
3056 } else {
3057 module = Module::GetAllocatedModuleAtIndex(image_idx);
3058 module_sp = module->shared_from_this();
3059 }
3060
3061 const size_t indent = strm.Printf("[%3u] ", image_idx);
3062 PrintModule(target, module, indent, strm);
3063 }
3065 } else {
3066 if (argc) {
3067 if (use_global_module_list)
3068 result.AppendError(
3069 "the global module list has no matching modules");
3070 else
3071 result.AppendError("the target has no matching modules");
3072 } else {
3073 if (use_global_module_list)
3074 result.AppendError("the global module list is empty");
3075 else
3076 result.AppendError(
3077 "the target has no associated executable images");
3078 }
3079 return false;
3080 }
3081 }
3082 return result.Succeeded();
3083 }
3084
3085 void PrintModule(Target *target, Module *module, int indent, Stream &strm) {
3086 if (module == nullptr) {
3087 strm.PutCString("Null module");
3088 return;
3089 }
3090
3091 bool dump_object_name = false;
3092 if (m_options.m_format_array.empty()) {
3093 m_options.m_format_array.push_back(std::make_pair('u', 0));
3094 m_options.m_format_array.push_back(std::make_pair('h', 0));
3095 m_options.m_format_array.push_back(std::make_pair('f', 0));
3096 m_options.m_format_array.push_back(std::make_pair('S', 0));
3097 }
3098 const size_t num_entries = m_options.m_format_array.size();
3099 bool print_space = false;
3100 for (size_t i = 0; i < num_entries; ++i) {
3101 if (print_space)
3102 strm.PutChar(' ');
3103 print_space = true;
3104 const char format_char = m_options.m_format_array[i].first;
3105 uint32_t width = m_options.m_format_array[i].second;
3106 switch (format_char) {
3107 case 'A':
3108 DumpModuleArchitecture(strm, module, false, width);
3109 break;
3110
3111 case 't':
3112 DumpModuleArchitecture(strm, module, true, width);
3113 break;
3114
3115 case 'f':
3116 DumpFullpath(strm, &module->GetFileSpec(), width);
3117 dump_object_name = true;
3118 break;
3119
3120 case 'd':
3121 DumpDirectory(strm, &module->GetFileSpec(), width);
3122 break;
3123
3124 case 'b':
3125 DumpBasename(strm, &module->GetFileSpec(), width);
3126 dump_object_name = true;
3127 break;
3128
3129 case 'h':
3130 case 'o':
3131 // Image header address
3132 {
3133 uint32_t addr_nibble_width =
3134 target ? (target->GetArchitecture().GetAddressByteSize() * 2)
3135 : 16;
3136
3137 ObjectFile *objfile = module->GetObjectFile();
3138 if (objfile) {
3139 Address base_addr(objfile->GetBaseAddress());
3140 if (base_addr.IsValid()) {
3141 if (target && !target->GetSectionLoadList().IsEmpty()) {
3142 lldb::addr_t load_addr = base_addr.GetLoadAddress(target);
3143 if (load_addr == LLDB_INVALID_ADDRESS) {
3144 base_addr.Dump(&strm, target,
3147 } else {
3148 if (format_char == 'o') {
3149 // Show the offset of slide for the image
3150 strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3151 addr_nibble_width,
3152 load_addr - base_addr.GetFileAddress());
3153 } else {
3154 // Show the load address of the image
3155 strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3156 addr_nibble_width, load_addr);
3157 }
3158 }
3159 break;
3160 }
3161 // The address was valid, but the image isn't loaded, output the
3162 // address in an appropriate format
3163 base_addr.Dump(&strm, target, Address::DumpStyleFileAddress);
3164 break;
3165 }
3166 }
3167 strm.Printf("%*s", addr_nibble_width + 2, "");
3168 }
3169 break;
3170
3171 case 'r': {
3172 size_t ref_count = 0;
3173 ModuleSP module_sp(module->shared_from_this());
3174 if (module_sp) {
3175 // Take one away to make sure we don't count our local "module_sp"
3176 ref_count = module_sp.use_count() - 1;
3177 }
3178 if (width)
3179 strm.Printf("{%*" PRIu64 "}", width, (uint64_t)ref_count);
3180 else
3181 strm.Printf("{%" PRIu64 "}", (uint64_t)ref_count);
3182 } break;
3183
3184 case 's':
3185 case 'S': {
3186 if (const SymbolFile *symbol_file = module->GetSymbolFile()) {
3187 const FileSpec symfile_spec =
3188 symbol_file->GetObjectFile()->GetFileSpec();
3189 if (format_char == 'S') {
3190 // Dump symbol file only if different from module file
3191 if (!symfile_spec || symfile_spec == module->GetFileSpec()) {
3192 print_space = false;
3193 break;
3194 }
3195 // Add a newline and indent past the index
3196 strm.Printf("\n%*s", indent, "");
3197 }
3198 DumpFullpath(strm, &symfile_spec, width);
3199 dump_object_name = true;
3200 break;
3201 }
3202 strm.Printf("%.*s", width, "<NONE>");
3203 } break;
3204
3205 case 'm':
3206 strm.Format("{0:%c}", llvm::fmt_align(module->GetModificationTime(),
3207 llvm::AlignStyle::Left, width));
3208 break;
3209
3210 case 'p':
3211 strm.Printf("%p", static_cast<void *>(module));
3212 break;
3213
3214 case 'u':
3215 DumpModuleUUID(strm, module);
3216 break;
3217
3218 default:
3219 break;
3220 }
3221 }
3222 if (dump_object_name) {
3223 const char *object_name = module->GetObjectName().GetCString();
3224 if (object_name)
3225 strm.Printf("(%s)", object_name);
3226 }
3227 strm.EOL();
3228 }
3229
3231};
3232
3233#pragma mark CommandObjectTargetModulesShowUnwind
3234
3235// Lookup unwind information in images
3236#define LLDB_OPTIONS_target_modules_show_unwind
3237#include "CommandOptions.inc"
3238
3240public:
3241 enum {
3249
3250 class CommandOptions : public Options {
3251 public:
3252 CommandOptions() = default;
3253
3254 ~CommandOptions() override = default;
3255
3256 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3257 ExecutionContext *execution_context) override {
3258 Status error;
3259
3260 const int short_option = m_getopt_table[option_idx].val;
3261
3262 switch (short_option) {
3263 case 'a': {
3264 m_str = std::string(option_arg);
3266 m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
3269 error.SetErrorStringWithFormat("invalid address string '%s'",
3270 option_arg.str().c_str());
3271 break;
3272 }
3273
3274 case 'n':
3275 m_str = std::string(option_arg);
3277 break;
3278
3279 default:
3280 llvm_unreachable("Unimplemented option");
3281 }
3282
3283 return error;
3284 }
3285
3286 void OptionParsingStarting(ExecutionContext *execution_context) override {
3288 m_str.clear();
3290 }
3291
3292 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3293 return llvm::ArrayRef(g_target_modules_show_unwind_options);
3294 }
3295
3296 // Instance variables to hold the values for command options.
3297
3298 int m_type = eLookupTypeInvalid; // Should be a eLookupTypeXXX enum after
3299 // parsing options
3300 std::string m_str; // Holds name lookup
3301 lldb::addr_t m_addr = LLDB_INVALID_ADDRESS; // Holds the address to lookup
3302 };
3303
3306 interpreter, "target modules show-unwind",
3307 "Show synthesized unwind instructions for a function.", nullptr,
3308 eCommandRequiresTarget | eCommandRequiresProcess |
3309 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {}
3310
3312
3313 Options *GetOptions() override { return &m_options; }
3314
3315protected:
3316 bool DoExecute(Args &command, CommandReturnObject &result) override {
3317 Target *target = m_exe_ctx.GetTargetPtr();
3318 Process *process = m_exe_ctx.GetProcessPtr();
3319 ABI *abi = nullptr;
3320 if (process)
3321 abi = process->GetABI().get();
3322
3323 if (process == nullptr) {
3324 result.AppendError(
3325 "You must have a process running to use this command.");
3326 return false;
3327 }
3328
3329 ThreadList threads(process->GetThreadList());
3330 if (threads.GetSize() == 0) {
3331 result.AppendError("The process must be paused to use this command.");
3332 return false;
3333 }
3334
3335 ThreadSP thread(threads.GetThreadAtIndex(0));
3336 if (!thread) {
3337 result.AppendError("The process must be paused to use this command.");
3338 return false;
3339 }
3340
3341 SymbolContextList sc_list;
3342
3344 ConstString function_name(m_options.m_str.c_str());
3345 ModuleFunctionSearchOptions function_options;
3346 function_options.include_symbols = true;
3347 function_options.include_inlines = false;
3348 target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto,
3349 function_options, sc_list);
3350 } else if (m_options.m_type == eLookupTypeAddress && target) {
3351 Address addr;
3353 addr)) {
3354 SymbolContext sc;
3355 ModuleSP module_sp(addr.GetModule());
3356 module_sp->ResolveSymbolContextForAddress(addr,
3357 eSymbolContextEverything, sc);
3358 if (sc.function || sc.symbol) {
3359 sc_list.Append(sc);
3360 }
3361 }
3362 } else {
3363 result.AppendError(
3364 "address-expression or function name option must be specified.");
3365 return false;
3366 }
3367
3368 size_t num_matches = sc_list.GetSize();
3369 if (num_matches == 0) {
3370 result.AppendErrorWithFormat("no unwind data found that matches '%s'.",
3371 m_options.m_str.c_str());
3372 return false;
3373 }
3374
3375 for (uint32_t idx = 0; idx < num_matches; idx++) {
3376 SymbolContext sc;
3377 sc_list.GetContextAtIndex(idx, sc);
3378 if (sc.symbol == nullptr && sc.function == nullptr)
3379 continue;
3380 if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr)
3381 continue;
3382 AddressRange range;
3383 if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,
3384 false, range))
3385 continue;
3386 if (!range.GetBaseAddress().IsValid())
3387 continue;
3388 ConstString funcname(sc.GetFunctionName());
3389 if (funcname.IsEmpty())
3390 continue;
3391 addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
3392 if (abi)
3393 start_addr = abi->FixCodeAddress(start_addr);
3394
3395 FuncUnwindersSP func_unwinders_sp(
3396 sc.module_sp->GetUnwindTable()
3397 .GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
3398 if (!func_unwinders_sp)
3399 continue;
3400
3401 result.GetOutputStream().Printf(
3402 "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n",
3403 sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(),
3404 funcname.AsCString(), start_addr);
3405
3406 Args args;
3408 size_t count = args.GetArgumentCount();
3409 for (size_t i = 0; i < count; i++) {
3410 const char *trap_func_name = args.GetArgumentAtIndex(i);
3411 if (strcmp(funcname.GetCString(), trap_func_name) == 0)
3412 result.GetOutputStream().Printf(
3413 "This function is "
3414 "treated as a trap handler function via user setting.\n");
3415 }
3416 PlatformSP platform_sp(target->GetPlatform());
3417 if (platform_sp) {
3418 const std::vector<ConstString> trap_handler_names(
3419 platform_sp->GetTrapHandlerSymbolNames());
3420 for (ConstString trap_name : trap_handler_names) {
3421 if (trap_name == funcname) {
3422 result.GetOutputStream().Printf(
3423 "This function's "
3424 "name is listed by the platform as a trap handler.\n");
3425 }
3426 }
3427 }
3428
3429 result.GetOutputStream().Printf("\n");
3430
3431 UnwindPlanSP non_callsite_unwind_plan =
3432 func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread);
3433 if (non_callsite_unwind_plan) {
3434 result.GetOutputStream().Printf(
3435 "Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n",
3436 non_callsite_unwind_plan->GetSourceName().AsCString());
3437 }
3438 UnwindPlanSP callsite_unwind_plan =
3439 func_unwinders_sp->GetUnwindPlanAtCallSite(*target, *thread);
3440 if (callsite_unwind_plan) {
3441 result.GetOutputStream().Printf(
3442 "Synchronous (restricted to call-sites) UnwindPlan is '%s'\n",
3443 callsite_unwind_plan->GetSourceName().AsCString());
3444 }
3445 UnwindPlanSP fast_unwind_plan =
3446 func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread);
3447 if (fast_unwind_plan) {
3448 result.GetOutputStream().Printf(
3449 "Fast UnwindPlan is '%s'\n",
3450 fast_unwind_plan->GetSourceName().AsCString());
3451 }
3452
3453 result.GetOutputStream().Printf("\n");
3454
3455 UnwindPlanSP assembly_sp =
3456 func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread);
3457 if (assembly_sp) {
3458 result.GetOutputStream().Printf(
3459 "Assembly language inspection UnwindPlan:\n");
3460 assembly_sp->Dump(result.GetOutputStream(), thread.get(),
3462 result.GetOutputStream().Printf("\n");
3463 }
3464
3465 UnwindPlanSP of_unwind_sp =
3466 func_unwinders_sp->GetObjectFileUnwindPlan(*target);
3467 if (of_unwind_sp) {
3468 result.GetOutputStream().Printf("object file UnwindPlan:\n");
3469 of_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3471 result.GetOutputStream().Printf("\n");
3472 }
3473
3474 UnwindPlanSP of_unwind_augmented_sp =
3475 func_unwinders_sp->GetObjectFileAugmentedUnwindPlan(*target, *thread);
3476 if (of_unwind_augmented_sp) {
3477 result.GetOutputStream().Printf("object file augmented UnwindPlan:\n");
3478 of_unwind_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
3480 result.GetOutputStream().Printf("\n");
3481 }
3482
3483 UnwindPlanSP ehframe_sp =
3484 func_unwinders_sp->GetEHFrameUnwindPlan(*target);
3485 if (ehframe_sp) {
3486 result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
3487 ehframe_sp->Dump(result.GetOutputStream(), thread.get(),
3489 result.GetOutputStream().Printf("\n");
3490 }
3491
3492 UnwindPlanSP ehframe_augmented_sp =
3493 func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread);
3494 if (ehframe_augmented_sp) {
3495 result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
3496 ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
3498 result.GetOutputStream().Printf("\n");
3499 }
3500
3501 if (UnwindPlanSP plan_sp =
3502 func_unwinders_sp->GetDebugFrameUnwindPlan(*target)) {
3503 result.GetOutputStream().Printf("debug_frame UnwindPlan:\n");
3504 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3506 result.GetOutputStream().Printf("\n");
3507 }
3508
3509 if (UnwindPlanSP plan_sp =
3510 func_unwinders_sp->GetDebugFrameAugmentedUnwindPlan(*target,
3511 *thread)) {
3512 result.GetOutputStream().Printf("debug_frame augmented UnwindPlan:\n");
3513 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3515 result.GetOutputStream().Printf("\n");
3516 }
3517
3518 UnwindPlanSP arm_unwind_sp =
3519 func_unwinders_sp->GetArmUnwindUnwindPlan(*target);
3520 if (arm_unwind_sp) {
3521 result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
3522 arm_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3524 result.GetOutputStream().Printf("\n");
3525 }
3526
3527 if (UnwindPlanSP symfile_plan_sp =
3528 func_unwinders_sp->GetSymbolFileUnwindPlan(*thread)) {
3529 result.GetOutputStream().Printf("Symbol file UnwindPlan:\n");
3530 symfile_plan_sp->Dump(result.GetOutputStream(), thread.get(),
3532 result.GetOutputStream().Printf("\n");
3533 }
3534
3535 UnwindPlanSP compact_unwind_sp =
3536 func_unwinders_sp->GetCompactUnwindUnwindPlan(*target);
3537 if (compact_unwind_sp) {
3538 result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
3539 compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3541 result.GetOutputStream().Printf("\n");
3542 }
3543
3544 if (fast_unwind_plan) {
3545 result.GetOutputStream().Printf("Fast UnwindPlan:\n");
3546 fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(),
3548 result.GetOutputStream().Printf("\n");
3549 }
3550
3551 ABISP abi_sp = process->GetABI();
3552 if (abi_sp) {
3554 if (abi_sp->CreateDefaultUnwindPlan(arch_default)) {
3555 result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
3556 arch_default.Dump(result.GetOutputStream(), thread.get(),
3558 result.GetOutputStream().Printf("\n");
3559 }
3560
3562 if (abi_sp->CreateFunctionEntryUnwindPlan(arch_entry)) {
3563 result.GetOutputStream().Printf(
3564 "Arch default at entry point UnwindPlan:\n");
3565 arch_entry.Dump(result.GetOutputStream(), thread.get(),
3567 result.GetOutputStream().Printf("\n");
3568 }
3569 }
3570
3571 result.GetOutputStream().Printf("\n");
3572 }
3573 return result.Succeeded();
3574 }
3575
3577};
3578
3579// Lookup information in images
3580#define LLDB_OPTIONS_target_modules_lookup
3581#include "CommandOptions.inc"
3582
3584public:
3585 enum {
3589 eLookupTypeFileLine, // Line is optional
3595
3596 class CommandOptions : public Options {
3597 public:
3599
3600 ~CommandOptions() override = default;
3601
3602 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3603 ExecutionContext *execution_context) override {
3604 Status error;
3605
3606 const int short_option = m_getopt_table[option_idx].val;
3607
3608 switch (short_option) {
3609 case 'a': {
3611 m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
3613 } break;
3614
3615 case 'o':
3616 if (option_arg.getAsInteger(0, m_offset))
3617 error.SetErrorStringWithFormat("invalid offset string '%s'",
3618 option_arg.str().c_str());
3619 break;
3620
3621 case 's':
3622 m_str = std::string(option_arg);
3624 break;
3625
3626 case 'f':
3627 m_file.SetFile(option_arg, FileSpec::Style::native);
3629 break;
3630
3631 case 'i':
3632 m_include_inlines = false;
3633 break;
3634
3635 case 'l':
3636 if (option_arg.getAsInteger(0, m_line_number))
3637 error.SetErrorStringWithFormat("invalid line number string '%s'",
3638 option_arg.str().c_str());
3639 else if (m_line_number == 0)
3640 error.SetErrorString("zero is an invalid line number");
3642 break;
3643
3644 case 'F':
3645 m_str = std::string(option_arg);
3647 break;
3648
3649 case 'n':
3650 m_str = std::string(option_arg);
3652 break;
3653
3654 case 't':
3655 m_str = std::string(option_arg);
3657 break;
3658
3659 case 'v':
3660 m_verbose = true;
3661 break;
3662
3663 case 'A':
3664 m_print_all = true;
3665 break;
3666
3667 case 'r':
3668 m_use_regex = true;
3669 break;
3670
3671 case '\x01':
3672 m_all_ranges = true;
3673 break;
3674 default:
3675 llvm_unreachable("Unimplemented option");
3676 }
3677
3678 return error;
3679 }
3680
3681 void OptionParsingStarting(ExecutionContext *execution_context) override {
3683 m_str.clear();
3684 m_file.Clear();
3686 m_offset = 0;
3687 m_line_number = 0;
3688 m_use_regex = false;
3689 m_include_inlines = true;
3690 m_all_ranges = false;
3691 m_verbose = false;
3692 m_print_all = false;
3693 }
3694
3695 Status OptionParsingFinished(ExecutionContext *execution_context) override {
3696 Status status;
3697 if (m_all_ranges && !m_verbose) {
3698 status.SetErrorString("--show-variable-ranges must be used in "
3699 "conjunction with --verbose.");
3700 }
3701 return status;
3702 }
3703
3704 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3705 return llvm::ArrayRef(g_target_modules_lookup_options);
3706 }
3707
3708 int m_type; // Should be a eLookupTypeXXX enum after parsing options
3709 std::string m_str; // Holds name lookup
3710 FileSpec m_file; // Files for file lookups
3711 lldb::addr_t m_addr; // Holds the address to lookup
3713 m_offset; // Subtract this offset from m_addr before doing lookups.
3714 uint32_t m_line_number; // Line number for file+line lookups
3715 bool m_use_regex; // Name lookups in m_str are regular expressions.
3716 bool m_include_inlines; // Check for inline entries when looking up by
3717 // file/line.
3718 bool m_all_ranges; // Print all ranges or single range.
3719 bool m_verbose; // Enable verbose lookup info
3720 bool m_print_all; // Print all matches, even in cases where there's a best
3721 // match.
3722 };
3723
3725 : CommandObjectParsed(interpreter, "target modules lookup",
3726 "Look up information within executable and "
3727 "dependent shared library images.",
3728 nullptr, eCommandRequiresTarget) {
3730 CommandArgumentData file_arg;
3731
3732 // Define the first (and only) variant of this arg.
3733 file_arg.arg_type = eArgTypeFilename;
3734 file_arg.arg_repetition = eArgRepeatStar;
3735
3736 // There is only one variant this argument could be; put it into the
3737 // argument entry.
3738 arg.push_back(file_arg);
3739
3740 // Push the data for the first argument into the m_arguments vector.
3741 m_arguments.push_back(arg);
3742 }
3743
3745
3746 Options *GetOptions() override { return &m_options; }
3747
3749 bool &syntax_error) {
3750 switch (m_options.m_type) {
3751 case eLookupTypeAddress:
3755 case eLookupTypeSymbol:
3756 default:
3757 return false;
3758 case eLookupTypeType:
3759 break;
3760 }
3761
3762 StackFrameSP frame = m_exe_ctx.GetFrameSP();
3763
3764 if (!frame)
3765 return false;
3766
3767 const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
3768
3769 if (!sym_ctx.module_sp)
3770 return false;
3771
3772 switch (m_options.m_type) {
3773 default:
3774 return false;
3775 case eLookupTypeType:
3776 if (!m_options.m_str.empty()) {
3778 result.GetOutputStream(), *sym_ctx.module_sp,
3781 return true;
3782 }
3783 }
3784 break;
3785 }
3786
3787 return false;
3788 }
3789
3790 bool LookupInModule(CommandInterpreter &interpreter, Module *module,
3791 CommandReturnObject &result, bool &syntax_error) {
3792 switch (m_options.m_type) {
3793 case eLookupTypeAddress:
3796 m_interpreter, result.GetOutputStream(), module,
3797 eSymbolContextEverything |
3799 ? static_cast<int>(eSymbolContextVariable)
3800 : 0),
3804 return true;
3805 }
3806 }
3807 break;
3808
3809 case eLookupTypeSymbol:
3810 if (!m_options.m_str.empty()) {
3812 module, m_options.m_str.c_str(),
3816 return true;
3817 }
3818 }
3819 break;
3820
3822 if (m_options.m_file) {
3824 m_interpreter, result.GetOutputStream(), module,
3829 return true;
3830 }
3831 }
3832 break;
3833
3836 if (!m_options.m_str.empty()) {
3837 ModuleFunctionSearchOptions function_options;
3838 function_options.include_symbols =
3840 function_options.include_inlines = m_options.m_include_inlines;
3841
3843 module, m_options.m_str.c_str(),
3844 m_options.m_use_regex, function_options,
3848 return true;
3849 }
3850 }
3851 break;
3852
3853 case eLookupTypeType:
3854 if (!m_options.m_str.empty()) {
3857 module, m_options.m_str.c_str(), m_options.m_use_regex)) {
3859 return true;
3860 }
3861 }
3862 break;
3863
3864 default:
3866 result.GetErrorStream(), *this,
3867 GetCommandInterpreter().GetDebugger().GetTerminalWidth());
3868 syntax_error = true;
3869 break;
3870 }
3871
3873 return false;
3874 }
3875
3876protected:
3877 bool DoExecute(Args &command, CommandReturnObject &result) override {
3878 Target *target = &GetSelectedTarget();
3879 bool syntax_error = false;
3880 uint32_t i;
3881 uint32_t num_successful_lookups = 0;
3882 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
3883 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3884 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3885 // Dump all sections for all modules images
3886
3887 if (command.GetArgumentCount() == 0) {
3888 ModuleSP current_module;
3889
3890 // Where it is possible to look in the current symbol context first,
3891 // try that. If this search was successful and --all was not passed,
3892 // don't print anything else.
3893 if (LookupHere(m_interpreter, result, syntax_error)) {
3894 result.GetOutputStream().EOL();
3895 num_successful_lookups++;
3896 if (!m_options.m_print_all) {
3898 return result.Succeeded();
3899 }
3900 }
3901
3902 // Dump all sections for all other modules
3903
3904 const ModuleList &target_modules = target->GetImages();
3905 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
3906 if (target_modules.GetSize() == 0) {
3907 result.AppendError("the target has no associated executable images");
3908 return false;
3909 }
3910
3911 for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
3912 if (module_sp != current_module &&
3913 LookupInModule(m_interpreter, module_sp.get(), result,
3914 syntax_error)) {
3915 result.GetOutputStream().EOL();
3916 num_successful_lookups++;
3917 }
3918 }
3919 } else {
3920 // Dump specified images (by basename or fullpath)
3921 const char *arg_cstr;
3922 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr &&
3923 !syntax_error;
3924 ++i) {
3925 ModuleList module_list;
3926 const size_t num_matches =
3927 FindModulesByName(target, arg_cstr, module_list, false);
3928 if (num_matches > 0) {
3929 for (size_t j = 0; j < num_matches; ++j) {
3930 Module *module = module_list.GetModulePointerAtIndex(j);
3931 if (module) {
3932 if (LookupInModule(m_interpreter, module, result, syntax_error)) {
3933 result.GetOutputStream().EOL();
3934 num_successful_lookups++;
3935 }
3936 }
3937 }
3938 } else
3940 "Unable to find an image that matches '%s'.\n", arg_cstr);
3941 }
3942 }
3943
3944 if (num_successful_lookups > 0)
3946 else
3948 return result.Succeeded();
3949 }
3950
3952};
3953
3954#pragma mark CommandObjectMultiwordImageSearchPaths
3955
3956// CommandObjectMultiwordImageSearchPaths
3957
3959 : public CommandObjectMultiword {
3960public:
3963 interpreter, "target modules search-paths",
3964 "Commands for managing module search paths for a target.",
3965 "target modules search-paths <subcommand> [<subcommand-options>]") {
3967 "add", CommandObjectSP(
3970 "clear", CommandObjectSP(new CommandObjectTargetModulesSearchPathsClear(
3971 interpreter)));
3973 "insert",
3974 CommandObjectSP(
3977 "list", CommandObjectSP(new CommandObjectTargetModulesSearchPathsList(
3978 interpreter)));
3980 "query", CommandObjectSP(new CommandObjectTargetModulesSearchPathsQuery(
3981 interpreter)));
3982 }
3983
3985};
3986
3987#pragma mark CommandObjectTargetModules
3988
3989// CommandObjectTargetModules
3990
3992public:
3993 // Constructors and Destructors
3995 : CommandObjectMultiword(interpreter, "target modules",
3996 "Commands for accessing information for one or "
3997 "more target modules.",
3998 "target modules <sub-command> ...") {
4000 "add", CommandObjectSP(new CommandObjectTargetModulesAdd(interpreter)));
4001 LoadSubCommand("load", CommandObjectSP(new CommandObjectTargetModulesLoad(
4002 interpreter)));
4003 LoadSubCommand("dump", CommandObjectSP(new CommandObjectTargetModulesDump(
4004 interpreter)));
4005 LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetModulesList(
4006 interpreter)));
4008 "lookup",
4009 CommandObjectSP(new CommandObjectTargetModulesLookup(interpreter)));
4011 "search-paths",
4012 CommandObjectSP(
4015 "show-unwind",
4016 CommandObjectSP(new CommandObjectTargetModulesShowUnwind(interpreter)));
4017 }
4018
4019 ~CommandObjectTargetModules() override = default;
4020
4021private:
4022 // For CommandObjectTargetModules only
4026};
4027
4029public:
4032 interpreter, "target symbols add",
4033 "Add a debug symbol file to one of the target's current modules by "
4034 "specifying a path to a debug symbols file or by using the options "
4035 "to specify a module.",
4036 "target symbols add <cmd-options> [<symfile>]",
4037 eCommandRequiresTarget),
4039 LLDB_OPT_SET_1, false, "shlib", 's',
4040 CommandCompletions::eModuleCompletion, eArgTypeShlibName,
4041 "Locate the debug symbols for the shared library specified by "
4042 "name."),
4044 LLDB_OPT_SET_2, false, "frame", 'F',
4045 "Locate the debug symbols for the currently selected frame.", false,
4046 true),
4047 m_current_stack_option(LLDB_OPT_SET_2, false, "stack", 'S',
4048 "Locate the debug symbols for every frame in "
4049 "the current call stack.",
4050 false, true)
4051
4052 {
4062 m_arguments.push_back({module_arg});
4063 }
4064
4066
4067 void
4069 OptionElementVector &opt_element_vector) override {
4072 request, nullptr);
4073 }
4074
4075 Options *GetOptions() override { return &m_option_group; }
4076
4077protected:
4078 bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush,
4079 CommandReturnObject &result) {
4080 const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
4081 if (!symbol_fspec) {
4082 result.AppendError(
4083 "one or more executable image paths must be specified");
4084 return false;
4085 }
4086
4087 char symfile_path[PATH_MAX];
4088 symbol_fspec.GetPath(symfile_path, sizeof(symfile_path));
4089
4090 if (!module_spec.GetUUID().IsValid()) {
4091 if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
4092 module_spec.GetFileSpec().SetFilename(symbol_fspec.GetFilename());
4093 }
4094
4095 // Now module_spec represents a symbol file for a module that might exist
4096 // in the current target. Let's find possible matches.
4097 ModuleList matching_modules;
4098
4099 // First extract all module specs from the symbol file
4100 lldb_private::ModuleSpecList symfile_module_specs;
4102 0, 0, symfile_module_specs)) {
4103 // Now extract the module spec that matches the target architecture
4104 ModuleSpec target_arch_module_spec;
4105 ModuleSpec symfile_module_spec;
4106 target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
4107 if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec,
4108 symfile_module_spec)) {
4109 if (symfile_module_spec.GetUUID().IsValid()) {
4110 // It has a UUID, look for this UUID in the target modules
4111 ModuleSpec symfile_uuid_module_spec;
4112 symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
4113 target->GetImages().FindModules(symfile_uuid_module_spec,
4114 matching_modules);
4115 }
4116 }
4117
4118 if (matching_modules.IsEmpty()) {
4119 // No matches yet. Iterate through the module specs to find a UUID
4120 // value that we can match up to an image in our target.
4121 const size_t num_symfile_module_specs = symfile_module_specs.GetSize();
4122 for (size_t i = 0;
4123 i < num_symfile_module_specs && matching_modules.IsEmpty(); ++i) {
4124 if (symfile_module_specs.GetModuleSpecAtIndex(
4125 i, symfile_module_spec)) {
4126 if (symfile_module_spec.GetUUID().IsValid()) {
4127 // It has a UUID. Look for this UUID in the target modules.
4128 ModuleSpec symfile_uuid_module_spec;
4129 symfile_uuid_module_spec.GetUUID() =
4130 symfile_module_spec.GetUUID();
4131 target->GetImages().FindModules(symfile_uuid_module_spec,
4132 matching_modules);
4133 }
4134 }
4135 }
4136 }
4137 }
4138
4139 // Just try to match up the file by basename if we have no matches at
4140 // this point. For example, module foo might have symbols in foo.debug.
4141 if (matching_modules.IsEmpty())
4142 target->GetImages().FindModules(module_spec, matching_modules);
4143
4144 while (matching_modules.IsEmpty()) {
4145 ConstString filename_no_extension(
4147 // Empty string returned, let's bail
4148 if (!filename_no_extension)
4149 break;
4150
4151 // Check if there was no extension to strip and the basename is the same
4152 if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
4153 break;
4154
4155 // Replace basename with one fewer extension
4156 module_spec.GetFileSpec().SetFilename(filename_no_extension);
4157 target->GetImages().FindModules(module_spec, matching_modules);
4158 }
4159
4160 if (matching_modules.GetSize() > 1) {
4161 result.AppendErrorWithFormat("multiple modules match symbol file '%s', "
4162 "use the --uuid option to resolve the "
4163 "ambiguity.\n",
4164 symfile_path);
4165 return false;
4166 }
4167
4168 if (matching_modules.GetSize() == 1) {
4169 ModuleSP module_sp(matching_modules.GetModuleAtIndex(0));
4170
4171 // The module has not yet created its symbol vendor, we can just give
4172 // the existing target module the symfile path to use for when it
4173 // decides to create it!
4174 module_sp->SetSymbolFileFileSpec(symbol_fspec);
4175
4176 SymbolFile *symbol_file =
4177 module_sp->GetSymbolFile(true, &result.GetErrorStream());
4178 if (symbol_file) {
4179 ObjectFile *object_file = symbol_file->GetObjectFile();
4180 if (object_file && object_file->GetFileSpec() == symbol_fspec) {
4181 // Provide feedback that the symfile has been successfully added.
4182 const FileSpec &module_fs = module_sp->GetFileSpec();
4184 "symbol file '%s' has been added to '%s'\n", symfile_path,
4185 module_fs.GetPath().c_str());
4186
4187 // Let clients know something changed in the module if it is
4188 // currently loaded
4189 ModuleList module_list;
4190 module_list.Append(module_sp);
4191 target->SymbolsDidLoad(module_list);
4192
4193 // Make sure we load any scripting resources that may be embedded
4194 // in the debug info files in case the platform supports that.
4195 Status error;
4196 StreamString feedback_stream;
4197 module_sp->LoadScriptingResourceInTarget(target, error,
4198 &feedback_stream);
4199 if (error.Fail() && error.AsCString())
4201 "unable to load scripting data for module %s - error "
4202 "reported was %s",
4203 module_sp->GetFileSpec()
4204 .GetFileNameStrippingExtension()
4205 .GetCString(),
4206 error.AsCString());
4207 else if (feedback_stream.GetSize())
4208 result.AppendWarning(feedback_stream.GetData());
4209
4210 flush = true;
4212 return true;
4213 }
4214 }
4215 // Clear the symbol file spec if anything went wrong
4216 module_sp->SetSymbolFileFileSpec(FileSpec());
4217 }
4218
4219 StreamString ss_symfile_uuid;
4220 if (module_spec.GetUUID().IsValid()) {
4221 ss_symfile_uuid << " (";
4222 module_spec.GetUUID().Dump(&ss_symfile_uuid);
4223 ss_symfile_uuid << ')';
4224 }
4225 result.AppendErrorWithFormat(
4226 "symbol file '%s'%s does not match any existing module%s\n",
4227 symfile_path, ss_symfile_uuid.GetData(),
4228 !llvm::sys::fs::is_regular_file(symbol_fspec.GetPath())
4229 ? "\n please specify the full path to the symbol file"
4230 : "");
4231 return false;
4232 }
4233
4235 CommandReturnObject &result, bool &flush) {
4236 Status error;
4237 if (Symbols::DownloadObjectAndSymbolFile(module_spec, error)) {
4238 if (module_spec.GetSymbolFileSpec())
4239 return AddModuleSymbols(m_exe_ctx.GetTargetPtr(), module_spec, flush,
4240 result);
4241 } else {
4242 result.SetError(error);
4243 }
4244 return false;
4245 }
4246
4247 bool AddSymbolsForUUID(CommandReturnObject &result, bool &flush) {
4249
4250 ModuleSpec module_spec;
4251 module_spec.GetUUID() =
4253
4254 if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) {
4255 StreamString error_strm;
4256 error_strm.PutCString("unable to find debug symbols for UUID ");
4257 module_spec.GetUUID().Dump(&error_strm);
4258 result.AppendError(error_strm.GetString());
4259 return false;
4260 }
4261
4262 return true;
4263 }
4264
4265 bool AddSymbolsForFile(CommandReturnObject &result, bool &flush) {
4267
4268 ModuleSpec module_spec;
4269 module_spec.GetFileSpec() =
4271
4272 Target *target = m_exe_ctx.GetTargetPtr();
4273 ModuleSP module_sp(target->GetImages().FindFirstModule(module_spec));
4274 if (module_sp) {
4275 module_spec.GetFileSpec() = module_sp->GetFileSpec();
4276 module_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec();
4277 module_spec.GetUUID() = module_sp->GetUUID();
4278 module_spec.GetArchitecture() = module_sp->GetArchitecture();
4279 } else {
4280 module_spec.GetArchitecture() = target->GetArchitecture();
4281 }
4282
4283 if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) {
4284 StreamString error_strm;
4285 error_strm.PutCString(
4286 "unable to find debug symbols for the executable file ");
4287 error_strm << module_spec.GetFileSpec();
4288 result.AppendError(error_strm.GetString());
4289 return false;
4290 }
4291
4292 return true;
4293 }
4294
4295 bool AddSymbolsForFrame(CommandReturnObject &result, bool &flush) {
4297
4298 Process *process = m_exe_ctx.GetProcessPtr();
4299 if (!process) {
4300 result.AppendError(
4301 "a process must exist in order to use the --frame option");
4302 return false;
4303 }
4304
4305 const StateType process_state = process->GetState();
4306 if (!StateIsStoppedState(process_state, true)) {
4307 result.AppendErrorWithFormat("process is not stopped: %s",
4308 StateAsCString(process_state));
4309 return false;
4310 }
4311
4312 StackFrame *frame = m_exe_ctx.GetFramePtr();
4313 if (!frame) {
4314 result.AppendError("invalid current frame");
4315 return false;
4316 }
4317
4318 ModuleSP frame_module_sp(
4319 frame->GetSymbolContext(eSymbolContextModule).module_sp);
4320 if (!frame_module_sp) {
4321 result.AppendError("frame has no module");
4322 return false;
4323 }
4324
4325 ModuleSpec module_spec;
4326 module_spec.GetUUID() = frame_module_sp->GetUUID();
4327
4328 if (FileSystem::Instance().Exists(frame_module_sp->GetPlatformFileSpec())) {
4329 module_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
4330 module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
4331 }
4332
4333 if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) {
4334 result.AppendError("unable to find debug symbols for the current frame");
4335 return false;
4336 }
4337
4338 return true;
4339 }
4340
4341 bool AddSymbolsForStack(CommandReturnObject &result, bool &flush) {
4343
4344 Process *process = m_exe_ctx.GetProcessPtr();
4345 if (!process) {
4346 result.AppendError(
4347 "a process must exist in order to use the --stack option");
4348 return false;
4349 }
4350
4351 const StateType process_state = process->GetState();
4352 if (!StateIsStoppedState(process_state, true)) {
4353 result.AppendErrorWithFormat("process is not stopped: %s",
4354 StateAsCString(process_state));
4355 return false;
4356 }
4357
4358 Thread *thread = m_exe_ctx.GetThreadPtr();
4359 if (!thread) {
4360 result.AppendError("invalid current thread");
4361 return false;
4362 }
4363
4364 bool symbols_found = false;
4365 uint32_t frame_count = thread->GetStackFrameCount();
4366 for (uint32_t i = 0; i < frame_count; ++i) {
4367 lldb::StackFrameSP frame_sp = thread->GetStackFrameAtIndex(i);
4368
4369 ModuleSP frame_module_sp(
4370 frame_sp->GetSymbolContext(eSymbolContextModule).module_sp);
4371 if (!frame_module_sp)
4372 continue;
4373
4374 ModuleSpec module_spec;
4375 module_spec.GetUUID() = frame_module_sp->GetUUID();
4376
4377 if (FileSystem::Instance().Exists(
4378 frame_module_sp->GetPlatformFileSpec())) {
4379 module_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
4380 module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
4381 }
4382
4383 bool current_frame_flush = false;
4384 if (DownloadObjectAndSymbolFile(module_spec, result, current_frame_flush))
4385 symbols_found = true;
4386 flush |= current_frame_flush;
4387 }
4388
4389 if (!symbols_found) {
4390 result.AppendError(
4391 "unable to find debug symbols in the current call stack");
4392 return false;
4393 }
4394
4395 return true;
4396 }
4397
4398 bool DoExecute(Args &args, CommandReturnObject &result) override {
4399 Target *target = m_exe_ctx.GetTargetPtr();
4401 bool flush = false;
4402 ModuleSpec module_spec;
4403 const bool uuid_option_set =
4405 const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
4406 const bool frame_option_set =
4408 const bool stack_option_set =
4410 const size_t argc = args.GetArgumentCount();
4411
4412 if (argc == 0) {
4413 if (uuid_option_set)
4414 AddSymbolsForUUID(result, flush);
4415 else if (file_option_set)
4416 AddSymbolsForFile(result, flush);
4417 else if (frame_option_set)
4418 AddSymbolsForFrame(result, flush);
4419 else if (stack_option_set)
4420 AddSymbolsForStack(result, flush);
4421 else
4422 result.AppendError("one or more symbol file paths must be specified, "
4423 "or options must be specified");
4424 } else {
4425 if (uuid_option_set) {
4426 result.AppendError("specify either one or more paths to symbol files "
4427 "or use the --uuid option without arguments");
4428 } else if (frame_option_set) {
4429 result.AppendError("specify either one or more paths to symbol files "
4430 "or use the --frame option without arguments");
4431 } else if (file_option_set && argc > 1) {
4432 result.AppendError("specify at most one symbol file path when "
4433 "--shlib option is set");
4434 } else {
4435 PlatformSP platform_sp(target->GetPlatform());
4436
4437 for (auto &entry : args.entries()) {
4438 if (!entry.ref().empty()) {
4439 auto &symbol_file_spec = module_spec.GetSymbolFileSpec();
4440 symbol_file_spec.SetFile(entry.ref(), FileSpec::Style::native);
4441 FileSystem::Instance().Resolve(symbol_file_spec);
4442 if (file_option_set) {
4443 module_spec.GetFileSpec() =
4445 }
4446 if (platform_sp) {
4447 FileSpec symfile_spec;
4448 if (platform_sp
4449 ->ResolveSymbolFile(*target, module_spec, symfile_spec)
4450 .Success())
4451 module_spec.GetSymbolFileSpec() = symfile_spec;
4452 }
4453
4454 bool symfile_exists =
4456
4457 if (symfile_exists) {
4458 if (!AddModuleSymbols(target, module_spec, flush, result))
4459 break;
4460 } else {
4461 std::string resolved_symfile_path =
4462 module_spec.GetSymbolFileSpec().GetPath();
4463 if (resolved_symfile_path != entry.ref()) {
4464 result.AppendErrorWithFormat(
4465 "invalid module path '%s' with resolved path '%s'\n",
4466 entry.c_str(), resolved_symfile_path.c_str());
4467 break;
4468 }
4469 result.AppendErrorWithFormat("invalid module path '%s'\n",
4470 entry.c_str());
4471 break;
4472 }
4473 }
4474 }
4475 }
4476 }
4477
4478 if (flush) {
4479 Process *process = m_exe_ctx.GetProcessPtr();
4480 if (process)
4481 process->Flush();
4482 }
4483 return result.Succeeded();
4484 }
4485
4491};
4492
4493#pragma mark CommandObjectTargetSymbols
4494
4495// CommandObjectTargetSymbols
4496
4498public:
4499 // Constructors and Destructors
4502 interpreter, "target symbols",
4503 "Commands for adding and managing debug symbol files.",
4504 "target symbols <sub-command> ...") {
4506 "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter)));
4507 }
4508
4509 ~CommandObjectTargetSymbols() override = default;
4510
4511private:
4512 // For CommandObjectTargetModules only
4516};
4517
4518#pragma mark CommandObjectTargetStopHookAdd
4519
4520// CommandObjectTargetStopHookAdd
4521#define LLDB_OPTIONS_target_stop_hook_add
4522#include "CommandOptions.inc"
4523
4526public:
4528 public:
4530
4531 ~CommandOptions() override = default;
4532
4533 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
4534 return llvm::ArrayRef(g_target_stop_hook_add_options);
4535 }
4536
4537 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
4538 ExecutionContext *execution_context) override {
4539 Status error;
4540 const int short_option =
4541 g_target_stop_hook_add_options[option_idx].short_option;
4542
4543 switch (short_option) {
4544 case 'c':
4545 m_class_name = std::string(option_arg);
4546 m_sym_ctx_specified = true;
4547 break;
4548
4549 case 'e':
4550 if (option_arg.getAsInteger(0, m_line_end)) {
4551 error.SetErrorStringWithFormat("invalid end line number: \"%s\"",
4552 option_arg.str().c_str());
4553 break;
4554 }
4555 m_sym_ctx_specified = true;
4556 break;
4557
4558 case 'G': {
4559 bool value, success;
4560 value = OptionArgParser::ToBoolean(option_arg, false, &success);
4561 if (success) {
4562 m_auto_continue = value;
4563 } else
4564 error.SetErrorStringWithFormat(
4565 "invalid boolean value '%s' passed for -G option",
4566 option_arg.str().c_str());
4567 } break;
4568 case 'l':
4569 if (option_arg.getAsInteger(0, m_line_start)) {
4570 error.SetErrorStringWithFormat("invalid start line number: \"%s\"",
4571 option_arg.str().c_str());
4572 break;
4573 }
4574 m_sym_ctx_specified = true;
4575 break;
4576
4577 case 'i':
4578 m_no_inlines = true;
4579 break;
4580
4581 case 'n':
4582 m_function_name = std::string(option_arg);
4583 m_func_name_type_mask |= eFunctionNameTypeAuto;
4584 m_sym_ctx_specified = true;
4585 break;
4586
4587 case 'f':
4588 m_file_name = std::string(option_arg);
4589 m_sym_ctx_specified = true;
4590 break;
4591
4592 case 's':
4593 m_module_name = std::string(option_arg);
4594 m_sym_ctx_specified = true;
4595 break;
4596
4597 case 't':
4598 if (option_arg.getAsInteger(0, m_thread_id))
4599 error.SetErrorStringWithFormat("invalid thread id string '%s'",
4600 option_arg.str().c_str());
4601 m_thread_specified = true;
4602 break;
4603
4604 case 'T':
4605 m_thread_name = std::string(option_arg);
4606 m_thread_specified = true;
4607 break;
4608
4609 case 'q':
4610 m_queue_name = std::string(option_arg);
4611 m_thread_specified = true;
4612 break;
4613
4614 case 'x':
4615 if (option_arg.getAsInteger(0, m_thread_index))
4616 error.SetErrorStringWithFormat("invalid thread index string '%s'",
4617 option_arg.str().c_str());
4618 m_thread_specified = true;
4619 break;
4620
4621 case 'o':
4622 m_use_one_liner = true;
4623 m_one_liner.push_back(std::string(option_arg));
4624 break;
4625
4626 default:
4627 llvm_unreachable("Unimplemented option");
4628 }
4629 return error;
4630 }
4631
4632 void OptionParsingStarting(ExecutionContext *execution_context) override {
4633 m_class_name.clear();
4634 m_function_name.clear();
4635 m_line_start = 0;
4637 m_file_name.clear();
4638 m_module_name.clear();
4639 m_func_name_type_mask = eFunctionNameTypeAuto;
4642 m_thread_name.clear();
4643 m_queue_name.clear();
4644
4645 m_no_inlines = false;
4646 m_sym_ctx_specified = false;
4647 m_thread_specified = false;
4648
4649 m_use_one_liner = false;
4650 m_one_liner.clear();
4651 m_auto_continue = false;
4652 }
4653
4654 std::string m_class_name;
4655 std::string m_function_name;
4658 std::string m_file_name;
4659 std::string