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"
50#include "lldb/Target/Thread.h"
52#include "lldb/Utility/Args.h"
57#include "lldb/Utility/State.h"
58#include "lldb/Utility/Stream.h"
60#include "lldb/Utility/Timer.h"
63#include "lldb/lldb-forward.h"
65
66#include "llvm/ADT/ScopeExit.h"
67#include "llvm/ADT/StringRef.h"
68#include "llvm/Support/ErrorHandling.h"
69#include "llvm/Support/FileSystem.h"
70#include "llvm/Support/FormatAdapters.h"
71
72#include <numeric>
73
74using namespace lldb;
75using namespace lldb_private;
76
77static void DumpTargetInfo(uint32_t target_idx, Target *target,
78 const char *prefix_cstr,
79 bool show_stopped_process_status, Stream &strm) {
80 const ArchSpec &target_arch = target->GetArchitecture();
81
82 Module *exe_module = target->GetExecutableModulePointer();
83 char exe_path[PATH_MAX];
84 bool exe_valid = false;
85 if (exe_module)
86 exe_valid = exe_module->GetFileSpec().GetPath(exe_path, sizeof(exe_path));
87
88 if (!exe_valid)
89 ::strcpy(exe_path, "<none>");
90
91 std::string formatted_label = "";
92 const std::string &label = target->GetLabel();
93 if (!label.empty()) {
94 formatted_label = " (" + label + ")";
95 }
96
97 strm.Printf("%starget #%u%s: %s", prefix_cstr ? prefix_cstr : "", target_idx,
98 formatted_label.data(), exe_path);
99
100 uint32_t properties = 0;
101 if (target_arch.IsValid()) {
102 strm.PutCString(" ( arch=");
103 target_arch.DumpTriple(strm.AsRawOstream());
104 properties++;
105 }
106 PlatformSP platform_sp(target->GetPlatform());
107 if (platform_sp)
108 strm.Format("{0}platform={1}", properties++ > 0 ? ", " : " ( ",
109 platform_sp->GetName());
110
111 ProcessSP process_sp(target->GetProcessSP());
112 bool show_process_status = false;
113 if (process_sp) {
114 lldb::pid_t pid = process_sp->GetID();
115 StateType state = process_sp->GetState();
116 if (show_stopped_process_status)
117 show_process_status = StateIsStoppedState(state, true);
118 const char *state_cstr = StateAsCString(state);
119 if (pid != LLDB_INVALID_PROCESS_ID)
120 strm.Printf("%spid=%" PRIu64, properties++ > 0 ? ", " : " ( ", pid);
121 strm.Printf("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
122 }
123 if (properties > 0)
124 strm.PutCString(" )\n");
125 else
126 strm.EOL();
127 if (show_process_status) {
128 const bool only_threads_with_stop_reason = true;
129 const uint32_t start_frame = 0;
130 const uint32_t num_frames = 1;
131 const uint32_t num_frames_with_source = 1;
132 const bool stop_format = false;
133 process_sp->GetStatus(strm);
134 process_sp->GetThreadStatus(strm, only_threads_with_stop_reason,
135 start_frame, num_frames, num_frames_with_source,
136 stop_format);
137 }
138}
139
140static uint32_t DumpTargetList(TargetList &target_list,
141 bool show_stopped_process_status, Stream &strm) {
142 const uint32_t num_targets = target_list.GetNumTargets();
143 if (num_targets) {
144 TargetSP selected_target_sp(target_list.GetSelectedTarget());
145 strm.PutCString("Current targets:\n");
146 for (uint32_t i = 0; i < num_targets; ++i) {
147 TargetSP target_sp(target_list.GetTargetAtIndex(i));
148 if (target_sp) {
149 bool is_selected = target_sp.get() == selected_target_sp.get();
150 DumpTargetInfo(i, target_sp.get(), is_selected ? "* " : " ",
151 show_stopped_process_status, strm);
152 }
153 }
154 }
155 return num_targets;
156}
157
158#define LLDB_OPTIONS_target_dependents
159#include "CommandOptions.inc"
160
162public:
164
165 ~OptionGroupDependents() override = default;
166
167 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
168 return llvm::ArrayRef(g_target_dependents_options);
169 }
170
171 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
172 ExecutionContext *execution_context) override {
174
175 // For compatibility no value means don't load dependents.
176 if (option_value.empty()) {
178 return error;
179 }
180
181 const char short_option =
182 g_target_dependents_options[option_idx].short_option;
183 if (short_option == 'd') {
184 LoadDependentFiles tmp_load_dependents;
186 option_value, g_target_dependents_options[option_idx].enum_values, 0,
187 error);
188 if (error.Success())
189 m_load_dependent_files = tmp_load_dependents;
190 } else {
192 "unrecognized short option '%c'", short_option);
193 }
194
195 return error;
196 }
197
198 Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete;
199
203
205
206private:
210};
211
212#pragma mark CommandObjectTargetCreate
213
215public:
218 interpreter, "target create",
219 "Create a target using the argument as the main executable.",
220 nullptr),
221 m_platform_options(true), // Include the --platform option.
222 m_core_file(LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename,
223 "Fullpath to a core file to use for this target."),
224 m_label(LLDB_OPT_SET_1, false, "label", 'l', 0, eArgTypeName,
225 "Optional name for this target.", nullptr),
226 m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
228 "Fullpath to a stand alone debug "
229 "symbols file for when debug symbols "
230 "are not in the executable."),
232 LLDB_OPT_SET_1, false, "remote-file", 'r', 0, eArgTypeFilename,
233 "Fullpath to the file on the remote host if debugging remotely.") {
234
236
244 m_option_group.Finalize();
245 }
246
247 ~CommandObjectTargetCreate() override = default;
248
249 Options *GetOptions() override { return &m_option_group; }
250
251protected:
252 void DoExecute(Args &command, CommandReturnObject &result) override {
253 const size_t argc = command.GetArgumentCount();
254 FileSpec core_file(m_core_file.GetOptionValue().GetCurrentValue());
255 FileSpec remote_file(m_remote_file.GetOptionValue().GetCurrentValue());
256
257 if (core_file) {
258 auto file = FileSystem::Instance().Open(
260
261 if (!file) {
262 result.AppendErrorWithFormatv("Cannot open '{0}': {1}.",
263 core_file.GetPath(),
264 llvm::toString(file.takeError()));
265 return;
266 }
267 }
268
269 if (argc == 1 || core_file || remote_file) {
270 FileSpec symfile(m_symbol_file.GetOptionValue().GetCurrentValue());
271 if (symfile) {
272 auto file = FileSystem::Instance().Open(
274
275 if (!file) {
276 result.AppendErrorWithFormatv("Cannot open '{0}': {1}.",
277 symfile.GetPath(),
278 llvm::toString(file.takeError()));
279 return;
280 }
281 }
282
283 const char *file_path = command.GetArgumentAtIndex(0);
284 LLDB_SCOPED_TIMERF("(lldb) target create '%s'", file_path);
285
286 bool must_set_platform_path = false;
287
288 Debugger &debugger = GetDebugger();
289
290 TargetSP target_sp;
291 llvm::StringRef arch_cstr = m_arch_option.GetArchitectureName();
293 debugger, file_path, arch_cstr,
294 m_add_dependents.m_load_dependent_files, &m_platform_options,
295 target_sp));
296
297 if (!target_sp) {
298 result.AppendError(error.AsCString());
299 return;
300 }
301
302 const llvm::StringRef label =
303 m_label.GetOptionValue().GetCurrentValueAsRef();
304 if (!label.empty()) {
305 if (auto E = target_sp->SetLabel(label))
306 result.SetError(std::move(E));
307 else
309 return;
310 }
311
312 llvm::scope_exit on_error(
313 [&target_list = debugger.GetTargetList(), &target_sp]() {
314 target_list.DeleteTarget(target_sp);
315 });
316
317 // Only get the platform after we create the target because we might
318 // have switched platforms depending on what the arguments were to
319 // CreateTarget() we can't rely on the selected platform.
320
321 PlatformSP platform_sp = target_sp->GetPlatform();
322
323 FileSpec file_spec;
324 if (file_path) {
325 file_spec.SetFile(file_path, FileSpec::Style::native);
326 FileSystem::Instance().Resolve(file_spec);
327
328 // Try to resolve the exe based on PATH and/or platform-specific
329 // suffixes, but only if using the host platform.
330 if (platform_sp && platform_sp->IsHost() &&
331 !FileSystem::Instance().Exists(file_spec))
333 }
334
335 if (remote_file) {
336 if (platform_sp) {
337 // I have a remote file.. two possible cases
338 if (file_spec && FileSystem::Instance().Exists(file_spec)) {
339 // if the remote file does not exist, push it there
340 if (!platform_sp->GetFileExists(remote_file)) {
341 Status err = platform_sp->PutFile(file_spec, remote_file);
342 if (err.Fail()) {
343 result.AppendError(err.AsCString());
344 return;
345 }
346 }
347 } else {
348 // there is no local file and we need one
349 // in order to make the remote ---> local transfer we need a
350 // platform
351 // TODO: if the user has passed in a --platform argument, use it
352 // to fetch the right platform
353 if (file_path) {
354 // copy the remote file to the local file
355 Status err = platform_sp->GetFile(remote_file, file_spec);
356 if (err.Fail()) {
357 result.AppendError(err.AsCString());
358 return;
359 }
360 } else {
361 // If the remote file exists, we can debug reading that out of
362 // memory. If the platform is already connected to an lldb-server
363 // then we can at least check the file exists remotely. Otherwise
364 // we'll just have to trust that it will be there when we do
365 // process connect.
366 // I don't do this for the host platform because it seems odd to
367 // support supplying a remote file but no local file for a local
368 // debug session.
369 if (platform_sp->IsHost()) {
370 result.AppendError("Supply a local file, not a remote file, "
371 "when debugging on the host.");
372 return;
373 }
374 if (platform_sp->IsConnected() && !platform_sp->GetFileExists(remote_file)) {
375 result.AppendError("remote --> local transfer without local "
376 "path is not implemented yet");
377 return;
378 }
379 // Since there's only a remote file, we need to set the executable
380 // file spec to the remote one.
381 ProcessLaunchInfo launch_info = target_sp->GetProcessLaunchInfo();
382 launch_info.SetExecutableFile(FileSpec(remote_file), true);
383 target_sp->SetProcessLaunchInfo(launch_info);
384 }
385 }
386 } else {
387 result.AppendError("no platform found for target");
388 return;
389 }
390 }
391
392 if (symfile || remote_file) {
393 ModuleSP module_sp(target_sp->GetExecutableModule());
394 if (module_sp) {
395 if (symfile)
396 module_sp->SetSymbolFileFileSpec(symfile);
397 if (remote_file) {
398 std::string remote_path = remote_file.GetPath();
399 target_sp->SetArg0(remote_path.c_str());
400 module_sp->SetPlatformFileSpec(remote_file);
401 }
402 }
403 }
404
405 if (must_set_platform_path) {
406 ModuleSpec main_module_spec(file_spec);
407 ModuleSP module_sp =
408 target_sp->GetOrCreateModule(main_module_spec, true /* notify */);
409 if (module_sp)
410 module_sp->SetPlatformFileSpec(remote_file);
411 }
412
413 if (core_file) {
414 FileSpec core_file_dir;
415 core_file_dir.SetDirectory(core_file.GetDirectory());
416 target_sp->AppendExecutableSearchPaths(core_file_dir);
417
418 ProcessSP process_sp(target_sp->CreateProcess(
419 GetDebugger().GetListener(), llvm::StringRef(), &core_file, false));
420
421 if (process_sp) {
422 // Seems weird that we Launch a core file, but that is what we
423 // do!
424 {
425 ElapsedTime load_core_time(
426 target_sp->GetStatistics().GetLoadCoreTime());
427 error = process_sp->LoadCore();
428 }
429
430 if (error.Fail()) {
431 result.AppendError(error.AsCString("unknown core file format"));
432 return;
433 } else {
435 "Core file '{0}' ({1}) was loaded.\n", core_file.GetPath(),
436 target_sp->GetArchitecture().GetArchitectureName());
437 if (auto core_args = process_sp->GetCoreFileArgs())
438 core_args->Format(result.GetOutputStream());
440 on_error.release();
441 }
442 } else {
443 result.AppendErrorWithFormatv("Unknown core file format '{0}'\n",
444 core_file.GetPath());
445 }
446 } else {
448 "Current executable set to '{0}' ({1}).",
449 file_spec.GetPath().c_str(),
450 target_sp->GetArchitecture().GetArchitectureName());
452 on_error.release();
453 }
454 } else {
455 result.AppendErrorWithFormat("'%s' takes exactly one executable path "
456 "argument, or use the --core option",
457 m_cmd_name.c_str());
458 }
459 }
460
461private:
470};
471
472#pragma mark CommandObjectTargetList
473
475public:
478 interpreter, "target list",
479 "List all current targets in the current debug session.", nullptr) {
480 }
481
482 ~CommandObjectTargetList() override = default;
483
484protected:
485 void DoExecute(Args &args, CommandReturnObject &result) override {
486 Stream &strm = result.GetOutputStream();
487
488 bool show_stopped_process_status = false;
489 if (DumpTargetList(GetDebugger().GetTargetList(),
490 show_stopped_process_status, strm) == 0) {
491 strm.PutCString("No targets.\n");
492 }
494 }
495};
496
497#pragma mark CommandObjectTargetGroups
498
499static llvm::StringRef GetTargetGroupRoleName(TargetGroup::Role role) {
500 switch (role) {
502 return "CPU";
504 return "accelerator";
505 }
506 llvm_unreachable("unhandled target group role");
507}
508
510public:
512 : CommandObjectParsed(interpreter, "target groups list",
513 "List all target groups and their members.",
514 nullptr),
515 m_target_option(LLDB_OPT_SET_1, false, "target", 't', 0,
517 "List only groups containing this target.", 0) {
519 m_option_group.Finalize();
521 }
522
523 ~CommandObjectTargetGroupsList() override = default;
524
525 Options *GetOptions() override { return &m_option_group; }
526
527protected:
528 void DoExecute(Args &args, CommandReturnObject &result) override {
529 Debugger &debugger = GetDebugger();
530 TargetGroupList &group_list = debugger.GetTargetGroupList();
531 std::vector<TargetGroupSP> groups = group_list.GetGroups();
532
533 std::vector<size_t> group_indexes;
534 if (args.empty()) {
535 group_indexes.resize(groups.size());
536 std::iota(group_indexes.begin(), group_indexes.end(), 0);
537 } else {
538 group_indexes.reserve(args.size());
539 for (size_t i = 0; i < args.size(); ++i) {
540 uint64_t group_index;
541 llvm::StringRef argument = args.GetArgumentAtIndex(i);
542 if (!llvm::to_integer(argument, group_index)) {
543 result.AppendErrorWithFormatv("invalid group index '{0}'", argument);
544 return;
545 }
546 if (group_index >= groups.size()) {
547 result.AppendErrorWithFormatv("group index {0} is out of range",
548 group_index);
549 return;
550 }
551 group_indexes.push_back(static_cast<size_t>(group_index));
552 }
553 }
554
555 TargetSP target_filter_sp;
556 if (m_target_option.GetOptionValue().OptionWasSet()) {
557 uint64_t target_index =
558 m_target_option.GetOptionValue().GetCurrentValue();
559 if (target_index >= LLDB_INVALID_INDEX32 ||
560 !(target_filter_sp = debugger.GetTargetList().GetTargetAtIndex(
561 static_cast<uint32_t>(target_index)))) {
562 result.AppendErrorWithFormatv("target index {0} is out of range",
563 target_index);
564 return;
565 }
566 }
567
568 Stream &strm = result.GetOutputStream();
569 if (groups.empty()) {
570 strm.PutCString("No target groups.\n");
572 return;
573 }
574
575 TargetList &target_list = debugger.GetTargetList();
576 bool listed_group = false;
577 for (size_t group_index : group_indexes) {
578 const TargetGroupSP &group_sp = groups[group_index];
579 if (target_filter_sp && !group_sp->GetRole(target_filter_sp))
580 continue;
581
582 listed_group = true;
583 strm.Format("group #{0}", group_index);
584 if (!group_sp->GetDescription().empty())
585 strm.Format(": {0}", group_sp->GetDescription());
586 strm.EOL();
587
588 for (const TargetSP &target_sp : group_sp->GetTargets()) {
589 std::optional<TargetGroup::Role> role = group_sp->GetRole(target_sp);
590 if (!role)
591 continue;
592 uint32_t target_index = target_list.GetIndexOfTarget(target_sp);
593 if (target_index == LLDB_INVALID_INDEX32)
594 strm.Format(" unlisted target: {0}\n",
596 else
597 strm.Format(" target #{0}: {1}\n", target_index,
599 }
600 }
601 if (!listed_group)
602 strm.PutCString("No matching target groups.\n");
604 }
605
606private:
609};
610
612public:
614 : CommandObjectMultiword(interpreter, "target groups",
615 "Commands for viewing target groups.",
616 "target groups <subcommand>") {
618 new CommandObjectTargetGroupsList(interpreter)));
619 }
620
621 ~CommandObjectTargetGroups() override = default;
622};
623
624#pragma mark CommandObjectTargetSelect
625
627public:
630 interpreter, "target select",
631 "Select a target as the current target by target index.", nullptr) {
633 }
634
635 ~CommandObjectTargetSelect() override = default;
636
637protected:
638 void DoExecute(Args &args, CommandReturnObject &result) override {
639 if (args.GetArgumentCount() == 1) {
640 const char *target_identifier = args.GetArgumentAtIndex(0);
641 uint32_t target_idx = LLDB_INVALID_INDEX32;
642 TargetList &target_list = GetDebugger().GetTargetList();
643 const uint32_t num_targets = target_list.GetNumTargets();
644 if (llvm::to_integer(target_identifier, target_idx)) {
645 if (target_idx < num_targets) {
646 target_list.SetSelectedTarget(target_idx);
647 Stream &strm = result.GetOutputStream();
648 bool show_stopped_process_status = false;
649 DumpTargetList(target_list, show_stopped_process_status, strm);
651 } else {
652 if (num_targets > 0) {
654 "index %u is out of range, valid target indexes are 0 - %u",
655 target_idx, num_targets - 1);
656 } else {
658 "index %u is out of range since there are no active targets",
659 target_idx);
660 }
661 }
662 } else {
663 for (size_t i = 0; i < num_targets; i++) {
664 if (TargetSP target_sp = target_list.GetTargetAtIndex(i)) {
665 const std::string &label = target_sp->GetLabel();
666 if (!label.empty() && label == target_identifier) {
667 target_idx = i;
668 break;
669 }
670 }
671 }
672
673 if (target_idx != LLDB_INVALID_INDEX32) {
674 target_list.SetSelectedTarget(target_idx);
675 Stream &strm = result.GetOutputStream();
676 bool show_stopped_process_status = false;
677 DumpTargetList(target_list, show_stopped_process_status, strm);
679 } else {
680 result.AppendErrorWithFormat("invalid index string value '%s'",
681 target_identifier);
682 }
683 }
684 } else {
685 result.AppendError(
686 "'target select' takes a single argument: a target index\n");
687 }
688 }
689};
690
691#pragma mark CommandObjectTargetDelete
692
694public:
696 : CommandObjectParsed(interpreter, "target delete",
697 "Delete one or more targets by target index.",
698 nullptr),
699 m_all_option(LLDB_OPT_SET_1, false, "all", 'a', "Delete all targets.",
700 false, true),
702 LLDB_OPT_SET_1, false, "clean", 'c',
703 "Perform extra cleanup to minimize memory consumption after "
704 "deleting the target. "
705 "By default, LLDB will keep in memory any modules previously "
706 "loaded by the target as well "
707 "as all of its debug info. Specifying --clean will unload all of "
708 "these shared modules and "
709 "cause them to be reparsed again the next time the target is run",
710 false, true) {
713 m_option_group.Finalize();
715 }
716
717 ~CommandObjectTargetDelete() override = default;
718
719 Options *GetOptions() override { return &m_option_group; }
720
721protected:
722 void DoExecute(Args &args, CommandReturnObject &result) override {
723 const size_t argc = args.GetArgumentCount();
724 std::vector<TargetSP> delete_target_list;
725 TargetList &target_list = GetDebugger().GetTargetList();
726 TargetSP target_sp;
727
728 if (m_all_option.GetOptionValue()) {
729 for (size_t i = 0; i < target_list.GetNumTargets(); ++i)
730 delete_target_list.push_back(target_list.GetTargetAtIndex(i));
731 } else if (argc > 0) {
732 const uint32_t num_targets = target_list.GetNumTargets();
733 // Bail out if don't have any targets.
734 if (num_targets == 0) {
735 result.AppendError("no targets to delete");
736 return;
737 }
738
739 for (auto &entry : args.entries()) {
740 uint32_t target_idx;
741 if (entry.ref().getAsInteger(0, target_idx)) {
742 result.AppendErrorWithFormat("invalid target index '%s'",
743 entry.c_str());
744 return;
745 }
746 if (target_idx < num_targets) {
747 target_sp = target_list.GetTargetAtIndex(target_idx);
748 if (target_sp) {
749 delete_target_list.push_back(target_sp);
750 continue;
751 }
752 }
753 if (num_targets > 1)
754 result.AppendErrorWithFormat("target index %u is out of range, valid "
755 "target indexes are 0 - %u",
756 target_idx, num_targets - 1);
757 else
759 "target index %u is out of range, the only valid index is 0",
760 target_idx);
761
762 return;
763 }
764 } else {
765 target_sp = target_list.GetSelectedTarget();
766 if (!target_sp) {
767 result.AppendErrorWithFormat("no target is currently selected");
768 return;
769 }
770 delete_target_list.push_back(target_sp);
771 }
772
773 const size_t num_targets_to_delete = delete_target_list.size();
774 for (size_t idx = 0; idx < num_targets_to_delete; ++idx) {
775 target_sp = delete_target_list[idx];
776 target_list.DeleteTarget(target_sp);
777 target_sp->Destroy();
778 }
779 // If "--clean" was specified, prune any orphaned shared modules from the
780 // global shared module list
781 if (m_cleanup_option.GetOptionValue()) {
782 const bool mandatory = true;
784 }
785 result.GetOutputStream().Printf("%u targets deleted.\n",
786 (uint32_t)num_targets_to_delete);
788 }
789
793};
794
796public:
799 interpreter, "target show-launch-environment",
800 "Shows the environment being passed to the process when launched, "
801 "taking info account 3 settings: target.env-vars, "
802 "target.inherit-env and target.unset-env-vars.",
803 nullptr, eCommandRequiresTarget) {}
804
806
807protected:
808 void DoExecute(Args &args, CommandReturnObject &result) override {
809 Target *target = m_exe_ctx.GetTargetPtr();
810 Environment env = target->GetEnvironment();
811
812 std::vector<Environment::value_type *> env_vector;
813 env_vector.reserve(env.size());
814 for (auto &KV : env)
815 env_vector.push_back(&KV);
816 std::sort(env_vector.begin(), env_vector.end(),
817 [](Environment::value_type *a, Environment::value_type *b) {
818 return a->first() < b->first();
819 });
820
821 auto &strm = result.GetOutputStream();
822 for (auto &KV : env_vector)
823 strm.Format("{0}={1}\n", KV->first(), KV->second);
824
826 }
827};
828
829#pragma mark CommandObjectTargetVariable
830
832 static const uint32_t SHORT_OPTION_FILE = 0x66696c65; // 'file'
833 static const uint32_t SHORT_OPTION_SHLB = 0x73686c62; // 'shlb'
834
835public:
837 : CommandObjectParsed(interpreter, "target variable",
838 "Read global variables for the current target, "
839 "before or while running a process.",
840 nullptr, eCommandRequiresTarget),
841 m_option_variable(false), // Don't include frame options
845 "A basename or fullpath to a file that contains "
846 "global variables. This option can be "
847 "specified multiple times."),
849 LLDB_OPT_SET_1, false, "shlib", SHORT_OPTION_SHLB, 0,
851 "A basename or fullpath to a shared library to use in the search "
852 "for global "
853 "variables. This option can be specified multiple times.") {
855
866 m_option_group.Finalize();
867 }
868
869 ~CommandObjectTargetVariable() override = default;
870
871 void DumpValueObject(Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp,
872 const char *root_name) {
873 DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions());
874
875 if (!valobj_sp->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
876 valobj_sp->IsRuntimeSupportValue())
877 return;
878
879 switch (var_sp->GetScope()) {
881 if (m_option_variable.show_scope)
882 s.PutCString("GLOBAL: ");
883 break;
884
886 if (m_option_variable.show_scope)
887 s.PutCString("STATIC: ");
888 break;
889
891 if (m_option_variable.show_scope)
892 s.PutCString(" ARG: ");
893 break;
894
896 if (m_option_variable.show_scope)
897 s.PutCString(" LOCAL: ");
898 break;
899
901 if (m_option_variable.show_scope)
902 s.PutCString("THREAD: ");
903 break;
904
905 default:
906 break;
907 }
908
909 if (m_option_variable.show_decl) {
910 bool show_fullpaths = false;
911 bool show_module = true;
912 if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
913 s.PutCString(": ");
914 }
915
916 const Format format = m_option_format.GetFormat();
917 if (format != eFormatDefault)
918 options.SetFormat(format);
919
920 options.SetRootValueObjectName(root_name);
921
922 if (llvm::Error error = valobj_sp->Dump(s, options))
923 s << "error: " << toString(std::move(error));
924 }
925
926 static size_t GetVariableCallback(void *baton, const char *name,
927 VariableList &variable_list) {
928 size_t old_size = variable_list.GetSize();
929 Target *target = static_cast<Target *>(baton);
930 if (target)
932 variable_list);
933 return variable_list.GetSize() - old_size;
934 }
935
936 Options *GetOptions() override { return &m_option_group; }
937
938protected:
940 const SymbolContext &sc,
941 const VariableList &variable_list,
942 CommandReturnObject &result) {
943 Stream &s = result.GetOutputStream();
944 if (variable_list.Empty())
945 return;
946 if (sc.module_sp) {
947 if (sc.comp_unit) {
948 s.Format("Global variables for {0} in {1}:\n",
949 sc.comp_unit->GetPrimaryFile(), sc.module_sp->GetFileSpec());
950 } else {
951 s.Printf("Global variables for %s\n",
952 sc.module_sp->GetFileSpec().GetPath().c_str());
953 }
954 } else if (sc.comp_unit) {
955 s.Format("Global variables for {0}\n", sc.comp_unit->GetPrimaryFile());
956 }
957
958 for (VariableSP var_sp : variable_list) {
959 if (!var_sp)
960 continue;
962 exe_ctx.GetBestExecutionContextScope(), var_sp));
963
964 if (valobj_sp) {
965 result.GetValueObjectList().Append(valobj_sp);
966 DumpValueObject(s, var_sp, valobj_sp, var_sp->GetName().GetCString());
967 }
968 }
969 }
970
971 void DoExecute(Args &args, CommandReturnObject &result) override {
972 Target *target = m_exe_ctx.GetTargetPtr();
973 const size_t argc = args.GetArgumentCount();
974
975 if (argc > 0) {
976 for (const Args::ArgEntry &arg : args) {
977 VariableList variable_list;
978 ValueObjectList valobj_list;
979
980 size_t matches = 0;
981 bool use_var_name = false;
982 if (m_option_variable.use_regex) {
983 RegularExpression regex(arg.ref());
984 if (!regex.IsValid()) {
985 result.GetErrorStream().Printf(
986 "error: invalid regular expression: '%s'\n", arg.c_str());
987 return;
988 }
989 use_var_name = true;
991 variable_list);
992 matches = variable_list.GetSize();
993 } else {
995 arg.c_str(), m_exe_ctx.GetBestExecutionContextScope(),
996 GetVariableCallback, target, variable_list, valobj_list));
997 matches = variable_list.GetSize();
998 }
999
1000 if (matches == 0) {
1001 result.AppendErrorWithFormat("can't find global variable '%s'",
1002 arg.c_str());
1003 return;
1004 } else {
1005 for (uint32_t global_idx = 0; global_idx < matches; ++global_idx) {
1006 VariableSP var_sp(variable_list.GetVariableAtIndex(global_idx));
1007 if (var_sp) {
1008 ValueObjectSP valobj_sp(
1009 valobj_list.GetValueObjectAtIndex(global_idx));
1010 if (!valobj_sp)
1011 valobj_sp = ValueObjectVariable::Create(
1012 m_exe_ctx.GetBestExecutionContextScope(), var_sp);
1013
1014 if (valobj_sp)
1015 DumpValueObject(result.GetOutputStream(), var_sp, valobj_sp,
1016 use_var_name ? var_sp->GetName().GetCString()
1017 : arg.c_str());
1018 }
1019 }
1020 }
1021 }
1022 } else {
1023 const FileSpecList &compile_units =
1024 m_option_compile_units.GetOptionValue().GetCurrentValue();
1025 const FileSpecList &shlibs =
1026 m_option_shared_libraries.GetOptionValue().GetCurrentValue();
1027 SymbolContextList sc_list;
1028 const size_t num_compile_units = compile_units.GetSize();
1029 const size_t num_shlibs = shlibs.GetSize();
1030 if (num_compile_units == 0 && num_shlibs == 0) {
1031 bool success = false;
1032 StackFrame *frame = m_exe_ctx.GetFramePtr();
1033 CompileUnit *comp_unit = nullptr;
1034 if (frame) {
1035 SymbolContext sc = frame->GetSymbolContext(eSymbolContextCompUnit);
1036 comp_unit = sc.comp_unit;
1037 if (sc.comp_unit) {
1038 const bool can_create = true;
1039 VariableListSP comp_unit_varlist_sp(
1040 sc.comp_unit->GetVariableList(can_create));
1041 if (comp_unit_varlist_sp) {
1042 size_t count = comp_unit_varlist_sp->GetSize();
1043 if (count > 0) {
1044 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp,
1045 result);
1046 success = true;
1047 }
1048 }
1049 }
1050 }
1051 if (!success) {
1052 if (frame) {
1053 if (comp_unit)
1055 "no global variables in current compile unit: {0}\n",
1056 comp_unit->GetPrimaryFile());
1057 else
1058 result.AppendErrorWithFormat("no debug information for frame %u",
1059 frame->GetFrameIndex());
1060 } else
1061 result.AppendError("'target variable' takes one or more global "
1062 "variable names as arguments\n");
1063 }
1064 } else {
1065 SymbolContextList sc_list;
1066 // We have one or more compile unit or shlib
1067 if (num_shlibs > 0) {
1068 for (size_t shlib_idx = 0; shlib_idx < num_shlibs; ++shlib_idx) {
1069 const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx));
1070 ModuleSpec module_spec(module_file);
1071
1072 ModuleSP module_sp(
1073 target->GetImages().FindFirstModule(module_spec));
1074 if (module_sp) {
1075 if (num_compile_units > 0) {
1076 for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
1077 module_sp->FindCompileUnits(
1078 compile_units.GetFileSpecAtIndex(cu_idx), sc_list);
1079 } else {
1080 SymbolContext sc;
1081 sc.module_sp = module_sp;
1082 sc_list.Append(sc);
1083 }
1084 } else {
1085 // Didn't find matching shlib/module in target...
1086 result.AppendErrorWithFormat(
1087 "target doesn't contain the specified shared library: %s",
1088 module_file.GetPath().c_str());
1089 }
1090 }
1091 } else {
1092 // No shared libraries, we just want to find globals for the compile
1093 // units files that were specified
1094 for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
1095 target->GetImages().FindCompileUnits(
1096 compile_units.GetFileSpecAtIndex(cu_idx), sc_list);
1097 }
1098
1099 for (const SymbolContext &sc : sc_list) {
1100 if (sc.comp_unit) {
1101 const bool can_create = true;
1102 VariableListSP comp_unit_varlist_sp(
1103 sc.comp_unit->GetVariableList(can_create));
1104 if (comp_unit_varlist_sp)
1105 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp,
1106 result);
1107 } else if (sc.module_sp) {
1108 // Get all global variables for this module
1109 lldb_private::RegularExpression all_globals_regex(
1110 llvm::StringRef(".")); // Any global with at least one character
1111 VariableList variable_list;
1112 sc.module_sp->FindGlobalVariables(all_globals_regex, UINT32_MAX,
1113 variable_list);
1114 DumpGlobalVariableList(m_exe_ctx, sc, variable_list, result);
1115 }
1116 }
1117 }
1118 }
1119
1120 m_interpreter.PrintWarningsIfNecessary(result.GetOutputStream(),
1121 m_cmd_name);
1122 if (result.GetStatus() != eReturnStatusFailed)
1124 }
1125
1132};
1133
1134#pragma mark CommandObjectTargetModulesSearchPathsAdd
1135
1137public:
1139 : CommandObjectParsed(interpreter, "target modules search-paths add",
1140 "Add new image search paths substitution pairs to "
1141 "the current target.",
1142 nullptr, eCommandRequiresTarget) {
1144 CommandArgumentData old_prefix_arg;
1145 CommandArgumentData new_prefix_arg;
1146
1147 // Define the first variant of this arg pair.
1148 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1149 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1150
1151 // Define the first variant of this arg pair.
1152 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1153 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1154
1155 // There are two required arguments that must always occur together, i.e.
1156 // an argument "pair". Because they must always occur together, they are
1157 // treated as two variants of one argument rather than two independent
1158 // arguments. Push them both into the first argument position for
1159 // m_arguments...
1160
1161 arg.push_back(old_prefix_arg);
1162 arg.push_back(new_prefix_arg);
1163
1164 m_arguments.push_back(arg);
1165 }
1166
1168
1169protected:
1170 void DoExecute(Args &command, CommandReturnObject &result) override {
1171 Target *target = GetTarget();
1172 assert(target && "target guaranteed by eCommandRequiresTarget");
1173 const size_t argc = command.GetArgumentCount();
1174 if (argc & 1) {
1175 result.AppendError("add requires an even number of arguments\n");
1176 } else {
1177 for (size_t i = 0; i < argc; i += 2) {
1178 const char *from = command.GetArgumentAtIndex(i);
1179 const char *to = command.GetArgumentAtIndex(i + 1);
1180
1181 if (from[0] && to[0]) {
1183 "target modules search path adding ImageSearchPath "
1184 "pair: '%s' -> '%s'",
1185 from, to);
1186 bool last_pair = ((argc - i) == 2);
1188 from, to, last_pair); // Notify if this is the last pair
1190 } else {
1191 if (from[0])
1192 result.AppendError("<path-prefix> can't be empty\n");
1193 else
1194 result.AppendError("<new-path-prefix> can't be empty\n");
1195 }
1196 }
1197 }
1198 }
1199};
1200
1201#pragma mark CommandObjectTargetModulesSearchPathsClear
1202
1204public:
1206 : CommandObjectParsed(interpreter, "target modules search-paths clear",
1207 "Clear all current image search path substitution "
1208 "pairs from the current target.",
1209 "target modules search-paths clear",
1210 eCommandRequiresTarget) {}
1211
1213
1214protected:
1215 void DoExecute(Args &command, CommandReturnObject &result) override {
1216 Target *target = GetTarget();
1217 assert(target && "target guaranteed by eCommandRequiresTarget");
1218 bool notify = true;
1219 target->GetImageSearchPathList().Clear(notify);
1221 }
1222};
1223
1224#pragma mark CommandObjectTargetModulesSearchPathsInsert
1225
1227public:
1229 : CommandObjectParsed(interpreter, "target modules search-paths insert",
1230 "Insert a new image search path substitution pair "
1231 "into the current target at the specified index.",
1232 nullptr, eCommandRequiresTarget) {
1235 CommandArgumentData index_arg;
1236 CommandArgumentData old_prefix_arg;
1237 CommandArgumentData new_prefix_arg;
1238
1239 // Define the first and only variant of this arg.
1240 index_arg.arg_type = eArgTypeIndex;
1241 index_arg.arg_repetition = eArgRepeatPlain;
1242
1243 // Put the one and only variant into the first arg for m_arguments:
1244 arg1.push_back(index_arg);
1245
1246 // Define the first variant of this arg pair.
1247 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1248 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1249
1250 // Define the first variant of this arg pair.
1251 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1252 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1253
1254 // There are two required arguments that must always occur together, i.e.
1255 // an argument "pair". Because they must always occur together, they are
1256 // treated as two variants of one argument rather than two independent
1257 // arguments. Push them both into the same argument position for
1258 // m_arguments...
1259
1260 arg2.push_back(old_prefix_arg);
1261 arg2.push_back(new_prefix_arg);
1262
1263 // Add arguments to m_arguments.
1264 m_arguments.push_back(arg1);
1265 m_arguments.push_back(arg2);
1266 }
1267
1269
1270 void
1272 OptionElementVector &opt_element_vector) override {
1273 if (!m_exe_ctx.HasTargetScope() || request.GetCursorIndex() != 0)
1274 return;
1275
1276 Target *target = m_exe_ctx.GetTargetPtr();
1277
1278 const PathMappingList &list = target->GetImageSearchPathList();
1279 const size_t num = list.GetSize();
1280 std::string old_path, new_path;
1281 for (size_t i = 0; i < num; ++i) {
1282 if (!list.GetPathsAtIndex(i, old_path, new_path))
1283 break;
1284 StreamString strm;
1285 strm << old_path << " -> " << new_path;
1286 request.TryCompleteCurrentArg(std::to_string(i), strm.GetString());
1287 }
1288 }
1289
1290protected:
1291 void DoExecute(Args &command, CommandReturnObject &result) override {
1292 Target *target = GetTarget();
1293 assert(target && "target guaranteed by eCommandRequiresTarget");
1294 size_t argc = command.GetArgumentCount();
1295 // check for at least 3 arguments and an odd number of parameters
1296 if (argc >= 3 && argc & 1) {
1297 uint32_t insert_idx;
1298
1299 if (!llvm::to_integer(command.GetArgumentAtIndex(0), insert_idx)) {
1300 result.AppendErrorWithFormat(
1301 "<index> parameter is not an integer: '%s'",
1302 command.GetArgumentAtIndex(0));
1303 return;
1304 }
1305
1306 // shift off the index
1307 command.Shift();
1308 argc = command.GetArgumentCount();
1309
1310 for (uint32_t i = 0; i < argc; i += 2, ++insert_idx) {
1311 const char *from = command.GetArgumentAtIndex(i);
1312 const char *to = command.GetArgumentAtIndex(i + 1);
1313
1314 if (from[0] && to[0]) {
1315 bool last_pair = ((argc - i) == 2);
1316 target->GetImageSearchPathList().Insert(from, to, insert_idx,
1317 last_pair);
1319 } else {
1320 if (from[0])
1321 result.AppendError("<path-prefix> can't be empty\n");
1322 else
1323 result.AppendError("<new-path-prefix> can't be empty\n");
1324 return;
1325 }
1326 }
1327 } else {
1328 result.AppendError("insert requires at least three arguments\n");
1329 }
1330 }
1331};
1332
1333#pragma mark CommandObjectTargetModulesSearchPathsList
1334
1336public:
1338 : CommandObjectParsed(interpreter, "target modules search-paths list",
1339 "List all current image search path substitution "
1340 "pairs in the current target.",
1341 "target modules search-paths list",
1342 eCommandRequiresTarget) {}
1343
1345
1346protected:
1347 void DoExecute(Args &command, CommandReturnObject &result) override {
1348 Target *target = GetTarget();
1349 assert(target && "target guaranteed by eCommandRequiresTarget");
1350 target->GetImageSearchPathList().Dump(&result.GetOutputStream());
1352 }
1353};
1354
1355#pragma mark CommandObjectTargetModulesSearchPathsQuery
1356
1358public:
1361 interpreter, "target modules search-paths query",
1362 "Transform a path using the first applicable image search path.",
1363 nullptr, eCommandRequiresTarget) {
1365 }
1366
1368
1369protected:
1370 void DoExecute(Args &command, CommandReturnObject &result) override {
1371 Target *target = GetTarget();
1372 assert(target && "target guaranteed by eCommandRequiresTarget");
1373 if (command.GetArgumentCount() != 1) {
1374 result.AppendError("query requires one argument\n");
1375 return;
1376 }
1377
1378 llvm::StringRef orig(command.GetArgumentAtIndex(0));
1379 std::string transformed;
1380 if (target->GetImageSearchPathList().RemapPath(orig, transformed))
1381 result.GetOutputStream().Format("{0}\n", transformed);
1382 else
1383 result.GetOutputStream().Format("{0}\n", orig);
1384
1386 }
1387};
1388
1389// Static Helper functions
1390static void DumpModuleArchitecture(Stream &strm, Module *module,
1391 bool full_triple, uint32_t width) {
1392 if (module) {
1393 StreamString arch_strm;
1394
1395 if (full_triple)
1396 module->GetArchitecture().DumpTriple(arch_strm.AsRawOstream());
1397 else
1398 arch_strm.PutCString(module->GetArchitecture().GetArchitectureName());
1399 std::string arch_str = std::string(arch_strm.GetString());
1400
1401 if (width)
1402 strm.Printf("%-*s", width, arch_str.c_str());
1403 else
1404 strm.PutCString(arch_str);
1405 }
1406}
1407
1408static void DumpModuleUUID(Stream &strm, Module *module) {
1409 if (module && module->GetUUID().IsValid())
1410 module->GetUUID().Dump(strm);
1411 else
1412 strm.PutCString(" ");
1413}
1414
1416 Stream &strm, Module *module,
1417 const FileSpec &file_spec,
1418 lldb::DescriptionLevel desc_level) {
1419 uint32_t num_matches = 0;
1420 if (module) {
1421 SymbolContextList sc_list;
1422 num_matches = module->ResolveSymbolContextsForFileSpec(
1423 file_spec, 0, false, eSymbolContextCompUnit, sc_list);
1424
1425 bool first_module = true;
1426 for (const SymbolContext &sc : sc_list) {
1427 if (!first_module)
1428 strm << "\n\n";
1429
1430 strm << "Line table for " << sc.comp_unit->GetPrimaryFile() << " in `"
1431 << module->GetFileSpec().GetFilename() << "\n";
1432 LineTable *line_table = sc.comp_unit->GetLineTable();
1433 if (line_table)
1434 line_table->GetDescription(
1435 &strm, interpreter.GetExecutionContext().GetTargetPtr(),
1436 desc_level);
1437 else
1438 strm << "No line table";
1439
1440 first_module = false;
1441 }
1442 }
1443 return num_matches;
1444}
1445
1446static void DumpFullpath(Stream &strm, const FileSpec *file_spec_ptr,
1447 uint32_t width) {
1448 if (file_spec_ptr) {
1449 if (width > 0) {
1450 std::string fullpath = file_spec_ptr->GetPath();
1451 strm.Printf("%-*s", width, fullpath.c_str());
1452 return;
1453 } else {
1454 file_spec_ptr->Dump(strm.AsRawOstream());
1455 return;
1456 }
1457 }
1458 // Keep the width spacing correct if things go wrong...
1459 if (width > 0)
1460 strm.Printf("%-*s", width, "");
1461}
1462
1463static void DumpDirectory(Stream &strm, const FileSpec *file_spec_ptr,
1464 uint32_t width) {
1465 if (file_spec_ptr) {
1466 if (width > 0)
1467 strm.Format("{0}", fmt_align(file_spec_ptr->GetDirectory(),
1468 llvm::AlignStyle::Left, width));
1469 else
1470 strm.PutCString(file_spec_ptr->GetDirectory());
1471 return;
1472 }
1473 // Keep the width spacing correct if things go wrong...
1474 if (width > 0)
1475 strm.Printf("%-*s", width, "");
1476}
1477
1478static void DumpBasename(Stream &strm, const FileSpec *file_spec_ptr,
1479 uint32_t width) {
1480 if (file_spec_ptr) {
1481 if (width > 0)
1482 strm.Format("{0}", fmt_align(file_spec_ptr->GetFilename(),
1483 llvm::AlignStyle::Left, width));
1484 else
1485 strm.PutCString(file_spec_ptr->GetFilename());
1486 return;
1487 }
1488 // Keep the width spacing correct if things go wrong...
1489 if (width > 0)
1490 strm.Printf("%-*s", width, "");
1491}
1492
1493static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) {
1494 std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
1495 const size_t num_modules = module_list.GetSize();
1496 if (num_modules == 0)
1497 return 0;
1498
1499 size_t num_dumped = 0;
1500 strm.Format("Dumping headers for {0} module(s).\n", num_modules);
1501 strm.IndentMore();
1502 for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
1503 if (module_sp) {
1504 if (num_dumped++ > 0) {
1505 strm.EOL();
1506 strm.EOL();
1507 }
1508 ObjectFile *objfile = module_sp->GetObjectFile();
1509 if (objfile)
1510 objfile->Dump(&strm);
1511 else {
1512 strm.Format("No object file for module: {0:F}\n",
1513 module_sp->GetFileSpec());
1514 }
1515 }
1516 }
1517 strm.IndentLess();
1518 return num_dumped;
1519}
1520
1521static void DumpModuleSymtab(CommandInterpreter &interpreter, Stream &strm,
1522 Module *module, SortOrder sort_order,
1523 Mangled::NamePreference name_preference) {
1524 if (!module)
1525 return;
1526 if (Symtab *symtab = module->GetSymtab())
1527 symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(),
1528 sort_order, name_preference);
1529}
1530
1531static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm,
1532 Module *module) {
1533 if (module) {
1534 SectionList *section_list = module->GetSectionList();
1535 if (section_list) {
1536 strm.Printf("Sections for '%s' (%s):\n",
1537 module->GetSpecificationDescription().c_str(),
1539 section_list->Dump(strm.AsRawOstream(), strm.GetIndentLevel() + 2,
1540 interpreter.GetExecutionContext().GetTargetPtr(), true,
1541 UINT32_MAX);
1542 }
1543 }
1544}
1545
1546static bool DumpModuleSymbolFile(Stream &strm, Module *module) {
1547 if (module) {
1548 if (SymbolFile *symbol_file = module->GetSymbolFile(true)) {
1549 symbol_file->Dump(strm);
1550 return true;
1551 }
1552 }
1553 return false;
1554}
1555
1557 Module *module, bool errors_only,
1558 bool load_all_debug_info) {
1559 if (module) {
1560 if (SymbolFile *symbol_file = module->GetSymbolFile(/*can_create=*/true)) {
1562 if (symbol_file->GetSeparateDebugInfo(d, errors_only,
1563 load_all_debug_info)) {
1564 list.AddItem(
1565 std::make_shared<StructuredData::Dictionary>(std::move(d)));
1566 return true;
1567 }
1568 }
1569 }
1570 return false;
1571}
1572
1573static void DumpDwoFilesTable(Stream &strm,
1574 StructuredData::Array &dwo_listings) {
1575 strm.PutCString("Dwo ID Err Dwo Path");
1576 strm.EOL();
1577 strm.PutCString(
1578 "------------------ --- -----------------------------------------");
1579 strm.EOL();
1580 dwo_listings.ForEach([&strm](StructuredData::Object *dwo) {
1582 if (!dict)
1583 return false;
1584
1585 uint64_t dwo_id;
1586 if (dict->GetValueForKeyAsInteger("dwo_id", dwo_id))
1587 strm.Printf("0x%16.16" PRIx64 " ", dwo_id);
1588 else
1589 strm.PutCString("0x???????????????? ");
1590
1591 llvm::StringRef error;
1592 if (dict->GetValueForKeyAsString("error", error))
1593 strm << "E " << error;
1594 else {
1595 llvm::StringRef resolved_dwo_path;
1596 if (dict->GetValueForKeyAsString("resolved_dwo_path",
1597 resolved_dwo_path)) {
1598 strm << " " << resolved_dwo_path;
1599 if (resolved_dwo_path.ends_with(".dwp")) {
1600 llvm::StringRef dwo_name;
1601 if (dict->GetValueForKeyAsString("dwo_name", dwo_name))
1602 strm << "(" << dwo_name << ")";
1603 }
1604 }
1605 }
1606 strm.EOL();
1607 return true;
1608 });
1609}
1610
1611static void DumpOsoFilesTable(Stream &strm,
1612 StructuredData::Array &oso_listings) {
1613 strm.PutCString("Mod Time Err Oso Path");
1614 strm.EOL();
1615 strm.PutCString("------------------ --- ---------------------");
1616 strm.EOL();
1617 oso_listings.ForEach([&strm](StructuredData::Object *oso) {
1619 if (!dict)
1620 return false;
1621
1622 uint32_t oso_mod_time;
1623 if (dict->GetValueForKeyAsInteger("oso_mod_time", oso_mod_time))
1624 strm.Printf("0x%16.16" PRIx32 " ", oso_mod_time);
1625
1626 llvm::StringRef error;
1627 if (dict->GetValueForKeyAsString("error", error))
1628 strm << "E " << error;
1629 else {
1630 llvm::StringRef oso_path;
1631 if (dict->GetValueForKeyAsString("oso_path", oso_path))
1632 strm << " " << oso_path;
1633 }
1634 strm.EOL();
1635 return true;
1636 });
1637}
1638
1639static void
1640DumpAddress(ExecutionContextScope *exe_scope, const Address &so_addr,
1641 bool verbose, bool all_ranges, Stream &strm,
1642 std::optional<Stream::HighlightSettings> settings = std::nullopt) {
1643 strm.IndentMore();
1644 strm.Indent(" Address: ");
1645 so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
1646 strm.PutCString(" (");
1647 so_addr.Dump(&strm, exe_scope, Address::DumpStyleSectionNameOffset);
1648 strm.PutCString(")\n");
1649 strm.Indent(" Summary: ");
1650 const uint32_t save_indent = strm.GetIndentLevel();
1651 strm.SetIndentLevel(save_indent + 13);
1652 so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription,
1653 Address::DumpStyleInvalid, UINT32_MAX, false, settings);
1654 strm.SetIndentLevel(save_indent);
1655 // Print out detailed address information when verbose is enabled
1656 if (verbose) {
1657 strm.EOL();
1658 so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext,
1659 Address::DumpStyleInvalid, UINT32_MAX, all_ranges, settings);
1660 }
1661 strm.IndentLess();
1662}
1663
1664static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm,
1665 Module *module, uint32_t resolve_mask,
1666 lldb::addr_t raw_addr, lldb::addr_t offset,
1667 bool verbose, bool all_ranges) {
1668 if (module) {
1669 lldb::addr_t addr = raw_addr - offset;
1670 Address so_addr;
1671 SymbolContext sc;
1672 Target *target = interpreter.GetExecutionContext().GetTargetPtr();
1673 if (target && target->HasLoadedSections()) {
1674 if (!target->ResolveLoadAddress(addr, so_addr))
1675 return false;
1676 else if (so_addr.GetModule().get() != module)
1677 return false;
1678 } else {
1679 if (!module->ResolveFileAddress(addr, so_addr))
1680 return false;
1681 }
1682
1683 ExecutionContextScope *exe_scope =
1685 DumpAddress(exe_scope, so_addr, verbose, all_ranges, strm);
1686 return true;
1687 }
1688
1689 return false;
1690}
1691
1692static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
1693 Stream &strm, Module *module,
1694 const char *name, bool name_is_regex,
1695 bool verbose, bool all_ranges) {
1696 if (!module)
1697 return 0;
1698
1699 Symtab *symtab = module->GetSymtab();
1700 if (!symtab)
1701 return 0;
1702
1703 SymbolContext sc;
1704 const bool use_color = interpreter.GetDebugger().GetUseColor();
1705 std::vector<uint32_t> match_indexes;
1706 ConstString symbol_name(name);
1707 uint32_t num_matches = 0;
1708 if (name_is_regex) {
1709 RegularExpression name_regexp(symbol_name.GetStringRef());
1710 num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType(
1711 name_regexp, eSymbolTypeAny, match_indexes);
1712 } else {
1713 num_matches =
1714 symtab->AppendSymbolIndexesWithName(symbol_name, match_indexes);
1715 }
1716
1717 if (num_matches > 0) {
1718 strm.Indent();
1719 strm.Printf("%u symbols match %s'%s' in ", num_matches,
1720 name_is_regex ? "the regular expression " : "", name);
1721 DumpFullpath(strm, &module->GetFileSpec(), 0);
1722 strm.PutCString(":\n");
1723 strm.IndentMore();
1725 name, interpreter.GetDebugger().GetRegexMatchAnsiPrefix(),
1726 interpreter.GetDebugger().GetRegexMatchAnsiSuffix());
1727 for (uint32_t i = 0; i < num_matches; ++i) {
1728 const Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
1729 if (symbol) {
1730 if (symbol->ValueIsAddress()) {
1733 symbol->GetAddressRef(), verbose, all_ranges, strm,
1734 use_color && name_is_regex
1735 ? std::optional<Stream::HighlightSettings>{settings}
1736 : std::nullopt);
1737 strm.EOL();
1738 } else {
1739 strm.IndentMore();
1740 strm.Indent(" Name: ");
1742 symbol->GetDisplayName().GetStringRef(),
1743 use_color && name_is_regex
1744 ? std::optional<Stream::HighlightSettings>{settings}
1745 : std::nullopt);
1746 strm.EOL();
1747 strm.Indent(" Value: ");
1748 strm.Printf("0x%16.16" PRIx64 "\n", symbol->GetRawValue());
1749 if (symbol->GetByteSizeIsValid()) {
1750 strm.Indent(" Size: ");
1751 strm.Printf("0x%16.16" PRIx64 "\n", symbol->GetByteSize());
1752 }
1753 strm.IndentLess();
1754 }
1755 }
1756 }
1757 strm.IndentLess();
1758 }
1759 return num_matches;
1760}
1761
1763 ExecutionContextScope *exe_scope, Stream &strm,
1764 const SymbolContextList &sc_list, bool verbose, bool all_ranges,
1765 std::optional<Stream::HighlightSettings> settings = std::nullopt) {
1766 strm.IndentMore();
1767 bool first_module = true;
1768 for (const SymbolContext &sc : sc_list) {
1769 if (!first_module)
1770 strm.EOL();
1771
1772 Address addr;
1773 if (sc.line_entry.IsValid())
1774 addr = sc.line_entry.range.GetBaseAddress();
1775 else if (sc.block && sc.block->GetContainingInlinedBlock())
1776 sc.block->GetContainingInlinedBlock()->GetStartAddress(addr);
1777 else
1778 addr = sc.GetFunctionOrSymbolAddress();
1779
1780 DumpAddress(exe_scope, addr, verbose, all_ranges, strm, settings);
1781 first_module = false;
1782 }
1783 strm.IndentLess();
1784}
1785
1787 Stream &strm, Module *module,
1788 const char *name, bool name_is_regex,
1789 const ModuleFunctionSearchOptions &options,
1790 bool verbose, bool all_ranges) {
1791 if (module && name && name[0]) {
1792 SymbolContextList sc_list;
1793 size_t num_matches = 0;
1794 if (name_is_regex) {
1795 RegularExpression function_name_regex((llvm::StringRef(name)));
1796 module->FindFunctions(function_name_regex, options, sc_list);
1797 } else {
1798 ConstString function_name(name);
1799 module->FindFunctions(function_name, CompilerDeclContext(),
1800 eFunctionNameTypeAuto, options, sc_list);
1801 }
1802 num_matches = sc_list.GetSize();
1803 if (num_matches) {
1804 strm.Indent();
1805 strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
1806 num_matches > 1 ? "es" : "");
1807 DumpFullpath(strm, &module->GetFileSpec(), 0);
1808 strm.PutCString(":\n");
1811 strm, sc_list, verbose, all_ranges);
1812 }
1813 return num_matches;
1814 }
1815 return 0;
1816}
1817
1818static size_t LookupTypeInModule(Target *target,
1819 CommandInterpreter &interpreter, Stream &strm,
1820 Module *module, const char *name_cstr,
1821 bool name_is_regex) {
1822 if (module && name_cstr && name_cstr[0]) {
1823 TypeQuery query(name_cstr);
1824 TypeResults results;
1825 module->FindTypes(query, results);
1826
1827 TypeList type_list;
1828 SymbolContext sc;
1829 if (module)
1830 sc.module_sp = module->shared_from_this();
1831 // Sort the type results and put the results that matched in \a module
1832 // first if \a module was specified.
1833 sc.SortTypeList(results.GetTypeMap(), type_list);
1834 if (type_list.Empty())
1835 return 0;
1836
1837 const uint64_t num_matches = type_list.GetSize();
1838
1839 strm.Indent();
1840 strm.Printf("%" PRIu64 " match%s found in ", num_matches,
1841 num_matches > 1 ? "es" : "");
1842 DumpFullpath(strm, &module->GetFileSpec(), 0);
1843 strm.PutCString(":\n");
1844 for (TypeSP type_sp : type_list.Types()) {
1845 if (!type_sp)
1846 continue;
1847 // Resolve the clang type so that any forward references to types
1848 // that haven't yet been parsed will get parsed.
1849 type_sp->GetFullCompilerType();
1850 type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target);
1851 // Print all typedef chains
1852 TypeSP typedef_type_sp(type_sp);
1853 TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1854 while (typedefed_type_sp) {
1855 strm.EOL();
1856 strm.Printf(" typedef '%s': ",
1857 typedef_type_sp->GetName().GetCString());
1858 typedefed_type_sp->GetFullCompilerType();
1859 typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true,
1860 target);
1861 typedef_type_sp = typedefed_type_sp;
1862 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1863 }
1864 strm.EOL();
1865 }
1866 return type_list.GetSize();
1867 }
1868 return 0;
1869}
1870
1871static size_t LookupTypeHere(Target *target, CommandInterpreter &interpreter,
1872 Stream &strm, Module &module,
1873 const char *name_cstr, bool name_is_regex) {
1874 TypeQuery query(name_cstr);
1875 TypeResults results;
1876 module.FindTypes(query, results);
1877 TypeList type_list;
1878 SymbolContext sc;
1879 sc.module_sp = module.shared_from_this();
1880 sc.SortTypeList(results.GetTypeMap(), type_list);
1881 if (type_list.Empty())
1882 return 0;
1883
1884 strm.Indent();
1885 strm.PutCString("Best match found in ");
1886 DumpFullpath(strm, &module.GetFileSpec(), 0);
1887 strm.PutCString(":\n");
1888
1889 TypeSP type_sp(type_list.GetTypeAtIndex(0));
1890 if (type_sp) {
1891 // Resolve the clang type so that any forward references to types that
1892 // haven't yet been parsed will get parsed.
1893 type_sp->GetFullCompilerType();
1894 type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target);
1895 // Print all typedef chains.
1896 TypeSP typedef_type_sp(type_sp);
1897 TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1898 while (typedefed_type_sp) {
1899 strm.EOL();
1900 strm.Printf(" typedef '%s': ",
1901 typedef_type_sp->GetName().GetCString());
1902 typedefed_type_sp->GetFullCompilerType();
1903 typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true,
1904 target);
1905 typedef_type_sp = typedefed_type_sp;
1906 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1907 }
1908 }
1909 strm.EOL();
1910 return type_list.GetSize();
1911}
1912
1914 Stream &strm, Module *module,
1915 const FileSpec &file_spec,
1916 uint32_t line, bool check_inlines,
1917 bool verbose, bool all_ranges) {
1918 if (module && file_spec) {
1919 SymbolContextList sc_list;
1920 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(
1921 file_spec, line, check_inlines, eSymbolContextEverything, sc_list);
1922 if (num_matches > 0) {
1923 strm.Indent();
1924 strm.Printf("%u match%s found in ", num_matches,
1925 num_matches > 1 ? "es" : "");
1926 strm << file_spec;
1927 if (line > 0)
1928 strm.Printf(":%u", line);
1929 strm << " in ";
1930 DumpFullpath(strm, &module->GetFileSpec(), 0);
1931 strm.PutCString(":\n");
1934 strm, sc_list, verbose, all_ranges);
1935 return num_matches;
1936 }
1937 }
1938 return 0;
1939}
1940
1941static size_t FindModulesByName(Target *target, const char *module_name,
1942 ModuleList &module_list,
1943 bool check_global_list) {
1944 FileSpec module_file_spec(module_name);
1945 ModuleSpec module_spec(module_file_spec);
1946
1947 const size_t initial_size = module_list.GetSize();
1948
1949 if (check_global_list) {
1950 // Check the global list
1951 std::lock_guard<std::recursive_mutex> guard(
1953 const size_t num_modules = Module::GetNumberAllocatedModules();
1954 ModuleSP module_sp;
1955 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
1956 Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
1957
1958 if (module) {
1959 if (module->MatchesModuleSpec(module_spec)) {
1960 module_sp = module->shared_from_this();
1961 module_list.AppendIfNeeded(module_sp);
1962 }
1963 }
1964 }
1965 } else {
1966 if (target) {
1967 target->GetImages().FindModules(module_spec, module_list);
1968 const size_t num_matches = module_list.GetSize();
1969
1970 // Not found in our module list for our target, check the main shared
1971 // module list in case it is a extra file used somewhere else
1972 if (num_matches == 0) {
1973 module_spec.GetArchitecture() = target->GetArchitecture();
1974 ModuleList::FindSharedModules(module_spec, module_list);
1975 }
1976 } else {
1977 ModuleList::FindSharedModules(module_spec, module_list);
1978 }
1979 }
1980
1981 return module_list.GetSize() - initial_size;
1982}
1983
1984#pragma mark CommandObjectTargetModulesModuleAutoComplete
1985
1986// A base command object class that can auto complete with module file
1987// paths
1988
1990 : public CommandObjectParsed {
1991public:
1993 const char *name,
1994 const char *help,
1995 const char *syntax,
1996 uint32_t flags = 0)
1997 : CommandObjectParsed(interpreter, name, help, syntax, flags) {
1999 }
2000
2002
2003 void
2009};
2010
2011#pragma mark CommandObjectTargetModulesSourceFileAutoComplete
2012
2013// A base command object class that can auto complete with module source
2014// file paths
2015
2017 : public CommandObjectParsed {
2018public:
2020 CommandInterpreter &interpreter, const char *name, const char *help,
2021 const char *syntax, uint32_t flags)
2022 : CommandObjectParsed(interpreter, name, help, syntax, flags) {
2024 }
2025
2027
2028 void
2034};
2035
2036#pragma mark CommandObjectTargetModulesDumpObjfile
2037
2040public:
2043 interpreter, "target modules dump objfile",
2044 "Dump the object file headers from one or more target modules.",
2045 nullptr, eCommandRequiresTarget) {}
2046
2048
2049protected:
2050 void DoExecute(Args &command, CommandReturnObject &result) override {
2051 Target *target = GetTarget();
2052 assert(target && "target guaranteed by eCommandRequiresTarget");
2053 size_t num_dumped = 0;
2054 if (command.GetArgumentCount() == 0) {
2055 // Dump all headers for all modules images
2056 num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(),
2057 target->GetImages());
2058 if (num_dumped == 0) {
2059 result.AppendError("the target has no associated executable images");
2060 }
2061 } else {
2062 // Find the modules that match the basename or full path.
2063 ModuleList module_list;
2064 const char *arg_cstr;
2065 for (int arg_idx = 0;
2066 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2067 ++arg_idx) {
2068 size_t num_matched =
2069 FindModulesByName(target, arg_cstr, module_list, true);
2070 if (num_matched == 0) {
2072 "unable to find an image that matches '{0}'", arg_cstr);
2073 }
2074 }
2075 // Dump all the modules we found.
2076 num_dumped =
2077 DumpModuleObjfileHeaders(result.GetOutputStream(), module_list);
2078 }
2079
2080 if (num_dumped > 0) {
2082 } else {
2083 result.AppendError("no matching executable images found");
2084 }
2085 }
2086};
2087
2088#define LLDB_OPTIONS_target_modules_dump_symtab
2089#include "CommandOptions.inc"
2090
2093public:
2096 interpreter, "target modules dump symtab",
2097 "Dump the symbol table from one or more target modules.", nullptr,
2098 eCommandRequiresTarget) {}
2099
2101
2102 Options *GetOptions() override { return &m_options; }
2103
2104 class CommandOptions : public Options {
2105 public:
2106 CommandOptions() = default;
2107
2108 ~CommandOptions() override = default;
2109
2110 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2111 ExecutionContext *execution_context) override {
2112 Status error;
2113 const int short_option = m_getopt_table[option_idx].val;
2114
2115 switch (short_option) {
2116 case 'm':
2117 m_prefer_mangled.SetCurrentValue(true);
2118 m_prefer_mangled.SetOptionWasSet();
2119 break;
2120
2121 case 's':
2123 option_arg, GetDefinitions()[option_idx].enum_values,
2125 break;
2126
2127 default:
2128 llvm_unreachable("Unimplemented option");
2129 }
2130 return error;
2131 }
2132
2133 void OptionParsingStarting(ExecutionContext *execution_context) override {
2135 m_prefer_mangled.Clear();
2136 }
2137
2138 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2139 return llvm::ArrayRef(g_target_modules_dump_symtab_options);
2140 }
2141
2144 };
2145
2146protected:
2147 void DoExecute(Args &command, CommandReturnObject &result) override {
2148 Target *target = GetTarget();
2149 assert(target && "target guaranteed by eCommandRequiresTarget");
2150 uint32_t num_dumped = 0;
2151 Mangled::NamePreference name_preference =
2152 (m_options.m_prefer_mangled ? Mangled::ePreferMangled
2154
2155 if (command.GetArgumentCount() == 0) {
2156 // Dump all sections for all modules images
2157 const ModuleList &module_list = target->GetImages();
2158 std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
2159 const size_t num_modules = module_list.GetSize();
2160 if (num_modules > 0) {
2161 result.GetOutputStream().Format(
2162 "Dumping symbol table for {0} modules.\n", num_modules);
2163 for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
2164 if (num_dumped > 0) {
2165 result.GetOutputStream().EOL();
2166 result.GetOutputStream().EOL();
2167 }
2169 "Interrupted in dump all symtabs with {0} "
2170 "of {1} dumped.", num_dumped, num_modules))
2171 break;
2172
2173 num_dumped++;
2175 module_sp.get(), m_options.m_sort_order,
2176 name_preference);
2177 }
2178 } else {
2179 result.AppendError("the target has no associated executable images");
2180 return;
2181 }
2182 } else {
2183 // Dump specified images (by basename or fullpath)
2184 const char *arg_cstr;
2185 for (int arg_idx = 0;
2186 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2187 ++arg_idx) {
2188 ModuleList module_list;
2189 const size_t num_matches =
2190 FindModulesByName(target, arg_cstr, module_list, true);
2191 if (num_matches > 0) {
2192 for (ModuleSP module_sp : module_list.Modules()) {
2193 if (module_sp) {
2194 if (num_dumped > 0) {
2195 result.GetOutputStream().EOL();
2196 result.GetOutputStream().EOL();
2197 }
2199 "Interrupted in dump symtab list with {0} of {1} dumped.",
2200 num_dumped, num_matches))
2201 break;
2202
2203 num_dumped++;
2205 module_sp.get(), m_options.m_sort_order,
2206 name_preference);
2207 }
2208 }
2209 } else
2211 "unable to find an image that matches '{0}'", arg_cstr);
2212 }
2213 }
2214
2215 if (num_dumped > 0)
2217 else {
2218 result.AppendError("no matching executable images found");
2219 }
2220 }
2221
2223};
2224
2225#pragma mark CommandObjectTargetModulesDumpSections
2226
2227// Image section dumping command
2228
2231public:
2234 interpreter, "target modules dump sections",
2235 "Dump the sections from one or more target modules.",
2236 //"target modules dump sections [<file1> ...]")
2237 nullptr, eCommandRequiresTarget) {}
2238
2240
2241protected:
2242 void DoExecute(Args &command, CommandReturnObject &result) override {
2243 Target *target = GetTarget();
2244 assert(target && "target guaranteed by eCommandRequiresTarget");
2245 uint32_t num_dumped = 0;
2246
2247 if (command.GetArgumentCount() == 0) {
2248 // Dump all sections for all modules images
2249 const size_t num_modules = target->GetImages().GetSize();
2250 if (num_modules == 0) {
2251 result.AppendError("the target has no associated executable images");
2252 return;
2253 }
2254
2255 result.GetOutputStream().Format("Dumping sections for {0} modules.\n",
2256 num_modules);
2257 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2259 "Interrupted in dump all sections with {0} of {1} dumped",
2260 image_idx, num_modules))
2261 break;
2262
2263 num_dumped++;
2266 target->GetImages().GetModulePointerAtIndex(image_idx));
2267 }
2268 } else {
2269 // Dump specified images (by basename or fullpath)
2270 const char *arg_cstr;
2271 for (int arg_idx = 0;
2272 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2273 ++arg_idx) {
2274 ModuleList module_list;
2275 const size_t num_matches =
2276 FindModulesByName(target, arg_cstr, module_list, true);
2277 if (num_matches > 0) {
2278 for (size_t i = 0; i < num_matches; ++i) {
2280 "Interrupted in dump section list with {0} of {1} dumped.",
2281 i, num_matches))
2282 break;
2283
2284 Module *module = module_list.GetModulePointerAtIndex(i);
2285 if (module) {
2286 num_dumped++;
2288 module);
2289 }
2290 }
2291 } else {
2292 // Check the global list
2293 std::lock_guard<std::recursive_mutex> guard(
2295
2297 "unable to find an image that matches '{0}'", arg_cstr);
2298 }
2299 }
2300 }
2301
2302 if (num_dumped > 0)
2304 else {
2305 result.AppendError("no matching executable images found");
2306 }
2307 }
2308};
2309
2310#pragma mark CommandObjectTargetModulesDumpClangAST
2311
2312// Clang AST dumping command
2313
2316public:
2319 interpreter, "target modules dump ast",
2320 "Dump the clang ast for a given module's symbol file.",
2321 "target modules dump ast [--filter <name>] [<file1> ...]",
2322 eCommandRequiresTarget),
2323 m_filter(LLDB_OPT_SET_1, false, "filter", 'f', 0, eArgTypeName,
2324 "Dump only the decls whose names contain the specified filter "
2325 "string.",
2326 /*default_value=*/"") {
2328 m_option_group.Finalize();
2329 }
2330
2331 Options *GetOptions() override { return &m_option_group; }
2332
2334
2337
2338protected:
2339 void DoExecute(Args &command, CommandReturnObject &result) override {
2340 Target *target = GetTarget();
2341 assert(target && "target guaranteed by eCommandRequiresTarget");
2342 const ModuleList &module_list = target->GetImages();
2343 const size_t num_modules = module_list.GetSize();
2344 if (num_modules == 0) {
2345 result.AppendError("the target has no associated executable images");
2346 return;
2347 }
2348
2349 llvm::StringRef filter = m_filter.GetOptionValue().GetCurrentValueAsRef();
2350
2351 if (command.GetArgumentCount() == 0) {
2352 // Dump all ASTs for all modules images
2353 result.GetOutputStream().Format("Dumping clang ast for {0} modules.\n",
2354 num_modules);
2355 for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
2356 if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted dumping clang ast"))
2357 break;
2358 if (SymbolFile *sf = module_sp->GetSymbolFile())
2359 sf->DumpClangAST(result.GetOutputStream(), filter,
2360 GetCommandInterpreter().GetDebugger().GetUseColor());
2361 }
2363 return;
2364 }
2365
2366 // Dump specified ASTs (by basename or fullpath)
2367 for (const Args::ArgEntry &arg : command.entries()) {
2368 ModuleList module_list;
2369 const size_t num_matches =
2370 FindModulesByName(target, arg.c_str(), module_list, true);
2371 if (num_matches == 0) {
2372 // Check the global list
2373 std::lock_guard<std::recursive_mutex> guard(
2375
2377 "unable to find an image that matches '{0}'", arg.c_str());
2378 continue;
2379 }
2380
2381 for (size_t i = 0; i < num_matches; ++i) {
2383 "Interrupted in dump clang ast list with {0} of {1} dumped.",
2384 i, num_matches))
2385 break;
2386
2387 Module *m = module_list.GetModulePointerAtIndex(i);
2388 if (SymbolFile *sf = m->GetSymbolFile())
2389 sf->DumpClangAST(result.GetOutputStream(), filter,
2390 GetCommandInterpreter().GetDebugger().GetUseColor());
2391 }
2392 }
2394 }
2395};
2396
2397#pragma mark CommandObjectTargetModulesDumpSymfile
2398
2399// Image debug symbol dumping command
2400
2403public:
2406 interpreter, "target modules dump symfile",
2407 "Dump the debug symbol file for one or more target modules.",
2408 //"target modules dump symfile [<file1> ...]")
2409 nullptr, eCommandRequiresTarget) {}
2410
2412
2413protected:
2414 void DoExecute(Args &command, CommandReturnObject &result) override {
2415 Target *target = GetTarget();
2416 assert(target && "target guaranteed by eCommandRequiresTarget");
2417 uint32_t num_dumped = 0;
2418
2419 if (command.GetArgumentCount() == 0) {
2420 // Dump all sections for all modules images
2421 const ModuleList &target_modules = target->GetImages();
2422 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2423 const size_t num_modules = target_modules.GetSize();
2424 if (num_modules == 0) {
2425 result.AppendError("the target has no associated executable images");
2426 return;
2427 }
2428 result.GetOutputStream().Format(
2429 "Dumping debug symbols for {0} modules.\n", num_modules);
2430 for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
2431 if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted in dumping all "
2432 "debug symbols with {0} of {1} modules dumped",
2433 num_dumped, num_modules))
2434 break;
2435
2436 if (DumpModuleSymbolFile(result.GetOutputStream(), module_sp.get()))
2437 num_dumped++;
2438 }
2439 } else {
2440 // Dump specified images (by basename or fullpath)
2441 const char *arg_cstr;
2442 for (int arg_idx = 0;
2443 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2444 ++arg_idx) {
2445 ModuleList module_list;
2446 const size_t num_matches =
2447 FindModulesByName(target, arg_cstr, module_list, true);
2448 if (num_matches > 0) {
2449 for (size_t i = 0; i < num_matches; ++i) {
2450 if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted dumping {0} "
2451 "of {1} requested modules",
2452 i, num_matches))
2453 break;
2454 Module *module = module_list.GetModulePointerAtIndex(i);
2455 if (module) {
2456 if (DumpModuleSymbolFile(result.GetOutputStream(), module))
2457 num_dumped++;
2458 }
2459 }
2460 } else
2462 "unable to find an image that matches '{0}'", arg_cstr);
2463 }
2464 }
2465
2466 if (num_dumped > 0)
2468 else {
2469 result.AppendError("no matching executable images found");
2470 }
2471 }
2472};
2473
2474#pragma mark CommandObjectTargetModulesDumpLineTable
2475#define LLDB_OPTIONS_target_modules_dump
2476#include "CommandOptions.inc"
2477
2478// Image debug line table dumping command
2479
2482public:
2485 interpreter, "target modules dump line-table",
2486 "Dump the line table for one or more compilation units.", nullptr,
2487 eCommandRequiresTarget) {}
2488
2490
2491 Options *GetOptions() override { return &m_options; }
2492
2493protected:
2494 void DoExecute(Args &command, CommandReturnObject &result) override {
2495 Target *target = m_exe_ctx.GetTargetPtr();
2496 uint32_t total_num_dumped = 0;
2497
2498 if (command.GetArgumentCount() == 0) {
2499 result.AppendError("file option must be specified");
2500 return;
2501 } else {
2502 // Dump specified images (by basename or fullpath)
2503 const char *arg_cstr;
2504 for (int arg_idx = 0;
2505 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2506 ++arg_idx) {
2507 FileSpec file_spec(arg_cstr);
2508
2509 const ModuleList &target_modules = target->GetImages();
2510 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2511 size_t num_modules = target_modules.GetSize();
2512 if (num_modules > 0) {
2513 uint32_t num_dumped = 0;
2514 for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
2516 "Interrupted in dump all line tables with "
2517 "{0} of {1} dumped", num_dumped,
2518 num_modules))
2519 break;
2520
2522 m_interpreter, result.GetOutputStream(), module_sp.get(),
2523 file_spec,
2526 num_dumped++;
2527 }
2528 if (num_dumped == 0)
2529 result.AppendWarningWithFormatv("no source filenames matched '{0}'",
2530 arg_cstr);
2531 else
2532 total_num_dumped += num_dumped;
2533 }
2534 }
2535 }
2536
2537 if (total_num_dumped > 0)
2539 else {
2540 result.AppendError("no source filenames matched any command arguments");
2541 }
2542 }
2543
2544 class CommandOptions : public Options {
2545 public:
2547
2548 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2549 ExecutionContext *execution_context) override {
2550 assert(option_idx == 0 && "We only have one option.");
2551 m_verbose = true;
2552
2553 return Status();
2554 }
2555
2556 void OptionParsingStarting(ExecutionContext *execution_context) override {
2557 m_verbose = false;
2558 }
2559
2560 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2561 return llvm::ArrayRef(g_target_modules_dump_options);
2562 }
2563
2565 };
2566
2568};
2569
2570#pragma mark CommandObjectTargetModulesDumpSeparateDebugInfoFiles
2571#define LLDB_OPTIONS_target_modules_dump_separate_debug_info
2572#include "CommandOptions.inc"
2573
2574// Image debug separate debug info dumping command
2575
2578public:
2580 CommandInterpreter &interpreter)
2582 interpreter, "target modules dump separate-debug-info",
2583 "List the separate debug info symbol files for one or more target "
2584 "modules.",
2585 nullptr, eCommandRequiresTarget) {}
2586
2588
2589 Options *GetOptions() override { return &m_options; }
2590
2591 class CommandOptions : public Options {
2592 public:
2593 CommandOptions() = default;
2594
2595 ~CommandOptions() override = default;
2596
2597 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2598 ExecutionContext *execution_context) override {
2599 Status error;
2600 const int short_option = m_getopt_table[option_idx].val;
2601
2602 switch (short_option) {
2603 case 'f':
2604 m_load_all_debug_info.SetCurrentValue(true);
2605 m_load_all_debug_info.SetOptionWasSet();
2606 break;
2607 case 'j':
2608 m_json.SetCurrentValue(true);
2609 m_json.SetOptionWasSet();
2610 break;
2611 case 'e':
2612 m_errors_only.SetCurrentValue(true);
2613 m_errors_only.SetOptionWasSet();
2614 break;
2615 default:
2616 llvm_unreachable("Unimplemented option");
2617 }
2618 return error;
2619 }
2620
2621 void OptionParsingStarting(ExecutionContext *execution_context) override {
2622 m_json.Clear();
2623 m_errors_only.Clear();
2624 m_load_all_debug_info.Clear();
2625 }
2626
2627 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2628 return llvm::ArrayRef(g_target_modules_dump_separate_debug_info_options);
2629 }
2630
2634 };
2635
2636protected:
2637 void DoExecute(Args &command, CommandReturnObject &result) override {
2638 Target *target = GetTarget();
2639 assert(target && "target guaranteed by eCommandRequiresTarget");
2640 uint32_t num_dumped = 0;
2641
2642 StructuredData::Array separate_debug_info_lists_by_module;
2643 if (command.GetArgumentCount() == 0) {
2644 // Dump all sections for all modules images
2645 const ModuleList &target_modules = target->GetImages();
2646 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2647 const size_t num_modules = target_modules.GetSize();
2648 if (num_modules == 0) {
2649 result.AppendError("the target has no associated executable images");
2650 return;
2651 }
2652 for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
2654 GetDebugger(),
2655 "Interrupted in dumping all "
2656 "separate debug info with {0} of {1} modules dumped",
2657 num_dumped, num_modules))
2658 break;
2659
2660 if (GetSeparateDebugInfoList(separate_debug_info_lists_by_module,
2661 module_sp.get(),
2662 bool(m_options.m_errors_only),
2663 bool(m_options.m_load_all_debug_info)))
2664 num_dumped++;
2665 }
2666 } else {
2667 // Dump specified images (by basename or fullpath)
2668 const char *arg_cstr;
2669 for (int arg_idx = 0;
2670 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2671 ++arg_idx) {
2672 ModuleList module_list;
2673 const size_t num_matches =
2674 FindModulesByName(target, arg_cstr, module_list, true);
2675 if (num_matches > 0) {
2676 for (size_t i = 0; i < num_matches; ++i) {
2678 "Interrupted dumping {0} "
2679 "of {1} requested modules",
2680 i, num_matches))
2681 break;
2682 Module *module = module_list.GetModulePointerAtIndex(i);
2683 if (GetSeparateDebugInfoList(separate_debug_info_lists_by_module,
2684 module, bool(m_options.m_errors_only),
2685 bool(m_options.m_load_all_debug_info)))
2686 num_dumped++;
2687 }
2688 } else
2690 "unable to find an image that matches '{0}'", arg_cstr);
2691 }
2692 }
2693
2694 if (num_dumped > 0) {
2695 Stream &strm = result.GetOutputStream();
2696 // Display the debug info files in some format.
2697 if (m_options.m_json) {
2698 // JSON format
2699 separate_debug_info_lists_by_module.Dump(strm,
2700 /*pretty_print=*/true);
2701 } else {
2702 // Human-readable table format
2703 separate_debug_info_lists_by_module.ForEach(
2704 [&result, &strm](StructuredData::Object *obj) {
2705 if (!obj) {
2706 return false;
2707 }
2708
2709 // Each item in `separate_debug_info_lists_by_module` should be a
2710 // valid structured data dictionary.
2711 StructuredData::Dictionary *separate_debug_info_list =
2712 obj->GetAsDictionary();
2713 if (!separate_debug_info_list) {
2714 return false;
2715 }
2716
2717 llvm::StringRef type;
2718 llvm::StringRef symfile;
2719 StructuredData::Array *files;
2720 if (!(separate_debug_info_list->GetValueForKeyAsString("type",
2721 type) &&
2722 separate_debug_info_list->GetValueForKeyAsString("symfile",
2723 symfile) &&
2724 separate_debug_info_list->GetValueForKeyAsArray(
2725 "separate-debug-info-files", files))) {
2726 assert(false);
2727 }
2728
2729 strm << "Symbol file: " << symfile;
2730 strm.EOL();
2731 strm << "Type: \"" << type << "\"";
2732 strm.EOL();
2733 if (type == "dwo") {
2734 DumpDwoFilesTable(strm, *files);
2735 } else if (type == "oso") {
2736 DumpOsoFilesTable(strm, *files);
2737 } else {
2739 "found unsupported debug info type '{0}'", type);
2740 }
2741 return true;
2742 });
2743 }
2745 } else {
2746 result.AppendError("no matching executable images found");
2747 }
2748 }
2749
2751};
2752
2753#pragma mark CommandObjectTargetModulesDump
2754
2755// Dump multi-word command for target modules
2756
2758public:
2759 // Constructors and Destructors
2762 interpreter, "target modules dump",
2763 "Commands for dumping information about one or more target "
2764 "modules.",
2765 "target modules dump "
2766 "[objfile|symtab|sections|ast|symfile|line-table|pcm-info|separate-"
2767 "debug-info] "
2768 "[<file1> <file2> ...]") {
2769 LoadSubCommand("objfile",
2771 new CommandObjectTargetModulesDumpObjfile(interpreter)));
2773 "symtab",
2775 LoadSubCommand("sections",
2777 interpreter)));
2778 LoadSubCommand("symfile",
2780 new CommandObjectTargetModulesDumpSymfile(interpreter)));
2782 "ast", CommandObjectSP(
2783 new CommandObjectTargetModulesDumpClangAST(interpreter)));
2784 LoadSubCommand("line-table",
2786 interpreter)));
2787 LoadSubCommand("separate-debug-info",
2790 interpreter)));
2791 }
2792
2794};
2795
2797public:
2799 : CommandObjectParsed(interpreter, "target modules add",
2800 "Add a new module to the current target's modules.",
2801 "target modules add [<module>]",
2802 eCommandRequiresTarget),
2803 m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
2805 "Fullpath to a stand alone debug "
2806 "symbols file for when debug symbols "
2807 "are not in the executable.") {
2811 m_option_group.Finalize();
2813 }
2814
2816
2817 Options *GetOptions() override { return &m_option_group; }
2818
2819protected:
2823
2824 void DoExecute(Args &args, CommandReturnObject &result) override {
2825 Target *target = GetTarget();
2826 assert(target && "target guaranteed by eCommandRequiresTarget");
2827 bool flush = false;
2828
2829 const size_t argc = args.GetArgumentCount();
2830 if (argc == 0) {
2831 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2832 // We are given a UUID only, go locate the file
2833 ModuleSpec module_spec;
2834 module_spec.GetUUID() =
2835 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2836 if (m_symbol_file.GetOptionValue().OptionWasSet())
2837 module_spec.GetSymbolFileSpec() =
2838 m_symbol_file.GetOptionValue().GetCurrentValue();
2839 Status error;
2841 ModuleSP module_sp(
2842 target->GetOrCreateModule(module_spec, true /* notify */));
2843 if (module_sp) {
2845 return;
2846 } else {
2847 StreamString strm;
2848 module_spec.GetUUID().Dump(strm);
2849 if (module_spec.GetFileSpec()) {
2850 if (module_spec.GetSymbolFileSpec()) {
2851 result.AppendErrorWithFormat(
2852 "Unable to create the executable or symbol file with "
2853 "UUID %s with path %s and symbol file %s",
2854 strm.GetData(), module_spec.GetFileSpec().GetPath().c_str(),
2855 module_spec.GetSymbolFileSpec().GetPath().c_str());
2856 } else {
2857 result.AppendErrorWithFormat(
2858 "Unable to create the executable or symbol file with "
2859 "UUID %s with path %s",
2860 strm.GetData(),
2861 module_spec.GetFileSpec().GetPath().c_str());
2862 }
2863 } else {
2864 result.AppendErrorWithFormat("Unable to create the executable "
2865 "or symbol file with UUID %s",
2866 strm.GetData());
2867 }
2868 return;
2869 }
2870 } else {
2871 StreamString strm;
2872 module_spec.GetUUID().Dump(strm);
2873 result.AppendErrorWithFormat(
2874 "Unable to locate the executable or symbol file with UUID %s",
2875 strm.GetData());
2876 result.SetError(std::move(error));
2877 return;
2878 }
2879 } else {
2880 result.AppendError(
2881 "one or more executable image paths must be specified");
2882 return;
2883 }
2884 } else {
2885 for (auto &entry : args.entries()) {
2886 if (entry.ref().empty())
2887 continue;
2888
2889 FileSpec file_spec(entry.ref());
2890 if (FileSystem::Instance().Exists(file_spec)) {
2891 ModuleSpec module_spec(file_spec);
2892 if (m_uuid_option_group.GetOptionValue().OptionWasSet())
2893 module_spec.GetUUID() =
2894 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2895 if (m_symbol_file.GetOptionValue().OptionWasSet())
2896 module_spec.GetSymbolFileSpec() =
2897 m_symbol_file.GetOptionValue().GetCurrentValue();
2898 if (!module_spec.GetArchitecture().IsValid())
2899 module_spec.GetArchitecture() = target->GetArchitecture();
2900 Status error;
2901 ModuleSP module_sp(target->GetOrCreateModule(
2902 module_spec, true /* notify */, &error));
2903 if (!module_sp) {
2904 const char *error_cstr = error.AsCString();
2905 if (error_cstr)
2906 result.AppendError(error_cstr);
2907 else
2908 result.AppendErrorWithFormat("unsupported module: %s",
2909 entry.c_str());
2910 return;
2911 } else {
2912 flush = true;
2913 }
2915 } else {
2916 std::string resolved_path = file_spec.GetPath();
2917 if (resolved_path != entry.ref()) {
2918 result.AppendErrorWithFormat(
2919 "invalid module path '%s' with resolved path '%s'",
2920 entry.ref().str().c_str(), resolved_path.c_str());
2921 break;
2922 }
2923 result.AppendErrorWithFormat("invalid module path '%s'",
2924 entry.c_str());
2925 break;
2926 }
2927 }
2928 }
2929
2930 if (flush) {
2931 ProcessSP process = target->GetProcessSP();
2932 if (process)
2933 process->Flush();
2934 }
2935 }
2936};
2937
2940public:
2943 interpreter, "target modules load",
2944 "Set the load addresses for one or more sections in a target "
2945 "module.",
2946 "target modules load [--file <module> --uuid <uuid>] <sect-name> "
2947 "<address> [<sect-name> <address> ....]",
2948 eCommandRequiresTarget),
2949 m_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName,
2950 "Fullpath or basename for module to load.", ""),
2951 m_load_option(LLDB_OPT_SET_1, false, "load", 'l',
2952 "Write file contents to the memory.", false, true),
2953 m_pc_option(LLDB_OPT_SET_1, false, "set-pc-to-entry", 'p',
2954 "Set PC to the entry point."
2955 " Only applicable with '--load' option.",
2956 false, true),
2957 m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset,
2958 "Set the load address for all sections to be the "
2959 "virtual address in the file plus the offset.",
2960 0) {
2967 m_option_group.Finalize();
2968 }
2969
2971
2972 Options *GetOptions() override { return &m_option_group; }
2973
2974protected:
2975 void DoExecute(Args &args, CommandReturnObject &result) override {
2976 Target *target = GetTarget();
2977 assert(target && "target guaranteed by eCommandRequiresTarget");
2978 const bool load = m_load_option.GetOptionValue().GetCurrentValue();
2979 const bool set_pc = m_pc_option.GetOptionValue().GetCurrentValue();
2980
2981 const size_t argc = args.GetArgumentCount();
2982 ModuleSpec module_spec;
2983 bool search_using_module_spec = false;
2984
2985 // Allow "load" option to work without --file or --uuid option.
2986 if (load) {
2987 if (!m_file_option.GetOptionValue().OptionWasSet() &&
2988 !m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2989 ModuleList &module_list = target->GetImages();
2990 if (module_list.GetSize() == 1) {
2991 search_using_module_spec = true;
2992 module_spec.GetFileSpec() =
2993 module_list.GetModuleAtIndex(0)->GetFileSpec();
2994 }
2995 }
2996 }
2997
2998 if (m_file_option.GetOptionValue().OptionWasSet()) {
2999 search_using_module_spec = true;
3000 const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
3001 const bool use_global_module_list = true;
3002 ModuleList module_list;
3003 const size_t num_matches = FindModulesByName(
3004 target, arg_cstr, module_list, use_global_module_list);
3005 if (num_matches == 1) {
3006 module_spec.GetFileSpec() =
3007 module_list.GetModuleAtIndex(0)->GetFileSpec();
3008 } else if (num_matches > 1) {
3009 search_using_module_spec = false;
3010 result.AppendErrorWithFormat("more than 1 module matched by name '%s'",
3011 arg_cstr);
3012 } else {
3013 search_using_module_spec = false;
3014 result.AppendErrorWithFormat("no object file for module '%s'",
3015 arg_cstr);
3016 }
3017 }
3018
3019 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
3020 search_using_module_spec = true;
3021 module_spec.GetUUID() =
3022 m_uuid_option_group.GetOptionValue().GetCurrentValue();
3023 }
3024
3025 if (search_using_module_spec) {
3026 ModuleList matching_modules;
3027 target->GetImages().FindModules(module_spec, matching_modules);
3028 const size_t num_matches = matching_modules.GetSize();
3029
3030 char path[PATH_MAX];
3031 if (num_matches == 1) {
3032 Module *module = matching_modules.GetModulePointerAtIndex(0);
3033 if (module) {
3034 ObjectFile *objfile = module->GetObjectFile();
3035 if (objfile) {
3036 SectionList *section_list = module->GetSectionList();
3037 if (section_list) {
3038 bool changed = false;
3039 if (argc == 0) {
3040 if (m_slide_option.GetOptionValue().OptionWasSet()) {
3041 const addr_t slide =
3042 m_slide_option.GetOptionValue().GetCurrentValue();
3043 const bool slide_is_offset = true;
3044 module->SetLoadAddress(*target, slide, slide_is_offset,
3045 changed);
3046 } else {
3047 result.AppendError("one or more section name + load "
3048 "address pair must be specified");
3049 return;
3050 }
3051 } else {
3052 if (m_slide_option.GetOptionValue().OptionWasSet()) {
3053 result.AppendError("The \"--slide <offset>\" option can't "
3054 "be used in conjunction with setting "
3055 "section load addresses.\n");
3056 return;
3057 }
3058
3059 for (size_t i = 0; i < argc; i += 2) {
3060 const char *sect_name = args.GetArgumentAtIndex(i);
3061 const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1);
3062 if (sect_name && load_addr_cstr) {
3063 addr_t load_addr;
3064 if (llvm::to_integer(load_addr_cstr, load_addr)) {
3065 SectionSP section_sp(
3066 section_list->FindSectionByName(sect_name));
3067 if (section_sp) {
3068 if (section_sp->IsThreadSpecific()) {
3069 result.AppendErrorWithFormat(
3070 "thread specific sections are not yet "
3071 "supported (section '%s')",
3072 sect_name);
3073 break;
3074 } else {
3075 if (target->SetSectionLoadAddress(section_sp,
3076 load_addr))
3077 changed = true;
3079 "section '{0}' loaded at {1:x}", sect_name,
3080 load_addr);
3081 }
3082 } else {
3083 result.AppendErrorWithFormat("no section found that "
3084 "matches the section "
3085 "name '%s'",
3086 sect_name);
3087 break;
3088 }
3089 } else {
3090 result.AppendErrorWithFormat(
3091 "invalid load address string '%s'", load_addr_cstr);
3092 break;
3093 }
3094 } else {
3095 if (sect_name)
3096 result.AppendError("section names must be followed by "
3097 "a load address.\n");
3098 else
3099 result.AppendError("one or more section name + load "
3100 "address pair must be specified.\n");
3101 break;
3102 }
3103 }
3104 }
3105
3106 if (changed) {
3107 target->ModulesDidLoad(matching_modules);
3108 Process *process = m_exe_ctx.GetProcessPtr();
3109 if (process)
3110 process->Flush();
3111 }
3112 if (load) {
3113 ProcessSP process = target->CalculateProcess();
3114 Address file_entry = objfile->GetEntryPointAddress();
3115 if (!process) {
3116 result.AppendError("No process");
3117 return;
3118 }
3119 if (set_pc && !file_entry.IsValid()) {
3120 result.AppendError("No entry address in object file");
3121 return;
3122 }
3123 std::vector<ObjectFile::LoadableData> loadables(
3124 objfile->GetLoadableData(*target));
3125 if (loadables.size() == 0) {
3126 result.AppendError("No loadable sections");
3127 return;
3128 }
3129 Status error = process->WriteObjectFile(std::move(loadables));
3130 if (error.Fail()) {
3131 result.AppendError(error.AsCString());
3132 return;
3133 }
3134 if (set_pc) {
3135 ThreadList &thread_list = process->GetThreadList();
3136 RegisterContextSP reg_context(
3137 thread_list.GetSelectedThread()->GetRegisterContext());
3138 addr_t file_entry_addr = file_entry.GetLoadAddress(target);
3139 if (!reg_context->SetPC(file_entry_addr)) {
3140 result.AppendErrorWithFormat("failed to set PC value to "
3141 "0x%" PRIx64,
3142 file_entry_addr);
3143 }
3144 }
3145 }
3146 } else {
3147 module->GetFileSpec().GetPath(path, sizeof(path));
3148 result.AppendErrorWithFormat("no sections in object file '%s'",
3149 path);
3150 }
3151 } else {
3152 module->GetFileSpec().GetPath(path, sizeof(path));
3153 result.AppendErrorWithFormat("no object file for module '%s'",
3154 path);
3155 }
3156 } else {
3157 FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
3158 if (module_spec_file) {
3159 module_spec_file->GetPath(path, sizeof(path));
3160 result.AppendErrorWithFormat("invalid module '%s'", path);
3161 } else
3162 result.AppendError("no module spec");
3163 }
3164 } else {
3165 std::string uuid_str;
3166
3167 if (module_spec.GetFileSpec())
3168 module_spec.GetFileSpec().GetPath(path, sizeof(path));
3169 else
3170 path[0] = '\0';
3171
3172 if (module_spec.GetUUIDPtr())
3173 uuid_str = module_spec.GetUUID().GetAsString();
3174 if (num_matches > 1) {
3175 result.AppendErrorWithFormat(
3176 "multiple modules match%s%s%s%s:", path[0] ? " file=" : "", path,
3177 !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
3178 for (size_t i = 0; i < num_matches; ++i) {
3179 if (matching_modules.GetModulePointerAtIndex(i)
3180 ->GetFileSpec()
3181 .GetPath(path, sizeof(path)))
3182 result.AppendMessageWithFormatv("{0}", path);
3183 }
3184 } else {
3185 result.AppendErrorWithFormat(
3186 "no modules were found that match%s%s%s%s",
3187 path[0] ? " file=" : "", path, !uuid_str.empty() ? " uuid=" : "",
3188 uuid_str.c_str());
3189 }
3190 }
3191 } else {
3192 result.AppendError("either the \"--file <module>\" or the \"--uuid "
3193 "<uuid>\" option must be specified.\n");
3194 }
3195 if (result.GetStatus() != eReturnStatusFailed)
3197 }
3198
3205};
3206
3207#pragma mark CommandObjectTargetModulesList
3208// List images with associated information
3209#define LLDB_OPTIONS_target_modules_list
3210#include "CommandOptions.inc"
3211
3213public:
3214 class CommandOptions : public Options {
3215 public:
3216 CommandOptions() = default;
3217
3218 ~CommandOptions() override = default;
3219
3220 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3221 ExecutionContext *execution_context) override {
3222 Status error;
3223
3224 const int short_option = m_getopt_table[option_idx].val;
3225 if (short_option == 'g') {
3227 } else if (short_option == 'a') {
3229 execution_context, option_arg, LLDB_INVALID_ADDRESS, &error);
3230 } else {
3231 unsigned long width = 0;
3232 option_arg.getAsInteger(0, width);
3233 m_format_array.push_back(std::make_pair(short_option, width));
3234 }
3235 return error;
3236 }
3237
3238 void OptionParsingStarting(ExecutionContext *execution_context) override {
3239 m_format_array.clear();
3242 }
3243
3244 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3245 return llvm::ArrayRef(g_target_modules_list_options);
3246 }
3247
3248 // Instance variables to hold the values for command options.
3249 typedef std::vector<std::pair<char, uint32_t>> FormatWidthCollection;
3253 };
3254
3257 interpreter, "target modules list",
3258 "List current executable and dependent shared library images.",
3259 nullptr, eCommandAllowsDummyTarget) {
3261 }
3262
3264
3265 Options *GetOptions() override { return &m_options; }
3266
3267protected:
3268 void DoExecute(Args &command, CommandReturnObject &result) override {
3269 Target *target = GetTarget();
3270 const bool use_global_module_list = m_options.m_use_global_module_list;
3271
3272 // Every code path other than the global module list needs a real target.
3273 if (!use_global_module_list && (!target || target->IsDummyTarget())) {
3275 return;
3276 }
3277
3278 // Define a local module list here to ensure it lives longer than any
3279 // "locker" object which might lock its contents below (through the
3280 // "module_list_ptr" variable).
3281 ModuleList module_list;
3282 // Dump all sections for all modules images
3283 Stream &strm = result.GetOutputStream();
3284
3285 if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) {
3286 Address module_address;
3287 if (module_address.SetLoadAddress(m_options.m_module_addr, target)) {
3288 ModuleSP module_sp(module_address.GetModule());
3289 if (module_sp) {
3290 PrintModule(*target, module_sp.get(), 0, strm);
3292 } else {
3293 result.AppendErrorWithFormat(
3294 "Couldn't find module matching address: 0x%" PRIx64,
3295 m_options.m_module_addr);
3296 }
3297 } else {
3298 result.AppendErrorWithFormat(
3299 "Couldn't find module containing address: 0x%" PRIx64,
3300 m_options.m_module_addr);
3301 }
3302 return;
3303 }
3304
3305 size_t num_modules = 0;
3306
3307 // This locker will be locked on the mutex in module_list_ptr if it is
3308 // non-nullptr. Otherwise it will lock the
3309 // AllocationModuleCollectionMutex when accessing the global module list
3310 // directly.
3311 std::unique_lock<std::recursive_mutex> guard(
3313
3314 const ModuleList *module_list_ptr = nullptr;
3315 const size_t argc = command.GetArgumentCount();
3316 if (argc == 0) {
3317 if (use_global_module_list) {
3318 guard.lock();
3319 num_modules = Module::GetNumberAllocatedModules();
3320 } else {
3321 module_list_ptr = &target->GetImages();
3322 }
3323 } else {
3324 for (const Args::ArgEntry &arg : command) {
3325 // Dump specified images (by basename or fullpath)
3326 const size_t num_matches = FindModulesByName(
3327 target, arg.c_str(), module_list, use_global_module_list);
3328 if (num_matches == 0) {
3329 if (argc == 1) {
3330 result.AppendErrorWithFormat("no modules found that match '%s'",
3331 arg.c_str());
3332 return;
3333 }
3334 }
3335 }
3336
3337 module_list_ptr = &module_list;
3338 }
3339
3340 std::unique_lock<std::recursive_mutex> lock;
3341 if (module_list_ptr != nullptr) {
3342 lock =
3343 std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex());
3344
3345 num_modules = module_list_ptr->GetSize();
3346 }
3347
3348 if (num_modules > 0) {
3349 for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
3350 ModuleSP module_sp;
3351 Module *module;
3352 if (module_list_ptr) {
3353 module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
3354 module = module_sp.get();
3355 } else {
3356 module = Module::GetAllocatedModuleAtIndex(image_idx);
3357 module_sp = module->shared_from_this();
3358 }
3359
3360 const size_t indent = strm.Printf("[%3u] ", image_idx);
3361 PrintModule(*target, module, indent, strm);
3362 }
3364 } else {
3365 if (argc) {
3366 if (use_global_module_list)
3367 result.AppendError(
3368 "the global module list has no matching modules");
3369 else
3370 result.AppendError("the target has no matching modules");
3371 } else {
3372 if (use_global_module_list)
3373 result.AppendError("the global module list is empty");
3374 else
3375 result.AppendError(
3376 "the target has no associated executable images");
3377 }
3378 return;
3379 }
3380 }
3381
3382 void PrintModule(Target &target, Module *module, int indent, Stream &strm) {
3383 if (module == nullptr) {
3384 strm.PutCString("Null module");
3385 return;
3386 }
3387
3388 bool dump_object_name = false;
3389 if (m_options.m_format_array.empty()) {
3390 m_options.m_format_array.push_back(std::make_pair('u', 0));
3391 m_options.m_format_array.push_back(std::make_pair('h', 0));
3392 m_options.m_format_array.push_back(std::make_pair('f', 0));
3393 m_options.m_format_array.push_back(std::make_pair('S', 0));
3394 }
3395 const size_t num_entries = m_options.m_format_array.size();
3396 bool print_space = false;
3397 for (size_t i = 0; i < num_entries; ++i) {
3398 if (print_space)
3399 strm.PutChar(' ');
3400 print_space = true;
3401 const char format_char = m_options.m_format_array[i].first;
3402 uint32_t width = m_options.m_format_array[i].second;
3403 switch (format_char) {
3404 case 'A':
3405 DumpModuleArchitecture(strm, module, false, width);
3406 break;
3407
3408 case 't':
3409 DumpModuleArchitecture(strm, module, true, width);
3410 break;
3411
3412 case 'f':
3413 DumpFullpath(strm, &module->GetFileSpec(), width);
3414 dump_object_name = true;
3415 break;
3416
3417 case 'd':
3418 DumpDirectory(strm, &module->GetFileSpec(), width);
3419 break;
3420
3421 case 'b':
3422 DumpBasename(strm, &module->GetFileSpec(), width);
3423 dump_object_name = true;
3424 break;
3425
3426 case 'h':
3427 case 'o':
3428 // Image header address
3429 {
3430 uint32_t addr_nibble_width =
3431 target.GetArchitecture().GetAddressByteSize() * 2;
3432
3433 ObjectFile *objfile = module->GetObjectFile();
3434 if (objfile) {
3435 Address base_addr(objfile->GetBaseAddress());
3436 if (base_addr.IsValid()) {
3437 if (target.HasLoadedSections()) {
3438 lldb::addr_t load_addr = base_addr.GetLoadAddress(&target);
3439 if (load_addr == LLDB_INVALID_ADDRESS) {
3440 base_addr.Dump(&strm, &target,
3443 } else {
3444 if (format_char == 'o') {
3445 // Show the offset of slide for the image
3446 strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3447 addr_nibble_width,
3448 load_addr - base_addr.GetFileAddress());
3449 } else {
3450 // Show the load address of the image
3451 strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3452 addr_nibble_width, load_addr);
3453 }
3454 }
3455 break;
3456 }
3457 // The address was valid, but the image isn't loaded, output the
3458 // address in an appropriate format
3459 base_addr.Dump(&strm, &target, Address::DumpStyleFileAddress);
3460 break;
3461 }
3462 }
3463 strm.Printf("%*s", addr_nibble_width + 2, "");
3464 }
3465 break;
3466
3467 case 'r': {
3468 size_t ref_count = 0;
3469 char in_shared_cache = 'Y';
3470
3471 ModuleSP module_sp(module->shared_from_this());
3472 if (!ModuleList::ModuleIsInCache(module))
3473 in_shared_cache = 'N';
3474 if (module_sp) {
3475 // Take one away to make sure we don't count our local "module_sp"
3476 ref_count = module_sp.use_count() - 1;
3477 }
3478 if (width)
3479 strm.Printf("{%c %*" PRIu64 "}", in_shared_cache, width, (uint64_t)ref_count);
3480 else
3481 strm.Printf("{%c %" PRIu64 "}", in_shared_cache, (uint64_t)ref_count);
3482 } break;
3483
3484 case 's':
3485 case 'S': {
3486 if (const SymbolFile *symbol_file = module->GetSymbolFile()) {
3487 const FileSpec symfile_spec =
3488 symbol_file->GetObjectFile()->GetFileSpec();
3489 if (format_char == 'S') {
3490 // Dump symbol file only if different from module file
3491 if (!symfile_spec || symfile_spec == module->GetFileSpec()) {
3492 print_space = false;
3493 break;
3494 }
3495 // Add a newline and indent past the index
3496 strm.Printf("\n%*s", indent, "");
3497 }
3498 DumpFullpath(strm, &symfile_spec, width);
3499 dump_object_name = true;
3500 break;
3501 }
3502 strm.Printf("%.*s", width, "<NONE>");
3503 } break;
3504
3505 case 'm':
3506 strm.Format("{0:%c}", llvm::fmt_align(module->GetModificationTime(),
3507 llvm::AlignStyle::Left, width));
3508 break;
3509
3510 case 'p':
3511 strm.Printf("%p", static_cast<void *>(module));
3512 break;
3513
3514 case 'u':
3515 DumpModuleUUID(strm, module);
3516 break;
3517
3518 default:
3519 break;
3520 }
3521 }
3522 if (dump_object_name) {
3523 if (llvm::StringRef object_name = module->GetObjectName();
3524 !object_name.empty())
3525 strm.Format("({0})", object_name);
3526 std::optional<addr_t> memory_addr = module->GetMemoryModuleAddress();
3527 if (memory_addr.has_value())
3528 strm.Printf("(0x%" PRIx64 ")", memory_addr.value());
3529 }
3530 strm.EOL();
3531 }
3532
3534};
3535
3536#pragma mark CommandObjectTargetModulesShowUnwind
3537
3538// Lookup unwind information in images
3539#define LLDB_OPTIONS_target_modules_show_unwind
3540#include "CommandOptions.inc"
3541
3543public:
3544 enum {
3551 };
3552
3553 class CommandOptions : public Options {
3554 public:
3555 CommandOptions() = default;
3556
3557 ~CommandOptions() override = default;
3558
3559 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3560 ExecutionContext *execution_context) override {
3561 Status error;
3562
3563 const int short_option = m_getopt_table[option_idx].val;
3564
3565 switch (short_option) {
3566 case 'a': {
3567 m_str = std::string(option_arg);
3569 m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
3573 "invalid address string '%s'", option_arg.str().c_str());
3574 break;
3575 }
3576
3577 case 'n':
3578 m_str = std::string(option_arg);
3580 break;
3581
3582 case 'c':
3583 bool value, success;
3584 value = OptionArgParser::ToBoolean(option_arg, false, &success);
3585 if (success) {
3586 m_cached = value;
3587 } else {
3589 "invalid boolean value '{}' passed for -c option", option_arg);
3590 }
3591 break;
3592
3593 default:
3594 llvm_unreachable("Unimplemented option");
3595 }
3596
3597 return error;
3598 }
3599
3600 void OptionParsingStarting(ExecutionContext *execution_context) override {
3602 m_str.clear();
3604 m_cached = false;
3605 }
3606
3607 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3608 return llvm::ArrayRef(g_target_modules_show_unwind_options);
3609 }
3610
3611 // Instance variables to hold the values for command options.
3612
3613 int m_type = eLookupTypeInvalid; // Should be a eLookupTypeXXX enum after
3614 // parsing options
3615 std::string m_str; // Holds name lookup
3616 lldb::addr_t m_addr = LLDB_INVALID_ADDRESS; // Holds the address to lookup
3617 bool m_cached = true;
3618 };
3619
3622 interpreter, "target modules show-unwind",
3623 "Show synthesized unwind instructions for a function.", nullptr,
3624 eCommandRequiresTarget | eCommandRequiresProcess |
3625 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {}
3626
3628
3629 Options *GetOptions() override { return &m_options; }
3630
3631protected:
3632 void DoExecute(Args &command, CommandReturnObject &result) override {
3633 Target *target = m_exe_ctx.GetTargetPtr();
3634 Process *process = m_exe_ctx.GetProcessPtr();
3635 ABI *abi = nullptr;
3636 if (process)
3637 abi = process->GetABI().get();
3638
3639 if (process == nullptr) {
3640 result.AppendError(
3641 "You must have a process running to use this command.");
3642 return;
3643 }
3644
3645 ThreadList threads(process->GetThreadList());
3646 if (threads.GetSize() == 0) {
3647 result.AppendError("the process must be paused to use this command");
3648 return;
3649 }
3650
3651 ThreadSP thread(threads.GetThreadAtIndex(0));
3652 if (!thread) {
3653 result.AppendError("the process must be paused to use this command");
3654 return;
3655 }
3656
3657 SymbolContextList sc_list;
3658
3659 if (m_options.m_type == eLookupTypeFunctionOrSymbol) {
3660 ConstString function_name(m_options.m_str);
3661 ModuleFunctionSearchOptions function_options;
3662 function_options.include_symbols = true;
3663 function_options.include_inlines = false;
3664 target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto,
3665 function_options, sc_list);
3666 } else if (m_options.m_type == eLookupTypeAddress && target) {
3667 Address addr;
3668 if (target->ResolveLoadAddress(m_options.m_addr, addr)) {
3669 SymbolContext sc;
3670 ModuleSP module_sp(addr.GetModule());
3671 module_sp->ResolveSymbolContextForAddress(addr,
3672 eSymbolContextEverything, sc);
3673 if (sc.function || sc.symbol) {
3674 sc_list.Append(sc);
3675 }
3676 }
3677 } else {
3678 result.AppendError(
3679 "address-expression or function name option must be specified.");
3680 return;
3681 }
3682
3683 if (sc_list.GetSize() == 0) {
3684 result.AppendErrorWithFormat("no unwind data found that matches '%s'",
3685 m_options.m_str.c_str());
3686 return;
3687 }
3688
3689 for (const SymbolContext &sc : sc_list) {
3690 if (sc.symbol == nullptr && sc.function == nullptr)
3691 continue;
3692 if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr)
3693 continue;
3694 Address addr = sc.GetFunctionOrSymbolAddress();
3695 if (!addr.IsValid())
3696 continue;
3697 ConstString funcname(sc.GetFunctionName());
3698 if (funcname.IsEmpty())
3699 continue;
3700 addr_t start_addr = addr.GetLoadAddress(target);
3701 if (abi)
3702 start_addr = abi->FixCodeAddress(start_addr);
3703
3704 UnwindTable &uw_table = sc.module_sp->GetUnwindTable();
3705 FuncUnwindersSP func_unwinders_sp =
3706 m_options.m_cached
3707 ? uw_table.GetFuncUnwindersContainingAddress(Address(start_addr),
3708 sc)
3710 Address(start_addr), sc);
3711 if (!func_unwinders_sp)
3712 continue;
3713
3714 result.GetOutputStream().Format(
3715 "UNWIND PLANS for {0}`{1} (start addr {2:x})\n",
3716 sc.module_sp->GetPlatformFileSpec().GetFilename(), funcname,
3717 start_addr);
3718
3719 Args args;
3721 size_t count = args.GetArgumentCount();
3722 for (size_t i = 0; i < count; i++) {
3723 const char *trap_func_name = args.GetArgumentAtIndex(i);
3724 if (strcmp(funcname.GetCString(), trap_func_name) == 0)
3725 result.GetOutputStream().Printf(
3726 "This function is "
3727 "treated as a trap handler function via user setting.\n");
3728 }
3729 PlatformSP platform_sp(target->GetPlatform());
3730 if (platform_sp) {
3731 const std::vector<std::string> &trap_handler_names(
3732 platform_sp->GetTrapHandlerSymbolNames());
3733 for (const std::string &trap_name : trap_handler_names) {
3734 if (llvm::StringRef(trap_name) == funcname) {
3735 result.GetOutputStream().Printf(
3736 "This function's "
3737 "name is listed by the platform as a trap handler.\n");
3738 }
3739 }
3740 }
3741
3742 result.GetOutputStream().Printf("\n");
3743
3744 if (std::shared_ptr<const UnwindPlan> plan_sp =
3745 func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread)) {
3746 result.GetOutputStream().Format(
3747 "Asynchronous (not restricted to call-sites) UnwindPlan is '{0}'\n",
3748 plan_sp->GetSourceName());
3749 }
3750 if (std::shared_ptr<const UnwindPlan> plan_sp =
3751 func_unwinders_sp->GetUnwindPlanAtCallSite(*target, *thread)) {
3752 result.GetOutputStream().Format(
3753 "Synchronous (restricted to call-sites) UnwindPlan is '{0}'\n",
3754 plan_sp->GetSourceName());
3755 }
3756 if (std::shared_ptr<const UnwindPlan> plan_sp =
3757 func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread)) {
3758 result.GetOutputStream().Format("Fast UnwindPlan is '{0}'\n",
3759 plan_sp->GetSourceName());
3760 }
3761
3762 result.GetOutputStream().Printf("\n");
3763
3764 if (std::shared_ptr<const UnwindPlan> plan_sp =
3765 func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread)) {
3766 result.GetOutputStream().Printf(
3767 "Assembly language inspection UnwindPlan:\n");
3768 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3770 result.GetOutputStream().Printf("\n");
3771 }
3772
3773 if (std::shared_ptr<const UnwindPlan> plan_sp =
3774 func_unwinders_sp->GetObjectFileUnwindPlan(*target)) {
3775 result.GetOutputStream().Printf("object file UnwindPlan:\n");
3776 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3778 result.GetOutputStream().Printf("\n");
3779 }
3780
3781 if (std::shared_ptr<const UnwindPlan> plan_sp =
3782 func_unwinders_sp->GetObjectFileAugmentedUnwindPlan(*target,
3783 *thread)) {
3784 result.GetOutputStream().Printf("object file augmented UnwindPlan:\n");
3785 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3787 result.GetOutputStream().Printf("\n");
3788 }
3789
3790 if (std::shared_ptr<const UnwindPlan> plan_sp =
3791 func_unwinders_sp->GetEHFrameUnwindPlan(*target)) {
3792 result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
3793 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3795 result.GetOutputStream().Printf("\n");
3796 }
3797
3798 if (std::shared_ptr<const UnwindPlan> plan_sp =
3799 func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target,
3800 *thread)) {
3801 result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
3802 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3804 result.GetOutputStream().Printf("\n");
3805 }
3806
3807 if (std::shared_ptr<const UnwindPlan> plan_sp =
3808 func_unwinders_sp->GetDebugFrameUnwindPlan(*target)) {
3809 result.GetOutputStream().Printf("debug_frame UnwindPlan:\n");
3810 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3812 result.GetOutputStream().Printf("\n");
3813 }
3814
3815 if (std::shared_ptr<const UnwindPlan> plan_sp =
3816 func_unwinders_sp->GetDebugFrameAugmentedUnwindPlan(*target,
3817 *thread)) {
3818 result.GetOutputStream().Printf("debug_frame augmented UnwindPlan:\n");
3819 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3821 result.GetOutputStream().Printf("\n");
3822 }
3823
3824 if (std::shared_ptr<const UnwindPlan> plan_sp =
3825 func_unwinders_sp->GetArmUnwindUnwindPlan(*target)) {
3826 result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
3827 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3829 result.GetOutputStream().Printf("\n");
3830 }
3831
3832 if (std::shared_ptr<const UnwindPlan> plan_sp =
3833 func_unwinders_sp->GetSymbolFileUnwindPlan(*thread)) {
3834 result.GetOutputStream().Printf("Symbol file UnwindPlan:\n");
3835 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3837 result.GetOutputStream().Printf("\n");
3838 }
3839
3840 if (std::shared_ptr<const UnwindPlan> plan_sp =
3841 func_unwinders_sp->GetCompactUnwindUnwindPlan(*target)) {
3842 result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
3843 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3845 result.GetOutputStream().Printf("\n");
3846 }
3847
3848 if (std::shared_ptr<const UnwindPlan> plan_sp =
3849 func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread)) {
3850 result.GetOutputStream().Printf("Fast UnwindPlan:\n");
3851 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3853 result.GetOutputStream().Printf("\n");
3854 }
3855
3856 ABISP abi_sp = process->GetABI();
3857 if (abi_sp) {
3858 if (UnwindPlanSP plan_sp = abi_sp->CreateDefaultUnwindPlan()) {
3859 assert(((!plan_sp || plan_sp->GetRowCount() == 0 ||
3860 plan_sp->GetRowAtIndex(0)
3861 ->GetUnspecifiedRegistersAreUndefined())) &&
3862 "Default UnwindPlan must set "
3863 "UnspecifiedRegistersAreUndefined to true");
3864 result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
3865 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3867 result.GetOutputStream().Printf("\n");
3868 }
3869
3870 if (UnwindPlanSP plan_sp = abi_sp->CreateFunctionEntryUnwindPlan()) {
3871 result.GetOutputStream().Printf(
3872 "Arch default at entry point UnwindPlan:\n");
3873 plan_sp->Dump(result.GetOutputStream(), thread.get(),
3875 result.GetOutputStream().Printf("\n");
3876 }
3877 }
3878
3879 result.GetOutputStream().Printf("\n");
3880 }
3882 }
3883
3885};
3886
3887// Lookup information in images
3888#define LLDB_OPTIONS_target_modules_lookup
3889#include "CommandOptions.inc"
3890
3892public:
3893 enum {
3897 eLookupTypeFileLine, // Line is optional
3902 };
3903
3904 class CommandOptions : public Options {
3905 public:
3907
3908 ~CommandOptions() override = default;
3909
3910 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3911 ExecutionContext *execution_context) override {
3912 Status error;
3913
3914 const int short_option = m_getopt_table[option_idx].val;
3915
3916 switch (short_option) {
3917 case 'a': {
3919 m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
3921 } break;
3922
3923 case 'o':
3924 if (option_arg.getAsInteger(0, m_offset))
3926 "invalid offset string '%s'", option_arg.str().c_str());
3927 break;
3928
3929 case 's':
3930 m_str = std::string(option_arg);
3932 break;
3933
3934 case 'f':
3935 m_file.SetFile(option_arg, FileSpec::Style::native);
3937 break;
3938
3939 case 'i':
3940 m_include_inlines = false;
3941 break;
3942
3943 case 'l':
3944 if (option_arg.getAsInteger(0, m_line_number))
3946 "invalid line number string '%s'", option_arg.str().c_str());
3947 else if (m_line_number == 0)
3948 error = Status::FromErrorString("zero is an invalid line number");
3950 break;
3951
3952 case 'F':
3953 m_str = std::string(option_arg);
3955 break;
3956
3957 case 'n':
3958 m_str = std::string(option_arg);
3960 break;
3961
3962 case 't':
3963 m_str = std::string(option_arg);
3965 break;
3966
3967 case 'v':
3968 m_verbose = true;
3969 break;
3970
3971 case 'A':
3972 m_print_all = true;
3973 break;
3974
3975 case 'r':
3976 m_use_regex = true;
3977 break;
3978
3979 case '\x01':
3980 m_all_ranges = true;
3981 break;
3982 default:
3983 llvm_unreachable("Unimplemented option");
3984 }
3985
3986 return error;
3987 }
3988
3989 void OptionParsingStarting(ExecutionContext *execution_context) override {
3991 m_str.clear();
3992 m_file.Clear();
3994 m_offset = 0;
3995 m_line_number = 0;
3996 m_use_regex = false;
3997 m_include_inlines = true;
3998 m_all_ranges = false;
3999 m_verbose = false;
4000 m_print_all = false;
4001 }
4002
4003 Status OptionParsingFinished(ExecutionContext *execution_context) override {
4004 Status status;
4005 if (m_all_ranges && !m_verbose) {
4006 status =
4007 Status::FromErrorString("--show-variable-ranges must be used in "
4008 "conjunction with --verbose.");
4009 }
4010 return status;
4011 }
4012
4013 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
4014 return llvm::ArrayRef(g_target_modules_lookup_options);
4015 }
4016
4017 int m_type; // Should be a eLookupTypeXXX enum after parsing options
4018 std::string m_str; // Holds name lookup
4019 FileSpec m_file; // Files for file lookups
4020 lldb::addr_t m_addr; // Holds the address to lookup
4022 m_offset; // Subtract this offset from m_addr before doing lookups.
4023 uint32_t m_line_number; // Line number for file+line lookups
4024 bool m_use_regex; // Name lookups in m_str are regular expressions.
4025 bool m_include_inlines; // Check for inline entries when looking up by
4026 // file/line.
4027 bool m_all_ranges; // Print all ranges or single range.
4028 bool m_verbose; // Enable verbose lookup info
4029 bool m_print_all; // Print all matches, even in cases where there's a best
4030 // match.
4031 };
4032
4034 : CommandObjectParsed(interpreter, "target modules lookup",
4035 "Look up information within executable and "
4036 "dependent shared library images.",
4037 nullptr, eCommandRequiresTarget) {
4039 }
4040
4042
4043 Options *GetOptions() override { return &m_options; }
4044
4046 bool &syntax_error) {
4047 switch (m_options.m_type) {
4048 case eLookupTypeAddress:
4052 case eLookupTypeSymbol:
4053 default:
4054 return false;
4055 case eLookupTypeType:
4056 break;
4057 }
4058
4059 StackFrameSP frame = m_exe_ctx.GetFrameSP();
4060
4061 if (!frame)
4062 return false;
4063
4064 const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
4065
4066 if (!sym_ctx.module_sp)
4067 return false;
4068
4069 switch (m_options.m_type) {
4070 default:
4071 return false;
4072 case eLookupTypeType:
4073 if (!m_options.m_str.empty()) {
4075 *sym_ctx.module_sp, m_options.m_str.c_str(),
4076 m_options.m_use_regex)) {
4078 return true;
4079 }
4080 }
4081 break;
4082 }
4083
4084 return false;
4085 }
4086
4087 bool LookupInModule(CommandInterpreter &interpreter, Module *module,
4088 CommandReturnObject &result, bool &syntax_error) {
4089 switch (m_options.m_type) {
4090 case eLookupTypeAddress:
4091 if (m_options.m_addr != LLDB_INVALID_ADDRESS) {
4093 m_interpreter, result.GetOutputStream(), module,
4094 eSymbolContextEverything |
4095 (m_options.m_verbose
4096 ? static_cast<int>(eSymbolContextVariable)
4097 : 0),
4098 m_options.m_addr, m_options.m_offset, m_options.m_verbose,
4099 m_options.m_all_ranges)) {
4101 return true;
4102 }
4103 }
4104 break;
4105
4106 case eLookupTypeSymbol:
4107 if (!m_options.m_str.empty()) {
4109 module, m_options.m_str.c_str(),
4110 m_options.m_use_regex, m_options.m_verbose,
4111 m_options.m_all_ranges)) {
4113 return true;
4114 }
4115 }
4116 break;
4117
4119 if (m_options.m_file) {
4121 m_interpreter, result.GetOutputStream(), module,
4122 m_options.m_file, m_options.m_line_number,
4123 m_options.m_include_inlines, m_options.m_verbose,
4124 m_options.m_all_ranges)) {
4126 return true;
4127 }
4128 }
4129 break;
4130
4133 if (!m_options.m_str.empty()) {
4134 ModuleFunctionSearchOptions function_options;
4135 function_options.include_symbols =
4137 function_options.include_inlines = m_options.m_include_inlines;
4138
4140 module, m_options.m_str.c_str(),
4141 m_options.m_use_regex, function_options,
4142 m_options.m_verbose,
4143 m_options.m_all_ranges)) {
4145 return true;
4146 }
4147 }
4148 break;
4149
4150 case eLookupTypeType:
4151 if (!m_options.m_str.empty()) {
4153 GetTarget(), m_interpreter, result.GetOutputStream(), module,
4154 m_options.m_str.c_str(), m_options.m_use_regex)) {
4156 return true;
4157 }
4158 }
4159 break;
4160
4161 default:
4162 m_options.GenerateOptionUsage(
4163 result.GetErrorStream(), *this,
4164 GetCommandInterpreter().GetDebugger().GetTerminalWidth(),
4165 GetCommandInterpreter().GetDebugger().GetUseColor());
4166 syntax_error = true;
4167 break;
4168 }
4169
4171 return false;
4172 }
4173
4174protected:
4175 void DoExecute(Args &command, CommandReturnObject &result) override {
4176 Target *target = GetTarget();
4177 assert(target && "target guaranteed by eCommandRequiresTarget");
4178 bool syntax_error = false;
4179 uint32_t i;
4180 uint32_t num_successful_lookups = 0;
4181 // Dump all sections for all modules images
4182
4183 if (command.GetArgumentCount() == 0) {
4184 // Where it is possible to look in the current symbol context first,
4185 // try that. If this search was successful and --all was not passed,
4186 // don't print anything else.
4187 if (LookupHere(m_interpreter, result, syntax_error)) {
4188 result.GetOutputStream().EOL();
4189 num_successful_lookups++;
4190 if (!m_options.m_print_all) {
4192 return;
4193 }
4194 }
4195
4196 // Dump all sections for all other modules
4197
4198 const ModuleList &target_modules = target->GetImages();
4199 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
4200 if (target_modules.GetSize() == 0) {
4201 result.AppendError("the target has no associated executable images");
4202 return;
4203 }
4204
4205 for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
4206 if (LookupInModule(m_interpreter, module_sp.get(), result,
4207 syntax_error)) {
4208 result.GetOutputStream().EOL();
4209 num_successful_lookups++;
4210 }
4211 }
4212 } else {
4213 // Dump specified images (by basename or fullpath)
4214 const char *arg_cstr;
4215 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr &&
4216 !syntax_error;
4217 ++i) {
4218 ModuleList module_list;
4219 const size_t num_matches =
4220 FindModulesByName(target, arg_cstr, module_list, false);
4221 if (num_matches > 0) {
4222 for (size_t j = 0; j < num_matches; ++j) {
4223 Module *module = module_list.GetModulePointerAtIndex(j);
4224 if (module) {
4225 if (LookupInModule(m_interpreter, module, result, syntax_error)) {
4226 result.GetOutputStream().EOL();
4227 num_successful_lookups++;
4228 }
4229 }
4230 }
4231 } else
4233 "unable to find an image that matches '{0}'", arg_cstr);
4234 }
4235 }
4236
4237 if (num_successful_lookups > 0)
4239 else
4241 }
4242
4244};
4245
4246#pragma mark CommandObjectMultiwordImageSearchPaths
4247
4248// CommandObjectMultiwordImageSearchPaths
4249
4251 : public CommandObjectMultiword {
4252public:
4255 interpreter, "target modules search-paths",
4256 "Commands for managing module search paths for a target.",
4257 "target modules search-paths <subcommand> [<subcommand-options>]") {
4259 "add", CommandObjectSP(
4263 interpreter)));
4265 "insert",
4270 interpreter)));
4273 interpreter)));
4274 }
4275
4277};
4278
4279#pragma mark CommandObjectTargetModules
4280
4281// CommandObjectTargetModules
4282
4284public:
4285 // Constructors and Destructors
4287 : CommandObjectMultiword(interpreter, "target modules",
4288 "Commands for accessing information for one or "
4289 "more target modules.",
4290 "target modules <sub-command> ...") {
4292 "add", CommandObjectSP(new CommandObjectTargetModulesAdd(interpreter)));
4294 interpreter)));
4296 interpreter)));
4298 interpreter)));
4300 "lookup",
4303 "search-paths",
4307 "show-unwind",
4309 }
4310
4311 ~CommandObjectTargetModules() override = default;
4312
4313private:
4314 // For CommandObjectTargetModules only
4318};
4319
4321public:
4324 interpreter, "target symbols add",
4325 "Add a debug symbol file to one of the target's current modules by "
4326 "specifying a path to a debug symbols file or by using the options "
4327 "to specify a module.",
4328 "target symbols add <cmd-options> [<symfile>]",
4329 eCommandRequiresTarget),
4331 LLDB_OPT_SET_1, false, "shlib", 's', lldb::eModuleCompletion,
4333 "Locate the debug symbols for the shared library specified by "
4334 "name."),
4336 LLDB_OPT_SET_2, false, "frame", 'F',
4337 "Locate the debug symbols for the currently selected frame.", false,
4338 true),
4339 m_current_stack_option(LLDB_OPT_SET_2, false, "stack", 'S',
4340 "Locate the debug symbols for every frame in "
4341 "the current call stack.",
4342 false, true)
4343
4344 {
4352 m_option_group.Finalize();
4354 }
4355
4357
4358 Options *GetOptions() override { return &m_option_group; }
4359
4360protected:
4361 bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush,
4362 CommandReturnObject &result) {
4363 const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
4364 if (!symbol_fspec) {
4365 result.AppendError(
4366 "one or more executable image paths must be specified");
4367 return false;
4368 }
4369
4370 char symfile_path[PATH_MAX];
4371 symbol_fspec.GetPath(symfile_path, sizeof(symfile_path));
4372
4373 if (!module_spec.GetUUID().IsValid()) {
4374 if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
4375 module_spec.GetFileSpec().SetFilename(symbol_fspec.GetFilename());
4376 }
4377
4378 // Now module_spec represents a symbol file for a module that might exist
4379 // in the current target. Let's find possible matches.
4380 ModuleList matching_modules;
4381
4382 // First extract all module specs from the symbol file
4383 lldb_private::ModuleSpecList symfile_module_specs =
4385 0);
4386 if (symfile_module_specs.GetSize() > 0) {
4387 // Now extract the module spec that matches the target architecture
4388 ModuleSpec target_arch_module_spec;
4389 ModuleSpec symfile_module_spec;
4390 target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
4391 if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec,
4392 symfile_module_spec)) {
4393 if (symfile_module_spec.GetUUID().IsValid()) {
4394 // It has a UUID, look for this UUID in the target modules
4395 ModuleSpec symfile_uuid_module_spec;
4396 symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
4397 target->GetImages().FindModules(symfile_uuid_module_spec,
4398 matching_modules);
4399 }
4400 }
4401
4402 if (matching_modules.IsEmpty()) {
4403 // No matches yet. Iterate through the module specs to find a UUID
4404 // value that we can match up to an image in our target.
4405 const size_t num_symfile_module_specs = symfile_module_specs.GetSize();
4406 for (size_t i = 0;
4407 i < num_symfile_module_specs && matching_modules.IsEmpty(); ++i) {
4408 if (symfile_module_specs.GetModuleSpecAtIndex(
4409 i, symfile_module_spec)) {
4410 if (symfile_module_spec.GetUUID().IsValid()) {
4411 // It has a UUID. Look for this UUID in the target modules.
4412 ModuleSpec symfile_uuid_module_spec;
4413 symfile_uuid_module_spec.GetUUID() =
4414 symfile_module_spec.GetUUID();
4415 target->GetImages().FindModules(symfile_uuid_module_spec,
4416 matching_modules);
4417 }
4418 }
4419 }
4420 }
4421 }
4422
4423 // Just try to match up the file by basename if we have no matches at
4424 // this point. For example, module foo might have symbols in foo.debug.
4425 if (matching_modules.IsEmpty())
4426 target->GetImages().FindModules(module_spec, matching_modules);
4427
4428 while (matching_modules.IsEmpty()) {
4429 ConstString filename_no_extension(
4431 // Empty string returned, let's bail
4432 if (!filename_no_extension)
4433 break;
4434
4435 // Check if there was no extension to strip and the basename is the same
4436 if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
4437 break;
4438
4439 // Replace basename with one fewer extension
4440 module_spec.GetFileSpec().SetFilename(filename_no_extension);
4441 target->GetImages().FindModules(module_spec, matching_modules);
4442 }
4443
4444 if (matching_modules.GetSize() > 1) {
4445 result.AppendErrorWithFormat("multiple modules match symbol file '%s', "
4446 "use the --uuid option to resolve the "
4447 "ambiguity",
4448 symfile_path);
4449 return false;
4450 }
4451
4452 if (matching_modules.GetSize() == 1) {
4453 ModuleSP module_sp(matching_modules.GetModuleAtIndex(0));
4454
4455 // The module has not yet created its symbol vendor, we can just give
4456 // the existing target module the symfile path to use for when it
4457 // decides to create it!
4458 module_sp->SetSymbolFileFileSpec(symbol_fspec);
4459
4460 SymbolFile *symbol_file =
4461 module_sp->GetSymbolFile(true, &result.GetErrorStream());
4462 if (symbol_file) {
4463 ObjectFile *object_file = symbol_file->GetObjectFile();
4464 if (object_file && object_file->GetFileSpec() == symbol_fspec) {
4465 // Provide feedback that the symfile has been successfully added.
4466 const FileSpec &module_fs = module_sp->GetFileSpec();
4468 "symbol file '{0}' has been added to '{1}'", symfile_path,
4469 module_fs.GetPath().c_str());
4470
4471 // Let clients know something changed in the module if it is
4472 // currently loaded
4473 ModuleList module_list;
4474 module_list.Append(module_sp);
4475 target->SymbolsDidLoad(module_list);
4476
4477 // Make sure we load any scripting resources that may be embedded
4478 // in the debug info files in case the platform supports that.
4479 std::list<Status> errors;
4480 module_list.LoadScriptingResourcesInTarget(target, errors);
4481 for (const auto &err : errors)
4482 result.AppendWarning(err.AsCString());
4483
4484 flush = true;
4486 return true;
4487 }
4488 }
4489 // Clear the symbol file spec if anything went wrong
4490 module_sp->SetSymbolFileFileSpec(FileSpec());
4491 }
4492
4493 StreamString ss_symfile_uuid;
4494 if (module_spec.GetUUID().IsValid()) {
4495 ss_symfile_uuid << " (";
4496 module_spec.GetUUID().Dump(ss_symfile_uuid);
4497 ss_symfile_uuid << ')';
4498 }
4499 result.AppendErrorWithFormat(
4500 "symbol file '%s'%s does not match any existing module%s", symfile_path,
4501 ss_symfile_uuid.GetData(),
4502 !llvm::sys::fs::is_regular_file(symbol_fspec.GetPath())
4503 ? "\n please specify the full path to the symbol file"
4504 : "");
4505 return false;
4506 }
4507
4509 CommandReturnObject &result, bool &flush) {
4510 Status error;
4512 if (module_spec.GetSymbolFileSpec())
4513 return AddModuleSymbols(m_exe_ctx.GetTargetPtr(), module_spec, flush,
4514 result);
4515 } else {
4516 result.SetError(std::move(error));
4517 }
4518 return false;
4519 }
4520
4521 bool AddSymbolsForUUID(CommandReturnObject &result, bool &flush) {
4522 assert(m_uuid_option_group.GetOptionValue().OptionWasSet());
4523
4524 ModuleSpec module_spec;
4525 module_spec.GetUUID() =
4526 m_uuid_option_group.GetOptionValue().GetCurrentValue();
4527
4528 if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) {
4529 StreamString error_strm;
4530 error_strm.PutCString("unable to find debug symbols for UUID ");
4531 module_spec.GetUUID().Dump(error_strm);
4532 result.AppendError(error_strm.GetString());
4533 return false;
4534 }
4535
4536 return true;
4537 }
4538
4539 bool AddSymbolsForFile(CommandReturnObject &result, bool &flush) {
4540 assert(m_file_option.GetOptionValue().OptionWasSet());
4541
4542 ModuleSpec module_spec;
4543 module_spec.GetFileSpec() =
4544 m_file_option.GetOptionValue().GetCurrentValue();
4545
4546 Target *target = m_exe_ctx.GetTargetPtr();
4547
4548 ModuleSP module_sp(target->GetImages().FindFirstModule(module_spec));
4549 if (module_sp) {
4550 module_spec.GetFileSpec() = module_sp->GetFileSpec();
4551 module_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec();
4552 module_spec.GetUUID() = module_sp->GetUUID();
4553 module_spec.GetArchitecture() = module_sp->GetArchitecture();
4554 } else {
4555 module_spec.GetArchitecture() = target->GetArchitecture();
4556 }
4557
4558 if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) {
4559 StreamString error_strm;
4560 error_strm.PutCString(
4561 "unable to find debug symbols for the executable file ");
4562 error_strm << module_spec.GetFileSpec();
4563 result.AppendError(error_strm.GetString());
4564 return false;
4565 }
4566
4567 return true;
4568 }
4569
4570 bool AddSymbolsForFrame(CommandReturnObject &result, bool &flush) {
4571 assert(m_current_frame_option.GetOptionValue().OptionWasSet());
4572
4573 Process *process = m_exe_ctx.GetProcessPtr();
4574 if (!process) {
4575 result.AppendError(
4576 "a process must exist in order to use the --frame option");
4577 return false;
4578 }
4579
4580 const StateType process_state = process->GetState();
4581 if (!StateIsStoppedState(process_state, true)) {
4582 result.AppendErrorWithFormat("process is not stopped: %s",
4583 StateAsCString(process_state));
4584 return false;
4585 }
4586
4587 StackFrame *frame = m_exe_ctx.GetFramePtr();
4588 if (!frame) {
4589 result.AppendError("invalid current frame");
4590 return false;
4591 }
4592
4593 ModuleSP frame_module_sp(
4594 frame->GetSymbolContext(eSymbolContextModule).module_sp);
4595 if (!frame_module_sp) {
4596 result.AppendError("frame has no module");
4597 return false;
4598 }
4599
4600 ModuleSpec module_spec;
4601 module_spec.GetUUID() = frame_module_sp->GetUUID();
4602 module_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
4603 module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
4604
4605 if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) {
4606 result.AppendError("unable to find debug symbols for the current frame");
4607 return false;
4608 }
4609
4610 return true;
4611 }
4612
4613 bool AddSymbolsForStack(CommandReturnObject &result, bool &flush) {
4614 assert(m_current_stack_option.GetOptionValue().OptionWasSet());
4615
4616 Process *process = m_exe_ctx.GetProcessPtr();
4617 if (!process) {
4618 result.AppendError(
4619 "a process must exist in order to use the --stack option");
4620 return false;
4621 }
4622
4623 const StateType process_state = process->GetState();
4624 if (!StateIsStoppedState(process_state, true)) {
4625 result.AppendErrorWithFormat("process is not stopped: %s",
4626 StateAsCString(process_state));
4627 return false;
4628 }
4629
4630 Thread *thread = m_exe_ctx.GetThreadPtr();
4631 if (!thread) {
4632 result.AppendError("invalid current thread");
4633 return false;
4634 }
4635
4636 bool symbols_found = false;
4637 uint32_t frame_count = thread->GetStackFrameCount();
4638 for (uint32_t i = 0; i < frame_count; ++i) {
4639 lldb::StackFrameSP frame_sp = thread->GetStackFrameAtIndex(i);
4640
4641 ModuleSP frame_module_sp(
4642 frame_sp->GetSymbolContext(eSymbolContextModule).module_sp);
4643 if (!frame_module_sp)
4644 continue;
4645
4646 ModuleSpec module_spec;
4647 module_spec.GetUUID() = frame_module_sp->GetUUID();
4648 module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
4649 module_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
4650
4651 bool current_frame_flush = false;
4652 if (DownloadObjectAndSymbolFile(module_spec, result, current_frame_flush))
4653 symbols_found = true;
4654 flush |= current_frame_flush;
4655 }
4656
4657 if (!symbols_found) {
4658 result.AppendError(
4659 "unable to find debug symbols in the current call stack");
4660 return false;
4661 }
4662
4663 return true;
4664 }
4665
4666 void DoExecute(Args &args, CommandReturnObject &result) override {
4667 Target *target = m_exe_ctx.GetTargetPtr();
4669 bool flush = false;
4670 ModuleSpec module_spec;
4671 const bool uuid_option_set =
4672 m_uuid_option_group.GetOptionValue().OptionWasSet();
4673 const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
4674 const bool frame_option_set =
4675 m_current_frame_option.GetOptionValue().OptionWasSet();
4676 const bool stack_option_set =
4677 m_current_stack_option.GetOptionValue().OptionWasSet();
4678 const size_t argc = args.GetArgumentCount();
4679
4680 if (argc == 0) {
4681 if (uuid_option_set)
4682 AddSymbolsForUUID(result, flush);
4683 else if (file_option_set)
4684 AddSymbolsForFile(result, flush);
4685 else if (frame_option_set)
4686 AddSymbolsForFrame(result, flush);
4687 else if (stack_option_set)
4688 AddSymbolsForStack(result, flush);
4689 else
4690 result.AppendError("one or more symbol file paths must be specified, "
4691 "or options must be specified");
4692 } else {
4693 if (uuid_option_set) {
4694 result.AppendError("specify either one or more paths to symbol files "
4695 "or use the --uuid option without arguments");
4696 } else if (frame_option_set) {
4697 result.AppendError("specify either one or more paths to symbol files "
4698 "or use the --frame option without arguments");
4699 } else if (file_option_set && argc > 1) {
4700 result.AppendError("specify at most one symbol file path when "
4701 "--shlib option is set");
4702 } else {
4703 PlatformSP platform_sp(target->GetPlatform());
4704
4705 for (auto &entry : args.entries()) {
4706 if (!entry.ref().empty()) {
4707 auto &symbol_file_spec = module_spec.GetSymbolFileSpec();
4708 symbol_file_spec.SetFile(entry.ref(), FileSpec::Style::native);
4709 FileSystem::Instance().Resolve(symbol_file_spec);
4710 if (file_option_set) {
4711 module_spec.GetFileSpec() =
4712 m_file_option.GetOptionValue().GetCurrentValue();
4713 }
4714 if (platform_sp) {
4715 FileSpec symfile_spec;
4716 if (platform_sp
4717 ->ResolveSymbolFile(*target, module_spec, symfile_spec)
4718 .Success())
4719 module_spec.GetSymbolFileSpec() = symfile_spec;
4720 }
4721
4722 bool symfile_exists =
4724
4725 if (symfile_exists) {
4726 if (!AddModuleSymbols(target, module_spec, flush, result))
4727 break;
4728 } else {
4729 std::string resolved_symfile_path =
4730 module_spec.GetSymbolFileSpec().GetPath();
4731 if (resolved_symfile_path != entry.ref()) {
4732 result.AppendErrorWithFormat(
4733 "invalid module path '%s' with resolved path '%s'",
4734 entry.c_str(), resolved_symfile_path.c_str());
4735 break;
4736 }
4737 result.AppendErrorWithFormat("invalid module path '%s'",
4738 entry.c_str());
4739 break;
4740 }
4741 }
4742 }
4743 }
4744 }
4745
4746 if (flush) {
4747 Process *process = m_exe_ctx.GetProcessPtr();
4748 if (process)
4749 process->Flush();
4750 }
4751 }
4752
4758};
4759
4760#pragma mark CommandObjectTargetSymbols
4761
4762// CommandObjectTargetSymbols
4763
4765public:
4766 // Constructors and Destructors
4769 interpreter, "target symbols",
4770 "Commands for adding and managing debug symbol files.",
4771 "target symbols <sub-command> ...") {
4773 "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter)));
4774 }
4775
4776 ~CommandObjectTargetSymbols() override = default;
4777
4778private:
4779 // For CommandObjectTargetModules only
4783};
4784
4785#pragma mark CommandObjectTargetStopHookAdd
4786
4787// CommandObjectTargetStopHookAdd
4788#define LLDB_OPTIONS_target_stop_hook_add
4789#include "CommandOptions.inc"
4790
4793public:
4795 public:
4797
4798 ~CommandOptions() override = default;
4799
4800 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
4801 return llvm::ArrayRef(g_target_stop_hook_add_options);
4802 }
4803
4804 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
4805 ExecutionContext *execution_context) override {
4806 Status error;
4807 const int short_option =
4808 g_target_stop_hook_add_options[option_idx].short_option;
4809
4810 switch (short_option) {
4811 case 'c':
4812 m_class_name = std::string(option_arg);
4813 m_sym_ctx_specified = true;
4814 break;
4815
4816 case 'e':
4817 if (option_arg.getAsInteger(0, m_line_end)) {
4819 "invalid end line number: \"%s\"", option_arg.str().c_str());
4820 break;
4821 }
4822 m_sym_ctx_specified = true;
4823 break;
4824
4825 case 'G': {
4826 bool value, success;
4827 value = OptionArgParser::ToBoolean(option_arg, false, &success);
4828 if (success) {
4829 m_auto_continue = value;
4830 } else
4832 "invalid boolean value '%s' passed for -G option",
4833 option_arg.str().c_str());
4834 } break;
4835 case 'l':
4836 if (option_arg.getAsInteger(0, m_line_start)) {
4838 "invalid start line number: \"%s\"", option_arg.str().c_str());
4839 break;
4840 }
4841 m_sym_ctx_specified = true;
4842 break;
4843
4844 case 'i':
4845 m_no_inlines = true;
4846 break;
4847
4848 case 'n':
4849 m_function_name = std::string(option_arg);
4850 m_func_name_type_mask |= eFunctionNameTypeAuto;
4851 m_sym_ctx_specified = true;
4852 break;
4853
4854 case 'f':
4855 m_file_name = std::string(option_arg);
4856 m_sym_ctx_specified = true;
4857 break;
4858
4859 case 's':
4860 m_module_name = std::string(option_arg);
4861 m_sym_ctx_specified = true;
4862 break;
4863
4864 case 't':
4865 if (option_arg.getAsInteger(0, m_thread_id))
4867 "invalid thread id string '%s'", option_arg.str().c_str());
4868 m_thread_specified = true;
4869 break;
4870
4871 case 'T':
4872 m_thread_name = std::string(option_arg);
4873 m_thread_specified = true;
4874 break;
4875
4876 case 'q':
4877 m_queue_name = std::string(option_arg);
4878 m_thread_specified = true;
4879 break;
4880
4881 case 'x':
4882 if (option_arg.getAsInteger(0, m_thread_index))
4884 "invalid thread index string '%s'", option_arg.str().c_str());
4885 m_thread_specified = true;
4886 break;
4887
4888 case 'o':
4889 m_use_one_liner = true;
4890 m_one_liner.push_back(std::string(option_arg));
4891 break;
4892
4893 case 'I': {
4894 bool value, success;
4895 value = OptionArgParser::ToBoolean(option_arg, false, &success);
4896 if (success)
4897 m_at_initial_stop = value;
4898 else
4900 "invalid boolean value '%s' passed for -F option",
4901 option_arg.str().c_str());
4902 } break;
4903
4904 default:
4905 llvm_unreachable("Unimplemented option");
4906 }
4907 return error;
4908 }
4909
4910 void OptionParsingStarting(ExecutionContext *execution_context) override {
4911 m_class_name.clear();
4912 m_function_name.clear();
4913 m_line_start = 0;
4915 m_file_name.clear();
4916 m_module_name.clear();
4917 m_func_name_type_mask = eFunctionNameTypeAuto;
4920 m_thread_name.clear();
4921 m_queue_name.clear();
4922
4923 m_no_inlines = false;
4924 m_sym_ctx_specified = false;
4925 m_thread_specified = false;
4926
4927 m_use_one_liner = false;
4928 m_one_liner.clear();
4929 m_auto_continue = false;
4930 m_at_initial_stop = true;
4931 }
4932
4933 std::string m_class_name;
4934 std::string m_function_name;
4935 uint32_t m_line_start = 0;
4937 std::string m_file_name;
4938 std::string m_module_name;
4940 eFunctionNameTypeAuto; // A pick from lldb::FunctionNameType.
4943 std::string m_thread_name;
4944 std::string m_queue_name;
4946 bool m_no_inlines = false;
4948 // Instance variables to hold the values for one_liner options.
4949 bool m_use_one_liner = false;
4950 std::vector<std::string> m_one_liner;
4952
4953 bool m_auto_continue = false;
4954 };
4955
4957 : CommandObjectParsed(interpreter, "target stop-hook add",
4958 "Add a hook to be executed when the target stops."
4959 "The hook can either be a list of commands or an "
4960 "appropriately defined Python class. You can also "
4961 "add filters so the hook only runs a certain stop "
4962 "points.",
4963 "target stop-hook add", eCommandAllowsDummyTarget),
4966 m_python_class_options("scripted stop-hook", true, 'P') {
4968 R"(
4969Command Based stop-hooks:
4970-------------------------
4971 Stop hooks can run a list of lldb commands by providing one or more
4972 --one-liner options. The commands will get run in the order they are added.
4973 Or you can provide no commands, in which case you will enter a command editor
4974 where you can enter the commands to be run.
4975
4976Python Based Stop Hooks:
4977------------------------
4978 Stop hooks can be implemented with a suitably defined Python class, whose name
4979 is passed in the --python-class option.
4980
4981 When the stop hook is added, the class is initialized by calling:
4982
4983 def __init__(self, target, extra_args, internal_dict):
4984
4985 target: The target that the stop hook is being added to.
4986 extra_args: An SBStructuredData Dictionary filled with the -key -value
4987 option pairs passed to the command.
4988 dict: An implementation detail provided by lldb.
4989
4990 Then when the stop-hook triggers, lldb will run the 'handle_stop' method.
4991 The method has the signature:
4993 def handle_stop(self, exe_ctx, stream):
4994
4995 exe_ctx: An SBExecutionContext for the thread that has stopped.
4996 stream: An SBStream, anything written to this stream will be printed in the
4997 the stop message when the process stops.
4998
4999 Return Value: The method returns "should_stop". If should_stop is false
5000 from all the stop hook executions on threads that stopped
5001 with a reason, then the process will continue. Note that this
5002 will happen only after all the stop hooks are run.
5003
5004Filter Options:
5005---------------
5006 Stop hooks can be set to always run, or to only run when the stopped thread
5007 matches the filter options passed on the command line. The available filter
5008 options include a shared library or a thread or queue specification,
5009 a line range in a source file, a function name or a class name.
5010 )");
5013 LLDB_OPT_SET_FROM_TO(4, 6));
5014 m_all_options.Append(&m_options);
5015 m_all_options.Finalize();
5016 }
5017
5018 ~CommandObjectTargetStopHookAdd() override = default;
5019
5020 Options *GetOptions() override { return &m_all_options; }
5021
5022protected:
5023 void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
5024 if (interactive) {
5025 if (lldb::LockableStreamFileSP output_sp =
5026 io_handler.GetOutputStreamFileSP()) {
5027 LockedStreamFile locked_stream = output_sp->Lock();
5028 locked_stream.PutCString(
5029 "Enter your stop hook command(s). Type 'DONE' to end.\n");
5030 }
5031 }
5032 }
5033
5034 void IOHandlerInputComplete(IOHandler &io_handler,
5035 std::string &line) override {
5036 if (m_stop_hook_sp) {
5037 if (line.empty()) {
5038 if (lldb::LockableStreamFileSP error_sp =
5039 io_handler.GetErrorStreamFileSP()) {
5040 LockedStreamFile locked_stream = error_sp->Lock();
5041 locked_stream.Printf("error: stop hook #%" PRIu64
5042 " aborted, no commands.\n",
5043 m_stop_hook_sp->GetID());
5044 }
5046 } else {
5047 // The IOHandler editor is only for command lines stop hooks:
5048 Target::StopHookCommandLine *hook_ptr =
5049 static_cast<Target::StopHookCommandLine *>(m_stop_hook_sp.get());
5050
5051 hook_ptr->SetActionFromString(line);
5052 if (lldb::LockableStreamFileSP output_sp =
5053 io_handler.GetOutputStreamFileSP()) {
5054 LockedStreamFile locked_stream = output_sp->Lock();
5055 locked_stream.Printf("Stop hook #%" PRIu64 " added.\n",
5056 m_stop_hook_sp->GetID());
5057 }
5058 }
5059 m_stop_hook_sp.reset();
5060 }
5061 io_handler.SetIsDone(true);
5062 }
5063
5064 void DoExecute(Args &command, CommandReturnObject &result) override {
5065 m_stop_hook_sp.reset();
5066
5067 Target *target = GetTarget();
5068 assert(target && "target guaranteed by eCommandRequiresTarget");
5069 Target::StopHookSP new_hook_sp = target->CreateStopHook(
5070 m_python_class_options.GetName().empty()
5071 ? Target::StopHook::StopHookKind::CommandBased
5072 : Target::StopHook::StopHookKind::ScriptBased);
5073
5074 // First step, make the specifier.
5075 std::unique_ptr<SymbolContextSpecifier> specifier_up;
5076 if (m_options.m_sym_ctx_specified) {
5077 specifier_up =
5078 std::make_unique<SymbolContextSpecifier>(target->shared_from_this());
5079
5080 if (!m_options.m_module_name.empty()) {
5081 specifier_up->AddSpecification(
5082 m_options.m_module_name.c_str(),
5084 }
5085
5086 if (!m_options.m_class_name.empty()) {
5087 specifier_up->AddSpecification(
5088 m_options.m_class_name.c_str(),
5090 }
5091
5092 if (!m_options.m_file_name.empty()) {
5093 specifier_up->AddSpecification(m_options.m_file_name.c_str(),
5095 }
5096
5097 if (m_options.m_line_start != 0) {
5098 specifier_up->AddLineSpecification(
5099 m_options.m_line_start,
5101 }
5102
5103 if (m_options.m_line_end != UINT_MAX) {
5104 specifier_up->AddLineSpecification(
5106 }
5107
5108 if (!m_options.m_function_name.empty()) {
5109 specifier_up->AddSpecification(
5110 m_options.m_function_name.c_str(),
5112 }
5113 }
5114
5115 if (specifier_up)
5116 new_hook_sp->SetSpecifier(specifier_up.release());
5117
5118 // Should we run at the initial stop:
5119 new_hook_sp->SetRunAtInitialStop(m_options.m_at_initial_stop);
5120
5121 // Next see if any of the thread options have been entered:
5122
5123 if (m_options.m_thread_specified) {
5124 ThreadSpec *thread_spec = new ThreadSpec();
5125
5126 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) {
5127 thread_spec->SetTID(m_options.m_thread_id);
5128 }
5129
5130 if (m_options.m_thread_index != UINT32_MAX)
5131 thread_spec->SetIndex(m_options.m_thread_index);
5132
5133 if (!m_options.m_thread_name.empty())
5134 thread_spec->SetName(m_options.m_thread_name.c_str());
5136 if (!m_options.m_queue_name.empty())
5137 thread_spec->SetQueueName(m_options.m_queue_name.c_str());
5138
5139 new_hook_sp->SetThreadSpecifier(thread_spec);
5140 }
5141
5142 new_hook_sp->SetAutoContinue(m_options.m_auto_continue);
5144 // This is a command line stop hook:
5145 Target::StopHookCommandLine *hook_ptr =
5146 static_cast<Target::StopHookCommandLine *>(new_hook_sp.get());
5148 result.AppendMessageWithFormatv("Stop hook #{0} added.",
5149 new_hook_sp->GetID());
5150 } else if (!m_python_class_options.GetName().empty()) {
5151 // This is a scripted stop hook:
5152 Target::StopHookScripted *hook_ptr =
5153 static_cast<Target::StopHookScripted *>(new_hook_sp.get());
5154 ScriptedMetadata scripted_metadata(
5155 m_python_class_options.GetName(),
5156 m_python_class_options.GetStructuredData());
5157 Status error = hook_ptr->SetScriptCallback(scripted_metadata);
5158 if (error.Success())
5159 result.AppendMessageWithFormatv("Stop hook #{0} added.",
5160 new_hook_sp->GetID());
5161 else {
5162 // FIXME: Set the stop hook ID counter back.
5163 result.AppendErrorWithFormat("Couldn't add stop hook: %s",
5164 error.AsCString());
5165 target->UndoCreateStopHook(new_hook_sp->GetID());
5166 return;
5167 }
5168 } else {
5169 m_stop_hook_sp = new_hook_sp;
5170 m_interpreter.GetLLDBCommandsFromIOHandler("> ", // Prompt
5171 *this); // IOHandlerDelegate
5172 }
5174 }
5175
5176private:
5178 OptionGroupPythonClassWithDict m_python_class_options;
5179 OptionGroupOptions m_all_options;
5180
5182};
5183
5184#pragma mark CommandObjectTargetStopHookDelete
5185
5186// CommandObjectTargetStopHookDelete
5187
5189public:
5192 interpreter, "target stop-hook delete", "Delete a stop-hook.",
5193 "target stop-hook delete [<idx>]", eCommandAllowsDummyTarget) {
5195 R"(
5196Deletes the stop hook by index.
5197
5198At any given stop, all enabled stop hooks that pass the stop filter will
5199get a chance to run. That means if one stop-hook deletes another stop hook
5200while executing, the deleted stop hook will still fire for the stop at which
5201it was deleted.
5202 )");
5204 }
5205
5206 ~CommandObjectTargetStopHookDelete() override = default;
5207
5208 void
5210 OptionElementVector &opt_element_vector) override {
5211 if (request.GetCursorIndex())
5212 return;
5213 CommandObject::HandleArgumentCompletion(request, opt_element_vector);
5214 }
5215
5216protected:
5217 void DoExecute(Args &command, CommandReturnObject &result) override {
5218 Target *target = GetTarget();
5219 assert(target && "target guaranteed by eCommandRequiresTarget");
5220 // FIXME: see if we can use the breakpoint id style parser?
5221 size_t num_args = command.GetArgumentCount();
5222 if (num_args == 0) {
5223 if (!m_interpreter.Confirm("Delete all stop hooks?", true)) {
5225 return;
5226 } else {
5227 target->RemoveAllStopHooks();
5228 }
5229 } else {
5230 for (size_t i = 0; i < num_args; i++) {
5231 lldb::user_id_t user_id;
5232 if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
5233 result.AppendErrorWithFormat("invalid stop hook id: \"%s\"",
5234 command.GetArgumentAtIndex(i));
5235 return;
5236 }
5237 if (!target->RemoveStopHookByID(user_id)) {
5238 result.AppendErrorWithFormat("unknown stop hook id: \"%s\"",
5239 command.GetArgumentAtIndex(i));
5240 return;
5241 }
5242 }
5243 }
5245 }
5246};
5247
5248#pragma mark CommandObjectTargetStopHookEnableDisable
5249
5250// CommandObjectTargetStopHookEnableDisable
5251
5253public:
5255 bool enable, const char *name,
5256 const char *help, const char *syntax)
5257 : CommandObjectParsed(interpreter, name, help, syntax,
5258 eCommandAllowsDummyTarget),
5259 m_enable(enable) {
5261 }
5262
5264
5265 void
5267 OptionElementVector &opt_element_vector) override {
5268 if (request.GetCursorIndex())
5269 return;
5270 CommandObject::HandleArgumentCompletion(request, opt_element_vector);
5271 }
5272
5273protected:
5274 void DoExecute(Args &command, CommandReturnObject &result) override {
5275 Target *target = GetTarget();
5276 assert(target && "target guaranteed by eCommandRequiresTarget");
5277 // FIXME: see if we can use the breakpoint id style parser?
5278 size_t num_args = command.GetArgumentCount();
5279 bool success;
5280
5281 if (num_args == 0) {
5283 } else {
5284 for (size_t i = 0; i < num_args; i++) {
5285 lldb::user_id_t user_id;
5286 if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
5287 result.AppendErrorWithFormat("invalid stop hook id: \"%s\"",
5288 command.GetArgumentAtIndex(i));
5289 return;
5290 }
5291 success = target->SetStopHookActiveStateByID(user_id, m_enable);
5292 if (!success) {
5293 result.AppendErrorWithFormat("unknown stop hook id: \"%s\"",
5294 command.GetArgumentAtIndex(i));
5295 return;
5296 }
5297 }
5298 }
5300 }
5301
5302private:
5304};
5305
5306#pragma mark CommandObjectTargetStopHookList
5307
5308// CommandObjectTargetStopHookList
5309#define LLDB_OPTIONS_target_stop_hook_list
5310#include "CommandOptions.inc"
5311
5313public:
5315 : CommandObjectParsed(interpreter, "target stop-hook list",
5316 "List all stop-hooks.", nullptr,
5317 eCommandAllowsDummyTarget) {}
5318
5320
5321 Options *GetOptions() override { return &m_options; }
5322
5323 class CommandOptions : public Options {
5324 public:
5325 CommandOptions() = default;
5326 ~CommandOptions() override = default;
5327
5328 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
5329 ExecutionContext *execution_context) override {
5330 Status error;
5331 const int short_option = m_getopt_table[option_idx].val;
5332
5333 switch (short_option) {
5334 case 'i':
5335 m_internal = true;
5336 break;
5337 default:
5338 llvm_unreachable("Unimplemented option");
5339 }
5340
5341 return error;
5342 }
5343
5344 void OptionParsingStarting(ExecutionContext *execution_context) override {
5345 m_internal = false;
5346 }
5347
5348 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
5349 return llvm::ArrayRef(g_target_stop_hook_list_options);
5350 }
5351
5352 // Instance variables to hold the values for command options.
5353 bool m_internal = false;
5354 };
5355
5356protected:
5357 void DoExecute(Args &command, CommandReturnObject &result) override {
5358 Target *target = GetTarget();
5359 assert(target && "target guaranteed by eCommandRequiresTarget");
5360 bool printed_hook = false;
5361 for (auto &hook : target->GetStopHooks(m_options.m_internal)) {
5362 if (printed_hook)
5363 result.GetOutputStream().PutCString("\n");
5364 hook->GetDescription(result.GetOutputStream(), eDescriptionLevelFull);
5365 printed_hook = true;
5366 }
5367
5368 if (!printed_hook)
5369 result.GetOutputStream().PutCString("No stop hooks.\n");
5370
5372 }
5373
5374private:
5376};
5377
5378#pragma mark CommandObjectMultiwordTargetStopHooks
5379
5380// CommandObjectMultiwordTargetStopHooks
5381
5383public:
5386 interpreter, "target stop-hook",
5387 "Commands for operating on debugger target stop-hooks.",
5388 "target stop-hook <subcommand> [<subcommand-options>]") {
5390 new CommandObjectTargetStopHookAdd(interpreter)));
5392 "delete",
5394 LoadSubCommand("disable",
5396 interpreter, false, "target stop-hook disable [<id>]",
5397 "Disable a stop-hook.", "target stop-hook disable")));
5398 LoadSubCommand("enable",
5400 interpreter, true, "target stop-hook enable [<id>]",
5401 "Enable a stop-hook.", "target stop-hook enable")));
5403 interpreter)));
5404 }
5405
5407};
5408
5409#pragma mark CommandObjectTargetHookAdd
5410
5411#define LLDB_OPTIONS_target_hook_add
5412#include "CommandOptions.inc"
5413
5416public:
5418 public:
5419 CommandOptions() = default;
5420 ~CommandOptions() override = default;
5421
5422 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
5423 return llvm::ArrayRef(g_target_hook_add_options);
5424 }
5425
5426 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
5427 ExecutionContext *execution_context) override {
5428 Status error;
5429 const int short_option =
5430 g_target_hook_add_options[option_idx].short_option;
5431 switch (short_option) {
5432 case 'o':
5433 m_use_one_liner = true;
5434 m_one_liner.push_back(std::string(option_arg));
5435 break;
5436 case 'L':
5437 m_on_load = true;
5438 break;
5439 case 'u':
5440 m_on_unload = true;
5441 break;
5442 case 'S':
5443 m_on_stop = true;
5444 break;
5445 case 's':
5446 m_module_name = std::string(option_arg);
5447 m_sym_ctx_specified = true;
5448 break;
5449 case 'x': {
5450 uint32_t thread_index;
5451 if (option_arg.getAsInteger(0, thread_index))
5452 error = Status::FromErrorStringWithFormat("invalid thread index '%s'",
5453 option_arg.str().c_str());
5454 else
5455 m_thread_index = thread_index;
5456 m_thread_specified = true;
5457 break;
5458 }
5459 case 't': {
5460 lldb::tid_t thread_id;
5461 if (option_arg.getAsInteger(0, thread_id))
5462 error = Status::FromErrorStringWithFormat("invalid thread id '%s'",
5463 option_arg.str().c_str());
5464 else
5465 m_thread_id = thread_id;
5466 m_thread_specified = true;
5467 break;
5468 }
5469 case 'T':
5470 m_thread_name = std::string(option_arg);
5471 m_thread_specified = true;
5472 break;
5473 case 'q':
5474 m_queue_name = std::string(option_arg);
5475 m_thread_specified = true;
5476 break;
5477 case 'f':
5478 m_file_name = std::string(option_arg);
5479 m_sym_ctx_specified = true;
5480 break;
5481 case 'l': {
5482 uint32_t line;
5483 if (option_arg.getAsInteger(0, line))
5485 "invalid start line number '%s'", option_arg.str().c_str());
5486 else
5487 m_line_start = line;
5488 m_sym_ctx_specified = true;
5489 break;
5490 }
5491 case 'e': {
5492 uint32_t line;
5493 if (option_arg.getAsInteger(0, line))
5495 "invalid end line number '%s'", option_arg.str().c_str());
5496 else
5497 m_line_end = line;
5498 m_sym_ctx_specified = true;
5499 break;
5500 }
5501 case 'c':
5502 m_class_name = std::string(option_arg);
5503 m_sym_ctx_specified = true;
5504 break;
5505 case 'n':
5506 m_function_name = std::string(option_arg);
5507 m_sym_ctx_specified = true;
5508 break;
5509 case 'G': {
5510 bool value, success;
5511 value = OptionArgParser::ToBoolean(option_arg, false, &success);
5512 if (success)
5513 m_auto_continue = value;
5514 else
5516 "invalid boolean value '%s' passed for -G option",
5517 option_arg.str().c_str());
5518 break;
5519 }
5520 case 'I': {
5521 bool value, success;
5522 value = OptionArgParser::ToBoolean(option_arg, true, &success);
5523 if (success)
5524 m_at_initial_stop = value;
5525 else
5527 "invalid boolean value '%s' passed for -I option",
5528 option_arg.str().c_str());
5529 break;
5530 }
5531 default:
5532 llvm_unreachable("unhandled option");
5533 }
5534 return error;
5535 }
5536
5537 void OptionParsingStarting(ExecutionContext *execution_context) override {
5538 m_use_one_liner = false;
5539 m_one_liner.clear();
5540 m_on_load = false;
5541 m_on_unload = false;
5542 m_on_stop = false;
5543 m_sym_ctx_specified = false;
5544 m_thread_specified = false;
5545 m_module_name.clear();
5546 m_file_name.clear();
5547 m_class_name.clear();
5548 m_function_name.clear();
5549 m_line_start = 0;
5550 m_line_end = UINT_MAX;
5553 m_thread_name.clear();
5554 m_queue_name.clear();
5555 m_auto_continue = false;
5556 m_at_initial_stop = true;
5557 }
5558
5559 std::vector<std::string> m_one_liner;
5560 bool m_use_one_liner = false;
5561 bool m_on_load = false;
5562 bool m_on_unload = false;
5563 bool m_on_stop = false;
5564
5565 // Filter options (for stop trigger).
5568 std::string m_module_name;
5569 std::string m_file_name;
5570 std::string m_class_name;
5571 std::string m_function_name;
5572 uint32_t m_line_start = 0;
5573 uint32_t m_line_end = UINT_MAX;
5576 std::string m_thread_name;
5577 std::string m_queue_name;
5578 bool m_auto_continue = false;
5580 };
5581
5584 interpreter, "target hook add",
5585 "Add a hook to be executed on target lifecycle events.",
5586 "target hook add", eCommandAllowsDummyTarget),
5589 m_python_class_options("scripted hook", false, 'P') {
5590 SetHelpLong(R"help(
5591Command-based hooks:
5592--------------------
5593 Specify which triggers the hook responds to with --on-load (-L),
5594 --on-unload (-u), and/or --on-stop (-S). At least one trigger is required.
5595 Provide commands with --one-liner (-o), or omit -o to enter an interactive
5596 command editor. All commands run for every trigger the hook is signed up
5597 for; there is no per-trigger command list.
5598
5599 Examples:
5600 target hook add -L -o "script print('module loaded')"
5601 target hook add -L -u -o "script print('module event')"
5602 target hook add -S -o "bt"
5603 target hook add -L -u -S -o "script print('all events')"
5604 target hook add -S -s mylib.so -n main -o "bt"
5605 target hook add -S -G true -o "thread info"
5607Python class hooks:
5608-------------------
5609 Provide a Python class with --python-class (-P). The class controls which
5610 events it handles by implementing the corresponding methods; you do not
5611 specify triggers on the command line. Use -k <key> -v <value> to pass
5612 extra_args to the class constructor.
5613
5614 Examples:
5615 target hook add -P mymodule.MyHook
5616 target hook add -P mymodule.MyHook -k verbose -v true
5618 The Python class should implement at least one of these methods:
5619
5620 class MyHook:
5621 def __init__(self, target, extra_args, internal_dict):
5622 self.target = target
5623 def handle_module_loaded(self, stream):
5624 pass
5625 def handle_module_unloaded(self, stream):
5626 pass
5627 def handle_stop(self, exe_ctx, stream):
5628 return True # True = should_stop, False = continue
5629
5630Filter options:
5631---------------
5632 Filters (-s, -f, -l, -e, -c, -n, -x, -t, -T, -q) restrict when the hook
5633 fires. They apply to both command-based and Python class hooks.
5634)help");
5635 // Python class options (-P, -k, -v) are placed in Set 2 (dst_mask).
5636 // src_mask must cover Set 1 | Set 2 to match the internal usage masks of
5637 // OptionGroupPythonClassWithDict (class=Set1, key/value=Set2).
5638 // Since -o, -L, -u, -S are Group<1> only, the parser prevents mixing.
5641 m_all_options.Append(&m_options);
5642 m_all_options.Finalize();
5643 }
5645 ~CommandObjectTargetHookAdd() override = default;
5646
5647 Options *GetOptions() override { return &m_all_options; }
5648
5649protected:
5650 void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
5651 if (interactive) {
5652 if (lldb::LockableStreamFileSP output_sp =
5653 io_handler.GetOutputStreamFileSP()) {
5654 LockedStreamFile locked_stream = output_sp->Lock();
5655 locked_stream.PutCString(
5656 "Enter your hook command(s). Type 'DONE' to end.\n");
5657 }
5658 }
5659 }
5660
5661 void IOHandlerInputComplete(IOHandler &io_handler,
5662 std::string &line) override {
5663 if (m_hook_sp) {
5664 if (line.empty()) {
5665 if (lldb::LockableStreamFileSP error_sp =
5666 io_handler.GetErrorStreamFileSP()) {
5667 LockedStreamFile locked_stream = error_sp->Lock();
5668 locked_stream.Printf("error: hook #%" PRIu64
5669 " aborted, no commands.\n",
5670 m_hook_sp->GetID());
5671 }
5672 GetTarget()->UndoCreateHook(m_hook_sp->GetID());
5673 } else {
5674 auto *hook = static_cast<Target::HookCommandLine *>(m_hook_sp.get());
5675 hook->SetActionFromString(line);
5676 if (lldb::LockableStreamFileSP output_sp =
5677 io_handler.GetOutputStreamFileSP()) {
5678 LockedStreamFile locked_stream = output_sp->Lock();
5679 locked_stream.Printf("Hook #%" PRIu64 " added.\n",
5680 m_hook_sp->GetID());
5681 }
5682 }
5683 m_hook_sp.reset();
5684 }
5685 io_handler.SetIsDone(true);
5686 }
5687
5688 void DoExecute(Args &command, CommandReturnObject &result) override {
5689 m_hook_sp.reset();
5690 Target *target = GetTarget();
5691 assert(target && "target guaranteed by eCommandRequiresTarget");
5692 bool is_python_class = !m_python_class_options.GetName().empty();
5693
5694 // Command-based hooks require at least one explicit trigger.
5695 if (!is_python_class && !m_options.m_on_load && !m_options.m_on_unload &&
5696 !m_options.m_on_stop) {
5697 result.AppendError("at least one trigger must be specified: "
5698 "--on-load (-L), --on-unload (-u), or --on-stop (-S)");
5699 return;
5700 }
5701
5702 Target::Hook::HookKind hook_kind =
5703 is_python_class ? Target::Hook::HookKind::ScriptBased
5704 : Target::Hook::HookKind::CommandBased;
5705
5706 Target::HookSP new_hook_sp = target->CreateHook(hook_kind);
5707
5708 if (!is_python_class) {
5709 // Build trigger mask from explicit command-line flags.
5710 auto *cmd_hook =
5711 static_cast<Target::HookCommandLine *>(new_hook_sp.get());
5712 uint32_t trigger_mask = 0;
5713 if (m_options.m_on_load)
5714 trigger_mask |= Target::Hook::kModulesLoaded;
5715 if (m_options.m_on_unload)
5716 trigger_mask |= Target::Hook::kModulesUnloaded;
5717 if (m_options.m_on_stop)
5718 trigger_mask |= Target::Hook::kProcessStop;
5719 cmd_hook->SetTriggerMask(trigger_mask);
5720 }
5721 // Python class hooks: triggers are computed in SetScriptCallback based
5722 // on which callback methods the class implements.
5723
5724 // Set up symbol context specifier if filter options were provided.
5725 if (m_options.m_sym_ctx_specified) {
5726 auto specifier_up =
5727 std::make_unique<SymbolContextSpecifier>(target->shared_from_this());
5728
5729 if (!m_options.m_module_name.empty())
5730 specifier_up->AddSpecification(
5731 m_options.m_module_name.c_str(),
5733
5734 if (!m_options.m_class_name.empty())
5735 specifier_up->AddSpecification(
5736 m_options.m_class_name.c_str(),
5738
5739 if (!m_options.m_file_name.empty())
5740 specifier_up->AddSpecification(m_options.m_file_name.c_str(),
5742
5743 if (m_options.m_line_start != 0)
5744 specifier_up->AddLineSpecification(
5745 m_options.m_line_start,
5747
5748 if (m_options.m_line_end != UINT_MAX)
5749 specifier_up->AddLineSpecification(
5751
5752 if (!m_options.m_function_name.empty())
5753 specifier_up->AddSpecification(
5754 m_options.m_function_name.c_str(),
5756
5757 new_hook_sp->SetSCSpecifier(specifier_up.release());
5758 }
5759
5760 // Set up thread specifier.
5761 if (m_options.m_thread_specified) {
5762 ThreadSpec *thread_spec = new ThreadSpec();
5763
5764 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
5765 thread_spec->SetTID(m_options.m_thread_id);
5767 if (m_options.m_thread_index != UINT32_MAX)
5768 thread_spec->SetIndex(m_options.m_thread_index);
5770 if (!m_options.m_thread_name.empty())
5771 thread_spec->SetName(m_options.m_thread_name.c_str());
5772
5773 if (!m_options.m_queue_name.empty())
5774 thread_spec->SetQueueName(m_options.m_queue_name.c_str());
5775
5776 new_hook_sp->SetThreadSpecifier(thread_spec);
5777 }
5778
5779 new_hook_sp->SetAutoContinue(m_options.m_auto_continue);
5780 new_hook_sp->SetRunAtInitialStop(m_options.m_at_initial_stop);
5781
5783 auto *hook = static_cast<Target::HookCommandLine *>(new_hook_sp.get());
5785 result.AppendMessageWithFormatv("Hook #{0} added.\n",
5786 new_hook_sp->GetID());
5787 } else if (!m_python_class_options.GetName().empty()) {
5788 auto *hook = static_cast<Target::HookScripted *>(new_hook_sp.get());
5789 ScriptedMetadata scripted_metadata(
5790 m_python_class_options.GetName(),
5791 m_python_class_options.GetStructuredData());
5792 Status callback_error = hook->SetScriptCallback(scripted_metadata);
5793 if (callback_error.Fail()) {
5794 result.AppendErrorWithFormat("couldn't add hook: %s",
5795 callback_error.AsCString());
5796 target->UndoCreateHook(new_hook_sp->GetID());
5797 return;
5798 }
5799 result.AppendMessageWithFormatv("Hook #{0} added.\n",
5800 new_hook_sp->GetID());
5801 } else {
5802 m_hook_sp = new_hook_sp;
5803 m_interpreter.GetLLDBCommandsFromIOHandler("> ", // prompt
5804 *this); // delegate
5805 }
5807 }
5808
5809private:
5811 OptionGroupPythonClassWithDict m_python_class_options;
5812 OptionGroupOptions m_all_options;
5814};
5815
5816#pragma mark CommandObjectTargetHookDelete
5817
5819public:
5821 : CommandObjectParsed(interpreter, "target hook delete", "Delete a hook.",
5822 "target hook delete [<id>]",
5823 eCommandAllowsDummyTarget) {
5825 }
5826
5828
5829protected:
5830 void DoExecute(Args &command, CommandReturnObject &result) override {
5831 Target *target = GetTarget();
5832 assert(target && "target guaranteed by eCommandRequiresTarget");
5833 if (command.GetArgumentCount() == 0) {
5834 if (!m_interpreter.Confirm("Delete all hooks?", true)) {
5836 return;
5837 }
5838 target->RemoveAllHooks();
5840 return;
5841 }
5842
5843 for (size_t i = 0; i < command.GetArgumentCount(); i++) {
5844 lldb::user_id_t user_id;
5845 if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
5846 result.AppendErrorWithFormat("invalid hook id: \"%s\"",
5847 command.GetArgumentAtIndex(i));
5848 return;
5849 }
5850 if (!target->RemoveHookByID(user_id)) {
5851 result.AppendErrorWithFormat("unknown hook id: \"%s\"",
5852 command.GetArgumentAtIndex(i));
5853 return;
5854 }
5855 }
5857 }
5858};
5859
5860#pragma mark CommandObjectTargetHookEnableDisable
5861
5863public:
5865 bool enable, const char *name,
5866 const char *help, const char *syntax)
5867 : CommandObjectParsed(interpreter, name, help, syntax,
5868 eCommandAllowsDummyTarget),
5869 m_enable(enable) {
5871 }
5872
5874
5875protected:
5876 void DoExecute(Args &command, CommandReturnObject &result) override {
5877 Target *target = GetTarget();
5878 assert(target && "target guaranteed by eCommandRequiresTarget");
5879 // No IDs = apply to all hooks.
5880 if (command.GetArgumentCount() == 0) {
5883 return;
5884 }
5885
5886 for (size_t i = 0; i < command.GetArgumentCount(); i++) {
5887 lldb::user_id_t user_id;
5888 if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
5889 result.AppendErrorWithFormat("invalid hook id: \"%s\"",
5890 command.GetArgumentAtIndex(i));
5891 return;
5892 }
5893 if (!target->SetHookEnabledStateByID(user_id, m_enable)) {
5894 result.AppendErrorWithFormat("unknown hook id: \"%s\"",
5895 command.GetArgumentAtIndex(i));
5896 return;
5897 }
5898 }
5900 }
5901
5902private:
5904};
5905
5906#pragma mark CommandObjectTargetHookModify
5907
5908#define LLDB_OPTIONS_target_hook_modify
5909#include "CommandOptions.inc"
5910
5911/// Modify trigger settings on a hook. Only valid for command-based hooks;
5912/// scripted hooks derive their triggers from the class methods.
5914public:
5915 class CommandOptions : public Options {
5916 public:
5917 CommandOptions() = default;
5918 ~CommandOptions() override = default;
5919
5920 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
5921 return llvm::ArrayRef(g_target_hook_modify_options);
5922 }
5923
5924 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
5925 ExecutionContext *execution_context) override {
5926 Status error;
5927 const int short_option =
5928 g_target_hook_modify_options[option_idx].short_option;
5929 switch (short_option) {
5930 case 'e':
5931 m_enable_trigger = option_arg.str();
5932 break;
5933 case 'd':
5934 m_disable_trigger = option_arg.str();
5935 break;
5936 default:
5937 llvm_unreachable("unhandled option");
5938 }
5939 return error;
5940 }
5941
5942 void OptionParsingStarting(ExecutionContext *execution_context) override {
5943 m_enable_trigger.clear();
5944 m_disable_trigger.clear();
5945 }
5946
5947 std::string m_enable_trigger;
5949 };
5950
5952 : CommandObjectParsed(interpreter, "target hook modify",
5953 "Modify trigger settings on a hook.",
5954 "target hook modify [--enable-trigger <name>] "
5955 "[--disable-trigger <name>] [<id>]",
5956 eCommandAllowsDummyTarget) {
5958 SetHelpLong(R"help(
5959Modify trigger settings on command-based hooks. Scripted hooks derive their
5960triggers from the class methods and cannot be modified.
5962If no hook ID is given, the last added hook is modified.
5964Valid trigger names: load, unload, stop.
5965
5966Examples:
5967 target hook modify --enable-trigger stop 1
5968 target hook modify --disable-trigger load 1
5969 target hook modify --enable-trigger stop (modifies last added hook)
5970)help");
5971 }
5972
5973 ~CommandObjectTargetHookModify() override = default;
5974
5975 Options *GetOptions() override { return &m_options; }
5977protected:
5978 static uint32_t ParseTriggerName(llvm::StringRef name) {
5979 if (name == "load")
5981 if (name == "unload")
5983 if (name == "stop")
5985 return 0;
5986 }
5987
5988 void DoExecute(Args &command, CommandReturnObject &result) override {
5989 Target *target = GetTarget();
5990 assert(target && "target guaranteed by eCommandRequiresTarget");
5991 if (m_options.m_enable_trigger.empty() &&
5992 m_options.m_disable_trigger.empty()) {
5993 result.AppendError("at least one of --enable-trigger or "
5994 "--disable-trigger must be specified");
5995 return;
5996 }
5997
5998 // Resolve the hook ID. Default to last added if not specified.
5999 Target::HookSP hook_sp;
6000 if (command.GetArgumentCount() == 0) {
6001 size_t num_hooks = target->GetNumHooks();
6002 if (num_hooks == 0) {
6003 result.AppendError("no hooks exist");
6004 return;
6005 }
6006 hook_sp = target->GetHookAtIndex(num_hooks - 1);
6007 } else {
6008 lldb::user_id_t user_id;
6009 if (!llvm::to_integer(command.GetArgumentAtIndex(0), user_id)) {
6010 result.AppendErrorWithFormat("invalid hook id: \"%s\"",
6011 command.GetArgumentAtIndex(0));
6012 return;
6013 }
6014 hook_sp = target->GetHookByID(user_id);
6015 if (!hook_sp) {
6016 result.AppendErrorWithFormat("unknown hook id: \"%s\"",
6017 command.GetArgumentAtIndex(0));
6018 return;
6019 }
6020 }
6021
6022 // Reject trigger modification on scripted hooks.
6023 if (hook_sp->GetHookKind() != Target::Hook::HookKind::CommandBased) {
6024 result.AppendError("cannot modify triggers on a scripted hook; "
6025 "triggers are determined by the class methods");
6026 return;
6027 }
6028 auto *cmd_hook = static_cast<Target::HookCommandLine *>(hook_sp.get());
6029
6030 if (!m_options.m_enable_trigger.empty()) {
6031 uint32_t trigger = ParseTriggerName(m_options.m_enable_trigger);
6032 if (!trigger) {
6033 result.AppendErrorWithFormat("unknown trigger name: \"%s\". "
6034 "Valid names: load, unload, stop",
6035 m_options.m_enable_trigger.c_str());
6036 return;
6037 }
6038 cmd_hook->AddTrigger(trigger);
6039 }
6040
6041 if (!m_options.m_disable_trigger.empty()) {
6042 uint32_t trigger = ParseTriggerName(m_options.m_disable_trigger);
6043 if (!trigger) {
6044 result.AppendErrorWithFormat("unknown trigger name: \"%s\". "
6045 "Valid names: load, unload, stop",
6046 m_options.m_disable_trigger.c_str());
6047 return;
6048 }
6049 cmd_hook->RemoveTrigger(trigger);
6050 }
6051
6053 }
6054
6055private:
6057};
6058
6059#pragma mark CommandObjectTargetHookList
6060
6062public:
6064 : CommandObjectParsed(interpreter, "target hook list", "List all hooks.",
6065 "target hook list", eCommandAllowsDummyTarget) {}
6066
6067 ~CommandObjectTargetHookList() override = default;
6068
6069protected:
6070 void DoExecute(Args &command, CommandReturnObject &result) override {
6071 Target *target = GetTarget();
6072 assert(target && "target guaranteed by eCommandRequiresTarget");
6073 size_t num_hooks = target->GetNumHooks();
6074 if (num_hooks == 0) {
6075 result.GetOutputStream().PutCString("No hooks.\n");
6076 } else {
6077 for (size_t i = 0; i < num_hooks; i++) {
6078 Target::HookSP hook_sp = target->GetHookAtIndex(i);
6079 if (hook_sp)
6080 hook_sp->GetDescription(result.GetOutputStream(),
6082 }
6083 }
6085 }
6086};
6087
6088#pragma mark CommandObjectMultiwordTargetHooks
6089
6091public:
6094 interpreter, "target hook",
6095 "Commands for operating on target hooks.",
6096 "target hook <subcommand> [<subcommand-options>]") {
6098 "add", CommandObjectSP(new CommandObjectTargetHookAdd(interpreter)));
6100 interpreter)));
6101 LoadSubCommand("disable",
6103 interpreter, false, "target hook disable",
6104 "Disable a hook.", "target hook disable [<id> ...]")));
6105 LoadSubCommand("enable",
6107 interpreter, true, "target hook enable",
6108 "Enable a hook.", "target hook enable [<id> ...]")));
6110 "list", CommandObjectSP(new CommandObjectTargetHookList(interpreter)));
6112 interpreter)));
6113 }
6114
6116};
6117
6118#pragma mark CommandObjectTargetDumpTypesystem
6119
6120/// Dumps the TypeSystem of the selected Target.
6122public:
6125 interpreter, "target dump typesystem",
6126 "Dump the state of the target's internal type system. Intended to "
6127 "be used for debugging LLDB itself.",
6128 nullptr, eCommandRequiresTarget) {}
6129
6131
6132protected:
6133 void DoExecute(Args &command, CommandReturnObject &result) override {
6134 // Go over every scratch TypeSystem and dump to the command output.
6135 for (lldb::TypeSystemSP ts : GetTarget()->GetScratchTypeSystems())
6136 if (ts)
6137 ts->Dump(result.GetOutputStream().AsRawOstream(), "",
6138 GetCommandInterpreter().GetDebugger().GetUseColor());
6139
6141 }
6142};
6143
6144#pragma mark CommandObjectTargetDumpSectionLoadList
6145
6146/// Dumps the SectionLoadList of the selected Target.
6148public:
6151 interpreter, "target dump section-load-list",
6152 "Dump the state of the target's internal section load list. "
6153 "Intended to be used for debugging LLDB itself.",
6154 nullptr, eCommandRequiresTarget) {}
6155
6157
6158protected:
6159 void DoExecute(Args &command, CommandReturnObject &result) override {
6160 Target *target = GetTarget();
6161 assert(target && "target guaranteed by eCommandRequiresTarget");
6162 target->DumpSectionLoadList(result.GetOutputStream());
6164 }
6165};
6166
6167#pragma mark CommandObjectTargetDump
6168
6169/// Multi-word command for 'target dump'.
6171public:
6172 // Constructors and Destructors
6175 interpreter, "target dump",
6176 "Commands for dumping information about the target.",
6177 "target dump [typesystem|section-load-list]") {
6179 "typesystem",
6181 LoadSubCommand("section-load-list",
6183 interpreter)));
6184 }
6185
6186 ~CommandObjectTargetDump() override = default;
6187};
6188
6189#pragma mark CommandObjectTargetFrameProvider
6190
6191#define LLDB_OPTIONS_target_frame_provider_register
6192#include "CommandOptions.inc"
6193
6195public:
6198 interpreter, "target frame-provider register",
6199 "Register frame provider for all threads in this target.", nullptr,
6200 eCommandRequiresTarget),
6201
6202 m_class_options("target frame-provider", true, 'C', 'k', 'v', 0) {
6205 m_all_options.Finalize();
6206 }
6207
6209
6210 Options *GetOptions() override { return &m_all_options; }
6211
6212 std::optional<std::string> GetRepeatCommand(Args &current_command_args,
6213 uint32_t index) override {
6214 return std::string("");
6215 }
6216
6217protected:
6218 void DoExecute(Args &command, CommandReturnObject &result) override {
6219 ScriptedMetadataSP metadata_sp = std::make_shared<ScriptedMetadata>(
6220 m_class_options.GetName(), m_class_options.GetStructuredData());
6221
6222 Target *target = m_exe_ctx.GetTargetPtr();
6223
6224 if (!target)
6225 target = &GetDebugger().GetDummyTarget();
6226
6227 // Create the interface for calling static methods.
6229 GetDebugger()
6232
6233 // Create a descriptor from the metadata (applies to all threads by
6234 // default).
6235 ScriptedFrameProviderDescriptor descriptor(metadata_sp);
6236 descriptor.interface_sp = interface_sp;
6237
6238 auto id_or_err = target->AddScriptedFrameProviderDescriptor(descriptor);
6239 if (!id_or_err) {
6240 result.SetError(id_or_err.takeError());
6241 return;
6242 }
6243
6245 "successfully registered scripted frame provider '{0}' for target",
6246 m_class_options.GetName().c_str());
6248 }
6249
6252};
6253
6255public:
6258 interpreter, "target frame-provider clear",
6259 "Clear all registered frame providers from this target.", nullptr,
6260 eCommandRequiresTarget) {}
6261
6263
6264protected:
6265 void DoExecute(Args &command, CommandReturnObject &result) override {
6266 Target *target = m_exe_ctx.GetTargetPtr();
6267 if (!target) {
6268 result.AppendError("invalid target");
6269 return;
6270 }
6271
6273
6275 }
6276};
6277
6279public:
6282 interpreter, "target frame-provider list",
6283 "List all registered frame providers for the target.", nullptr,
6284 eCommandRequiresTarget) {}
6285
6287
6288protected:
6289 void DoExecute(Args &command, CommandReturnObject &result) override {
6290 Target *target = m_exe_ctx.GetTargetPtr();
6291 if (!target)
6292 target = &GetDebugger().GetDummyTarget();
6293
6294 const auto &descriptors = target->GetScriptedFrameProviderDescriptors();
6295 if (descriptors.empty()) {
6296 result.AppendMessage("no frame providers registered for this target.");
6298 return;
6299 }
6300
6301 Stream &strm = result.GetOutputStream();
6302 strm << llvm::formatv("{0} frame provider(s) registered:\n\n",
6303 descriptors.size());
6304
6305 for (const auto &entry : descriptors) {
6306 const ScriptedFrameProviderDescriptor &descriptor = entry.second;
6307 descriptor.Dump(&strm);
6308 strm.PutChar('\n');
6309 }
6310
6312 }
6313};
6314
6316public:
6319 interpreter, "target frame-provider remove",
6320 "Remove a registered frame provider from the target by id.",
6321 "target frame-provider remove <provider-id>",
6322 eCommandRequiresTarget) {
6324 }
6325
6327
6328protected:
6329 void DoExecute(Args &command, CommandReturnObject &result) override {
6330 Target *target = m_exe_ctx.GetTargetPtr();
6331 if (!target)
6332 target = &GetDebugger().GetDummyTarget();
6333
6334 std::vector<uint32_t> removed_provider_ids;
6335 for (size_t i = 0; i < command.GetArgumentCount(); i++) {
6336 uint32_t provider_id = 0;
6337 if (!llvm::to_integer(command[i].ref(), provider_id)) {
6338 result.AppendError("target frame-provider remove requires integer "
6339 "provider id argument");
6340 return;
6341 }
6342
6343 if (!target->RemoveScriptedFrameProviderDescriptor(provider_id)) {
6344 result.AppendErrorWithFormat(
6345 "no frame provider named '%u' found in target", provider_id);
6346 return;
6347 }
6348 removed_provider_ids.push_back(provider_id);
6349 }
6350
6351 if (size_t num_removed_providers = removed_provider_ids.size()) {
6353 "Successfully removed {0} frame-providers.", num_removed_providers);
6355 } else {
6356 result.AppendError("0 frame providers removed.\n");
6357 }
6358 }
6359};
6360
6362public:
6365 interpreter, "target frame-provider",
6366 "Commands for registering and viewing frame providers for the "
6367 "target.",
6368 "target frame-provider [<sub-command-options>] ") {
6369 LoadSubCommand("register",
6371 interpreter)));
6372 LoadSubCommand("clear",
6374 new CommandObjectTargetFrameProviderClear(interpreter)));
6376 "list",
6379 "remove", CommandObjectSP(
6380 new CommandObjectTargetFrameProviderRemove(interpreter)));
6381 }
6382
6384};
6385
6386#pragma mark CommandObjectMultiwordTarget
6387
6388// CommandObjectMultiwordTarget
6389
6391 CommandInterpreter &interpreter)
6392 : CommandObjectMultiword(interpreter, "target",
6393 "Commands for operating on debugger targets.",
6394 "target <subcommand> [<subcommand-options>]") {
6395 LoadSubCommand("create",
6396 CommandObjectSP(new CommandObjectTargetCreate(interpreter)));
6397 LoadSubCommand("delete",
6398 CommandObjectSP(new CommandObjectTargetDelete(interpreter)));
6399 LoadSubCommand("dump",
6400 CommandObjectSP(new CommandObjectTargetDump(interpreter)));
6402 "frame-provider",
6404 LoadSubCommand("groups",
6405 CommandObjectSP(new CommandObjectTargetGroups(interpreter)));
6406 LoadSubCommand("list",
6407 CommandObjectSP(new CommandObjectTargetList(interpreter)));
6408 LoadSubCommand("select",
6409 CommandObjectSP(new CommandObjectTargetSelect(interpreter)));
6410 LoadSubCommand("show-launch-environment",
6412 interpreter)));
6414 "stop-hook",
6417 interpreter)));
6418 LoadSubCommand("modules",
6420 LoadSubCommand("symbols",
6422 LoadSubCommand("variable",
6424}
6425
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 llvm::StringRef GetTargetGroupRoleName(TargetGroup::Role role)
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:525
#define LLDB_LOGF(log,...)
Definition Log.h:389
#define LLDB_SCOPED_TIMERF(...)
Definition Timer.h:86
CommandObjectMultiwordTargetHooks(CommandInterpreter &interpreter)
~CommandObjectMultiwordTargetHooks() override=default
~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
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTargetFrameProviderClear(CommandInterpreter &interpreter)
~CommandObjectTargetFrameProviderClear() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetFrameProviderList() override=default
CommandObjectTargetFrameProviderList(CommandInterpreter &interpreter)
OptionGroupPythonClassWithDict m_class_options
~CommandObjectTargetFrameProviderRegister() override=default
CommandObjectTargetFrameProviderRegister(CommandInterpreter &interpreter)
std::optional< std::string > GetRepeatCommand(Args &current_command_args, uint32_t index) override
Get the command that appropriate for a "repeat" of the current command.
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetFrameProviderRemove() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTargetFrameProviderRemove(CommandInterpreter &interpreter)
~CommandObjectTargetFrameProvider() override=default
CommandObjectTargetFrameProvider(CommandInterpreter &interpreter)
void DoExecute(Args &args, CommandReturnObject &result) override
CommandObjectTargetGroupsList(CommandInterpreter &interpreter)
~CommandObjectTargetGroupsList() override=default
~CommandObjectTargetGroups() override=default
CommandObjectTargetGroups(CommandInterpreter &interpreter)
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
CommandObjectTargetHookAdd(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
OptionGroupPythonClassWithDict m_python_class_options
void IOHandlerInputComplete(IOHandler &io_handler, std::string &line) override
Called when a line or lines have been retrieved.
~CommandObjectTargetHookAdd() override=default
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override
CommandObjectTargetHookDelete(CommandInterpreter &interpreter)
~CommandObjectTargetHookDelete() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetHookEnableDisable() override=default
CommandObjectTargetHookEnableDisable(CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax)
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTargetHookList(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTargetHookList() override=default
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
Modify trigger settings on a hook.
void DoExecute(Args &command, CommandReturnObject &result) override
static uint32_t ParseTriggerName(llvm::StringRef name)
CommandObjectTargetHookModify(CommandInterpreter &interpreter)
~CommandObjectTargetHookModify() 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
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)
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
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:141
A section + offset based address class.
Definition Address.h:62
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
Definition Address.cpp:303
bool SetLoadAddress(lldb::addr_t load_addr, Target *target, bool allow_section_end=false)
Set the address to represent load_addr.
Definition Address.cpp:1029
@ 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:398
lldb::ModuleSP GetModule() const
Get accessor for the module for this address.
Definition Address.cpp:275
lldb::addr_t GetFileAddress() const
Get the file address.
Definition Address.cpp:283
bool IsValid() const
Check if the object state is valid.
Definition Address.h:355
An architecture specification class.
Definition ArchSpec.h:32
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
Definition ArchSpec.cpp:894
bool IsValid() const
Tests if this ArchSpec is valid.
Definition ArchSpec.h:455
void DumpTriple(llvm::raw_ostream &s) const
const char * GetArchitectureName() const
Returns a static string representing the current architecture.
Definition ArchSpec.cpp:745
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
size_t size() const
Definition Args.h:139
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
bool empty() const
Definition Args.h:122
static bool InvokeCommonCompletionCallbacks(CommandInterpreter &interpreter, uint32_t completion_mask, lldb_private::CompletionRequest &request, SearchFilter *searcher)
bool Confirm(llvm::StringRef message, bool default_answer)
ExecutionContext GetExecutionContext(bool adopt_dummy_target=true) const
Returns the execution context the interpreter should run a command in.
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)
virtual const char * GetInvalidTargetDescription()
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,...
Target * GetTarget()
Get the target this command should operate on.
void AppendMessage(llvm::StringRef in_string)
void AppendError(llvm::StringRef in_string)
const ValueObjectList & GetValueObjectList() const
void AppendWarningWithFormatv(const char *format, Args &&...args)
void SetStatus(lldb::ReturnStatus status)
void AppendErrorWithFormat(const char *format,...) __attribute__((format(printf
void void AppendMessageWithFormatv(const char *format, Args &&...args)
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
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:103
TargetList & GetTargetList()
Get accessor for the target list.
Definition Debugger.h:223
TargetGroupList & GetTargetGroupList()
Definition Debugger.h:225
bool GetUseColor() const
Definition Debugger.cpp:543
llvm::StringRef GetRegexMatchAnsiSuffix() const
Definition Debugger.cpp:685
Target & GetDummyTarget()
Definition Debugger.h:567
llvm::StringRef GetRegexMatchAnsiPrefix() const
Definition Debugger.cpp:679
ScriptInterpreter * GetScriptInterpreter(bool can_create=true, std::optional< lldb::ScriptLanguage > language={})
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:56
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
Definition FileSpec.cpp:174
llvm::StringRef GetFileNameStrippingExtension() const
Return the filename without the extension part.
Definition FileSpec.cpp:414
void SetFilename(llvm::StringRef filename)
Filename string set accessor.
Definition FileSpec.cpp:363
llvm::StringRef GetFilename() const
Filename string const get accessor.
Definition FileSpec.h:248
llvm::StringRef GetDirectory() const
Directory string const get accessor.
Definition FileSpec.h:233
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition FileSpec.cpp:380
void SetDirectory(llvm::StringRef directory)
Directory string set accessor.
Definition FileSpec.cpp:358
void Dump(llvm::raw_ostream &s) const
Dump this object to a Stream.
Definition FileSpec.cpp:341
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()
void Resolve(llvm::SmallVectorImpl< char > &path, bool force_make_absolute=false)
Resolve path to make it canonical.
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:128
void FindFunctions(ConstString name, lldb::FunctionNameType name_type_mask, const ModuleFunctionSearchOptions &options, SymbolContextList &sc_list) const
ModuleIterableNoLocking ModulesNoLocking() const
Definition ModuleList.h:580
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:255
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)
bool LoadScriptingResourcesInTarget(Target *target, std::list< Status > &errors, bool continue_on_error=true)
ModuleIterable Modules() const
Definition ModuleList.h:574
size_t GetSize() const
Gets the size of the module list.
bool GetModuleSpecAtIndex(size_t i, ModuleSpec &module_spec) const
Definition ModuleSpec.h:386
bool FindMatchingModuleSpec(const ModuleSpec &module_spec, ModuleSpec &match_module_spec) const
Definition ModuleSpec.h:396
FileSpec & GetPlatformFileSpec()
Definition ModuleSpec.h:69
FileSpec & GetFileSpec()
Definition ModuleSpec.h:57
ArchSpec & GetArchitecture()
Definition ModuleSpec.h:93
FileSpec * GetFileSpecPtr()
Definition ModuleSpec.h:51
FileSpec & GetSymbolFileSpec()
Definition ModuleSpec.h:81
A class that describes an executable image and its associated object and symbol files.
Definition Module.h:91
const lldb_private::UUID & GetUUID()
Get a reference to the UUID value contained in this object.
Definition Module.cpp:337
virtual SymbolFile * GetSymbolFile(bool can_create=true, Stream *feedback_strm=nullptr)
Get the module's symbol file.
Definition Module.cpp:975
static Module * GetAllocatedModuleAtIndex(size_t idx)
Definition Module.cpp:120
llvm::StringRef GetObjectName() const
Definition Module.cpp:1176
static std::recursive_mutex & GetAllocationModuleCollectionMutex()
Definition Module.cpp:103
bool ResolveFileAddress(lldb::addr_t vm_addr, Address &so_addr)
Definition Module.cpp:421
Symtab * GetSymtab(bool can_create=true)
Get the module's symbol table.
Definition Module.cpp:1002
bool MatchesModuleSpec(const ModuleSpec &module_ref)
Definition Module.cpp:1467
static size_t GetNumberAllocatedModules()
Definition Module.cpp:114
const ArchSpec & GetArchitecture() const
Get const accessor for the module architecture.
Definition Module.cpp:1017
std::string GetSpecificationDescription() const
Get the module path and object name.
Definition Module.cpp:1019
const FileSpec & GetFileSpec() const
Get const accessor for the module file specification.
Definition Module.h:447
const llvm::sys::TimePoint & GetModificationTime() const
Definition Module.h:485
A plug-in interface definition class for object file parsers.
Definition ObjectFile.h:46
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:459
virtual FileSpec & GetFileSpec()
Get accessor to the object file specification.
Definition ObjectFile.h:281
static ModuleSpecList GetModuleSpecifications(const FileSpec &file, lldb::offset_t file_offset, lldb::offset_t file_size, lldb::DataExtractorSP=lldb::DataExtractorSP())
virtual lldb_private::Address GetBaseAddress()
Returns base address of this object file.
Definition ObjectFile.h:469
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
bool RemapPath(llvm::StringRef path, std::string &new_path) const
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 GetPathsAtIndex(uint32_t idx, std::string &path, std::string &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:369
ThreadList & GetThreadList()
Definition Process.h:2370
void Flush()
Flush all data in the process.
Definition Process.cpp:6273
lldb::StateType GetState()
Get accessor for the current process state.
Definition Process.cpp:1319
const lldb::ABISP & GetABI()
Definition Process.cpp:1529
bool IsValid() const
Test if this object contains a valid regular expression.
virtual lldb::ScriptedFrameProviderInterfaceSP CreateScriptedFrameProviderInterface()
lldb::SectionSP FindSectionByName(llvm::StringRef section_name) const
Definition Section.cpp:562
void Dump(llvm::raw_ostream &s, unsigned indent, Target *target, bool show_header, uint32_t depth) const
Definition Section.cpp:648
This base class provides an interface to stack frames.
Definition StackFrame.h:44
virtual const SymbolContext & GetSymbolContext(lldb::SymbolContextItem resolve_scope)
Provide a SymbolContext for this StackFrame's current pc value.
virtual 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:293
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition Status.cpp:194
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)
Forwards the arguments to llvm::formatv and writes to the stream.
Definition Stream.h:370
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
Definition Stream.h:405
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:63
size_t PutChar(char ch)
Definition Stream.cpp:131
void SetIndentLevel(unsigned level)
Set the current indentation level.
Definition Stream.cpp:196
void PutCStringColorHighlighted(llvm::StringRef text, std::optional< HighlightSettings > settings=std::nullopt)
Output a C string to the stream with color highlighting.
Definition Stream.cpp:73
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:204
void IndentMore(unsigned amount=2)
Increment the current indentation level.
Definition Stream.cpp:201
unsigned GetIndentLevel() const
Get the current indentation level.
Definition Stream.cpp:193
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:191
bool GetByteSizeIsValid() const
Definition Symbol.h:237
Address & GetAddressRef()
Definition Symbol.h:78
lldb::addr_t GetByteSize() const
Definition Symbol.cpp:469
ConstString GetDisplayName() const
Definition Symbol.cpp:199
uint64_t GetRawValue() const
Get the raw value of the symbol from the symbol table.
Definition Symbol.h:119
Symbol * SymbolAtIndex(size_t idx)
Definition Symtab.cpp:226
uint32_t AppendSymbolIndexesWithName(ConstString symbol_name, std::vector< uint32_t > &matches)
Definition Symtab.cpp:661
uint32_t AppendSymbolIndexesMatchingRegExAndType(const RegularExpression &regex, lldb::SymbolType symbol_type, std::vector< uint32_t > &indexes, Mangled::NamePreference name_preference=Mangled::ePreferDemangled)
Definition Symtab.cpp:728
A thread-safe collection of target groups.
std::vector< lldb::TargetGroupSP > GetGroups() const
Return a snapshot of the target groups.
Role
Describes the part a target plays in this group.
Definition TargetGroup.h:37
lldb::TargetSP GetTargetAtIndex(uint32_t index) const
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.
uint32_t GetIndexOfTarget(lldb::TargetSP target_sp) const
void SetSelectedTarget(uint32_t index)
bool DeleteTarget(lldb::TargetSP &target_sp)
Delete a Target object from the list.
lldb::TargetSP GetSelectedTarget()
size_t GetNumTargets() const
bool GetUserSpecifiedTrapHandlerNames(Args &args) const
Definition Target.cpp:5861
Environment GetEnvironment() const
Definition Target.cpp:5496
void SetActionFromStrings(const std::vector< std::string > &strings)
Populate the command list from a vector of individual command strings.
Definition Target.cpp:4605
void SetActionFromString(const std::string &strings)
Definition Target.cpp:4311
void SetActionFromStrings(const std::vector< std::string > &strings)
Definition Target.cpp:4315
Status SetScriptCallback(const ScriptedMetadata &scripted_metadata)
Definition Target.cpp:4357
void ModulesDidLoad(ModuleList &module_list)
This call may preload module symbols, and may do so in parallel depending on the following target set...
Definition Target.cpp:1975
llvm::Expected< uint32_t > AddScriptedFrameProviderDescriptor(const ScriptedFrameProviderDescriptor &descriptor)
Add or update a scripted frame provider descriptor for this target.
Definition Target.cpp:3921
Module * GetExecutableModulePointer()
Definition Target.cpp:1664
bool RemoveHookByID(lldb::user_id_t uid)
Definition Target.cpp:4851
PathMappingList & GetImageSearchPathList()
Definition Target.cpp:2738
size_t GetNumHooks() const
Definition Target.h:1967
std::shared_ptr< StopHook > StopHookSP
Definition Target.h:1777
void SymbolsDidLoad(ModuleList &module_list)
Definition Target.cpp:2003
const std::vector< StopHookSP > GetStopHooks(bool internal=false) const
Definition Target.cpp:3259
const llvm::MapVector< uint32_t, ScriptedFrameProviderDescriptor > & GetScriptedFrameProviderDescriptors() const
Get all scripted frame provider descriptors for this target.
Definition Target.cpp:3982
bool RemoveScriptedFrameProviderDescriptor(uint32_t id)
Remove a scripted frame provider descriptor by id.
Definition Target.cpp:3957
HookSP CreateHook(Hook::HookKind kind)
Definition Target.cpp:4829
void DumpSectionLoadList(Stream &s)
Definition Target.cpp:6141
bool SetHookEnabledStateByID(lldb::user_id_t uid, bool enabled)
Definition Target.cpp:4873
const lldb::ProcessSP & GetProcessSP() const
Definition Target.cpp:331
lldb::ModuleSP GetOrCreateModule(const ModuleSpec &module_spec, bool notify, Status *error_ptr=nullptr, bool invoke_symbol_locators=true)
Find a binary on the system and return its Module, or return an existing Module that is already in th...
Definition Target.cpp:2484
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:3211
bool ResolveLoadAddress(lldb::addr_t load_addr, Address &so_addr, uint32_t stop_id=SectionLoadHistory::eStopIDNow, bool allow_section_end=false)
Definition Target.cpp:3521
HookSP GetHookByID(lldb::user_id_t uid)
Definition Target.cpp:4858
bool SetStopHookActiveStateByID(lldb::user_id_t uid, bool active_state)
Definition Target.cpp:3235
void SetAllStopHooksActiveState(bool active_state)
Definition Target.cpp:3246
StopHookSP CreateStopHook(StopHook::StopHookKind kind, bool internal=false)
Add an empty stop hook to the Target's stop hook list, and returns a shared pointer to the new hook.
Definition Target.cpp:3189
void SetAllHooksEnabledState(bool enabled)
Definition Target.cpp:4881
void UndoCreateHook(lldb::user_id_t uid)
Removes the most recently created hook.
Definition Target.cpp:4844
HookSP GetHookAtIndex(size_t index)
Definition Target.cpp:4865
lldb::PlatformSP GetPlatform()
Definition Target.h:2007
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition Target.h:1282
const ArchSpec & GetArchitecture() const
Definition Target.h:1324
bool IsDummyTarget() const
Definition Target.h:694
const std::string & GetLabel() const
Definition Target.h:707
void ClearScriptedFrameProviderDescriptors()
Clear all scripted frame provider descriptors for this target.
Definition Target.cpp:3970
std::shared_ptr< Hook > HookSP
Definition Target.h:1948
lldb::ProcessSP CalculateProcess() override
Definition Target.cpp:2727
bool SetSectionLoadAddress(const lldb::SectionSP &section, lldb::addr_t load_addr, bool warn_multiple=false)
Definition Target.cpp:3532
bool RemoveStopHookByID(lldb::user_id_t uid)
Definition Target.cpp:3218
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:47
void SetName(llvm::StringRef name)
Definition ThreadSpec.h:51
void SetTID(lldb::tid_t tid)
Definition ThreadSpec.h:49
void SetQueueName(llvm::StringRef queue_name)
Definition ThreadSpec.h:53
uint32_t GetSize() const
Definition TypeList.cpp:36
bool Empty() const
Definition TypeList.h:35
TypeIterable Types()
Definition TypeList.h:42
lldb::TypeSP GetTypeAtIndex(uint32_t idx) const
Definition TypeList.cpp:42
A class that contains all state required for type lookups.
This class tracks the state and results of a TypeQuery.
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:342
#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:338
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
std::string toString(FormatterBytecode::OpCodes op)
@ 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::TargetGroup > TargetGroupSP
std::shared_ptr< lldb_private::ScriptedMetadata > ScriptedMetadataSP
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:84
@ eArgTypeOldPathPrefix
@ eArgTypeNewPathPrefix
@ eArgTypeUnsignedInteger
@ eArgTypeDirectoryName
std::shared_ptr< lldb_private::VariableList > VariableListSP
std::shared_ptr< lldb_private::UnwindPlan > UnwindPlanSP
std::shared_ptr< lldb_private::Variable > VariableSP
std::shared_ptr< lldb_private::ScriptedFrameProviderInterface > ScriptedFrameProviderInterfaceSP
@ eValueTypeVariableGlobal
globals variable
@ eValueTypeVariableLocal
function local variables
@ eValueTypeVariableArgument
function argument variables
@ eValueTypeVariableStatic
static variable
@ eValueTypeVariableThreadLocal
thread local storage variable
uint64_t user_id_t
Definition lldb-types.h:83
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:85
std::shared_ptr< lldb_private::Module > ModuleSP
Used to build individual command argument lists.
Options used by Module::FindFunctions.
Definition Module.h:67
bool include_inlines
Include inlined functions.
Definition Module.h:71
bool include_symbols
Include the symbol table.
Definition Module.h:69
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)
This struct contains the metadata needed to instantiate a frame provider and optional filters to cont...
void Dump(Stream *s) const
Dump a description of this descriptor to the given stream.
lldb::ScriptedFrameProviderInterfaceSP interface_sp
Interface for calling static methods on the provider class.
Struct to store information for color highlighting in the stream.
Definition Stream.h:37
#define PATH_MAX