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