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"
43#include "lldb/Target/ABI.h"
44#include "lldb/Target/Process.h"
48#include "lldb/Target/Thread.h"
50#include "lldb/Utility/Args.h"
54#include "lldb/Utility/State.h"
55#include "lldb/Utility/Stream.h"
57#include "lldb/Utility/Timer.h"
60#include "lldb/lldb-forward.h"
62
63#include "clang/Frontend/CompilerInstance.h"
64#include "clang/Frontend/CompilerInvocation.h"
65#include "clang/Frontend/FrontendActions.h"
66#include "clang/Serialization/ObjectFilePCHContainerReader.h"
67#include "llvm/ADT/ScopeExit.h"
68#include "llvm/ADT/StringRef.h"
69#include "llvm/Support/FileSystem.h"
70#include "llvm/Support/FormatAdapters.h"
71
72
73using namespace lldb;
74using namespace lldb_private;
75
76static void DumpTargetInfo(uint32_t target_idx, Target *target,
77 const char *prefix_cstr,
78 bool show_stopped_process_status, Stream &strm) {
79 const ArchSpec &target_arch = target->GetArchitecture();
80
81 Module *exe_module = target->GetExecutableModulePointer();
82 char exe_path[PATH_MAX];
83 bool exe_valid = false;
84 if (exe_module)
85 exe_valid = exe_module->GetFileSpec().GetPath(exe_path, sizeof(exe_path));
86
87 if (!exe_valid)
88 ::strcpy(exe_path, "<none>");
89
90 std::string formatted_label = "";
91 const std::string &label = target->GetLabel();
92 if (!label.empty()) {
93 formatted_label = " (" + label + ")";
94 }
95
96 strm.Printf("%starget #%u%s: %s", prefix_cstr ? prefix_cstr : "", target_idx,
97 formatted_label.data(), exe_path);
98
99 uint32_t properties = 0;
100 if (target_arch.IsValid()) {
101 strm.Printf(" ( arch=");
102 target_arch.DumpTriple(strm.AsRawOstream());
103 properties++;
104 }
105 PlatformSP platform_sp(target->GetPlatform());
106 if (platform_sp)
107 strm.Format("{0}platform={1}", properties++ > 0 ? ", " : " ( ",
108 platform_sp->GetName());
109
110 ProcessSP process_sp(target->GetProcessSP());
111 bool show_process_status = false;
112 if (process_sp) {
113 lldb::pid_t pid = process_sp->GetID();
114 StateType state = process_sp->GetState();
115 if (show_stopped_process_status)
116 show_process_status = StateIsStoppedState(state, true);
117 const char *state_cstr = StateAsCString(state);
118 if (pid != LLDB_INVALID_PROCESS_ID)
119 strm.Printf("%spid=%" PRIu64, properties++ > 0 ? ", " : " ( ", pid);
120 strm.Printf("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
121 }
122 if (properties > 0)
123 strm.PutCString(" )\n");
124 else
125 strm.EOL();
126 if (show_process_status) {
127 const bool only_threads_with_stop_reason = true;
128 const uint32_t start_frame = 0;
129 const uint32_t num_frames = 1;
130 const uint32_t num_frames_with_source = 1;
131 const bool stop_format = false;
132 process_sp->GetStatus(strm);
133 process_sp->GetThreadStatus(strm, only_threads_with_stop_reason,
134 start_frame, num_frames, num_frames_with_source,
135 stop_format);
136 }
137}
138
139static uint32_t DumpTargetList(TargetList &target_list,
140 bool show_stopped_process_status, Stream &strm) {
141 const uint32_t num_targets = target_list.GetNumTargets();
142 if (num_targets) {
143 TargetSP selected_target_sp(target_list.GetSelectedTarget());
144 strm.PutCString("Current targets:\n");
145 for (uint32_t i = 0; i < num_targets; ++i) {
146 TargetSP target_sp(target_list.GetTargetAtIndex(i));
147 if (target_sp) {
148 bool is_selected = target_sp.get() == selected_target_sp.get();
149 DumpTargetInfo(i, target_sp.get(), is_selected ? "* " : " ",
150 show_stopped_process_status, strm);
151 }
152 }
153 }
154 return num_targets;
155}
156
157#define LLDB_OPTIONS_target_dependents
158#include "CommandOptions.inc"
159
161public:
163
164 ~OptionGroupDependents() override = default;
165
166 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
167 return llvm::ArrayRef(g_target_dependents_options);
168 }
169
170 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
171 ExecutionContext *execution_context) override {
173
174 // For compatibility no value means don't load dependents.
175 if (option_value.empty()) {
177 return error;
178 }
179
180 const char short_option =
181 g_target_dependents_options[option_idx].short_option;
182 if (short_option == 'd') {
183 LoadDependentFiles tmp_load_dependents;
185 option_value, g_target_dependents_options[option_idx].enum_values, 0,
186 error);
187 if (error.Success())
188 m_load_dependent_files = tmp_load_dependents;
189 } else {
191 "unrecognized short option '%c'", short_option);
192 }
193
194 return error;
195 }
196
197 Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete;
198
202
204
205private:
209};
210
211#pragma mark CommandObjectTargetCreate
212
214public:
217 interpreter, "target create",
218 "Create a target using the argument as the main executable.",
219 nullptr),
220 m_platform_options(true), // Include the --platform option.
221 m_core_file(LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename,
222 "Fullpath to a core file to use for this target."),
223 m_label(LLDB_OPT_SET_1, false, "label", 'l', 0, eArgTypeName,
224 "Optional name for this target.", nullptr),
225 m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
227 "Fullpath to a stand alone debug "
228 "symbols file for when debug symbols "
229 "are not in the executable."),
231 LLDB_OPT_SET_1, false, "remote-file", 'r', 0, eArgTypeFilename,
232 "Fullpath to the file on the remote host if debugging remotely.") {
233
235
243 m_option_group.Finalize();
244 }
245
246 ~CommandObjectTargetCreate() override = default;
247
248 Options *GetOptions() override { return &m_option_group; }
249
250protected:
251 void DoExecute(Args &command, CommandReturnObject &result) override {
252 const size_t argc = command.GetArgumentCount();
253 FileSpec core_file(m_core_file.GetOptionValue().GetCurrentValue());
254 FileSpec remote_file(m_remote_file.GetOptionValue().GetCurrentValue());
255
256 if (core_file) {
257 auto file = FileSystem::Instance().Open(
259
260 if (!file) {
261 result.AppendErrorWithFormatv("Cannot open '{0}': {1}.",
262 core_file.GetPath(),
263 llvm::toString(file.takeError()));
264 return;
265 }
266 }
267
268 if (argc == 1 || core_file || remote_file) {
269 FileSpec symfile(m_symbol_file.GetOptionValue().GetCurrentValue());
270 if (symfile) {
271 auto file = FileSystem::Instance().Open(
273
274 if (!file) {
275 result.AppendErrorWithFormatv("Cannot open '{0}': {1}.",
276 symfile.GetPath(),
277 llvm::toString(file.takeError()));
278 return;
279 }
280 }
281
282 const char *file_path = command.GetArgumentAtIndex(0);
283 LLDB_SCOPED_TIMERF("(lldb) target create '%s'", file_path);
284
285 bool must_set_platform_path = false;
286
287 Debugger &debugger = GetDebugger();
288
289 TargetSP target_sp;
290 llvm::StringRef arch_cstr = m_arch_option.GetArchitectureName();
292 debugger, file_path, arch_cstr,
293 m_add_dependents.m_load_dependent_files, &m_platform_options,
294 target_sp));
295
296 if (!target_sp) {
297 result.AppendError(error.AsCString());
298 return;
299 }
300
301 const llvm::StringRef label =
302 m_label.GetOptionValue().GetCurrentValueAsRef();
303 if (!label.empty()) {
304 if (auto E = target_sp->SetLabel(label))
305 result.SetError(std::move(E));
306 return;
307 }
308
309 auto on_error = llvm::make_scope_exit(
310 [&target_list = debugger.GetTargetList(), &target_sp]() {
311 target_list.DeleteTarget(target_sp);
312 });
313
314 // Only get the platform after we create the target because we might
315 // have switched platforms depending on what the arguments were to
316 // CreateTarget() we can't rely on the selected platform.
317
318 PlatformSP platform_sp = target_sp->GetPlatform();
319
320 FileSpec file_spec;
321 if (file_path) {
322 file_spec.SetFile(file_path, FileSpec::Style::native);
323 FileSystem::Instance().Resolve(file_spec);
324
325 // Try to resolve the exe based on PATH and/or platform-specific
326 // suffixes, but only if using the host platform.
327 if (platform_sp && platform_sp->IsHost() &&
328 !FileSystem::Instance().Exists(file_spec))
330 }
331
332 if (remote_file) {
333 if (platform_sp) {
334 // I have a remote file.. two possible cases
335 if (file_spec && FileSystem::Instance().Exists(file_spec)) {
336 // if the remote file does not exist, push it there
337 if (!platform_sp->GetFileExists(remote_file)) {
338 Status err = platform_sp->PutFile(file_spec, remote_file);
339 if (err.Fail()) {
340 result.AppendError(err.AsCString());
341 return;
342 }
343 }
344 } else {
345 // there is no local file and we need one
346 // in order to make the remote ---> local transfer we need a
347 // platform
348 // TODO: if the user has passed in a --platform argument, use it
349 // to fetch the right platform
350 if (file_path) {
351 // copy the remote file to the local file
352 Status err = platform_sp->GetFile(remote_file, file_spec);
353 if (err.Fail()) {
354 result.AppendError(err.AsCString());
355 return;
356 }
357 } else {
358 // If the remote file exists, we can debug reading that out of
359 // memory. If the platform is already connected to an lldb-server
360 // then we can at least check the file exists remotely. Otherwise
361 // we'll just have to trust that it will be there when we do
362 // process connect.
363 // I don't do this for the host platform because it seems odd to
364 // support supplying a remote file but no local file for a local
365 // debug session.
366 if (platform_sp->IsHost()) {
367 result.AppendError("Supply a local file, not a remote file, "
368 "when debugging on the host.");
369 return;
370 }
371 if (platform_sp->IsConnected() && !platform_sp->GetFileExists(remote_file)) {
372 result.AppendError("remote --> local transfer without local "
373 "path is not implemented yet");
374 return;
375 }
376 // Since there's only a remote file, we need to set the executable
377 // file spec to the remote one.
378 ProcessLaunchInfo launch_info = target_sp->GetProcessLaunchInfo();
379 launch_info.SetExecutableFile(FileSpec(remote_file), true);
380 target_sp->SetProcessLaunchInfo(launch_info);
381 }
382 }
383 } else {
384 result.AppendError("no platform found for target");
385 return;
386 }
387 }
388
389 if (symfile || remote_file) {
390 ModuleSP module_sp(target_sp->GetExecutableModule());
391 if (module_sp) {
392 if (symfile)
393 module_sp->SetSymbolFileFileSpec(symfile);
394 if (remote_file) {
395 std::string remote_path = remote_file.GetPath();
396 target_sp->SetArg0(remote_path.c_str());
397 module_sp->SetPlatformFileSpec(remote_file);
398 }
399 }
400 }
401
402 if (must_set_platform_path) {
403 ModuleSpec main_module_spec(file_spec);
404 ModuleSP module_sp =
405 target_sp->GetOrCreateModule(main_module_spec, true /* notify */);
406 if (module_sp)
407 module_sp->SetPlatformFileSpec(remote_file);
408 }
409
410 if (core_file) {
411 FileSpec core_file_dir;
412 core_file_dir.SetDirectory(core_file.GetDirectory());
413 target_sp->AppendExecutableSearchPaths(core_file_dir);
414
415 ProcessSP process_sp(target_sp->CreateProcess(
416 GetDebugger().GetListener(), llvm::StringRef(), &core_file, false));
417
418 if (process_sp) {
419 // Seems weird that we Launch a core file, but that is what we
420 // do!
421 {
422 ElapsedTime load_core_time(
423 target_sp->GetStatistics().GetLoadCoreTime());
424 error = process_sp->LoadCore();
425 }
426
427 if (error.Fail()) {
428 result.AppendError(error.AsCString("unknown core file format"));
429 return;
430 } else {
432 "Core file '{0}' ({1}) was loaded.\n", core_file.GetPath(),
433 target_sp->GetArchitecture().GetArchitectureName());
435 on_error.release();
436 }
437 } else {
438 result.AppendErrorWithFormatv("Unknown core file format '{0}'\n",
439 core_file.GetPath());
440 }
441 } else {
443 "Current executable set to '%s' (%s).\n",
444 file_spec.GetPath().c_str(),
445 target_sp->GetArchitecture().GetArchitectureName());
447 on_error.release();
448 }
449 } else {
450 result.AppendErrorWithFormat("'%s' takes exactly one executable path "
451 "argument, or use the --core option.\n",
452 m_cmd_name.c_str());
453 }
454 }
455
456private:
465};
466
467#pragma mark CommandObjectTargetList
468
470public:
473 interpreter, "target list",
474 "List all current targets in the current debug session.", nullptr) {
475 }
476
477 ~CommandObjectTargetList() override = default;
478
479protected:
480 void DoExecute(Args &args, CommandReturnObject &result) override {
481 Stream &strm = result.GetOutputStream();
482
483 bool show_stopped_process_status = false;
484 if (DumpTargetList(GetDebugger().GetTargetList(),
485 show_stopped_process_status, strm) == 0) {
486 strm.PutCString("No targets.\n");
487 }
489 }
490};
491
492#pragma mark CommandObjectTargetSelect
493
495public:
498 interpreter, "target select",
499 "Select a target as the current target by target index.", nullptr) {
501 }
502
503 ~CommandObjectTargetSelect() override = default;
504
505protected:
506 void DoExecute(Args &args, CommandReturnObject &result) override {
507 if (args.GetArgumentCount() == 1) {
508 const char *target_identifier = args.GetArgumentAtIndex(0);
509 uint32_t target_idx = LLDB_INVALID_INDEX32;
510 TargetList &target_list = GetDebugger().GetTargetList();
511 const uint32_t num_targets = target_list.GetNumTargets();
512 if (llvm::to_integer(target_identifier, target_idx)) {
513 if (target_idx < num_targets) {
514 target_list.SetSelectedTarget(target_idx);
515 Stream &strm = result.GetOutputStream();
516 bool show_stopped_process_status = false;
517 DumpTargetList(target_list, show_stopped_process_status, strm);
519 } else {
520 if (num_targets > 0) {
522 "index %u is out of range, valid target indexes are 0 - %u\n",
523 target_idx, num_targets - 1);
524 } else {
526 "index %u is out of range since there are no active targets\n",
527 target_idx);
528 }
529 }
530 } else {
531 for (size_t i = 0; i < num_targets; i++) {
532 if (TargetSP target_sp = target_list.GetTargetAtIndex(i)) {
533 const std::string &label = target_sp->GetLabel();
534 if (!label.empty() && label == target_identifier) {
535 target_idx = i;
536 break;
537 }
538 }
539 }
540
541 if (target_idx != LLDB_INVALID_INDEX32) {
542 target_list.SetSelectedTarget(target_idx);
543 Stream &strm = result.GetOutputStream();
544 bool show_stopped_process_status = false;
545 DumpTargetList(target_list, show_stopped_process_status, strm);
547 } else {
548 result.AppendErrorWithFormat("invalid index string value '%s'\n",
549 target_identifier);
550 }
551 }
552 } else {
553 result.AppendError(
554 "'target select' takes a single argument: a target index\n");
555 }
556 }
557};
558
559#pragma mark CommandObjectTargetDelete
560
562public:
564 : CommandObjectParsed(interpreter, "target delete",
565 "Delete one or more targets by target index.",
566 nullptr),
567 m_all_option(LLDB_OPT_SET_1, false, "all", 'a', "Delete all targets.",
568 false, true),
570 LLDB_OPT_SET_1, false, "clean", 'c',
571 "Perform extra cleanup to minimize memory consumption after "
572 "deleting the target. "
573 "By default, LLDB will keep in memory any modules previously "
574 "loaded by the target as well "
575 "as all of its debug info. Specifying --clean will unload all of "
576 "these shared modules and "
577 "cause them to be reparsed again the next time the target is run",
578 false, true) {
581 m_option_group.Finalize();
583 }
584
585 ~CommandObjectTargetDelete() override = default;
586
587 Options *GetOptions() override { return &m_option_group; }
588
589protected:
590 void DoExecute(Args &args, CommandReturnObject &result) override {
591 const size_t argc = args.GetArgumentCount();
592 std::vector<TargetSP> delete_target_list;
593 TargetList &target_list = GetDebugger().GetTargetList();
594 TargetSP target_sp;
595
596 if (m_all_option.GetOptionValue()) {
597 for (size_t i = 0; i < target_list.GetNumTargets(); ++i)
598 delete_target_list.push_back(target_list.GetTargetAtIndex(i));
599 } else if (argc > 0) {
600 const uint32_t num_targets = target_list.GetNumTargets();
601 // Bail out if don't have any targets.
602 if (num_targets == 0) {
603 result.AppendError("no targets to delete");
604 return;
605 }
606
607 for (auto &entry : args.entries()) {
608 uint32_t target_idx;
609 if (entry.ref().getAsInteger(0, target_idx)) {
610 result.AppendErrorWithFormat("invalid target index '%s'\n",
611 entry.c_str());
612 return;
613 }
614 if (target_idx < num_targets) {
615 target_sp = target_list.GetTargetAtIndex(target_idx);
616 if (target_sp) {
617 delete_target_list.push_back(target_sp);
618 continue;
619 }
620 }
621 if (num_targets > 1)
622 result.AppendErrorWithFormat("target index %u is out of range, valid "
623 "target indexes are 0 - %u\n",
624 target_idx, num_targets - 1);
625 else
627 "target index %u is out of range, the only valid index is 0\n",
628 target_idx);
629
630 return;
631 }
632 } else {
633 target_sp = target_list.GetSelectedTarget();
634 if (!target_sp) {
635 result.AppendErrorWithFormat("no target is currently selected\n");
636 return;
637 }
638 delete_target_list.push_back(target_sp);
639 }
640
641 const size_t num_targets_to_delete = delete_target_list.size();
642 for (size_t idx = 0; idx < num_targets_to_delete; ++idx) {
643 target_sp = delete_target_list[idx];
644 target_list.DeleteTarget(target_sp);
645 target_sp->Destroy();
646 }
647 // If "--clean" was specified, prune any orphaned shared modules from the
648 // global shared module list
649 if (m_cleanup_option.GetOptionValue()) {
650 const bool mandatory = true;
652 }
653 result.GetOutputStream().Printf("%u targets deleted.\n",
654 (uint32_t)num_targets_to_delete);
656 }
657
661};
662
664public:
667 interpreter, "target show-launch-environment",
668 "Shows the environment being passed to the process when launched, "
669 "taking info account 3 settings: target.env-vars, "
670 "target.inherit-env and target.unset-env-vars.",
671 nullptr, eCommandRequiresTarget) {}
672
674
675protected:
676 void DoExecute(Args &args, CommandReturnObject &result) override {
677 Target *target = m_exe_ctx.GetTargetPtr();
678 Environment env = target->GetEnvironment();
679
680 std::vector<Environment::value_type *> env_vector;
681 env_vector.reserve(env.size());
682 for (auto &KV : env)
683 env_vector.push_back(&KV);
684 std::sort(env_vector.begin(), env_vector.end(),
685 [](Environment::value_type *a, Environment::value_type *b) {
686 return a->first() < b->first();
687 });
688
689 auto &strm = result.GetOutputStream();
690 for (auto &KV : env_vector)
691 strm.Format("{0}={1}\n", KV->first(), KV->second);
692
694 }
695};
696
697#pragma mark CommandObjectTargetVariable
698
700 static const uint32_t SHORT_OPTION_FILE = 0x66696c65; // 'file'
701 static const uint32_t SHORT_OPTION_SHLB = 0x73686c62; // 'shlb'
702
703public:
705 : CommandObjectParsed(interpreter, "target variable",
706 "Read global variables for the current target, "
707 "before or while running a process.",
708 nullptr, eCommandRequiresTarget),
709 m_option_variable(false), // Don't include frame options
713 "A basename or fullpath to a file that contains "
714 "global variables. This option can be "
715 "specified multiple times."),
717 LLDB_OPT_SET_1, false, "shlib", SHORT_OPTION_SHLB, 0,
719 "A basename or fullpath to a shared library to use in the search "
720 "for global "
721 "variables. This option can be specified multiple times.") {
723
734 m_option_group.Finalize();
735 }
736
737 ~CommandObjectTargetVariable() override = default;
738
739 void DumpValueObject(Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp,
740 const char *root_name) {
741 DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions());
742
743 if (!valobj_sp->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
744 valobj_sp->IsRuntimeSupportValue())
745 return;
746
747 switch (var_sp->GetScope()) {
749 if (m_option_variable.show_scope)
750 s.PutCString("GLOBAL: ");
751 break;
752
754 if (m_option_variable.show_scope)
755 s.PutCString("STATIC: ");
756 break;
757
759 if (m_option_variable.show_scope)
760 s.PutCString(" ARG: ");
761 break;
762
764 if (m_option_variable.show_scope)
765 s.PutCString(" LOCAL: ");
766 break;
767
769 if (m_option_variable.show_scope)
770 s.PutCString("THREAD: ");
771 break;
772
773 default:
774 break;
775 }
776
777 if (m_option_variable.show_decl) {
778 bool show_fullpaths = false;
779 bool show_module = true;
780 if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
781 s.PutCString(": ");
782 }
783
784 const Format format = m_option_format.GetFormat();
785 if (format != eFormatDefault)
786 options.SetFormat(format);
787
788 options.SetRootValueObjectName(root_name);
789
790 if (llvm::Error error = valobj_sp->Dump(s, options))
791 s << "error: " << toString(std::move(error));
792 }
793
794 static size_t GetVariableCallback(void *baton, const char *name,
795 VariableList &variable_list) {
796 size_t old_size = variable_list.GetSize();
797 Target *target = static_cast<Target *>(baton);
798 if (target)
800 variable_list);
801 return variable_list.GetSize() - old_size;
802 }
803
804 Options *GetOptions() override { return &m_option_group; }
805
806protected:
808 const SymbolContext &sc,
809 const VariableList &variable_list,
810 CommandReturnObject &result) {
811 Stream &s = result.GetOutputStream();
812 if (variable_list.Empty())
813 return;
814 if (sc.module_sp) {
815 if (sc.comp_unit) {
816 s.Format("Global variables for {0} in {1}:\n",
817 sc.comp_unit->GetPrimaryFile(), sc.module_sp->GetFileSpec());
818 } else {
819 s.Printf("Global variables for %s\n",
820 sc.module_sp->GetFileSpec().GetPath().c_str());
821 }
822 } else if (sc.comp_unit) {
823 s.Format("Global variables for {0}\n", sc.comp_unit->GetPrimaryFile());
824 }
825
826 for (VariableSP var_sp : variable_list) {
827 if (!var_sp)
828 continue;
830 exe_ctx.GetBestExecutionContextScope(), var_sp));
831
832 if (valobj_sp) {
833 result.GetValueObjectList().Append(valobj_sp);
834 DumpValueObject(s, var_sp, valobj_sp, var_sp->GetName().GetCString());
835 }
836 }
837 }
838
839 void DoExecute(Args &args, CommandReturnObject &result) override {
840 Target *target = m_exe_ctx.GetTargetPtr();
841 const size_t argc = args.GetArgumentCount();
842
843 if (argc > 0) {
844 for (const Args::ArgEntry &arg : args) {
845 VariableList variable_list;
846 ValueObjectList valobj_list;
847
848 size_t matches = 0;
849 bool use_var_name = false;
850 if (m_option_variable.use_regex) {
851 RegularExpression regex(arg.ref());
852 if (!regex.IsValid()) {
853 result.GetErrorStream().Printf(
854 "error: invalid regular expression: '%s'\n", arg.c_str());
855 return;
856 }
857 use_var_name = true;
859 variable_list);
860 matches = variable_list.GetSize();
861 } else {
863 arg.c_str(), m_exe_ctx.GetBestExecutionContextScope(),
864 GetVariableCallback, target, variable_list, valobj_list));
865 matches = variable_list.GetSize();
866 }
867
868 if (matches == 0) {
869 result.AppendErrorWithFormat("can't find global variable '%s'",
870 arg.c_str());
871 return;
872 } else {
873 for (uint32_t global_idx = 0; global_idx < matches; ++global_idx) {
874 VariableSP var_sp(variable_list.GetVariableAtIndex(global_idx));
875 if (var_sp) {
876 ValueObjectSP valobj_sp(
877 valobj_list.GetValueObjectAtIndex(global_idx));
878 if (!valobj_sp)
879 valobj_sp = ValueObjectVariable::Create(
880 m_exe_ctx.GetBestExecutionContextScope(), var_sp);
881
882 if (valobj_sp)
883 DumpValueObject(result.GetOutputStream(), var_sp, valobj_sp,
884 use_var_name ? var_sp->GetName().GetCString()
885 : arg.c_str());
886 }
887 }
888 }
889 }
890 } else {
891 const FileSpecList &compile_units =
892 m_option_compile_units.GetOptionValue().GetCurrentValue();
893 const FileSpecList &shlibs =
894 m_option_shared_libraries.GetOptionValue().GetCurrentValue();
895 SymbolContextList sc_list;
896 const size_t num_compile_units = compile_units.GetSize();
897 const size_t num_shlibs = shlibs.GetSize();
898 if (num_compile_units == 0 && num_shlibs == 0) {
899 bool success = false;
900 StackFrame *frame = m_exe_ctx.GetFramePtr();
901 CompileUnit *comp_unit = nullptr;
902 if (frame) {
903 SymbolContext sc = frame->GetSymbolContext(eSymbolContextCompUnit);
904 comp_unit = sc.comp_unit;
905 if (sc.comp_unit) {
906 const bool can_create = true;
907 VariableListSP comp_unit_varlist_sp(
908 sc.comp_unit->GetVariableList(can_create));
909 if (comp_unit_varlist_sp) {
910 size_t count = comp_unit_varlist_sp->GetSize();
911 if (count > 0) {
912 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp,
913 result);
914 success = true;
915 }
916 }
917 }
918 }
919 if (!success) {
920 if (frame) {
921 if (comp_unit)
923 "no global variables in current compile unit: {0}\n",
924 comp_unit->GetPrimaryFile());
925 else
927 "no debug information for frame %u\n",
928 frame->GetFrameIndex());
929 } else
930 result.AppendError("'target variable' takes one or more global "
931 "variable names as arguments\n");
932 }
933 } else {
934 SymbolContextList sc_list;
935 // We have one or more compile unit or shlib
936 if (num_shlibs > 0) {
937 for (size_t shlib_idx = 0; shlib_idx < num_shlibs; ++shlib_idx) {
938 const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx));
939 ModuleSpec module_spec(module_file);
940
941 ModuleSP module_sp(
942 target->GetImages().FindFirstModule(module_spec));
943 if (module_sp) {
944 if (num_compile_units > 0) {
945 for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
946 module_sp->FindCompileUnits(
947 compile_units.GetFileSpecAtIndex(cu_idx), sc_list);
948 } else {
949 SymbolContext sc;
950 sc.module_sp = module_sp;
951 sc_list.Append(sc);
952 }
953 } else {
954 // Didn't find matching shlib/module in target...
956 "target doesn't contain the specified shared library: %s\n",
957 module_file.GetPath().c_str());
958 }
959 }
960 } else {
961 // No shared libraries, we just want to find globals for the compile
962 // units files that were specified
963 for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
964 target->GetImages().FindCompileUnits(
965 compile_units.GetFileSpecAtIndex(cu_idx), sc_list);
966 }
967
968 for (const SymbolContext &sc : sc_list) {
969 if (sc.comp_unit) {
970 const bool can_create = true;
971 VariableListSP comp_unit_varlist_sp(
972 sc.comp_unit->GetVariableList(can_create));
973 if (comp_unit_varlist_sp)
974 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp,
975 result);
976 } else if (sc.module_sp) {
977 // Get all global variables for this module
978 lldb_private::RegularExpression all_globals_regex(
979 llvm::StringRef(".")); // Any global with at least one character
980 VariableList variable_list;
981 sc.module_sp->FindGlobalVariables(all_globals_regex, UINT32_MAX,
982 variable_list);
983 DumpGlobalVariableList(m_exe_ctx, sc, variable_list, result);
984 }
985 }
986 }
987 }
988
989 m_interpreter.PrintWarningsIfNecessary(result.GetOutputStream(),
990 m_cmd_name);
991 }
992
999};
1000
1001#pragma mark CommandObjectTargetModulesSearchPathsAdd
1002
1004public:
1006 : CommandObjectParsed(interpreter, "target modules search-paths add",
1007 "Add new image search paths substitution pairs to "
1008 "the current target.",
1009 nullptr, eCommandRequiresTarget) {
1011 CommandArgumentData old_prefix_arg;
1012 CommandArgumentData new_prefix_arg;
1013
1014 // Define the first variant of this arg pair.
1015 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1016 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1017
1018 // Define the first variant of this arg pair.
1019 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1020 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1021
1022 // There are two required arguments that must always occur together, i.e.
1023 // an argument "pair". Because they must always occur together, they are
1024 // treated as two variants of one argument rather than two independent
1025 // arguments. Push them both into the first argument position for
1026 // m_arguments...
1027
1028 arg.push_back(old_prefix_arg);
1029 arg.push_back(new_prefix_arg);
1030
1031 m_arguments.push_back(arg);
1032 }
1033
1035
1036protected:
1037 void DoExecute(Args &command, CommandReturnObject &result) override {
1038 Target &target = GetTarget();
1039 const size_t argc = command.GetArgumentCount();
1040 if (argc & 1) {
1041 result.AppendError("add requires an even number of arguments\n");
1042 } else {
1043 for (size_t i = 0; i < argc; i += 2) {
1044 const char *from = command.GetArgumentAtIndex(i);
1045 const char *to = command.GetArgumentAtIndex(i + 1);
1046
1047 if (from[0] && to[0]) {
1048 Log *log = GetLog(LLDBLog::Host);
1049 if (log) {
1050 LLDB_LOGF(log,
1051 "target modules search path adding ImageSearchPath "
1052 "pair: '%s' -> '%s'",
1053 from, to);
1054 }
1055 bool last_pair = ((argc - i) == 2);
1057 from, to, last_pair); // Notify if this is the last pair
1059 } else {
1060 if (from[0])
1061 result.AppendError("<path-prefix> can't be empty\n");
1062 else
1063 result.AppendError("<new-path-prefix> can't be empty\n");
1064 }
1065 }
1066 }
1067 }
1068};
1069
1070#pragma mark CommandObjectTargetModulesSearchPathsClear
1071
1073public:
1075 : CommandObjectParsed(interpreter, "target modules search-paths clear",
1076 "Clear all current image search path substitution "
1077 "pairs from the current target.",
1078 "target modules search-paths clear",
1079 eCommandRequiresTarget) {}
1080
1082
1083protected:
1084 void DoExecute(Args &command, CommandReturnObject &result) override {
1085 Target &target = GetTarget();
1086 bool notify = true;
1087 target.GetImageSearchPathList().Clear(notify);
1089 }
1090};
1091
1092#pragma mark CommandObjectTargetModulesSearchPathsInsert
1093
1095public:
1097 : CommandObjectParsed(interpreter, "target modules search-paths insert",
1098 "Insert a new image search path substitution pair "
1099 "into the current target at the specified index.",
1100 nullptr, eCommandRequiresTarget) {
1103 CommandArgumentData index_arg;
1104 CommandArgumentData old_prefix_arg;
1105 CommandArgumentData new_prefix_arg;
1106
1107 // Define the first and only variant of this arg.
1108 index_arg.arg_type = eArgTypeIndex;
1109 index_arg.arg_repetition = eArgRepeatPlain;
1110
1111 // Put the one and only variant into the first arg for m_arguments:
1112 arg1.push_back(index_arg);
1113
1114 // Define the first variant of this arg pair.
1115 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1116 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1117
1118 // Define the first variant of this arg pair.
1119 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1120 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1121
1122 // There are two required arguments that must always occur together, i.e.
1123 // an argument "pair". Because they must always occur together, they are
1124 // treated as two variants of one argument rather than two independent
1125 // arguments. Push them both into the same argument position for
1126 // m_arguments...
1127
1128 arg2.push_back(old_prefix_arg);
1129 arg2.push_back(new_prefix_arg);
1130
1131 // Add arguments to m_arguments.
1132 m_arguments.push_back(arg1);
1133 m_arguments.push_back(arg2);
1134 }
1135
1137
1138 void
1140 OptionElementVector &opt_element_vector) override {
1141 if (!m_exe_ctx.HasTargetScope() || request.GetCursorIndex() != 0)
1142 return;
1143
1144 Target *target = m_exe_ctx.GetTargetPtr();
1145 const PathMappingList &list = target->GetImageSearchPathList();
1146 const size_t num = list.GetSize();
1147 ConstString old_path, new_path;
1148 for (size_t i = 0; i < num; ++i) {
1149 if (!list.GetPathsAtIndex(i, old_path, new_path))
1150 break;
1151 StreamString strm;
1152 strm << old_path << " -> " << new_path;
1153 request.TryCompleteCurrentArg(std::to_string(i), strm.GetString());
1154 }
1155 }
1156
1157protected:
1158 void DoExecute(Args &command, CommandReturnObject &result) override {
1159 Target &target = GetTarget();
1160 size_t argc = command.GetArgumentCount();
1161 // check for at least 3 arguments and an odd number of parameters
1162 if (argc >= 3 && argc & 1) {
1163 uint32_t insert_idx;
1164
1165 if (!llvm::to_integer(command.GetArgumentAtIndex(0), insert_idx)) {
1166 result.AppendErrorWithFormat(
1167 "<index> parameter is not an integer: '%s'.\n",
1168 command.GetArgumentAtIndex(0));
1169 return;
1170 }
1171
1172 // shift off the index
1173 command.Shift();
1174 argc = command.GetArgumentCount();
1175
1176 for (uint32_t i = 0; i < argc; i += 2, ++insert_idx) {
1177 const char *from = command.GetArgumentAtIndex(i);
1178 const char *to = command.GetArgumentAtIndex(i + 1);
1179
1180 if (from[0] && to[0]) {
1181 bool last_pair = ((argc - i) == 2);
1182 target.GetImageSearchPathList().Insert(from, to, insert_idx,
1183 last_pair);
1185 } else {
1186 if (from[0])
1187 result.AppendError("<path-prefix> can't be empty\n");
1188 else
1189 result.AppendError("<new-path-prefix> can't be empty\n");
1190 return;
1191 }
1192 }
1193 } else {
1194 result.AppendError("insert requires at least three arguments\n");
1195 }
1196 }
1197};
1198
1199#pragma mark CommandObjectTargetModulesSearchPathsList
1200
1202public:
1204 : CommandObjectParsed(interpreter, "target modules search-paths list",
1205 "List all current image search path substitution "
1206 "pairs in the current target.",
1207 "target modules search-paths list",
1208 eCommandRequiresTarget) {}
1209
1211
1212protected:
1213 void DoExecute(Args &command, CommandReturnObject &result) override {
1214 Target &target = GetTarget();
1215 target.GetImageSearchPathList().Dump(&result.GetOutputStream());
1217 }
1218};
1219
1220#pragma mark CommandObjectTargetModulesSearchPathsQuery
1221
1223public:
1226 interpreter, "target modules search-paths query",
1227 "Transform a path using the first applicable image search path.",
1228 nullptr, eCommandRequiresTarget) {
1230 }
1231
1233
1234protected:
1235 void DoExecute(Args &command, CommandReturnObject &result) override {
1236 Target &target = GetTarget();
1237 if (command.GetArgumentCount() != 1) {
1238 result.AppendError("query requires one argument\n");
1239 return;
1240 }
1241
1242 ConstString orig(command.GetArgumentAtIndex(0));
1243 ConstString transformed;
1244 if (target.GetImageSearchPathList().RemapPath(orig, transformed))
1245 result.GetOutputStream().Printf("%s\n", transformed.GetCString());
1246 else
1247 result.GetOutputStream().Printf("%s\n", orig.GetCString());
1248
1250 }
1251};
1252
1253// Static Helper functions
1254static void DumpModuleArchitecture(Stream &strm, Module *module,
1255 bool full_triple, uint32_t width) {
1256 if (module) {
1257 StreamString arch_strm;
1258
1259 if (full_triple)
1260 module->GetArchitecture().DumpTriple(arch_strm.AsRawOstream());
1261 else
1262 arch_strm.PutCString(module->GetArchitecture().GetArchitectureName());
1263 std::string arch_str = std::string(arch_strm.GetString());
1264
1265 if (width)
1266 strm.Printf("%-*s", width, arch_str.c_str());
1267 else
1268 strm.PutCString(arch_str);
1269 }
1270}
1271
1272static void DumpModuleUUID(Stream &strm, Module *module) {
1273 if (module && module->GetUUID().IsValid())
1274 module->GetUUID().Dump(strm);
1275 else
1276 strm.PutCString(" ");
1277}
1278
1280 Stream &strm, Module *module,
1281 const FileSpec &file_spec,
1282 lldb::DescriptionLevel desc_level) {
1283 uint32_t num_matches = 0;
1284 if (module) {
1285 SymbolContextList sc_list;
1286 num_matches = module->ResolveSymbolContextsForFileSpec(
1287 file_spec, 0, false, eSymbolContextCompUnit, sc_list);
1288
1289 bool first_module = true;
1290 for (const SymbolContext &sc : sc_list) {
1291 if (!first_module)
1292 strm << "\n\n";
1293
1294 strm << "Line table for " << sc.comp_unit->GetPrimaryFile() << " in `"
1295 << module->GetFileSpec().GetFilename() << "\n";
1296 LineTable *line_table = sc.comp_unit->GetLineTable();
1297 if (line_table)
1298 line_table->GetDescription(
1299 &strm, interpreter.GetExecutionContext().GetTargetPtr(),
1300 desc_level);
1301 else
1302 strm << "No line table";
1303
1304 first_module = false;
1305 }
1306 }
1307 return num_matches;
1308}
1309
1310static void DumpFullpath(Stream &strm, const FileSpec *file_spec_ptr,
1311 uint32_t width) {
1312 if (file_spec_ptr) {
1313 if (width > 0) {
1314 std::string fullpath = file_spec_ptr->GetPath();
1315 strm.Printf("%-*s", width, fullpath.c_str());
1316 return;
1317 } else {
1318 file_spec_ptr->Dump(strm.AsRawOstream());
1319 return;
1320 }
1321 }
1322 // Keep the width spacing correct if things go wrong...
1323 if (width > 0)
1324 strm.Printf("%-*s", width, "");
1325}
1326
1327static void DumpDirectory(Stream &strm, const FileSpec *file_spec_ptr,
1328 uint32_t width) {
1329 if (file_spec_ptr) {
1330 if (width > 0)
1331 strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
1332 else
1333 file_spec_ptr->GetDirectory().Dump(&strm);
1334 return;
1335 }
1336 // Keep the width spacing correct if things go wrong...
1337 if (width > 0)
1338 strm.Printf("%-*s", width, "");
1339}
1340
1341static void DumpBasename(Stream &strm, const FileSpec *file_spec_ptr,
1342 uint32_t width) {
1343 if (file_spec_ptr) {
1344 if (width > 0)
1345 strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
1346 else
1347 file_spec_ptr->GetFilename().Dump(&strm);
1348 return;
1349 }
1350 // Keep the width spacing correct if things go wrong...
1351 if (width > 0)
1352 strm.Printf("%-*s", width, "");
1353}
1354
1355static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) {
1356 std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
1357 const size_t num_modules = module_list.GetSize();
1358 if (num_modules == 0)
1359 return 0;
1360
1361 size_t num_dumped = 0;
1362 strm.Format("Dumping headers for {0} module(s).\n", num_modules);
1363 strm.IndentMore();
1364 for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
1365 if (module_sp) {
1366 if (num_dumped++ > 0) {
1367 strm.EOL();
1368 strm.EOL();
1369 }
1370 ObjectFile *objfile = module_sp->GetObjectFile();
1371 if (objfile)
1372 objfile->Dump(&strm);
1373 else {
1374 strm.Format("No object file for module: {0:F}\n",
1375 module_sp->GetFileSpec());
1376 }
1377 }
1378 }
1379 strm.IndentLess();
1380 return num_dumped;
1381}
1382
1383static void DumpModuleSymtab(CommandInterpreter &interpreter, Stream &strm,
1384 Module *module, SortOrder sort_order,
1385 Mangled::NamePreference name_preference) {
1386 if (!module)
1387 return;
1388 if (Symtab *symtab = module->GetSymtab())
1389 symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(),
1390 sort_order, name_preference);
1391}
1392
1393static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm,
1394 Module *module) {
1395 if (module) {
1396 SectionList *section_list = module->GetSectionList();
1397 if (section_list) {
1398 strm.Printf("Sections for '%s' (%s):\n",
1399 module->GetSpecificationDescription().c_str(),
1401 section_list->Dump(strm.AsRawOstream(), strm.GetIndentLevel() + 2,
1402 interpreter.GetExecutionContext().GetTargetPtr(), true,
1403 UINT32_MAX);
1404 }
1405 }
1406}
1407
1408static bool DumpModuleSymbolFile(Stream &strm, Module *module) {
1409 if (module) {
1410 if (SymbolFile *symbol_file = module->GetSymbolFile(true)) {
1411 symbol_file->Dump(strm);
1412 return true;
1413 }
1414 }
1415 return false;
1416}
1417
1419 Module *module, bool errors_only,
1420 bool load_all_debug_info) {
1421 if (module) {
1422 if (SymbolFile *symbol_file = module->GetSymbolFile(/*can_create=*/true)) {
1424 if (symbol_file->GetSeparateDebugInfo(d, errors_only,
1425 load_all_debug_info)) {
1426 list.AddItem(
1427 std::make_shared<StructuredData::Dictionary>(std::move(d)));
1428 return true;
1429 }
1430 }
1431 }
1432 return false;
1433}
1434
1435static void DumpDwoFilesTable(Stream &strm,
1436 StructuredData::Array &dwo_listings) {
1437 strm.PutCString("Dwo ID Err Dwo Path");
1438 strm.EOL();
1439 strm.PutCString(
1440 "------------------ --- -----------------------------------------");
1441 strm.EOL();
1442 dwo_listings.ForEach([&strm](StructuredData::Object *dwo) {
1444 if (!dict)
1445 return false;
1446
1447 uint64_t dwo_id;
1448 if (dict->GetValueForKeyAsInteger("dwo_id", dwo_id))
1449 strm.Printf("0x%16.16" PRIx64 " ", dwo_id);
1450 else
1451 strm.Printf("0x???????????????? ");
1452
1453 llvm::StringRef error;
1454 if (dict->GetValueForKeyAsString("error", error))
1455 strm << "E " << error;
1456 else {
1457 llvm::StringRef resolved_dwo_path;
1458 if (dict->GetValueForKeyAsString("resolved_dwo_path",
1459 resolved_dwo_path)) {
1460 strm << " " << resolved_dwo_path;
1461 if (resolved_dwo_path.ends_with(".dwp")) {
1462 llvm::StringRef dwo_name;
1463 if (dict->GetValueForKeyAsString("dwo_name", dwo_name))
1464 strm << "(" << dwo_name << ")";
1465 }
1466 }
1467 }
1468 strm.EOL();
1469 return true;
1470 });
1471}
1472
1473static void DumpOsoFilesTable(Stream &strm,
1474 StructuredData::Array &oso_listings) {
1475 strm.PutCString("Mod Time Err Oso Path");
1476 strm.EOL();
1477 strm.PutCString("------------------ --- ---------------------");
1478 strm.EOL();
1479 oso_listings.ForEach([&strm](StructuredData::Object *oso) {
1481 if (!dict)
1482 return false;
1483
1484 uint32_t oso_mod_time;
1485 if (dict->GetValueForKeyAsInteger("oso_mod_time", oso_mod_time))
1486 strm.Printf("0x%16.16" PRIx32 " ", oso_mod_time);
1487
1488 llvm::StringRef error;
1489 if (dict->GetValueForKeyAsString("error", error))
1490 strm << "E " << error;
1491 else {
1492 llvm::StringRef oso_path;
1493 if (dict->GetValueForKeyAsString("oso_path", oso_path))
1494 strm << " " << oso_path;
1495 }
1496 strm.EOL();
1497 return true;
1498 });
1499}
1500
1501static void
1502DumpAddress(ExecutionContextScope *exe_scope, const Address &so_addr,
1503 bool verbose, bool all_ranges, Stream &strm,
1504 std::optional<Stream::HighlightSettings> settings = std::nullopt) {
1505 strm.IndentMore();
1506 strm.Indent(" Address: ");
1507 so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
1508 strm.PutCString(" (");
1509 so_addr.Dump(&strm, exe_scope, Address::DumpStyleSectionNameOffset);
1510 strm.PutCString(")\n");
1511 strm.Indent(" Summary: ");
1512 const uint32_t save_indent = strm.GetIndentLevel();
1513 strm.SetIndentLevel(save_indent + 13);
1514 so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription,
1515 Address::DumpStyleInvalid, UINT32_MAX, false, settings);
1516 strm.SetIndentLevel(save_indent);
1517 // Print out detailed address information when verbose is enabled
1518 if (verbose) {
1519 strm.EOL();
1520 so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext,
1521 Address::DumpStyleInvalid, UINT32_MAX, all_ranges, settings);
1522 }
1523 strm.IndentLess();
1524}
1525
1526static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm,
1527 Module *module, uint32_t resolve_mask,
1528 lldb::addr_t raw_addr, lldb::addr_t offset,
1529 bool verbose, bool all_ranges) {
1530 if (module) {
1531 lldb::addr_t addr = raw_addr - offset;
1532 Address so_addr;
1533 SymbolContext sc;
1534 Target *target = interpreter.GetExecutionContext().GetTargetPtr();
1535 if (target && target->HasLoadedSections()) {
1536 if (!target->ResolveLoadAddress(addr, so_addr))
1537 return false;
1538 else if (so_addr.GetModule().get() != module)
1539 return false;
1540 } else {
1541 if (!module->ResolveFileAddress(addr, so_addr))
1542 return false;
1543 }
1544
1545 ExecutionContextScope *exe_scope =
1547 DumpAddress(exe_scope, so_addr, verbose, all_ranges, strm);
1548 return true;
1549 }
1550
1551 return false;
1552}
1553
1554static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
1555 Stream &strm, Module *module,
1556 const char *name, bool name_is_regex,
1557 bool verbose, bool all_ranges) {
1558 if (!module)
1559 return 0;
1560
1561 Symtab *symtab = module->GetSymtab();
1562 if (!symtab)
1563 return 0;
1564
1565 SymbolContext sc;
1566 const bool use_color = interpreter.GetDebugger().GetUseColor();
1567 std::vector<uint32_t> match_indexes;
1568 ConstString symbol_name(name);
1569 uint32_t num_matches = 0;
1570 if (name_is_regex) {
1571 RegularExpression name_regexp(symbol_name.GetStringRef());
1572 num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType(
1573 name_regexp, eSymbolTypeAny, match_indexes);
1574 } else {
1575 num_matches =
1576 symtab->AppendSymbolIndexesWithName(symbol_name, match_indexes);
1577 }
1578
1579 if (num_matches > 0) {
1580 strm.Indent();
1581 strm.Printf("%u symbols match %s'%s' in ", num_matches,
1582 name_is_regex ? "the regular expression " : "", name);
1583 DumpFullpath(strm, &module->GetFileSpec(), 0);
1584 strm.PutCString(":\n");
1585 strm.IndentMore();
1587 name, interpreter.GetDebugger().GetRegexMatchAnsiPrefix(),
1588 interpreter.GetDebugger().GetRegexMatchAnsiSuffix());
1589 for (uint32_t i = 0; i < num_matches; ++i) {
1590 Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
1591 if (symbol) {
1592 if (symbol->ValueIsAddress()) {
1595 symbol->GetAddressRef(), verbose, all_ranges, strm,
1596 use_color && name_is_regex
1597 ? std::optional<Stream::HighlightSettings>{settings}
1598 : std::nullopt);
1599 strm.EOL();
1600 } else {
1601 strm.IndentMore();
1602 strm.Indent(" Name: ");
1604 symbol->GetDisplayName().GetStringRef(),
1605 use_color && name_is_regex
1606 ? std::optional<Stream::HighlightSettings>{settings}
1607 : std::nullopt);
1608 strm.EOL();
1609 strm.Indent(" Value: ");
1610 strm.Printf("0x%16.16" PRIx64 "\n", symbol->GetRawValue());
1611 if (symbol->GetByteSizeIsValid()) {
1612 strm.Indent(" Size: ");
1613 strm.Printf("0x%16.16" PRIx64 "\n", symbol->GetByteSize());
1614 }
1615 strm.IndentLess();
1616 }
1617 }
1618 }
1619 strm.IndentLess();
1620 }
1621 return num_matches;
1622}
1623
1625 ExecutionContextScope *exe_scope, Stream &strm,
1626 const SymbolContextList &sc_list, bool verbose, bool all_ranges,
1627 std::optional<Stream::HighlightSettings> settings = std::nullopt) {
1628 strm.IndentMore();
1629 bool first_module = true;
1630 for (const SymbolContext &sc : sc_list) {
1631 if (!first_module)
1632 strm.EOL();
1633
1634 Address addr;
1635 if (sc.line_entry.IsValid())
1636 addr = sc.line_entry.range.GetBaseAddress();
1637 else if (sc.block && sc.block->GetContainingInlinedBlock())
1638 sc.block->GetContainingInlinedBlock()->GetStartAddress(addr);
1639 else
1640 addr = sc.GetFunctionOrSymbolAddress();
1641
1642 DumpAddress(exe_scope, addr, verbose, all_ranges, strm, settings);
1643 first_module = false;
1644 }
1645 strm.IndentLess();
1646}
1647
1649 Stream &strm, Module *module,
1650 const char *name, bool name_is_regex,
1651 const ModuleFunctionSearchOptions &options,
1652 bool verbose, bool all_ranges) {
1653 if (module && name && name[0]) {
1654 SymbolContextList sc_list;
1655 size_t num_matches = 0;
1656 if (name_is_regex) {
1657 RegularExpression function_name_regex((llvm::StringRef(name)));
1658 module->FindFunctions(function_name_regex, options, sc_list);
1659 } else {
1660 ConstString function_name(name);
1661 module->FindFunctions(function_name, CompilerDeclContext(),
1662 eFunctionNameTypeAuto, options, sc_list);
1663 }
1664 num_matches = sc_list.GetSize();
1665 if (num_matches) {
1666 strm.Indent();
1667 strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
1668 num_matches > 1 ? "es" : "");
1669 DumpFullpath(strm, &module->GetFileSpec(), 0);
1670 strm.PutCString(":\n");
1673 strm, sc_list, verbose, all_ranges);
1674 }
1675 return num_matches;
1676 }
1677 return 0;
1678}
1679
1680static size_t LookupTypeInModule(Target *target,
1681 CommandInterpreter &interpreter, Stream &strm,
1682 Module *module, const char *name_cstr,
1683 bool name_is_regex) {
1684 if (module && name_cstr && name_cstr[0]) {
1685 TypeQuery query(name_cstr);
1686 TypeResults results;
1687 module->FindTypes(query, results);
1688
1689 TypeList type_list;
1690 SymbolContext sc;
1691 if (module)
1692 sc.module_sp = module->shared_from_this();
1693 // Sort the type results and put the results that matched in \a module
1694 // first if \a module was specified.
1695 sc.SortTypeList(results.GetTypeMap(), type_list);
1696 if (type_list.Empty())
1697 return 0;
1698
1699 const uint64_t num_matches = type_list.GetSize();
1700
1701 strm.Indent();
1702 strm.Printf("%" PRIu64 " match%s found in ", num_matches,
1703 num_matches > 1 ? "es" : "");
1704 DumpFullpath(strm, &module->GetFileSpec(), 0);
1705 strm.PutCString(":\n");
1706 for (TypeSP type_sp : type_list.Types()) {
1707 if (!type_sp)
1708 continue;
1709 // Resolve the clang type so that any forward references to types
1710 // that haven't yet been parsed will get parsed.
1711 type_sp->GetFullCompilerType();
1712 type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target);
1713 // Print all typedef chains
1714 TypeSP typedef_type_sp(type_sp);
1715 TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1716 while (typedefed_type_sp) {
1717 strm.EOL();
1718 strm.Printf(" typedef '%s': ",
1719 typedef_type_sp->GetName().GetCString());
1720 typedefed_type_sp->GetFullCompilerType();
1721 typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true,
1722 target);
1723 typedef_type_sp = typedefed_type_sp;
1724 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1725 }
1726 strm.EOL();
1727 }
1728 return type_list.GetSize();
1729 }
1730 return 0;
1731}
1732
1733static size_t LookupTypeHere(Target *target, CommandInterpreter &interpreter,
1734 Stream &strm, Module &module,
1735 const char *name_cstr, bool name_is_regex) {
1736 TypeQuery query(name_cstr);
1737 TypeResults results;
1738 module.FindTypes(query, results);
1739 TypeList type_list;
1740 SymbolContext sc;
1741 sc.module_sp = module.shared_from_this();
1742 sc.SortTypeList(results.GetTypeMap(), type_list);
1743 if (type_list.Empty())
1744 return 0;
1745
1746 strm.Indent();
1747 strm.PutCString("Best match found in ");
1748 DumpFullpath(strm, &module.GetFileSpec(), 0);
1749 strm.PutCString(":\n");
1750
1751 TypeSP type_sp(type_list.GetTypeAtIndex(0));
1752 if (type_sp) {
1753 // Resolve the clang type so that any forward references to types that
1754 // haven't yet been parsed will get parsed.
1755 type_sp->GetFullCompilerType();
1756 type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target);
1757 // Print all typedef chains.
1758 TypeSP typedef_type_sp(type_sp);
1759 TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1760 while (typedefed_type_sp) {
1761 strm.EOL();
1762 strm.Printf(" typedef '%s': ",
1763 typedef_type_sp->GetName().GetCString());
1764 typedefed_type_sp->GetFullCompilerType();
1765 typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true,
1766 target);
1767 typedef_type_sp = typedefed_type_sp;
1768 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1769 }
1770 }
1771 strm.EOL();
1772 return type_list.GetSize();
1773}
1774
1776 Stream &strm, Module *module,
1777 const FileSpec &file_spec,
1778 uint32_t line, bool check_inlines,
1779 bool verbose, bool all_ranges) {
1780 if (module && file_spec) {
1781 SymbolContextList sc_list;
1782 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(
1783 file_spec, line, check_inlines, eSymbolContextEverything, sc_list);
1784 if (num_matches > 0) {
1785 strm.Indent();
1786 strm.Printf("%u match%s found in ", num_matches,
1787 num_matches > 1 ? "es" : "");
1788 strm << file_spec;
1789 if (line > 0)
1790 strm.Printf(":%u", line);
1791 strm << " in ";
1792 DumpFullpath(strm, &module->GetFileSpec(), 0);
1793 strm.PutCString(":\n");
1796 strm, sc_list, verbose, all_ranges);
1797 return num_matches;
1798 }
1799 }
1800 return 0;
1801}
1802
1803static size_t FindModulesByName(Target *target, const char *module_name,
1804 ModuleList &module_list,
1805 bool check_global_list) {
1806 FileSpec module_file_spec(module_name);
1807 ModuleSpec module_spec(module_file_spec);
1808
1809 const size_t initial_size = module_list.GetSize();
1810
1811 if (check_global_list) {
1812 // Check the global list
1813 std::lock_guard<std::recursive_mutex> guard(
1815 const size_t num_modules = Module::GetNumberAllocatedModules();
1816 ModuleSP module_sp;
1817 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
1818 Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
1819
1820 if (module) {
1821 if (module->MatchesModuleSpec(module_spec)) {
1822 module_sp = module->shared_from_this();
1823 module_list.AppendIfNeeded(module_sp);
1824 }
1825 }
1826 }
1827 } else {
1828 if (target) {
1829 target->GetImages().FindModules(module_spec, module_list);
1830 const size_t num_matches = module_list.GetSize();
1831
1832 // Not found in our module list for our target, check the main shared
1833 // module list in case it is a extra file used somewhere else
1834 if (num_matches == 0) {
1835 module_spec.GetArchitecture() = target->GetArchitecture();
1836 ModuleList::FindSharedModules(module_spec, module_list);
1837 }
1838 } else {
1839 ModuleList::FindSharedModules(module_spec, module_list);
1840 }
1841 }
1842
1843 return module_list.GetSize() - initial_size;
1844}
1845
1846#pragma mark CommandObjectTargetModulesModuleAutoComplete
1847
1848// A base command object class that can auto complete with module file
1849// paths
1850
1852 : public CommandObjectParsed {
1853public:
1855 const char *name,
1856 const char *help,
1857 const char *syntax,
1858 uint32_t flags = 0)
1859 : CommandObjectParsed(interpreter, name, help, syntax, flags) {
1861 }
1862
1864
1865 void
1871};
1872
1873#pragma mark CommandObjectTargetModulesSourceFileAutoComplete
1874
1875// A base command object class that can auto complete with module source
1876// file paths
1877
1879 : public CommandObjectParsed {
1880public:
1882 CommandInterpreter &interpreter, const char *name, const char *help,
1883 const char *syntax, uint32_t flags)
1884 : CommandObjectParsed(interpreter, name, help, syntax, flags) {
1886 }
1887
1889
1890 void
1896};
1897
1898#pragma mark CommandObjectTargetModulesDumpObjfile
1899
1902public:
1905 interpreter, "target modules dump objfile",
1906 "Dump the object file headers from one or more target modules.",
1907 nullptr, eCommandRequiresTarget) {}
1908
1910
1911protected:
1912 void DoExecute(Args &command, CommandReturnObject &result) override {
1913 Target &target = GetTarget();
1914
1915 uint32_t addr_byte_size = target.GetArchitecture().GetAddressByteSize();
1916 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1917 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1918
1919 size_t num_dumped = 0;
1920 if (command.GetArgumentCount() == 0) {
1921 // Dump all headers for all modules images
1922 num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(),
1923 target.GetImages());
1924 if (num_dumped == 0) {
1925 result.AppendError("the target has no associated executable images");
1926 }
1927 } else {
1928 // Find the modules that match the basename or full path.
1929 ModuleList module_list;
1930 const char *arg_cstr;
1931 for (int arg_idx = 0;
1932 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
1933 ++arg_idx) {
1934 size_t num_matched =
1935 FindModulesByName(&target, arg_cstr, module_list, true);
1936 if (num_matched == 0) {
1938 "Unable to find an image that matches '%s'.\n", arg_cstr);
1939 }
1940 }
1941 // Dump all the modules we found.
1942 num_dumped =
1943 DumpModuleObjfileHeaders(result.GetOutputStream(), module_list);
1944 }
1945
1946 if (num_dumped > 0) {
1948 } else {
1949 result.AppendError("no matching executable images found");
1950 }
1951 }
1952};
1953
1954#define LLDB_OPTIONS_target_modules_dump_symtab
1955#include "CommandOptions.inc"
1956
1959public:
1962 interpreter, "target modules dump symtab",
1963 "Dump the symbol table from one or more target modules.", nullptr,
1964 eCommandRequiresTarget) {}
1965
1967
1968 Options *GetOptions() override { return &m_options; }
1969
1970 class CommandOptions : public Options {
1971 public:
1972 CommandOptions() = default;
1973
1974 ~CommandOptions() override = default;
1975
1976 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1977 ExecutionContext *execution_context) override {
1978 Status error;
1979 const int short_option = m_getopt_table[option_idx].val;
1980
1981 switch (short_option) {
1982 case 'm':
1983 m_prefer_mangled.SetCurrentValue(true);
1984 m_prefer_mangled.SetOptionWasSet();
1985 break;
1986
1987 case 's':
1989 option_arg, GetDefinitions()[option_idx].enum_values,
1991 break;
1992
1993 default:
1994 llvm_unreachable("Unimplemented option");
1995 }
1996 return error;
1997 }
1998
1999 void OptionParsingStarting(ExecutionContext *execution_context) override {
2001 m_prefer_mangled.Clear();
2002 }
2003
2004 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2005 return llvm::ArrayRef(g_target_modules_dump_symtab_options);
2006 }
2007
2010 };
2011
2012protected:
2013 void DoExecute(Args &command, CommandReturnObject &result) override {
2014 Target &target = GetTarget();
2015 uint32_t num_dumped = 0;
2016 Mangled::NamePreference name_preference =
2017 (m_options.m_prefer_mangled ? Mangled::ePreferMangled
2019
2020 uint32_t addr_byte_size = target.GetArchitecture().GetAddressByteSize();
2021 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2022 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2023
2024 if (command.GetArgumentCount() == 0) {
2025 // Dump all sections for all modules images
2026 const ModuleList &module_list = target.GetImages();
2027 std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
2028 const size_t num_modules = module_list.GetSize();
2029 if (num_modules > 0) {
2030 result.GetOutputStream().Format(
2031 "Dumping symbol table for {0} modules.\n", num_modules);
2032 for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
2033 if (num_dumped > 0) {
2034 result.GetOutputStream().EOL();
2035 result.GetOutputStream().EOL();
2036 }
2038 "Interrupted in dump all symtabs with {0} "
2039 "of {1} dumped.", num_dumped, num_modules))
2040 break;
2041
2042 num_dumped++;
2044 module_sp.get(), m_options.m_sort_order,
2045 name_preference);
2046 }
2047 } else {
2048 result.AppendError("the target has no associated executable images");
2049 return;
2050 }
2051 } else {
2052 // Dump specified images (by basename or fullpath)
2053 const char *arg_cstr;
2054 for (int arg_idx = 0;
2055 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2056 ++arg_idx) {
2057 ModuleList module_list;
2058 const size_t num_matches =
2059 FindModulesByName(&target, arg_cstr, module_list, true);
2060 if (num_matches > 0) {
2061 for (ModuleSP module_sp : module_list.Modules()) {
2062 if (module_sp) {
2063 if (num_dumped > 0) {
2064 result.GetOutputStream().EOL();
2065 result.GetOutputStream().EOL();
2066 }
2068 "Interrupted in dump symtab list with {0} of {1} dumped.",
2069 num_dumped, num_matches))
2070 break;
2071
2072 num_dumped++;
2074 module_sp.get(), m_options.m_sort_order,
2075 name_preference);
2076 }
2077 }
2078 } else
2080 "Unable to find an image that matches '%s'.\n", arg_cstr);
2081 }
2082 }
2083
2084 if (num_dumped > 0)
2086 else {
2087 result.AppendError("no matching executable images found");
2088 }
2089 }
2090
2092};
2093
2094#pragma mark CommandObjectTargetModulesDumpSections
2095
2096// Image section dumping command
2097
2100public:
2103 interpreter, "target modules dump sections",
2104 "Dump the sections from one or more target modules.",
2105 //"target modules dump sections [<file1> ...]")
2106 nullptr, eCommandRequiresTarget) {}
2107
2109
2110protected:
2111 void DoExecute(Args &command, CommandReturnObject &result) override {
2112 Target &target = GetTarget();
2113 uint32_t num_dumped = 0;
2114
2115 uint32_t addr_byte_size = target.GetArchitecture().GetAddressByteSize();
2116 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2117 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2118
2119 if (command.GetArgumentCount() == 0) {
2120 // Dump all sections for all modules images
2121 const size_t num_modules = target.GetImages().GetSize();
2122 if (num_modules == 0) {
2123 result.AppendError("the target has no associated executable images");
2124 return;
2125 }
2126
2127 result.GetOutputStream().Format("Dumping sections for {0} modules.\n",
2128 num_modules);
2129 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2131 "Interrupted in dump all sections with {0} of {1} dumped",
2132 image_idx, num_modules))
2133 break;
2134
2135 num_dumped++;
2138 target.GetImages().GetModulePointerAtIndex(image_idx));
2139 }
2140 } else {
2141 // Dump specified images (by basename or fullpath)
2142 const char *arg_cstr;
2143 for (int arg_idx = 0;
2144 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2145 ++arg_idx) {
2146 ModuleList module_list;
2147 const size_t num_matches =
2148 FindModulesByName(&target, arg_cstr, module_list, true);
2149 if (num_matches > 0) {
2150 for (size_t i = 0; i < num_matches; ++i) {
2152 "Interrupted in dump section list with {0} of {1} dumped.",
2153 i, num_matches))
2154 break;
2155
2156 Module *module = module_list.GetModulePointerAtIndex(i);
2157 if (module) {
2158 num_dumped++;
2160 module);
2161 }
2162 }
2163 } else {
2164 // Check the global list
2165 std::lock_guard<std::recursive_mutex> guard(
2167
2169 "Unable to find an image that matches '%s'.\n", arg_cstr);
2170 }
2171 }
2172 }
2173
2174 if (num_dumped > 0)
2176 else {
2177 result.AppendError("no matching executable images found");
2178 }
2179 }
2180};
2181
2183public:
2186 interpreter, "target modules dump pcm-info",
2187 "Dump information about the given clang module (pcm).") {
2188 // Take a single file argument.
2190 }
2191
2193
2194protected:
2195 void DoExecute(Args &command, CommandReturnObject &result) override {
2196 if (command.GetArgumentCount() != 1) {
2197 result.AppendErrorWithFormat("'%s' takes exactly one pcm path argument.",
2198 m_cmd_name.c_str());
2199 return;
2200 }
2201
2202 const char *pcm_path = command.GetArgumentAtIndex(0);
2203 const FileSpec pcm_file{pcm_path};
2204
2205 if (pcm_file.GetFileNameExtension() != ".pcm") {
2206 result.AppendError("file must have a .pcm extension");
2207 return;
2208 }
2209
2210 if (!FileSystem::Instance().Exists(pcm_file)) {
2211 result.AppendError("pcm file does not exist");
2212 return;
2213 }
2214
2215 const char *clang_args[] = {"clang", pcm_path};
2216 clang::CompilerInstance compiler(clang::createInvocation(clang_args));
2217 compiler.setVirtualFileSystem(
2218 FileSystem::Instance().GetVirtualFileSystem());
2219 compiler.createDiagnostics();
2220
2221 // Pass empty deleter to not attempt to free memory that was allocated
2222 // outside of the current scope, possibly statically.
2223 std::shared_ptr<llvm::raw_ostream> Out(
2224 &result.GetOutputStream().AsRawOstream(), [](llvm::raw_ostream *) {});
2225 clang::DumpModuleInfoAction dump_module_info(Out);
2226 // DumpModuleInfoAction requires ObjectFilePCHContainerReader.
2227 compiler.getPCHContainerOperations()->registerReader(
2228 std::make_unique<clang::ObjectFilePCHContainerReader>());
2229
2230 if (compiler.ExecuteAction(dump_module_info))
2232 }
2233};
2234
2235#pragma mark CommandObjectTargetModulesDumpClangAST
2236
2237// Clang AST dumping command
2238
2241public:
2244 interpreter, "target modules dump ast",
2245 "Dump the clang ast for a given module's symbol file.",
2246 "target modules dump ast [--filter <name>] [<file1> ...]",
2247 eCommandRequiresTarget),
2248 m_filter(LLDB_OPT_SET_1, false, "filter", 'f', 0, eArgTypeName,
2249 "Dump only the decls whose names contain the specified filter "
2250 "string.",
2251 /*default_value=*/"") {
2253 m_option_group.Finalize();
2254 }
2255
2256 Options *GetOptions() override { return &m_option_group; }
2257
2259
2262
2263protected:
2264 void DoExecute(Args &command, CommandReturnObject &result) override {
2265 Target &target = GetTarget();
2266
2267 const ModuleList &module_list = target.GetImages();
2268 const size_t num_modules = module_list.GetSize();
2269 if (num_modules == 0) {
2270 result.AppendError("the target has no associated executable images");
2271 return;
2272 }
2273
2274 llvm::StringRef filter = m_filter.GetOptionValue().GetCurrentValueAsRef();
2275
2276 if (command.GetArgumentCount() == 0) {
2277 // Dump all ASTs for all modules images
2278 result.GetOutputStream().Format("Dumping clang ast for {0} modules.\n",
2279 num_modules);
2280 for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
2281 if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted dumping clang ast"))
2282 break;
2283 if (SymbolFile *sf = module_sp->GetSymbolFile())
2284 sf->DumpClangAST(result.GetOutputStream(), filter,
2285 GetCommandInterpreter().GetDebugger().GetUseColor());
2286 }
2288 return;
2289 }
2290
2291 // Dump specified ASTs (by basename or fullpath)
2292 for (const Args::ArgEntry &arg : command.entries()) {
2293 ModuleList module_list;
2294 const size_t num_matches =
2295 FindModulesByName(&target, arg.c_str(), module_list, true);
2296 if (num_matches == 0) {
2297 // Check the global list
2298 std::lock_guard<std::recursive_mutex> guard(
2300
2302 "Unable to find an image that matches '%s'.\n", arg.c_str());
2303 continue;
2304 }
2305
2306 for (size_t i = 0; i < num_matches; ++i) {
2308 "Interrupted in dump clang ast list with {0} of {1} dumped.",
2309 i, num_matches))
2310 break;
2311
2312 Module *m = module_list.GetModulePointerAtIndex(i);
2313 if (SymbolFile *sf = m->GetSymbolFile())
2314 sf->DumpClangAST(result.GetOutputStream(), filter,
2315 GetCommandInterpreter().GetDebugger().GetUseColor());
2316 }
2317 }
2319 }
2320};
2321
2322#pragma mark CommandObjectTargetModulesDumpSymfile
2323
2324// Image debug symbol dumping command
2325
2328public:
2331 interpreter, "target modules dump symfile",
2332 "Dump the debug symbol file for one or more target modules.",
2333 //"target modules dump symfile [<file1> ...]")
2334 nullptr, eCommandRequiresTarget) {}
2335
2337
2338protected:
2339 void DoExecute(Args &command, CommandReturnObject &result) override {
2340 Target &target = GetTarget();
2341 uint32_t num_dumped = 0;
2342
2343 uint32_t addr_byte_size = target.GetArchitecture().GetAddressByteSize();
2344 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2345 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2346
2347 if (command.GetArgumentCount() == 0) {
2348 // Dump all sections for all modules images
2349 const ModuleList &target_modules = target.GetImages();
2350 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2351 const size_t num_modules = target_modules.GetSize();
2352 if (num_modules == 0) {
2353 result.AppendError("the target has no associated executable images");
2354 return;
2355 }
2356 result.GetOutputStream().Format(
2357 "Dumping debug symbols for {0} modules.\n", num_modules);
2358 for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
2359 if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted in dumping all "
2360 "debug symbols with {0} of {1} modules dumped",
2361 num_dumped, num_modules))
2362 break;
2363
2364 if (DumpModuleSymbolFile(result.GetOutputStream(), module_sp.get()))
2365 num_dumped++;
2366 }
2367 } else {
2368 // Dump specified images (by basename or fullpath)
2369 const char *arg_cstr;
2370 for (int arg_idx = 0;
2371 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2372 ++arg_idx) {
2373 ModuleList module_list;
2374 const size_t num_matches =
2375 FindModulesByName(&target, arg_cstr, module_list, true);
2376 if (num_matches > 0) {
2377 for (size_t i = 0; i < num_matches; ++i) {
2378 if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted dumping {0} "
2379 "of {1} requested modules",
2380 i, num_matches))
2381 break;
2382 Module *module = module_list.GetModulePointerAtIndex(i);
2383 if (module) {
2384 if (DumpModuleSymbolFile(result.GetOutputStream(), module))
2385 num_dumped++;
2386 }
2387 }
2388 } else
2390 "Unable to find an image that matches '%s'.\n", arg_cstr);
2391 }
2392 }
2393
2394 if (num_dumped > 0)
2396 else {
2397 result.AppendError("no matching executable images found");
2398 }
2399 }
2400};
2401
2402#pragma mark CommandObjectTargetModulesDumpLineTable
2403#define LLDB_OPTIONS_target_modules_dump
2404#include "CommandOptions.inc"
2405
2406// Image debug line table dumping command
2407
2410public:
2413 interpreter, "target modules dump line-table",
2414 "Dump the line table for one or more compilation units.", nullptr,
2415 eCommandRequiresTarget) {}
2416
2418
2419 Options *GetOptions() override { return &m_options; }
2420
2421protected:
2422 void DoExecute(Args &command, CommandReturnObject &result) override {
2423 Target *target = m_exe_ctx.GetTargetPtr();
2424 uint32_t total_num_dumped = 0;
2425
2426 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2427 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2428 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2429
2430 if (command.GetArgumentCount() == 0) {
2431 result.AppendError("file option must be specified");
2432 return;
2433 } else {
2434 // Dump specified images (by basename or fullpath)
2435 const char *arg_cstr;
2436 for (int arg_idx = 0;
2437 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2438 ++arg_idx) {
2439 FileSpec file_spec(arg_cstr);
2440
2441 const ModuleList &target_modules = target->GetImages();
2442 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2443 size_t num_modules = target_modules.GetSize();
2444 if (num_modules > 0) {
2445 uint32_t num_dumped = 0;
2446 for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
2448 "Interrupted in dump all line tables with "
2449 "{0} of {1} dumped", num_dumped,
2450 num_modules))
2451 break;
2452
2454 m_interpreter, result.GetOutputStream(), module_sp.get(),
2455 file_spec,
2458 num_dumped++;
2459 }
2460 if (num_dumped == 0)
2462 "No source filenames matched '%s'.\n", arg_cstr);
2463 else
2464 total_num_dumped += num_dumped;
2465 }
2466 }
2467 }
2468
2469 if (total_num_dumped > 0)
2471 else {
2472 result.AppendError("no source filenames matched any command arguments");
2473 }
2474 }
2475
2476 class CommandOptions : public Options {
2477 public:
2479
2480 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2481 ExecutionContext *execution_context) override {
2482 assert(option_idx == 0 && "We only have one option.");
2483 m_verbose = true;
2484
2485 return Status();
2486 }
2487
2488 void OptionParsingStarting(ExecutionContext *execution_context) override {
2489 m_verbose = false;
2490 }
2491
2492 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2493 return llvm::ArrayRef(g_target_modules_dump_options);
2494 }
2495
2497 };
2498
2500};
2501
2502#pragma mark CommandObjectTargetModulesDumpSeparateDebugInfoFiles
2503#define LLDB_OPTIONS_target_modules_dump_separate_debug_info
2504#include "CommandOptions.inc"
2505
2506// Image debug separate debug info dumping command
2507
2510public:
2512 CommandInterpreter &interpreter)
2514 interpreter, "target modules dump separate-debug-info",
2515 "List the separate debug info symbol files for one or more target "
2516 "modules.",
2517 nullptr, eCommandRequiresTarget) {}
2518
2520
2521 Options *GetOptions() override { return &m_options; }
2522
2523 class CommandOptions : public Options {
2524 public:
2525 CommandOptions() = default;
2526
2527 ~CommandOptions() override = default;
2528
2529 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2530 ExecutionContext *execution_context) override {
2531 Status error;
2532 const int short_option = m_getopt_table[option_idx].val;
2533
2534 switch (short_option) {
2535 case 'f':
2536 m_load_all_debug_info.SetCurrentValue(true);
2537 m_load_all_debug_info.SetOptionWasSet();
2538 break;
2539 case 'j':
2540 m_json.SetCurrentValue(true);
2541 m_json.SetOptionWasSet();
2542 break;
2543 case 'e':
2544 m_errors_only.SetCurrentValue(true);
2545 m_errors_only.SetOptionWasSet();
2546 break;
2547 default:
2548 llvm_unreachable("Unimplemented option");
2549 }
2550 return error;
2551 }
2552
2553 void OptionParsingStarting(ExecutionContext *execution_context) override {
2554 m_json.Clear();
2555 m_errors_only.Clear();
2556 m_load_all_debug_info.Clear();
2557 }
2558
2559 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2560 return llvm::ArrayRef(g_target_modules_dump_separate_debug_info_options);
2561 }
2562
2566 };
2567
2568protected:
2569 void DoExecute(Args &command, CommandReturnObject &result) override {
2570 Target &target = GetTarget();
2571 uint32_t num_dumped = 0;
2572
2573 uint32_t addr_byte_size = target.GetArchitecture().GetAddressByteSize();
2574 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2575 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2576
2577 StructuredData::Array separate_debug_info_lists_by_module;
2578 if (command.GetArgumentCount() == 0) {
2579 // Dump all sections for all modules images
2580 const ModuleList &target_modules = target.GetImages();
2581 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2582 const size_t num_modules = target_modules.GetSize();
2583 if (num_modules == 0) {
2584 result.AppendError("the target has no associated executable images");
2585 return;
2586 }
2587 for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
2589 GetDebugger(),
2590 "Interrupted in dumping all "
2591 "separate debug info with {0} of {1} modules dumped",
2592 num_dumped, num_modules))
2593 break;
2594
2595 if (GetSeparateDebugInfoList(separate_debug_info_lists_by_module,
2596 module_sp.get(),
2597 bool(m_options.m_errors_only),
2598 bool(m_options.m_load_all_debug_info)))
2599 num_dumped++;
2600 }
2601 } else {
2602 // Dump specified images (by basename or fullpath)
2603 const char *arg_cstr;
2604 for (int arg_idx = 0;
2605 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2606 ++arg_idx) {
2607 ModuleList module_list;
2608 const size_t num_matches =
2609 FindModulesByName(&target, arg_cstr, module_list, true);
2610 if (num_matches > 0) {
2611 for (size_t i = 0; i < num_matches; ++i) {
2613 "Interrupted dumping {0} "
2614 "of {1} requested modules",
2615 i, num_matches))
2616 break;
2617 Module *module = module_list.GetModulePointerAtIndex(i);
2618 if (GetSeparateDebugInfoList(separate_debug_info_lists_by_module,
2619 module, bool(m_options.m_errors_only),
2620 bool(m_options.m_load_all_debug_info)))
2621 num_dumped++;
2622 }
2623 } else
2625 "Unable to find an image that matches '%s'.\n", arg_cstr);
2626 }
2627 }
2628
2629 if (num_dumped > 0) {
2630 Stream &strm = result.GetOutputStream();
2631 // Display the debug info files in some format.
2632 if (m_options.m_json) {
2633 // JSON format
2634 separate_debug_info_lists_by_module.Dump(strm,
2635 /*pretty_print=*/true);
2636 } else {
2637 // Human-readable table format
2638 separate_debug_info_lists_by_module.ForEach(
2639 [&result, &strm](StructuredData::Object *obj) {
2640 if (!obj) {
2641 return false;
2642 }
2643
2644 // Each item in `separate_debug_info_lists_by_module` should be a
2645 // valid structured data dictionary.
2646 StructuredData::Dictionary *separate_debug_info_list =
2647 obj->GetAsDictionary();
2648 if (!separate_debug_info_list) {
2649 return false;
2650 }
2651
2652 llvm::StringRef type;
2653 llvm::StringRef symfile;
2654 StructuredData::Array *files;
2655 if (!(separate_debug_info_list->GetValueForKeyAsString("type",
2656 type) &&
2657 separate_debug_info_list->GetValueForKeyAsString("symfile",
2658 symfile) &&
2659 separate_debug_info_list->GetValueForKeyAsArray(
2660 "separate-debug-info-files", files))) {
2661 assert(false);
2662 }
2663
2664 strm << "Symbol file: " << symfile;
2665 strm.EOL();
2666 strm << "Type: \"" << type << "\"";
2667 strm.EOL();
2668 if (type == "dwo") {
2669 DumpDwoFilesTable(strm, *files);
2670 } else if (type == "oso") {
2671 DumpOsoFilesTable(strm, *files);
2672 } else {
2674 "Found unsupported debug info type '%s'.\n",
2675 type.str().c_str());
2676 }
2677 return true;
2678 });
2679 }
2681 } else {
2682 result.AppendError("no matching executable images found");
2683 }
2684 }
2685
2687};
2688
2689#pragma mark CommandObjectTargetModulesDump
2690
2691// Dump multi-word command for target modules
2692
2694public:
2695 // Constructors and Destructors
2698 interpreter, "target modules dump",
2699 "Commands for dumping information about one or more target "
2700 "modules.",
2701 "target modules dump "
2702 "[objfile|symtab|sections|ast|symfile|line-table|pcm-info|separate-"
2703 "debug-info] "
2704 "[<file1> <file2> ...]") {
2705 LoadSubCommand("objfile",
2707 new CommandObjectTargetModulesDumpObjfile(interpreter)));
2709 "symtab",
2711 LoadSubCommand("sections",
2713 interpreter)));
2714 LoadSubCommand("symfile",
2716 new CommandObjectTargetModulesDumpSymfile(interpreter)));
2718 "ast", CommandObjectSP(
2719 new CommandObjectTargetModulesDumpClangAST(interpreter)));
2720 LoadSubCommand("line-table",
2722 interpreter)));
2724 "pcm-info",
2727 LoadSubCommand("separate-debug-info",
2730 interpreter)));
2731 }
2732
2734};
2735
2737public:
2739 : CommandObjectParsed(interpreter, "target modules add",
2740 "Add a new module to the current target's modules.",
2741 "target modules add [<module>]",
2742 eCommandRequiresTarget),
2743 m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
2745 "Fullpath to a stand alone debug "
2746 "symbols file for when debug symbols "
2747 "are not in the executable.") {
2751 m_option_group.Finalize();
2753 }
2754
2756
2757 Options *GetOptions() override { return &m_option_group; }
2758
2759protected:
2763
2764 void DoExecute(Args &args, CommandReturnObject &result) override {
2765 Target &target = GetTarget();
2766 bool flush = false;
2767
2768 const size_t argc = args.GetArgumentCount();
2769 if (argc == 0) {
2770 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2771 // We are given a UUID only, go locate the file
2772 ModuleSpec module_spec;
2773 module_spec.GetUUID() =
2774 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2775 if (m_symbol_file.GetOptionValue().OptionWasSet())
2776 module_spec.GetSymbolFileSpec() =
2777 m_symbol_file.GetOptionValue().GetCurrentValue();
2778 Status error;
2780 ModuleSP module_sp(
2781 target.GetOrCreateModule(module_spec, true /* notify */));
2782 if (module_sp) {
2784 return;
2785 } else {
2786 StreamString strm;
2787 module_spec.GetUUID().Dump(strm);
2788 if (module_spec.GetFileSpec()) {
2789 if (module_spec.GetSymbolFileSpec()) {
2790 result.AppendErrorWithFormat(
2791 "Unable to create the executable or symbol file with "
2792 "UUID %s with path %s and symbol file %s",
2793 strm.GetData(), module_spec.GetFileSpec().GetPath().c_str(),
2794 module_spec.GetSymbolFileSpec().GetPath().c_str());
2795 } else {
2796 result.AppendErrorWithFormat(
2797 "Unable to create the executable or symbol file with "
2798 "UUID %s with path %s",
2799 strm.GetData(),
2800 module_spec.GetFileSpec().GetPath().c_str());
2801 }
2802 } else {
2803 result.AppendErrorWithFormat("Unable to create the executable "
2804 "or symbol file with UUID %s",
2805 strm.GetData());
2806 }
2807 return;
2808 }
2809 } else {
2810 StreamString strm;
2811 module_spec.GetUUID().Dump(strm);
2812 result.AppendErrorWithFormat(
2813 "Unable to locate the executable or symbol file with UUID %s",
2814 strm.GetData());
2815 result.SetError(std::move(error));
2816 return;
2817 }
2818 } else {
2819 result.AppendError(
2820 "one or more executable image paths must be specified");
2821 return;
2822 }
2823 } else {
2824 for (auto &entry : args.entries()) {
2825 if (entry.ref().empty())
2826 continue;
2827
2828 FileSpec file_spec(entry.ref());
2829 if (FileSystem::Instance().Exists(file_spec)) {
2830 ModuleSpec module_spec(file_spec);
2831 if (m_uuid_option_group.GetOptionValue().OptionWasSet())
2832 module_spec.GetUUID() =
2833 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2834 if (m_symbol_file.GetOptionValue().OptionWasSet())
2835 module_spec.GetSymbolFileSpec() =
2836 m_symbol_file.GetOptionValue().GetCurrentValue();
2837 if (!module_spec.GetArchitecture().IsValid())
2838 module_spec.GetArchitecture() = target.GetArchitecture();
2839 Status error;
2840 ModuleSP module_sp(
2841 target.GetOrCreateModule(module_spec, true /* notify */, &error));
2842 if (!module_sp) {
2843 const char *error_cstr = error.AsCString();
2844 if (error_cstr)
2845 result.AppendError(error_cstr);
2846 else
2847 result.AppendErrorWithFormat("unsupported module: %s",
2848 entry.c_str());
2849 return;
2850 } else {
2851 flush = true;
2852 }
2854 } else {
2855 std::string resolved_path = file_spec.GetPath();
2856 if (resolved_path != entry.ref()) {
2857 result.AppendErrorWithFormat(
2858 "invalid module path '%s' with resolved path '%s'\n",
2859 entry.ref().str().c_str(), resolved_path.c_str());
2860 break;
2861 }
2862 result.AppendErrorWithFormat("invalid module path '%s'\n",
2863 entry.c_str());
2864 break;
2865 }
2866 }
2867 }
2868
2869 if (flush) {
2870 ProcessSP process = target.GetProcessSP();
2871 if (process)
2872 process->Flush();
2873 }
2874 }
2875};
2876
2879public:
2882 interpreter, "target modules load",
2883 "Set the load addresses for one or more sections in a target "
2884 "module.",
2885 "target modules load [--file <module> --uuid <uuid>] <sect-name> "
2886 "<address> [<sect-name> <address> ....]",
2887 eCommandRequiresTarget),
2888 m_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName,
2889 "Fullpath or basename for module to load.", ""),
2890 m_load_option(LLDB_OPT_SET_1, false, "load", 'l',
2891 "Write file contents to the memory.", false, true),
2892 m_pc_option(LLDB_OPT_SET_1, false, "set-pc-to-entry", 'p',
2893 "Set PC to the entry point."
2894 " Only applicable with '--load' option.",
2895 false, true),
2896 m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset,
2897 "Set the load address for all sections to be the "
2898 "virtual address in the file plus the offset.",
2899 0) {
2906 m_option_group.Finalize();
2907 }
2908
2910
2911 Options *GetOptions() override { return &m_option_group; }
2912
2913protected:
2914 void DoExecute(Args &args, CommandReturnObject &result) override {
2915 Target &target = GetTarget();
2916 const bool load = m_load_option.GetOptionValue().GetCurrentValue();
2917 const bool set_pc = m_pc_option.GetOptionValue().GetCurrentValue();
2918
2919 const size_t argc = args.GetArgumentCount();
2920 ModuleSpec module_spec;
2921 bool search_using_module_spec = false;
2922
2923 // Allow "load" option to work without --file or --uuid option.
2924 if (load) {
2925 if (!m_file_option.GetOptionValue().OptionWasSet() &&
2926 !m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2927 ModuleList &module_list = target.GetImages();
2928 if (module_list.GetSize() == 1) {
2929 search_using_module_spec = true;
2930 module_spec.GetFileSpec() =
2931 module_list.GetModuleAtIndex(0)->GetFileSpec();
2932 }
2933 }
2934 }
2935
2936 if (m_file_option.GetOptionValue().OptionWasSet()) {
2937 search_using_module_spec = true;
2938 const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
2939 const bool use_global_module_list = true;
2940 ModuleList module_list;
2941 const size_t num_matches = FindModulesByName(
2942 &target, arg_cstr, module_list, use_global_module_list);
2943 if (num_matches == 1) {
2944 module_spec.GetFileSpec() =
2945 module_list.GetModuleAtIndex(0)->GetFileSpec();
2946 } else if (num_matches > 1) {
2947 search_using_module_spec = false;
2948 result.AppendErrorWithFormat(
2949 "more than 1 module matched by name '%s'\n", arg_cstr);
2950 } else {
2951 search_using_module_spec = false;
2952 result.AppendErrorWithFormat("no object file for module '%s'\n",
2953 arg_cstr);
2954 }
2955 }
2956
2957 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2958 search_using_module_spec = true;
2959 module_spec.GetUUID() =
2960 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2961 }
2962
2963 if (search_using_module_spec) {
2964 ModuleList matching_modules;
2965 target.GetImages().FindModules(module_spec, matching_modules);
2966 const size_t num_matches = matching_modules.GetSize();
2967
2968 char path[PATH_MAX];
2969 if (num_matches == 1) {
2970 Module *module = matching_modules.GetModulePointerAtIndex(0);
2971 if (module) {
2972 ObjectFile *objfile = module->GetObjectFile();
2973 if (objfile) {
2974 SectionList *section_list = module->GetSectionList();
2975 if (section_list) {
2976 bool changed = false;
2977 if (argc == 0) {
2978 if (m_slide_option.GetOptionValue().OptionWasSet()) {
2979 const addr_t slide =
2980 m_slide_option.GetOptionValue().GetCurrentValue();
2981 const bool slide_is_offset = true;
2982 module->SetLoadAddress(target, slide, slide_is_offset,
2983 changed);
2984 } else {
2985 result.AppendError("one or more section name + load "
2986 "address pair must be specified");
2987 return;
2988 }
2989 } else {
2990 if (m_slide_option.GetOptionValue().OptionWasSet()) {
2991 result.AppendError("The \"--slide <offset>\" option can't "
2992 "be used in conjunction with setting "
2993 "section load addresses.\n");
2994 return;
2995 }
2996
2997 for (size_t i = 0; i < argc; i += 2) {
2998 const char *sect_name = args.GetArgumentAtIndex(i);
2999 const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1);
3000 if (sect_name && load_addr_cstr) {
3001 ConstString const_sect_name(sect_name);
3002 addr_t load_addr;
3003 if (llvm::to_integer(load_addr_cstr, load_addr)) {
3004 SectionSP section_sp(
3005 section_list->FindSectionByName(const_sect_name));
3006 if (section_sp) {
3007 if (section_sp->IsThreadSpecific()) {
3008 result.AppendErrorWithFormat(
3009 "thread specific sections are not yet "
3010 "supported (section '%s')\n",
3011 sect_name);
3012 break;
3013 } else {
3014 if (target.SetSectionLoadAddress(section_sp,
3015 load_addr))
3016 changed = true;
3018 "section '%s' loaded at 0x%" PRIx64 "\n",
3019 sect_name, load_addr);
3020 }
3021 } else {
3022 result.AppendErrorWithFormat("no section found that "
3023 "matches the section "
3024 "name '%s'\n",
3025 sect_name);
3026 break;
3027 }
3028 } else {
3029 result.AppendErrorWithFormat(
3030 "invalid load address string '%s'\n", load_addr_cstr);
3031 break;
3032 }
3033 } else {
3034 if (sect_name)
3035 result.AppendError("section names must be followed by "
3036 "a load address.\n");
3037 else
3038 result.AppendError("one or more section name + load "
3039 "address pair must be specified.\n");
3040 break;
3041 }
3042 }
3043 }
3044
3045 if (changed) {
3046 target.ModulesDidLoad(matching_modules);
3047 Process *process = m_exe_ctx.GetProcessPtr();
3048 if (process)
3049 process->Flush();
3050 }
3051 if (load) {
3052 ProcessSP process = target.CalculateProcess();
3053 Address file_entry = objfile->GetEntryPointAddress();
3054 if (!process) {
3055 result.AppendError("No process");
3056 return;
3057 }
3058 if (set_pc && !file_entry.IsValid()) {
3059 result.AppendError("No entry address in object file");
3060 return;
3061 }
3062 std::vector<ObjectFile::LoadableData> loadables(
3063 objfile->GetLoadableData(target));
3064 if (loadables.size() == 0) {
3065 result.AppendError("No loadable sections");
3066 return;
3067 }
3068 Status error = process->WriteObjectFile(std::move(loadables));
3069 if (error.Fail()) {
3070 result.AppendError(error.AsCString());
3071 return;
3072 }
3073 if (set_pc) {
3074 ThreadList &thread_list = process->GetThreadList();
3075 RegisterContextSP reg_context(
3076 thread_list.GetSelectedThread()->GetRegisterContext());
3077 addr_t file_entry_addr = file_entry.GetLoadAddress(&target);
3078 if (!reg_context->SetPC(file_entry_addr)) {
3079 result.AppendErrorWithFormat("failed to set PC value to "
3080 "0x%" PRIx64 "\n",
3081 file_entry_addr);
3082 }
3083 }
3084 }
3085 } else {
3086 module->GetFileSpec().GetPath(path, sizeof(path));
3087 result.AppendErrorWithFormat("no sections in object file '%s'\n",
3088 path);
3089 }
3090 } else {
3091 module->GetFileSpec().GetPath(path, sizeof(path));
3092 result.AppendErrorWithFormat("no object file for module '%s'\n",
3093 path);
3094 }
3095 } else {
3096 FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
3097 if (module_spec_file) {
3098 module_spec_file->GetPath(path, sizeof(path));
3099 result.AppendErrorWithFormat("invalid module '%s'.\n", path);
3100 } else
3101 result.AppendError("no module spec");
3102 }
3103 } else {
3104 std::string uuid_str;
3105
3106 if (module_spec.GetFileSpec())
3107 module_spec.GetFileSpec().GetPath(path, sizeof(path));
3108 else
3109 path[0] = '\0';
3110
3111 if (module_spec.GetUUIDPtr())
3112 uuid_str = module_spec.GetUUID().GetAsString();
3113 if (num_matches > 1) {
3114 result.AppendErrorWithFormat(
3115 "multiple modules match%s%s%s%s:\n", path[0] ? " file=" : "",
3116 path, !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
3117 for (size_t i = 0; i < num_matches; ++i) {
3118 if (matching_modules.GetModulePointerAtIndex(i)
3119 ->GetFileSpec()
3120 .GetPath(path, sizeof(path)))
3121 result.AppendMessageWithFormat("%s\n", path);
3122 }
3123 } else {
3124 result.AppendErrorWithFormat(
3125 "no modules were found that match%s%s%s%s.\n",
3126 path[0] ? " file=" : "", path, !uuid_str.empty() ? " uuid=" : "",
3127 uuid_str.c_str());
3128 }
3129 }
3130 } else {
3131 result.AppendError("either the \"--file <module>\" or the \"--uuid "
3132 "<uuid>\" option must be specified.\n");
3133 }
3134 }
3135
3142};
3143
3144#pragma mark CommandObjectTargetModulesList
3145// List images with associated information
3146#define LLDB_OPTIONS_target_modules_list
3147#include "CommandOptions.inc"
3148
3150public:
3151 class CommandOptions : public Options {
3152 public:
3153 CommandOptions() = default;
3154
3155 ~CommandOptions() override = default;
3156
3157 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3158 ExecutionContext *execution_context) override {
3159 Status error;
3160
3161 const int short_option = m_getopt_table[option_idx].val;
3162 if (short_option == 'g') {
3164 } else if (short_option == 'a') {
3166 execution_context, option_arg, LLDB_INVALID_ADDRESS, &error);
3167 } else {
3168 unsigned long width = 0;
3169 option_arg.getAsInteger(0, width);
3170 m_format_array.push_back(std::make_pair(short_option, width));
3171 }
3172 return error;
3173 }
3174
3175 void OptionParsingStarting(ExecutionContext *execution_context) override {
3176 m_format_array.clear();
3179 }
3180
3181 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3182 return llvm::ArrayRef(g_target_modules_list_options);
3183 }
3184
3185 // Instance variables to hold the values for command options.
3186 typedef std::vector<std::pair<char, uint32_t>> FormatWidthCollection;
3190 };
3191
3194 interpreter, "target modules list",
3195 "List current executable and dependent shared library images.") {
3197 }
3198
3200
3201 Options *GetOptions() override { return &m_options; }
3202
3203protected:
3204 void DoExecute(Args &command, CommandReturnObject &result) override {
3205 Target &target = GetTarget();
3206 const bool use_global_module_list = m_options.m_use_global_module_list;
3207 // Define a local module list here to ensure it lives longer than any
3208 // "locker" object which might lock its contents below (through the
3209 // "module_list_ptr" variable).
3210 ModuleList module_list;
3211 uint32_t addr_byte_size = target.GetArchitecture().GetAddressByteSize();
3212 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3213 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3214 // Dump all sections for all modules images
3215 Stream &strm = result.GetOutputStream();
3216
3217 if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) {
3218 Address module_address;
3219 if (module_address.SetLoadAddress(m_options.m_module_addr, &target)) {
3220 ModuleSP module_sp(module_address.GetModule());
3221 if (module_sp) {
3222 PrintModule(target, module_sp.get(), 0, strm);
3224 } else {
3225 result.AppendErrorWithFormat(
3226 "Couldn't find module matching address: 0x%" PRIx64 ".",
3227 m_options.m_module_addr);
3228 }
3229 } else {
3230 result.AppendErrorWithFormat(
3231 "Couldn't find module containing address: 0x%" PRIx64 ".",
3232 m_options.m_module_addr);
3233 }
3234 return;
3235 }
3236
3237 size_t num_modules = 0;
3238
3239 // This locker will be locked on the mutex in module_list_ptr if it is
3240 // non-nullptr. Otherwise it will lock the
3241 // AllocationModuleCollectionMutex when accessing the global module list
3242 // directly.
3243 std::unique_lock<std::recursive_mutex> guard(
3245
3246 const ModuleList *module_list_ptr = nullptr;
3247 const size_t argc = command.GetArgumentCount();
3248 if (argc == 0) {
3249 if (use_global_module_list) {
3250 guard.lock();
3251 num_modules = Module::GetNumberAllocatedModules();
3252 } else {
3253 module_list_ptr = &target.GetImages();
3254 }
3255 } else {
3256 for (const Args::ArgEntry &arg : command) {
3257 // Dump specified images (by basename or fullpath)
3258 const size_t num_matches = FindModulesByName(
3259 &target, arg.c_str(), module_list, use_global_module_list);
3260 if (num_matches == 0) {
3261 if (argc == 1) {
3262 result.AppendErrorWithFormat("no modules found that match '%s'",
3263 arg.c_str());
3264 return;
3265 }
3266 }
3267 }
3268
3269 module_list_ptr = &module_list;
3270 }
3271
3272 std::unique_lock<std::recursive_mutex> lock;
3273 if (module_list_ptr != nullptr) {
3274 lock =
3275 std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex());
3276
3277 num_modules = module_list_ptr->GetSize();
3278 }
3279
3280 if (num_modules > 0) {
3281 for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
3282 ModuleSP module_sp;
3283 Module *module;
3284 if (module_list_ptr) {
3285 module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
3286 module = module_sp.get();
3287 } else {
3288 module = Module::GetAllocatedModuleAtIndex(image_idx);
3289 module_sp = module->shared_from_this();
3290 }
3291
3292 const size_t indent = strm.Printf("[%3u] ", image_idx);
3293 PrintModule(target, module, indent, strm);
3294 }
3296 } else {
3297 if (argc) {
3298 if (use_global_module_list)
3299 result.AppendError(
3300 "the global module list has no matching modules");
3301 else
3302 result.AppendError("the target has no matching modules");
3303 } else {
3304 if (use_global_module_list)
3305 result.AppendError("the global module list is empty");
3306 else
3307 result.AppendError(
3308 "the target has no associated executable images");
3309 }
3310 return;
3311 }
3312 }
3313
3314 void PrintModule(Target &target, Module *module, int indent, Stream &strm) {
3315 if (module == nullptr) {
3316 strm.PutCString("Null module");
3317 return;
3318 }
3319
3320 bool dump_object_name = false;
3321 if (m_options.m_format_array.empty()) {
3322 m_options.m_format_array.push_back(std::make_pair('u', 0));
3323 m_options.m_format_array.push_back(std::make_pair('h', 0));
3324 m_options.m_format_array.push_back(std::make_pair('f', 0));
3325 m_options.m_format_array.push_back(std::make_pair('S', 0));
3326 }
3327 const size_t num_entries = m_options.m_format_array.size();
3328 bool print_space = false;
3329 for (size_t i = 0; i < num_entries; ++i) {
3330 if (print_space)
3331 strm.PutChar(' ');
3332 print_space = true;
3333 const char format_char = m_options.m_format_array[i].first;
3334 uint32_t width = m_options.m_format_array[i].second;
3335 switch (format_char) {
3336 case 'A':
3337 DumpModuleArchitecture(strm, module, false, width);
3338 break;
3339
3340 case 't':
3341 DumpModuleArchitecture(strm, module, true, width);
3342 break;
3343
3344 case 'f':
3345 DumpFullpath(strm, &module->GetFileSpec(), width);
3346 dump_object_name = true;
3347 break;
3348
3349 case 'd':
3350 DumpDirectory(strm, &module->GetFileSpec(), width);
3351 break;
3352
3353 case 'b':
3354 DumpBasename(strm, &module->GetFileSpec(), width);
3355 dump_object_name = true;
3356 break;
3357
3358 case 'h':
3359 case 'o':
3360 // Image header address
3361 {
3362 uint32_t addr_nibble_width =
3363 target.GetArchitecture().GetAddressByteSize() * 2;
3364
3365 ObjectFile *objfile = module->GetObjectFile();
3366 if (objfile) {
3367 Address base_addr(objfile->GetBaseAddress());
3368 if (base_addr.IsValid()) {
3369 if (target.HasLoadedSections()) {
3370 lldb::addr_t load_addr = base_addr.GetLoadAddress(&target);
3371 if (load_addr == LLDB_INVALID_ADDRESS) {
3372 base_addr.Dump(&strm, &target,
3375 } else {
3376 if (format_char == 'o') {
3377 // Show the offset of slide for the image
3378 strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3379 addr_nibble_width,
3380 load_addr - base_addr.GetFileAddress());
3381 } else {
3382 // Show the load address of the image
3383 strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3384 addr_nibble_width, load_addr);
3385 }
3386 }
3387 break;
3388 }
3389 // The address was valid, but the image isn't loaded, output the
3390 // address in an appropriate format
3391 base_addr.Dump(&strm, &target, Address::DumpStyleFileAddress);
3392 break;
3393 }
3394 }
3395 strm.Printf("%*s", addr_nibble_width + 2, "");
3396 }
3397 break;
3398
3399 case 'r': {
3400 size_t ref_count = 0;
3401 char in_shared_cache = 'Y';
3402
3403 ModuleSP module_sp(module->shared_from_this());
3404 if (!ModuleList::ModuleIsInCache(module))
3405 in_shared_cache = 'N';
3406 if (module_sp) {
3407 // Take one away to make sure we don't count our local "module_sp"
3408 ref_count = module_sp.use_count() - 1;
3409 }
3410 if (width)
3411 strm.Printf("{%c %*" PRIu64 "}", in_shared_cache, width, (uint64_t)ref_count);
3412 else
3413 strm.Printf("{%c %" PRIu64 "}", in_shared_cache, (uint64_t)ref_count);
3414 } break;
3415
3416 case 's':
3417 case 'S': {
3418 if (const SymbolFile *symbol_file = module->GetSymbolFile()) {
3419 const FileSpec symfile_spec =
3420 symbol_file->GetObjectFile()->GetFileSpec();
3421 if (format_char == 'S') {
3422 // Dump symbol file only if different from module file
3423 if (!symfile_spec || symfile_spec == module->GetFileSpec()) {
3424 print_space = false;
3425 break;
3426 }
3427 // Add a newline and indent past the index
3428 strm.Printf("\n%*s", indent, "");
3429 }
3430 DumpFullpath(strm, &symfile_spec, width);
3431 dump_object_name = true;
3432 break;
3433 }
3434 strm.Printf("%.*s", width, "<NONE>");
3435 } break;
3436
3437 case 'm':
3438 strm.Format("{0:%c}", llvm::fmt_align(module->GetModificationTime(),
3439 llvm::AlignStyle::Left, width));
3440 break;
3441
3442 case 'p':
3443 strm.Printf("%p", static_cast<void *>(module));
3444 break;
3445
3446 case 'u':
3447 DumpModuleUUID(strm, module);
3448 break;
3449
3450 default:
3451 break;
3452 }
3453 }
3454 if (dump_object_name) {
3455 const char *object_name = module->GetObjectName().GetCString();
3456 if (object_name)
3457 strm.Printf("(%s)", object_name);
3458 }
3459 strm.EOL();
3460 }
3461
3463};
3464
3465#pragma mark CommandObjectTargetModulesShowUnwind
3466
3467// Lookup unwind information in images
3468#define LLDB_OPTIONS_target_modules_show_unwind
3469#include "CommandOptions.inc"
3470
3472public:
3473 enum {
3480 };
3481
3482 class CommandOptions : public Options {
3483 public:
3484 CommandOptions() = default;
3485
3486 ~CommandOptions() override = default;
3487
3488 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3489 ExecutionContext *execution_context) override {
3490 Status error;
3491
3492 const int short_option = m_getopt_table[option_idx].val;
3493
3494 switch (short_option) {
3495 case 'a': {
3496 m_str = std::string(option_arg);
3498 m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
3502 "invalid address string '%s'", option_arg.str().c_str());
3503 break;
3504 }
3505
3506 case 'n':
3507 m_str = std::string(option_arg);
3509 break;
3510
3511 case 'c':
3512 bool value, success;
3513 value = OptionArgParser::ToBoolean(option_arg, false, &success);
3514 if (success) {
3515 m_cached = value;
3516 } else {
3518 "invalid boolean value '%s' passed for -c option", option_arg);
3519 }
3520 break;
3521
3522 default:
3523 llvm_unreachable("Unimplemented option");
3524 }
3525
3526 return error;
3527 }
3528
3529 void OptionParsingStarting(ExecutionContext *execution_context) override {
3531 m_str.clear();
3533 m_cached = false;
3534 }
3535
3536 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3537 return llvm::ArrayRef(g_target_modules_show_unwind_options);
3538 }
3539
3540 // Instance variables to hold the values for command options.
3541
3542 int m_type = eLookupTypeInvalid; // Should be a eLookupTypeXXX enum after
3543 // parsing options
3544 std::string m_str; // Holds name lookup
3545 lldb::addr_t m_addr = LLDB_INVALID_ADDRESS; // Holds the address to lookup
3546 bool m_cached = true;
3547 };
3548
3551 interpreter, "target modules show-unwind",
3552 "Show synthesized unwind instructions for a function.", nullptr,
3553 eCommandRequiresTarget | eCommandRequiresProcess |
3554 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {}
3555
3557
3558 Options *GetOptions() override { return &m_options; }
3559
3560protected:
3561 void DoExecute(Args &command, CommandReturnObject &result) override {
3562 Target *target = m_exe_ctx.GetTargetPtr();
3563 Process *process = m_exe_ctx.GetProcessPtr();
3564 ABI *abi = nullptr;
3565 if (process)
3566 abi = process->GetABI().get();
3567
3568 if (process == nullptr) {
3569 result.AppendError(
3570 "You must have a process running to use this command.");
3571 return;
3572 }
3573
3574 ThreadList threads(process->GetThreadList());
3575 if (threads.GetSize() == 0) {
3576 result.AppendError("the process must be paused to use this command");
3577 return;
3578 }
3579
3580 ThreadSP thread(threads.GetThreadAtIndex(0));
3581 if (!thread) {
3582 result.AppendError("the process must be paused to use this command");
3583 return;
3584 }
3585
3586 SymbolContextList sc_list;
3587
3588 if (m_options.m_type == eLookupTypeFunctionOrSymbol) {
3589 ConstString function_name(m_options.m_str.c_str());
3590 ModuleFunctionSearchOptions function_options;
3591 function_options.include_symbols = true;
3592 function_options.include_inlines = false;
3593 target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto,
3594 function_options, sc_list);
3595 } else if (m_options.m_type == eLookupTypeAddress && target) {
3596 Address addr;
3597 if (target->ResolveLoadAddress(m_options.m_addr, addr)) {
3598 SymbolContext sc;
3599 ModuleSP module_sp(addr.GetModule());
3600 module_sp->ResolveSymbolContextForAddress(addr,
3601 eSymbolContextEverything, sc);
3602 if (sc.function || sc.symbol) {
3603 sc_list.Append(sc);
3604 }
3605 }
3606 } else {
3607 result.AppendError(
3608 "address-expression or function name option must be specified.");
3609 return;
3610 }
3611
3612 if (sc_list.GetSize() == 0) {
3613 result.AppendErrorWithFormat("no unwind data found that matches '%s'.",
3614 m_options.m_str.c_str());
3615 return;
3616 }
3617
3618 for (const SymbolContext &sc : sc_list) {
3619 if (sc.symbol == nullptr && sc.function == nullptr)
3620 continue;
3621 if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr)
3622 continue;
3623 Address addr = sc.GetFunctionOrSymbolAddress();
3624 if (!addr.IsValid())
3625 continue;
3626 ConstString funcname(sc.GetFunctionName());
3627 if (funcname.IsEmpty())
3628 continue;
3629 addr_t start_addr = addr.GetLoadAddress(target);
3630 if (abi)
3631 start_addr = abi->FixCodeAddress(start_addr);
3632
3633 UnwindTable &uw_table = sc.module_sp->GetUnwindTable();
3634 FuncUnwindersSP func_unwinders_sp =
3635 m_options.m_cached
3636 ? uw_table.GetFuncUnwindersContainingAddress(start_addr, sc)
3637 : uw_table.GetUncachedFuncUnwindersContainingAddress(start_addr,
3638 sc);
3639 if (!func_unwinders_sp)
3640 continue;
3641
3642 result.GetOutputStream().Printf(
3643 "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n",
3644 sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(),
3645 funcname.AsCString(), start_addr);
3646
3647 Args args;
3649 size_t count = args.GetArgumentCount();
3650 for (size_t i = 0; i < count; i++) {
3651 const char *trap_func_name = args.GetArgumentAtIndex(i);
3652 if (strcmp(funcname.GetCString(), trap_func_name) == 0)
3653 result.GetOutputStream().Printf(
3654 "This function is "
3655 "treated as a trap handler function via user setting.\n");
3656 }
3657 PlatformSP platform_sp(target->GetPlatform());
3658 if (platform_sp) {
3659 const std::vector<ConstString> trap_handler_names(
3660 platform_sp->GetTrapHandlerSymbolNames());
3661 for (ConstString trap_name : trap_handler_names) {
3662 if (trap_name == funcname) {
3663 result.GetOutputStream().Printf(
3664 "This function's "
3665 "name is listed by the platform as a trap handler.\n");
3666 }
3667 }
3668 }
3669
3670 result.GetOutputStream().Printf("\n");
3671
3672 if (std::shared_ptr<const UnwindPlan> plan_sp =
3673 func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread)) {
3674 result.GetOutputStream().Printf(
3675 "Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n",
3676 plan_sp->GetSourceName().AsCString());
3677 }
3678 if (std::shared_ptr<const UnwindPlan> plan_sp =
3679 func_unwinders_sp->GetUnwindPlanAtCallSite(*target, *thread)) {
3680 result.GetOutputStream().Printf(
3681 "Synchronous (restricted to call-sites) UnwindPlan is '%s'\n",
3682 plan_sp->GetSourceName().AsCString());
3683 }
3684 if (std::shared_ptr<const UnwindPlan> plan_sp =
3685 func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread)) {
3686 result.GetOutputStream().Printf("Fast UnwindPlan is '%s'\n",
3687 plan_sp->GetSourceName().AsCString());
3688 }
3689
3690 result.GetOutputStream().Printf("\n");
3691
3692 if (std::shared_ptr<const UnwindPlan> plan_sp =
3693 func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread)) {
3694 result.GetOutputStream().Printf(
3695 "Assembly language inspection UnwindPlan:\n");
3696 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3698 result.GetOutputStream().Printf("\n");
3699 }
3700
3701 if (std::shared_ptr<const UnwindPlan> plan_sp =
3702 func_unwinders_sp->GetObjectFileUnwindPlan(*target)) {
3703 result.GetOutputStream().Printf("object file UnwindPlan:\n");
3704 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3706 result.GetOutputStream().Printf("\n");
3707 }
3708
3709 if (std::shared_ptr<const UnwindPlan> plan_sp =
3710 func_unwinders_sp->GetObjectFileAugmentedUnwindPlan(*target,
3711 *thread)) {
3712 result.GetOutputStream().Printf("object file augmented UnwindPlan:\n");
3713 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3715 result.GetOutputStream().Printf("\n");
3716 }
3717
3718 if (std::shared_ptr<const UnwindPlan> plan_sp =
3719 func_unwinders_sp->GetEHFrameUnwindPlan(*target)) {
3720 result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
3721 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3723 result.GetOutputStream().Printf("\n");
3724 }
3725
3726 if (std::shared_ptr<const UnwindPlan> plan_sp =
3727 func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target,
3728 *thread)) {
3729 result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
3730 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3732 result.GetOutputStream().Printf("\n");
3733 }
3734
3735 if (std::shared_ptr<const UnwindPlan> plan_sp =
3736 func_unwinders_sp->GetDebugFrameUnwindPlan(*target)) {
3737 result.GetOutputStream().Printf("debug_frame UnwindPlan:\n");
3738 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3740 result.GetOutputStream().Printf("\n");
3741 }
3742
3743 if (std::shared_ptr<const UnwindPlan> plan_sp =
3744 func_unwinders_sp->GetDebugFrameAugmentedUnwindPlan(*target,
3745 *thread)) {
3746 result.GetOutputStream().Printf("debug_frame augmented UnwindPlan:\n");
3747 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3749 result.GetOutputStream().Printf("\n");
3750 }
3751
3752 if (std::shared_ptr<const UnwindPlan> plan_sp =
3753 func_unwinders_sp->GetArmUnwindUnwindPlan(*target)) {
3754 result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
3755 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3757 result.GetOutputStream().Printf("\n");
3758 }
3759
3760 if (std::shared_ptr<const UnwindPlan> plan_sp =
3761 func_unwinders_sp->GetSymbolFileUnwindPlan(*thread)) {
3762 result.GetOutputStream().Printf("Symbol file UnwindPlan:\n");
3763 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3765 result.GetOutputStream().Printf("\n");
3766 }
3767
3768 if (std::shared_ptr<const UnwindPlan> plan_sp =
3769 func_unwinders_sp->GetCompactUnwindUnwindPlan(*target)) {
3770 result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
3771 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3773 result.GetOutputStream().Printf("\n");
3774 }
3775
3776 if (std::shared_ptr<const UnwindPlan> plan_sp =
3777 func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread)) {
3778 result.GetOutputStream().Printf("Fast UnwindPlan:\n");
3779 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3781 result.GetOutputStream().Printf("\n");
3782 }
3783
3784 ABISP abi_sp = process->GetABI();
3785 if (abi_sp) {
3786 if (UnwindPlanSP plan_sp = abi_sp->CreateDefaultUnwindPlan()) {
3787 result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
3788 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3790 result.GetOutputStream().Printf("\n");
3791 }
3792
3793 if (UnwindPlanSP plan_sp = abi_sp->CreateFunctionEntryUnwindPlan()) {
3794 result.GetOutputStream().Printf(
3795 "Arch default at entry point UnwindPlan:\n");
3796 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3798 result.GetOutputStream().Printf("\n");
3799 }
3800 }
3801
3802 result.GetOutputStream().Printf("\n");
3803 }
3804 }
3805
3807};
3808
3809// Lookup information in images
3810#define LLDB_OPTIONS_target_modules_lookup
3811#include "CommandOptions.inc"
3812
3814public:
3815 enum {
3819 eLookupTypeFileLine, // Line is optional
3824 };
3825
3826 class CommandOptions : public Options {
3827 public:
3829
3830 ~CommandOptions() override = default;
3831
3832 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3833 ExecutionContext *execution_context) override {
3834 Status error;
3835
3836 const int short_option = m_getopt_table[option_idx].val;
3837
3838 switch (short_option) {
3839 case 'a': {
3841 m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
3843 } break;
3844
3845 case 'o':
3846 if (option_arg.getAsInteger(0, m_offset))
3848 "invalid offset string '%s'", option_arg.str().c_str());
3849 break;
3850
3851 case 's':
3852 m_str = std::string(option_arg);
3854 break;
3855
3856 case 'f':
3857 m_file.SetFile(option_arg, FileSpec::Style::native);
3859 break;
3860
3861 case 'i':
3862 m_include_inlines = false;
3863 break;
3864
3865 case 'l':
3866 if (option_arg.getAsInteger(0, m_line_number))
3868 "invalid line number string '%s'", option_arg.str().c_str());
3869 else if (m_line_number == 0)
3870 error = Status::FromErrorString("zero is an invalid line number");
3872 break;
3873
3874 case 'F':
3875 m_str = std::string(option_arg);
3877 break;
3878
3879 case 'n':
3880 m_str = std::string(option_arg);
3882 break;
3883
3884 case 't':
3885 m_str = std::string(option_arg);
3887 break;
3888
3889 case 'v':
3890 m_verbose = true;
3891 break;
3892
3893 case 'A':
3894 m_print_all = true;
3895 break;
3896
3897 case 'r':
3898 m_use_regex = true;
3899 break;
3900
3901 case '\x01':
3902 m_all_ranges = true;
3903 break;
3904 default:
3905 llvm_unreachable("Unimplemented option");
3906 }
3907
3908 return error;
3909 }
3910
3911 void OptionParsingStarting(ExecutionContext *execution_context) override {
3913 m_str.clear();
3914 m_file.Clear();
3916 m_offset = 0;
3917 m_line_number = 0;
3918 m_use_regex = false;
3919 m_include_inlines = true;
3920 m_all_ranges = false;
3921 m_verbose = false;
3922 m_print_all = false;
3923 }
3924
3925 Status OptionParsingFinished(ExecutionContext *execution_context) override {
3926 Status status;
3927 if (m_all_ranges && !m_verbose) {
3928 status =
3929 Status::FromErrorString("--show-variable-ranges must be used in "
3930 "conjunction with --verbose.");
3931 }
3932 return status;
3933 }
3934
3935 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3936 return llvm::ArrayRef(g_target_modules_lookup_options);
3937 }
3938
3939 int m_type; // Should be a eLookupTypeXXX enum after parsing options
3940 std::string m_str; // Holds name lookup
3941 FileSpec m_file; // Files for file lookups
3942 lldb::addr_t m_addr; // Holds the address to lookup
3944 m_offset; // Subtract this offset from m_addr before doing lookups.
3945 uint32_t m_line_number; // Line number for file+line lookups
3946 bool m_use_regex; // Name lookups in m_str are regular expressions.
3947 bool m_include_inlines; // Check for inline entries when looking up by
3948 // file/line.
3949 bool m_all_ranges; // Print all ranges or single range.
3950 bool m_verbose; // Enable verbose lookup info
3951 bool m_print_all; // Print all matches, even in cases where there's a best
3952 // match.
3953 };
3954
3956 : CommandObjectParsed(interpreter, "target modules lookup",
3957 "Look up information within executable and "
3958 "dependent shared library images.",
3959 nullptr, eCommandRequiresTarget) {
3961 }
3962
3964
3965 Options *GetOptions() override { return &m_options; }
3966
3968 bool &syntax_error) {
3969 switch (m_options.m_type) {
3970 case eLookupTypeAddress:
3974 case eLookupTypeSymbol:
3975 default:
3976 return false;
3977 case eLookupTypeType:
3978 break;
3979 }
3980
3981 StackFrameSP frame = m_exe_ctx.GetFrameSP();
3982
3983 if (!frame)
3984 return false;
3985
3986 const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
3987
3988 if (!sym_ctx.module_sp)
3989 return false;
3990
3991 switch (m_options.m_type) {
3992 default:
3993 return false;
3994 case eLookupTypeType:
3995 if (!m_options.m_str.empty()) {
3997 result.GetOutputStream(), *sym_ctx.module_sp,
3998 m_options.m_str.c_str(), m_options.m_use_regex)) {
4000 return true;
4001 }
4002 }
4003 break;
4004 }
4005
4006 return false;
4007 }
4008
4009 bool LookupInModule(CommandInterpreter &interpreter, Module *module,
4010 CommandReturnObject &result, bool &syntax_error) {
4011 switch (m_options.m_type) {
4012 case eLookupTypeAddress:
4013 if (m_options.m_addr != LLDB_INVALID_ADDRESS) {
4015 m_interpreter, result.GetOutputStream(), module,
4016 eSymbolContextEverything |
4017 (m_options.m_verbose
4018 ? static_cast<int>(eSymbolContextVariable)
4019 : 0),
4020 m_options.m_addr, m_options.m_offset, m_options.m_verbose,
4021 m_options.m_all_ranges)) {
4023 return true;
4024 }
4025 }
4026 break;
4027
4028 case eLookupTypeSymbol:
4029 if (!m_options.m_str.empty()) {
4031 module, m_options.m_str.c_str(),
4032 m_options.m_use_regex, m_options.m_verbose,
4033 m_options.m_all_ranges)) {
4035 return true;
4036 }
4037 }
4038 break;
4039
4041 if (m_options.m_file) {
4043 m_interpreter, result.GetOutputStream(), module,
4044 m_options.m_file, m_options.m_line_number,
4045 m_options.m_include_inlines, m_options.m_verbose,
4046 m_options.m_all_ranges)) {
4048 return true;
4049 }
4050 }
4051 break;
4052
4055 if (!m_options.m_str.empty()) {
4056 ModuleFunctionSearchOptions function_options;
4057 function_options.include_symbols =
4059 function_options.include_inlines = m_options.m_include_inlines;
4060
4062 module, m_options.m_str.c_str(),
4063 m_options.m_use_regex, function_options,
4064 m_options.m_verbose,
4065 m_options.m_all_ranges)) {
4067 return true;
4068 }
4069 }
4070 break;
4071
4072 case eLookupTypeType:
4073 if (!m_options.m_str.empty()) {
4075 &GetTarget(), m_interpreter, result.GetOutputStream(), module,
4076 m_options.m_str.c_str(), m_options.m_use_regex)) {
4078 return true;
4079 }
4080 }
4081 break;
4082
4083 default:
4084 m_options.GenerateOptionUsage(
4085 result.GetErrorStream(), *this,
4086 GetCommandInterpreter().GetDebugger().GetTerminalWidth(),
4087 GetCommandInterpreter().GetDebugger().GetUseColor());
4088 syntax_error = true;
4089 break;
4090 }
4091
4093 return false;
4094 }
4095
4096protected:
4097 void DoExecute(Args &command, CommandReturnObject &result) override {
4098 Target &target = GetTarget();
4099 bool syntax_error = false;
4100 uint32_t i;
4101 uint32_t num_successful_lookups = 0;
4102 uint32_t addr_byte_size = target.GetArchitecture().GetAddressByteSize();
4103 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
4104 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
4105 // Dump all sections for all modules images
4106
4107 if (command.GetArgumentCount() == 0) {
4108 // Where it is possible to look in the current symbol context first,
4109 // try that. If this search was successful and --all was not passed,
4110 // don't print anything else.
4111 if (LookupHere(m_interpreter, result, syntax_error)) {
4112 result.GetOutputStream().EOL();
4113 num_successful_lookups++;
4114 if (!m_options.m_print_all) {
4116 return;
4117 }
4118 }
4119
4120 // Dump all sections for all other modules
4121
4122 const ModuleList &target_modules = target.GetImages();
4123 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
4124 if (target_modules.GetSize() == 0) {
4125 result.AppendError("the target has no associated executable images");
4126 return;
4127 }
4128
4129 for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
4130 if (LookupInModule(m_interpreter, module_sp.get(), result,
4131 syntax_error)) {
4132 result.GetOutputStream().EOL();
4133 num_successful_lookups++;
4134 }
4135 }
4136 } else {
4137 // Dump specified images (by basename or fullpath)
4138 const char *arg_cstr;
4139 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr &&
4140 !syntax_error;
4141 ++i) {
4142 ModuleList module_list;
4143 const size_t num_matches =
4144 FindModulesByName(&target, arg_cstr, module_list, false);
4145 if (num_matches > 0) {
4146 for (size_t j = 0; j < num_matches; ++j) {
4147 Module *module = module_list.GetModulePointerAtIndex(j);
4148 if (module) {
4149 if (LookupInModule(m_interpreter, module, result, syntax_error)) {
4150 result.GetOutputStream().EOL();
4151 num_successful_lookups++;
4152 }
4153 }
4154 }
4155 } else
4157 "Unable to find an image that matches '%s'.\n", arg_cstr);
4158 }
4159 }
4160
4161 if (num_successful_lookups > 0)
4163 else
4165 }
4166
4168};
4169
4170#pragma mark CommandObjectMultiwordImageSearchPaths
4171
4172// CommandObjectMultiwordImageSearchPaths
4173
4175 : public CommandObjectMultiword {
4176public:
4179 interpreter, "target modules search-paths",
4180 "Commands for managing module search paths for a target.",
4181 "target modules search-paths <subcommand> [<subcommand-options>]") {
4183 "add", CommandObjectSP(
4187 interpreter)));
4189 "insert",
4194 interpreter)));
4197 interpreter)));
4198 }
4199
4201};
4202
4203#pragma mark CommandObjectTargetModules
4204
4205// CommandObjectTargetModules
4206
4208public:
4209 // Constructors and Destructors
4211 : CommandObjectMultiword(interpreter, "target modules",
4212 "Commands for accessing information for one or "
4213 "more target modules.",
4214 "target modules <sub-command> ...") {
4216 "add", CommandObjectSP(new CommandObjectTargetModulesAdd(interpreter)));
4218 interpreter)));
4220 interpreter)));
4222 interpreter)));
4224 "lookup",
4227 "search-paths",
4231 "show-unwind",
4233 }
4234
4235 ~CommandObjectTargetModules() override = default;
4236
4237private:
4238 // For CommandObjectTargetModules only
4242};
4243
4245public:
4248 interpreter, "target symbols add",
4249 "Add a debug symbol file to one of the target's current modules by "
4250 "specifying a path to a debug symbols file or by using the options "
4251 "to specify a module.",
4252 "target symbols add <cmd-options> [<symfile>]",
4253 eCommandRequiresTarget),
4255 LLDB_OPT_SET_1, false, "shlib", 's', lldb::eModuleCompletion,
4257 "Locate the debug symbols for the shared library specified by "
4258 "name."),
4260 LLDB_OPT_SET_2, false, "frame", 'F',
4261 "Locate the debug symbols for the currently selected frame.", false,
4262 true),
4263 m_current_stack_option(LLDB_OPT_SET_2, false, "stack", 'S',
4264 "Locate the debug symbols for every frame in "
4265 "the current call stack.",
4266 false, true)
4267
4268 {
4276 m_option_group.Finalize();
4278 }
4279
4281
4282 Options *GetOptions() override { return &m_option_group; }
4283
4284protected:
4285 bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush,
4286 CommandReturnObject &result) {
4287 const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
4288 if (!symbol_fspec) {
4289 result.AppendError(
4290 "one or more executable image paths must be specified");
4291 return false;
4292 }
4293
4294 char symfile_path[PATH_MAX];
4295 symbol_fspec.GetPath(symfile_path, sizeof(symfile_path));
4296
4297 if (!module_spec.GetUUID().IsValid()) {
4298 if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
4299 module_spec.GetFileSpec().SetFilename(symbol_fspec.GetFilename());
4300 }
4301
4302 // Now module_spec represents a symbol file for a module that might exist
4303 // in the current target. Let's find possible matches.
4304 ModuleList matching_modules;
4305
4306 // First extract all module specs from the symbol file
4307 lldb_private::ModuleSpecList symfile_module_specs;
4309 0, 0, symfile_module_specs)) {
4310 // Now extract the module spec that matches the target architecture
4311 ModuleSpec target_arch_module_spec;
4312 ModuleSpec symfile_module_spec;
4313 target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
4314 if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec,
4315 symfile_module_spec)) {
4316 if (symfile_module_spec.GetUUID().IsValid()) {
4317 // It has a UUID, look for this UUID in the target modules
4318 ModuleSpec symfile_uuid_module_spec;
4319 symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
4320 target->GetImages().FindModules(symfile_uuid_module_spec,
4321 matching_modules);
4322 }
4323 }
4324
4325 if (matching_modules.IsEmpty()) {
4326 // No matches yet. Iterate through the module specs to find a UUID
4327 // value that we can match up to an image in our target.
4328 const size_t num_symfile_module_specs = symfile_module_specs.GetSize();
4329 for (size_t i = 0;
4330 i < num_symfile_module_specs && matching_modules.IsEmpty(); ++i) {
4331 if (symfile_module_specs.GetModuleSpecAtIndex(
4332 i, symfile_module_spec)) {
4333 if (symfile_module_spec.GetUUID().IsValid()) {
4334 // It has a UUID. Look for this UUID in the target modules.
4335 ModuleSpec symfile_uuid_module_spec;
4336 symfile_uuid_module_spec.GetUUID() =
4337 symfile_module_spec.GetUUID();
4338 target->GetImages().FindModules(symfile_uuid_module_spec,
4339 matching_modules);
4340 }
4341 }
4342 }
4343 }
4344 }
4345
4346 // Just try to match up the file by basename if we have no matches at
4347 // this point. For example, module foo might have symbols in foo.debug.
4348 if (matching_modules.IsEmpty())
4349 target->GetImages().FindModules(module_spec, matching_modules);
4350
4351 while (matching_modules.IsEmpty()) {
4352 ConstString filename_no_extension(
4354 // Empty string returned, let's bail
4355 if (!filename_no_extension)
4356 break;
4357
4358 // Check if there was no extension to strip and the basename is the same
4359 if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
4360 break;
4361
4362 // Replace basename with one fewer extension
4363 module_spec.GetFileSpec().SetFilename(filename_no_extension);
4364 target->GetImages().FindModules(module_spec, matching_modules);
4365 }
4366
4367 if (matching_modules.GetSize() > 1) {
4368 result.AppendErrorWithFormat("multiple modules match symbol file '%s', "
4369 "use the --uuid option to resolve the "
4370 "ambiguity.\n",
4371 symfile_path);
4372 return false;
4373 }
4374
4375 if (matching_modules.GetSize() == 1) {
4376 ModuleSP module_sp(matching_modules.GetModuleAtIndex(0));
4377
4378 // The module has not yet created its symbol vendor, we can just give
4379 // the existing target module the symfile path to use for when it
4380 // decides to create it!
4381 module_sp->SetSymbolFileFileSpec(symbol_fspec);
4382
4383 SymbolFile *symbol_file =
4384 module_sp->GetSymbolFile(true, &result.GetErrorStream());
4385 if (symbol_file) {
4386 ObjectFile *object_file = symbol_file->GetObjectFile();
4387 if (object_file && object_file->GetFileSpec() == symbol_fspec) {
4388 // Provide feedback that the symfile has been successfully added.
4389 const FileSpec &module_fs = module_sp->GetFileSpec();
4391 "symbol file '%s' has been added to '%s'\n", symfile_path,
4392 module_fs.GetPath().c_str());
4393
4394 // Let clients know something changed in the module if it is
4395 // currently loaded
4396 ModuleList module_list;
4397 module_list.Append(module_sp);
4398 target->SymbolsDidLoad(module_list);
4399
4400 // Make sure we load any scripting resources that may be embedded
4401 // in the debug info files in case the platform supports that.
4402 Status error;
4403 StreamString feedback_stream;
4404 module_sp->LoadScriptingResourceInTarget(target, error,
4405 feedback_stream);
4406 if (error.Fail() && error.AsCString())
4408 "unable to load scripting data for module %s - error "
4409 "reported was %s",
4410 module_sp->GetFileSpec()
4411 .GetFileNameStrippingExtension()
4412 .GetCString(),
4413 error.AsCString());
4414 else if (feedback_stream.GetSize())
4415 result.AppendWarning(feedback_stream.GetData());
4416
4417 flush = true;
4419 return true;
4420 }
4421 }
4422 // Clear the symbol file spec if anything went wrong
4423 module_sp->SetSymbolFileFileSpec(FileSpec());
4424 }
4425
4426 StreamString ss_symfile_uuid;
4427 if (module_spec.GetUUID().IsValid()) {
4428 ss_symfile_uuid << " (";
4429 module_spec.GetUUID().Dump(ss_symfile_uuid);
4430 ss_symfile_uuid << ')';
4431 }
4432 result.AppendErrorWithFormat(
4433 "symbol file '%s'%s does not match any existing module%s\n",
4434 symfile_path, ss_symfile_uuid.GetData(),
4435 !llvm::sys::fs::is_regular_file(symbol_fspec.GetPath())
4436 ? "\n please specify the full path to the symbol file"
4437 : "");
4438 return false;
4439 }
4440
4442 CommandReturnObject &result, bool &flush) {
4443 Status error;
4445 if (module_spec.GetSymbolFileSpec())
4446 return AddModuleSymbols(m_exe_ctx.GetTargetPtr(), module_spec, flush,
4447 result);
4448 } else {
4449 result.SetError(std::move(error));
4450 }
4451 return false;
4452 }
4453
4454 bool AddSymbolsForUUID(CommandReturnObject &result, bool &flush) {
4455 assert(m_uuid_option_group.GetOptionValue().OptionWasSet());
4456
4457 ModuleSpec module_spec;
4458 module_spec.GetUUID() =
4459 m_uuid_option_group.GetOptionValue().GetCurrentValue();
4460
4461 if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) {
4462 StreamString error_strm;
4463 error_strm.PutCString("unable to find debug symbols for UUID ");
4464 module_spec.GetUUID().Dump(error_strm);
4465 result.AppendError(error_strm.GetString());
4466 return false;
4467 }
4468
4469 return true;
4470 }
4471
4472 bool AddSymbolsForFile(CommandReturnObject &result, bool &flush) {
4473 assert(m_file_option.GetOptionValue().OptionWasSet());
4474
4475 ModuleSpec module_spec;
4476 module_spec.GetFileSpec() =
4477 m_file_option.GetOptionValue().GetCurrentValue();
4478
4479 Target *target = m_exe_ctx.GetTargetPtr();
4480 ModuleSP module_sp(target->GetImages().FindFirstModule(module_spec));
4481 if (module_sp) {
4482 module_spec.GetFileSpec() = module_sp->GetFileSpec();
4483 module_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec();
4484 module_spec.GetUUID() = module_sp->GetUUID();
4485 module_spec.GetArchitecture() = module_sp->GetArchitecture();
4486 } else {
4487 module_spec.GetArchitecture() = target->GetArchitecture();
4488 }
4489
4490 if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) {
4491 StreamString error_strm;
4492 error_strm.PutCString(
4493 "unable to find debug symbols for the executable file ");
4494 error_strm << module_spec.GetFileSpec();
4495 result.AppendError(error_strm.GetString());
4496 return false;
4497 }
4498
4499 return true;
4500 }
4501
4502 bool AddSymbolsForFrame(CommandReturnObject &result, bool &flush) {
4503 assert(m_current_frame_option.GetOptionValue().OptionWasSet());
4504
4505 Process *process = m_exe_ctx.GetProcessPtr();
4506 if (!process) {
4507 result.AppendError(
4508 "a process must exist in order to use the --frame option");
4509 return false;
4510 }
4511
4512 const StateType process_state = process->GetState();
4513 if (!StateIsStoppedState(process_state, true)) {
4514 result.AppendErrorWithFormat("process is not stopped: %s",
4515 StateAsCString(process_state));
4516 return false;
4517 }
4518
4519 StackFrame *frame = m_exe_ctx.GetFramePtr();
4520 if (!frame) {
4521 result.AppendError("invalid current frame");
4522 return false;
4523 }
4524
4525 ModuleSP frame_module_sp(
4526 frame->GetSymbolContext(eSymbolContextModule).module_sp);
4527 if (!frame_module_sp) {
4528 result.AppendError("frame has no module");
4529 return false;
4530 }
4531
4532 ModuleSpec module_spec;
4533 module_spec.GetUUID() = frame_module_sp->GetUUID();
4534 module_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
4535 module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
4536
4537 if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) {
4538 result.AppendError("unable to find debug symbols for the current frame");
4539 return false;
4540 }
4541
4542 return true;
4543 }
4544
4545 bool AddSymbolsForStack(CommandReturnObject &result, bool &flush) {
4546 assert(m_current_stack_option.GetOptionValue().OptionWasSet());
4547
4548 Process *process = m_exe_ctx.GetProcessPtr();
4549 if (!process) {
4550 result.AppendError(
4551 "a process must exist in order to use the --stack option");
4552 return false;
4553 }
4554
4555 const StateType process_state = process->GetState();
4556 if (!StateIsStoppedState(process_state, true)) {
4557 result.AppendErrorWithFormat("process is not stopped: %s",
4558 StateAsCString(process_state));
4559 return false;
4560 }
4561
4562 Thread *thread = m_exe_ctx.GetThreadPtr();
4563 if (!thread) {
4564 result.AppendError("invalid current thread");
4565 return false;
4566 }
4567
4568 bool symbols_found = false;
4569 uint32_t frame_count = thread->GetStackFrameCount();
4570 for (uint32_t i = 0; i < frame_count; ++i) {
4571 lldb::StackFrameSP frame_sp = thread->GetStackFrameAtIndex(i);
4572
4573 ModuleSP frame_module_sp(
4574 frame_sp->GetSymbolContext(eSymbolContextModule).module_sp);
4575 if (!frame_module_sp)
4576 continue;
4577
4578 ModuleSpec module_spec;
4579 module_spec.GetUUID() = frame_module_sp->GetUUID();
4580 module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
4581 module_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
4582
4583 bool current_frame_flush = false;
4584 if (DownloadObjectAndSymbolFile(module_spec, result, current_frame_flush))
4585 symbols_found = true;
4586 flush |= current_frame_flush;
4587 }
4588
4589 if (!symbols_found) {
4590 result.AppendError(
4591 "unable to find debug symbols in the current call stack");
4592 return false;
4593 }
4594
4595 return true;
4596 }
4597
4598 void DoExecute(Args &args, CommandReturnObject &result) override {
4599 Target *target = m_exe_ctx.GetTargetPtr();
4601 bool flush = false;
4602 ModuleSpec module_spec;
4603 const bool uuid_option_set =
4604 m_uuid_option_group.GetOptionValue().OptionWasSet();
4605 const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
4606 const bool frame_option_set =
4607 m_current_frame_option.GetOptionValue().OptionWasSet();
4608 const bool stack_option_set =
4609 m_current_stack_option.GetOptionValue().OptionWasSet();
4610 const size_t argc = args.GetArgumentCount();
4611
4612 if (argc == 0) {
4613 if (uuid_option_set)
4614 AddSymbolsForUUID(result, flush);
4615 else if (file_option_set)
4616 AddSymbolsForFile(result, flush);
4617 else if (frame_option_set)
4618 AddSymbolsForFrame(result, flush);
4619 else if (stack_option_set)
4620 AddSymbolsForStack(result, flush);
4621 else
4622 result.AppendError("one or more symbol file paths must be specified, "
4623 "or options must be specified");
4624 } else {
4625 if (uuid_option_set) {
4626 result.AppendError("specify either one or more paths to symbol files "
4627 "or use the --uuid option without arguments");
4628 } else if (frame_option_set) {
4629 result.AppendError("specify either one or more paths to symbol files "
4630 "or use the --frame option without arguments");
4631 } else if (file_option_set && argc > 1) {
4632 result.AppendError("specify at most one symbol file path when "
4633 "--shlib option is set");
4634 } else {
4635 PlatformSP platform_sp(target->GetPlatform());
4636
4637 for (auto &entry : args.entries()) {
4638 if (!entry.ref().empty()) {
4639 auto &symbol_file_spec = module_spec.GetSymbolFileSpec();
4640 symbol_file_spec.SetFile(entry.ref(), FileSpec::Style::native);
4641 FileSystem::Instance().Resolve(symbol_file_spec);
4642 if (file_option_set) {
4643 module_spec.GetFileSpec() =
4644 m_file_option.GetOptionValue().GetCurrentValue();
4645 }
4646 if (platform_sp) {
4647 FileSpec symfile_spec;
4648 if (platform_sp
4649 ->ResolveSymbolFile(*target, module_spec, symfile_spec)
4650 .Success())
4651 module_spec.GetSymbolFileSpec() = symfile_spec;
4652 }
4653
4654 bool symfile_exists =
4656
4657 if (symfile_exists) {
4658 if (!AddModuleSymbols(target, module_spec, flush, result))
4659 break;
4660 } else {
4661 std::string resolved_symfile_path =
4662 module_spec.GetSymbolFileSpec().GetPath();
4663 if (resolved_symfile_path != entry.ref()) {
4664 result.AppendErrorWithFormat(
4665 "invalid module path '%s' with resolved path '%s'\n",
4666 entry.c_str(), resolved_symfile_path.c_str());
4667 break;
4668 }
4669 result.AppendErrorWithFormat("invalid module path '%s'\n",
4670 entry.c_str());
4671 break;
4672 }
4673 }
4674 }
4675 }
4676 }
4677
4678 if (flush) {
4679 Process *process = m_exe_ctx.GetProcessPtr();
4680 if (process)
4681 process->Flush();
4682 }
4683 }
4684
4690};
4691
4692#pragma mark CommandObjectTargetSymbols
4693
4694// CommandObjectTargetSymbols
4695
4697public:
4698 // Constructors and Destructors
4701 interpreter, "target symbols",
4702 "Commands for adding and managing debug symbol files.",
4703 "target symbols <sub-command> ...") {
4705 "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter)));
4706 }
4707
4708 ~CommandObjectTargetSymbols() override = default;
4709
4710private:
4711 // For CommandObjectTargetModules only
4715};
4716
4717#pragma mark CommandObjectTargetStopHookAdd
4718
4719// CommandObjectTargetStopHookAdd
4720#define LLDB_OPTIONS_target_stop_hook_add
4721#include "CommandOptions.inc"
4722
4725public:
4727 public:
4729
4730 ~CommandOptions() override = default;
4731
4732 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
4733 return llvm::ArrayRef(g_target_stop_hook_add_options);
4734 }
4735
4736 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
4737 ExecutionContext *execution_context) override {
4738 Status error;
4739 const int short_option =
4740 g_target_stop_hook_add_options[option_idx].short_option;
4741
4742 switch (short_option) {
4743 case 'c':
4744 m_class_name = std::string(option_arg);
4745 m_sym_ctx_specified = true;
4746 break;
4747
4748 case 'e':
4749 if (option_arg.getAsInteger(0, m_line_end)) {
4751 "invalid end line number: \"%s\"", option_arg.str().c_str());
4752 break;
4753 }
4754 m_sym_ctx_specified = true;
4755 break;
4756
4757 case 'G': {
4758 bool value, success;
4759 value = OptionArgParser::ToBoolean(option_arg, false, &success);
4760 if (success) {
4761 m_auto_continue = value;
4762 } else
4764 "invalid boolean value '%s' passed for -G option",
4765 option_arg.str().c_str());
4766 } break;
4767 case 'l':
4768 if (option_arg.getAsInteger(0, m_line_start)) {
4770 "invalid start line number: \"%s\"", option_arg.str().c_str());
4771 break;
4772 }
4773 m_sym_ctx_specified = true;
4774 break;
4775
4776 case 'i':
4777 m_no_inlines = true;
4778 break;
4779
4780 case 'n':
4781 m_function_name = std::string(option_arg);
4782 m_func_name_type_mask |= eFunctionNameTypeAuto;
4783 m_sym_ctx_specified = true;
4784 break;
4785
4786 case 'f':
4787 m_file_name = std::string(option_arg);
4788 m_sym_ctx_specified = true;
4789 break;
4790
4791 case 's':
4792 m_module_name = std::string(option_arg);
4793 m_sym_ctx_specified = true;
4794 break;
4795
4796 case 't':
4797 if (option_arg.getAsInteger(0, m_thread_id))
4799 "invalid thread id string '%s'", option_arg.str().c_str());
4800 m_thread_specified = true;
4801 break;
4802
4803 case 'T':
4804 m_thread_name = std::string(option_arg);
4805 m_thread_specified = true;
4806 break;
4807
4808 case 'q':
4809 m_queue_name = std::string(option_arg);
4810 m_thread_specified = true;
4811 break;
4812
4813 case 'x':
4814 if (option_arg.getAsInteger(0, m_thread_index))
4816 "invalid thread index string '%s'", option_arg.str().c_str());
4817 m_thread_specified = true;
4818 break;
4819
4820 case 'o':
4821 m_use_one_liner = true;
4822 m_one_liner.push_back(std::string(option_arg));
4823 break;
4824
4825 case 'I': {
4826 bool value, success;
4827 value = OptionArgParser::ToBoolean(option_arg, false, &success);
4828 if (success)
4829 m_at_initial_stop = value;
4830 else
4832 "invalid boolean value '%s' passed for -F option",
4833 option_arg.str().c_str());
4834 } break;
4835
4836 default:
4837 llvm_unreachable("Unimplemented option");
4838 }
4839 return error;
4840 }
4841
4842 void OptionParsingStarting(ExecutionContext *execution_context) override {
4843 m_class_name.clear();
4844 m_function_name.clear();
4845 m_line_start = 0;
4847 m_file_name.clear();
4848 m_module_name.clear();
4849 m_func_name_type_mask = eFunctionNameTypeAuto;
4852 m_thread_name.clear();
4853 m_queue_name.clear();
4854
4855 m_no_inlines = false;
4856 m_sym_ctx_specified = false;
4857 m_thread_specified = false;
4858
4859 m_use_one_liner = false;
4860 m_one_liner.clear();
4861 m_auto_continue = false;
4862 m_at_initial_stop = true;
4863 }
4864
4865 std::string m_class_name;
4866 std::string m_function_name;
4867 uint32_t m_line_start = 0;
4869 std::string m_file_name;
4870 std::string m_module_name;
4872 eFunctionNameTypeAuto; // A pick from lldb::FunctionNameType.
4875 std::string m_thread_name;
4876 std::string m_queue_name;
4878 bool m_no_inlines = false;
4880 // Instance variables to hold the values for one_liner options.
4881 bool m_use_one_liner = false;
4882 std::vector<std::string> m_one_liner;
4884
4885 bool m_auto_continue = false;
4886 };
4887
4889 : CommandObjectParsed(interpreter, "target stop-hook add",
4890 "Add a hook to be executed when the target stops."
4891 "The hook can either be a list of commands or an "
4892 "appropriately defined Python class. You can also "
4893 "add filters so the hook only runs a certain stop "
4894 "points.",
4895 "target stop-hook add"),
4898 m_python_class_options("scripted stop-hook", true, 'P') {
4900 R"(
4901Command Based stop-hooks:
4902-------------------------
4903 Stop hooks can run a list of lldb commands by providing one or more
4904 --one-liner options. The commands will get run in the order they are added.
4905 Or you can provide no commands, in which case you will enter a command editor
4906 where you can enter the commands to be run.
4907
4908Python Based Stop Hooks:
4909------------------------
4910 Stop hooks can be implemented with a suitably defined Python class, whose name
4911 is passed in the --python-class option.
4912
4913 When the stop hook is added, the class is initialized by calling:
4914
4915 def __init__(self, target, extra_args, internal_dict):
4916
4917 target: The target that the stop hook is being added to.
4918 extra_args: An SBStructuredData Dictionary filled with the -key -value
4919 option pairs passed to the command.
4920 dict: An implementation detail provided by lldb.
4921
4922 Then when the stop-hook triggers, lldb will run the 'handle_stop' method.
4923 The method has the signature:
4925 def handle_stop(self, exe_ctx, stream):
4926
4927 exe_ctx: An SBExecutionContext for the thread that has stopped.
4928 stream: An SBStream, anything written to this stream will be printed in the
4929 the stop message when the process stops.
4930
4931 Return Value: The method returns "should_stop". If should_stop is false
4932 from all the stop hook executions on threads that stopped
4933 with a reason, then the process will continue. Note that this
4934 will happen only after all the stop hooks are run.
4935
4936Filter Options:
4937---------------
4938 Stop hooks can be set to always run, or to only run when the stopped thread
4939 matches the filter options passed on the command line. The available filter
4940 options include a shared library or a thread or queue specification,
4941 a line range in a source file, a function name or a class name.
4942 )");
4945 LLDB_OPT_SET_FROM_TO(4, 6));
4946 m_all_options.Append(&m_options);
4947 m_all_options.Finalize();
4948 }
4949
4950 ~CommandObjectTargetStopHookAdd() override = default;
4951
4952 Options *GetOptions() override { return &m_all_options; }
4953
4954protected:
4955 void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
4956 if (interactive) {
4957 if (lldb::LockableStreamFileSP output_sp =
4958 io_handler.GetOutputStreamFileSP()) {
4959 LockedStreamFile locked_stream = output_sp->Lock();
4960 locked_stream.PutCString(
4961 "Enter your stop hook command(s). Type 'DONE' to end.\n");
4962 }
4963 }
4964 }
4965
4966 void IOHandlerInputComplete(IOHandler &io_handler,
4967 std::string &line) override {
4968 if (m_stop_hook_sp) {
4969 if (line.empty()) {
4970 if (lldb::LockableStreamFileSP error_sp =
4971 io_handler.GetErrorStreamFileSP()) {
4972 LockedStreamFile locked_stream = error_sp->Lock();
4973 locked_stream.Printf("error: stop hook #%" PRIu64
4974 " aborted, no commands.\n",
4975 m_stop_hook_sp->GetID());
4976 }
4978 } else {
4979 // The IOHandler editor is only for command lines stop hooks:
4980 Target::StopHookCommandLine *hook_ptr =
4981 static_cast<Target::StopHookCommandLine *>(m_stop_hook_sp.get());
4982
4983 hook_ptr->SetActionFromString(line);
4984 if (lldb::LockableStreamFileSP output_sp =
4985 io_handler.GetOutputStreamFileSP()) {
4986 LockedStreamFile locked_stream = output_sp->Lock();
4987 locked_stream.Printf("Stop hook #%" PRIu64 " added.\n",
4988 m_stop_hook_sp->GetID());
4989 }
4990 }
4991 m_stop_hook_sp.reset();
4992 }
4993 io_handler.SetIsDone(true);
4994 }
4995
4996 void DoExecute(Args &command, CommandReturnObject &result) override {
4997 m_stop_hook_sp.reset();
4998
4999 Target &target = GetTarget();
5000 Target::StopHookSP new_hook_sp =
5001 target.CreateStopHook(m_python_class_options.GetName().empty() ?
5002 Target::StopHook::StopHookKind::CommandBased
5003 : Target::StopHook::StopHookKind::ScriptBased);
5004
5005 // First step, make the specifier.
5006 std::unique_ptr<SymbolContextSpecifier> specifier_up;
5007 if (m_options.m_sym_ctx_specified) {
5008 specifier_up = std::make_unique<SymbolContextSpecifier>(
5009 GetDebugger().GetSelectedTarget());
5010
5011 if (!m_options.m_module_name.empty()) {
5012 specifier_up->AddSpecification(
5013 m_options.m_module_name.c_str(),
5015 }
5016
5017 if (!m_options.m_class_name.empty()) {
5018 specifier_up->AddSpecification(
5019 m_options.m_class_name.c_str(),
5021 }
5022
5023 if (!m_options.m_file_name.empty()) {
5024 specifier_up->AddSpecification(m_options.m_file_name.c_str(),
5026 }
5027
5028 if (m_options.m_line_start != 0) {
5029 specifier_up->AddLineSpecification(
5030 m_options.m_line_start,
5032 }
5033
5034 if (m_options.m_line_end != UINT_MAX) {
5035 specifier_up->AddLineSpecification(
5037 }
5038
5039 if (!m_options.m_function_name.empty()) {
5040 specifier_up->AddSpecification(
5041 m_options.m_function_name.c_str(),
5043 }
5044 }
5045
5046 if (specifier_up)
5047 new_hook_sp->SetSpecifier(specifier_up.release());
5048
5049 // Should we run at the initial stop:
5050 new_hook_sp->SetRunAtInitialStop(m_options.m_at_initial_stop);
5051
5052 // Next see if any of the thread options have been entered:
5053
5054 if (m_options.m_thread_specified) {
5055 ThreadSpec *thread_spec = new ThreadSpec();
5056
5057 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) {
5058 thread_spec->SetTID(m_options.m_thread_id);
5059 }
5060
5061 if (m_options.m_thread_index != UINT32_MAX)
5062 thread_spec->SetIndex(m_options.m_thread_index);
5063
5064 if (!m_options.m_thread_name.empty())
5065 thread_spec->SetName(m_options.m_thread_name.c_str());
5067 if (!m_options.m_queue_name.empty())
5068 thread_spec->SetQueueName(m_options.m_queue_name.c_str());
5070 new_hook_sp->SetThreadSpecifier(thread_spec);
5071 }
5072
5073 new_hook_sp->SetAutoContinue(m_options.m_auto_continue);
5075 // This is a command line stop hook:
5076 Target::StopHookCommandLine *hook_ptr =
5077 static_cast<Target::StopHookCommandLine *>(new_hook_sp.get());
5079 result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
5080 new_hook_sp->GetID());
5081 } else if (!m_python_class_options.GetName().empty()) {
5082 // This is a scripted stop hook:
5083 Target::StopHookScripted *hook_ptr =
5084 static_cast<Target::StopHookScripted *>(new_hook_sp.get());
5085 Status error = hook_ptr->SetScriptCallback(
5086 m_python_class_options.GetName(),
5087 m_python_class_options.GetStructuredData());
5088 if (error.Success())
5089 result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
5090 new_hook_sp->GetID());
5091 else {
5092 // FIXME: Set the stop hook ID counter back.
5093 result.AppendErrorWithFormat("Couldn't add stop hook: %s",
5094 error.AsCString());
5095 target.UndoCreateStopHook(new_hook_sp->GetID());
5096 return;
5097 }
5098 } else {
5099 m_stop_hook_sp = new_hook_sp;
5100 m_interpreter.GetLLDBCommandsFromIOHandler("> ", // Prompt
5101 *this); // IOHandlerDelegate
5102 }
5104 }
5105
5106private:
5108 OptionGroupPythonClassWithDict m_python_class_options;
5109 OptionGroupOptions m_all_options;
5110
5112};
5113
5114#pragma mark CommandObjectTargetStopHookDelete
5115
5116// CommandObjectTargetStopHookDelete
5117
5119public:
5121 : CommandObjectParsed(interpreter, "target stop-hook delete",
5122 "Delete a stop-hook.",
5123 "target stop-hook delete [<idx>]") {
5125 }
5126
5128
5129 void
5131 OptionElementVector &opt_element_vector) override {
5132 if (request.GetCursorIndex())
5133 return;
5134 CommandObject::HandleArgumentCompletion(request, opt_element_vector);
5135 }
5136
5137protected:
5138 void DoExecute(Args &command, CommandReturnObject &result) override {
5139 Target &target = GetTarget();
5140 // FIXME: see if we can use the breakpoint id style parser?
5141 size_t num_args = command.GetArgumentCount();
5142 if (num_args == 0) {
5143 if (!m_interpreter.Confirm("Delete all stop hooks?", true)) {
5145 return;
5146 } else {
5147 target.RemoveAllStopHooks();
5148 }
5149 } else {
5150 for (size_t i = 0; i < num_args; i++) {
5151 lldb::user_id_t user_id;
5152 if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
5153 result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
5154 command.GetArgumentAtIndex(i));
5155 return;
5156 }
5157 if (!target.RemoveStopHookByID(user_id)) {
5158 result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
5159 command.GetArgumentAtIndex(i));
5160 return;
5161 }
5162 }
5163 }
5165 }
5166};
5167
5168#pragma mark CommandObjectTargetStopHookEnableDisable
5169
5170// CommandObjectTargetStopHookEnableDisable
5171
5173public:
5175 bool enable, const char *name,
5176 const char *help, const char *syntax)
5177 : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable) {
5179 }
5180
5182
5183 void
5185 OptionElementVector &opt_element_vector) override {
5186 if (request.GetCursorIndex())
5187 return;
5188 CommandObject::HandleArgumentCompletion(request, opt_element_vector);
5189 }
5190
5191protected:
5192 void DoExecute(Args &command, CommandReturnObject &result) override {
5193 Target &target = GetTarget();
5194 // FIXME: see if we can use the breakpoint id style parser?
5195 size_t num_args = command.GetArgumentCount();
5196 bool success;
5197
5198 if (num_args == 0) {
5200 } else {
5201 for (size_t i = 0; i < num_args; i++) {
5202 lldb::user_id_t user_id;
5203 if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
5204 result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
5205 command.GetArgumentAtIndex(i));
5206 return;
5207 }
5208 success = target.SetStopHookActiveStateByID(user_id, m_enable);
5209 if (!success) {
5210 result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
5211 command.GetArgumentAtIndex(i));
5212 return;
5213 }
5214 }
5215 }
5217 }
5218
5219private:
5221};
5222
5223#pragma mark CommandObjectTargetStopHookList
5224
5225// CommandObjectTargetStopHookList
5226
5228public:
5230 : CommandObjectParsed(interpreter, "target stop-hook list",
5231 "List all stop-hooks.", "target stop-hook list") {}
5232
5234
5235protected:
5236 void DoExecute(Args &command, CommandReturnObject &result) override {
5237 Target &target = GetTarget();
5238
5239 size_t num_hooks = target.GetNumStopHooks();
5240 if (num_hooks == 0) {
5241 result.GetOutputStream().PutCString("No stop hooks.\n");
5242 } else {
5243 for (size_t i = 0; i < num_hooks; i++) {
5244 Target::StopHookSP this_hook = target.GetStopHookAtIndex(i);
5245 if (i > 0)
5246 result.GetOutputStream().PutCString("\n");
5247 this_hook->GetDescription(result.GetOutputStream(),
5249 }
5250 }
5252 }
5253};
5254
5255#pragma mark CommandObjectMultiwordTargetStopHooks
5256
5257// CommandObjectMultiwordTargetStopHooks
5258
5260public:
5263 interpreter, "target stop-hook",
5264 "Commands for operating on debugger target stop-hooks.",
5265 "target stop-hook <subcommand> [<subcommand-options>]") {
5267 new CommandObjectTargetStopHookAdd(interpreter)));
5269 "delete",
5271 LoadSubCommand("disable",
5273 interpreter, false, "target stop-hook disable [<id>]",
5274 "Disable a stop-hook.", "target stop-hook disable")));
5275 LoadSubCommand("enable",
5277 interpreter, true, "target stop-hook enable [<id>]",
5278 "Enable a stop-hook.", "target stop-hook enable")));
5280 interpreter)));
5281 }
5282
5284};
5285
5286#pragma mark CommandObjectTargetDumpTypesystem
5287
5288/// Dumps the TypeSystem of the selected Target.
5290public:
5293 interpreter, "target dump typesystem",
5294 "Dump the state of the target's internal type system. Intended to "
5295 "be used for debugging LLDB itself.",
5296 nullptr, eCommandRequiresTarget) {}
5297
5299
5300protected:
5301 void DoExecute(Args &command, CommandReturnObject &result) override {
5302 // Go over every scratch TypeSystem and dump to the command output.
5303 for (lldb::TypeSystemSP ts : GetTarget().GetScratchTypeSystems())
5304 if (ts)
5305 ts->Dump(result.GetOutputStream().AsRawOstream(), "",
5306 GetCommandInterpreter().GetDebugger().GetUseColor());
5307
5309 }
5310};
5311
5312#pragma mark CommandObjectTargetDumpSectionLoadList
5313
5314/// Dumps the SectionLoadList of the selected Target.
5316public:
5319 interpreter, "target dump section-load-list",
5320 "Dump the state of the target's internal section load list. "
5321 "Intended to be used for debugging LLDB itself.",
5322 nullptr, eCommandRequiresTarget) {}
5323
5325
5326protected:
5327 void DoExecute(Args &command, CommandReturnObject &result) override {
5328 Target &target = GetTarget();
5329 target.DumpSectionLoadList(result.GetOutputStream());
5331 }
5332};
5333
5334#pragma mark CommandObjectTargetDump
5335
5336/// Multi-word command for 'target dump'.
5338public:
5339 // Constructors and Destructors
5342 interpreter, "target dump",
5343 "Commands for dumping information about the target.",
5344 "target dump [typesystem|section-load-list]") {
5346 "typesystem",
5348 LoadSubCommand("section-load-list",
5350 interpreter)));
5351 }
5352
5353 ~CommandObjectTargetDump() override = default;
5354};
5355
5356#pragma mark CommandObjectMultiwordTarget
5357
5358// CommandObjectMultiwordTarget
5359
5361 CommandInterpreter &interpreter)
5362 : CommandObjectMultiword(interpreter, "target",
5363 "Commands for operating on debugger targets.",
5364 "target <subcommand> [<subcommand-options>]") {
5365 LoadSubCommand("create",
5366 CommandObjectSP(new CommandObjectTargetCreate(interpreter)));
5367 LoadSubCommand("delete",
5368 CommandObjectSP(new CommandObjectTargetDelete(interpreter)));
5369 LoadSubCommand("dump",
5370 CommandObjectSP(new CommandObjectTargetDump(interpreter)));
5371 LoadSubCommand("list",
5372 CommandObjectSP(new CommandObjectTargetList(interpreter)));
5373 LoadSubCommand("select",
5374 CommandObjectSP(new CommandObjectTargetSelect(interpreter)));
5375 LoadSubCommand("show-launch-environment",
5377 interpreter)));
5379 "stop-hook",
5381 LoadSubCommand("modules",
5383 LoadSubCommand("symbols",
5385 LoadSubCommand("variable",
5387}
5388
static bool GetSeparateDebugInfoList(StructuredData::Array &list, Module *module, bool errors_only, bool load_all_debug_info)
static uint32_t DumpTargetList(TargetList &target_list, bool show_stopped_process_status, Stream &strm)
static void DumpModuleUUID(Stream &strm, Module *module)
static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm, Module *module)
static void DumpModuleArchitecture(Stream &strm, Module *module, bool full_triple, uint32_t width)
static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm, Module *module, uint32_t resolve_mask, lldb::addr_t raw_addr, lldb::addr_t offset, bool verbose, bool all_ranges)
static void DumpTargetInfo(uint32_t target_idx, Target *target, const char *prefix_cstr, bool show_stopped_process_status, Stream &strm)
static void DumpDirectory(Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex, bool verbose, bool all_ranges)
static size_t LookupTypeInModule(Target *target, CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name_cstr, bool name_is_regex)
static bool DumpModuleSymbolFile(Stream &strm, Module *module)
static void DumpFullpath(Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
static void DumpDwoFilesTable(Stream &strm, StructuredData::Array &dwo_listings)
static size_t LookupFunctionInModule(CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex, const ModuleFunctionSearchOptions &options, bool verbose, bool all_ranges)
static size_t LookupTypeHere(Target *target, CommandInterpreter &interpreter, Stream &strm, Module &module, const char *name_cstr, bool name_is_regex)
static uint32_t DumpCompileUnitLineTable(CommandInterpreter &interpreter, Stream &strm, Module *module, const FileSpec &file_spec, lldb::DescriptionLevel desc_level)
static void DumpBasename(Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list)
static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter, Stream &strm, Module *module, const FileSpec &file_spec, uint32_t line, bool check_inlines, bool verbose, bool all_ranges)
static void DumpSymbolContextList(ExecutionContextScope *exe_scope, Stream &strm, const SymbolContextList &sc_list, bool verbose, bool all_ranges, std::optional< Stream::HighlightSettings > settings=std::nullopt)
static void DumpOsoFilesTable(Stream &strm, StructuredData::Array &oso_listings)
static size_t FindModulesByName(Target *target, const char *module_name, ModuleList &module_list, bool check_global_list)
static void DumpModuleSymtab(CommandInterpreter &interpreter, Stream &strm, Module *module, SortOrder sort_order, Mangled::NamePreference name_preference)
static llvm::raw_ostream & error(Stream &strm)
#define INTERRUPT_REQUESTED(debugger,...)
This handy define will keep you from having to generate a report for the interruption by hand.
Definition Debugger.h:466
#define LLDB_LOGF(log,...)
Definition Log.h:376
#define LLDB_SCOPED_TIMERF(...)
Definition Timer.h:86
~CommandObjectMultiwordTargetStopHooks() override=default
CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter)
OptionGroupPlatform m_platform_options
~CommandObjectTargetCreate() override=default
OptionGroupArchitecture m_arch_option
CommandObjectTargetCreate(CommandInterpreter &interpreter)
OptionGroupDependents m_add_dependents
void DoExecute(Args &command, CommandReturnObject &result) override
void DoExecute(Args &args, CommandReturnObject &result) override
CommandObjectTargetDelete(CommandInterpreter &interpreter)
~CommandObjectTargetDelete() override=default
Dumps the SectionLoadList of the selected Target.
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetDumpSectionLoadList() override=default
CommandObjectTargetDumpSectionLoadList(CommandInterpreter &interpreter)
Dumps the TypeSystem of the selected Target.
CommandObjectTargetDumpTypesystem(CommandInterpreter &interpreter)
~CommandObjectTargetDumpTypesystem() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
Multi-word command for 'target dump'.
CommandObjectTargetDump(CommandInterpreter &interpreter)
~CommandObjectTargetDump() override=default
CommandObjectTargetList(CommandInterpreter &interpreter)
void DoExecute(Args &args, CommandReturnObject &result) override
~CommandObjectTargetList() override=default
CommandObjectTargetModulesAdd(CommandInterpreter &interpreter)
void DoExecute(Args &args, CommandReturnObject &result) override
~CommandObjectTargetModulesAdd() override=default
CommandObjectTargetModulesDumpClangAST(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetModulesDumpClangAST() override=default
~CommandObjectTargetModulesDumpClangPCMInfo() override=default
CommandObjectTargetModulesDumpClangPCMInfo(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
~CommandObjectTargetModulesDumpLineTable() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTargetModulesDumpLineTable(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetModulesDumpObjfile() override=default
CommandObjectTargetModulesDumpObjfile(CommandInterpreter &interpreter)
CommandObjectTargetModulesDumpSections(CommandInterpreter &interpreter)
~CommandObjectTargetModulesDumpSections() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
~CommandObjectTargetModulesDumpSeparateDebugInfoFiles() override=default
CommandObjectTargetModulesDumpSeparateDebugInfoFiles(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTargetModulesDumpSymfile(CommandInterpreter &interpreter)
~CommandObjectTargetModulesDumpSymfile() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTargetModulesDumpSymtab(CommandInterpreter &interpreter)
~CommandObjectTargetModulesDumpSymtab() override=default
~CommandObjectTargetModulesDump() override=default
CommandObjectTargetModulesDump(CommandInterpreter &interpreter)
CommandObjectTargetModulesImageSearchPaths(CommandInterpreter &interpreter)
~CommandObjectTargetModulesImageSearchPaths() override=default
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
std::vector< std::pair< char, uint32_t > > FormatWidthCollection
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
CommandObjectTargetModulesList(CommandInterpreter &interpreter)
~CommandObjectTargetModulesList() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
void PrintModule(Target &target, Module *module, int indent, Stream &strm)
void DoExecute(Args &args, CommandReturnObject &result) override
~CommandObjectTargetModulesLoad() override=default
CommandObjectTargetModulesLoad(CommandInterpreter &interpreter)
void OptionParsingStarting(ExecutionContext *execution_context) override
Status OptionParsingFinished(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
bool LookupInModule(CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error)
~CommandObjectTargetModulesLookup() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
bool LookupHere(CommandInterpreter &interpreter, CommandReturnObject &result, bool &syntax_error)
CommandObjectTargetModulesLookup(CommandInterpreter &interpreter)
CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter &interpreter, const char *name, const char *help, const char *syntax, uint32_t flags=0)
~CommandObjectTargetModulesModuleAutoComplete() override=default
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
~CommandObjectTargetModulesSearchPathsAdd() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTargetModulesSearchPathsAdd(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetModulesSearchPathsClear() override=default
CommandObjectTargetModulesSearchPathsClear(CommandInterpreter &interpreter)
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
~CommandObjectTargetModulesSearchPathsInsert() override=default
CommandObjectTargetModulesSearchPathsInsert(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetModulesSearchPathsList() override=default
CommandObjectTargetModulesSearchPathsList(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetModulesSearchPathsQuery() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter &interpreter)
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
CommandObjectTargetModulesShowUnwind(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetModulesShowUnwind() override=default
CommandObjectTargetModulesSourceFileAutoComplete(CommandInterpreter &interpreter, const char *name, const char *help, const char *syntax, uint32_t flags)
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
~CommandObjectTargetModulesSourceFileAutoComplete() override=default
~CommandObjectTargetModules() override=default
const CommandObjectTargetModules & operator=(const CommandObjectTargetModules &)=delete
CommandObjectTargetModules(const CommandObjectTargetModules &)=delete
CommandObjectTargetModules(CommandInterpreter &interpreter)
~CommandObjectTargetSelect() override=default
void DoExecute(Args &args, CommandReturnObject &result) override
CommandObjectTargetSelect(CommandInterpreter &interpreter)
CommandObjectTargetShowLaunchEnvironment(CommandInterpreter &interpreter)
void DoExecute(Args &args, CommandReturnObject &result) override
~CommandObjectTargetShowLaunchEnvironment() override=default
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override
CommandObjectTargetStopHookAdd(CommandInterpreter &interpreter)
void IOHandlerInputComplete(IOHandler &io_handler, std::string &line) override
Called when a line or lines have been retrieved.
~CommandObjectTargetStopHookAdd() override=default
OptionGroupPythonClassWithDict m_python_class_options
void DoExecute(Args &command, CommandReturnObject &result) override
void DoExecute(Args &command, CommandReturnObject &result) override
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
CommandObjectTargetStopHookDelete(CommandInterpreter &interpreter)
~CommandObjectTargetStopHookDelete() override=default
~CommandObjectTargetStopHookEnableDisable() override=default
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTargetStopHookEnableDisable(CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetStopHookList() override=default
CommandObjectTargetStopHookList(CommandInterpreter &interpreter)
bool AddSymbolsForUUID(CommandReturnObject &result, bool &flush)
bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec, CommandReturnObject &result, bool &flush)
bool AddSymbolsForStack(CommandReturnObject &result, bool &flush)
CommandObjectTargetSymbolsAdd(CommandInterpreter &interpreter)
bool AddSymbolsForFrame(CommandReturnObject &result, bool &flush)
~CommandObjectTargetSymbolsAdd() override=default
void DoExecute(Args &args, CommandReturnObject &result) override
bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush, CommandReturnObject &result)
bool AddSymbolsForFile(CommandReturnObject &result, bool &flush)
const CommandObjectTargetSymbols & operator=(const CommandObjectTargetSymbols &)=delete
CommandObjectTargetSymbols(CommandInterpreter &interpreter)
~CommandObjectTargetSymbols() override=default
CommandObjectTargetSymbols(const CommandObjectTargetSymbols &)=delete
void DumpGlobalVariableList(const ExecutionContext &exe_ctx, const SymbolContext &sc, const VariableList &variable_list, CommandReturnObject &result)
void DumpValueObject(Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp, const char *root_name)
static size_t GetVariableCallback(void *baton, const char *name, VariableList &variable_list)
static const uint32_t SHORT_OPTION_SHLB
CommandObjectTargetVariable(CommandInterpreter &interpreter)
OptionGroupFileList m_option_shared_libraries
void DoExecute(Args &args, CommandReturnObject &result) override
OptionGroupFileList m_option_compile_units
static const uint32_t SHORT_OPTION_FILE
OptionGroupValueObjectDisplay m_varobj_options
~CommandObjectTargetVariable() override=default
~OptionGroupDependents() override=default
OptionGroupDependents()=default
LoadDependentFiles m_load_dependent_files
OptionGroupDependents(const OptionGroupDependents &)=delete
const OptionGroupDependents & operator=(const OptionGroupDependents &)=delete
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t, const char *, ExecutionContext *)=delete
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
virtual lldb::addr_t FixCodeAddress(lldb::addr_t pc)
Some targets might use bits in a code address to indicate a mode switch.
Definition ABI.cpp:150
A section + offset based address class.
Definition Address.h:62
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
Definition Address.cpp:301
bool SetLoadAddress(lldb::addr_t load_addr, Target *target, bool allow_section_end=false)
Set the address to represent load_addr.
Definition Address.cpp:1035
@ DumpStyleFileAddress
Display as the file address (if any).
Definition Address.h:87
@ DumpStyleSectionNameOffset
Display as the section name + offset.
Definition Address.h:74
@ DumpStyleDetailedSymbolContext
Detailed symbol context information for an address for all symbol context members.
Definition Address.h:112
@ DumpStyleInvalid
Invalid dump style.
Definition Address.h:68
@ DumpStyleModuleWithFileAddress
Display as the file address with the module name prepended (if any).
Definition Address.h:93
@ DumpStyleResolvedDescription
Display the details about what an address resolves to.
Definition Address.h:104
bool Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style=DumpStyleInvalid, uint32_t addr_byte_size=UINT32_MAX, bool all_ranges=false, std::optional< Stream::HighlightSettings > settings=std::nullopt) const
Dump a description of this object to a Stream.
Definition Address.cpp:396
lldb::ModuleSP GetModule() const
Get accessor for the module for this address.
Definition Address.cpp:273
lldb::addr_t GetFileAddress() const
Get the file address.
Definition Address.cpp:281
bool IsValid() const
Check if the object state is valid.
Definition Address.h:355
An architecture specification class.
Definition ArchSpec.h:31
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
Definition ArchSpec.cpp:685
bool IsValid() const
Tests if this ArchSpec is valid.
Definition ArchSpec.h:366
void DumpTriple(llvm::raw_ostream &s) const
const char * GetArchitectureName() const
Returns a static string representing the current architecture.
Definition ArchSpec.cpp:548
A command line argument class.
Definition Args.h:33
void Shift()
Shifts the first argument C string value of the array off the argument array.
Definition Args.cpp:295
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
Definition Args.h:120
llvm::ArrayRef< ArgEntry > entries() const
Definition Args.h:132
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx.
Definition Args.cpp:273
static bool InvokeCommonCompletionCallbacks(CommandInterpreter &interpreter, uint32_t completion_mask, lldb_private::CompletionRequest &request, SearchFilter *searcher)
ExecutionContext GetExecutionContext() const
CommandObjectMultiwordTarget(CommandInterpreter &interpreter)
bool LoadSubCommand(llvm::StringRef cmd_name, const lldb::CommandObjectSP &command_obj) override
CommandObjectMultiword(CommandInterpreter &interpreter, const char *name, const char *help=nullptr, const char *syntax=nullptr, uint32_t flags=0)
CommandObjectParsed(CommandInterpreter &interpreter, const char *name, const char *help=nullptr, const char *syntax=nullptr, uint32_t flags=0)
std::vector< CommandArgumentData > CommandArgumentEntry
virtual void SetHelpLong(llvm::StringRef str)
void AddSimpleArgumentList(lldb::CommandArgumentType arg_type, ArgumentRepetitionType repetition_type=eArgRepeatPlain)
std::vector< CommandArgumentEntry > m_arguments
CommandInterpreter & GetCommandInterpreter()
CommandInterpreter & m_interpreter
virtual void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector)
The default version handles argument definitions that have only one argument type,...
void void AppendError(llvm::StringRef in_string)
const ValueObjectList & GetValueObjectList() const
void AppendWarningWithFormat(const char *format,...) __attribute__((format(printf
void SetStatus(lldb::ReturnStatus status)
void AppendErrorWithFormat(const char *format,...) __attribute__((format(printf
void AppendMessageWithFormat(const char *format,...) __attribute__((format(printf
void void AppendMessageWithFormatv(const char *format, Args &&...args)
void void AppendWarning(llvm::StringRef in_string)
void AppendErrorWithFormatv(const char *format, Args &&...args)
A class that describes a compilation unit.
Definition CompileUnit.h:43
lldb::VariableListSP GetVariableList(bool can_create)
Get the variable list for a compile unit.
const FileSpec & GetPrimaryFile() const
Return the primary source spec associated with this compile unit.
"lldb/Utility/ArgCompletionRequest.h"
void TryCompleteCurrentArg(llvm::StringRef completion, llvm::StringRef description="")
Adds a possible completion string if the completion would complete the current argument.
A uniqued constant string class.
Definition ConstString.h:40
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
void Dump(Stream *s, const char *value_if_empty=nullptr) const
Dump the object description to a stream.
bool IsEmpty() const
Test for empty string.
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
const char * GetCString() const
Get the string value as a C string.
A class to manage flag bits.
Definition Debugger.h:80
TargetList & GetTargetList()
Get accessor for the target list.
Definition Debugger.h:201
bool GetUseColor() const
Definition Debugger.cpp:454
llvm::StringRef GetRegexMatchAnsiSuffix() const
Definition Debugger.cpp:559
llvm::StringRef GetRegexMatchAnsiPrefix() const
Definition Debugger.cpp:553
DumpValueObjectOptions & SetRootValueObjectName(const char *name=nullptr)
DumpValueObjectOptions & SetFormat(lldb::Format format=lldb::eFormatDefault)
A class that measures elapsed time in an exception safe way.
Definition Statistics.h:76
"lldb/Target/ExecutionContextScope.h" Inherit from this if your object can reconstruct its execution ...
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
ExecutionContextScope * GetBestExecutionContextScope() const
Target * GetTargetPtr() const
Returns a pointer to the target object.
A file collection class.
const FileSpec & GetFileSpecAtIndex(size_t idx) const
Get file at index.
size_t GetSize() const
Get the number of files in the file list.
A file utility class.
Definition FileSpec.h:57
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
Definition FileSpec.cpp:174
void SetDirectory(ConstString directory)
Directory string set accessor.
Definition FileSpec.cpp:342
const ConstString & GetFilename() const
Filename string const get accessor.
Definition FileSpec.h:251
const ConstString & GetDirectory() const
Directory string const get accessor.
Definition FileSpec.h:234
ConstString GetFileNameStrippingExtension() const
Return the filename without the extension part.
Definition FileSpec.cpp:414
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition FileSpec.cpp:374
void Dump(llvm::raw_ostream &s) const
Dump this object to a Stream.
Definition FileSpec.cpp:325
llvm::StringRef GetFileNameExtension() const
Extract the extension of the file.
Definition FileSpec.cpp:410
void SetFilename(ConstString filename)
Filename string set accessor.
Definition FileSpec.cpp:352
void Resolve(llvm::SmallVectorImpl< char > &path)
Resolve path to make it canonical.
bool ResolveExecutableLocation(FileSpec &file_spec)
Call into the Host to see if it can help find the file.
bool Exists(const FileSpec &file_spec) const
Returns whether the given file exists.
int Open(const char *path, int flags, int mode=0600)
Wraps open in a platform-independent way.
static FileSystem & Instance()
@ eOpenOptionReadOnly
Definition File.h:51
IOHandlerDelegateMultiline(llvm::StringRef end_line, Completion completion=Completion::None)
Definition IOHandler.h:289
A delegate class for use with IOHandler subclasses.
Definition IOHandler.h:184
lldb::LockableStreamFileSP GetErrorStreamFileSP()
Definition IOHandler.cpp:95
lldb::LockableStreamFileSP GetOutputStreamFileSP()
Definition IOHandler.cpp:93
void SetIsDone(bool b)
Definition IOHandler.h:81
A line table class.
Definition LineTable.h:25
void GetDescription(Stream *s, Target *target, lldb::DescriptionLevel level)
A collection class for Module objects.
Definition ModuleList.h:104
void FindFunctions(ConstString name, lldb::FunctionNameType name_type_mask, const ModuleFunctionSearchOptions &options, SymbolContextList &sc_list) const
ModuleIterableNoLocking ModulesNoLocking() const
Definition ModuleList.h:546
static bool ModuleIsInCache(const Module *module_ptr)
void FindGlobalVariables(ConstString name, size_t max_matches, VariableList &variable_list) const
Find global and static variables by name.
std::recursive_mutex & GetMutex() const
Definition ModuleList.h:231
lldb::ModuleSP FindFirstModule(const ModuleSpec &module_spec) const
Finds the first module whose file specification matches module_spec.
lldb::ModuleSP GetModuleAtIndexUnlocked(size_t idx) const
Get the module shared pointer for the module at index idx without acquiring the ModuleList mutex.
void FindCompileUnits(const FileSpec &path, SymbolContextList &sc_list) const
Find compile units by partial or full path.
bool AppendIfNeeded(const lldb::ModuleSP &new_module, bool notify=true)
Append a module to the module list, if it is not already there.
Module * GetModulePointerAtIndex(size_t idx) const
Get the module pointer for the module at index idx.
void FindModules(const ModuleSpec &module_spec, ModuleList &matching_module_list) const
Finds modules whose file specification matches module_spec.
lldb::ModuleSP GetModuleAtIndex(size_t idx) const
Get the module shared pointer for the module at index idx.
void Append(const lldb::ModuleSP &module_sp, bool notify=true)
Append a module to the module list.
static size_t RemoveOrphanSharedModules(bool mandatory)
static void FindSharedModules(const ModuleSpec &module_spec, ModuleList &matching_module_list)
ModuleIterable Modules() const
Definition ModuleList.h:540
size_t GetSize() const
Gets the size of the module list.
bool GetModuleSpecAtIndex(size_t i, ModuleSpec &module_spec) const
Definition ModuleSpec.h:323
bool FindMatchingModuleSpec(const ModuleSpec &module_spec, ModuleSpec &match_module_spec) const
Definition ModuleSpec.h:333
FileSpec & GetPlatformFileSpec()
Definition ModuleSpec.h:65
FileSpec & GetFileSpec()
Definition ModuleSpec.h:53
ArchSpec & GetArchitecture()
Definition ModuleSpec.h:89
FileSpec * GetFileSpecPtr()
Definition ModuleSpec.h:47
FileSpec & GetSymbolFileSpec()
Definition ModuleSpec.h:77
A class that describes an executable image and its associated object and symbol files.
Definition Module.h:90
const lldb_private::UUID & GetUUID()
Get a reference to the UUID value contained in this object.
Definition Module.cpp:350
virtual SymbolFile * GetSymbolFile(bool can_create=true, Stream *feedback_strm=nullptr)
Get the module's symbol file.
Definition Module.cpp:977
static Module * GetAllocatedModuleAtIndex(size_t idx)
Definition Module.cpp:124
static std::recursive_mutex & GetAllocationModuleCollectionMutex()
Definition Module.cpp:106
bool ResolveFileAddress(lldb::addr_t vm_addr, Address &so_addr)
Definition Module.cpp:447
Symtab * GetSymtab(bool can_create=true)
Get the module's symbol table.
Definition Module.cpp:1004
bool MatchesModuleSpec(const ModuleSpec &module_ref)
Definition Module.cpp:1503
static size_t GetNumberAllocatedModules()
Definition Module.cpp:118
const ArchSpec & GetArchitecture() const
Get const accessor for the module architecture.
Definition Module.cpp:1019
std::string GetSpecificationDescription() const
Get the module path and object name.
Definition Module.cpp:1021
const FileSpec & GetFileSpec() const
Get const accessor for the module file specification.
Definition Module.h:454
const llvm::sys::TimePoint & GetModificationTime() const
Definition Module.h:490
A plug-in interface definition class for object file parsers.
Definition ObjectFile.h:45
virtual void Dump(Stream *s)=0
Dump a description of this object to a Stream.
virtual std::vector< LoadableData > GetLoadableData(Target &target)
Loads this objfile to memory.
virtual lldb_private::Address GetEntryPointAddress()
Returns the address of the Entry Point in this object file - if the object file doesn't have an entry...
Definition ObjectFile.h:476
virtual FileSpec & GetFileSpec()
Get accessor to the object file specification.
Definition ObjectFile.h:281
virtual lldb_private::Address GetBaseAddress()
Returns base address of this object file.
Definition ObjectFile.h:486
static size_t GetModuleSpecifications(const FileSpec &file, lldb::offset_t file_offset, lldb::offset_t file_size, ModuleSpecList &specs, lldb::DataBufferSP data_sp=lldb::DataBufferSP())
static const uint32_t OPTION_GROUP_GDB_FMT
static const uint32_t OPTION_GROUP_FORMAT
A command line option parsing protocol class.
Definition Options.h:58
std::vector< Option > m_getopt_table
Definition Options.h:198
void Insert(llvm::StringRef path, llvm::StringRef replacement, uint32_t insert_idx, bool notify)
void Append(llvm::StringRef path, llvm::StringRef replacement, bool notify)
bool RemapPath(ConstString path, ConstString &new_path) const
bool GetPathsAtIndex(uint32_t idx, ConstString &path, ConstString &new_path) const
void Dump(Stream *s, int pair_index=-1)
static bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec, Status &error, bool force_lookup=true, bool copy_executable=true)
void SetExecutableFile(const FileSpec &exe_file, bool add_exe_file_as_first_arg)
A plug-in interface definition class for debugging a process.
Definition Process.h:357
ThreadList & GetThreadList()
Definition Process.h:2253
void Flush()
Flush all data in the process.
Definition Process.cpp:5890
lldb::StateType GetState()
Get accessor for the current process state.
Definition Process.cpp:1285
const lldb::ABISP & GetABI()
Definition Process.cpp:1481
bool IsValid() const
Test if this object contains a valid regular expression.
lldb::SectionSP FindSectionByName(ConstString section_dstr) const
Definition Section.cpp:558
void Dump(llvm::raw_ostream &s, unsigned indent, Target *target, bool show_header, uint32_t depth) const
Definition Section.cpp:644
This base class provides an interface to stack frames.
Definition StackFrame.h:44
const SymbolContext & GetSymbolContext(lldb::SymbolContextItem resolve_scope)
Provide a SymbolContext for this StackFrame's current pc value.
uint32_t GetFrameIndex() const
Query this frame to find what frame it is in this Thread's StackFrameList.
An error handling class.
Definition Status.h:118
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Definition Status.cpp:106
static Status FromErrorString(const char *str)
Definition Status.h:141
bool Fail() const
Test for error condition.
Definition Status.cpp:294
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition Status.cpp:195
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
Definition Status.h:151
const char * GetData() const
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
Definition Stream.h:28
void Format(const char *format, Args &&... args)
Definition Stream.h:344
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
Definition Stream.h:392
size_t Indent(llvm::StringRef s="")
Indent the current line in the stream.
Definition Stream.cpp:157
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition Stream.cpp:134
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition Stream.cpp:65
void SetAddressByteSize(uint32_t addr_size)
Set the address size in bytes.
Definition Stream.cpp:209
size_t PutChar(char ch)
Definition Stream.cpp:131
void SetIndentLevel(unsigned level)
Set the current indentation level.
Definition Stream.cpp:190
void PutCStringColorHighlighted(llvm::StringRef text, std::optional< HighlightSettings > settings=std::nullopt)
Output a C string to the stream with color highlighting.
Definition Stream.cpp:75
size_t EOL()
Output and End of Line character to the stream.
Definition Stream.cpp:155
void IndentLess(unsigned amount=2)
Decrement the current indentation level.
Definition Stream.cpp:198
void IndentMore(unsigned amount=2)
Increment the current indentation level.
Definition Stream.cpp:195
unsigned GetIndentLevel() const
Get the current indentation level.
Definition Stream.cpp:187
void AddItem(const ObjectSP &item)
bool ForEach(std::function< bool(Object *object)> const &foreach_callback) const
bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const
bool GetValueForKeyAsString(llvm::StringRef key, llvm::StringRef &result) const
bool GetValueForKeyAsArray(llvm::StringRef key, Array *&result) const
void Dump(lldb_private::Stream &s, bool pretty_print=true) const
Defines a list of symbol context objects.
uint32_t GetSize() const
Get accessor for a symbol context list size.
void Append(const SymbolContext &sc)
Append a new symbol context to the list.
Defines a symbol context baton that can be handed other debug core functions.
Function * function
The Function for a given query.
void SortTypeList(TypeMap &type_map, TypeList &type_list) const
Sorts the types in TypeMap according to SymbolContext to TypeList.
lldb::ModuleSP module_sp
The Module for a given query.
CompileUnit * comp_unit
The CompileUnit for a given query.
Symbol * symbol
The Symbol for a given query.
Provides public interface for all SymbolFiles.
Definition SymbolFile.h:51
virtual ObjectFile * GetObjectFile()=0
bool ValueIsAddress() const
Definition Symbol.cpp:165
bool GetByteSizeIsValid() const
Definition Symbol.h:209
Address & GetAddressRef()
Definition Symbol.h:73
lldb::addr_t GetByteSize() const
Definition Symbol.cpp:431
ConstString GetDisplayName() const
Definition Symbol.cpp:169
uint64_t GetRawValue() const
Get the raw value of the symbol from the symbol table.
Definition Symbol.h:110
Symbol * SymbolAtIndex(size_t idx)
Definition Symtab.cpp:228
uint32_t AppendSymbolIndexesWithName(ConstString symbol_name, std::vector< uint32_t > &matches)
Definition Symtab.cpp:681
uint32_t AppendSymbolIndexesMatchingRegExAndType(const RegularExpression &regex, lldb::SymbolType symbol_type, std::vector< uint32_t > &indexes, Mangled::NamePreference name_preference=Mangled::ePreferDemangled)
Definition Symtab.cpp:758
lldb::TargetSP GetTargetAtIndex(uint32_t index) const
void SetSelectedTarget(uint32_t index)
bool DeleteTarget(lldb::TargetSP &target_sp)
Delete a Target object from the list.
Status CreateTarget(Debugger &debugger, llvm::StringRef user_exe_path, llvm::StringRef triple_str, LoadDependentFiles get_dependent_modules, const OptionGroupPlatform *platform_options, lldb::TargetSP &target_sp)
Create a new Target.
lldb::TargetSP GetSelectedTarget()
size_t GetNumTargets() const
bool GetUserSpecifiedTrapHandlerNames(Args &args) const
Definition Target.cpp:5020
Environment GetEnvironment() const
Definition Target.cpp:4674
void SetActionFromString(const std::string &strings)
Definition Target.cpp:3989
void SetActionFromStrings(const std::vector< std::string > &strings)
Definition Target.cpp:3993
Status SetScriptCallback(std::string class_name, StructuredData::ObjectSP extra_args_sp)
Definition Target.cpp:4034
void ModulesDidLoad(ModuleList &module_list)
Definition Target.cpp:1854
Module * GetExecutableModulePointer()
Definition Target.cpp:1536
StopHookSP CreateStopHook(StopHook::StopHookKind kind)
Add an empty stop hook to the Target's stop hook list, and returns a shared pointer to it in new_hook...
Definition Target.cpp:3044
PathMappingList & GetImageSearchPathList()
Definition Target.cpp:2596
std::shared_ptr< StopHook > StopHookSP
Definition Target.h:1471
void SymbolsDidLoad(ModuleList &module_list)
Definition Target.cpp:1874
size_t GetNumStopHooks() const
Definition Target.h:1507
void DumpSectionLoadList(Stream &s)
Definition Target.cpp:5244
const lldb::ProcessSP & GetProcessSP() const
Definition Target.cpp:309
lldb::ModuleSP GetOrCreateModule(const ModuleSpec &module_spec, bool notify, Status *error_ptr=nullptr)
Find a binary on the system and return its Module, or return an existing Module that is already in th...
Definition Target.cpp:2342
void UndoCreateStopHook(lldb::user_id_t uid)
If you tried to create a stop hook, and that failed, call this to remove the stop hook,...
Definition Target.cpp:3059
bool ResolveLoadAddress(lldb::addr_t load_addr, Address &so_addr, uint32_t stop_id=SectionLoadHistory::eStopIDNow, bool allow_section_end=false)
Definition Target.cpp:3288
bool SetStopHookActiveStateByID(lldb::user_id_t uid, bool active_state)
Definition Target.cpp:3083
void SetAllStopHooksActiveState(bool active_state)
Definition Target.cpp:3094
StopHookSP GetStopHookAtIndex(size_t index)
Definition Target.h:1509
lldb::PlatformSP GetPlatform()
Definition Target.h:1521
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition Target.h:1025
const ArchSpec & GetArchitecture() const
Definition Target.h:1067
const std::string & GetLabel() const
Definition Target.h:614
lldb::ProcessSP CalculateProcess() override
Definition Target.cpp:2585
bool SetSectionLoadAddress(const lldb::SectionSP &section, lldb::addr_t load_addr, bool warn_multiple=false)
Definition Target.cpp:3299
bool RemoveStopHookByID(lldb::user_id_t uid)
Definition Target.cpp:3066
lldb::ThreadSP GetSelectedThread()
uint32_t GetSize(bool can_update=true)
lldb::ThreadSP GetThreadAtIndex(uint32_t idx, bool can_update=true)
void SetIndex(uint32_t index)
Definition ThreadSpec.h:45
void SetName(llvm::StringRef name)
Definition ThreadSpec.h:49
void SetTID(lldb::tid_t tid)
Definition ThreadSpec.h:47
void SetQueueName(llvm::StringRef queue_name)
Definition ThreadSpec.h:51
uint32_t GetSize() const
Definition TypeList.cpp:60
bool Empty() const
Definition TypeList.h:37
TypeIterable Types()
Definition TypeList.h:44
lldb::TypeSP GetTypeAtIndex(uint32_t idx)
Definition TypeList.cpp:66
A class that contains all state required for type lookups.
Definition Type.h:104
This class tracks the state and results of a TypeQuery.
Definition Type.h:344
TypeMap & GetTypeMap()
Definition Type.h:386
void Dump(Stream &s) const
Definition UUID.cpp:68
std::string GetAsString(llvm::StringRef separator="-") const
Definition UUID.cpp:54
bool IsValid() const
Definition UUID.h:69
lldb::FuncUnwindersSP GetFuncUnwindersContainingAddress(const Address &addr, const SymbolContext &sc)
lldb::FuncUnwindersSP GetUncachedFuncUnwindersContainingAddress(const Address &addr, const SymbolContext &sc)
A collection of ValueObject values that.
void Append(const lldb::ValueObjectSP &val_obj_sp)
lldb::ValueObjectSP GetValueObjectAtIndex(size_t idx)
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, const lldb::VariableSP &var_sp)
lldb::VariableSP GetVariableAtIndex(size_t idx) const
static Status GetValuesForVariableExpressionPath(llvm::StringRef variable_expr_path, ExecutionContextScope *scope, GetVariableCallback callback, void *baton, VariableList &variable_list, ValueObjectList &valobj_list)
Definition Variable.cpp:326
#define LLDB_OPT_SET_1
#define LLDB_OPT_SET_FROM_TO(A, B)
#define LLDB_OPT_SET_2
#define LLDB_INVALID_LINE_NUMBER
#define LLDB_INVALID_THREAD_ID
#define LLDB_INVALID_INDEX32
#define LLDB_OPT_SET_ALL
#define LLDB_INVALID_ADDRESS
#define UINT32_MAX
#define LLDB_INVALID_PROCESS_ID
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:332
std::vector< OptionArgElement > OptionElementVector
Definition Options.h:43
bool StateIsStoppedState(lldb::StateType state, bool must_exist)
Check if a state represents a state where the process or thread is stopped.
Definition State.cpp:89
void DumpAddress(llvm::raw_ostream &s, uint64_t addr, uint32_t addr_size, const char *prefix=nullptr, const char *suffix=nullptr)
Output an address value to this stream.
Definition Stream.cpp:108
const char * StateAsCString(lldb::StateType state)
Converts a StateType to a C string.
Definition State.cpp:14
const char * toString(AppleArm64ExceptionClass EC)
@ eSourceFileCompletion
std::shared_ptr< lldb_private::TypeSystem > TypeSystemSP
std::shared_ptr< lldb_private::ABI > ABISP
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
DescriptionLevel
Description levels for "void GetDescription(Stream *, DescriptionLevel)" calls.
@ eDescriptionLevelBrief
@ eDescriptionLevelFull
std::shared_ptr< lldb_private::Thread > ThreadSP
std::shared_ptr< lldb_private::CommandObject > CommandObjectSP
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
Format
Display format definitions.
std::shared_ptr< lldb_private::Platform > PlatformSP
StateType
Process and Thread States.
std::shared_ptr< lldb_private::FuncUnwinders > FuncUnwindersSP
std::shared_ptr< lldb_private::Type > TypeSP
std::shared_ptr< lldb_private::Process > ProcessSP
@ eReturnStatusFailed
@ eReturnStatusSuccessFinishResult
@ eReturnStatusSuccessFinishNoResult
uint64_t pid_t
Definition lldb-types.h:83
@ eArgTypeOldPathPrefix
@ eArgTypeNewPathPrefix
@ eArgTypeDirectoryName
std::shared_ptr< lldb_private::VariableList > VariableListSP
std::shared_ptr< lldb_private::UnwindPlan > UnwindPlanSP
std::shared_ptr< lldb_private::Variable > VariableSP
uint64_t user_id_t
Definition lldb-types.h:82
std::shared_ptr< lldb_private::LockableStreamFile > LockableStreamFileSP
std::shared_ptr< lldb_private::Section > SectionSP
uint64_t addr_t
Definition lldb-types.h:80
std::shared_ptr< lldb_private::Target > TargetSP
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
uint64_t tid_t
Definition lldb-types.h:84
std::shared_ptr< lldb_private::Module > ModuleSP
@ eValueTypeVariableGlobal
globals variable
@ eValueTypeVariableLocal
function local variables
@ eValueTypeVariableArgument
function argument variables
@ eValueTypeVariableStatic
static variable
@ eValueTypeVariableThreadLocal
thread local storage variable
Used to build individual command argument lists.
Options used by Module::FindFunctions.
Definition Module.h:66
bool include_inlines
Include inlined functions.
Definition Module.h:70
bool include_symbols
Include the symbol table.
Definition Module.h:68
static int64_t ToOptionEnum(llvm::StringRef s, const OptionEnumValues &enum_values, int32_t fail_value, Status &error)
static lldb::addr_t ToAddress(const ExecutionContext *exe_ctx, llvm::StringRef s, lldb::addr_t fail_value, Status *error_ptr)
Try to parse an address.
static bool ToBoolean(llvm::StringRef s, bool fail_value, bool *success_ptr)
Struct to store information for color highlighting in the stream.
Definition Stream.h:37
#define PATH_MAX