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