1cfca06d7SDimitry Andric //===-- CommandObjectTarget.cpp -------------------------------------------===//
2f034231aSEd Maste //
35f29bb8aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f29bb8aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f29bb8aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f034231aSEd Maste //
7f034231aSEd Maste //===----------------------------------------------------------------------===//
8f034231aSEd Maste
9f034231aSEd Maste #include "CommandObjectTarget.h"
10f034231aSEd Maste
11b1c73532SDimitry Andric #include "lldb/Core/Address.h"
12f034231aSEd Maste #include "lldb/Core/Debugger.h"
13866dcdacSEd Maste #include "lldb/Core/IOHandler.h"
14f034231aSEd Maste #include "lldb/Core/Module.h"
15f034231aSEd Maste #include "lldb/Core/ModuleSpec.h"
16b1c73532SDimitry Andric #include "lldb/Core/PluginManager.h"
17f034231aSEd Maste #include "lldb/Core/Section.h"
18f034231aSEd Maste #include "lldb/Core/ValueObjectVariable.h"
19f21a844fSEd Maste #include "lldb/DataFormatters/ValueObjectPrinter.h"
2074a628f7SDimitry Andric #include "lldb/Host/OptionParser.h"
21f034231aSEd Maste #include "lldb/Interpreter/CommandInterpreter.h"
224b4fe385SDimitry Andric #include "lldb/Interpreter/CommandOptionArgumentTable.h"
23f034231aSEd Maste #include "lldb/Interpreter/CommandReturnObject.h"
24f73363f1SDimitry Andric #include "lldb/Interpreter/OptionArgParser.h"
25f034231aSEd Maste #include "lldb/Interpreter/OptionGroupArchitecture.h"
26f034231aSEd Maste #include "lldb/Interpreter/OptionGroupBoolean.h"
27f034231aSEd Maste #include "lldb/Interpreter/OptionGroupFile.h"
28f034231aSEd Maste #include "lldb/Interpreter/OptionGroupFormat.h"
29b60736ecSDimitry Andric #include "lldb/Interpreter/OptionGroupPlatform.h"
30b60736ecSDimitry Andric #include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
3114f1b3e8SDimitry Andric #include "lldb/Interpreter/OptionGroupString.h"
32f034231aSEd Maste #include "lldb/Interpreter/OptionGroupUInt64.h"
33f034231aSEd Maste #include "lldb/Interpreter/OptionGroupUUID.h"
34f034231aSEd Maste #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
3514f1b3e8SDimitry Andric #include "lldb/Interpreter/OptionGroupVariable.h"
3614f1b3e8SDimitry Andric #include "lldb/Interpreter/Options.h"
37f034231aSEd Maste #include "lldb/Symbol/CompileUnit.h"
38f034231aSEd Maste #include "lldb/Symbol/FuncUnwinders.h"
39f034231aSEd Maste #include "lldb/Symbol/LineTable.h"
40f034231aSEd Maste #include "lldb/Symbol/ObjectFile.h"
41f034231aSEd Maste #include "lldb/Symbol/SymbolFile.h"
42f034231aSEd Maste #include "lldb/Symbol/UnwindPlan.h"
43f034231aSEd Maste #include "lldb/Symbol/VariableList.h"
445e95aa85SEd Maste #include "lldb/Target/ABI.h"
45f034231aSEd Maste #include "lldb/Target/Process.h"
46f73363f1SDimitry Andric #include "lldb/Target/RegisterContext.h"
47866dcdacSEd Maste #include "lldb/Target/SectionLoadList.h"
48f034231aSEd Maste #include "lldb/Target/StackFrame.h"
49f034231aSEd Maste #include "lldb/Target/Thread.h"
50f034231aSEd Maste #include "lldb/Target/ThreadSpec.h"
51f73363f1SDimitry Andric #include "lldb/Utility/Args.h"
521f917f69SDimitry Andric #include "lldb/Utility/ConstString.h"
531f917f69SDimitry Andric #include "lldb/Utility/FileSpec.h"
54145449b1SDimitry Andric #include "lldb/Utility/LLDBLog.h"
5594994d37SDimitry Andric #include "lldb/Utility/State.h"
564df029ccSDimitry Andric #include "lldb/Utility/Stream.h"
57b1c73532SDimitry Andric #include "lldb/Utility/StructuredData.h"
581b306c26SDimitry Andric #include "lldb/Utility/Timer.h"
59145449b1SDimitry Andric #include "lldb/lldb-enumerations.h"
60145449b1SDimitry Andric #include "lldb/lldb-private-enumerations.h"
61f034231aSEd Maste
621f917f69SDimitry Andric #include "clang/CodeGen/ObjectFilePCHContainerOperations.h"
631f917f69SDimitry Andric #include "clang/Frontend/CompilerInstance.h"
641f917f69SDimitry Andric #include "clang/Frontend/CompilerInvocation.h"
651f917f69SDimitry Andric #include "clang/Frontend/FrontendActions.h"
66b60736ecSDimitry Andric #include "llvm/ADT/ScopeExit.h"
67b1c73532SDimitry Andric #include "llvm/ADT/StringRef.h"
6874a628f7SDimitry Andric #include "llvm/Support/FileSystem.h"
69ef5d0b5eSDimitry Andric #include "llvm/Support/FormatAdapters.h"
7074a628f7SDimitry Andric
7114f1b3e8SDimitry Andric
72f034231aSEd Maste using namespace lldb;
73f034231aSEd Maste using namespace lldb_private;
74f034231aSEd Maste
DumpTargetInfo(uint32_t target_idx,Target * target,const char * prefix_cstr,bool show_stopped_process_status,Stream & strm)7514f1b3e8SDimitry Andric static void DumpTargetInfo(uint32_t target_idx, Target *target,
7614f1b3e8SDimitry Andric const char *prefix_cstr,
7714f1b3e8SDimitry Andric bool show_stopped_process_status, Stream &strm) {
78f034231aSEd Maste const ArchSpec &target_arch = target->GetArchitecture();
79f034231aSEd Maste
80f034231aSEd Maste Module *exe_module = target->GetExecutableModulePointer();
81f034231aSEd Maste char exe_path[PATH_MAX];
82f034231aSEd Maste bool exe_valid = false;
83f034231aSEd Maste if (exe_module)
84f034231aSEd Maste exe_valid = exe_module->GetFileSpec().GetPath(exe_path, sizeof(exe_path));
85f034231aSEd Maste
86f034231aSEd Maste if (!exe_valid)
87f034231aSEd Maste ::strcpy(exe_path, "<none>");
88f034231aSEd Maste
897fa27ce4SDimitry Andric std::string formatted_label = "";
907fa27ce4SDimitry Andric const std::string &label = target->GetLabel();
917fa27ce4SDimitry Andric if (!label.empty()) {
927fa27ce4SDimitry Andric formatted_label = " (" + label + ")";
937fa27ce4SDimitry Andric }
947fa27ce4SDimitry Andric
957fa27ce4SDimitry Andric strm.Printf("%starget #%u%s: %s", prefix_cstr ? prefix_cstr : "", target_idx,
967fa27ce4SDimitry Andric formatted_label.data(), exe_path);
97f034231aSEd Maste
98f034231aSEd Maste uint32_t properties = 0;
9914f1b3e8SDimitry Andric if (target_arch.IsValid()) {
100e81d9d49SDimitry Andric strm.Printf("%sarch=", properties++ > 0 ? ", " : " ( ");
101706b4fc4SDimitry Andric target_arch.DumpTriple(strm.AsRawOstream());
102f034231aSEd Maste properties++;
103f034231aSEd Maste }
104f034231aSEd Maste PlatformSP platform_sp(target->GetPlatform());
105f034231aSEd Maste if (platform_sp)
106145449b1SDimitry Andric strm.Format("{0}platform={1}", properties++ > 0 ? ", " : " ( ",
107145449b1SDimitry Andric platform_sp->GetName());
108f034231aSEd Maste
109f034231aSEd Maste ProcessSP process_sp(target->GetProcessSP());
110f034231aSEd Maste bool show_process_status = false;
11114f1b3e8SDimitry Andric if (process_sp) {
112f034231aSEd Maste lldb::pid_t pid = process_sp->GetID();
113f034231aSEd Maste StateType state = process_sp->GetState();
114f034231aSEd Maste if (show_stopped_process_status)
115f034231aSEd Maste show_process_status = StateIsStoppedState(state, true);
116f034231aSEd Maste const char *state_cstr = StateAsCString(state);
117f034231aSEd Maste if (pid != LLDB_INVALID_PROCESS_ID)
118f034231aSEd Maste strm.Printf("%spid=%" PRIu64, properties++ > 0 ? ", " : " ( ", pid);
119f034231aSEd Maste strm.Printf("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
120f034231aSEd Maste }
121f034231aSEd Maste if (properties > 0)
122f034231aSEd Maste strm.PutCString(" )\n");
123f034231aSEd Maste else
124f034231aSEd Maste strm.EOL();
12514f1b3e8SDimitry Andric if (show_process_status) {
126f034231aSEd Maste const bool only_threads_with_stop_reason = true;
127f034231aSEd Maste const uint32_t start_frame = 0;
128f034231aSEd Maste const uint32_t num_frames = 1;
129f034231aSEd Maste const uint32_t num_frames_with_source = 1;
13014f1b3e8SDimitry Andric const bool stop_format = false;
131f034231aSEd Maste process_sp->GetStatus(strm);
13214f1b3e8SDimitry Andric process_sp->GetThreadStatus(strm, only_threads_with_stop_reason,
133706b4fc4SDimitry Andric start_frame, num_frames, num_frames_with_source,
134706b4fc4SDimitry Andric stop_format);
135f034231aSEd Maste }
136f034231aSEd Maste }
137f034231aSEd Maste
DumpTargetList(TargetList & target_list,bool show_stopped_process_status,Stream & strm)13814f1b3e8SDimitry Andric static uint32_t DumpTargetList(TargetList &target_list,
13914f1b3e8SDimitry Andric bool show_stopped_process_status, Stream &strm) {
140f034231aSEd Maste const uint32_t num_targets = target_list.GetNumTargets();
14114f1b3e8SDimitry Andric if (num_targets) {
142f034231aSEd Maste TargetSP selected_target_sp(target_list.GetSelectedTarget());
143f034231aSEd Maste strm.PutCString("Current targets:\n");
14414f1b3e8SDimitry Andric for (uint32_t i = 0; i < num_targets; ++i) {
145f034231aSEd Maste TargetSP target_sp(target_list.GetTargetAtIndex(i));
14614f1b3e8SDimitry Andric if (target_sp) {
147f034231aSEd Maste bool is_selected = target_sp.get() == selected_target_sp.get();
14814f1b3e8SDimitry Andric DumpTargetInfo(i, target_sp.get(), is_selected ? "* " : " ",
14914f1b3e8SDimitry Andric show_stopped_process_status, strm);
150f034231aSEd Maste }
151f034231aSEd Maste }
152f034231aSEd Maste }
153f034231aSEd Maste return num_targets;
154f034231aSEd Maste }
155f3fbd1c0SDimitry Andric
156ead24645SDimitry Andric #define LLDB_OPTIONS_target_dependents
157ead24645SDimitry Andric #include "CommandOptions.inc"
15894994d37SDimitry Andric
15994994d37SDimitry Andric class OptionGroupDependents : public OptionGroup {
16094994d37SDimitry Andric public:
161344a3780SDimitry Andric OptionGroupDependents() = default;
16294994d37SDimitry Andric
163344a3780SDimitry Andric ~OptionGroupDependents() override = default;
16494994d37SDimitry Andric
GetDefinitions()16594994d37SDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
166e3b55780SDimitry Andric return llvm::ArrayRef(g_target_dependents_options);
16794994d37SDimitry Andric }
16894994d37SDimitry Andric
SetOptionValue(uint32_t option_idx,llvm::StringRef option_value,ExecutionContext * execution_context)16994994d37SDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
17094994d37SDimitry Andric ExecutionContext *execution_context) override {
17194994d37SDimitry Andric Status error;
17294994d37SDimitry Andric
17394994d37SDimitry Andric // For compatibility no value means don't load dependents.
17494994d37SDimitry Andric if (option_value.empty()) {
17594994d37SDimitry Andric m_load_dependent_files = eLoadDependentsNo;
17694994d37SDimitry Andric return error;
17794994d37SDimitry Andric }
17894994d37SDimitry Andric
179ead24645SDimitry Andric const char short_option =
180ead24645SDimitry Andric g_target_dependents_options[option_idx].short_option;
18194994d37SDimitry Andric if (short_option == 'd') {
18294994d37SDimitry Andric LoadDependentFiles tmp_load_dependents;
18394994d37SDimitry Andric tmp_load_dependents = (LoadDependentFiles)OptionArgParser::ToOptionEnum(
184ead24645SDimitry Andric option_value, g_target_dependents_options[option_idx].enum_values, 0,
185ead24645SDimitry Andric error);
18694994d37SDimitry Andric if (error.Success())
18794994d37SDimitry Andric m_load_dependent_files = tmp_load_dependents;
18894994d37SDimitry Andric } else {
18994994d37SDimitry Andric error.SetErrorStringWithFormat("unrecognized short option '%c'",
19094994d37SDimitry Andric short_option);
19194994d37SDimitry Andric }
19294994d37SDimitry Andric
19394994d37SDimitry Andric return error;
19494994d37SDimitry Andric }
19594994d37SDimitry Andric
19694994d37SDimitry Andric Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete;
19794994d37SDimitry Andric
OptionParsingStarting(ExecutionContext * execution_context)19894994d37SDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override {
19994994d37SDimitry Andric m_load_dependent_files = eLoadDependentsDefault;
20094994d37SDimitry Andric }
20194994d37SDimitry Andric
20294994d37SDimitry Andric LoadDependentFiles m_load_dependent_files;
20394994d37SDimitry Andric
20494994d37SDimitry Andric private:
205cfca06d7SDimitry Andric OptionGroupDependents(const OptionGroupDependents &) = delete;
206cfca06d7SDimitry Andric const OptionGroupDependents &
207cfca06d7SDimitry Andric operator=(const OptionGroupDependents &) = delete;
20894994d37SDimitry Andric };
20994994d37SDimitry Andric
210f034231aSEd Maste #pragma mark CommandObjectTargetCreate
211f034231aSEd Maste
21214f1b3e8SDimitry Andric class CommandObjectTargetCreate : public CommandObjectParsed {
213f034231aSEd Maste public:
CommandObjectTargetCreate(CommandInterpreter & interpreter)21414f1b3e8SDimitry Andric CommandObjectTargetCreate(CommandInterpreter &interpreter)
21514f1b3e8SDimitry Andric : CommandObjectParsed(
21614f1b3e8SDimitry Andric interpreter, "target create",
217f034231aSEd Maste "Create a target using the argument as the main executable.",
218f3fbd1c0SDimitry Andric nullptr),
219b60736ecSDimitry Andric m_platform_options(true), // Include the --platform option.
22014f1b3e8SDimitry Andric m_core_file(LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename,
22114f1b3e8SDimitry Andric "Fullpath to a core file to use for this target."),
2227fa27ce4SDimitry Andric m_label(LLDB_OPT_SET_1, false, "label", 'l', 0, eArgTypeName,
2237fa27ce4SDimitry Andric "Optional name for this target.", nullptr),
22414f1b3e8SDimitry Andric m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
22594994d37SDimitry Andric eArgTypeFilename,
22694994d37SDimitry Andric "Fullpath to a stand alone debug "
22714f1b3e8SDimitry Andric "symbols file for when debug symbols "
22814f1b3e8SDimitry Andric "are not in the executable."),
22914f1b3e8SDimitry Andric m_remote_file(
23014f1b3e8SDimitry Andric LLDB_OPT_SET_1, false, "remote-file", 'r', 0, eArgTypeFilename,
2316f8fc217SDimitry Andric "Fullpath to the file on the remote host if debugging remotely.") {
232f034231aSEd Maste
233ac9a064cSDimitry Andric AddSimpleArgumentList(eArgTypeFilename);
234f034231aSEd Maste
235f034231aSEd Maste m_option_group.Append(&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
236b60736ecSDimitry Andric m_option_group.Append(&m_platform_options, LLDB_OPT_SET_ALL, 1);
237f034231aSEd Maste m_option_group.Append(&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2387fa27ce4SDimitry Andric m_option_group.Append(&m_label, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
239f034231aSEd Maste m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
240f034231aSEd Maste m_option_group.Append(&m_remote_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
241f034231aSEd Maste m_option_group.Append(&m_add_dependents, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
242f034231aSEd Maste m_option_group.Finalize();
243f034231aSEd Maste }
244f034231aSEd Maste
245f3fbd1c0SDimitry Andric ~CommandObjectTargetCreate() override = default;
246f034231aSEd Maste
GetOptions()24714f1b3e8SDimitry Andric Options *GetOptions() override { return &m_option_group; }
248f034231aSEd Maste
249f034231aSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)250b1c73532SDimitry Andric void DoExecute(Args &command, CommandReturnObject &result) override {
251f034231aSEd Maste const size_t argc = command.GetArgumentCount();
252f034231aSEd Maste FileSpec core_file(m_core_file.GetOptionValue().GetCurrentValue());
253f034231aSEd Maste FileSpec remote_file(m_remote_file.GetOptionValue().GetCurrentValue());
254f034231aSEd Maste
25514f1b3e8SDimitry Andric if (core_file) {
256cfca06d7SDimitry Andric auto file = FileSystem::Instance().Open(
257c0981da4SDimitry Andric core_file, lldb_private::File::eOpenOptionReadOnly);
258cfca06d7SDimitry Andric
259cfca06d7SDimitry Andric if (!file) {
260cfca06d7SDimitry Andric result.AppendErrorWithFormatv("Cannot open '{0}': {1}.",
261cfca06d7SDimitry Andric core_file.GetPath(),
262cfca06d7SDimitry Andric llvm::toString(file.takeError()));
263b1c73532SDimitry Andric return;
2640cac4ca3SEd Maste }
2650cac4ca3SEd Maste }
2660cac4ca3SEd Maste
26714f1b3e8SDimitry Andric if (argc == 1 || core_file || remote_file) {
268f034231aSEd Maste FileSpec symfile(m_symbol_file.GetOptionValue().GetCurrentValue());
26914f1b3e8SDimitry Andric if (symfile) {
270cfca06d7SDimitry Andric auto file = FileSystem::Instance().Open(
271c0981da4SDimitry Andric symfile, lldb_private::File::eOpenOptionReadOnly);
272cfca06d7SDimitry Andric
273cfca06d7SDimitry Andric if (!file) {
274cfca06d7SDimitry Andric result.AppendErrorWithFormatv("Cannot open '{0}': {1}.",
275cfca06d7SDimitry Andric symfile.GetPath(),
276cfca06d7SDimitry Andric llvm::toString(file.takeError()));
277b1c73532SDimitry Andric return;
278f034231aSEd Maste }
279f034231aSEd Maste }
280f034231aSEd Maste
281f034231aSEd Maste const char *file_path = command.GetArgumentAtIndex(0);
282b60736ecSDimitry Andric LLDB_SCOPED_TIMERF("(lldb) target create '%s'", file_path);
283f21a844fSEd Maste
284f21a844fSEd Maste bool must_set_platform_path = false;
285f21a844fSEd Maste
2865f29bb8aSDimitry Andric Debugger &debugger = GetDebugger();
28712bd4897SEd Maste
28812bd4897SEd Maste TargetSP target_sp;
28914f1b3e8SDimitry Andric llvm::StringRef arch_cstr = m_arch_option.GetArchitectureName();
290b76161e4SDimitry Andric Status error(debugger.GetTargetList().CreateTarget(
29194994d37SDimitry Andric debugger, file_path, arch_cstr,
292b60736ecSDimitry Andric m_add_dependents.m_load_dependent_files, &m_platform_options,
293b60736ecSDimitry Andric target_sp));
29412bd4897SEd Maste
295b60736ecSDimitry Andric if (!target_sp) {
296b60736ecSDimitry Andric result.AppendError(error.AsCString());
297b1c73532SDimitry Andric return;
298b60736ecSDimitry Andric }
299b60736ecSDimitry Andric
3007fa27ce4SDimitry Andric const llvm::StringRef label =
3017fa27ce4SDimitry Andric m_label.GetOptionValue().GetCurrentValueAsRef();
3027fa27ce4SDimitry Andric if (!label.empty()) {
3037fa27ce4SDimitry Andric if (auto E = target_sp->SetLabel(label))
3047fa27ce4SDimitry Andric result.SetError(std::move(E));
305b1c73532SDimitry Andric return;
3067fa27ce4SDimitry Andric }
3077fa27ce4SDimitry Andric
308b60736ecSDimitry Andric auto on_error = llvm::make_scope_exit(
309b60736ecSDimitry Andric [&target_list = debugger.GetTargetList(), &target_sp]() {
310b60736ecSDimitry Andric target_list.DeleteTarget(target_sp);
311b60736ecSDimitry Andric });
312b60736ecSDimitry Andric
31314f1b3e8SDimitry Andric // Only get the platform after we create the target because we might
314f73363f1SDimitry Andric // have switched platforms depending on what the arguments were to
315f73363f1SDimitry Andric // CreateTarget() we can't rely on the selected platform.
31612bd4897SEd Maste
31712bd4897SEd Maste PlatformSP platform_sp = target_sp->GetPlatform();
318f21a844fSEd Maste
319145449b1SDimitry Andric FileSpec file_spec;
320145449b1SDimitry Andric if (file_path) {
321145449b1SDimitry Andric file_spec.SetFile(file_path, FileSpec::Style::native);
322145449b1SDimitry Andric FileSystem::Instance().Resolve(file_spec);
323145449b1SDimitry Andric
324145449b1SDimitry Andric // Try to resolve the exe based on PATH and/or platform-specific
325145449b1SDimitry Andric // suffixes, but only if using the host platform.
326145449b1SDimitry Andric if (platform_sp && platform_sp->IsHost() &&
327145449b1SDimitry Andric !FileSystem::Instance().Exists(file_spec))
328145449b1SDimitry Andric FileSystem::Instance().ResolveExecutableLocation(file_spec);
329145449b1SDimitry Andric }
330145449b1SDimitry Andric
33114f1b3e8SDimitry Andric if (remote_file) {
33214f1b3e8SDimitry Andric if (platform_sp) {
333f21a844fSEd Maste // I have a remote file.. two possible cases
33494994d37SDimitry Andric if (file_spec && FileSystem::Instance().Exists(file_spec)) {
335f21a844fSEd Maste // if the remote file does not exist, push it there
33614f1b3e8SDimitry Andric if (!platform_sp->GetFileExists(remote_file)) {
337b76161e4SDimitry Andric Status err = platform_sp->PutFile(file_spec, remote_file);
33814f1b3e8SDimitry Andric if (err.Fail()) {
339f21a844fSEd Maste result.AppendError(err.AsCString());
340b1c73532SDimitry Andric return;
341f21a844fSEd Maste }
342f21a844fSEd Maste }
34314f1b3e8SDimitry Andric } else {
344f21a844fSEd Maste // there is no local file and we need one
34514f1b3e8SDimitry Andric // in order to make the remote ---> local transfer we need a
34614f1b3e8SDimitry Andric // platform
34714f1b3e8SDimitry Andric // TODO: if the user has passed in a --platform argument, use it
34814f1b3e8SDimitry Andric // to fetch the right platform
34914f1b3e8SDimitry Andric if (file_path) {
350f21a844fSEd Maste // copy the remote file to the local file
351b76161e4SDimitry Andric Status err = platform_sp->GetFile(remote_file, file_spec);
35214f1b3e8SDimitry Andric if (err.Fail()) {
353f21a844fSEd Maste result.AppendError(err.AsCString());
354b1c73532SDimitry Andric return;
355f21a844fSEd Maste }
35614f1b3e8SDimitry Andric } else {
357145449b1SDimitry Andric // If the remote file exists, we can debug reading that out of
358145449b1SDimitry Andric // memory. If the platform is already connected to an lldb-server
359145449b1SDimitry Andric // then we can at least check the file exists remotely. Otherwise
360145449b1SDimitry Andric // we'll just have to trust that it will be there when we do
361145449b1SDimitry Andric // process connect.
362145449b1SDimitry Andric // I don't do this for the host platform because it seems odd to
363145449b1SDimitry Andric // support supplying a remote file but no local file for a local
364145449b1SDimitry Andric // debug session.
365145449b1SDimitry Andric if (platform_sp->IsHost()) {
366145449b1SDimitry Andric result.AppendError("Supply a local file, not a remote file, "
367145449b1SDimitry Andric "when debugging on the host.");
368b1c73532SDimitry Andric return;
369145449b1SDimitry Andric }
370145449b1SDimitry Andric if (platform_sp->IsConnected() && !platform_sp->GetFileExists(remote_file)) {
37114f1b3e8SDimitry Andric result.AppendError("remote --> local transfer without local "
37214f1b3e8SDimitry Andric "path is not implemented yet");
373b1c73532SDimitry Andric return;
374f21a844fSEd Maste }
375145449b1SDimitry Andric // Since there's only a remote file, we need to set the executable
376145449b1SDimitry Andric // file spec to the remote one.
377145449b1SDimitry Andric ProcessLaunchInfo launch_info = target_sp->GetProcessLaunchInfo();
378145449b1SDimitry Andric launch_info.SetExecutableFile(FileSpec(remote_file), true);
379145449b1SDimitry Andric target_sp->SetProcessLaunchInfo(launch_info);
380145449b1SDimitry Andric }
381f21a844fSEd Maste }
38214f1b3e8SDimitry Andric } else {
38312bd4897SEd Maste result.AppendError("no platform found for target");
384b1c73532SDimitry Andric return;
38512bd4897SEd Maste }
38612bd4897SEd Maste }
38712bd4897SEd Maste
38814f1b3e8SDimitry Andric if (symfile || remote_file) {
389f034231aSEd Maste ModuleSP module_sp(target_sp->GetExecutableModule());
39014f1b3e8SDimitry Andric if (module_sp) {
391f034231aSEd Maste if (symfile)
392f034231aSEd Maste module_sp->SetSymbolFileFileSpec(symfile);
39314f1b3e8SDimitry Andric if (remote_file) {
394f034231aSEd Maste std::string remote_path = remote_file.GetPath();
395f034231aSEd Maste target_sp->SetArg0(remote_path.c_str());
396f034231aSEd Maste module_sp->SetPlatformFileSpec(remote_file);
397f034231aSEd Maste }
398f034231aSEd Maste }
399f034231aSEd Maste }
400f034231aSEd Maste
40114f1b3e8SDimitry Andric if (must_set_platform_path) {
402f21a844fSEd Maste ModuleSpec main_module_spec(file_spec);
403706b4fc4SDimitry Andric ModuleSP module_sp =
404706b4fc4SDimitry Andric target_sp->GetOrCreateModule(main_module_spec, true /* notify */);
405f21a844fSEd Maste if (module_sp)
406f21a844fSEd Maste module_sp->SetPlatformFileSpec(remote_file);
407f21a844fSEd Maste }
408cfca06d7SDimitry Andric
40914f1b3e8SDimitry Andric if (core_file) {
410f034231aSEd Maste FileSpec core_file_dir;
411e3b55780SDimitry Andric core_file_dir.SetDirectory(core_file.GetDirectory());
4125f29bb8aSDimitry Andric target_sp->AppendExecutableSearchPaths(core_file_dir);
413f034231aSEd Maste
41414f1b3e8SDimitry Andric ProcessSP process_sp(target_sp->CreateProcess(
415b60736ecSDimitry Andric GetDebugger().GetListener(), llvm::StringRef(), &core_file, false));
416f034231aSEd Maste
41714f1b3e8SDimitry Andric if (process_sp) {
418f73363f1SDimitry Andric // Seems weird that we Launch a core file, but that is what we
419f73363f1SDimitry Andric // do!
420f034231aSEd Maste error = process_sp->LoadCore();
421f034231aSEd Maste
42214f1b3e8SDimitry Andric if (error.Fail()) {
423b1c73532SDimitry Andric result.AppendError(error.AsCString("unknown core file format"));
424b1c73532SDimitry Andric return;
42514f1b3e8SDimitry Andric } else {
426b60736ecSDimitry Andric result.AppendMessageWithFormatv(
427b60736ecSDimitry Andric "Core file '{0}' ({1}) was loaded.\n", core_file.GetPath(),
42814f1b3e8SDimitry Andric target_sp->GetArchitecture().GetArchitectureName());
429f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishNoResult);
430b60736ecSDimitry Andric on_error.release();
431f034231aSEd Maste }
43214f1b3e8SDimitry Andric } else {
433b1c73532SDimitry Andric result.AppendErrorWithFormatv("Unknown core file format '{0}'\n",
434cfca06d7SDimitry Andric core_file.GetPath());
435f034231aSEd Maste }
43614f1b3e8SDimitry Andric } else {
43714f1b3e8SDimitry Andric result.AppendMessageWithFormat(
438ead24645SDimitry Andric "Current executable set to '%s' (%s).\n",
439ead24645SDimitry Andric file_spec.GetPath().c_str(),
44014f1b3e8SDimitry Andric target_sp->GetArchitecture().GetArchitectureName());
441f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishNoResult);
442b60736ecSDimitry Andric on_error.release();
443f034231aSEd Maste }
44414f1b3e8SDimitry Andric } else {
44514f1b3e8SDimitry Andric result.AppendErrorWithFormat("'%s' takes exactly one executable path "
44614f1b3e8SDimitry Andric "argument, or use the --core option.\n",
44714f1b3e8SDimitry Andric m_cmd_name.c_str());
448f034231aSEd Maste }
449f034231aSEd Maste }
450f034231aSEd Maste
451f034231aSEd Maste private:
452f034231aSEd Maste OptionGroupOptions m_option_group;
453f034231aSEd Maste OptionGroupArchitecture m_arch_option;
454b60736ecSDimitry Andric OptionGroupPlatform m_platform_options;
455f034231aSEd Maste OptionGroupFile m_core_file;
4567fa27ce4SDimitry Andric OptionGroupString m_label;
457f034231aSEd Maste OptionGroupFile m_symbol_file;
458f034231aSEd Maste OptionGroupFile m_remote_file;
45994994d37SDimitry Andric OptionGroupDependents m_add_dependents;
460f034231aSEd Maste };
461f034231aSEd Maste
462f034231aSEd Maste #pragma mark CommandObjectTargetList
463f034231aSEd Maste
46414f1b3e8SDimitry Andric class CommandObjectTargetList : public CommandObjectParsed {
465f034231aSEd Maste public:
CommandObjectTargetList(CommandInterpreter & interpreter)46614f1b3e8SDimitry Andric CommandObjectTargetList(CommandInterpreter &interpreter)
46714f1b3e8SDimitry Andric : CommandObjectParsed(
46814f1b3e8SDimitry Andric interpreter, "target list",
46914f1b3e8SDimitry Andric "List all current targets in the current debug session.", nullptr) {
470f034231aSEd Maste }
471f034231aSEd Maste
472f3fbd1c0SDimitry Andric ~CommandObjectTargetList() override = default;
473f034231aSEd Maste
474f034231aSEd Maste protected:
DoExecute(Args & args,CommandReturnObject & result)475b1c73532SDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override {
476f034231aSEd Maste Stream &strm = result.GetOutputStream();
477f034231aSEd Maste
478f034231aSEd Maste bool show_stopped_process_status = false;
4795f29bb8aSDimitry Andric if (DumpTargetList(GetDebugger().GetTargetList(),
48014f1b3e8SDimitry Andric show_stopped_process_status, strm) == 0) {
481f034231aSEd Maste strm.PutCString("No targets.\n");
482f034231aSEd Maste }
483f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
484f034231aSEd Maste }
485f034231aSEd Maste };
486f034231aSEd Maste
487f034231aSEd Maste #pragma mark CommandObjectTargetSelect
488f034231aSEd Maste
48914f1b3e8SDimitry Andric class CommandObjectTargetSelect : public CommandObjectParsed {
490f034231aSEd Maste public:
CommandObjectTargetSelect(CommandInterpreter & interpreter)49114f1b3e8SDimitry Andric CommandObjectTargetSelect(CommandInterpreter &interpreter)
49214f1b3e8SDimitry Andric : CommandObjectParsed(
49314f1b3e8SDimitry Andric interpreter, "target select",
49414f1b3e8SDimitry Andric "Select a target as the current target by target index.", nullptr) {
495ac9a064cSDimitry Andric AddSimpleArgumentList(eArgTypeTargetID);
496f034231aSEd Maste }
497f034231aSEd Maste
498f3fbd1c0SDimitry Andric ~CommandObjectTargetSelect() override = default;
499f034231aSEd Maste
500f034231aSEd Maste protected:
DoExecute(Args & args,CommandReturnObject & result)501b1c73532SDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override {
50214f1b3e8SDimitry Andric if (args.GetArgumentCount() == 1) {
5037fa27ce4SDimitry Andric const char *target_identifier = args.GetArgumentAtIndex(0);
5047fa27ce4SDimitry Andric uint32_t target_idx = LLDB_INVALID_INDEX32;
5055f29bb8aSDimitry Andric TargetList &target_list = GetDebugger().GetTargetList();
506f034231aSEd Maste const uint32_t num_targets = target_list.GetNumTargets();
5077fa27ce4SDimitry Andric if (llvm::to_integer(target_identifier, target_idx)) {
50814f1b3e8SDimitry Andric if (target_idx < num_targets) {
509b60736ecSDimitry Andric target_list.SetSelectedTarget(target_idx);
510f034231aSEd Maste Stream &strm = result.GetOutputStream();
511f034231aSEd Maste bool show_stopped_process_status = false;
512f034231aSEd Maste DumpTargetList(target_list, show_stopped_process_status, strm);
513f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
51414f1b3e8SDimitry Andric } else {
51514f1b3e8SDimitry Andric if (num_targets > 0) {
51614f1b3e8SDimitry Andric result.AppendErrorWithFormat(
51714f1b3e8SDimitry Andric "index %u is out of range, valid target indexes are 0 - %u\n",
51814f1b3e8SDimitry Andric target_idx, num_targets - 1);
51914f1b3e8SDimitry Andric } else {
52014f1b3e8SDimitry Andric result.AppendErrorWithFormat(
52114f1b3e8SDimitry Andric "index %u is out of range since there are no active targets\n",
5220cac4ca3SEd Maste target_idx);
5230cac4ca3SEd Maste }
524f034231aSEd Maste }
52514f1b3e8SDimitry Andric } else {
5267fa27ce4SDimitry Andric for (size_t i = 0; i < num_targets; i++) {
5277fa27ce4SDimitry Andric if (TargetSP target_sp = target_list.GetTargetAtIndex(i)) {
5287fa27ce4SDimitry Andric const std::string &label = target_sp->GetLabel();
5297fa27ce4SDimitry Andric if (!label.empty() && label == target_identifier) {
5307fa27ce4SDimitry Andric target_idx = i;
5317fa27ce4SDimitry Andric break;
5327fa27ce4SDimitry Andric }
5337fa27ce4SDimitry Andric }
5347fa27ce4SDimitry Andric }
5357fa27ce4SDimitry Andric
5367fa27ce4SDimitry Andric if (target_idx != LLDB_INVALID_INDEX32) {
5377fa27ce4SDimitry Andric target_list.SetSelectedTarget(target_idx);
5387fa27ce4SDimitry Andric Stream &strm = result.GetOutputStream();
5397fa27ce4SDimitry Andric bool show_stopped_process_status = false;
5407fa27ce4SDimitry Andric DumpTargetList(target_list, show_stopped_process_status, strm);
5417fa27ce4SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
5427fa27ce4SDimitry Andric } else {
54314f1b3e8SDimitry Andric result.AppendErrorWithFormat("invalid index string value '%s'\n",
5447fa27ce4SDimitry Andric target_identifier);
5457fa27ce4SDimitry Andric }
546f034231aSEd Maste }
54714f1b3e8SDimitry Andric } else {
54814f1b3e8SDimitry Andric result.AppendError(
54914f1b3e8SDimitry Andric "'target select' takes a single argument: a target index\n");
550f034231aSEd Maste }
551f034231aSEd Maste }
552f034231aSEd Maste };
553f034231aSEd Maste
554cfca06d7SDimitry Andric #pragma mark CommandObjectTargetDelete
555f034231aSEd Maste
55614f1b3e8SDimitry Andric class CommandObjectTargetDelete : public CommandObjectParsed {
557f034231aSEd Maste public:
CommandObjectTargetDelete(CommandInterpreter & interpreter)55814f1b3e8SDimitry Andric CommandObjectTargetDelete(CommandInterpreter &interpreter)
55914f1b3e8SDimitry Andric : CommandObjectParsed(interpreter, "target delete",
560f034231aSEd Maste "Delete one or more targets by target index.",
561f3fbd1c0SDimitry Andric nullptr),
5626f8fc217SDimitry Andric m_all_option(LLDB_OPT_SET_1, false, "all", 'a', "Delete all targets.",
5636f8fc217SDimitry Andric false, true),
5645e95aa85SEd Maste m_cleanup_option(
56514f1b3e8SDimitry Andric LLDB_OPT_SET_1, false, "clean", 'c',
56614f1b3e8SDimitry Andric "Perform extra cleanup to minimize memory consumption after "
56714f1b3e8SDimitry Andric "deleting the target. "
56814f1b3e8SDimitry Andric "By default, LLDB will keep in memory any modules previously "
56914f1b3e8SDimitry Andric "loaded by the target as well "
57014f1b3e8SDimitry Andric "as all of its debug info. Specifying --clean will unload all of "
57114f1b3e8SDimitry Andric "these shared modules and "
5725e95aa85SEd Maste "cause them to be reparsed again the next time the target is run",
57314f1b3e8SDimitry Andric false, true) {
5745e95aa85SEd Maste m_option_group.Append(&m_all_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
575f034231aSEd Maste m_option_group.Append(&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
576f034231aSEd Maste m_option_group.Finalize();
577ac9a064cSDimitry Andric AddSimpleArgumentList(eArgTypeTargetID, eArgRepeatStar);
578f034231aSEd Maste }
579f034231aSEd Maste
580f3fbd1c0SDimitry Andric ~CommandObjectTargetDelete() override = default;
581f034231aSEd Maste
GetOptions()58214f1b3e8SDimitry Andric Options *GetOptions() override { return &m_option_group; }
583f034231aSEd Maste
584f034231aSEd Maste protected:
DoExecute(Args & args,CommandReturnObject & result)585b1c73532SDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override {
586f034231aSEd Maste const size_t argc = args.GetArgumentCount();
587f034231aSEd Maste std::vector<TargetSP> delete_target_list;
5885f29bb8aSDimitry Andric TargetList &target_list = GetDebugger().GetTargetList();
589f034231aSEd Maste TargetSP target_sp;
5905e95aa85SEd Maste
59114f1b3e8SDimitry Andric if (m_all_option.GetOptionValue()) {
5927fa27ce4SDimitry Andric for (size_t i = 0; i < target_list.GetNumTargets(); ++i)
5935e95aa85SEd Maste delete_target_list.push_back(target_list.GetTargetAtIndex(i));
59414f1b3e8SDimitry Andric } else if (argc > 0) {
595f034231aSEd Maste const uint32_t num_targets = target_list.GetNumTargets();
596f034231aSEd Maste // Bail out if don't have any targets.
597f034231aSEd Maste if (num_targets == 0) {
598f034231aSEd Maste result.AppendError("no targets to delete");
599b1c73532SDimitry Andric return;
600f034231aSEd Maste }
601f034231aSEd Maste
60214f1b3e8SDimitry Andric for (auto &entry : args.entries()) {
60314f1b3e8SDimitry Andric uint32_t target_idx;
604ead24645SDimitry Andric if (entry.ref().getAsInteger(0, target_idx)) {
60514f1b3e8SDimitry Andric result.AppendErrorWithFormat("invalid target index '%s'\n",
60614f1b3e8SDimitry Andric entry.c_str());
607b1c73532SDimitry Andric return;
6085e95aa85SEd Maste }
60914f1b3e8SDimitry Andric if (target_idx < num_targets) {
610f034231aSEd Maste target_sp = target_list.GetTargetAtIndex(target_idx);
61114f1b3e8SDimitry Andric if (target_sp) {
612f034231aSEd Maste delete_target_list.push_back(target_sp);
613f034231aSEd Maste continue;
614f034231aSEd Maste }
615f034231aSEd Maste }
616f034231aSEd Maste if (num_targets > 1)
61714f1b3e8SDimitry Andric result.AppendErrorWithFormat("target index %u is out of range, valid "
61814f1b3e8SDimitry Andric "target indexes are 0 - %u\n",
61914f1b3e8SDimitry Andric target_idx, num_targets - 1);
620f034231aSEd Maste else
62114f1b3e8SDimitry Andric result.AppendErrorWithFormat(
62214f1b3e8SDimitry Andric "target index %u is out of range, the only valid index is 0\n",
623f034231aSEd Maste target_idx);
624f034231aSEd Maste
625b1c73532SDimitry Andric return;
626f034231aSEd Maste }
62714f1b3e8SDimitry Andric } else {
628f034231aSEd Maste target_sp = target_list.GetSelectedTarget();
62914f1b3e8SDimitry Andric if (!target_sp) {
630f034231aSEd Maste result.AppendErrorWithFormat("no target is currently selected\n");
631b1c73532SDimitry Andric return;
632f034231aSEd Maste }
6335e95aa85SEd Maste delete_target_list.push_back(target_sp);
634f034231aSEd Maste }
6355e95aa85SEd Maste
636f034231aSEd Maste const size_t num_targets_to_delete = delete_target_list.size();
63714f1b3e8SDimitry Andric for (size_t idx = 0; idx < num_targets_to_delete; ++idx) {
638f034231aSEd Maste target_sp = delete_target_list[idx];
639f034231aSEd Maste target_list.DeleteTarget(target_sp);
640f034231aSEd Maste target_sp->Destroy();
641f034231aSEd Maste }
642f73363f1SDimitry Andric // If "--clean" was specified, prune any orphaned shared modules from the
643f73363f1SDimitry Andric // global shared module list
64414f1b3e8SDimitry Andric if (m_cleanup_option.GetOptionValue()) {
645f034231aSEd Maste const bool mandatory = true;
646f034231aSEd Maste ModuleList::RemoveOrphanSharedModules(mandatory);
647f034231aSEd Maste }
64814f1b3e8SDimitry Andric result.GetOutputStream().Printf("%u targets deleted.\n",
64914f1b3e8SDimitry Andric (uint32_t)num_targets_to_delete);
650f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
651f034231aSEd Maste
652b1c73532SDimitry Andric return;
653f034231aSEd Maste }
654f034231aSEd Maste
655f034231aSEd Maste OptionGroupOptions m_option_group;
6565e95aa85SEd Maste OptionGroupBoolean m_all_option;
657f034231aSEd Maste OptionGroupBoolean m_cleanup_option;
658f034231aSEd Maste };
659f034231aSEd Maste
660cfca06d7SDimitry Andric class CommandObjectTargetShowLaunchEnvironment : public CommandObjectParsed {
661cfca06d7SDimitry Andric public:
CommandObjectTargetShowLaunchEnvironment(CommandInterpreter & interpreter)662cfca06d7SDimitry Andric CommandObjectTargetShowLaunchEnvironment(CommandInterpreter &interpreter)
663cfca06d7SDimitry Andric : CommandObjectParsed(
664cfca06d7SDimitry Andric interpreter, "target show-launch-environment",
665cfca06d7SDimitry Andric "Shows the environment being passed to the process when launched, "
666cfca06d7SDimitry Andric "taking info account 3 settings: target.env-vars, "
667cfca06d7SDimitry Andric "target.inherit-env and target.unset-env-vars.",
668cfca06d7SDimitry Andric nullptr, eCommandRequiresTarget) {}
669cfca06d7SDimitry Andric
670cfca06d7SDimitry Andric ~CommandObjectTargetShowLaunchEnvironment() override = default;
671cfca06d7SDimitry Andric
672cfca06d7SDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)673b1c73532SDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override {
674cfca06d7SDimitry Andric Target *target = m_exe_ctx.GetTargetPtr();
675cfca06d7SDimitry Andric Environment env = target->GetEnvironment();
676cfca06d7SDimitry Andric
677cfca06d7SDimitry Andric std::vector<Environment::value_type *> env_vector;
678cfca06d7SDimitry Andric env_vector.reserve(env.size());
679cfca06d7SDimitry Andric for (auto &KV : env)
680cfca06d7SDimitry Andric env_vector.push_back(&KV);
681cfca06d7SDimitry Andric std::sort(env_vector.begin(), env_vector.end(),
682cfca06d7SDimitry Andric [](Environment::value_type *a, Environment::value_type *b) {
683cfca06d7SDimitry Andric return a->first() < b->first();
684cfca06d7SDimitry Andric });
685cfca06d7SDimitry Andric
686cfca06d7SDimitry Andric auto &strm = result.GetOutputStream();
687cfca06d7SDimitry Andric for (auto &KV : env_vector)
688cfca06d7SDimitry Andric strm.Format("{0}={1}\n", KV->first(), KV->second);
689cfca06d7SDimitry Andric
690cfca06d7SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
691cfca06d7SDimitry Andric }
692cfca06d7SDimitry Andric };
693cfca06d7SDimitry Andric
694f034231aSEd Maste #pragma mark CommandObjectTargetVariable
695f034231aSEd Maste
69614f1b3e8SDimitry Andric class CommandObjectTargetVariable : public CommandObjectParsed {
6970cac4ca3SEd Maste static const uint32_t SHORT_OPTION_FILE = 0x66696c65; // 'file'
6980cac4ca3SEd Maste static const uint32_t SHORT_OPTION_SHLB = 0x73686c62; // 'shlb'
6990cac4ca3SEd Maste
700f034231aSEd Maste public:
CommandObjectTargetVariable(CommandInterpreter & interpreter)701f3fbd1c0SDimitry Andric CommandObjectTargetVariable(CommandInterpreter &interpreter)
702f3fbd1c0SDimitry Andric : CommandObjectParsed(interpreter, "target variable",
70314f1b3e8SDimitry Andric "Read global variables for the current target, "
70414f1b3e8SDimitry Andric "before or while running a process.",
705f3fbd1c0SDimitry Andric nullptr, eCommandRequiresTarget),
706f034231aSEd Maste m_option_variable(false), // Don't include frame options
707f034231aSEd Maste m_option_format(eFormatDefault),
70814f1b3e8SDimitry Andric m_option_compile_units(LLDB_OPT_SET_1, false, "file", SHORT_OPTION_FILE,
70914f1b3e8SDimitry Andric 0, eArgTypeFilename,
71014f1b3e8SDimitry Andric "A basename or fullpath to a file that contains "
71114f1b3e8SDimitry Andric "global variables. This option can be "
712f3fbd1c0SDimitry Andric "specified multiple times."),
71314f1b3e8SDimitry Andric m_option_shared_libraries(
71414f1b3e8SDimitry Andric LLDB_OPT_SET_1, false, "shlib", SHORT_OPTION_SHLB, 0,
71514f1b3e8SDimitry Andric eArgTypeFilename,
71614f1b3e8SDimitry Andric "A basename or fullpath to a shared library to use in the search "
71714f1b3e8SDimitry Andric "for global "
7186f8fc217SDimitry Andric "variables. This option can be specified multiple times.") {
719ac9a064cSDimitry Andric AddSimpleArgumentList(eArgTypeVarName, eArgRepeatPlus);
720f034231aSEd Maste
721f034231aSEd Maste m_option_group.Append(&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
722f034231aSEd Maste m_option_group.Append(&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
72314f1b3e8SDimitry Andric m_option_group.Append(&m_option_format,
72414f1b3e8SDimitry Andric OptionGroupFormat::OPTION_GROUP_FORMAT |
72514f1b3e8SDimitry Andric OptionGroupFormat::OPTION_GROUP_GDB_FMT,
72614f1b3e8SDimitry Andric LLDB_OPT_SET_1);
72714f1b3e8SDimitry Andric m_option_group.Append(&m_option_compile_units, LLDB_OPT_SET_ALL,
72814f1b3e8SDimitry Andric LLDB_OPT_SET_1);
72914f1b3e8SDimitry Andric m_option_group.Append(&m_option_shared_libraries, LLDB_OPT_SET_ALL,
73014f1b3e8SDimitry Andric LLDB_OPT_SET_1);
731f034231aSEd Maste m_option_group.Finalize();
732f034231aSEd Maste }
733f034231aSEd Maste
734f3fbd1c0SDimitry Andric ~CommandObjectTargetVariable() override = default;
735f034231aSEd Maste
DumpValueObject(Stream & s,VariableSP & var_sp,ValueObjectSP & valobj_sp,const char * root_name)73614f1b3e8SDimitry Andric void DumpValueObject(Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp,
73714f1b3e8SDimitry Andric const char *root_name) {
738f21a844fSEd Maste DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions());
739f034231aSEd Maste
740f3fbd1c0SDimitry Andric if (!valobj_sp->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
741f3fbd1c0SDimitry Andric valobj_sp->IsRuntimeSupportValue())
7425e95aa85SEd Maste return;
7435e95aa85SEd Maste
74414f1b3e8SDimitry Andric switch (var_sp->GetScope()) {
745f034231aSEd Maste case eValueTypeVariableGlobal:
746f034231aSEd Maste if (m_option_variable.show_scope)
747f034231aSEd Maste s.PutCString("GLOBAL: ");
748f034231aSEd Maste break;
749f034231aSEd Maste
750f034231aSEd Maste case eValueTypeVariableStatic:
751f034231aSEd Maste if (m_option_variable.show_scope)
752f034231aSEd Maste s.PutCString("STATIC: ");
753f034231aSEd Maste break;
754f034231aSEd Maste
755f034231aSEd Maste case eValueTypeVariableArgument:
756f034231aSEd Maste if (m_option_variable.show_scope)
757f034231aSEd Maste s.PutCString(" ARG: ");
758f034231aSEd Maste break;
759f034231aSEd Maste
760f034231aSEd Maste case eValueTypeVariableLocal:
761f034231aSEd Maste if (m_option_variable.show_scope)
762f034231aSEd Maste s.PutCString(" LOCAL: ");
763f034231aSEd Maste break;
764f034231aSEd Maste
765f3fbd1c0SDimitry Andric case eValueTypeVariableThreadLocal:
766f3fbd1c0SDimitry Andric if (m_option_variable.show_scope)
767f3fbd1c0SDimitry Andric s.PutCString("THREAD: ");
768f3fbd1c0SDimitry Andric break;
769f3fbd1c0SDimitry Andric
770f034231aSEd Maste default:
771f034231aSEd Maste break;
772f034231aSEd Maste }
773f034231aSEd Maste
77414f1b3e8SDimitry Andric if (m_option_variable.show_decl) {
775f034231aSEd Maste bool show_fullpaths = false;
776f034231aSEd Maste bool show_module = true;
777f034231aSEd Maste if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
778f034231aSEd Maste s.PutCString(": ");
779f034231aSEd Maste }
780f034231aSEd Maste
781f034231aSEd Maste const Format format = m_option_format.GetFormat();
782f034231aSEd Maste if (format != eFormatDefault)
783f034231aSEd Maste options.SetFormat(format);
784f034231aSEd Maste
785f034231aSEd Maste options.SetRootValueObjectName(root_name);
786f034231aSEd Maste
787ac9a064cSDimitry Andric if (llvm::Error error = valobj_sp->Dump(s, options))
788ac9a064cSDimitry Andric s << "error: " << toString(std::move(error));
789f034231aSEd Maste }
790f034231aSEd Maste
GetVariableCallback(void * baton,const char * name,VariableList & variable_list)79114f1b3e8SDimitry Andric static size_t GetVariableCallback(void *baton, const char *name,
79214f1b3e8SDimitry Andric VariableList &variable_list) {
793ead24645SDimitry Andric size_t old_size = variable_list.GetSize();
794f034231aSEd Maste Target *target = static_cast<Target *>(baton);
795ead24645SDimitry Andric if (target)
796ead24645SDimitry Andric target->GetImages().FindGlobalVariables(ConstString(name), UINT32_MAX,
797ead24645SDimitry Andric variable_list);
798ead24645SDimitry Andric return variable_list.GetSize() - old_size;
799f034231aSEd Maste }
800f034231aSEd Maste
GetOptions()80114f1b3e8SDimitry Andric Options *GetOptions() override { return &m_option_group; }
802f034231aSEd Maste
803f034231aSEd Maste protected:
DumpGlobalVariableList(const ExecutionContext & exe_ctx,const SymbolContext & sc,const VariableList & variable_list,Stream & s)80414f1b3e8SDimitry Andric void DumpGlobalVariableList(const ExecutionContext &exe_ctx,
80514f1b3e8SDimitry Andric const SymbolContext &sc,
80614f1b3e8SDimitry Andric const VariableList &variable_list, Stream &s) {
807706b4fc4SDimitry Andric if (variable_list.Empty())
808706b4fc4SDimitry Andric return;
80914f1b3e8SDimitry Andric if (sc.module_sp) {
81014f1b3e8SDimitry Andric if (sc.comp_unit) {
811706b4fc4SDimitry Andric s.Format("Global variables for {0} in {1}:\n",
812706b4fc4SDimitry Andric sc.comp_unit->GetPrimaryFile(), sc.module_sp->GetFileSpec());
81314f1b3e8SDimitry Andric } else {
814f034231aSEd Maste s.Printf("Global variables for %s\n",
815f034231aSEd Maste sc.module_sp->GetFileSpec().GetPath().c_str());
816f034231aSEd Maste }
81714f1b3e8SDimitry Andric } else if (sc.comp_unit) {
818706b4fc4SDimitry Andric s.Format("Global variables for {0}\n", sc.comp_unit->GetPrimaryFile());
819f034231aSEd Maste }
820f034231aSEd Maste
821706b4fc4SDimitry Andric for (VariableSP var_sp : variable_list) {
822706b4fc4SDimitry Andric if (!var_sp)
823706b4fc4SDimitry Andric continue;
82414f1b3e8SDimitry Andric ValueObjectSP valobj_sp(ValueObjectVariable::Create(
82514f1b3e8SDimitry Andric exe_ctx.GetBestExecutionContextScope(), var_sp));
826f034231aSEd Maste
827f034231aSEd Maste if (valobj_sp)
828706b4fc4SDimitry Andric DumpValueObject(s, var_sp, valobj_sp, var_sp->GetName().GetCString());
829f034231aSEd Maste }
830f034231aSEd Maste }
831f3fbd1c0SDimitry Andric
DoExecute(Args & args,CommandReturnObject & result)832b1c73532SDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override {
833f034231aSEd Maste Target *target = m_exe_ctx.GetTargetPtr();
834f034231aSEd Maste const size_t argc = args.GetArgumentCount();
835f034231aSEd Maste Stream &s = result.GetOutputStream();
836f034231aSEd Maste
83714f1b3e8SDimitry Andric if (argc > 0) {
838cfca06d7SDimitry Andric for (const Args::ArgEntry &arg : args) {
839f034231aSEd Maste VariableList variable_list;
840f034231aSEd Maste ValueObjectList valobj_list;
841f034231aSEd Maste
842f034231aSEd Maste size_t matches = 0;
843f034231aSEd Maste bool use_var_name = false;
84414f1b3e8SDimitry Andric if (m_option_variable.use_regex) {
845344a3780SDimitry Andric RegularExpression regex(arg.ref());
84614f1b3e8SDimitry Andric if (!regex.IsValid()) {
84714f1b3e8SDimitry Andric result.GetErrorStream().Printf(
848cfca06d7SDimitry Andric "error: invalid regular expression: '%s'\n", arg.c_str());
849b1c73532SDimitry Andric return;
850f034231aSEd Maste }
851f034231aSEd Maste use_var_name = true;
852ead24645SDimitry Andric target->GetImages().FindGlobalVariables(regex, UINT32_MAX,
853f73363f1SDimitry Andric variable_list);
854ead24645SDimitry Andric matches = variable_list.GetSize();
85514f1b3e8SDimitry Andric } else {
856b76161e4SDimitry Andric Status error(Variable::GetValuesForVariableExpressionPath(
857cfca06d7SDimitry Andric arg.c_str(), m_exe_ctx.GetBestExecutionContextScope(),
85814f1b3e8SDimitry Andric GetVariableCallback, target, variable_list, valobj_list));
859f034231aSEd Maste matches = variable_list.GetSize();
860f034231aSEd Maste }
861f034231aSEd Maste
86214f1b3e8SDimitry Andric if (matches == 0) {
863344a3780SDimitry Andric result.AppendErrorWithFormat("can't find global variable '%s'",
864344a3780SDimitry Andric arg.c_str());
865b1c73532SDimitry Andric return;
86614f1b3e8SDimitry Andric } else {
86714f1b3e8SDimitry Andric for (uint32_t global_idx = 0; global_idx < matches; ++global_idx) {
868f034231aSEd Maste VariableSP var_sp(variable_list.GetVariableAtIndex(global_idx));
86914f1b3e8SDimitry Andric if (var_sp) {
87014f1b3e8SDimitry Andric ValueObjectSP valobj_sp(
87114f1b3e8SDimitry Andric valobj_list.GetValueObjectAtIndex(global_idx));
872f034231aSEd Maste if (!valobj_sp)
87314f1b3e8SDimitry Andric valobj_sp = ValueObjectVariable::Create(
87414f1b3e8SDimitry Andric m_exe_ctx.GetBestExecutionContextScope(), var_sp);
875f034231aSEd Maste
876f034231aSEd Maste if (valobj_sp)
87714f1b3e8SDimitry Andric DumpValueObject(s, var_sp, valobj_sp,
87814f1b3e8SDimitry Andric use_var_name ? var_sp->GetName().GetCString()
879cfca06d7SDimitry Andric : arg.c_str());
880f034231aSEd Maste }
881f034231aSEd Maste }
882f034231aSEd Maste }
883f034231aSEd Maste }
88414f1b3e8SDimitry Andric } else {
88514f1b3e8SDimitry Andric const FileSpecList &compile_units =
88614f1b3e8SDimitry Andric m_option_compile_units.GetOptionValue().GetCurrentValue();
88714f1b3e8SDimitry Andric const FileSpecList &shlibs =
88814f1b3e8SDimitry Andric m_option_shared_libraries.GetOptionValue().GetCurrentValue();
889f034231aSEd Maste SymbolContextList sc_list;
890f034231aSEd Maste const size_t num_compile_units = compile_units.GetSize();
891f034231aSEd Maste const size_t num_shlibs = shlibs.GetSize();
89214f1b3e8SDimitry Andric if (num_compile_units == 0 && num_shlibs == 0) {
893f034231aSEd Maste bool success = false;
894f034231aSEd Maste StackFrame *frame = m_exe_ctx.GetFramePtr();
895f3fbd1c0SDimitry Andric CompileUnit *comp_unit = nullptr;
89614f1b3e8SDimitry Andric if (frame) {
897f034231aSEd Maste SymbolContext sc = frame->GetSymbolContext(eSymbolContextCompUnit);
898b60736ecSDimitry Andric comp_unit = sc.comp_unit;
89914f1b3e8SDimitry Andric if (sc.comp_unit) {
900f034231aSEd Maste const bool can_create = true;
90114f1b3e8SDimitry Andric VariableListSP comp_unit_varlist_sp(
90214f1b3e8SDimitry Andric sc.comp_unit->GetVariableList(can_create));
90314f1b3e8SDimitry Andric if (comp_unit_varlist_sp) {
904f034231aSEd Maste size_t count = comp_unit_varlist_sp->GetSize();
90514f1b3e8SDimitry Andric if (count > 0) {
906f034231aSEd Maste DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
907f034231aSEd Maste success = true;
908f034231aSEd Maste }
909f034231aSEd Maste }
910f034231aSEd Maste }
911f034231aSEd Maste }
91214f1b3e8SDimitry Andric if (!success) {
91314f1b3e8SDimitry Andric if (frame) {
914f034231aSEd Maste if (comp_unit)
915706b4fc4SDimitry Andric result.AppendErrorWithFormatv(
916706b4fc4SDimitry Andric "no global variables in current compile unit: {0}\n",
917706b4fc4SDimitry Andric comp_unit->GetPrimaryFile());
918f034231aSEd Maste else
91914f1b3e8SDimitry Andric result.AppendErrorWithFormat(
92014f1b3e8SDimitry Andric "no debug information for frame %u\n",
92114f1b3e8SDimitry Andric frame->GetFrameIndex());
92214f1b3e8SDimitry Andric } else
92314f1b3e8SDimitry Andric result.AppendError("'target variable' takes one or more global "
92414f1b3e8SDimitry Andric "variable names as arguments\n");
925f034231aSEd Maste }
92614f1b3e8SDimitry Andric } else {
927f034231aSEd Maste SymbolContextList sc_list;
928f034231aSEd Maste // We have one or more compile unit or shlib
92914f1b3e8SDimitry Andric if (num_shlibs > 0) {
93014f1b3e8SDimitry Andric for (size_t shlib_idx = 0; shlib_idx < num_shlibs; ++shlib_idx) {
931f034231aSEd Maste const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx));
932f034231aSEd Maste ModuleSpec module_spec(module_file);
933f034231aSEd Maste
93414f1b3e8SDimitry Andric ModuleSP module_sp(
93514f1b3e8SDimitry Andric target->GetImages().FindFirstModule(module_spec));
93614f1b3e8SDimitry Andric if (module_sp) {
93714f1b3e8SDimitry Andric if (num_compile_units > 0) {
938f034231aSEd Maste for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
93914f1b3e8SDimitry Andric module_sp->FindCompileUnits(
940ead24645SDimitry Andric compile_units.GetFileSpecAtIndex(cu_idx), sc_list);
94114f1b3e8SDimitry Andric } else {
942f034231aSEd Maste SymbolContext sc;
943f034231aSEd Maste sc.module_sp = module_sp;
944f034231aSEd Maste sc_list.Append(sc);
945f034231aSEd Maste }
94614f1b3e8SDimitry Andric } else {
947f034231aSEd Maste // Didn't find matching shlib/module in target...
94814f1b3e8SDimitry Andric result.AppendErrorWithFormat(
94914f1b3e8SDimitry Andric "target doesn't contain the specified shared library: %s\n",
950f034231aSEd Maste module_file.GetPath().c_str());
951f034231aSEd Maste }
952f034231aSEd Maste }
95314f1b3e8SDimitry Andric } else {
95414f1b3e8SDimitry Andric // No shared libraries, we just want to find globals for the compile
95514f1b3e8SDimitry Andric // units files that were specified
956f034231aSEd Maste for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
95714f1b3e8SDimitry Andric target->GetImages().FindCompileUnits(
958ead24645SDimitry Andric compile_units.GetFileSpecAtIndex(cu_idx), sc_list);
959f034231aSEd Maste }
960f034231aSEd Maste
9617fa27ce4SDimitry Andric for (const SymbolContext &sc : sc_list) {
96214f1b3e8SDimitry Andric if (sc.comp_unit) {
963f034231aSEd Maste const bool can_create = true;
96414f1b3e8SDimitry Andric VariableListSP comp_unit_varlist_sp(
96514f1b3e8SDimitry Andric sc.comp_unit->GetVariableList(can_create));
966f034231aSEd Maste if (comp_unit_varlist_sp)
9677fa27ce4SDimitry Andric DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
96814f1b3e8SDimitry Andric } else if (sc.module_sp) {
969f034231aSEd Maste // Get all global variables for this module
97014f1b3e8SDimitry Andric lldb_private::RegularExpression all_globals_regex(
9717fa27ce4SDimitry Andric llvm::StringRef(".")); // Any global with at least one character
972f034231aSEd Maste VariableList variable_list;
973f73363f1SDimitry Andric sc.module_sp->FindGlobalVariables(all_globals_regex, UINT32_MAX,
974f73363f1SDimitry Andric variable_list);
975f034231aSEd Maste DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s);
976f034231aSEd Maste }
977f034231aSEd Maste }
978f034231aSEd Maste }
979f034231aSEd Maste }
980f034231aSEd Maste
981145449b1SDimitry Andric m_interpreter.PrintWarningsIfNecessary(result.GetOutputStream(),
982145449b1SDimitry Andric m_cmd_name);
983f034231aSEd Maste }
984f034231aSEd Maste
985f034231aSEd Maste OptionGroupOptions m_option_group;
986f034231aSEd Maste OptionGroupVariable m_option_variable;
987f034231aSEd Maste OptionGroupFormat m_option_format;
988f034231aSEd Maste OptionGroupFileList m_option_compile_units;
989f034231aSEd Maste OptionGroupFileList m_option_shared_libraries;
990f034231aSEd Maste OptionGroupValueObjectDisplay m_varobj_options;
991f034231aSEd Maste };
992f034231aSEd Maste
993f034231aSEd Maste #pragma mark CommandObjectTargetModulesSearchPathsAdd
994f034231aSEd Maste
99514f1b3e8SDimitry Andric class CommandObjectTargetModulesSearchPathsAdd : public CommandObjectParsed {
996f034231aSEd Maste public:
CommandObjectTargetModulesSearchPathsAdd(CommandInterpreter & interpreter)99714f1b3e8SDimitry Andric CommandObjectTargetModulesSearchPathsAdd(CommandInterpreter &interpreter)
99814f1b3e8SDimitry Andric : CommandObjectParsed(interpreter, "target modules search-paths add",
99914f1b3e8SDimitry Andric "Add new image search paths substitution pairs to "
100014f1b3e8SDimitry Andric "the current target.",
1001ead24645SDimitry Andric nullptr, eCommandRequiresTarget) {
1002f034231aSEd Maste CommandArgumentEntry arg;
1003f034231aSEd Maste CommandArgumentData old_prefix_arg;
1004f034231aSEd Maste CommandArgumentData new_prefix_arg;
1005f034231aSEd Maste
1006f034231aSEd Maste // Define the first variant of this arg pair.
1007f034231aSEd Maste old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1008f034231aSEd Maste old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1009f034231aSEd Maste
1010f034231aSEd Maste // Define the first variant of this arg pair.
1011f034231aSEd Maste new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1012f034231aSEd Maste new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1013f034231aSEd Maste
1014f73363f1SDimitry Andric // There are two required arguments that must always occur together, i.e.
1015f73363f1SDimitry Andric // an argument "pair". Because they must always occur together, they are
1016f73363f1SDimitry Andric // treated as two variants of one argument rather than two independent
101714f1b3e8SDimitry Andric // arguments. Push them both into the first argument position for
101814f1b3e8SDimitry Andric // m_arguments...
1019f034231aSEd Maste
1020f034231aSEd Maste arg.push_back(old_prefix_arg);
1021f034231aSEd Maste arg.push_back(new_prefix_arg);
1022f034231aSEd Maste
1023f034231aSEd Maste m_arguments.push_back(arg);
1024f034231aSEd Maste }
1025f034231aSEd Maste
1026f3fbd1c0SDimitry Andric ~CommandObjectTargetModulesSearchPathsAdd() override = default;
1027f034231aSEd Maste
1028f034231aSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)1029b1c73532SDimitry Andric void DoExecute(Args &command, CommandReturnObject &result) override {
1030ead24645SDimitry Andric Target *target = &GetSelectedTarget();
1031f034231aSEd Maste const size_t argc = command.GetArgumentCount();
103214f1b3e8SDimitry Andric if (argc & 1) {
1033f034231aSEd Maste result.AppendError("add requires an even number of arguments\n");
103414f1b3e8SDimitry Andric } else {
103514f1b3e8SDimitry Andric for (size_t i = 0; i < argc; i += 2) {
1036f034231aSEd Maste const char *from = command.GetArgumentAtIndex(i);
1037f034231aSEd Maste const char *to = command.GetArgumentAtIndex(i + 1);
1038f034231aSEd Maste
103914f1b3e8SDimitry Andric if (from[0] && to[0]) {
1040145449b1SDimitry Andric Log *log = GetLog(LLDBLog::Host);
104114f1b3e8SDimitry Andric if (log) {
1042ead24645SDimitry Andric LLDB_LOGF(log,
1043ead24645SDimitry Andric "target modules search path adding ImageSearchPath "
104414f1b3e8SDimitry Andric "pair: '%s' -> '%s'",
1045e81d9d49SDimitry Andric from, to);
1046e81d9d49SDimitry Andric }
1047f034231aSEd Maste bool last_pair = ((argc - i) == 2);
104814f1b3e8SDimitry Andric target->GetImageSearchPathList().Append(
1049c0981da4SDimitry Andric from, to, last_pair); // Notify if this is the last pair
1050f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishNoResult);
105114f1b3e8SDimitry Andric } else {
1052f034231aSEd Maste if (from[0])
1053f034231aSEd Maste result.AppendError("<path-prefix> can't be empty\n");
1054f034231aSEd Maste else
1055f034231aSEd Maste result.AppendError("<new-path-prefix> can't be empty\n");
1056f034231aSEd Maste }
1057f034231aSEd Maste }
1058f034231aSEd Maste }
1059f034231aSEd Maste }
1060f034231aSEd Maste };
1061f034231aSEd Maste
1062f034231aSEd Maste #pragma mark CommandObjectTargetModulesSearchPathsClear
1063f034231aSEd Maste
106414f1b3e8SDimitry Andric class CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed {
1065f034231aSEd Maste public:
CommandObjectTargetModulesSearchPathsClear(CommandInterpreter & interpreter)106614f1b3e8SDimitry Andric CommandObjectTargetModulesSearchPathsClear(CommandInterpreter &interpreter)
106714f1b3e8SDimitry Andric : CommandObjectParsed(interpreter, "target modules search-paths clear",
106814f1b3e8SDimitry Andric "Clear all current image search path substitution "
106914f1b3e8SDimitry Andric "pairs from the current target.",
1070ead24645SDimitry Andric "target modules search-paths clear",
1071ead24645SDimitry Andric eCommandRequiresTarget) {}
1072f034231aSEd Maste
1073f3fbd1c0SDimitry Andric ~CommandObjectTargetModulesSearchPathsClear() override = default;
1074f034231aSEd Maste
1075f034231aSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)1076b1c73532SDimitry Andric void DoExecute(Args &command, CommandReturnObject &result) override {
1077ead24645SDimitry Andric Target *target = &GetSelectedTarget();
1078f034231aSEd Maste bool notify = true;
1079f034231aSEd Maste target->GetImageSearchPathList().Clear(notify);
1080f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishNoResult);
1081f034231aSEd Maste }
1082f034231aSEd Maste };
1083f034231aSEd Maste
1084f034231aSEd Maste #pragma mark CommandObjectTargetModulesSearchPathsInsert
1085f034231aSEd Maste
108614f1b3e8SDimitry Andric class CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed {
1087f034231aSEd Maste public:
CommandObjectTargetModulesSearchPathsInsert(CommandInterpreter & interpreter)108814f1b3e8SDimitry Andric CommandObjectTargetModulesSearchPathsInsert(CommandInterpreter &interpreter)
108914f1b3e8SDimitry Andric : CommandObjectParsed(interpreter, "target modules search-paths insert",
109014f1b3e8SDimitry Andric "Insert a new image search path substitution pair "
109114f1b3e8SDimitry Andric "into the current target at the specified index.",
1092ead24645SDimitry Andric nullptr, eCommandRequiresTarget) {
1093f034231aSEd Maste CommandArgumentEntry arg1;
1094f034231aSEd Maste CommandArgumentEntry arg2;
1095f034231aSEd Maste CommandArgumentData index_arg;
1096f034231aSEd Maste CommandArgumentData old_prefix_arg;
1097f034231aSEd Maste CommandArgumentData new_prefix_arg;
1098f034231aSEd Maste
1099f034231aSEd Maste // Define the first and only variant of this arg.
1100f034231aSEd Maste index_arg.arg_type = eArgTypeIndex;
1101f034231aSEd Maste index_arg.arg_repetition = eArgRepeatPlain;
1102f034231aSEd Maste
1103f034231aSEd Maste // Put the one and only variant into the first arg for m_arguments:
1104f034231aSEd Maste arg1.push_back(index_arg);
1105f034231aSEd Maste
1106f034231aSEd Maste // Define the first variant of this arg pair.
1107f034231aSEd Maste old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1108f034231aSEd Maste old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1109f034231aSEd Maste
1110f034231aSEd Maste // Define the first variant of this arg pair.
1111f034231aSEd Maste new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1112f034231aSEd Maste new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1113f034231aSEd Maste
1114f73363f1SDimitry Andric // There are two required arguments that must always occur together, i.e.
1115f73363f1SDimitry Andric // an argument "pair". Because they must always occur together, they are
1116f73363f1SDimitry Andric // treated as two variants of one argument rather than two independent
111714f1b3e8SDimitry Andric // arguments. Push them both into the same argument position for
111814f1b3e8SDimitry Andric // m_arguments...
1119f034231aSEd Maste
1120f034231aSEd Maste arg2.push_back(old_prefix_arg);
1121f034231aSEd Maste arg2.push_back(new_prefix_arg);
1122f034231aSEd Maste
1123f034231aSEd Maste // Add arguments to m_arguments.
1124f034231aSEd Maste m_arguments.push_back(arg1);
1125f034231aSEd Maste m_arguments.push_back(arg2);
1126f034231aSEd Maste }
1127f034231aSEd Maste
1128f3fbd1c0SDimitry Andric ~CommandObjectTargetModulesSearchPathsInsert() override = default;
1129f034231aSEd Maste
1130b60736ecSDimitry Andric void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)1131b60736ecSDimitry Andric HandleArgumentCompletion(CompletionRequest &request,
1132b60736ecSDimitry Andric OptionElementVector &opt_element_vector) override {
1133b60736ecSDimitry Andric if (!m_exe_ctx.HasTargetScope() || request.GetCursorIndex() != 0)
1134b60736ecSDimitry Andric return;
1135b60736ecSDimitry Andric
1136b60736ecSDimitry Andric Target *target = m_exe_ctx.GetTargetPtr();
1137b60736ecSDimitry Andric const PathMappingList &list = target->GetImageSearchPathList();
1138b60736ecSDimitry Andric const size_t num = list.GetSize();
1139b60736ecSDimitry Andric ConstString old_path, new_path;
1140b60736ecSDimitry Andric for (size_t i = 0; i < num; ++i) {
1141b60736ecSDimitry Andric if (!list.GetPathsAtIndex(i, old_path, new_path))
1142b60736ecSDimitry Andric break;
1143b60736ecSDimitry Andric StreamString strm;
1144b60736ecSDimitry Andric strm << old_path << " -> " << new_path;
1145b60736ecSDimitry Andric request.TryCompleteCurrentArg(std::to_string(i), strm.GetString());
1146b60736ecSDimitry Andric }
1147b60736ecSDimitry Andric }
1148b60736ecSDimitry Andric
1149f034231aSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)1150b1c73532SDimitry Andric void DoExecute(Args &command, CommandReturnObject &result) override {
1151ead24645SDimitry Andric Target *target = &GetSelectedTarget();
1152f034231aSEd Maste size_t argc = command.GetArgumentCount();
1153e81d9d49SDimitry Andric // check for at least 3 arguments and an odd number of parameters
115414f1b3e8SDimitry Andric if (argc >= 3 && argc & 1) {
1155cfca06d7SDimitry Andric uint32_t insert_idx;
1156f034231aSEd Maste
1157cfca06d7SDimitry Andric if (!llvm::to_integer(command.GetArgumentAtIndex(0), insert_idx)) {
115814f1b3e8SDimitry Andric result.AppendErrorWithFormat(
115914f1b3e8SDimitry Andric "<index> parameter is not an integer: '%s'.\n",
116014f1b3e8SDimitry Andric command.GetArgumentAtIndex(0));
1161b1c73532SDimitry Andric return;
1162f034231aSEd Maste }
1163f034231aSEd Maste
1164f034231aSEd Maste // shift off the index
1165f034231aSEd Maste command.Shift();
1166f034231aSEd Maste argc = command.GetArgumentCount();
1167f034231aSEd Maste
116814f1b3e8SDimitry Andric for (uint32_t i = 0; i < argc; i += 2, ++insert_idx) {
1169f034231aSEd Maste const char *from = command.GetArgumentAtIndex(i);
1170f034231aSEd Maste const char *to = command.GetArgumentAtIndex(i + 1);
1171f034231aSEd Maste
117214f1b3e8SDimitry Andric if (from[0] && to[0]) {
1173f034231aSEd Maste bool last_pair = ((argc - i) == 2);
1174c0981da4SDimitry Andric target->GetImageSearchPathList().Insert(from, to, insert_idx,
1175c0981da4SDimitry Andric last_pair);
1176f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishNoResult);
117714f1b3e8SDimitry Andric } else {
1178f034231aSEd Maste if (from[0])
1179f034231aSEd Maste result.AppendError("<path-prefix> can't be empty\n");
1180f034231aSEd Maste else
1181f034231aSEd Maste result.AppendError("<new-path-prefix> can't be empty\n");
1182b1c73532SDimitry Andric return;
1183f034231aSEd Maste }
1184f034231aSEd Maste }
118514f1b3e8SDimitry Andric } else {
1186f034231aSEd Maste result.AppendError("insert requires at least three arguments\n");
1187f034231aSEd Maste }
1188f034231aSEd Maste }
1189f034231aSEd Maste };
1190f034231aSEd Maste
1191f034231aSEd Maste #pragma mark CommandObjectTargetModulesSearchPathsList
1192f034231aSEd Maste
119314f1b3e8SDimitry Andric class CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed {
1194f034231aSEd Maste public:
CommandObjectTargetModulesSearchPathsList(CommandInterpreter & interpreter)119514f1b3e8SDimitry Andric CommandObjectTargetModulesSearchPathsList(CommandInterpreter &interpreter)
119614f1b3e8SDimitry Andric : CommandObjectParsed(interpreter, "target modules search-paths list",
119714f1b3e8SDimitry Andric "List all current image search path substitution "
119814f1b3e8SDimitry Andric "pairs in the current target.",
1199ead24645SDimitry Andric "target modules search-paths list",
1200ead24645SDimitry Andric eCommandRequiresTarget) {}
1201f034231aSEd Maste
1202f3fbd1c0SDimitry Andric ~CommandObjectTargetModulesSearchPathsList() override = default;
1203f034231aSEd Maste
1204f034231aSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)1205b1c73532SDimitry Andric void DoExecute(Args &command, CommandReturnObject &result) override {
1206ead24645SDimitry Andric Target *target = &GetSelectedTarget();
1207f034231aSEd Maste
1208f034231aSEd Maste target->GetImageSearchPathList().Dump(&result.GetOutputStream());
1209f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
1210f034231aSEd Maste }
1211f034231aSEd Maste };
1212f034231aSEd Maste
1213f034231aSEd Maste #pragma mark CommandObjectTargetModulesSearchPathsQuery
1214f034231aSEd Maste
121514f1b3e8SDimitry Andric class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed {
1216f034231aSEd Maste public:
CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter & interpreter)121714f1b3e8SDimitry Andric CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter &interpreter)
121814f1b3e8SDimitry Andric : CommandObjectParsed(
121914f1b3e8SDimitry Andric interpreter, "target modules search-paths query",
1220f034231aSEd Maste "Transform a path using the first applicable image search path.",
1221ead24645SDimitry Andric nullptr, eCommandRequiresTarget) {
1222ac9a064cSDimitry Andric AddSimpleArgumentList(eArgTypeDirectoryName);
1223f034231aSEd Maste }
1224f034231aSEd Maste
1225f3fbd1c0SDimitry Andric ~CommandObjectTargetModulesSearchPathsQuery() override = default;
1226f034231aSEd Maste
1227f034231aSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)1228b1c73532SDimitry Andric void DoExecute(Args &command, CommandReturnObject &result) override {
1229ead24645SDimitry Andric Target *target = &GetSelectedTarget();
123014f1b3e8SDimitry Andric if (command.GetArgumentCount() != 1) {
1231f034231aSEd Maste result.AppendError("query requires one argument\n");
1232b1c73532SDimitry Andric return;
1233f034231aSEd Maste }
1234f034231aSEd Maste
1235f034231aSEd Maste ConstString orig(command.GetArgumentAtIndex(0));
1236f034231aSEd Maste ConstString transformed;
1237f034231aSEd Maste if (target->GetImageSearchPathList().RemapPath(orig, transformed))
1238f034231aSEd Maste result.GetOutputStream().Printf("%s\n", transformed.GetCString());
1239f034231aSEd Maste else
1240f034231aSEd Maste result.GetOutputStream().Printf("%s\n", orig.GetCString());
1241f034231aSEd Maste
1242f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
1243f034231aSEd Maste }
1244f034231aSEd Maste };
1245f034231aSEd Maste
1246f034231aSEd Maste // Static Helper functions
DumpModuleArchitecture(Stream & strm,Module * module,bool full_triple,uint32_t width)124714f1b3e8SDimitry Andric static void DumpModuleArchitecture(Stream &strm, Module *module,
124814f1b3e8SDimitry Andric bool full_triple, uint32_t width) {
124914f1b3e8SDimitry Andric if (module) {
1250e81d9d49SDimitry Andric StreamString arch_strm;
1251e81d9d49SDimitry Andric
1252f034231aSEd Maste if (full_triple)
1253706b4fc4SDimitry Andric module->GetArchitecture().DumpTriple(arch_strm.AsRawOstream());
1254f034231aSEd Maste else
1255e81d9d49SDimitry Andric arch_strm.PutCString(module->GetArchitecture().GetArchitectureName());
1256cfca06d7SDimitry Andric std::string arch_str = std::string(arch_strm.GetString());
1257e81d9d49SDimitry Andric
1258f034231aSEd Maste if (width)
1259e81d9d49SDimitry Andric strm.Printf("%-*s", width, arch_str.c_str());
1260f034231aSEd Maste else
126114f1b3e8SDimitry Andric strm.PutCString(arch_str);
1262f034231aSEd Maste }
1263f034231aSEd Maste }
1264f034231aSEd Maste
DumpModuleUUID(Stream & strm,Module * module)126514f1b3e8SDimitry Andric static void DumpModuleUUID(Stream &strm, Module *module) {
1266f034231aSEd Maste if (module && module->GetUUID().IsValid())
12677fa27ce4SDimitry Andric module->GetUUID().Dump(strm);
1268f034231aSEd Maste else
1269f034231aSEd Maste strm.PutCString(" ");
1270f034231aSEd Maste }
1271f034231aSEd Maste
DumpCompileUnitLineTable(CommandInterpreter & interpreter,Stream & strm,Module * module,const FileSpec & file_spec,lldb::DescriptionLevel desc_level)127214f1b3e8SDimitry Andric static uint32_t DumpCompileUnitLineTable(CommandInterpreter &interpreter,
127314f1b3e8SDimitry Andric Stream &strm, Module *module,
1274f034231aSEd Maste const FileSpec &file_spec,
12755f29bb8aSDimitry Andric lldb::DescriptionLevel desc_level) {
1276f034231aSEd Maste uint32_t num_matches = 0;
127714f1b3e8SDimitry Andric if (module) {
1278f034231aSEd Maste SymbolContextList sc_list;
127914f1b3e8SDimitry Andric num_matches = module->ResolveSymbolContextsForFileSpec(
128014f1b3e8SDimitry Andric file_spec, 0, false, eSymbolContextCompUnit, sc_list);
1281f034231aSEd Maste
12827fa27ce4SDimitry Andric bool first_module = true;
12837fa27ce4SDimitry Andric for (const SymbolContext &sc : sc_list) {
12847fa27ce4SDimitry Andric if (!first_module)
1285f034231aSEd Maste strm << "\n\n";
1286f034231aSEd Maste
1287706b4fc4SDimitry Andric strm << "Line table for " << sc.comp_unit->GetPrimaryFile() << " in `"
1288706b4fc4SDimitry Andric << module->GetFileSpec().GetFilename() << "\n";
1289f034231aSEd Maste LineTable *line_table = sc.comp_unit->GetLineTable();
1290f034231aSEd Maste if (line_table)
129114f1b3e8SDimitry Andric line_table->GetDescription(
129214f1b3e8SDimitry Andric &strm, interpreter.GetExecutionContext().GetTargetPtr(),
12935f29bb8aSDimitry Andric desc_level);
1294f034231aSEd Maste else
1295f034231aSEd Maste strm << "No line table";
12967fa27ce4SDimitry Andric
12977fa27ce4SDimitry Andric first_module = false;
1298f034231aSEd Maste }
1299f034231aSEd Maste }
1300f034231aSEd Maste return num_matches;
1301f034231aSEd Maste }
1302f034231aSEd Maste
DumpFullpath(Stream & strm,const FileSpec * file_spec_ptr,uint32_t width)130314f1b3e8SDimitry Andric static void DumpFullpath(Stream &strm, const FileSpec *file_spec_ptr,
130414f1b3e8SDimitry Andric uint32_t width) {
130514f1b3e8SDimitry Andric if (file_spec_ptr) {
130614f1b3e8SDimitry Andric if (width > 0) {
1307f034231aSEd Maste std::string fullpath = file_spec_ptr->GetPath();
1308f034231aSEd Maste strm.Printf("%-*s", width, fullpath.c_str());
1309f034231aSEd Maste return;
131014f1b3e8SDimitry Andric } else {
1311706b4fc4SDimitry Andric file_spec_ptr->Dump(strm.AsRawOstream());
1312f034231aSEd Maste return;
1313f034231aSEd Maste }
1314f034231aSEd Maste }
1315f034231aSEd Maste // Keep the width spacing correct if things go wrong...
1316f034231aSEd Maste if (width > 0)
1317f034231aSEd Maste strm.Printf("%-*s", width, "");
1318f034231aSEd Maste }
1319f034231aSEd Maste
DumpDirectory(Stream & strm,const FileSpec * file_spec_ptr,uint32_t width)132014f1b3e8SDimitry Andric static void DumpDirectory(Stream &strm, const FileSpec *file_spec_ptr,
132114f1b3e8SDimitry Andric uint32_t width) {
132214f1b3e8SDimitry Andric if (file_spec_ptr) {
1323f034231aSEd Maste if (width > 0)
1324f034231aSEd Maste strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
1325f034231aSEd Maste else
1326f034231aSEd Maste file_spec_ptr->GetDirectory().Dump(&strm);
1327f034231aSEd Maste return;
1328f034231aSEd Maste }
1329f034231aSEd Maste // Keep the width spacing correct if things go wrong...
1330f034231aSEd Maste if (width > 0)
1331f034231aSEd Maste strm.Printf("%-*s", width, "");
1332f034231aSEd Maste }
1333f034231aSEd Maste
DumpBasename(Stream & strm,const FileSpec * file_spec_ptr,uint32_t width)133414f1b3e8SDimitry Andric static void DumpBasename(Stream &strm, const FileSpec *file_spec_ptr,
133514f1b3e8SDimitry Andric uint32_t width) {
133614f1b3e8SDimitry Andric if (file_spec_ptr) {
1337f034231aSEd Maste if (width > 0)
1338f034231aSEd Maste strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
1339f034231aSEd Maste else
1340f034231aSEd Maste file_spec_ptr->GetFilename().Dump(&strm);
1341f034231aSEd Maste return;
1342f034231aSEd Maste }
1343f034231aSEd Maste // Keep the width spacing correct if things go wrong...
1344f034231aSEd Maste if (width > 0)
1345f034231aSEd Maste strm.Printf("%-*s", width, "");
1346f034231aSEd Maste }
1347f034231aSEd Maste
DumpModuleObjfileHeaders(Stream & strm,ModuleList & module_list)134814f1b3e8SDimitry Andric static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) {
1349f3fbd1c0SDimitry Andric std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
1350f3fbd1c0SDimitry Andric const size_t num_modules = module_list.GetSize();
1351b60736ecSDimitry Andric if (num_modules == 0)
1352b60736ecSDimitry Andric return 0;
1353b60736ecSDimitry Andric
1354b60736ecSDimitry Andric size_t num_dumped = 0;
1355b60736ecSDimitry Andric strm.Format("Dumping headers for {0} module(s).\n", num_modules);
1356f3fbd1c0SDimitry Andric strm.IndentMore();
1357b60736ecSDimitry Andric for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
1358b60736ecSDimitry Andric if (module_sp) {
135914f1b3e8SDimitry Andric if (num_dumped++ > 0) {
1360f3fbd1c0SDimitry Andric strm.EOL();
1361f3fbd1c0SDimitry Andric strm.EOL();
1362f3fbd1c0SDimitry Andric }
1363b60736ecSDimitry Andric ObjectFile *objfile = module_sp->GetObjectFile();
1364f73363f1SDimitry Andric if (objfile)
1365f3fbd1c0SDimitry Andric objfile->Dump(&strm);
1366f73363f1SDimitry Andric else {
1367f73363f1SDimitry Andric strm.Format("No object file for module: {0:F}\n",
1368b60736ecSDimitry Andric module_sp->GetFileSpec());
1369f73363f1SDimitry Andric }
1370f3fbd1c0SDimitry Andric }
1371f3fbd1c0SDimitry Andric }
1372f3fbd1c0SDimitry Andric strm.IndentLess();
1373f3fbd1c0SDimitry Andric return num_dumped;
1374f3fbd1c0SDimitry Andric }
1375f034231aSEd Maste
DumpModuleSymtab(CommandInterpreter & interpreter,Stream & strm,Module * module,SortOrder sort_order,Mangled::NamePreference name_preference)137614f1b3e8SDimitry Andric static void DumpModuleSymtab(CommandInterpreter &interpreter, Stream &strm,
1377706b4fc4SDimitry Andric Module *module, SortOrder sort_order,
1378706b4fc4SDimitry Andric Mangled::NamePreference name_preference) {
1379ead24645SDimitry Andric if (!module)
1380ead24645SDimitry Andric return;
1381ead24645SDimitry Andric if (Symtab *symtab = module->GetSymtab())
138214f1b3e8SDimitry Andric symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(),
1383706b4fc4SDimitry Andric sort_order, name_preference);
1384f034231aSEd Maste }
1385f034231aSEd Maste
DumpModuleSections(CommandInterpreter & interpreter,Stream & strm,Module * module)138614f1b3e8SDimitry Andric static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm,
138714f1b3e8SDimitry Andric Module *module) {
138814f1b3e8SDimitry Andric if (module) {
1389f034231aSEd Maste SectionList *section_list = module->GetSectionList();
139014f1b3e8SDimitry Andric if (section_list) {
1391f034231aSEd Maste strm.Printf("Sections for '%s' (%s):\n",
1392f034231aSEd Maste module->GetSpecificationDescription().c_str(),
1393f034231aSEd Maste module->GetArchitecture().GetArchitectureName());
1394cfca06d7SDimitry Andric section_list->Dump(strm.AsRawOstream(), strm.GetIndentLevel() + 2,
139514f1b3e8SDimitry Andric interpreter.GetExecutionContext().GetTargetPtr(), true,
139614f1b3e8SDimitry Andric UINT32_MAX);
1397f034231aSEd Maste }
1398f034231aSEd Maste }
1399f034231aSEd Maste }
1400f034231aSEd Maste
DumpModuleSymbolFile(Stream & strm,Module * module)1401ead24645SDimitry Andric static bool DumpModuleSymbolFile(Stream &strm, Module *module) {
140214f1b3e8SDimitry Andric if (module) {
1403ead24645SDimitry Andric if (SymbolFile *symbol_file = module->GetSymbolFile(true)) {
1404ead24645SDimitry Andric symbol_file->Dump(strm);
1405f034231aSEd Maste return true;
1406f034231aSEd Maste }
1407f034231aSEd Maste }
1408f034231aSEd Maste return false;
1409f034231aSEd Maste }
1410f034231aSEd Maste
GetSeparateDebugInfoList(StructuredData::Array & list,Module * module,bool errors_only)1411b1c73532SDimitry Andric static bool GetSeparateDebugInfoList(StructuredData::Array &list,
1412b1c73532SDimitry Andric Module *module, bool errors_only) {
1413b1c73532SDimitry Andric if (module) {
1414b1c73532SDimitry Andric if (SymbolFile *symbol_file = module->GetSymbolFile(/*can_create=*/true)) {
1415b1c73532SDimitry Andric StructuredData::Dictionary d;
1416b1c73532SDimitry Andric if (symbol_file->GetSeparateDebugInfo(d, errors_only)) {
1417b1c73532SDimitry Andric list.AddItem(
1418b1c73532SDimitry Andric std::make_shared<StructuredData::Dictionary>(std::move(d)));
1419b1c73532SDimitry Andric return true;
1420b1c73532SDimitry Andric }
1421b1c73532SDimitry Andric }
1422b1c73532SDimitry Andric }
1423b1c73532SDimitry Andric return false;
1424b1c73532SDimitry Andric }
1425b1c73532SDimitry Andric
DumpDwoFilesTable(Stream & strm,StructuredData::Array & dwo_listings)1426b1c73532SDimitry Andric static void DumpDwoFilesTable(Stream &strm,
1427b1c73532SDimitry Andric StructuredData::Array &dwo_listings) {
1428b1c73532SDimitry Andric strm.PutCString("Dwo ID Err Dwo Path");
1429b1c73532SDimitry Andric strm.EOL();
1430b1c73532SDimitry Andric strm.PutCString(
1431b1c73532SDimitry Andric "------------------ --- -----------------------------------------");
1432b1c73532SDimitry Andric strm.EOL();
1433b1c73532SDimitry Andric dwo_listings.ForEach([&strm](StructuredData::Object *dwo) {
1434b1c73532SDimitry Andric StructuredData::Dictionary *dict = dwo->GetAsDictionary();
1435b1c73532SDimitry Andric if (!dict)
1436b1c73532SDimitry Andric return false;
1437b1c73532SDimitry Andric
1438b1c73532SDimitry Andric uint64_t dwo_id;
1439b1c73532SDimitry Andric if (dict->GetValueForKeyAsInteger("dwo_id", dwo_id))
1440b1c73532SDimitry Andric strm.Printf("0x%16.16" PRIx64 " ", dwo_id);
1441b1c73532SDimitry Andric else
1442b1c73532SDimitry Andric strm.Printf("0x???????????????? ");
1443b1c73532SDimitry Andric
1444b1c73532SDimitry Andric llvm::StringRef error;
1445b1c73532SDimitry Andric if (dict->GetValueForKeyAsString("error", error))
1446b1c73532SDimitry Andric strm << "E " << error;
1447b1c73532SDimitry Andric else {
1448b1c73532SDimitry Andric llvm::StringRef resolved_dwo_path;
1449b1c73532SDimitry Andric if (dict->GetValueForKeyAsString("resolved_dwo_path",
1450b1c73532SDimitry Andric resolved_dwo_path)) {
1451b1c73532SDimitry Andric strm << " " << resolved_dwo_path;
1452b1c73532SDimitry Andric if (resolved_dwo_path.ends_with(".dwp")) {
1453b1c73532SDimitry Andric llvm::StringRef dwo_name;
1454b1c73532SDimitry Andric if (dict->GetValueForKeyAsString("dwo_name", dwo_name))
1455b1c73532SDimitry Andric strm << "(" << dwo_name << ")";
1456b1c73532SDimitry Andric }
1457b1c73532SDimitry Andric }
1458b1c73532SDimitry Andric }
1459b1c73532SDimitry Andric strm.EOL();
1460b1c73532SDimitry Andric return true;
1461b1c73532SDimitry Andric });
1462b1c73532SDimitry Andric }
1463b1c73532SDimitry Andric
DumpOsoFilesTable(Stream & strm,StructuredData::Array & oso_listings)1464b1c73532SDimitry Andric static void DumpOsoFilesTable(Stream &strm,
1465b1c73532SDimitry Andric StructuredData::Array &oso_listings) {
1466b1c73532SDimitry Andric strm.PutCString("Mod Time Err Oso Path");
1467b1c73532SDimitry Andric strm.EOL();
1468b1c73532SDimitry Andric strm.PutCString("------------------ --- ---------------------");
1469b1c73532SDimitry Andric strm.EOL();
1470b1c73532SDimitry Andric oso_listings.ForEach([&strm](StructuredData::Object *oso) {
1471b1c73532SDimitry Andric StructuredData::Dictionary *dict = oso->GetAsDictionary();
1472b1c73532SDimitry Andric if (!dict)
1473b1c73532SDimitry Andric return false;
1474b1c73532SDimitry Andric
1475b1c73532SDimitry Andric uint32_t oso_mod_time;
1476b1c73532SDimitry Andric if (dict->GetValueForKeyAsInteger("oso_mod_time", oso_mod_time))
1477b1c73532SDimitry Andric strm.Printf("0x%16.16" PRIx32 " ", oso_mod_time);
1478b1c73532SDimitry Andric
1479b1c73532SDimitry Andric llvm::StringRef error;
1480b1c73532SDimitry Andric if (dict->GetValueForKeyAsString("error", error))
1481b1c73532SDimitry Andric strm << "E " << error;
1482b1c73532SDimitry Andric else {
1483b1c73532SDimitry Andric llvm::StringRef oso_path;
1484b1c73532SDimitry Andric if (dict->GetValueForKeyAsString("oso_path", oso_path))
1485b1c73532SDimitry Andric strm << " " << oso_path;
1486b1c73532SDimitry Andric }
1487b1c73532SDimitry Andric strm.EOL();
1488b1c73532SDimitry Andric return true;
1489b1c73532SDimitry Andric });
1490b1c73532SDimitry Andric }
1491b1c73532SDimitry Andric
14924df029ccSDimitry Andric static void
DumpAddress(ExecutionContextScope * exe_scope,const Address & so_addr,bool verbose,bool all_ranges,Stream & strm,std::optional<Stream::HighlightSettings> settings=std::nullopt)14934df029ccSDimitry Andric DumpAddress(ExecutionContextScope *exe_scope, const Address &so_addr,
14944df029ccSDimitry Andric bool verbose, bool all_ranges, Stream &strm,
14954df029ccSDimitry Andric std::optional<Stream::HighlightSettings> settings = std::nullopt) {
1496f034231aSEd Maste strm.IndentMore();
1497f034231aSEd Maste strm.Indent(" Address: ");
1498f034231aSEd Maste so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
1499f034231aSEd Maste strm.PutCString(" (");
1500f034231aSEd Maste so_addr.Dump(&strm, exe_scope, Address::DumpStyleSectionNameOffset);
1501f034231aSEd Maste strm.PutCString(")\n");
1502f034231aSEd Maste strm.Indent(" Summary: ");
1503f034231aSEd Maste const uint32_t save_indent = strm.GetIndentLevel();
1504f034231aSEd Maste strm.SetIndentLevel(save_indent + 13);
1505b1c73532SDimitry Andric so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription,
15064df029ccSDimitry Andric Address::DumpStyleInvalid, UINT32_MAX, false, settings);
1507f034231aSEd Maste strm.SetIndentLevel(save_indent);
1508f034231aSEd Maste // Print out detailed address information when verbose is enabled
150914f1b3e8SDimitry Andric if (verbose) {
1510f034231aSEd Maste strm.EOL();
1511145449b1SDimitry Andric so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext,
15124df029ccSDimitry Andric Address::DumpStyleInvalid, UINT32_MAX, all_ranges, settings);
1513f034231aSEd Maste }
1514f034231aSEd Maste strm.IndentLess();
1515f034231aSEd Maste }
1516f034231aSEd Maste
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)151714f1b3e8SDimitry Andric static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm,
151814f1b3e8SDimitry Andric Module *module, uint32_t resolve_mask,
151914f1b3e8SDimitry Andric lldb::addr_t raw_addr, lldb::addr_t offset,
1520145449b1SDimitry Andric bool verbose, bool all_ranges) {
152114f1b3e8SDimitry Andric if (module) {
1522f034231aSEd Maste lldb::addr_t addr = raw_addr - offset;
1523f034231aSEd Maste Address so_addr;
1524f034231aSEd Maste SymbolContext sc;
1525f034231aSEd Maste Target *target = interpreter.GetExecutionContext().GetTargetPtr();
152614f1b3e8SDimitry Andric if (target && !target->GetSectionLoadList().IsEmpty()) {
1527f034231aSEd Maste if (!target->GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
1528f034231aSEd Maste return false;
1529f034231aSEd Maste else if (so_addr.GetModule().get() != module)
1530f034231aSEd Maste return false;
153114f1b3e8SDimitry Andric } else {
1532f034231aSEd Maste if (!module->ResolveFileAddress(addr, so_addr))
1533f034231aSEd Maste return false;
1534f034231aSEd Maste }
1535f034231aSEd Maste
153614f1b3e8SDimitry Andric ExecutionContextScope *exe_scope =
153714f1b3e8SDimitry Andric interpreter.GetExecutionContext().GetBestExecutionContextScope();
1538145449b1SDimitry Andric DumpAddress(exe_scope, so_addr, verbose, all_ranges, strm);
1539f034231aSEd Maste return true;
1540f034231aSEd Maste }
1541f034231aSEd Maste
1542f034231aSEd Maste return false;
1543f034231aSEd Maste }
1544f034231aSEd Maste
LookupSymbolInModule(CommandInterpreter & interpreter,Stream & strm,Module * module,const char * name,bool name_is_regex,bool verbose,bool all_ranges)154514f1b3e8SDimitry Andric static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
154614f1b3e8SDimitry Andric Stream &strm, Module *module,
154714f1b3e8SDimitry Andric const char *name, bool name_is_regex,
1548145449b1SDimitry Andric bool verbose, bool all_ranges) {
1549ead24645SDimitry Andric if (!module)
1550ead24645SDimitry Andric return 0;
1551f034231aSEd Maste
1552ead24645SDimitry Andric Symtab *symtab = module->GetSymtab();
1553ead24645SDimitry Andric if (!symtab)
1554ead24645SDimitry Andric return 0;
1555ead24645SDimitry Andric
1556ead24645SDimitry Andric SymbolContext sc;
1557b1c73532SDimitry Andric const bool use_color = interpreter.GetDebugger().GetUseColor();
1558f034231aSEd Maste std::vector<uint32_t> match_indexes;
1559f034231aSEd Maste ConstString symbol_name(name);
1560f034231aSEd Maste uint32_t num_matches = 0;
156114f1b3e8SDimitry Andric if (name_is_regex) {
156214f1b3e8SDimitry Andric RegularExpression name_regexp(symbol_name.GetStringRef());
156314f1b3e8SDimitry Andric num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType(
156414f1b3e8SDimitry Andric name_regexp, eSymbolTypeAny, match_indexes);
156514f1b3e8SDimitry Andric } else {
156614f1b3e8SDimitry Andric num_matches =
156714f1b3e8SDimitry Andric symtab->AppendSymbolIndexesWithName(symbol_name, match_indexes);
1568f034231aSEd Maste }
1569f034231aSEd Maste
157014f1b3e8SDimitry Andric if (num_matches > 0) {
1571f034231aSEd Maste strm.Indent();
1572f034231aSEd Maste strm.Printf("%u symbols match %s'%s' in ", num_matches,
1573f034231aSEd Maste name_is_regex ? "the regular expression " : "", name);
1574f034231aSEd Maste DumpFullpath(strm, &module->GetFileSpec(), 0);
1575f034231aSEd Maste strm.PutCString(":\n");
1576f034231aSEd Maste strm.IndentMore();
15774df029ccSDimitry Andric Stream::HighlightSettings settings(
15784df029ccSDimitry Andric name, interpreter.GetDebugger().GetRegexMatchAnsiPrefix(),
15794df029ccSDimitry Andric interpreter.GetDebugger().GetRegexMatchAnsiSuffix());
158014f1b3e8SDimitry Andric for (uint32_t i = 0; i < num_matches; ++i) {
1581f034231aSEd Maste Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
1582e3b55780SDimitry Andric if (symbol) {
1583e3b55780SDimitry Andric if (symbol->ValueIsAddress()) {
1584ead24645SDimitry Andric DumpAddress(
1585ead24645SDimitry Andric interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1586b1c73532SDimitry Andric symbol->GetAddressRef(), verbose, all_ranges, strm,
15874df029ccSDimitry Andric use_color && name_is_regex
15884df029ccSDimitry Andric ? std::optional<Stream::HighlightSettings>{settings}
15894df029ccSDimitry Andric : std::nullopt);
1590e3b55780SDimitry Andric strm.EOL();
1591e3b55780SDimitry Andric } else {
1592e3b55780SDimitry Andric strm.IndentMore();
1593e3b55780SDimitry Andric strm.Indent(" Name: ");
1594b1c73532SDimitry Andric strm.PutCStringColorHighlighted(
1595b1c73532SDimitry Andric symbol->GetDisplayName().GetStringRef(),
15964df029ccSDimitry Andric use_color && name_is_regex
15974df029ccSDimitry Andric ? std::optional<Stream::HighlightSettings>{settings}
15984df029ccSDimitry Andric : std::nullopt);
1599e3b55780SDimitry Andric strm.EOL();
1600e3b55780SDimitry Andric strm.Indent(" Value: ");
1601e3b55780SDimitry Andric strm.Printf("0x%16.16" PRIx64 "\n", symbol->GetRawValue());
1602e3b55780SDimitry Andric if (symbol->GetByteSizeIsValid()) {
1603e3b55780SDimitry Andric strm.Indent(" Size: ");
1604e3b55780SDimitry Andric strm.Printf("0x%16.16" PRIx64 "\n", symbol->GetByteSize());
1605e3b55780SDimitry Andric }
1606e3b55780SDimitry Andric strm.IndentLess();
1607e3b55780SDimitry Andric }
16085e95aa85SEd Maste }
1609f034231aSEd Maste }
1610f034231aSEd Maste strm.IndentLess();
1611ead24645SDimitry Andric }
1612f034231aSEd Maste return num_matches;
1613f034231aSEd Maste }
1614f034231aSEd Maste
DumpSymbolContextList(ExecutionContextScope * exe_scope,Stream & strm,const SymbolContextList & sc_list,bool verbose,bool all_ranges,std::optional<Stream::HighlightSettings> settings=std::nullopt)16154df029ccSDimitry Andric static void DumpSymbolContextList(
16164df029ccSDimitry Andric ExecutionContextScope *exe_scope, Stream &strm,
16174df029ccSDimitry Andric const SymbolContextList &sc_list, bool verbose, bool all_ranges,
16184df029ccSDimitry Andric std::optional<Stream::HighlightSettings> settings = std::nullopt) {
1619f034231aSEd Maste strm.IndentMore();
16207fa27ce4SDimitry Andric bool first_module = true;
16217fa27ce4SDimitry Andric for (const SymbolContext &sc : sc_list) {
16227fa27ce4SDimitry Andric if (!first_module)
16237fa27ce4SDimitry Andric strm.EOL();
1624f3fbd1c0SDimitry Andric
1625f034231aSEd Maste AddressRange range;
1626f034231aSEd Maste
162714f1b3e8SDimitry Andric sc.GetAddressRange(eSymbolContextEverything, 0, true, range);
1628f034231aSEd Maste
16294df029ccSDimitry Andric DumpAddress(exe_scope, range.GetBaseAddress(), verbose, all_ranges, strm,
16304df029ccSDimitry Andric settings);
16317fa27ce4SDimitry Andric first_module = false;
1632f034231aSEd Maste }
1633f034231aSEd Maste strm.IndentLess();
1634f034231aSEd Maste }
1635f034231aSEd Maste
LookupFunctionInModule(CommandInterpreter & interpreter,Stream & strm,Module * module,const char * name,bool name_is_regex,const ModuleFunctionSearchOptions & options,bool verbose,bool all_ranges)163614f1b3e8SDimitry Andric static size_t LookupFunctionInModule(CommandInterpreter &interpreter,
163714f1b3e8SDimitry Andric Stream &strm, Module *module,
163814f1b3e8SDimitry Andric const char *name, bool name_is_regex,
1639c0981da4SDimitry Andric const ModuleFunctionSearchOptions &options,
1640145449b1SDimitry Andric bool verbose, bool all_ranges) {
164114f1b3e8SDimitry Andric if (module && name && name[0]) {
1642f034231aSEd Maste SymbolContextList sc_list;
1643f034231aSEd Maste size_t num_matches = 0;
164414f1b3e8SDimitry Andric if (name_is_regex) {
164514f1b3e8SDimitry Andric RegularExpression function_name_regex((llvm::StringRef(name)));
1646c0981da4SDimitry Andric module->FindFunctions(function_name_regex, options, sc_list);
164714f1b3e8SDimitry Andric } else {
1648f034231aSEd Maste ConstString function_name(name);
1649cfca06d7SDimitry Andric module->FindFunctions(function_name, CompilerDeclContext(),
1650c0981da4SDimitry Andric eFunctionNameTypeAuto, options, sc_list);
1651f034231aSEd Maste }
1652ead24645SDimitry Andric num_matches = sc_list.GetSize();
165314f1b3e8SDimitry Andric if (num_matches) {
1654f034231aSEd Maste strm.Indent();
165514f1b3e8SDimitry Andric strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
165614f1b3e8SDimitry Andric num_matches > 1 ? "es" : "");
1657f034231aSEd Maste DumpFullpath(strm, &module->GetFileSpec(), 0);
1658f034231aSEd Maste strm.PutCString(":\n");
165914f1b3e8SDimitry Andric DumpSymbolContextList(
166014f1b3e8SDimitry Andric interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1661145449b1SDimitry Andric strm, sc_list, verbose, all_ranges);
1662f034231aSEd Maste }
1663f034231aSEd Maste return num_matches;
1664f034231aSEd Maste }
1665f034231aSEd Maste return 0;
1666f034231aSEd Maste }
1667f034231aSEd Maste
LookupTypeInModule(Target * target,CommandInterpreter & interpreter,Stream & strm,Module * module,const char * name_cstr,bool name_is_regex)1668b60736ecSDimitry Andric static size_t LookupTypeInModule(Target *target,
1669b60736ecSDimitry Andric CommandInterpreter &interpreter, Stream &strm,
167014f1b3e8SDimitry Andric Module *module, const char *name_cstr,
167114f1b3e8SDimitry Andric bool name_is_regex) {
1672ead24645SDimitry Andric if (module && name_cstr && name_cstr[0]) {
1673312c0ed1SDimitry Andric TypeQuery query(name_cstr);
1674312c0ed1SDimitry Andric TypeResults results;
1675312c0ed1SDimitry Andric module->FindTypes(query, results);
1676f034231aSEd Maste
1677312c0ed1SDimitry Andric TypeList type_list;
1678312c0ed1SDimitry Andric SymbolContext sc;
1679312c0ed1SDimitry Andric if (module)
1680312c0ed1SDimitry Andric sc.module_sp = module->shared_from_this();
1681312c0ed1SDimitry Andric // Sort the type results and put the results that matched in \a module
1682312c0ed1SDimitry Andric // first if \a module was specified.
1683312c0ed1SDimitry Andric sc.SortTypeList(results.GetTypeMap(), type_list);
1684ead24645SDimitry Andric if (type_list.Empty())
1685ead24645SDimitry Andric return 0;
1686ead24645SDimitry Andric
16876f8fc217SDimitry Andric const uint64_t num_matches = type_list.GetSize();
16886f8fc217SDimitry Andric
1689f034231aSEd Maste strm.Indent();
16906f8fc217SDimitry Andric strm.Printf("%" PRIu64 " match%s found in ", num_matches,
169114f1b3e8SDimitry Andric num_matches > 1 ? "es" : "");
1692f034231aSEd Maste DumpFullpath(strm, &module->GetFileSpec(), 0);
1693f034231aSEd Maste strm.PutCString(":\n");
169414f1b3e8SDimitry Andric for (TypeSP type_sp : type_list.Types()) {
1695ead24645SDimitry Andric if (!type_sp)
1696ead24645SDimitry Andric continue;
1697f73363f1SDimitry Andric // Resolve the clang type so that any forward references to types
1698f73363f1SDimitry Andric // that haven't yet been parsed will get parsed.
1699e81d9d49SDimitry Andric type_sp->GetFullCompilerType();
1700b60736ecSDimitry Andric type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target);
1701f034231aSEd Maste // Print all typedef chains
1702f034231aSEd Maste TypeSP typedef_type_sp(type_sp);
1703f034231aSEd Maste TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
170414f1b3e8SDimitry Andric while (typedefed_type_sp) {
1705f034231aSEd Maste strm.EOL();
170614f1b3e8SDimitry Andric strm.Printf(" typedef '%s': ",
170714f1b3e8SDimitry Andric typedef_type_sp->GetName().GetCString());
1708e81d9d49SDimitry Andric typedefed_type_sp->GetFullCompilerType();
1709b60736ecSDimitry Andric typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true,
1710b60736ecSDimitry Andric target);
1711f034231aSEd Maste typedef_type_sp = typedefed_type_sp;
1712f034231aSEd Maste typedefed_type_sp = typedef_type_sp->GetTypedefType();
1713f034231aSEd Maste }
1714f034231aSEd Maste strm.EOL();
1715f034231aSEd Maste }
1716ead24645SDimitry Andric return type_list.GetSize();
1717f034231aSEd Maste }
1718312c0ed1SDimitry Andric return 0;
1719312c0ed1SDimitry Andric }
1720f034231aSEd Maste
LookupTypeHere(Target * target,CommandInterpreter & interpreter,Stream & strm,Module & module,const char * name_cstr,bool name_is_regex)1721b60736ecSDimitry Andric static size_t LookupTypeHere(Target *target, CommandInterpreter &interpreter,
1722b60736ecSDimitry Andric Stream &strm, Module &module,
1723b60736ecSDimitry Andric const char *name_cstr, bool name_is_regex) {
1724312c0ed1SDimitry Andric TypeQuery query(name_cstr);
1725312c0ed1SDimitry Andric TypeResults results;
1726312c0ed1SDimitry Andric module.FindTypes(query, results);
1727f034231aSEd Maste TypeList type_list;
1728312c0ed1SDimitry Andric SymbolContext sc;
1729312c0ed1SDimitry Andric sc.module_sp = module.shared_from_this();
1730312c0ed1SDimitry Andric sc.SortTypeList(results.GetTypeMap(), type_list);
1731ead24645SDimitry Andric if (type_list.Empty())
1732ead24645SDimitry Andric return 0;
1733ead24645SDimitry Andric
1734f034231aSEd Maste strm.Indent();
1735f034231aSEd Maste strm.PutCString("Best match found in ");
173694994d37SDimitry Andric DumpFullpath(strm, &module.GetFileSpec(), 0);
1737f034231aSEd Maste strm.PutCString(":\n");
1738f034231aSEd Maste
1739f034231aSEd Maste TypeSP type_sp(type_list.GetTypeAtIndex(0));
174014f1b3e8SDimitry Andric if (type_sp) {
1741f73363f1SDimitry Andric // Resolve the clang type so that any forward references to types that
1742f73363f1SDimitry Andric // haven't yet been parsed will get parsed.
1743e81d9d49SDimitry Andric type_sp->GetFullCompilerType();
1744b60736ecSDimitry Andric type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target);
1745b60736ecSDimitry Andric // Print all typedef chains.
1746f034231aSEd Maste TypeSP typedef_type_sp(type_sp);
1747f034231aSEd Maste TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
174814f1b3e8SDimitry Andric while (typedefed_type_sp) {
1749f034231aSEd Maste strm.EOL();
175014f1b3e8SDimitry Andric strm.Printf(" typedef '%s': ",
175114f1b3e8SDimitry Andric typedef_type_sp->GetName().GetCString());
1752e81d9d49SDimitry Andric typedefed_type_sp->GetFullCompilerType();
1753b60736ecSDimitry Andric typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true,
1754b60736ecSDimitry Andric target);
1755f034231aSEd Maste typedef_type_sp = typedefed_type_sp;
1756f034231aSEd Maste typedefed_type_sp = typedef_type_sp->GetTypedefType();
1757f034231aSEd Maste }
1758f034231aSEd Maste }
1759f034231aSEd Maste strm.EOL();
1760ead24645SDimitry Andric return type_list.GetSize();
1761f034231aSEd Maste }
1762f034231aSEd Maste
LookupFileAndLineInModule(CommandInterpreter & interpreter,Stream & strm,Module * module,const FileSpec & file_spec,uint32_t line,bool check_inlines,bool verbose,bool all_ranges)176314f1b3e8SDimitry Andric static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter,
176414f1b3e8SDimitry Andric Stream &strm, Module *module,
1765f034231aSEd Maste const FileSpec &file_spec,
176614f1b3e8SDimitry Andric uint32_t line, bool check_inlines,
1767145449b1SDimitry Andric bool verbose, bool all_ranges) {
176814f1b3e8SDimitry Andric if (module && file_spec) {
1769f034231aSEd Maste SymbolContextList sc_list;
177014f1b3e8SDimitry Andric const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(
177114f1b3e8SDimitry Andric file_spec, line, check_inlines, eSymbolContextEverything, sc_list);
177214f1b3e8SDimitry Andric if (num_matches > 0) {
1773f034231aSEd Maste strm.Indent();
177414f1b3e8SDimitry Andric strm.Printf("%u match%s found in ", num_matches,
177514f1b3e8SDimitry Andric num_matches > 1 ? "es" : "");
1776f034231aSEd Maste strm << file_spec;
1777f034231aSEd Maste if (line > 0)
1778f034231aSEd Maste strm.Printf(":%u", line);
1779f034231aSEd Maste strm << " in ";
1780f034231aSEd Maste DumpFullpath(strm, &module->GetFileSpec(), 0);
1781f034231aSEd Maste strm.PutCString(":\n");
178214f1b3e8SDimitry Andric DumpSymbolContextList(
178314f1b3e8SDimitry Andric interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1784145449b1SDimitry Andric strm, sc_list, verbose, all_ranges);
1785f034231aSEd Maste return num_matches;
1786f034231aSEd Maste }
1787f034231aSEd Maste }
1788f034231aSEd Maste return 0;
1789f034231aSEd Maste }
1790f034231aSEd Maste
FindModulesByName(Target * target,const char * module_name,ModuleList & module_list,bool check_global_list)179114f1b3e8SDimitry Andric static size_t FindModulesByName(Target *target, const char *module_name,
1792f034231aSEd Maste ModuleList &module_list,
179314f1b3e8SDimitry Andric bool check_global_list) {
179494994d37SDimitry Andric FileSpec module_file_spec(module_name);
1795f034231aSEd Maste ModuleSpec module_spec(module_file_spec);
1796f034231aSEd Maste
1797f034231aSEd Maste const size_t initial_size = module_list.GetSize();
1798f034231aSEd Maste
179914f1b3e8SDimitry Andric if (check_global_list) {
1800f034231aSEd Maste // Check the global list
180114f1b3e8SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
180214f1b3e8SDimitry Andric Module::GetAllocationModuleCollectionMutex());
1803f034231aSEd Maste const size_t num_modules = Module::GetNumberAllocatedModules();
1804f034231aSEd Maste ModuleSP module_sp;
180514f1b3e8SDimitry Andric for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
1806f034231aSEd Maste Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
1807f034231aSEd Maste
180814f1b3e8SDimitry Andric if (module) {
180914f1b3e8SDimitry Andric if (module->MatchesModuleSpec(module_spec)) {
1810f034231aSEd Maste module_sp = module->shared_from_this();
1811f034231aSEd Maste module_list.AppendIfNeeded(module_sp);
1812f034231aSEd Maste }
1813f034231aSEd Maste }
1814f034231aSEd Maste }
181514f1b3e8SDimitry Andric } else {
181614f1b3e8SDimitry Andric if (target) {
181714f1b3e8SDimitry Andric target->GetImages().FindModules(module_spec, module_list);
1818ead24645SDimitry Andric const size_t num_matches = module_list.GetSize();
1819f034231aSEd Maste
1820f73363f1SDimitry Andric // Not found in our module list for our target, check the main shared
1821f73363f1SDimitry Andric // module list in case it is a extra file used somewhere else
182214f1b3e8SDimitry Andric if (num_matches == 0) {
1823f034231aSEd Maste module_spec.GetArchitecture() = target->GetArchitecture();
1824f034231aSEd Maste ModuleList::FindSharedModules(module_spec, module_list);
1825f034231aSEd Maste }
182614f1b3e8SDimitry Andric } else {
1827f034231aSEd Maste ModuleList::FindSharedModules(module_spec, module_list);
1828f034231aSEd Maste }
1829f034231aSEd Maste }
1830f034231aSEd Maste
1831f034231aSEd Maste return module_list.GetSize() - initial_size;
1832f034231aSEd Maste }
1833f034231aSEd Maste
1834f034231aSEd Maste #pragma mark CommandObjectTargetModulesModuleAutoComplete
1835f034231aSEd Maste
1836f034231aSEd Maste // A base command object class that can auto complete with module file
1837f034231aSEd Maste // paths
1838f034231aSEd Maste
183914f1b3e8SDimitry Andric class CommandObjectTargetModulesModuleAutoComplete
184014f1b3e8SDimitry Andric : public CommandObjectParsed {
1841f034231aSEd Maste public:
CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter & interpreter,const char * name,const char * help,const char * syntax,uint32_t flags=0)1842f034231aSEd Maste CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter &interpreter,
1843f034231aSEd Maste const char *name,
1844f034231aSEd Maste const char *help,
1845ead24645SDimitry Andric const char *syntax,
1846ead24645SDimitry Andric uint32_t flags = 0)
1847ead24645SDimitry Andric : CommandObjectParsed(interpreter, name, help, syntax, flags) {
1848ac9a064cSDimitry Andric AddSimpleArgumentList(eArgTypeFilename, eArgRepeatStar);
1849f034231aSEd Maste }
1850f034231aSEd Maste
1851f3fbd1c0SDimitry Andric ~CommandObjectTargetModulesModuleAutoComplete() override = default;
1852f034231aSEd Maste
1853ead24645SDimitry Andric void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)1854ead24645SDimitry Andric HandleArgumentCompletion(CompletionRequest &request,
1855f73363f1SDimitry Andric OptionElementVector &opt_element_vector) override {
18567fa27ce4SDimitry Andric lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
18577fa27ce4SDimitry Andric GetCommandInterpreter(), lldb::eModuleCompletion, request, nullptr);
1858f034231aSEd Maste }
1859f034231aSEd Maste };
1860f034231aSEd Maste
1861f034231aSEd Maste #pragma mark CommandObjectTargetModulesSourceFileAutoComplete
1862f034231aSEd Maste
1863f034231aSEd Maste // A base command object class that can auto complete with module source
1864f034231aSEd Maste // file paths
1865f034231aSEd Maste
186614f1b3e8SDimitry Andric class CommandObjectTargetModulesSourceFileAutoComplete
186714f1b3e8SDimitry Andric : public CommandObjectParsed {
1868f034231aSEd Maste public:
CommandObjectTargetModulesSourceFileAutoComplete(CommandInterpreter & interpreter,const char * name,const char * help,const char * syntax,uint32_t flags)186914f1b3e8SDimitry Andric CommandObjectTargetModulesSourceFileAutoComplete(
187014f1b3e8SDimitry Andric CommandInterpreter &interpreter, const char *name, const char *help,
187114f1b3e8SDimitry Andric const char *syntax, uint32_t flags)
187214f1b3e8SDimitry Andric : CommandObjectParsed(interpreter, name, help, syntax, flags) {
1873ac9a064cSDimitry Andric AddSimpleArgumentList(eArgTypeSourceFile, eArgRepeatPlus);
1874f034231aSEd Maste }
1875f034231aSEd Maste
1876f3fbd1c0SDimitry Andric ~CommandObjectTargetModulesSourceFileAutoComplete() override = default;
1877f034231aSEd Maste
1878ead24645SDimitry Andric void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)1879ead24645SDimitry Andric HandleArgumentCompletion(CompletionRequest &request,
1880f73363f1SDimitry Andric OptionElementVector &opt_element_vector) override {
18817fa27ce4SDimitry Andric lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
18827fa27ce4SDimitry Andric GetCommandInterpreter(), lldb::eSourceFileCompletion, request, nullptr);
1883f034231aSEd Maste }
1884f034231aSEd Maste };
1885f034231aSEd Maste
1886f3fbd1c0SDimitry Andric #pragma mark CommandObjectTargetModulesDumpObjfile
1887f3fbd1c0SDimitry Andric
188814f1b3e8SDimitry Andric class CommandObjectTargetModulesDumpObjfile
188914f1b3e8SDimitry Andric : public CommandObjectTargetModulesModuleAutoComplete {
1890f3fbd1c0SDimitry Andric public:
CommandObjectTargetModulesDumpObjfile(CommandInterpreter & interpreter)1891f3fbd1c0SDimitry Andric CommandObjectTargetModulesDumpObjfile(CommandInterpreter &interpreter)
189214f1b3e8SDimitry Andric : CommandObjectTargetModulesModuleAutoComplete(
189314f1b3e8SDimitry Andric interpreter, "target modules dump objfile",
1894f3fbd1c0SDimitry Andric "Dump the object file headers from one or more target modules.",
1895ead24645SDimitry Andric nullptr, eCommandRequiresTarget) {}
1896f3fbd1c0SDimitry Andric
1897f3fbd1c0SDimitry Andric ~CommandObjectTargetModulesDumpObjfile() override = default;
1898f3fbd1c0SDimitry Andric
1899f3fbd1c0SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)1900b1c73532SDimitry Andric void DoExecute(Args &command, CommandReturnObject &result) override {
1901ead24645SDimitry Andric Target *target = &GetSelectedTarget();
1902f3fbd1c0SDimitry Andric
1903f3fbd1c0SDimitry Andric uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1904f3fbd1c0SDimitry Andric result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1905f3fbd1c0SDimitry Andric result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1906f3fbd1c0SDimitry Andric
1907f3fbd1c0SDimitry Andric size_t num_dumped = 0;
190814f1b3e8SDimitry Andric if (command.GetArgumentCount() == 0) {
1909f3fbd1c0SDimitry Andric // Dump all headers for all modules images
191014f1b3e8SDimitry Andric num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(),
191114f1b3e8SDimitry Andric target->GetImages());
191214f1b3e8SDimitry Andric if (num_dumped == 0) {
1913f3fbd1c0SDimitry Andric result.AppendError("the target has no associated executable images");
1914f3fbd1c0SDimitry Andric }
191514f1b3e8SDimitry Andric } else {
1916f3fbd1c0SDimitry Andric // Find the modules that match the basename or full path.
1917f3fbd1c0SDimitry Andric ModuleList module_list;
1918f3fbd1c0SDimitry Andric const char *arg_cstr;
191914f1b3e8SDimitry Andric for (int arg_idx = 0;
192014f1b3e8SDimitry Andric (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
192114f1b3e8SDimitry Andric ++arg_idx) {
192214f1b3e8SDimitry Andric size_t num_matched =
192314f1b3e8SDimitry Andric FindModulesByName(target, arg_cstr, module_list, true);
192414f1b3e8SDimitry Andric if (num_matched == 0) {
192514f1b3e8SDimitry Andric result.AppendWarningWithFormat(
192614f1b3e8SDimitry Andric "Unable to find an image that matches '%s'.\n", arg_cstr);
1927f3fbd1c0SDimitry Andric }
1928f3fbd1c0SDimitry Andric }
1929f3fbd1c0SDimitry Andric // Dump all the modules we found.
193014f1b3e8SDimitry Andric num_dumped =
193114f1b3e8SDimitry Andric DumpModuleObjfileHeaders(result.GetOutputStream(), module_list);
1932f3fbd1c0SDimitry Andric }
1933f3fbd1c0SDimitry Andric
193414f1b3e8SDimitry Andric if (num_dumped > 0) {
1935f3fbd1c0SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
193614f1b3e8SDimitry Andric } else {
1937f3fbd1c0SDimitry Andric result.AppendError("no matching executable images found");
1938f3fbd1c0SDimitry Andric }
1939f3fbd1c0SDimitry Andric }
1940f3fbd1c0SDimitry Andric };
1941f034231aSEd Maste
19425f29bb8aSDimitry Andric #define LLDB_OPTIONS_target_modules_dump_symtab
19435f29bb8aSDimitry Andric #include "CommandOptions.inc"
194414f1b3e8SDimitry Andric
194514f1b3e8SDimitry Andric class CommandObjectTargetModulesDumpSymtab
194614f1b3e8SDimitry Andric : public CommandObjectTargetModulesModuleAutoComplete {
1947f034231aSEd Maste public:
CommandObjectTargetModulesDumpSymtab(CommandInterpreter & interpreter)194814f1b3e8SDimitry Andric CommandObjectTargetModulesDumpSymtab(CommandInterpreter &interpreter)
194914f1b3e8SDimitry Andric : CommandObjectTargetModulesModuleAutoComplete(
195014f1b3e8SDimitry Andric interpreter, "target modules dump symtab",
1951ead24645SDimitry Andric "Dump the symbol table from one or more target modules.", nullptr,
19526f8fc217SDimitry Andric eCommandRequiresTarget) {}
1953f034231aSEd Maste
1954f3fbd1c0SDimitry Andric ~CommandObjectTargetModulesDumpSymtab() override = default;
1955f034231aSEd Maste
GetOptions()195614f1b3e8SDimitry Andric Options *GetOptions() override { return &m_options; }
1957f034231aSEd Maste
195814f1b3e8SDimitry Andric class CommandOptions : public Options {
1959f034231aSEd Maste public:
1960145449b1SDimitry Andric CommandOptions() = default;
1961f034231aSEd Maste
1962f3fbd1c0SDimitry Andric ~CommandOptions() override = default;
1963f034231aSEd Maste
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)1964b76161e4SDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
196514f1b3e8SDimitry Andric ExecutionContext *execution_context) override {
1966b76161e4SDimitry Andric Status error;
1967f034231aSEd Maste const int short_option = m_getopt_table[option_idx].val;
1968f034231aSEd Maste
196914f1b3e8SDimitry Andric switch (short_option) {
1970706b4fc4SDimitry Andric case 'm':
1971706b4fc4SDimitry Andric m_prefer_mangled.SetCurrentValue(true);
1972706b4fc4SDimitry Andric m_prefer_mangled.SetOptionWasSet();
1973706b4fc4SDimitry Andric break;
1974706b4fc4SDimitry Andric
1975f034231aSEd Maste case 's':
1976f73363f1SDimitry Andric m_sort_order = (SortOrder)OptionArgParser::ToOptionEnum(
197714f1b3e8SDimitry Andric option_arg, GetDefinitions()[option_idx].enum_values,
197814f1b3e8SDimitry Andric eSortOrderNone, error);
1979f034231aSEd Maste break;
1980f034231aSEd Maste
1981f034231aSEd Maste default:
1982ead24645SDimitry Andric llvm_unreachable("Unimplemented option");
1983f034231aSEd Maste }
1984f034231aSEd Maste return error;
1985f034231aSEd Maste }
1986f034231aSEd Maste
OptionParsingStarting(ExecutionContext * execution_context)198714f1b3e8SDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override {
1988f034231aSEd Maste m_sort_order = eSortOrderNone;
1989706b4fc4SDimitry Andric m_prefer_mangled.Clear();
1990f034231aSEd Maste }
1991f034231aSEd Maste
GetDefinitions()199214f1b3e8SDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1993e3b55780SDimitry Andric return llvm::ArrayRef(g_target_modules_dump_symtab_options);
1994f034231aSEd Maste }
1995f034231aSEd Maste
1996344a3780SDimitry Andric SortOrder m_sort_order = eSortOrderNone;
1997706b4fc4SDimitry Andric OptionValueBoolean m_prefer_mangled = {false, false};
1998f034231aSEd Maste };
1999f034231aSEd Maste
2000f034231aSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)2001b1c73532SDimitry Andric void DoExecute(Args &command, CommandReturnObject &result) override {
2002ead24645SDimitry Andric Target *target = &GetSelectedTarget();
2003f034231aSEd Maste uint32_t num_dumped = 0;
2004706b4fc4SDimitry Andric Mangled::NamePreference name_preference =
2005706b4fc4SDimitry Andric (m_options.m_prefer_mangled ? Mangled::ePreferMangled
2006706b4fc4SDimitry Andric : Mangled::ePreferDemangled);
2007f034231aSEd Maste
2008f034231aSEd Maste uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2009f034231aSEd Maste result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2010f034231aSEd Maste result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2011f034231aSEd Maste
201214f1b3e8SDimitry Andric if (command.GetArgumentCount() == 0) {
2013f034231aSEd Maste // Dump all sections for all modules images
2014b60736ecSDimitry Andric const ModuleList &module_list = target->GetImages();
2015b60736ecSDimitry Andric std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
2016b60736ecSDimitry Andric const size_t num_modules = module_list.GetSize();
201714f1b3e8SDimitry Andric if (num_modules > 0) {
2018b60736ecSDimitry Andric result.GetOutputStream().Format(
2019b60736ecSDimitry Andric "Dumping symbol table for {0} modules.\n", num_modules);
2020b60736ecSDimitry Andric for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
202114f1b3e8SDimitry Andric if (num_dumped > 0) {
2022f034231aSEd Maste result.GetOutputStream().EOL();
2023f034231aSEd Maste result.GetOutputStream().EOL();
2024f034231aSEd Maste }
20257fa27ce4SDimitry Andric if (INTERRUPT_REQUESTED(GetDebugger(),
20267fa27ce4SDimitry Andric "Interrupted in dump all symtabs with {0} "
20277fa27ce4SDimitry Andric "of {1} dumped.", num_dumped, num_modules))
2028ef5d0b5eSDimitry Andric break;
20297fa27ce4SDimitry Andric
2030f034231aSEd Maste num_dumped++;
2031b60736ecSDimitry Andric DumpModuleSymtab(m_interpreter, result.GetOutputStream(),
2032b60736ecSDimitry Andric module_sp.get(), m_options.m_sort_order,
2033b60736ecSDimitry Andric name_preference);
2034f034231aSEd Maste }
203514f1b3e8SDimitry Andric } else {
2036f034231aSEd Maste result.AppendError("the target has no associated executable images");
2037b1c73532SDimitry Andric return;
2038f034231aSEd Maste }
203914f1b3e8SDimitry Andric } else {
2040f034231aSEd Maste // Dump specified images (by basename or fullpath)
2041f034231aSEd Maste const char *arg_cstr;
204214f1b3e8SDimitry Andric for (int arg_idx = 0;
204314f1b3e8SDimitry Andric (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
204414f1b3e8SDimitry Andric ++arg_idx) {
2045f034231aSEd Maste ModuleList module_list;
204614f1b3e8SDimitry Andric const size_t num_matches =
204714f1b3e8SDimitry Andric FindModulesByName(target, arg_cstr, module_list, true);
204814f1b3e8SDimitry Andric if (num_matches > 0) {
2049b60736ecSDimitry Andric for (ModuleSP module_sp : module_list.Modules()) {
2050b60736ecSDimitry Andric if (module_sp) {
205114f1b3e8SDimitry Andric if (num_dumped > 0) {
2052f034231aSEd Maste result.GetOutputStream().EOL();
2053f034231aSEd Maste result.GetOutputStream().EOL();
2054f034231aSEd Maste }
20557fa27ce4SDimitry Andric if (INTERRUPT_REQUESTED(GetDebugger(),
20567fa27ce4SDimitry Andric "Interrupted in dump symtab list with {0} of {1} dumped.",
20577fa27ce4SDimitry Andric num_dumped, num_matches))
2058ef5d0b5eSDimitry Andric break;
20597fa27ce4SDimitry Andric
2060f034231aSEd Maste num_dumped++;
2061b60736ecSDimitry Andric DumpModuleSymtab(m_interpreter, result.GetOutputStream(),
2062b60736ecSDimitry Andric module_sp.get(), m_options.m_sort_order,
2063b60736ecSDimitry Andric name_preference);
2064f034231aSEd Maste }
2065f034231aSEd Maste }
206614f1b3e8SDimitry Andric } else
206714f1b3e8SDimitry Andric result.AppendWarningWithFormat(
206814f1b3e8SDimitry Andric "Unable to find an image that matches '%s'.\n", arg_cstr);
2069f034231aSEd Maste }
2070f034231aSEd Maste }
2071f034231aSEd Maste
2072f034231aSEd Maste if (num_dumped > 0)
2073f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
207414f1b3e8SDimitry Andric else {
2075f034231aSEd Maste result.AppendError("no matching executable images found");
2076f034231aSEd Maste }
2077f034231aSEd Maste }
2078f034231aSEd Maste
2079f034231aSEd Maste CommandOptions m_options;
2080f034231aSEd Maste };
2081f034231aSEd Maste
2082f034231aSEd Maste #pragma mark CommandObjectTargetModulesDumpSections
2083f034231aSEd Maste
2084f034231aSEd Maste // Image section dumping command
2085f034231aSEd Maste
208614f1b3e8SDimitry Andric class CommandObjectTargetModulesDumpSections
208714f1b3e8SDimitry Andric : public CommandObjectTargetModulesModuleAutoComplete {
2088f034231aSEd Maste public:
CommandObjectTargetModulesDumpSections(CommandInterpreter & interpreter)208914f1b3e8SDimitry Andric CommandObjectTargetModulesDumpSections(CommandInterpreter &interpreter)
209014f1b3e8SDimitry Andric : CommandObjectTargetModulesModuleAutoComplete(
209114f1b3e8SDimitry Andric interpreter, "target modules dump sections",
2092f034231aSEd Maste "Dump the sections from one or more target modules.",
2093f034231aSEd Maste //"target modules dump sections [<file1> ...]")
2094ead24645SDimitry Andric nullptr, eCommandRequiresTarget) {}
2095f034231aSEd Maste
2096f3fbd1c0SDimitry Andric ~CommandObjectTargetModulesDumpSections() override = default;
2097f034231aSEd Maste
2098f034231aSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)2099b1c73532SDimitry Andric void DoExecute(Args &command, CommandReturnObject &result) override {
2100ead24645SDimitry Andric Target *target = &GetSelectedTarget();
2101f034231aSEd Maste uint32_t num_dumped = 0;
2102f034231aSEd Maste
2103f034231aSEd Maste uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2104f034231aSEd Maste result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2105f034231aSEd Maste result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2106f034231aSEd Maste
210714f1b3e8SDimitry Andric if (command.GetArgumentCount() == 0) {
2108f034231aSEd Maste // Dump all sections for all modules images
2109f034231aSEd Maste const size_t num_modules = target->GetImages().GetSize();
2110b60736ecSDimitry Andric if (num_modules == 0) {
2111b60736ecSDimitry Andric result.AppendError("the target has no associated executable images");
2112b1c73532SDimitry Andric return;
2113b60736ecSDimitry Andric }
2114b60736ecSDimitry Andric
2115b60736ecSDimitry Andric result.GetOutputStream().Format("Dumping sections for {0} modules.\n",
2116b60736ecSDimitry Andric num_modules);
211714f1b3e8SDimitry Andric for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
21187fa27ce4SDimitry Andric if (INTERRUPT_REQUESTED(GetDebugger(),
21197fa27ce4SDimitry Andric "Interrupted in dump all sections with {0} of {1} dumped",
21207fa27ce4SDimitry Andric image_idx, num_modules))
2121ef5d0b5eSDimitry Andric break;
21227fa27ce4SDimitry Andric
2123f034231aSEd Maste num_dumped++;
212414f1b3e8SDimitry Andric DumpModuleSections(
212514f1b3e8SDimitry Andric m_interpreter, result.GetOutputStream(),
212614f1b3e8SDimitry Andric target->GetImages().GetModulePointerAtIndex(image_idx));
2127f034231aSEd Maste }
212814f1b3e8SDimitry Andric } else {
2129f034231aSEd Maste // Dump specified images (by basename or fullpath)
2130f034231aSEd Maste const char *arg_cstr;
213114f1b3e8SDimitry Andric for (int arg_idx = 0;
213214f1b3e8SDimitry Andric (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
213314f1b3e8SDimitry Andric ++arg_idx) {
2134f034231aSEd Maste ModuleList module_list;
213514f1b3e8SDimitry Andric const size_t num_matches =
213614f1b3e8SDimitry Andric FindModulesByName(target, arg_cstr, module_list, true);
213714f1b3e8SDimitry Andric if (num_matches > 0) {
213814f1b3e8SDimitry Andric for (size_t i = 0; i < num_matches; ++i) {
21397fa27ce4SDimitry Andric if (INTERRUPT_REQUESTED(GetDebugger(),
21407fa27ce4SDimitry Andric "Interrupted in dump section list with {0} of {1} dumped.",
21417fa27ce4SDimitry Andric i, num_matches))
2142ef5d0b5eSDimitry Andric break;
21437fa27ce4SDimitry Andric
2144f034231aSEd Maste Module *module = module_list.GetModulePointerAtIndex(i);
214514f1b3e8SDimitry Andric if (module) {
2146f034231aSEd Maste num_dumped++;
214714f1b3e8SDimitry Andric DumpModuleSections(m_interpreter, result.GetOutputStream(),
214814f1b3e8SDimitry Andric module);
2149f034231aSEd Maste }
2150f034231aSEd Maste }
215114f1b3e8SDimitry Andric } else {
2152f034231aSEd Maste // Check the global list
215314f1b3e8SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
215414f1b3e8SDimitry Andric Module::GetAllocationModuleCollectionMutex());
2155f034231aSEd Maste
215614f1b3e8SDimitry Andric result.AppendWarningWithFormat(
215714f1b3e8SDimitry Andric "Unable to find an image that matches '%s'.\n", arg_cstr);
2158f034231aSEd Maste }
2159f034231aSEd Maste }
2160f034231aSEd Maste }
2161f034231aSEd Maste
2162f034231aSEd Maste if (num_dumped > 0)
2163f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
216414f1b3e8SDimitry Andric else {
2165f034231aSEd Maste result.AppendError("no matching executable images found");
2166f034231aSEd Maste }
2167f034231aSEd Maste }
2168f034231aSEd Maste };
2169f034231aSEd Maste
21701f917f69SDimitry Andric class CommandObjectTargetModulesDumpClangPCMInfo : public CommandObjectParsed {
21711f917f69SDimitry Andric public:
CommandObjectTargetModulesDumpClangPCMInfo(CommandInterpreter & interpreter)21721f917f69SDimitry Andric CommandObjectTargetModulesDumpClangPCMInfo(CommandInterpreter &interpreter)
21731f917f69SDimitry Andric : CommandObjectParsed(
21741f917f69SDimitry Andric interpreter, "target modules dump pcm-info",
21751f917f69SDimitry Andric "Dump information about the given clang module (pcm).") {
21761f917f69SDimitry Andric // Take a single file argument.
2177ac9a064cSDimitry Andric AddSimpleArgumentList(eArgTypeFilename);
21781f917f69SDimitry Andric }
21791f917f69SDimitry Andric
21801f917f69SDimitry Andric ~CommandObjectTargetModulesDumpClangPCMInfo() override = default;
21811f917f69SDimitry Andric
21821f917f69SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)2183b1c73532SDimitry Andric void DoExecute(Args &command, CommandReturnObject &result) override {
21841f917f69SDimitry Andric if (command.GetArgumentCount() != 1) {
21851f917f69SDimitry Andric result.AppendErrorWithFormat("'%s' takes exactly one pcm path argument.",
21861f917f69SDimitry Andric m_cmd_name.c_str());
2187b1c73532SDimitry Andric return;
21881f917f69SDimitry Andric }
21891f917f69SDimitry Andric
21901f917f69SDimitry Andric const char *pcm_path = command.GetArgumentAtIndex(0);
21917fa27ce4SDimitry Andric const FileSpec pcm_file{pcm_path};
21921f917f69SDimitry Andric
21937fa27ce4SDimitry Andric if (pcm_file.GetFileNameExtension() != ".pcm") {
21941f917f69SDimitry Andric result.AppendError("file must have a .pcm extension");
2195b1c73532SDimitry Andric return;
21961f917f69SDimitry Andric }
21971f917f69SDimitry Andric
21981f917f69SDimitry Andric if (!FileSystem::Instance().Exists(pcm_file)) {
21991f917f69SDimitry Andric result.AppendError("pcm file does not exist");
2200b1c73532SDimitry Andric return;
22011f917f69SDimitry Andric }
22021f917f69SDimitry Andric
22031f917f69SDimitry Andric clang::CompilerInstance compiler;
22041f917f69SDimitry Andric compiler.createDiagnostics();
22051f917f69SDimitry Andric
22061f917f69SDimitry Andric const char *clang_args[] = {"clang", pcm_path};
22071f917f69SDimitry Andric compiler.setInvocation(clang::createInvocation(clang_args));
22081f917f69SDimitry Andric
22097fa27ce4SDimitry Andric // Pass empty deleter to not attempt to free memory that was allocated
22107fa27ce4SDimitry Andric // outside of the current scope, possibly statically.
22117fa27ce4SDimitry Andric std::shared_ptr<llvm::raw_ostream> Out(
22127fa27ce4SDimitry Andric &result.GetOutputStream().AsRawOstream(), [](llvm::raw_ostream *) {});
22137fa27ce4SDimitry Andric clang::DumpModuleInfoAction dump_module_info(Out);
22141f917f69SDimitry Andric // DumpModuleInfoAction requires ObjectFilePCHContainerReader.
22151f917f69SDimitry Andric compiler.getPCHContainerOperations()->registerReader(
22161f917f69SDimitry Andric std::make_unique<clang::ObjectFilePCHContainerReader>());
22171f917f69SDimitry Andric
22181f917f69SDimitry Andric if (compiler.ExecuteAction(dump_module_info))
22191f917f69SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
22201f917f69SDimitry Andric }
22211f917f69SDimitry Andric };
22221f917f69SDimitry Andric
2223cfca06d7SDimitry Andric #pragma mark CommandObjectTargetModulesDumpClangAST
222494994d37SDimitry Andric
222594994d37SDimitry Andric // Clang AST dumping command
222694994d37SDimitry Andric
222794994d37SDimitry Andric class CommandObjectTargetModulesDumpClangAST
222894994d37SDimitry Andric : public CommandObjectTargetModulesModuleAutoComplete {
222994994d37SDimitry Andric public:
CommandObjectTargetModulesDumpClangAST(CommandInterpreter & interpreter)223094994d37SDimitry Andric CommandObjectTargetModulesDumpClangAST(CommandInterpreter &interpreter)
223194994d37SDimitry Andric : CommandObjectTargetModulesModuleAutoComplete(
223294994d37SDimitry Andric interpreter, "target modules dump ast",
223394994d37SDimitry Andric "Dump the clang ast for a given module's symbol file.",
223494994d37SDimitry Andric //"target modules dump ast [<file1> ...]")
2235ead24645SDimitry Andric nullptr, eCommandRequiresTarget) {}
223694994d37SDimitry Andric
223794994d37SDimitry Andric ~CommandObjectTargetModulesDumpClangAST() override = default;
223894994d37SDimitry Andric
223994994d37SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)2240b1c73532SDimitry Andric void DoExecute(Args &command, CommandReturnObject &result) override {
2241ead24645SDimitry Andric Target *target = &GetSelectedTarget();
224294994d37SDimitry Andric
2243b60736ecSDimitry Andric const ModuleList &module_list = target->GetImages();
2244b60736ecSDimitry Andric const size_t num_modules = module_list.GetSize();
224594994d37SDimitry Andric if (num_modules == 0) {
224694994d37SDimitry Andric result.AppendError("the target has no associated executable images");
2247b1c73532SDimitry Andric return;
224894994d37SDimitry Andric }
224994994d37SDimitry Andric
225094994d37SDimitry Andric if (command.GetArgumentCount() == 0) {
225194994d37SDimitry Andric // Dump all ASTs for all modules images
2252b60736ecSDimitry Andric result.GetOutputStream().Format("Dumping clang ast for {0} modules.\n",
2253b60736ecSDimitry Andric num_modules);
2254b60736ecSDimitry Andric for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
22557fa27ce4SDimitry Andric if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted dumping clang ast"))
225694994d37SDimitry Andric break;
2257b60736ecSDimitry Andric if (SymbolFile *sf = module_sp->GetSymbolFile())
225894994d37SDimitry Andric sf->DumpClangAST(result.GetOutputStream());
225994994d37SDimitry Andric }
226094994d37SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
2261b1c73532SDimitry Andric return;
226294994d37SDimitry Andric }
226394994d37SDimitry Andric
226494994d37SDimitry Andric // Dump specified ASTs (by basename or fullpath)
226594994d37SDimitry Andric for (const Args::ArgEntry &arg : command.entries()) {
226694994d37SDimitry Andric ModuleList module_list;
226794994d37SDimitry Andric const size_t num_matches =
226894994d37SDimitry Andric FindModulesByName(target, arg.c_str(), module_list, true);
226994994d37SDimitry Andric if (num_matches == 0) {
227094994d37SDimitry Andric // Check the global list
227194994d37SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
227294994d37SDimitry Andric Module::GetAllocationModuleCollectionMutex());
227394994d37SDimitry Andric
227494994d37SDimitry Andric result.AppendWarningWithFormat(
227594994d37SDimitry Andric "Unable to find an image that matches '%s'.\n", arg.c_str());
227694994d37SDimitry Andric continue;
227794994d37SDimitry Andric }
227894994d37SDimitry Andric
227994994d37SDimitry Andric for (size_t i = 0; i < num_matches; ++i) {
22807fa27ce4SDimitry Andric if (INTERRUPT_REQUESTED(GetDebugger(),
22817fa27ce4SDimitry Andric "Interrupted in dump clang ast list with {0} of {1} dumped.",
22827fa27ce4SDimitry Andric i, num_matches))
228394994d37SDimitry Andric break;
22847fa27ce4SDimitry Andric
228594994d37SDimitry Andric Module *m = module_list.GetModulePointerAtIndex(i);
2286ead24645SDimitry Andric if (SymbolFile *sf = m->GetSymbolFile())
228794994d37SDimitry Andric sf->DumpClangAST(result.GetOutputStream());
228894994d37SDimitry Andric }
228994994d37SDimitry Andric }
229094994d37SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
229194994d37SDimitry Andric }
229294994d37SDimitry Andric };
229394994d37SDimitry Andric
2294f034231aSEd Maste #pragma mark CommandObjectTargetModulesDumpSymfile
2295f034231aSEd Maste
2296f034231aSEd Maste // Image debug symbol dumping command
2297f034231aSEd Maste
229814f1b3e8SDimitry Andric class CommandObjectTargetModulesDumpSymfile
229914f1b3e8SDimitry Andric : public CommandObjectTargetModulesModuleAutoComplete {
2300f034231aSEd Maste public:
CommandObjectTargetModulesDumpSymfile(CommandInterpreter & interpreter)230114f1b3e8SDimitry Andric CommandObjectTargetModulesDumpSymfile(CommandInterpreter &interpreter)
230214f1b3e8SDimitry Andric : CommandObjectTargetModulesModuleAutoComplete(
230314f1b3e8SDimitry Andric interpreter, "target modules dump symfile",
2304f034231aSEd Maste "Dump the debug symbol file for one or more target modules.",
2305f034231aSEd Maste //"target modules dump symfile [<file1> ...]")
2306ead24645SDimitry Andric nullptr, eCommandRequiresTarget) {}
2307f034231aSEd Maste
2308f3fbd1c0SDimitry Andric ~CommandObjectTargetModulesDumpSymfile() override = default;
2309f034231aSEd Maste
2310f034231aSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)2311b1c73532SDimitry Andric void DoExecute(Args &command, CommandReturnObject &result) override {
2312ead24645SDimitry Andric Target *target = &GetSelectedTarget();
2313f034231aSEd Maste uint32_t num_dumped = 0;
2314f034231aSEd Maste
2315f034231aSEd Maste uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2316f034231aSEd Maste result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2317f034231aSEd Maste result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2318f034231aSEd Maste
231914f1b3e8SDimitry Andric if (command.GetArgumentCount() == 0) {
2320f034231aSEd Maste // Dump all sections for all modules images
2321f034231aSEd Maste const ModuleList &target_modules = target->GetImages();
2322f3fbd1c0SDimitry Andric std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2323f034231aSEd Maste const size_t num_modules = target_modules.GetSize();
2324b60736ecSDimitry Andric if (num_modules == 0) {
2325f034231aSEd Maste result.AppendError("the target has no associated executable images");
2326b1c73532SDimitry Andric return;
2327f034231aSEd Maste }
2328b60736ecSDimitry Andric result.GetOutputStream().Format(
2329b60736ecSDimitry Andric "Dumping debug symbols for {0} modules.\n", num_modules);
2330b60736ecSDimitry Andric for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
23317fa27ce4SDimitry Andric if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted in dumping all "
23327fa27ce4SDimitry Andric "debug symbols with {0} of {1} modules dumped",
23337fa27ce4SDimitry Andric num_dumped, num_modules))
2334b60736ecSDimitry Andric break;
23357fa27ce4SDimitry Andric
2336b60736ecSDimitry Andric if (DumpModuleSymbolFile(result.GetOutputStream(), module_sp.get()))
2337b60736ecSDimitry Andric num_dumped++;
2338b60736ecSDimitry Andric }
233914f1b3e8SDimitry Andric } else {
2340f034231aSEd Maste // Dump specified images (by basename or fullpath)
2341f034231aSEd Maste const char *arg_cstr;
234214f1b3e8SDimitry Andric for (int arg_idx = 0;
234314f1b3e8SDimitry Andric (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
234414f1b3e8SDimitry Andric ++arg_idx) {
2345f034231aSEd Maste ModuleList module_list;
234614f1b3e8SDimitry Andric const size_t num_matches =
234714f1b3e8SDimitry Andric FindModulesByName(target, arg_cstr, module_list, true);
234814f1b3e8SDimitry Andric if (num_matches > 0) {
234914f1b3e8SDimitry Andric for (size_t i = 0; i < num_matches; ++i) {
23507fa27ce4SDimitry Andric if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted dumping {0} "
23517fa27ce4SDimitry Andric "of {1} requested modules",
23527fa27ce4SDimitry Andric i, num_matches))
2353ef5d0b5eSDimitry Andric break;
2354f034231aSEd Maste Module *module = module_list.GetModulePointerAtIndex(i);
235514f1b3e8SDimitry Andric if (module) {
2356ead24645SDimitry Andric if (DumpModuleSymbolFile(result.GetOutputStream(), module))
2357f034231aSEd Maste num_dumped++;
2358f034231aSEd Maste }
2359f034231aSEd Maste }
236014f1b3e8SDimitry Andric } else
236114f1b3e8SDimitry Andric result.AppendWarningWithFormat(
236214f1b3e8SDimitry Andric "Unable to find an image that matches '%s'.\n", arg_cstr);
2363f034231aSEd Maste }
2364f034231aSEd Maste }
2365f034231aSEd Maste
2366f034231aSEd Maste if (num_dumped > 0)
2367f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
236814f1b3e8SDimitry Andric else {
2369f034231aSEd Maste result.AppendError("no matching executable images found");
2370f034231aSEd Maste }
2371f034231aSEd Maste }
2372f034231aSEd Maste };
2373f034231aSEd Maste
2374f034231aSEd Maste #pragma mark CommandObjectTargetModulesDumpLineTable
2375ead24645SDimitry Andric #define LLDB_OPTIONS_target_modules_dump
2376ead24645SDimitry Andric #include "CommandOptions.inc"
2377f034231aSEd Maste
2378f034231aSEd Maste // Image debug line table dumping command
2379f034231aSEd Maste
238014f1b3e8SDimitry Andric class CommandObjectTargetModulesDumpLineTable
238114f1b3e8SDimitry Andric : public CommandObjectTargetModulesSourceFileAutoComplete {
2382f034231aSEd Maste public:
CommandObjectTargetModulesDumpLineTable(CommandInterpreter & interpreter)238314f1b3e8SDimitry Andric CommandObjectTargetModulesDumpLineTable(CommandInterpreter &interpreter)
238414f1b3e8SDimitry Andric : CommandObjectTargetModulesSourceFileAutoComplete(
238514f1b3e8SDimitry Andric interpreter, "target modules dump line-table",
238614f1b3e8SDimitry Andric "Dump the line table for one or more compilation units.", nullptr,
238714f1b3e8SDimitry Andric eCommandRequiresTarget) {}
2388f034231aSEd Maste
2389f3fbd1c0SDimitry Andric ~CommandObjectTargetModulesDumpLineTable() override = default;
2390f034231aSEd Maste
GetOptions()23915f29bb8aSDimitry Andric Options *GetOptions() override { return &m_options; }
23925f29bb8aSDimitry Andric
2393f034231aSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)2394b1c73532SDimitry Andric void DoExecute(Args &command, CommandReturnObject &result) override {
2395f034231aSEd Maste Target *target = m_exe_ctx.GetTargetPtr();
2396f034231aSEd Maste uint32_t total_num_dumped = 0;
2397f034231aSEd Maste
2398f034231aSEd Maste uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2399f034231aSEd Maste result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2400f034231aSEd Maste result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2401f034231aSEd Maste
240214f1b3e8SDimitry Andric if (command.GetArgumentCount() == 0) {
24039e6d3549SDimitry Andric result.AppendError("file option must be specified.");
2404b1c73532SDimitry Andric return;
240514f1b3e8SDimitry Andric } else {
2406f034231aSEd Maste // Dump specified images (by basename or fullpath)
2407f034231aSEd Maste const char *arg_cstr;
240814f1b3e8SDimitry Andric for (int arg_idx = 0;
240914f1b3e8SDimitry Andric (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
241014f1b3e8SDimitry Andric ++arg_idx) {
241194994d37SDimitry Andric FileSpec file_spec(arg_cstr);
2412f034231aSEd Maste
2413f034231aSEd Maste const ModuleList &target_modules = target->GetImages();
2414f3fbd1c0SDimitry Andric std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
24157fa27ce4SDimitry Andric size_t num_modules = target_modules.GetSize();
24167fa27ce4SDimitry Andric if (num_modules > 0) {
2417f034231aSEd Maste uint32_t num_dumped = 0;
2418b60736ecSDimitry Andric for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
24197fa27ce4SDimitry Andric if (INTERRUPT_REQUESTED(GetDebugger(),
24207fa27ce4SDimitry Andric "Interrupted in dump all line tables with "
24217fa27ce4SDimitry Andric "{0} of {1} dumped", num_dumped,
24227fa27ce4SDimitry Andric num_modules))
2423ef5d0b5eSDimitry Andric break;
24247fa27ce4SDimitry Andric
242514f1b3e8SDimitry Andric if (DumpCompileUnitLineTable(
2426b60736ecSDimitry Andric m_interpreter, result.GetOutputStream(), module_sp.get(),
24275f29bb8aSDimitry Andric file_spec,
24285f29bb8aSDimitry Andric m_options.m_verbose ? eDescriptionLevelFull
24295f29bb8aSDimitry Andric : eDescriptionLevelBrief))
2430f034231aSEd Maste num_dumped++;
2431f034231aSEd Maste }
2432f034231aSEd Maste if (num_dumped == 0)
243314f1b3e8SDimitry Andric result.AppendWarningWithFormat(
243414f1b3e8SDimitry Andric "No source filenames matched '%s'.\n", arg_cstr);
2435f034231aSEd Maste else
2436f034231aSEd Maste total_num_dumped += num_dumped;
2437f034231aSEd Maste }
2438f034231aSEd Maste }
2439f034231aSEd Maste }
2440f034231aSEd Maste
2441f034231aSEd Maste if (total_num_dumped > 0)
2442f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
244314f1b3e8SDimitry Andric else {
2444f034231aSEd Maste result.AppendError("no source filenames matched any command arguments");
2445f034231aSEd Maste }
2446f034231aSEd Maste }
24475f29bb8aSDimitry Andric
24485f29bb8aSDimitry Andric class CommandOptions : public Options {
24495f29bb8aSDimitry Andric public:
CommandOptions()24506f8fc217SDimitry Andric CommandOptions() { OptionParsingStarting(nullptr); }
24515f29bb8aSDimitry Andric
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)24525f29bb8aSDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
24535f29bb8aSDimitry Andric ExecutionContext *execution_context) override {
24545f29bb8aSDimitry Andric assert(option_idx == 0 && "We only have one option.");
24555f29bb8aSDimitry Andric m_verbose = true;
24565f29bb8aSDimitry Andric
24575f29bb8aSDimitry Andric return Status();
24585f29bb8aSDimitry Andric }
24595f29bb8aSDimitry Andric
OptionParsingStarting(ExecutionContext * execution_context)24605f29bb8aSDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override {
24615f29bb8aSDimitry Andric m_verbose = false;
24625f29bb8aSDimitry Andric }
24635f29bb8aSDimitry Andric
GetDefinitions()24645f29bb8aSDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2465e3b55780SDimitry Andric return llvm::ArrayRef(g_target_modules_dump_options);
24665f29bb8aSDimitry Andric }
24675f29bb8aSDimitry Andric
24685f29bb8aSDimitry Andric bool m_verbose;
24695f29bb8aSDimitry Andric };
24705f29bb8aSDimitry Andric
24715f29bb8aSDimitry Andric CommandOptions m_options;
2472f034231aSEd Maste };
2473f034231aSEd Maste
2474b1c73532SDimitry Andric #pragma mark CommandObjectTargetModulesDumpSeparateDebugInfoFiles
2475b1c73532SDimitry Andric #define LLDB_OPTIONS_target_modules_dump_separate_debug_info
2476b1c73532SDimitry Andric #include "CommandOptions.inc"
2477b1c73532SDimitry Andric
2478b1c73532SDimitry Andric // Image debug separate debug info dumping command
2479b1c73532SDimitry Andric
2480b1c73532SDimitry Andric class CommandObjectTargetModulesDumpSeparateDebugInfoFiles
2481b1c73532SDimitry Andric : public CommandObjectTargetModulesModuleAutoComplete {
2482b1c73532SDimitry Andric public:
CommandObjectTargetModulesDumpSeparateDebugInfoFiles(CommandInterpreter & interpreter)2483b1c73532SDimitry Andric CommandObjectTargetModulesDumpSeparateDebugInfoFiles(
2484b1c73532SDimitry Andric CommandInterpreter &interpreter)
2485b1c73532SDimitry Andric : CommandObjectTargetModulesModuleAutoComplete(
2486b1c73532SDimitry Andric interpreter, "target modules dump separate-debug-info",
2487b1c73532SDimitry Andric "List the separate debug info symbol files for one or more target "
2488b1c73532SDimitry Andric "modules.",
2489b1c73532SDimitry Andric nullptr, eCommandRequiresTarget) {}
2490b1c73532SDimitry Andric
2491b1c73532SDimitry Andric ~CommandObjectTargetModulesDumpSeparateDebugInfoFiles() override = default;
2492b1c73532SDimitry Andric
GetOptions()2493b1c73532SDimitry Andric Options *GetOptions() override { return &m_options; }
2494b1c73532SDimitry Andric
2495b1c73532SDimitry Andric class CommandOptions : public Options {
2496b1c73532SDimitry Andric public:
2497b1c73532SDimitry Andric CommandOptions() = default;
2498b1c73532SDimitry Andric
2499b1c73532SDimitry Andric ~CommandOptions() override = default;
2500b1c73532SDimitry Andric
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)2501b1c73532SDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2502b1c73532SDimitry Andric ExecutionContext *execution_context) override {
2503b1c73532SDimitry Andric Status error;
2504b1c73532SDimitry Andric const int short_option = m_getopt_table[option_idx].val;
2505b1c73532SDimitry Andric
2506b1c73532SDimitry Andric switch (short_option) {
2507b1c73532SDimitry Andric case 'j':
2508b1c73532SDimitry Andric m_json.SetCurrentValue(true);
2509b1c73532SDimitry Andric m_json.SetOptionWasSet();
2510b1c73532SDimitry Andric break;
2511b1c73532SDimitry Andric case 'e':
2512b1c73532SDimitry Andric m_errors_only.SetCurrentValue(true);
2513b1c73532SDimitry Andric m_errors_only.SetOptionWasSet();
2514b1c73532SDimitry Andric break;
2515b1c73532SDimitry Andric default:
2516b1c73532SDimitry Andric llvm_unreachable("Unimplemented option");
2517b1c73532SDimitry Andric }
2518b1c73532SDimitry Andric return error;
2519b1c73532SDimitry Andric }
2520b1c73532SDimitry Andric
OptionParsingStarting(ExecutionContext * execution_context)2521b1c73532SDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override {
2522b1c73532SDimitry Andric m_json.Clear();
2523b1c73532SDimitry Andric m_errors_only.Clear();
2524b1c73532SDimitry Andric }
2525b1c73532SDimitry Andric
GetDefinitions()2526b1c73532SDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2527b1c73532SDimitry Andric return llvm::ArrayRef(g_target_modules_dump_separate_debug_info_options);
2528b1c73532SDimitry Andric }
2529b1c73532SDimitry Andric
2530b1c73532SDimitry Andric OptionValueBoolean m_json = false;
2531b1c73532SDimitry Andric OptionValueBoolean m_errors_only = false;
2532b1c73532SDimitry Andric };
2533b1c73532SDimitry Andric
2534b1c73532SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)2535b1c73532SDimitry Andric void DoExecute(Args &command, CommandReturnObject &result) override {
2536b1c73532SDimitry Andric Target &target = GetSelectedTarget();
2537b1c73532SDimitry Andric uint32_t num_dumped = 0;
2538b1c73532SDimitry Andric
2539b1c73532SDimitry Andric uint32_t addr_byte_size = target.GetArchitecture().GetAddressByteSize();
2540b1c73532SDimitry Andric result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2541b1c73532SDimitry Andric result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2542b1c73532SDimitry Andric
2543b1c73532SDimitry Andric StructuredData::Array separate_debug_info_lists_by_module;
2544b1c73532SDimitry Andric if (command.GetArgumentCount() == 0) {
2545b1c73532SDimitry Andric // Dump all sections for all modules images
2546b1c73532SDimitry Andric const ModuleList &target_modules = target.GetImages();
2547b1c73532SDimitry Andric std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2548b1c73532SDimitry Andric const size_t num_modules = target_modules.GetSize();
2549b1c73532SDimitry Andric if (num_modules == 0) {
2550b1c73532SDimitry Andric result.AppendError("the target has no associated executable images");
2551b1c73532SDimitry Andric return;
2552b1c73532SDimitry Andric }
2553b1c73532SDimitry Andric for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
2554b1c73532SDimitry Andric if (INTERRUPT_REQUESTED(
2555b1c73532SDimitry Andric GetDebugger(),
2556b1c73532SDimitry Andric "Interrupted in dumping all "
2557b1c73532SDimitry Andric "separate debug info with {0} of {1} modules dumped",
2558b1c73532SDimitry Andric num_dumped, num_modules))
2559b1c73532SDimitry Andric break;
2560b1c73532SDimitry Andric
2561b1c73532SDimitry Andric if (GetSeparateDebugInfoList(separate_debug_info_lists_by_module,
2562b1c73532SDimitry Andric module_sp.get(),
2563b1c73532SDimitry Andric bool(m_options.m_errors_only)))
2564b1c73532SDimitry Andric num_dumped++;
2565b1c73532SDimitry Andric }
2566b1c73532SDimitry Andric } else {
2567b1c73532SDimitry Andric // Dump specified images (by basename or fullpath)
2568b1c73532SDimitry Andric const char *arg_cstr;
2569b1c73532SDimitry Andric for (int arg_idx = 0;
2570b1c73532SDimitry Andric (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2571b1c73532SDimitry Andric ++arg_idx) {
2572b1c73532SDimitry Andric ModuleList module_list;
2573b1c73532SDimitry Andric const size_t num_matches =
2574b1c73532SDimitry Andric FindModulesByName(&target, arg_cstr, module_list, true);
2575b1c73532SDimitry Andric if (num_matches > 0) {
2576b1c73532SDimitry Andric for (size_t i = 0; i < num_matches; ++i) {
2577b1c73532SDimitry Andric if (INTERRUPT_REQUESTED(GetDebugger(),
2578b1c73532SDimitry Andric "Interrupted dumping {0} "
2579b1c73532SDimitry Andric "of {1} requested modules",
2580b1c73532SDimitry Andric i, num_matches))
2581b1c73532SDimitry Andric break;
2582b1c73532SDimitry Andric Module *module = module_list.GetModulePointerAtIndex(i);
2583b1c73532SDimitry Andric if (GetSeparateDebugInfoList(separate_debug_info_lists_by_module,
2584b1c73532SDimitry Andric module, bool(m_options.m_errors_only)))
2585b1c73532SDimitry Andric num_dumped++;
2586b1c73532SDimitry Andric }
2587b1c73532SDimitry Andric } else
2588b1c73532SDimitry Andric result.AppendWarningWithFormat(
2589b1c73532SDimitry Andric "Unable to find an image that matches '%s'.\n", arg_cstr);
2590b1c73532SDimitry Andric }
2591b1c73532SDimitry Andric }
2592b1c73532SDimitry Andric
2593b1c73532SDimitry Andric if (num_dumped > 0) {
2594b1c73532SDimitry Andric Stream &strm = result.GetOutputStream();
2595b1c73532SDimitry Andric // Display the debug info files in some format.
2596b1c73532SDimitry Andric if (m_options.m_json) {
2597b1c73532SDimitry Andric // JSON format
2598b1c73532SDimitry Andric separate_debug_info_lists_by_module.Dump(strm,
2599b1c73532SDimitry Andric /*pretty_print=*/true);
2600b1c73532SDimitry Andric } else {
2601b1c73532SDimitry Andric // Human-readable table format
2602b1c73532SDimitry Andric separate_debug_info_lists_by_module.ForEach(
2603b1c73532SDimitry Andric [&result, &strm](StructuredData::Object *obj) {
2604b1c73532SDimitry Andric if (!obj) {
2605b1c73532SDimitry Andric return false;
2606b1c73532SDimitry Andric }
2607b1c73532SDimitry Andric
2608b1c73532SDimitry Andric // Each item in `separate_debug_info_lists_by_module` should be a
2609b1c73532SDimitry Andric // valid structured data dictionary.
2610b1c73532SDimitry Andric StructuredData::Dictionary *separate_debug_info_list =
2611b1c73532SDimitry Andric obj->GetAsDictionary();
2612b1c73532SDimitry Andric if (!separate_debug_info_list) {
2613b1c73532SDimitry Andric return false;
2614b1c73532SDimitry Andric }
2615b1c73532SDimitry Andric
2616b1c73532SDimitry Andric llvm::StringRef type;
2617b1c73532SDimitry Andric llvm::StringRef symfile;
2618b1c73532SDimitry Andric StructuredData::Array *files;
2619b1c73532SDimitry Andric if (!(separate_debug_info_list->GetValueForKeyAsString("type",
2620b1c73532SDimitry Andric type) &&
2621b1c73532SDimitry Andric separate_debug_info_list->GetValueForKeyAsString("symfile",
2622b1c73532SDimitry Andric symfile) &&
2623b1c73532SDimitry Andric separate_debug_info_list->GetValueForKeyAsArray(
2624b1c73532SDimitry Andric "separate-debug-info-files", files))) {
2625b1c73532SDimitry Andric assert(false);
2626b1c73532SDimitry Andric }
2627b1c73532SDimitry Andric
2628b1c73532SDimitry Andric strm << "Symbol file: " << symfile;
2629b1c73532SDimitry Andric strm.EOL();
2630b1c73532SDimitry Andric strm << "Type: \"" << type << "\"";
2631b1c73532SDimitry Andric strm.EOL();
2632b1c73532SDimitry Andric if (type == "dwo") {
2633b1c73532SDimitry Andric DumpDwoFilesTable(strm, *files);
2634b1c73532SDimitry Andric } else if (type == "oso") {
2635b1c73532SDimitry Andric DumpOsoFilesTable(strm, *files);
2636b1c73532SDimitry Andric } else {
2637b1c73532SDimitry Andric result.AppendWarningWithFormat(
2638b1c73532SDimitry Andric "Found unsupported debug info type '%s'.\n",
2639b1c73532SDimitry Andric type.str().c_str());
2640b1c73532SDimitry Andric }
2641b1c73532SDimitry Andric return true;
2642b1c73532SDimitry Andric });
2643b1c73532SDimitry Andric }
2644b1c73532SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
2645b1c73532SDimitry Andric } else {
2646b1c73532SDimitry Andric result.AppendError("no matching executable images found");
2647b1c73532SDimitry Andric }
2648b1c73532SDimitry Andric }
2649b1c73532SDimitry Andric
2650b1c73532SDimitry Andric CommandOptions m_options;
2651b1c73532SDimitry Andric };
2652b1c73532SDimitry Andric
2653f034231aSEd Maste #pragma mark CommandObjectTargetModulesDump
2654f034231aSEd Maste
2655f034231aSEd Maste // Dump multi-word command for target modules
2656f034231aSEd Maste
265714f1b3e8SDimitry Andric class CommandObjectTargetModulesDump : public CommandObjectMultiword {
2658f034231aSEd Maste public:
2659f034231aSEd Maste // Constructors and Destructors
CommandObjectTargetModulesDump(CommandInterpreter & interpreter)2660f3fbd1c0SDimitry Andric CommandObjectTargetModulesDump(CommandInterpreter &interpreter)
266194994d37SDimitry Andric : CommandObjectMultiword(
266294994d37SDimitry Andric interpreter, "target modules dump",
26631f917f69SDimitry Andric "Commands for dumping information about one or more target "
26641f917f69SDimitry Andric "modules.",
266514f1b3e8SDimitry Andric "target modules dump "
2666b1c73532SDimitry Andric "[objfile|symtab|sections|ast|symfile|line-table|pcm-info|separate-"
2667b1c73532SDimitry Andric "debug-info] "
266814f1b3e8SDimitry Andric "[<file1> <file2> ...]") {
266914f1b3e8SDimitry Andric LoadSubCommand("objfile",
267014f1b3e8SDimitry Andric CommandObjectSP(
267114f1b3e8SDimitry Andric new CommandObjectTargetModulesDumpObjfile(interpreter)));
267214f1b3e8SDimitry Andric LoadSubCommand(
267314f1b3e8SDimitry Andric "symtab",
267414f1b3e8SDimitry Andric CommandObjectSP(new CommandObjectTargetModulesDumpSymtab(interpreter)));
267514f1b3e8SDimitry Andric LoadSubCommand("sections",
267614f1b3e8SDimitry Andric CommandObjectSP(new CommandObjectTargetModulesDumpSections(
267714f1b3e8SDimitry Andric interpreter)));
267814f1b3e8SDimitry Andric LoadSubCommand("symfile",
267914f1b3e8SDimitry Andric CommandObjectSP(
268014f1b3e8SDimitry Andric new CommandObjectTargetModulesDumpSymfile(interpreter)));
268194994d37SDimitry Andric LoadSubCommand(
268294994d37SDimitry Andric "ast", CommandObjectSP(
268394994d37SDimitry Andric new CommandObjectTargetModulesDumpClangAST(interpreter)));
268414f1b3e8SDimitry Andric LoadSubCommand("line-table",
268514f1b3e8SDimitry Andric CommandObjectSP(new CommandObjectTargetModulesDumpLineTable(
268614f1b3e8SDimitry Andric interpreter)));
26871f917f69SDimitry Andric LoadSubCommand(
26881f917f69SDimitry Andric "pcm-info",
26891f917f69SDimitry Andric CommandObjectSP(
26901f917f69SDimitry Andric new CommandObjectTargetModulesDumpClangPCMInfo(interpreter)));
2691b1c73532SDimitry Andric LoadSubCommand("separate-debug-info",
2692b1c73532SDimitry Andric CommandObjectSP(
2693b1c73532SDimitry Andric new CommandObjectTargetModulesDumpSeparateDebugInfoFiles(
2694b1c73532SDimitry Andric interpreter)));
2695f034231aSEd Maste }
2696f034231aSEd Maste
2697f3fbd1c0SDimitry Andric ~CommandObjectTargetModulesDump() override = default;
2698f034231aSEd Maste };
2699f034231aSEd Maste
270014f1b3e8SDimitry Andric class CommandObjectTargetModulesAdd : public CommandObjectParsed {
2701f034231aSEd Maste public:
CommandObjectTargetModulesAdd(CommandInterpreter & interpreter)270214f1b3e8SDimitry Andric CommandObjectTargetModulesAdd(CommandInterpreter &interpreter)
270314f1b3e8SDimitry Andric : CommandObjectParsed(interpreter, "target modules add",
2704f034231aSEd Maste "Add a new module to the current target's modules.",
2705ead24645SDimitry Andric "target modules add [<module>]",
2706ead24645SDimitry Andric eCommandRequiresTarget),
27076f8fc217SDimitry Andric m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
27086f8fc217SDimitry Andric eArgTypeFilename,
2709ead24645SDimitry Andric "Fullpath to a stand alone debug "
271014f1b3e8SDimitry Andric "symbols file for when debug symbols "
271114f1b3e8SDimitry Andric "are not in the executable.") {
271214f1b3e8SDimitry Andric m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
271314f1b3e8SDimitry Andric LLDB_OPT_SET_1);
2714f034231aSEd Maste m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2715f034231aSEd Maste m_option_group.Finalize();
2716ac9a064cSDimitry Andric AddSimpleArgumentList(eArgTypePath, eArgRepeatStar);
2717f034231aSEd Maste }
2718f034231aSEd Maste
2719f3fbd1c0SDimitry Andric ~CommandObjectTargetModulesAdd() override = default;
2720f034231aSEd Maste
GetOptions()272114f1b3e8SDimitry Andric Options *GetOptions() override { return &m_option_group; }
2722f034231aSEd Maste
2723f034231aSEd Maste protected:
2724f034231aSEd Maste OptionGroupOptions m_option_group;
2725f034231aSEd Maste OptionGroupUUID m_uuid_option_group;
2726f034231aSEd Maste OptionGroupFile m_symbol_file;
2727f034231aSEd Maste
DoExecute(Args & args,CommandReturnObject & result)2728b1c73532SDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override {
2729ead24645SDimitry Andric Target *target = &GetSelectedTarget();
2730f034231aSEd Maste bool flush = false;
2731f034231aSEd Maste
2732f034231aSEd Maste const size_t argc = args.GetArgumentCount();
273314f1b3e8SDimitry Andric if (argc == 0) {
273414f1b3e8SDimitry Andric if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2735f034231aSEd Maste // We are given a UUID only, go locate the file
2736f034231aSEd Maste ModuleSpec module_spec;
273714f1b3e8SDimitry Andric module_spec.GetUUID() =
273814f1b3e8SDimitry Andric m_uuid_option_group.GetOptionValue().GetCurrentValue();
2739f034231aSEd Maste if (m_symbol_file.GetOptionValue().OptionWasSet())
274014f1b3e8SDimitry Andric module_spec.GetSymbolFileSpec() =
274114f1b3e8SDimitry Andric m_symbol_file.GetOptionValue().GetCurrentValue();
2742145449b1SDimitry Andric Status error;
2743b1c73532SDimitry Andric if (PluginManager::DownloadObjectAndSymbolFile(module_spec, error)) {
2744ead24645SDimitry Andric ModuleSP module_sp(
2745ead24645SDimitry Andric target->GetOrCreateModule(module_spec, true /* notify */));
274614f1b3e8SDimitry Andric if (module_sp) {
2747f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
2748b1c73532SDimitry Andric return;
274914f1b3e8SDimitry Andric } else {
2750f034231aSEd Maste StreamString strm;
27517fa27ce4SDimitry Andric module_spec.GetUUID().Dump(strm);
275214f1b3e8SDimitry Andric if (module_spec.GetFileSpec()) {
275314f1b3e8SDimitry Andric if (module_spec.GetSymbolFileSpec()) {
275414f1b3e8SDimitry Andric result.AppendErrorWithFormat(
275514f1b3e8SDimitry Andric "Unable to create the executable or symbol file with "
275614f1b3e8SDimitry Andric "UUID %s with path %s and symbol file %s",
2757ead24645SDimitry Andric strm.GetData(), module_spec.GetFileSpec().GetPath().c_str(),
2758f034231aSEd Maste module_spec.GetSymbolFileSpec().GetPath().c_str());
275914f1b3e8SDimitry Andric } else {
276014f1b3e8SDimitry Andric result.AppendErrorWithFormat(
276114f1b3e8SDimitry Andric "Unable to create the executable or symbol file with "
276214f1b3e8SDimitry Andric "UUID %s with path %s",
276314f1b3e8SDimitry Andric strm.GetData(),
2764f034231aSEd Maste module_spec.GetFileSpec().GetPath().c_str());
2765f034231aSEd Maste }
276614f1b3e8SDimitry Andric } else {
276714f1b3e8SDimitry Andric result.AppendErrorWithFormat("Unable to create the executable "
276814f1b3e8SDimitry Andric "or symbol file with UUID %s",
276914f1b3e8SDimitry Andric strm.GetData());
2770f034231aSEd Maste }
2771b1c73532SDimitry Andric return;
2772f034231aSEd Maste }
277314f1b3e8SDimitry Andric } else {
2774f034231aSEd Maste StreamString strm;
27757fa27ce4SDimitry Andric module_spec.GetUUID().Dump(strm);
277614f1b3e8SDimitry Andric result.AppendErrorWithFormat(
277714f1b3e8SDimitry Andric "Unable to locate the executable or symbol file with UUID %s",
277814f1b3e8SDimitry Andric strm.GetData());
2779145449b1SDimitry Andric result.SetError(error);
2780b1c73532SDimitry Andric return;
2781f034231aSEd Maste }
278214f1b3e8SDimitry Andric } else {
278314f1b3e8SDimitry Andric result.AppendError(
278414f1b3e8SDimitry Andric "one or more executable image paths must be specified");
2785b1c73532SDimitry Andric return;
2786f034231aSEd Maste }
278714f1b3e8SDimitry Andric } else {
278814f1b3e8SDimitry Andric for (auto &entry : args.entries()) {
2789ead24645SDimitry Andric if (entry.ref().empty())
279014f1b3e8SDimitry Andric continue;
279114f1b3e8SDimitry Andric
2792ead24645SDimitry Andric FileSpec file_spec(entry.ref());
279394994d37SDimitry Andric if (FileSystem::Instance().Exists(file_spec)) {
2794f034231aSEd Maste ModuleSpec module_spec(file_spec);
2795f034231aSEd Maste if (m_uuid_option_group.GetOptionValue().OptionWasSet())
279614f1b3e8SDimitry Andric module_spec.GetUUID() =
279714f1b3e8SDimitry Andric m_uuid_option_group.GetOptionValue().GetCurrentValue();
2798f034231aSEd Maste if (m_symbol_file.GetOptionValue().OptionWasSet())
279914f1b3e8SDimitry Andric module_spec.GetSymbolFileSpec() =
280014f1b3e8SDimitry Andric m_symbol_file.GetOptionValue().GetCurrentValue();
2801f21a844fSEd Maste if (!module_spec.GetArchitecture().IsValid())
2802f21a844fSEd Maste module_spec.GetArchitecture() = target->GetArchitecture();
2803b76161e4SDimitry Andric Status error;
2804ead24645SDimitry Andric ModuleSP module_sp(target->GetOrCreateModule(
2805ead24645SDimitry Andric module_spec, true /* notify */, &error));
280614f1b3e8SDimitry Andric if (!module_sp) {
2807f034231aSEd Maste const char *error_cstr = error.AsCString();
2808f034231aSEd Maste if (error_cstr)
2809f034231aSEd Maste result.AppendError(error_cstr);
2810f034231aSEd Maste else
281114f1b3e8SDimitry Andric result.AppendErrorWithFormat("unsupported module: %s",
281214f1b3e8SDimitry Andric entry.c_str());
2813b1c73532SDimitry Andric return;
281414f1b3e8SDimitry Andric } else {
2815f034231aSEd Maste flush = true;
2816f034231aSEd Maste }
2817f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
281814f1b3e8SDimitry Andric } else {
281914f1b3e8SDimitry Andric std::string resolved_path = file_spec.GetPath();
2820ead24645SDimitry Andric if (resolved_path != entry.ref()) {
282114f1b3e8SDimitry Andric result.AppendErrorWithFormat(
282214f1b3e8SDimitry Andric "invalid module path '%s' with resolved path '%s'\n",
2823ead24645SDimitry Andric entry.ref().str().c_str(), resolved_path.c_str());
2824f034231aSEd Maste break;
2825f034231aSEd Maste }
282614f1b3e8SDimitry Andric result.AppendErrorWithFormat("invalid module path '%s'\n",
282714f1b3e8SDimitry Andric entry.c_str());
2828f034231aSEd Maste break;
2829f034231aSEd Maste }
2830f034231aSEd Maste }
2831f034231aSEd Maste }
2832f034231aSEd Maste
283314f1b3e8SDimitry Andric if (flush) {
2834f034231aSEd Maste ProcessSP process = target->GetProcessSP();
2835f034231aSEd Maste if (process)
2836f034231aSEd Maste process->Flush();
2837f034231aSEd Maste }
2838f034231aSEd Maste }
2839f034231aSEd Maste };
2840f034231aSEd Maste
284114f1b3e8SDimitry Andric class CommandObjectTargetModulesLoad
284214f1b3e8SDimitry Andric : public CommandObjectTargetModulesModuleAutoComplete {
2843f034231aSEd Maste public:
CommandObjectTargetModulesLoad(CommandInterpreter & interpreter)284414f1b3e8SDimitry Andric CommandObjectTargetModulesLoad(CommandInterpreter &interpreter)
284514f1b3e8SDimitry Andric : CommandObjectTargetModulesModuleAutoComplete(
2846ead24645SDimitry Andric interpreter, "target modules load",
2847ead24645SDimitry Andric "Set the load addresses for one or more sections in a target "
2848ead24645SDimitry Andric "module.",
284914f1b3e8SDimitry Andric "target modules load [--file <module> --uuid <uuid>] <sect-name> "
2850ead24645SDimitry Andric "<address> [<sect-name> <address> ....]",
2851ead24645SDimitry Andric eCommandRequiresTarget),
285214f1b3e8SDimitry Andric m_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName,
285314f1b3e8SDimitry Andric "Fullpath or basename for module to load.", ""),
285474a628f7SDimitry Andric m_load_option(LLDB_OPT_SET_1, false, "load", 'l',
285574a628f7SDimitry Andric "Write file contents to the memory.", false, true),
2856ef5d0b5eSDimitry Andric m_pc_option(LLDB_OPT_SET_1, false, "set-pc-to-entry", 'p',
285774a628f7SDimitry Andric "Set PC to the entry point."
285874a628f7SDimitry Andric " Only applicable with '--load' option.",
285974a628f7SDimitry Andric false, true),
286014f1b3e8SDimitry Andric m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset,
286114f1b3e8SDimitry Andric "Set the load address for all sections to be the "
286214f1b3e8SDimitry Andric "virtual address in the file plus the offset.",
286314f1b3e8SDimitry Andric 0) {
286414f1b3e8SDimitry Andric m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
286514f1b3e8SDimitry Andric LLDB_OPT_SET_1);
2866f034231aSEd Maste m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
286774a628f7SDimitry Andric m_option_group.Append(&m_load_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
286874a628f7SDimitry Andric m_option_group.Append(&m_pc_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2869f034231aSEd Maste m_option_group.Append(&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2870f034231aSEd Maste m_option_group.Finalize();
2871f034231aSEd Maste }
2872f034231aSEd Maste
2873f3fbd1c0SDimitry Andric ~CommandObjectTargetModulesLoad() override = default;
2874f034231aSEd Maste
GetOptions()287514f1b3e8SDimitry Andric Options *GetOptions() override { return &m_option_group; }
2876f034231aSEd Maste
2877f034231aSEd Maste protected:
DoExecute(Args & args,CommandReturnObject & result)2878b1c73532SDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override {
2879ead24645SDimitry Andric Target *target = &GetSelectedTarget();
288074a628f7SDimitry Andric const bool load = m_load_option.GetOptionValue().GetCurrentValue();
288174a628f7SDimitry Andric const bool set_pc = m_pc_option.GetOptionValue().GetCurrentValue();
2882ead24645SDimitry Andric
2883f034231aSEd Maste const size_t argc = args.GetArgumentCount();
2884f034231aSEd Maste ModuleSpec module_spec;
2885f034231aSEd Maste bool search_using_module_spec = false;
288674a628f7SDimitry Andric
2887f73363f1SDimitry Andric // Allow "load" option to work without --file or --uuid option.
288874a628f7SDimitry Andric if (load) {
288974a628f7SDimitry Andric if (!m_file_option.GetOptionValue().OptionWasSet() &&
289074a628f7SDimitry Andric !m_uuid_option_group.GetOptionValue().OptionWasSet()) {
289174a628f7SDimitry Andric ModuleList &module_list = target->GetImages();
289274a628f7SDimitry Andric if (module_list.GetSize() == 1) {
289374a628f7SDimitry Andric search_using_module_spec = true;
289474a628f7SDimitry Andric module_spec.GetFileSpec() =
289574a628f7SDimitry Andric module_list.GetModuleAtIndex(0)->GetFileSpec();
289674a628f7SDimitry Andric }
289774a628f7SDimitry Andric }
289874a628f7SDimitry Andric }
289974a628f7SDimitry Andric
290014f1b3e8SDimitry Andric if (m_file_option.GetOptionValue().OptionWasSet()) {
2901f034231aSEd Maste search_using_module_spec = true;
2902205afe67SEd Maste const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
2903205afe67SEd Maste const bool use_global_module_list = true;
2904205afe67SEd Maste ModuleList module_list;
290514f1b3e8SDimitry Andric const size_t num_matches = FindModulesByName(
290614f1b3e8SDimitry Andric target, arg_cstr, module_list, use_global_module_list);
290714f1b3e8SDimitry Andric if (num_matches == 1) {
290814f1b3e8SDimitry Andric module_spec.GetFileSpec() =
290914f1b3e8SDimitry Andric module_list.GetModuleAtIndex(0)->GetFileSpec();
291014f1b3e8SDimitry Andric } else if (num_matches > 1) {
2911205afe67SEd Maste search_using_module_spec = false;
291214f1b3e8SDimitry Andric result.AppendErrorWithFormat(
291314f1b3e8SDimitry Andric "more than 1 module matched by name '%s'\n", arg_cstr);
291414f1b3e8SDimitry Andric } else {
2915205afe67SEd Maste search_using_module_spec = false;
291614f1b3e8SDimitry Andric result.AppendErrorWithFormat("no object file for module '%s'\n",
291714f1b3e8SDimitry Andric arg_cstr);
2918205afe67SEd Maste }
2919f034231aSEd Maste }
2920f034231aSEd Maste
292114f1b3e8SDimitry Andric if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2922f034231aSEd Maste search_using_module_spec = true;
292314f1b3e8SDimitry Andric module_spec.GetUUID() =
292414f1b3e8SDimitry Andric m_uuid_option_group.GetOptionValue().GetCurrentValue();
2925f034231aSEd Maste }
2926f034231aSEd Maste
292714f1b3e8SDimitry Andric if (search_using_module_spec) {
2928f034231aSEd Maste ModuleList matching_modules;
292914f1b3e8SDimitry Andric target->GetImages().FindModules(module_spec, matching_modules);
2930ead24645SDimitry Andric const size_t num_matches = matching_modules.GetSize();
2931f034231aSEd Maste
2932f034231aSEd Maste char path[PATH_MAX];
293314f1b3e8SDimitry Andric if (num_matches == 1) {
2934f034231aSEd Maste Module *module = matching_modules.GetModulePointerAtIndex(0);
293514f1b3e8SDimitry Andric if (module) {
2936f034231aSEd Maste ObjectFile *objfile = module->GetObjectFile();
293714f1b3e8SDimitry Andric if (objfile) {
2938f034231aSEd Maste SectionList *section_list = module->GetSectionList();
293914f1b3e8SDimitry Andric if (section_list) {
2940f034231aSEd Maste bool changed = false;
294114f1b3e8SDimitry Andric if (argc == 0) {
294214f1b3e8SDimitry Andric if (m_slide_option.GetOptionValue().OptionWasSet()) {
294314f1b3e8SDimitry Andric const addr_t slide =
294414f1b3e8SDimitry Andric m_slide_option.GetOptionValue().GetCurrentValue();
2945866dcdacSEd Maste const bool slide_is_offset = true;
294614f1b3e8SDimitry Andric module->SetLoadAddress(*target, slide, slide_is_offset,
294714f1b3e8SDimitry Andric changed);
294814f1b3e8SDimitry Andric } else {
294914f1b3e8SDimitry Andric result.AppendError("one or more section name + load "
295014f1b3e8SDimitry Andric "address pair must be specified");
2951b1c73532SDimitry Andric return;
2952f034231aSEd Maste }
295314f1b3e8SDimitry Andric } else {
295414f1b3e8SDimitry Andric if (m_slide_option.GetOptionValue().OptionWasSet()) {
295514f1b3e8SDimitry Andric result.AppendError("The \"--slide <offset>\" option can't "
295614f1b3e8SDimitry Andric "be used in conjunction with setting "
295714f1b3e8SDimitry Andric "section load addresses.\n");
2958b1c73532SDimitry Andric return;
2959f034231aSEd Maste }
2960f034231aSEd Maste
296114f1b3e8SDimitry Andric for (size_t i = 0; i < argc; i += 2) {
2962f034231aSEd Maste const char *sect_name = args.GetArgumentAtIndex(i);
2963f034231aSEd Maste const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1);
296414f1b3e8SDimitry Andric if (sect_name && load_addr_cstr) {
2965f034231aSEd Maste ConstString const_sect_name(sect_name);
2966cfca06d7SDimitry Andric addr_t load_addr;
2967cfca06d7SDimitry Andric if (llvm::to_integer(load_addr_cstr, load_addr)) {
296814f1b3e8SDimitry Andric SectionSP section_sp(
296914f1b3e8SDimitry Andric section_list->FindSectionByName(const_sect_name));
297014f1b3e8SDimitry Andric if (section_sp) {
297114f1b3e8SDimitry Andric if (section_sp->IsThreadSpecific()) {
297214f1b3e8SDimitry Andric result.AppendErrorWithFormat(
297314f1b3e8SDimitry Andric "thread specific sections are not yet "
297414f1b3e8SDimitry Andric "supported (section '%s')\n",
297514f1b3e8SDimitry Andric sect_name);
2976f034231aSEd Maste break;
297714f1b3e8SDimitry Andric } else {
297814f1b3e8SDimitry Andric if (target->GetSectionLoadList()
2979ead24645SDimitry Andric .SetSectionLoadAddress(section_sp, load_addr))
2980f034231aSEd Maste changed = true;
298114f1b3e8SDimitry Andric result.AppendMessageWithFormat(
298214f1b3e8SDimitry Andric "section '%s' loaded at 0x%" PRIx64 "\n",
298314f1b3e8SDimitry Andric sect_name, load_addr);
2984f034231aSEd Maste }
298514f1b3e8SDimitry Andric } else {
298614f1b3e8SDimitry Andric result.AppendErrorWithFormat("no section found that "
298714f1b3e8SDimitry Andric "matches the section "
298814f1b3e8SDimitry Andric "name '%s'\n",
298914f1b3e8SDimitry Andric sect_name);
2990f034231aSEd Maste break;
2991f034231aSEd Maste }
299214f1b3e8SDimitry Andric } else {
299314f1b3e8SDimitry Andric result.AppendErrorWithFormat(
2994ead24645SDimitry Andric "invalid load address string '%s'\n", load_addr_cstr);
2995f034231aSEd Maste break;
2996f034231aSEd Maste }
299714f1b3e8SDimitry Andric } else {
2998f034231aSEd Maste if (sect_name)
299914f1b3e8SDimitry Andric result.AppendError("section names must be followed by "
300014f1b3e8SDimitry Andric "a load address.\n");
3001f034231aSEd Maste else
300214f1b3e8SDimitry Andric result.AppendError("one or more section name + load "
300314f1b3e8SDimitry Andric "address pair must be specified.\n");
3004f034231aSEd Maste break;
3005f034231aSEd Maste }
3006f034231aSEd Maste }
3007f034231aSEd Maste }
3008f034231aSEd Maste
300914f1b3e8SDimitry Andric if (changed) {
3010f034231aSEd Maste target->ModulesDidLoad(matching_modules);
3011f034231aSEd Maste Process *process = m_exe_ctx.GetProcessPtr();
3012f034231aSEd Maste if (process)
3013f034231aSEd Maste process->Flush();
3014f034231aSEd Maste }
301574a628f7SDimitry Andric if (load) {
3016f73363f1SDimitry Andric ProcessSP process = target->CalculateProcess();
3017f73363f1SDimitry Andric Address file_entry = objfile->GetEntryPointAddress();
3018f73363f1SDimitry Andric if (!process) {
3019f73363f1SDimitry Andric result.AppendError("No process");
3020b1c73532SDimitry Andric return;
3021f73363f1SDimitry Andric }
3022f73363f1SDimitry Andric if (set_pc && !file_entry.IsValid()) {
3023f73363f1SDimitry Andric result.AppendError("No entry address in object file");
3024b1c73532SDimitry Andric return;
3025f73363f1SDimitry Andric }
3026f73363f1SDimitry Andric std::vector<ObjectFile::LoadableData> loadables(
3027f73363f1SDimitry Andric objfile->GetLoadableData(*target));
3028f73363f1SDimitry Andric if (loadables.size() == 0) {
3029f73363f1SDimitry Andric result.AppendError("No loadable sections");
3030b1c73532SDimitry Andric return;
3031f73363f1SDimitry Andric }
3032f73363f1SDimitry Andric Status error = process->WriteObjectFile(std::move(loadables));
303374a628f7SDimitry Andric if (error.Fail()) {
303474a628f7SDimitry Andric result.AppendError(error.AsCString());
3035b1c73532SDimitry Andric return;
303674a628f7SDimitry Andric }
3037f73363f1SDimitry Andric if (set_pc) {
3038f73363f1SDimitry Andric ThreadList &thread_list = process->GetThreadList();
3039f73363f1SDimitry Andric RegisterContextSP reg_context(
304094994d37SDimitry Andric thread_list.GetSelectedThread()->GetRegisterContext());
304194994d37SDimitry Andric addr_t file_entry_addr = file_entry.GetLoadAddress(target);
304294994d37SDimitry Andric if (!reg_context->SetPC(file_entry_addr)) {
304394994d37SDimitry Andric result.AppendErrorWithFormat("failed to set PC value to "
304494994d37SDimitry Andric "0x%" PRIx64 "\n",
304594994d37SDimitry Andric file_entry_addr);
304694994d37SDimitry Andric }
3047f73363f1SDimitry Andric }
304874a628f7SDimitry Andric }
304914f1b3e8SDimitry Andric } else {
3050f034231aSEd Maste module->GetFileSpec().GetPath(path, sizeof(path));
3051ead24645SDimitry Andric result.AppendErrorWithFormat("no sections in object file '%s'\n",
3052ead24645SDimitry Andric path);
3053f034231aSEd Maste }
305414f1b3e8SDimitry Andric } else {
3055f034231aSEd Maste module->GetFileSpec().GetPath(path, sizeof(path));
305614f1b3e8SDimitry Andric result.AppendErrorWithFormat("no object file for module '%s'\n",
305714f1b3e8SDimitry Andric path);
3058f034231aSEd Maste }
305914f1b3e8SDimitry Andric } else {
3060f034231aSEd Maste FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
306114f1b3e8SDimitry Andric if (module_spec_file) {
3062f034231aSEd Maste module_spec_file->GetPath(path, sizeof(path));
3063f034231aSEd Maste result.AppendErrorWithFormat("invalid module '%s'.\n", path);
306414f1b3e8SDimitry Andric } else
3065f034231aSEd Maste result.AppendError("no module spec");
3066f034231aSEd Maste }
306714f1b3e8SDimitry Andric } else {
3068f034231aSEd Maste std::string uuid_str;
3069f034231aSEd Maste
3070f034231aSEd Maste if (module_spec.GetFileSpec())
3071f034231aSEd Maste module_spec.GetFileSpec().GetPath(path, sizeof(path));
3072f034231aSEd Maste else
3073f034231aSEd Maste path[0] = '\0';
3074f034231aSEd Maste
3075f034231aSEd Maste if (module_spec.GetUUIDPtr())
3076f034231aSEd Maste uuid_str = module_spec.GetUUID().GetAsString();
307714f1b3e8SDimitry Andric if (num_matches > 1) {
307814f1b3e8SDimitry Andric result.AppendErrorWithFormat(
307914f1b3e8SDimitry Andric "multiple modules match%s%s%s%s:\n", path[0] ? " file=" : "",
308014f1b3e8SDimitry Andric path, !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
308114f1b3e8SDimitry Andric for (size_t i = 0; i < num_matches; ++i) {
308214f1b3e8SDimitry Andric if (matching_modules.GetModulePointerAtIndex(i)
308314f1b3e8SDimitry Andric ->GetFileSpec()
308414f1b3e8SDimitry Andric .GetPath(path, sizeof(path)))
3085f034231aSEd Maste result.AppendMessageWithFormat("%s\n", path);
3086f034231aSEd Maste }
308714f1b3e8SDimitry Andric } else {
308814f1b3e8SDimitry Andric result.AppendErrorWithFormat(
308914f1b3e8SDimitry Andric "no modules were found that match%s%s%s%s.\n",
3090ead24645SDimitry Andric path[0] ? " file=" : "", path, !uuid_str.empty() ? " uuid=" : "",
3091ead24645SDimitry Andric uuid_str.c_str());
3092f034231aSEd Maste }
3093f034231aSEd Maste }
309414f1b3e8SDimitry Andric } else {
309514f1b3e8SDimitry Andric result.AppendError("either the \"--file <module>\" or the \"--uuid "
309614f1b3e8SDimitry Andric "<uuid>\" option must be specified.\n");
3097f034231aSEd Maste }
3098f034231aSEd Maste }
3099f034231aSEd Maste
3100f034231aSEd Maste OptionGroupOptions m_option_group;
3101f034231aSEd Maste OptionGroupUUID m_uuid_option_group;
3102205afe67SEd Maste OptionGroupString m_file_option;
310374a628f7SDimitry Andric OptionGroupBoolean m_load_option;
310474a628f7SDimitry Andric OptionGroupBoolean m_pc_option;
3105f034231aSEd Maste OptionGroupUInt64 m_slide_option;
3106f034231aSEd Maste };
3107f034231aSEd Maste
3108c0981da4SDimitry Andric #pragma mark CommandObjectTargetModulesList
3109f034231aSEd Maste // List images with associated information
3110ead24645SDimitry Andric #define LLDB_OPTIONS_target_modules_list
3111ead24645SDimitry Andric #include "CommandOptions.inc"
311214f1b3e8SDimitry Andric
311314f1b3e8SDimitry Andric class CommandObjectTargetModulesList : public CommandObjectParsed {
3114f034231aSEd Maste public:
311514f1b3e8SDimitry Andric class CommandOptions : public Options {
3116f034231aSEd Maste public:
3117145449b1SDimitry Andric CommandOptions() = default;
3118f034231aSEd Maste
3119f3fbd1c0SDimitry Andric ~CommandOptions() override = default;
3120f034231aSEd Maste
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)3121b76161e4SDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
312214f1b3e8SDimitry Andric ExecutionContext *execution_context) override {
3123b76161e4SDimitry Andric Status error;
3124f034231aSEd Maste
3125f034231aSEd Maste const int short_option = m_getopt_table[option_idx].val;
312614f1b3e8SDimitry Andric if (short_option == 'g') {
3127f034231aSEd Maste m_use_global_module_list = true;
312814f1b3e8SDimitry Andric } else if (short_option == 'a') {
3129f73363f1SDimitry Andric m_module_addr = OptionArgParser::ToAddress(
3130f73363f1SDimitry Andric execution_context, option_arg, LLDB_INVALID_ADDRESS, &error);
313114f1b3e8SDimitry Andric } else {
3132f034231aSEd Maste unsigned long width = 0;
313314f1b3e8SDimitry Andric option_arg.getAsInteger(0, width);
3134f034231aSEd Maste m_format_array.push_back(std::make_pair(short_option, width));
3135f034231aSEd Maste }
3136f034231aSEd Maste return error;
3137f034231aSEd Maste }
3138f034231aSEd Maste
OptionParsingStarting(ExecutionContext * execution_context)313914f1b3e8SDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override {
3140f034231aSEd Maste m_format_array.clear();
3141f034231aSEd Maste m_use_global_module_list = false;
3142f034231aSEd Maste m_module_addr = LLDB_INVALID_ADDRESS;
3143f034231aSEd Maste }
3144f034231aSEd Maste
GetDefinitions()314514f1b3e8SDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3146e3b55780SDimitry Andric return llvm::ArrayRef(g_target_modules_list_options);
3147f034231aSEd Maste }
3148f034231aSEd Maste
3149f034231aSEd Maste // Instance variables to hold the values for command options.
3150f034231aSEd Maste typedef std::vector<std::pair<char, uint32_t>> FormatWidthCollection;
3151f034231aSEd Maste FormatWidthCollection m_format_array;
3152344a3780SDimitry Andric bool m_use_global_module_list = false;
3153344a3780SDimitry Andric lldb::addr_t m_module_addr = LLDB_INVALID_ADDRESS;
3154f034231aSEd Maste };
3155f034231aSEd Maste
CommandObjectTargetModulesList(CommandInterpreter & interpreter)315614f1b3e8SDimitry Andric CommandObjectTargetModulesList(CommandInterpreter &interpreter)
315714f1b3e8SDimitry Andric : CommandObjectParsed(
315814f1b3e8SDimitry Andric interpreter, "target modules list",
3159145449b1SDimitry Andric "List current executable and dependent shared library images.") {
3160ac9a064cSDimitry Andric AddSimpleArgumentList(eArgTypeModule, eArgRepeatStar);
3161145449b1SDimitry Andric }
3162f034231aSEd Maste
3163f3fbd1c0SDimitry Andric ~CommandObjectTargetModulesList() override = default;
3164f034231aSEd Maste
GetOptions()316514f1b3e8SDimitry Andric Options *GetOptions() override { return &m_options; }
3166f034231aSEd Maste
3167f034231aSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)3168b1c73532SDimitry Andric void DoExecute(Args &command, CommandReturnObject &result) override {
31695f29bb8aSDimitry Andric Target *target = GetDebugger().GetSelectedTarget().get();
3170f034231aSEd Maste const bool use_global_module_list = m_options.m_use_global_module_list;
317114f1b3e8SDimitry Andric // Define a local module list here to ensure it lives longer than any
3172f73363f1SDimitry Andric // "locker" object which might lock its contents below (through the
3173f73363f1SDimitry Andric // "module_list_ptr" variable).
3174f034231aSEd Maste ModuleList module_list;
317514f1b3e8SDimitry Andric if (target == nullptr && !use_global_module_list) {
317614f1b3e8SDimitry Andric result.AppendError("invalid target, create a debug target using the "
317714f1b3e8SDimitry Andric "'target create' command");
3178b1c73532SDimitry Andric return;
317914f1b3e8SDimitry Andric } else {
318014f1b3e8SDimitry Andric if (target) {
318114f1b3e8SDimitry Andric uint32_t addr_byte_size =
318214f1b3e8SDimitry Andric target->GetArchitecture().GetAddressByteSize();
3183f034231aSEd Maste result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3184f034231aSEd Maste result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3185f034231aSEd Maste }
3186f034231aSEd Maste // Dump all sections for all modules images
3187f034231aSEd Maste Stream &strm = result.GetOutputStream();
3188f034231aSEd Maste
318914f1b3e8SDimitry Andric if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) {
319014f1b3e8SDimitry Andric if (target) {
3191f034231aSEd Maste Address module_address;
319214f1b3e8SDimitry Andric if (module_address.SetLoadAddress(m_options.m_module_addr, target)) {
3193f034231aSEd Maste ModuleSP module_sp(module_address.GetModule());
319414f1b3e8SDimitry Andric if (module_sp) {
3195f034231aSEd Maste PrintModule(target, module_sp.get(), 0, strm);
3196f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
319714f1b3e8SDimitry Andric } else {
319814f1b3e8SDimitry Andric result.AppendErrorWithFormat(
319914f1b3e8SDimitry Andric "Couldn't find module matching address: 0x%" PRIx64 ".",
320014f1b3e8SDimitry Andric m_options.m_module_addr);
3201f034231aSEd Maste }
320214f1b3e8SDimitry Andric } else {
320314f1b3e8SDimitry Andric result.AppendErrorWithFormat(
320414f1b3e8SDimitry Andric "Couldn't find module containing address: 0x%" PRIx64 ".",
320514f1b3e8SDimitry Andric m_options.m_module_addr);
3206f034231aSEd Maste }
320714f1b3e8SDimitry Andric } else {
320814f1b3e8SDimitry Andric result.AppendError(
320914f1b3e8SDimitry Andric "Can only look up modules by address with a valid target.");
3210f034231aSEd Maste }
3211b1c73532SDimitry Andric return;
3212f034231aSEd Maste }
3213f034231aSEd Maste
3214f034231aSEd Maste size_t num_modules = 0;
3215f3fbd1c0SDimitry Andric
321614f1b3e8SDimitry Andric // This locker will be locked on the mutex in module_list_ptr if it is
3217f73363f1SDimitry Andric // non-nullptr. Otherwise it will lock the
3218f73363f1SDimitry Andric // AllocationModuleCollectionMutex when accessing the global module list
3219f73363f1SDimitry Andric // directly.
322014f1b3e8SDimitry Andric std::unique_lock<std::recursive_mutex> guard(
322114f1b3e8SDimitry Andric Module::GetAllocationModuleCollectionMutex(), std::defer_lock);
3222f3fbd1c0SDimitry Andric
3223f3fbd1c0SDimitry Andric const ModuleList *module_list_ptr = nullptr;
3224f034231aSEd Maste const size_t argc = command.GetArgumentCount();
322514f1b3e8SDimitry Andric if (argc == 0) {
322614f1b3e8SDimitry Andric if (use_global_module_list) {
3227f3fbd1c0SDimitry Andric guard.lock();
3228f034231aSEd Maste num_modules = Module::GetNumberAllocatedModules();
322914f1b3e8SDimitry Andric } else {
3230f034231aSEd Maste module_list_ptr = &target->GetImages();
3231f034231aSEd Maste }
323214f1b3e8SDimitry Andric } else {
3233cfca06d7SDimitry Andric for (const Args::ArgEntry &arg : command) {
3234f034231aSEd Maste // Dump specified images (by basename or fullpath)
323514f1b3e8SDimitry Andric const size_t num_matches = FindModulesByName(
3236cfca06d7SDimitry Andric target, arg.c_str(), module_list, use_global_module_list);
323714f1b3e8SDimitry Andric if (num_matches == 0) {
323814f1b3e8SDimitry Andric if (argc == 1) {
323914f1b3e8SDimitry Andric result.AppendErrorWithFormat("no modules found that match '%s'",
3240cfca06d7SDimitry Andric arg.c_str());
3241b1c73532SDimitry Andric return;
3242f034231aSEd Maste }
3243f034231aSEd Maste }
3244f034231aSEd Maste }
3245f034231aSEd Maste
3246f034231aSEd Maste module_list_ptr = &module_list;
3247f034231aSEd Maste }
3248f034231aSEd Maste
3249f3fbd1c0SDimitry Andric std::unique_lock<std::recursive_mutex> lock;
325014f1b3e8SDimitry Andric if (module_list_ptr != nullptr) {
325114f1b3e8SDimitry Andric lock =
325214f1b3e8SDimitry Andric std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex());
3253f3fbd1c0SDimitry Andric
3254f034231aSEd Maste num_modules = module_list_ptr->GetSize();
3255f034231aSEd Maste }
3256f034231aSEd Maste
325714f1b3e8SDimitry Andric if (num_modules > 0) {
325814f1b3e8SDimitry Andric for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
3259f034231aSEd Maste ModuleSP module_sp;
3260f034231aSEd Maste Module *module;
326114f1b3e8SDimitry Andric if (module_list_ptr) {
3262f034231aSEd Maste module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
3263f034231aSEd Maste module = module_sp.get();
326414f1b3e8SDimitry Andric } else {
3265f034231aSEd Maste module = Module::GetAllocatedModuleAtIndex(image_idx);
3266f034231aSEd Maste module_sp = module->shared_from_this();
3267f034231aSEd Maste }
3268f034231aSEd Maste
3269f034231aSEd Maste const size_t indent = strm.Printf("[%3u] ", image_idx);
3270f034231aSEd Maste PrintModule(target, module, indent, strm);
3271f034231aSEd Maste }
3272f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
327314f1b3e8SDimitry Andric } else {
327414f1b3e8SDimitry Andric if (argc) {
3275f034231aSEd Maste if (use_global_module_list)
327614f1b3e8SDimitry Andric result.AppendError(
327714f1b3e8SDimitry Andric "the global module list has no matching modules");
3278f034231aSEd Maste else
3279f034231aSEd Maste result.AppendError("the target has no matching modules");
328014f1b3e8SDimitry Andric } else {
3281f034231aSEd Maste if (use_global_module_list)
3282f034231aSEd Maste result.AppendError("the global module list is empty");
3283f034231aSEd Maste else
328414f1b3e8SDimitry Andric result.AppendError(
328514f1b3e8SDimitry Andric "the target has no associated executable images");
3286f034231aSEd Maste }
3287b1c73532SDimitry Andric return;
3288f034231aSEd Maste }
3289f034231aSEd Maste }
3290f034231aSEd Maste }
3291f034231aSEd Maste
PrintModule(Target * target,Module * module,int indent,Stream & strm)329214f1b3e8SDimitry Andric void PrintModule(Target *target, Module *module, int indent, Stream &strm) {
329314f1b3e8SDimitry Andric if (module == nullptr) {
3294f034231aSEd Maste strm.PutCString("Null module");
3295f034231aSEd Maste return;
3296f034231aSEd Maste }
3297f034231aSEd Maste
3298f034231aSEd Maste bool dump_object_name = false;
329914f1b3e8SDimitry Andric if (m_options.m_format_array.empty()) {
3300f034231aSEd Maste m_options.m_format_array.push_back(std::make_pair('u', 0));
3301f034231aSEd Maste m_options.m_format_array.push_back(std::make_pair('h', 0));
3302f034231aSEd Maste m_options.m_format_array.push_back(std::make_pair('f', 0));
3303f034231aSEd Maste m_options.m_format_array.push_back(std::make_pair('S', 0));
3304f034231aSEd Maste }
3305f034231aSEd Maste const size_t num_entries = m_options.m_format_array.size();
3306f034231aSEd Maste bool print_space = false;
330714f1b3e8SDimitry Andric for (size_t i = 0; i < num_entries; ++i) {
3308f034231aSEd Maste if (print_space)
3309f034231aSEd Maste strm.PutChar(' ');
3310f034231aSEd Maste print_space = true;
3311f034231aSEd Maste const char format_char = m_options.m_format_array[i].first;
3312f034231aSEd Maste uint32_t width = m_options.m_format_array[i].second;
331314f1b3e8SDimitry Andric switch (format_char) {
3314f034231aSEd Maste case 'A':
3315f034231aSEd Maste DumpModuleArchitecture(strm, module, false, width);
3316f034231aSEd Maste break;
3317f034231aSEd Maste
3318f034231aSEd Maste case 't':
3319f034231aSEd Maste DumpModuleArchitecture(strm, module, true, width);
3320f034231aSEd Maste break;
3321f034231aSEd Maste
3322f034231aSEd Maste case 'f':
3323f034231aSEd Maste DumpFullpath(strm, &module->GetFileSpec(), width);
3324f034231aSEd Maste dump_object_name = true;
3325f034231aSEd Maste break;
3326f034231aSEd Maste
3327f034231aSEd Maste case 'd':
3328f034231aSEd Maste DumpDirectory(strm, &module->GetFileSpec(), width);
3329f034231aSEd Maste break;
3330f034231aSEd Maste
3331f034231aSEd Maste case 'b':
3332f034231aSEd Maste DumpBasename(strm, &module->GetFileSpec(), width);
3333f034231aSEd Maste dump_object_name = true;
3334f034231aSEd Maste break;
3335f034231aSEd Maste
3336f034231aSEd Maste case 'h':
3337f034231aSEd Maste case 'o':
3338f034231aSEd Maste // Image header address
3339f034231aSEd Maste {
334014f1b3e8SDimitry Andric uint32_t addr_nibble_width =
334114f1b3e8SDimitry Andric target ? (target->GetArchitecture().GetAddressByteSize() * 2)
334214f1b3e8SDimitry Andric : 16;
3343f034231aSEd Maste
3344f034231aSEd Maste ObjectFile *objfile = module->GetObjectFile();
334514f1b3e8SDimitry Andric if (objfile) {
334694994d37SDimitry Andric Address base_addr(objfile->GetBaseAddress());
334794994d37SDimitry Andric if (base_addr.IsValid()) {
334814f1b3e8SDimitry Andric if (target && !target->GetSectionLoadList().IsEmpty()) {
3349706b4fc4SDimitry Andric lldb::addr_t load_addr = base_addr.GetLoadAddress(target);
335094994d37SDimitry Andric if (load_addr == LLDB_INVALID_ADDRESS) {
335194994d37SDimitry Andric base_addr.Dump(&strm, target,
335214f1b3e8SDimitry Andric Address::DumpStyleModuleWithFileAddress,
335314f1b3e8SDimitry Andric Address::DumpStyleFileAddress);
335414f1b3e8SDimitry Andric } else {
335514f1b3e8SDimitry Andric if (format_char == 'o') {
3356f034231aSEd Maste // Show the offset of slide for the image
3357706b4fc4SDimitry Andric strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3358706b4fc4SDimitry Andric addr_nibble_width,
335994994d37SDimitry Andric load_addr - base_addr.GetFileAddress());
336014f1b3e8SDimitry Andric } else {
3361f034231aSEd Maste // Show the load address of the image
336214f1b3e8SDimitry Andric strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
336394994d37SDimitry Andric addr_nibble_width, load_addr);
3364f034231aSEd Maste }
3365f034231aSEd Maste }
3366f034231aSEd Maste break;
3367f034231aSEd Maste }
336814f1b3e8SDimitry Andric // The address was valid, but the image isn't loaded, output the
336914f1b3e8SDimitry Andric // address in an appropriate format
337094994d37SDimitry Andric base_addr.Dump(&strm, target, Address::DumpStyleFileAddress);
3371f034231aSEd Maste break;
3372f034231aSEd Maste }
3373f034231aSEd Maste }
3374f034231aSEd Maste strm.Printf("%*s", addr_nibble_width + 2, "");
3375f034231aSEd Maste }
3376f034231aSEd Maste break;
3377f3fbd1c0SDimitry Andric
337814f1b3e8SDimitry Andric case 'r': {
3379f034231aSEd Maste size_t ref_count = 0;
3380ac9a064cSDimitry Andric char in_shared_cache = 'Y';
3381ac9a064cSDimitry Andric
3382f034231aSEd Maste ModuleSP module_sp(module->shared_from_this());
3383ac9a064cSDimitry Andric if (!ModuleList::ModuleIsInCache(module))
3384ac9a064cSDimitry Andric in_shared_cache = 'N';
338514f1b3e8SDimitry Andric if (module_sp) {
3386f034231aSEd Maste // Take one away to make sure we don't count our local "module_sp"
3387f034231aSEd Maste ref_count = module_sp.use_count() - 1;
3388f034231aSEd Maste }
3389f034231aSEd Maste if (width)
3390ac9a064cSDimitry Andric strm.Printf("{%c %*" PRIu64 "}", in_shared_cache, width, (uint64_t)ref_count);
3391f034231aSEd Maste else
3392ac9a064cSDimitry Andric strm.Printf("{%c %" PRIu64 "}", in_shared_cache, (uint64_t)ref_count);
339314f1b3e8SDimitry Andric } break;
3394f034231aSEd Maste
3395f034231aSEd Maste case 's':
339614f1b3e8SDimitry Andric case 'S': {
3397ead24645SDimitry Andric if (const SymbolFile *symbol_file = module->GetSymbolFile()) {
3398ead24645SDimitry Andric const FileSpec symfile_spec =
3399ead24645SDimitry Andric symbol_file->GetObjectFile()->GetFileSpec();
340014f1b3e8SDimitry Andric if (format_char == 'S') {
3401f034231aSEd Maste // Dump symbol file only if different from module file
340214f1b3e8SDimitry Andric if (!symfile_spec || symfile_spec == module->GetFileSpec()) {
3403f034231aSEd Maste print_space = false;
3404f034231aSEd Maste break;
3405f034231aSEd Maste }
3406f034231aSEd Maste // Add a newline and indent past the index
3407f034231aSEd Maste strm.Printf("\n%*s", indent, "");
3408f034231aSEd Maste }
34095e95aa85SEd Maste DumpFullpath(strm, &symfile_spec, width);
3410f034231aSEd Maste dump_object_name = true;
3411f034231aSEd Maste break;
3412f034231aSEd Maste }
3413f034231aSEd Maste strm.Printf("%.*s", width, "<NONE>");
341414f1b3e8SDimitry Andric } break;
3415f034231aSEd Maste
3416f034231aSEd Maste case 'm':
3417ef5d0b5eSDimitry Andric strm.Format("{0:%c}", llvm::fmt_align(module->GetModificationTime(),
3418ef5d0b5eSDimitry Andric llvm::AlignStyle::Left, width));
3419f034231aSEd Maste break;
3420f034231aSEd Maste
3421f034231aSEd Maste case 'p':
34220cac4ca3SEd Maste strm.Printf("%p", static_cast<void *>(module));
3423f034231aSEd Maste break;
3424f034231aSEd Maste
3425f034231aSEd Maste case 'u':
3426f034231aSEd Maste DumpModuleUUID(strm, module);
3427f034231aSEd Maste break;
3428f034231aSEd Maste
3429f034231aSEd Maste default:
3430f034231aSEd Maste break;
3431f034231aSEd Maste }
3432f034231aSEd Maste }
343314f1b3e8SDimitry Andric if (dump_object_name) {
3434f034231aSEd Maste const char *object_name = module->GetObjectName().GetCString();
3435f034231aSEd Maste if (object_name)
3436f034231aSEd Maste strm.Printf("(%s)", object_name);
3437f034231aSEd Maste }
3438f034231aSEd Maste strm.EOL();
3439f034231aSEd Maste }
3440f034231aSEd Maste
3441f034231aSEd Maste CommandOptions m_options;
3442f034231aSEd Maste };
3443f034231aSEd Maste
3444f034231aSEd Maste #pragma mark CommandObjectTargetModulesShowUnwind
3445f034231aSEd Maste
3446f034231aSEd Maste // Lookup unwind information in images
3447ead24645SDimitry Andric #define LLDB_OPTIONS_target_modules_show_unwind
3448ead24645SDimitry Andric #include "CommandOptions.inc"
344914f1b3e8SDimitry Andric
345014f1b3e8SDimitry Andric class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {
3451f034231aSEd Maste public:
345214f1b3e8SDimitry Andric enum {
3453f034231aSEd Maste eLookupTypeInvalid = -1,
3454f034231aSEd Maste eLookupTypeAddress = 0,
3455f034231aSEd Maste eLookupTypeSymbol,
3456f034231aSEd Maste eLookupTypeFunction,
3457f034231aSEd Maste eLookupTypeFunctionOrSymbol,
3458f034231aSEd Maste kNumLookupTypes
3459f034231aSEd Maste };
3460f034231aSEd Maste
346114f1b3e8SDimitry Andric class CommandOptions : public Options {
3462f034231aSEd Maste public:
3463145449b1SDimitry Andric CommandOptions() = default;
3464f034231aSEd Maste
3465f3fbd1c0SDimitry Andric ~CommandOptions() override = default;
3466f034231aSEd Maste
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)3467b76161e4SDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
346814f1b3e8SDimitry Andric ExecutionContext *execution_context) override {
3469b76161e4SDimitry Andric Status error;
3470f034231aSEd Maste
3471f034231aSEd Maste const int short_option = m_getopt_table[option_idx].val;
3472f034231aSEd Maste
347314f1b3e8SDimitry Andric switch (short_option) {
347414f1b3e8SDimitry Andric case 'a': {
3475cfca06d7SDimitry Andric m_str = std::string(option_arg);
3476f034231aSEd Maste m_type = eLookupTypeAddress;
3477f73363f1SDimitry Andric m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
347814f1b3e8SDimitry Andric LLDB_INVALID_ADDRESS, &error);
3479f034231aSEd Maste if (m_addr == LLDB_INVALID_ADDRESS)
348014f1b3e8SDimitry Andric error.SetErrorStringWithFormat("invalid address string '%s'",
348114f1b3e8SDimitry Andric option_arg.str().c_str());
3482f034231aSEd Maste break;
3483f034231aSEd Maste }
3484f034231aSEd Maste
3485f034231aSEd Maste case 'n':
3486cfca06d7SDimitry Andric m_str = std::string(option_arg);
3487f034231aSEd Maste m_type = eLookupTypeFunctionOrSymbol;
3488f034231aSEd Maste break;
3489f21a844fSEd Maste
3490f21a844fSEd Maste default:
3491ead24645SDimitry Andric llvm_unreachable("Unimplemented option");
3492f034231aSEd Maste }
3493f034231aSEd Maste
3494f034231aSEd Maste return error;
3495f034231aSEd Maste }
3496f034231aSEd Maste
OptionParsingStarting(ExecutionContext * execution_context)349714f1b3e8SDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override {
3498f034231aSEd Maste m_type = eLookupTypeInvalid;
3499f034231aSEd Maste m_str.clear();
3500f034231aSEd Maste m_addr = LLDB_INVALID_ADDRESS;
3501f034231aSEd Maste }
3502f034231aSEd Maste
GetDefinitions()350314f1b3e8SDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3504e3b55780SDimitry Andric return llvm::ArrayRef(g_target_modules_show_unwind_options);
3505f034231aSEd Maste }
3506f034231aSEd Maste
3507f034231aSEd Maste // Instance variables to hold the values for command options.
3508f034231aSEd Maste
3509344a3780SDimitry Andric int m_type = eLookupTypeInvalid; // Should be a eLookupTypeXXX enum after
3510344a3780SDimitry Andric // parsing options
3511f034231aSEd Maste std::string m_str; // Holds name lookup
3512344a3780SDimitry Andric lldb::addr_t m_addr = LLDB_INVALID_ADDRESS; // Holds the address to lookup
3513f034231aSEd Maste };
3514f034231aSEd Maste
CommandObjectTargetModulesShowUnwind(CommandInterpreter & interpreter)351514f1b3e8SDimitry Andric CommandObjectTargetModulesShowUnwind(CommandInterpreter &interpreter)
351614f1b3e8SDimitry Andric : CommandObjectParsed(
351714f1b3e8SDimitry Andric interpreter, "target modules show-unwind",
351814f1b3e8SDimitry Andric "Show synthesized unwind instructions for a function.", nullptr,
351914f1b3e8SDimitry Andric eCommandRequiresTarget | eCommandRequiresProcess |
35206f8fc217SDimitry Andric eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {}
3521f034231aSEd Maste
3522f3fbd1c0SDimitry Andric ~CommandObjectTargetModulesShowUnwind() override = default;
3523f034231aSEd Maste
GetOptions()352414f1b3e8SDimitry Andric Options *GetOptions() override { return &m_options; }
3525f034231aSEd Maste
3526f034231aSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)3527b1c73532SDimitry Andric void DoExecute(Args &command, CommandReturnObject &result) override {
3528f034231aSEd Maste Target *target = m_exe_ctx.GetTargetPtr();
3529f034231aSEd Maste Process *process = m_exe_ctx.GetProcessPtr();
3530f3fbd1c0SDimitry Andric ABI *abi = nullptr;
3531f034231aSEd Maste if (process)
3532f034231aSEd Maste abi = process->GetABI().get();
3533f034231aSEd Maste
353414f1b3e8SDimitry Andric if (process == nullptr) {
353514f1b3e8SDimitry Andric result.AppendError(
353614f1b3e8SDimitry Andric "You must have a process running to use this command.");
3537b1c73532SDimitry Andric return;
3538f034231aSEd Maste }
3539f034231aSEd Maste
3540f034231aSEd Maste ThreadList threads(process->GetThreadList());
354114f1b3e8SDimitry Andric if (threads.GetSize() == 0) {
3542f034231aSEd Maste result.AppendError("The process must be paused to use this command.");
3543b1c73532SDimitry Andric return;
3544f034231aSEd Maste }
3545f034231aSEd Maste
3546f034231aSEd Maste ThreadSP thread(threads.GetThreadAtIndex(0));
354714f1b3e8SDimitry Andric if (!thread) {
3548f034231aSEd Maste result.AppendError("The process must be paused to use this command.");
3549b1c73532SDimitry Andric return;
3550f034231aSEd Maste }
3551f034231aSEd Maste
3552f034231aSEd Maste SymbolContextList sc_list;
3553f034231aSEd Maste
355414f1b3e8SDimitry Andric if (m_options.m_type == eLookupTypeFunctionOrSymbol) {
3555f034231aSEd Maste ConstString function_name(m_options.m_str.c_str());
3556c0981da4SDimitry Andric ModuleFunctionSearchOptions function_options;
3557c0981da4SDimitry Andric function_options.include_symbols = true;
3558c0981da4SDimitry Andric function_options.include_inlines = false;
355914f1b3e8SDimitry Andric target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto,
3560c0981da4SDimitry Andric function_options, sc_list);
356114f1b3e8SDimitry Andric } else if (m_options.m_type == eLookupTypeAddress && target) {
3562f034231aSEd Maste Address addr;
356314f1b3e8SDimitry Andric if (target->GetSectionLoadList().ResolveLoadAddress(m_options.m_addr,
356414f1b3e8SDimitry Andric addr)) {
3565f034231aSEd Maste SymbolContext sc;
3566f034231aSEd Maste ModuleSP module_sp(addr.GetModule());
356714f1b3e8SDimitry Andric module_sp->ResolveSymbolContextForAddress(addr,
356814f1b3e8SDimitry Andric eSymbolContextEverything, sc);
356914f1b3e8SDimitry Andric if (sc.function || sc.symbol) {
3570f034231aSEd Maste sc_list.Append(sc);
3571f034231aSEd Maste }
3572f034231aSEd Maste }
357314f1b3e8SDimitry Andric } else {
357414f1b3e8SDimitry Andric result.AppendError(
357514f1b3e8SDimitry Andric "address-expression or function name option must be specified.");
3576b1c73532SDimitry Andric return;
3577f21a844fSEd Maste }
3578f034231aSEd Maste
35797fa27ce4SDimitry Andric if (sc_list.GetSize() == 0) {
358014f1b3e8SDimitry Andric result.AppendErrorWithFormat("no unwind data found that matches '%s'.",
358114f1b3e8SDimitry Andric m_options.m_str.c_str());
3582b1c73532SDimitry Andric return;
3583f21a844fSEd Maste }
3584f21a844fSEd Maste
35857fa27ce4SDimitry Andric for (const SymbolContext &sc : sc_list) {
3586f3fbd1c0SDimitry Andric if (sc.symbol == nullptr && sc.function == nullptr)
3587f034231aSEd Maste continue;
3588f3fbd1c0SDimitry Andric if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr)
3589f034231aSEd Maste continue;
3590f034231aSEd Maste AddressRange range;
359114f1b3e8SDimitry Andric if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,
359214f1b3e8SDimitry Andric false, range))
3593f034231aSEd Maste continue;
3594f034231aSEd Maste if (!range.GetBaseAddress().IsValid())
3595f034231aSEd Maste continue;
3596f034231aSEd Maste ConstString funcname(sc.GetFunctionName());
3597f034231aSEd Maste if (funcname.IsEmpty())
3598f034231aSEd Maste continue;
3599f034231aSEd Maste addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
3600f034231aSEd Maste if (abi)
3601f034231aSEd Maste start_addr = abi->FixCodeAddress(start_addr);
3602f034231aSEd Maste
360314f1b3e8SDimitry Andric FuncUnwindersSP func_unwinders_sp(
36045f29bb8aSDimitry Andric sc.module_sp->GetUnwindTable()
360514f1b3e8SDimitry Andric .GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
3606f3fbd1c0SDimitry Andric if (!func_unwinders_sp)
3607f034231aSEd Maste continue;
3608f034231aSEd Maste
360914f1b3e8SDimitry Andric result.GetOutputStream().Printf(
3610b60736ecSDimitry Andric "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n",
361114f1b3e8SDimitry Andric sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(),
361214f1b3e8SDimitry Andric funcname.AsCString(), start_addr);
3613f034231aSEd Maste
3614b60736ecSDimitry Andric Args args;
3615b60736ecSDimitry Andric target->GetUserSpecifiedTrapHandlerNames(args);
3616b60736ecSDimitry Andric size_t count = args.GetArgumentCount();
3617b60736ecSDimitry Andric for (size_t i = 0; i < count; i++) {
3618b60736ecSDimitry Andric const char *trap_func_name = args.GetArgumentAtIndex(i);
3619b60736ecSDimitry Andric if (strcmp(funcname.GetCString(), trap_func_name) == 0)
3620b60736ecSDimitry Andric result.GetOutputStream().Printf(
3621b60736ecSDimitry Andric "This function is "
3622b60736ecSDimitry Andric "treated as a trap handler function via user setting.\n");
3623b60736ecSDimitry Andric }
3624b60736ecSDimitry Andric PlatformSP platform_sp(target->GetPlatform());
3625b60736ecSDimitry Andric if (platform_sp) {
3626b60736ecSDimitry Andric const std::vector<ConstString> trap_handler_names(
3627b60736ecSDimitry Andric platform_sp->GetTrapHandlerSymbolNames());
3628b60736ecSDimitry Andric for (ConstString trap_name : trap_handler_names) {
3629b60736ecSDimitry Andric if (trap_name == funcname) {
3630b60736ecSDimitry Andric result.GetOutputStream().Printf(
3631b60736ecSDimitry Andric "This function's "
3632b60736ecSDimitry Andric "name is listed by the platform as a trap handler.\n");
3633b60736ecSDimitry Andric }
3634b60736ecSDimitry Andric }
3635b60736ecSDimitry Andric }
3636b60736ecSDimitry Andric
3637b60736ecSDimitry Andric result.GetOutputStream().Printf("\n");
3638b60736ecSDimitry Andric
363914f1b3e8SDimitry Andric UnwindPlanSP non_callsite_unwind_plan =
36405f29bb8aSDimitry Andric func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread);
364114f1b3e8SDimitry Andric if (non_callsite_unwind_plan) {
364214f1b3e8SDimitry Andric result.GetOutputStream().Printf(
364314f1b3e8SDimitry Andric "Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n",
364414f1b3e8SDimitry Andric non_callsite_unwind_plan->GetSourceName().AsCString());
3645f034231aSEd Maste }
364614f1b3e8SDimitry Andric UnwindPlanSP callsite_unwind_plan =
36475f29bb8aSDimitry Andric func_unwinders_sp->GetUnwindPlanAtCallSite(*target, *thread);
364814f1b3e8SDimitry Andric if (callsite_unwind_plan) {
364914f1b3e8SDimitry Andric result.GetOutputStream().Printf(
365014f1b3e8SDimitry Andric "Synchronous (restricted to call-sites) UnwindPlan is '%s'\n",
365114f1b3e8SDimitry Andric callsite_unwind_plan->GetSourceName().AsCString());
3652f034231aSEd Maste }
365314f1b3e8SDimitry Andric UnwindPlanSP fast_unwind_plan =
365414f1b3e8SDimitry Andric func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread);
365514f1b3e8SDimitry Andric if (fast_unwind_plan) {
365614f1b3e8SDimitry Andric result.GetOutputStream().Printf(
365714f1b3e8SDimitry Andric "Fast UnwindPlan is '%s'\n",
365814f1b3e8SDimitry Andric fast_unwind_plan->GetSourceName().AsCString());
3659205afe67SEd Maste }
3660205afe67SEd Maste
3661205afe67SEd Maste result.GetOutputStream().Printf("\n");
3662205afe67SEd Maste
366314f1b3e8SDimitry Andric UnwindPlanSP assembly_sp =
36645f29bb8aSDimitry Andric func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread);
366514f1b3e8SDimitry Andric if (assembly_sp) {
366614f1b3e8SDimitry Andric result.GetOutputStream().Printf(
366714f1b3e8SDimitry Andric "Assembly language inspection UnwindPlan:\n");
366814f1b3e8SDimitry Andric assembly_sp->Dump(result.GetOutputStream(), thread.get(),
366914f1b3e8SDimitry Andric LLDB_INVALID_ADDRESS);
3670205afe67SEd Maste result.GetOutputStream().Printf("\n");
3671205afe67SEd Maste }
3672205afe67SEd Maste
3673ead24645SDimitry Andric UnwindPlanSP of_unwind_sp =
3674ead24645SDimitry Andric func_unwinders_sp->GetObjectFileUnwindPlan(*target);
3675ead24645SDimitry Andric if (of_unwind_sp) {
3676ead24645SDimitry Andric result.GetOutputStream().Printf("object file UnwindPlan:\n");
3677ead24645SDimitry Andric of_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3678ead24645SDimitry Andric LLDB_INVALID_ADDRESS);
3679ead24645SDimitry Andric result.GetOutputStream().Printf("\n");
3680ead24645SDimitry Andric }
3681ead24645SDimitry Andric
3682ead24645SDimitry Andric UnwindPlanSP of_unwind_augmented_sp =
3683706b4fc4SDimitry Andric func_unwinders_sp->GetObjectFileAugmentedUnwindPlan(*target, *thread);
3684ead24645SDimitry Andric if (of_unwind_augmented_sp) {
3685ead24645SDimitry Andric result.GetOutputStream().Printf("object file augmented UnwindPlan:\n");
3686ead24645SDimitry Andric of_unwind_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
3687ead24645SDimitry Andric LLDB_INVALID_ADDRESS);
3688ead24645SDimitry Andric result.GetOutputStream().Printf("\n");
3689ead24645SDimitry Andric }
3690ead24645SDimitry Andric
369114f1b3e8SDimitry Andric UnwindPlanSP ehframe_sp =
36925f29bb8aSDimitry Andric func_unwinders_sp->GetEHFrameUnwindPlan(*target);
369314f1b3e8SDimitry Andric if (ehframe_sp) {
3694205afe67SEd Maste result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
369514f1b3e8SDimitry Andric ehframe_sp->Dump(result.GetOutputStream(), thread.get(),
369614f1b3e8SDimitry Andric LLDB_INVALID_ADDRESS);
3697205afe67SEd Maste result.GetOutputStream().Printf("\n");
3698205afe67SEd Maste }
3699205afe67SEd Maste
370014f1b3e8SDimitry Andric UnwindPlanSP ehframe_augmented_sp =
37015f29bb8aSDimitry Andric func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread);
370214f1b3e8SDimitry Andric if (ehframe_augmented_sp) {
3703205afe67SEd Maste result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
370414f1b3e8SDimitry Andric ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
370514f1b3e8SDimitry Andric LLDB_INVALID_ADDRESS);
3706205afe67SEd Maste result.GetOutputStream().Printf("\n");
3707205afe67SEd Maste }
3708205afe67SEd Maste
37091b306c26SDimitry Andric if (UnwindPlanSP plan_sp =
37105f29bb8aSDimitry Andric func_unwinders_sp->GetDebugFrameUnwindPlan(*target)) {
37111b306c26SDimitry Andric result.GetOutputStream().Printf("debug_frame UnwindPlan:\n");
37121b306c26SDimitry Andric plan_sp->Dump(result.GetOutputStream(), thread.get(),
37131b306c26SDimitry Andric LLDB_INVALID_ADDRESS);
37141b306c26SDimitry Andric result.GetOutputStream().Printf("\n");
37151b306c26SDimitry Andric }
37161b306c26SDimitry Andric
37171b306c26SDimitry Andric if (UnwindPlanSP plan_sp =
37181b306c26SDimitry Andric func_unwinders_sp->GetDebugFrameAugmentedUnwindPlan(*target,
37195f29bb8aSDimitry Andric *thread)) {
37201b306c26SDimitry Andric result.GetOutputStream().Printf("debug_frame augmented UnwindPlan:\n");
37211b306c26SDimitry Andric plan_sp->Dump(result.GetOutputStream(), thread.get(),
37221b306c26SDimitry Andric LLDB_INVALID_ADDRESS);
37231b306c26SDimitry Andric result.GetOutputStream().Printf("\n");
37241b306c26SDimitry Andric }
37251b306c26SDimitry Andric
372614f1b3e8SDimitry Andric UnwindPlanSP arm_unwind_sp =
37275f29bb8aSDimitry Andric func_unwinders_sp->GetArmUnwindUnwindPlan(*target);
372814f1b3e8SDimitry Andric if (arm_unwind_sp) {
3729e81d9d49SDimitry Andric result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
373014f1b3e8SDimitry Andric arm_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
373114f1b3e8SDimitry Andric LLDB_INVALID_ADDRESS);
3732e81d9d49SDimitry Andric result.GetOutputStream().Printf("\n");
3733e81d9d49SDimitry Andric }
3734e81d9d49SDimitry Andric
37355f29bb8aSDimitry Andric if (UnwindPlanSP symfile_plan_sp =
37365f29bb8aSDimitry Andric func_unwinders_sp->GetSymbolFileUnwindPlan(*thread)) {
37375f29bb8aSDimitry Andric result.GetOutputStream().Printf("Symbol file UnwindPlan:\n");
37385f29bb8aSDimitry Andric symfile_plan_sp->Dump(result.GetOutputStream(), thread.get(),
37395f29bb8aSDimitry Andric LLDB_INVALID_ADDRESS);
37405f29bb8aSDimitry Andric result.GetOutputStream().Printf("\n");
37415f29bb8aSDimitry Andric }
37425f29bb8aSDimitry Andric
374314f1b3e8SDimitry Andric UnwindPlanSP compact_unwind_sp =
37445f29bb8aSDimitry Andric func_unwinders_sp->GetCompactUnwindUnwindPlan(*target);
374514f1b3e8SDimitry Andric if (compact_unwind_sp) {
3746205afe67SEd Maste result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
374714f1b3e8SDimitry Andric compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
374814f1b3e8SDimitry Andric LLDB_INVALID_ADDRESS);
3749205afe67SEd Maste result.GetOutputStream().Printf("\n");
3750205afe67SEd Maste }
3751205afe67SEd Maste
375214f1b3e8SDimitry Andric if (fast_unwind_plan) {
3753205afe67SEd Maste result.GetOutputStream().Printf("Fast UnwindPlan:\n");
375414f1b3e8SDimitry Andric fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(),
375514f1b3e8SDimitry Andric LLDB_INVALID_ADDRESS);
3756f034231aSEd Maste result.GetOutputStream().Printf("\n");
3757f034231aSEd Maste }
3758f034231aSEd Maste
3759205afe67SEd Maste ABISP abi_sp = process->GetABI();
376014f1b3e8SDimitry Andric if (abi_sp) {
3761205afe67SEd Maste UnwindPlan arch_default(lldb::eRegisterKindGeneric);
376214f1b3e8SDimitry Andric if (abi_sp->CreateDefaultUnwindPlan(arch_default)) {
3763205afe67SEd Maste result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
376414f1b3e8SDimitry Andric arch_default.Dump(result.GetOutputStream(), thread.get(),
376514f1b3e8SDimitry Andric LLDB_INVALID_ADDRESS);
3766205afe67SEd Maste result.GetOutputStream().Printf("\n");
3767205afe67SEd Maste }
3768205afe67SEd Maste
3769205afe67SEd Maste UnwindPlan arch_entry(lldb::eRegisterKindGeneric);
377014f1b3e8SDimitry Andric if (abi_sp->CreateFunctionEntryUnwindPlan(arch_entry)) {
377114f1b3e8SDimitry Andric result.GetOutputStream().Printf(
377214f1b3e8SDimitry Andric "Arch default at entry point UnwindPlan:\n");
377314f1b3e8SDimitry Andric arch_entry.Dump(result.GetOutputStream(), thread.get(),
377414f1b3e8SDimitry Andric LLDB_INVALID_ADDRESS);
3775205afe67SEd Maste result.GetOutputStream().Printf("\n");
3776205afe67SEd Maste }
3777205afe67SEd Maste }
3778f034231aSEd Maste
3779f034231aSEd Maste result.GetOutputStream().Printf("\n");
3780f034231aSEd Maste }
3781f034231aSEd Maste }
3782f034231aSEd Maste
3783f034231aSEd Maste CommandOptions m_options;
3784f034231aSEd Maste };
3785f034231aSEd Maste
3786f034231aSEd Maste // Lookup information in images
3787ead24645SDimitry Andric #define LLDB_OPTIONS_target_modules_lookup
3788ead24645SDimitry Andric #include "CommandOptions.inc"
378914f1b3e8SDimitry Andric
379014f1b3e8SDimitry Andric class CommandObjectTargetModulesLookup : public CommandObjectParsed {
3791f034231aSEd Maste public:
379214f1b3e8SDimitry Andric enum {
3793f034231aSEd Maste eLookupTypeInvalid = -1,
3794f034231aSEd Maste eLookupTypeAddress = 0,
3795f034231aSEd Maste eLookupTypeSymbol,
3796f034231aSEd Maste eLookupTypeFileLine, // Line is optional
3797f034231aSEd Maste eLookupTypeFunction,
3798f034231aSEd Maste eLookupTypeFunctionOrSymbol,
3799f034231aSEd Maste eLookupTypeType,
3800f034231aSEd Maste kNumLookupTypes
3801f034231aSEd Maste };
3802f034231aSEd Maste
380314f1b3e8SDimitry Andric class CommandOptions : public Options {
3804f034231aSEd Maste public:
CommandOptions()38056f8fc217SDimitry Andric CommandOptions() { OptionParsingStarting(nullptr); }
3806f034231aSEd Maste
3807f3fbd1c0SDimitry Andric ~CommandOptions() override = default;
3808f034231aSEd Maste
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)3809b76161e4SDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
381014f1b3e8SDimitry Andric ExecutionContext *execution_context) override {
3811b76161e4SDimitry Andric Status error;
3812f034231aSEd Maste
3813f034231aSEd Maste const int short_option = m_getopt_table[option_idx].val;
3814f034231aSEd Maste
381514f1b3e8SDimitry Andric switch (short_option) {
381614f1b3e8SDimitry Andric case 'a': {
3817f034231aSEd Maste m_type = eLookupTypeAddress;
3818f73363f1SDimitry Andric m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
381914f1b3e8SDimitry Andric LLDB_INVALID_ADDRESS, &error);
382014f1b3e8SDimitry Andric } break;
3821f034231aSEd Maste
3822f034231aSEd Maste case 'o':
382314f1b3e8SDimitry Andric if (option_arg.getAsInteger(0, m_offset))
382414f1b3e8SDimitry Andric error.SetErrorStringWithFormat("invalid offset string '%s'",
382514f1b3e8SDimitry Andric option_arg.str().c_str());
3826f034231aSEd Maste break;
3827f034231aSEd Maste
3828f034231aSEd Maste case 's':
3829cfca06d7SDimitry Andric m_str = std::string(option_arg);
3830f034231aSEd Maste m_type = eLookupTypeSymbol;
3831f034231aSEd Maste break;
3832f034231aSEd Maste
3833f034231aSEd Maste case 'f':
383494994d37SDimitry Andric m_file.SetFile(option_arg, FileSpec::Style::native);
3835f034231aSEd Maste m_type = eLookupTypeFileLine;
3836f034231aSEd Maste break;
3837f034231aSEd Maste
3838f034231aSEd Maste case 'i':
3839f034231aSEd Maste m_include_inlines = false;
3840f034231aSEd Maste break;
3841f034231aSEd Maste
3842f034231aSEd Maste case 'l':
384314f1b3e8SDimitry Andric if (option_arg.getAsInteger(0, m_line_number))
384414f1b3e8SDimitry Andric error.SetErrorStringWithFormat("invalid line number string '%s'",
384514f1b3e8SDimitry Andric option_arg.str().c_str());
3846f034231aSEd Maste else if (m_line_number == 0)
3847f034231aSEd Maste error.SetErrorString("zero is an invalid line number");
3848f034231aSEd Maste m_type = eLookupTypeFileLine;
3849f034231aSEd Maste break;
3850f034231aSEd Maste
3851f034231aSEd Maste case 'F':
3852cfca06d7SDimitry Andric m_str = std::string(option_arg);
3853f034231aSEd Maste m_type = eLookupTypeFunction;
3854f034231aSEd Maste break;
3855f034231aSEd Maste
3856f034231aSEd Maste case 'n':
3857cfca06d7SDimitry Andric m_str = std::string(option_arg);
3858f034231aSEd Maste m_type = eLookupTypeFunctionOrSymbol;
3859f034231aSEd Maste break;
3860f034231aSEd Maste
3861f034231aSEd Maste case 't':
3862cfca06d7SDimitry Andric m_str = std::string(option_arg);
3863f034231aSEd Maste m_type = eLookupTypeType;
3864f034231aSEd Maste break;
3865f034231aSEd Maste
3866f034231aSEd Maste case 'v':
38675f29bb8aSDimitry Andric m_verbose = true;
3868f034231aSEd Maste break;
3869f034231aSEd Maste
3870f034231aSEd Maste case 'A':
3871f034231aSEd Maste m_print_all = true;
3872f034231aSEd Maste break;
3873f034231aSEd Maste
3874f034231aSEd Maste case 'r':
3875f034231aSEd Maste m_use_regex = true;
3876f034231aSEd Maste break;
3877145449b1SDimitry Andric
3878145449b1SDimitry Andric case '\x01':
3879145449b1SDimitry Andric m_all_ranges = true;
3880145449b1SDimitry Andric break;
3881ead24645SDimitry Andric default:
3882ead24645SDimitry Andric llvm_unreachable("Unimplemented option");
3883f034231aSEd Maste }
3884f034231aSEd Maste
3885f034231aSEd Maste return error;
3886f034231aSEd Maste }
3887f034231aSEd Maste
OptionParsingStarting(ExecutionContext * execution_context)388814f1b3e8SDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override {
3889f034231aSEd Maste m_type = eLookupTypeInvalid;
3890f034231aSEd Maste m_str.clear();
3891f034231aSEd Maste m_file.Clear();
3892f034231aSEd Maste m_addr = LLDB_INVALID_ADDRESS;
3893f034231aSEd Maste m_offset = 0;
3894f034231aSEd Maste m_line_number = 0;
3895f034231aSEd Maste m_use_regex = false;
3896f034231aSEd Maste m_include_inlines = true;
3897145449b1SDimitry Andric m_all_ranges = false;
3898f034231aSEd Maste m_verbose = false;
3899f034231aSEd Maste m_print_all = false;
3900f034231aSEd Maste }
3901f034231aSEd Maste
OptionParsingFinished(ExecutionContext * execution_context)3902145449b1SDimitry Andric Status OptionParsingFinished(ExecutionContext *execution_context) override {
3903145449b1SDimitry Andric Status status;
3904145449b1SDimitry Andric if (m_all_ranges && !m_verbose) {
3905145449b1SDimitry Andric status.SetErrorString("--show-variable-ranges must be used in "
3906145449b1SDimitry Andric "conjunction with --verbose.");
3907145449b1SDimitry Andric }
3908145449b1SDimitry Andric return status;
3909145449b1SDimitry Andric }
3910145449b1SDimitry Andric
GetDefinitions()391114f1b3e8SDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3912e3b55780SDimitry Andric return llvm::ArrayRef(g_target_modules_lookup_options);
3913f034231aSEd Maste }
3914f034231aSEd Maste
3915f034231aSEd Maste int m_type; // Should be a eLookupTypeXXX enum after parsing options
3916f034231aSEd Maste std::string m_str; // Holds name lookup
3917f034231aSEd Maste FileSpec m_file; // Files for file lookups
3918f034231aSEd Maste lldb::addr_t m_addr; // Holds the address to lookup
391914f1b3e8SDimitry Andric lldb::addr_t
392014f1b3e8SDimitry Andric m_offset; // Subtract this offset from m_addr before doing lookups.
3921f034231aSEd Maste uint32_t m_line_number; // Line number for file+line lookups
3922f034231aSEd Maste bool m_use_regex; // Name lookups in m_str are regular expressions.
392314f1b3e8SDimitry Andric bool m_include_inlines; // Check for inline entries when looking up by
392414f1b3e8SDimitry Andric // file/line.
3925145449b1SDimitry Andric bool m_all_ranges; // Print all ranges or single range.
3926f034231aSEd Maste bool m_verbose; // Enable verbose lookup info
392714f1b3e8SDimitry Andric bool m_print_all; // Print all matches, even in cases where there's a best
392814f1b3e8SDimitry Andric // match.
3929f034231aSEd Maste };
3930f034231aSEd Maste
CommandObjectTargetModulesLookup(CommandInterpreter & interpreter)393114f1b3e8SDimitry Andric CommandObjectTargetModulesLookup(CommandInterpreter &interpreter)
393214f1b3e8SDimitry Andric : CommandObjectParsed(interpreter, "target modules lookup",
393314f1b3e8SDimitry Andric "Look up information within executable and "
393414f1b3e8SDimitry Andric "dependent shared library images.",
39356f8fc217SDimitry Andric nullptr, eCommandRequiresTarget) {
3936ac9a064cSDimitry Andric AddSimpleArgumentList(eArgTypeFilename, eArgRepeatStar);
3937f034231aSEd Maste }
3938f034231aSEd Maste
3939f3fbd1c0SDimitry Andric ~CommandObjectTargetModulesLookup() override = default;
3940f034231aSEd Maste
GetOptions()394114f1b3e8SDimitry Andric Options *GetOptions() override { return &m_options; }
3942f034231aSEd Maste
LookupHere(CommandInterpreter & interpreter,CommandReturnObject & result,bool & syntax_error)394314f1b3e8SDimitry Andric bool LookupHere(CommandInterpreter &interpreter, CommandReturnObject &result,
394414f1b3e8SDimitry Andric bool &syntax_error) {
394514f1b3e8SDimitry Andric switch (m_options.m_type) {
3946f034231aSEd Maste case eLookupTypeAddress:
3947f034231aSEd Maste case eLookupTypeFileLine:
3948f034231aSEd Maste case eLookupTypeFunction:
3949f034231aSEd Maste case eLookupTypeFunctionOrSymbol:
3950f034231aSEd Maste case eLookupTypeSymbol:
3951f034231aSEd Maste default:
3952f034231aSEd Maste return false;
3953f034231aSEd Maste case eLookupTypeType:
3954f034231aSEd Maste break;
3955f034231aSEd Maste }
3956f034231aSEd Maste
3957f034231aSEd Maste StackFrameSP frame = m_exe_ctx.GetFrameSP();
3958f034231aSEd Maste
3959f034231aSEd Maste if (!frame)
3960f034231aSEd Maste return false;
3961f034231aSEd Maste
3962f034231aSEd Maste const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
3963f034231aSEd Maste
3964f034231aSEd Maste if (!sym_ctx.module_sp)
3965f034231aSEd Maste return false;
3966f034231aSEd Maste
396714f1b3e8SDimitry Andric switch (m_options.m_type) {
3968f034231aSEd Maste default:
3969f034231aSEd Maste return false;
3970f034231aSEd Maste case eLookupTypeType:
397114f1b3e8SDimitry Andric if (!m_options.m_str.empty()) {
3972b60736ecSDimitry Andric if (LookupTypeHere(&GetSelectedTarget(), m_interpreter,
3973b60736ecSDimitry Andric result.GetOutputStream(), *sym_ctx.module_sp,
3974b60736ecSDimitry Andric m_options.m_str.c_str(), m_options.m_use_regex)) {
3975f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
3976f034231aSEd Maste return true;
3977f034231aSEd Maste }
3978f034231aSEd Maste }
3979f034231aSEd Maste break;
3980f034231aSEd Maste }
3981f034231aSEd Maste
3982706b4fc4SDimitry Andric return false;
3983f034231aSEd Maste }
3984f034231aSEd Maste
LookupInModule(CommandInterpreter & interpreter,Module * module,CommandReturnObject & result,bool & syntax_error)398514f1b3e8SDimitry Andric bool LookupInModule(CommandInterpreter &interpreter, Module *module,
398614f1b3e8SDimitry Andric CommandReturnObject &result, bool &syntax_error) {
398714f1b3e8SDimitry Andric switch (m_options.m_type) {
3988f034231aSEd Maste case eLookupTypeAddress:
398914f1b3e8SDimitry Andric if (m_options.m_addr != LLDB_INVALID_ADDRESS) {
399014f1b3e8SDimitry Andric if (LookupAddressInModule(
399114f1b3e8SDimitry Andric m_interpreter, result.GetOutputStream(), module,
399214f1b3e8SDimitry Andric eSymbolContextEverything |
399314f1b3e8SDimitry Andric (m_options.m_verbose
399414f1b3e8SDimitry Andric ? static_cast<int>(eSymbolContextVariable)
399514f1b3e8SDimitry Andric : 0),
3996145449b1SDimitry Andric m_options.m_addr, m_options.m_offset, m_options.m_verbose,
3997145449b1SDimitry Andric m_options.m_all_ranges)) {
3998f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
3999f034231aSEd Maste return true;
4000f034231aSEd Maste }
4001f034231aSEd Maste }
4002f034231aSEd Maste break;
4003f034231aSEd Maste
4004f034231aSEd Maste case eLookupTypeSymbol:
400514f1b3e8SDimitry Andric if (!m_options.m_str.empty()) {
400614f1b3e8SDimitry Andric if (LookupSymbolInModule(m_interpreter, result.GetOutputStream(),
400714f1b3e8SDimitry Andric module, m_options.m_str.c_str(),
4008145449b1SDimitry Andric m_options.m_use_regex, m_options.m_verbose,
4009145449b1SDimitry Andric m_options.m_all_ranges)) {
4010f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
4011f034231aSEd Maste return true;
4012f034231aSEd Maste }
4013f034231aSEd Maste }
4014f034231aSEd Maste break;
4015f034231aSEd Maste
4016f034231aSEd Maste case eLookupTypeFileLine:
401714f1b3e8SDimitry Andric if (m_options.m_file) {
401814f1b3e8SDimitry Andric if (LookupFileAndLineInModule(
401914f1b3e8SDimitry Andric m_interpreter, result.GetOutputStream(), module,
402014f1b3e8SDimitry Andric m_options.m_file, m_options.m_line_number,
4021145449b1SDimitry Andric m_options.m_include_inlines, m_options.m_verbose,
4022145449b1SDimitry Andric m_options.m_all_ranges)) {
4023f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
4024f034231aSEd Maste return true;
4025f034231aSEd Maste }
4026f034231aSEd Maste }
4027f034231aSEd Maste break;
4028f034231aSEd Maste
4029f034231aSEd Maste case eLookupTypeFunctionOrSymbol:
4030f034231aSEd Maste case eLookupTypeFunction:
403114f1b3e8SDimitry Andric if (!m_options.m_str.empty()) {
4032c0981da4SDimitry Andric ModuleFunctionSearchOptions function_options;
4033c0981da4SDimitry Andric function_options.include_symbols =
4034c0981da4SDimitry Andric m_options.m_type == eLookupTypeFunctionOrSymbol;
4035c0981da4SDimitry Andric function_options.include_inlines = m_options.m_include_inlines;
4036c0981da4SDimitry Andric
4037c0981da4SDimitry Andric if (LookupFunctionInModule(m_interpreter, result.GetOutputStream(),
4038c0981da4SDimitry Andric module, m_options.m_str.c_str(),
4039c0981da4SDimitry Andric m_options.m_use_regex, function_options,
4040145449b1SDimitry Andric m_options.m_verbose,
4041145449b1SDimitry Andric m_options.m_all_ranges)) {
4042f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
4043f034231aSEd Maste return true;
4044f034231aSEd Maste }
4045f034231aSEd Maste }
4046f034231aSEd Maste break;
4047f034231aSEd Maste
4048f034231aSEd Maste case eLookupTypeType:
404914f1b3e8SDimitry Andric if (!m_options.m_str.empty()) {
4050b60736ecSDimitry Andric if (LookupTypeInModule(
4051b60736ecSDimitry Andric &GetSelectedTarget(), m_interpreter, result.GetOutputStream(),
4052b60736ecSDimitry Andric module, m_options.m_str.c_str(), m_options.m_use_regex)) {
4053f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
4054f034231aSEd Maste return true;
4055f034231aSEd Maste }
4056f034231aSEd Maste }
4057f034231aSEd Maste break;
4058f034231aSEd Maste
4059f034231aSEd Maste default:
406014f1b3e8SDimitry Andric m_options.GenerateOptionUsage(
4061145449b1SDimitry Andric result.GetErrorStream(), *this,
406214f1b3e8SDimitry Andric GetCommandInterpreter().GetDebugger().GetTerminalWidth());
4063f034231aSEd Maste syntax_error = true;
4064f034231aSEd Maste break;
4065f034231aSEd Maste }
4066f034231aSEd Maste
4067f034231aSEd Maste result.SetStatus(eReturnStatusFailed);
4068f034231aSEd Maste return false;
4069f034231aSEd Maste }
4070f034231aSEd Maste
4071f034231aSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)4072b1c73532SDimitry Andric void DoExecute(Args &command, CommandReturnObject &result) override {
4073ead24645SDimitry Andric Target *target = &GetSelectedTarget();
4074f034231aSEd Maste bool syntax_error = false;
4075f034231aSEd Maste uint32_t i;
4076f034231aSEd Maste uint32_t num_successful_lookups = 0;
4077f034231aSEd Maste uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
4078f034231aSEd Maste result.GetOutputStream().SetAddressByteSize(addr_byte_size);
4079f034231aSEd Maste result.GetErrorStream().SetAddressByteSize(addr_byte_size);
4080f034231aSEd Maste // Dump all sections for all modules images
4081f034231aSEd Maste
408214f1b3e8SDimitry Andric if (command.GetArgumentCount() == 0) {
4083f034231aSEd Maste ModuleSP current_module;
4084f034231aSEd Maste
4085f73363f1SDimitry Andric // Where it is possible to look in the current symbol context first,
4086f73363f1SDimitry Andric // try that. If this search was successful and --all was not passed,
4087f73363f1SDimitry Andric // don't print anything else.
408814f1b3e8SDimitry Andric if (LookupHere(m_interpreter, result, syntax_error)) {
4089f034231aSEd Maste result.GetOutputStream().EOL();
4090f034231aSEd Maste num_successful_lookups++;
409114f1b3e8SDimitry Andric if (!m_options.m_print_all) {
4092f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
4093b1c73532SDimitry Andric return;
4094f034231aSEd Maste }
4095f034231aSEd Maste }
4096f034231aSEd Maste
4097f034231aSEd Maste // Dump all sections for all other modules
4098f034231aSEd Maste
4099f034231aSEd Maste const ModuleList &target_modules = target->GetImages();
4100f3fbd1c0SDimitry Andric std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
4101b60736ecSDimitry Andric if (target_modules.GetSize() == 0) {
4102f034231aSEd Maste result.AppendError("the target has no associated executable images");
4103b1c73532SDimitry Andric return;
4104f034231aSEd Maste }
4105b60736ecSDimitry Andric
4106b60736ecSDimitry Andric for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
4107b60736ecSDimitry Andric if (module_sp != current_module &&
4108b60736ecSDimitry Andric LookupInModule(m_interpreter, module_sp.get(), result,
4109b60736ecSDimitry Andric syntax_error)) {
4110b60736ecSDimitry Andric result.GetOutputStream().EOL();
4111b60736ecSDimitry Andric num_successful_lookups++;
4112b60736ecSDimitry Andric }
4113b60736ecSDimitry Andric }
411414f1b3e8SDimitry Andric } else {
4115f034231aSEd Maste // Dump specified images (by basename or fullpath)
4116f034231aSEd Maste const char *arg_cstr;
411714f1b3e8SDimitry Andric for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr &&
411814f1b3e8SDimitry Andric !syntax_error;
411914f1b3e8SDimitry Andric ++i) {
4120f034231aSEd Maste ModuleList module_list;
412114f1b3e8SDimitry Andric const size_t num_matches =
412214f1b3e8SDimitry Andric FindModulesByName(target, arg_cstr, module_list, false);
412314f1b3e8SDimitry Andric if (num_matches > 0) {
412414f1b3e8SDimitry Andric for (size_t j = 0; j < num_matches; ++j) {
4125f034231aSEd Maste Module *module = module_list.GetModulePointerAtIndex(j);
412614f1b3e8SDimitry Andric if (module) {
4127ead24645SDimitry Andric if (LookupInModule(m_interpreter, module, result, syntax_error)) {
4128f034231aSEd Maste result.GetOutputStream().EOL();
4129f034231aSEd Maste num_successful_lookups++;
4130f034231aSEd Maste }
4131f034231aSEd Maste }
4132f034231aSEd Maste }
413314f1b3e8SDimitry Andric } else
413414f1b3e8SDimitry Andric result.AppendWarningWithFormat(
413514f1b3e8SDimitry Andric "Unable to find an image that matches '%s'.\n", arg_cstr);
4136f034231aSEd Maste }
4137f034231aSEd Maste }
4138f034231aSEd Maste
4139f034231aSEd Maste if (num_successful_lookups > 0)
4140f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
4141f034231aSEd Maste else
4142f034231aSEd Maste result.SetStatus(eReturnStatusFailed);
4143f034231aSEd Maste }
4144f034231aSEd Maste
4145f034231aSEd Maste CommandOptions m_options;
4146f034231aSEd Maste };
4147f034231aSEd Maste
4148f034231aSEd Maste #pragma mark CommandObjectMultiwordImageSearchPaths
4149f034231aSEd Maste
4150f034231aSEd Maste // CommandObjectMultiwordImageSearchPaths
4151f034231aSEd Maste
415214f1b3e8SDimitry Andric class CommandObjectTargetModulesImageSearchPaths
415314f1b3e8SDimitry Andric : public CommandObjectMultiword {
4154f034231aSEd Maste public:
CommandObjectTargetModulesImageSearchPaths(CommandInterpreter & interpreter)4155f3fbd1c0SDimitry Andric CommandObjectTargetModulesImageSearchPaths(CommandInterpreter &interpreter)
415614f1b3e8SDimitry Andric : CommandObjectMultiword(
415714f1b3e8SDimitry Andric interpreter, "target modules search-paths",
4158f3fbd1c0SDimitry Andric "Commands for managing module search paths for a target.",
415914f1b3e8SDimitry Andric "target modules search-paths <subcommand> [<subcommand-options>]") {
416014f1b3e8SDimitry Andric LoadSubCommand(
416114f1b3e8SDimitry Andric "add", CommandObjectSP(
416214f1b3e8SDimitry Andric new CommandObjectTargetModulesSearchPathsAdd(interpreter)));
416314f1b3e8SDimitry Andric LoadSubCommand(
416414f1b3e8SDimitry Andric "clear", CommandObjectSP(new CommandObjectTargetModulesSearchPathsClear(
416514f1b3e8SDimitry Andric interpreter)));
416614f1b3e8SDimitry Andric LoadSubCommand(
416714f1b3e8SDimitry Andric "insert",
416814f1b3e8SDimitry Andric CommandObjectSP(
416914f1b3e8SDimitry Andric new CommandObjectTargetModulesSearchPathsInsert(interpreter)));
417014f1b3e8SDimitry Andric LoadSubCommand(
417114f1b3e8SDimitry Andric "list", CommandObjectSP(new CommandObjectTargetModulesSearchPathsList(
417214f1b3e8SDimitry Andric interpreter)));
417314f1b3e8SDimitry Andric LoadSubCommand(
417414f1b3e8SDimitry Andric "query", CommandObjectSP(new CommandObjectTargetModulesSearchPathsQuery(
417514f1b3e8SDimitry Andric interpreter)));
4176f034231aSEd Maste }
4177f034231aSEd Maste
4178f3fbd1c0SDimitry Andric ~CommandObjectTargetModulesImageSearchPaths() override = default;
4179f034231aSEd Maste };
4180f034231aSEd Maste
4181f034231aSEd Maste #pragma mark CommandObjectTargetModules
4182f034231aSEd Maste
4183f034231aSEd Maste // CommandObjectTargetModules
4184f034231aSEd Maste
418514f1b3e8SDimitry Andric class CommandObjectTargetModules : public CommandObjectMultiword {
4186f034231aSEd Maste public:
4187f034231aSEd Maste // Constructors and Destructors
CommandObjectTargetModules(CommandInterpreter & interpreter)4188f3fbd1c0SDimitry Andric CommandObjectTargetModules(CommandInterpreter &interpreter)
4189f3fbd1c0SDimitry Andric : CommandObjectMultiword(interpreter, "target modules",
419014f1b3e8SDimitry Andric "Commands for accessing information for one or "
419114f1b3e8SDimitry Andric "more target modules.",
419214f1b3e8SDimitry Andric "target modules <sub-command> ...") {
419314f1b3e8SDimitry Andric LoadSubCommand(
419414f1b3e8SDimitry Andric "add", CommandObjectSP(new CommandObjectTargetModulesAdd(interpreter)));
419514f1b3e8SDimitry Andric LoadSubCommand("load", CommandObjectSP(new CommandObjectTargetModulesLoad(
419614f1b3e8SDimitry Andric interpreter)));
419714f1b3e8SDimitry Andric LoadSubCommand("dump", CommandObjectSP(new CommandObjectTargetModulesDump(
419814f1b3e8SDimitry Andric interpreter)));
419914f1b3e8SDimitry Andric LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetModulesList(
420014f1b3e8SDimitry Andric interpreter)));
420114f1b3e8SDimitry Andric LoadSubCommand(
420214f1b3e8SDimitry Andric "lookup",
420314f1b3e8SDimitry Andric CommandObjectSP(new CommandObjectTargetModulesLookup(interpreter)));
420414f1b3e8SDimitry Andric LoadSubCommand(
420514f1b3e8SDimitry Andric "search-paths",
420614f1b3e8SDimitry Andric CommandObjectSP(
420714f1b3e8SDimitry Andric new CommandObjectTargetModulesImageSearchPaths(interpreter)));
420814f1b3e8SDimitry Andric LoadSubCommand(
420914f1b3e8SDimitry Andric "show-unwind",
421014f1b3e8SDimitry Andric CommandObjectSP(new CommandObjectTargetModulesShowUnwind(interpreter)));
4211f034231aSEd Maste }
4212e81d9d49SDimitry Andric
4213f3fbd1c0SDimitry Andric ~CommandObjectTargetModules() override = default;
4214f034231aSEd Maste
4215f034231aSEd Maste private:
4216f034231aSEd Maste // For CommandObjectTargetModules only
4217cfca06d7SDimitry Andric CommandObjectTargetModules(const CommandObjectTargetModules &) = delete;
4218cfca06d7SDimitry Andric const CommandObjectTargetModules &
4219cfca06d7SDimitry Andric operator=(const CommandObjectTargetModules &) = delete;
4220f034231aSEd Maste };
4221f034231aSEd Maste
422214f1b3e8SDimitry Andric class CommandObjectTargetSymbolsAdd : public CommandObjectParsed {
4223f034231aSEd Maste public:
CommandObjectTargetSymbolsAdd(CommandInterpreter & interpreter)422414f1b3e8SDimitry Andric CommandObjectTargetSymbolsAdd(CommandInterpreter &interpreter)
422514f1b3e8SDimitry Andric : CommandObjectParsed(
422614f1b3e8SDimitry Andric interpreter, "target symbols add",
422714f1b3e8SDimitry Andric "Add a debug symbol file to one of the target's current modules by "
4228cfca06d7SDimitry Andric "specifying a path to a debug symbols file or by using the options "
4229cfca06d7SDimitry Andric "to specify a module.",
4230ef5d0b5eSDimitry Andric "target symbols add <cmd-options> [<symfile>]",
4231ef5d0b5eSDimitry Andric eCommandRequiresTarget),
423214f1b3e8SDimitry Andric m_file_option(
42337fa27ce4SDimitry Andric LLDB_OPT_SET_1, false, "shlib", 's', lldb::eModuleCompletion,
42347fa27ce4SDimitry Andric eArgTypeShlibName,
4235cfca06d7SDimitry Andric "Locate the debug symbols for the shared library specified by "
4236cfca06d7SDimitry Andric "name."),
423714f1b3e8SDimitry Andric m_current_frame_option(
423814f1b3e8SDimitry Andric LLDB_OPT_SET_2, false, "frame", 'F',
4239c0981da4SDimitry Andric "Locate the debug symbols for the currently selected frame.", false,
4240c0981da4SDimitry Andric true),
4241c0981da4SDimitry Andric m_current_stack_option(LLDB_OPT_SET_2, false, "stack", 'S',
4242c0981da4SDimitry Andric "Locate the debug symbols for every frame in "
4243c0981da4SDimitry Andric "the current call stack.",
4244cfca06d7SDimitry Andric false, true)
4245f034231aSEd Maste
4246f034231aSEd Maste {
424714f1b3e8SDimitry Andric m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
424814f1b3e8SDimitry Andric LLDB_OPT_SET_1);
4249f034231aSEd Maste m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
425014f1b3e8SDimitry Andric m_option_group.Append(&m_current_frame_option, LLDB_OPT_SET_2,
425114f1b3e8SDimitry Andric LLDB_OPT_SET_2);
4252c0981da4SDimitry Andric m_option_group.Append(&m_current_stack_option, LLDB_OPT_SET_2,
4253c0981da4SDimitry Andric LLDB_OPT_SET_2);
4254f034231aSEd Maste m_option_group.Finalize();
4255ac9a064cSDimitry Andric AddSimpleArgumentList(eArgTypeFilename);
4256f034231aSEd Maste }
4257f034231aSEd Maste
4258f3fbd1c0SDimitry Andric ~CommandObjectTargetSymbolsAdd() override = default;
4259f034231aSEd Maste
GetOptions()426014f1b3e8SDimitry Andric Options *GetOptions() override { return &m_option_group; }
4261f034231aSEd Maste
4262f034231aSEd Maste protected:
AddModuleSymbols(Target * target,ModuleSpec & module_spec,bool & flush,CommandReturnObject & result)426314f1b3e8SDimitry Andric bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush,
426414f1b3e8SDimitry Andric CommandReturnObject &result) {
4265f034231aSEd Maste const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
4266706b4fc4SDimitry Andric if (!symbol_fspec) {
4267706b4fc4SDimitry Andric result.AppendError(
4268706b4fc4SDimitry Andric "one or more executable image paths must be specified");
4269706b4fc4SDimitry Andric return false;
4270706b4fc4SDimitry Andric }
4271706b4fc4SDimitry Andric
4272f034231aSEd Maste char symfile_path[PATH_MAX];
4273f034231aSEd Maste symbol_fspec.GetPath(symfile_path, sizeof(symfile_path));
4274f034231aSEd Maste
427514f1b3e8SDimitry Andric if (!module_spec.GetUUID().IsValid()) {
4276f034231aSEd Maste if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
4277e3b55780SDimitry Andric module_spec.GetFileSpec().SetFilename(symbol_fspec.GetFilename());
4278f034231aSEd Maste }
4279706b4fc4SDimitry Andric
4280cfca06d7SDimitry Andric // Now module_spec represents a symbol file for a module that might exist
4281cfca06d7SDimitry Andric // in the current target. Let's find possible matches.
4282cfca06d7SDimitry Andric ModuleList matching_modules;
4283f034231aSEd Maste
4284f034231aSEd Maste // First extract all module specs from the symbol file
4285f034231aSEd Maste lldb_private::ModuleSpecList symfile_module_specs;
428614f1b3e8SDimitry Andric if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(),
428714f1b3e8SDimitry Andric 0, 0, symfile_module_specs)) {
4288f034231aSEd Maste // Now extract the module spec that matches the target architecture
4289f034231aSEd Maste ModuleSpec target_arch_module_spec;
4290f034231aSEd Maste ModuleSpec symfile_module_spec;
4291f034231aSEd Maste target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
429214f1b3e8SDimitry Andric if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec,
429314f1b3e8SDimitry Andric symfile_module_spec)) {
429414f1b3e8SDimitry Andric if (symfile_module_spec.GetUUID().IsValid()) {
4295f034231aSEd Maste // It has a UUID, look for this UUID in the target modules
4296f034231aSEd Maste ModuleSpec symfile_uuid_module_spec;
4297f034231aSEd Maste symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
4298ead24645SDimitry Andric target->GetImages().FindModules(symfile_uuid_module_spec,
4299cfca06d7SDimitry Andric matching_modules);
4300f034231aSEd Maste }
4301f034231aSEd Maste }
4302f034231aSEd Maste
4303cfca06d7SDimitry Andric if (matching_modules.IsEmpty()) {
4304cfca06d7SDimitry Andric // No matches yet. Iterate through the module specs to find a UUID
4305cfca06d7SDimitry Andric // value that we can match up to an image in our target.
4306cfca06d7SDimitry Andric const size_t num_symfile_module_specs = symfile_module_specs.GetSize();
4307cfca06d7SDimitry Andric for (size_t i = 0;
4308cfca06d7SDimitry Andric i < num_symfile_module_specs && matching_modules.IsEmpty(); ++i) {
430914f1b3e8SDimitry Andric if (symfile_module_specs.GetModuleSpecAtIndex(
431014f1b3e8SDimitry Andric i, symfile_module_spec)) {
431114f1b3e8SDimitry Andric if (symfile_module_spec.GetUUID().IsValid()) {
4312cfca06d7SDimitry Andric // It has a UUID. Look for this UUID in the target modules.
4313f034231aSEd Maste ModuleSpec symfile_uuid_module_spec;
431414f1b3e8SDimitry Andric symfile_uuid_module_spec.GetUUID() =
431514f1b3e8SDimitry Andric symfile_module_spec.GetUUID();
4316ead24645SDimitry Andric target->GetImages().FindModules(symfile_uuid_module_spec,
4317cfca06d7SDimitry Andric matching_modules);
4318f034231aSEd Maste }
4319f034231aSEd Maste }
4320f034231aSEd Maste }
4321f034231aSEd Maste }
4322f034231aSEd Maste }
4323f034231aSEd Maste
4324f73363f1SDimitry Andric // Just try to match up the file by basename if we have no matches at
4325cfca06d7SDimitry Andric // this point. For example, module foo might have symbols in foo.debug.
4326cfca06d7SDimitry Andric if (matching_modules.IsEmpty())
4327cfca06d7SDimitry Andric target->GetImages().FindModules(module_spec, matching_modules);
4328f034231aSEd Maste
4329cfca06d7SDimitry Andric while (matching_modules.IsEmpty()) {
433014f1b3e8SDimitry Andric ConstString filename_no_extension(
433114f1b3e8SDimitry Andric module_spec.GetFileSpec().GetFileNameStrippingExtension());
4332706b4fc4SDimitry Andric // Empty string returned, let's bail
4333f034231aSEd Maste if (!filename_no_extension)
4334f034231aSEd Maste break;
4335f034231aSEd Maste
4336706b4fc4SDimitry Andric // Check if there was no extension to strip and the basename is the same
4337f034231aSEd Maste if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
4338f034231aSEd Maste break;
4339f034231aSEd Maste
4340706b4fc4SDimitry Andric // Replace basename with one fewer extension
4341e3b55780SDimitry Andric module_spec.GetFileSpec().SetFilename(filename_no_extension);
4342cfca06d7SDimitry Andric target->GetImages().FindModules(module_spec, matching_modules);
4343f034231aSEd Maste }
4344f034231aSEd Maste
4345cfca06d7SDimitry Andric if (matching_modules.GetSize() > 1) {
434614f1b3e8SDimitry Andric result.AppendErrorWithFormat("multiple modules match symbol file '%s', "
434714f1b3e8SDimitry Andric "use the --uuid option to resolve the "
434814f1b3e8SDimitry Andric "ambiguity.\n",
434914f1b3e8SDimitry Andric symfile_path);
4350cfca06d7SDimitry Andric return false;
4351cfca06d7SDimitry Andric }
4352cfca06d7SDimitry Andric
4353cfca06d7SDimitry Andric if (matching_modules.GetSize() == 1) {
4354cfca06d7SDimitry Andric ModuleSP module_sp(matching_modules.GetModuleAtIndex(0));
4355f034231aSEd Maste
4356f73363f1SDimitry Andric // The module has not yet created its symbol vendor, we can just give
4357f73363f1SDimitry Andric // the existing target module the symfile path to use for when it
4358f73363f1SDimitry Andric // decides to create it!
4359f034231aSEd Maste module_sp->SetSymbolFileFileSpec(symbol_fspec);
4360f034231aSEd Maste
4361ead24645SDimitry Andric SymbolFile *symbol_file =
4362ead24645SDimitry Andric module_sp->GetSymbolFile(true, &result.GetErrorStream());
436314f1b3e8SDimitry Andric if (symbol_file) {
4364f034231aSEd Maste ObjectFile *object_file = symbol_file->GetObjectFile();
436514f1b3e8SDimitry Andric if (object_file && object_file->GetFileSpec() == symbol_fspec) {
4366f034231aSEd Maste // Provide feedback that the symfile has been successfully added.
4367f034231aSEd Maste const FileSpec &module_fs = module_sp->GetFileSpec();
436814f1b3e8SDimitry Andric result.AppendMessageWithFormat(
436914f1b3e8SDimitry Andric "symbol file '%s' has been added to '%s'\n", symfile_path,
4370f034231aSEd Maste module_fs.GetPath().c_str());
4371f034231aSEd Maste
4372f73363f1SDimitry Andric // Let clients know something changed in the module if it is
4373f73363f1SDimitry Andric // currently loaded
4374f034231aSEd Maste ModuleList module_list;
4375f034231aSEd Maste module_list.Append(module_sp);
4376f034231aSEd Maste target->SymbolsDidLoad(module_list);
4377f034231aSEd Maste
4378f034231aSEd Maste // Make sure we load any scripting resources that may be embedded
4379f034231aSEd Maste // in the debug info files in case the platform supports that.
4380b76161e4SDimitry Andric Status error;
4381f034231aSEd Maste StreamString feedback_stream;
438214f1b3e8SDimitry Andric module_sp->LoadScriptingResourceInTarget(target, error,
43837fa27ce4SDimitry Andric feedback_stream);
4384f034231aSEd Maste if (error.Fail() && error.AsCString())
438514f1b3e8SDimitry Andric result.AppendWarningWithFormat(
438614f1b3e8SDimitry Andric "unable to load scripting data for module %s - error "
438714f1b3e8SDimitry Andric "reported was %s",
438814f1b3e8SDimitry Andric module_sp->GetFileSpec()
438914f1b3e8SDimitry Andric .GetFileNameStrippingExtension()
439014f1b3e8SDimitry Andric .GetCString(),
4391f034231aSEd Maste error.AsCString());
4392f034231aSEd Maste else if (feedback_stream.GetSize())
4393cfca06d7SDimitry Andric result.AppendWarning(feedback_stream.GetData());
4394f034231aSEd Maste
4395f034231aSEd Maste flush = true;
4396f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
4397f034231aSEd Maste return true;
4398f034231aSEd Maste }
4399f034231aSEd Maste }
4400f034231aSEd Maste // Clear the symbol file spec if anything went wrong
4401f034231aSEd Maste module_sp->SetSymbolFileFileSpec(FileSpec());
4402f034231aSEd Maste }
4403f034231aSEd Maste
4404f034231aSEd Maste StreamString ss_symfile_uuid;
4405706b4fc4SDimitry Andric if (module_spec.GetUUID().IsValid()) {
4406706b4fc4SDimitry Andric ss_symfile_uuid << " (";
44077fa27ce4SDimitry Andric module_spec.GetUUID().Dump(ss_symfile_uuid);
4408706b4fc4SDimitry Andric ss_symfile_uuid << ')';
4409706b4fc4SDimitry Andric }
441014f1b3e8SDimitry Andric result.AppendErrorWithFormat(
4411706b4fc4SDimitry Andric "symbol file '%s'%s does not match any existing module%s\n",
441214f1b3e8SDimitry Andric symfile_path, ss_symfile_uuid.GetData(),
4413cfca06d7SDimitry Andric !llvm::sys::fs::is_regular_file(symbol_fspec.GetPath())
4414f034231aSEd Maste ? "\n please specify the full path to the symbol file"
4415f034231aSEd Maste : "");
4416f034231aSEd Maste return false;
4417f034231aSEd Maste }
4418f034231aSEd Maste
DownloadObjectAndSymbolFile(ModuleSpec & module_spec,CommandReturnObject & result,bool & flush)4419c0981da4SDimitry Andric bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
4420c0981da4SDimitry Andric CommandReturnObject &result, bool &flush) {
4421145449b1SDimitry Andric Status error;
4422b1c73532SDimitry Andric if (PluginManager::DownloadObjectAndSymbolFile(module_spec, error)) {
4423c0981da4SDimitry Andric if (module_spec.GetSymbolFileSpec())
4424c0981da4SDimitry Andric return AddModuleSymbols(m_exe_ctx.GetTargetPtr(), module_spec, flush,
4425c0981da4SDimitry Andric result);
4426145449b1SDimitry Andric } else {
4427145449b1SDimitry Andric result.SetError(error);
4428c0981da4SDimitry Andric }
4429c0981da4SDimitry Andric return false;
4430c0981da4SDimitry Andric }
4431c0981da4SDimitry Andric
AddSymbolsForUUID(CommandReturnObject & result,bool & flush)4432c0981da4SDimitry Andric bool AddSymbolsForUUID(CommandReturnObject &result, bool &flush) {
4433c0981da4SDimitry Andric assert(m_uuid_option_group.GetOptionValue().OptionWasSet());
4434c0981da4SDimitry Andric
4435c0981da4SDimitry Andric ModuleSpec module_spec;
4436c0981da4SDimitry Andric module_spec.GetUUID() =
4437c0981da4SDimitry Andric m_uuid_option_group.GetOptionValue().GetCurrentValue();
4438c0981da4SDimitry Andric
4439c0981da4SDimitry Andric if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) {
4440c0981da4SDimitry Andric StreamString error_strm;
4441c0981da4SDimitry Andric error_strm.PutCString("unable to find debug symbols for UUID ");
44427fa27ce4SDimitry Andric module_spec.GetUUID().Dump(error_strm);
4443c0981da4SDimitry Andric result.AppendError(error_strm.GetString());
4444c0981da4SDimitry Andric return false;
4445c0981da4SDimitry Andric }
4446c0981da4SDimitry Andric
4447c0981da4SDimitry Andric return true;
4448c0981da4SDimitry Andric }
4449c0981da4SDimitry Andric
AddSymbolsForFile(CommandReturnObject & result,bool & flush)4450c0981da4SDimitry Andric bool AddSymbolsForFile(CommandReturnObject &result, bool &flush) {
4451c0981da4SDimitry Andric assert(m_file_option.GetOptionValue().OptionWasSet());
4452c0981da4SDimitry Andric
4453c0981da4SDimitry Andric ModuleSpec module_spec;
4454c0981da4SDimitry Andric module_spec.GetFileSpec() =
4455c0981da4SDimitry Andric m_file_option.GetOptionValue().GetCurrentValue();
4456c0981da4SDimitry Andric
4457c0981da4SDimitry Andric Target *target = m_exe_ctx.GetTargetPtr();
4458c0981da4SDimitry Andric ModuleSP module_sp(target->GetImages().FindFirstModule(module_spec));
4459c0981da4SDimitry Andric if (module_sp) {
4460c0981da4SDimitry Andric module_spec.GetFileSpec() = module_sp->GetFileSpec();
4461c0981da4SDimitry Andric module_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec();
4462c0981da4SDimitry Andric module_spec.GetUUID() = module_sp->GetUUID();
4463c0981da4SDimitry Andric module_spec.GetArchitecture() = module_sp->GetArchitecture();
4464c0981da4SDimitry Andric } else {
4465c0981da4SDimitry Andric module_spec.GetArchitecture() = target->GetArchitecture();
4466c0981da4SDimitry Andric }
4467c0981da4SDimitry Andric
4468c0981da4SDimitry Andric if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) {
4469c0981da4SDimitry Andric StreamString error_strm;
4470c0981da4SDimitry Andric error_strm.PutCString(
4471c0981da4SDimitry Andric "unable to find debug symbols for the executable file ");
4472c0981da4SDimitry Andric error_strm << module_spec.GetFileSpec();
4473c0981da4SDimitry Andric result.AppendError(error_strm.GetString());
4474c0981da4SDimitry Andric return false;
4475c0981da4SDimitry Andric }
4476c0981da4SDimitry Andric
4477c0981da4SDimitry Andric return true;
4478c0981da4SDimitry Andric }
4479c0981da4SDimitry Andric
AddSymbolsForFrame(CommandReturnObject & result,bool & flush)4480c0981da4SDimitry Andric bool AddSymbolsForFrame(CommandReturnObject &result, bool &flush) {
4481c0981da4SDimitry Andric assert(m_current_frame_option.GetOptionValue().OptionWasSet());
4482c0981da4SDimitry Andric
4483c0981da4SDimitry Andric Process *process = m_exe_ctx.GetProcessPtr();
4484c0981da4SDimitry Andric if (!process) {
4485c0981da4SDimitry Andric result.AppendError(
4486c0981da4SDimitry Andric "a process must exist in order to use the --frame option");
4487c0981da4SDimitry Andric return false;
4488c0981da4SDimitry Andric }
4489c0981da4SDimitry Andric
4490c0981da4SDimitry Andric const StateType process_state = process->GetState();
4491c0981da4SDimitry Andric if (!StateIsStoppedState(process_state, true)) {
4492c0981da4SDimitry Andric result.AppendErrorWithFormat("process is not stopped: %s",
4493c0981da4SDimitry Andric StateAsCString(process_state));
4494c0981da4SDimitry Andric return false;
4495c0981da4SDimitry Andric }
4496c0981da4SDimitry Andric
4497c0981da4SDimitry Andric StackFrame *frame = m_exe_ctx.GetFramePtr();
4498c0981da4SDimitry Andric if (!frame) {
4499c0981da4SDimitry Andric result.AppendError("invalid current frame");
4500c0981da4SDimitry Andric return false;
4501c0981da4SDimitry Andric }
4502c0981da4SDimitry Andric
4503c0981da4SDimitry Andric ModuleSP frame_module_sp(
4504c0981da4SDimitry Andric frame->GetSymbolContext(eSymbolContextModule).module_sp);
4505c0981da4SDimitry Andric if (!frame_module_sp) {
4506c0981da4SDimitry Andric result.AppendError("frame has no module");
4507c0981da4SDimitry Andric return false;
4508c0981da4SDimitry Andric }
4509c0981da4SDimitry Andric
4510c0981da4SDimitry Andric ModuleSpec module_spec;
4511c0981da4SDimitry Andric module_spec.GetUUID() = frame_module_sp->GetUUID();
4512c0981da4SDimitry Andric module_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
4513c0981da4SDimitry Andric module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
4514c0981da4SDimitry Andric
4515c0981da4SDimitry Andric if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) {
4516c0981da4SDimitry Andric result.AppendError("unable to find debug symbols for the current frame");
4517c0981da4SDimitry Andric return false;
4518c0981da4SDimitry Andric }
4519c0981da4SDimitry Andric
4520c0981da4SDimitry Andric return true;
4521c0981da4SDimitry Andric }
4522c0981da4SDimitry Andric
AddSymbolsForStack(CommandReturnObject & result,bool & flush)4523c0981da4SDimitry Andric bool AddSymbolsForStack(CommandReturnObject &result, bool &flush) {
4524c0981da4SDimitry Andric assert(m_current_stack_option.GetOptionValue().OptionWasSet());
4525c0981da4SDimitry Andric
4526c0981da4SDimitry Andric Process *process = m_exe_ctx.GetProcessPtr();
4527c0981da4SDimitry Andric if (!process) {
4528c0981da4SDimitry Andric result.AppendError(
4529c0981da4SDimitry Andric "a process must exist in order to use the --stack option");
4530c0981da4SDimitry Andric return false;
4531c0981da4SDimitry Andric }
4532c0981da4SDimitry Andric
4533c0981da4SDimitry Andric const StateType process_state = process->GetState();
4534c0981da4SDimitry Andric if (!StateIsStoppedState(process_state, true)) {
4535c0981da4SDimitry Andric result.AppendErrorWithFormat("process is not stopped: %s",
4536c0981da4SDimitry Andric StateAsCString(process_state));
4537c0981da4SDimitry Andric return false;
4538c0981da4SDimitry Andric }
4539c0981da4SDimitry Andric
4540c0981da4SDimitry Andric Thread *thread = m_exe_ctx.GetThreadPtr();
4541c0981da4SDimitry Andric if (!thread) {
4542c0981da4SDimitry Andric result.AppendError("invalid current thread");
4543c0981da4SDimitry Andric return false;
4544c0981da4SDimitry Andric }
4545c0981da4SDimitry Andric
4546c0981da4SDimitry Andric bool symbols_found = false;
4547c0981da4SDimitry Andric uint32_t frame_count = thread->GetStackFrameCount();
4548c0981da4SDimitry Andric for (uint32_t i = 0; i < frame_count; ++i) {
4549c0981da4SDimitry Andric lldb::StackFrameSP frame_sp = thread->GetStackFrameAtIndex(i);
4550c0981da4SDimitry Andric
4551c0981da4SDimitry Andric ModuleSP frame_module_sp(
4552c0981da4SDimitry Andric frame_sp->GetSymbolContext(eSymbolContextModule).module_sp);
4553c0981da4SDimitry Andric if (!frame_module_sp)
4554c0981da4SDimitry Andric continue;
4555c0981da4SDimitry Andric
4556c0981da4SDimitry Andric ModuleSpec module_spec;
4557c0981da4SDimitry Andric module_spec.GetUUID() = frame_module_sp->GetUUID();
4558c0981da4SDimitry Andric module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
4559ac9a064cSDimitry Andric module_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
4560c0981da4SDimitry Andric
4561c0981da4SDimitry Andric bool current_frame_flush = false;
4562c0981da4SDimitry Andric if (DownloadObjectAndSymbolFile(module_spec, result, current_frame_flush))
4563c0981da4SDimitry Andric symbols_found = true;
4564c0981da4SDimitry Andric flush |= current_frame_flush;
4565c0981da4SDimitry Andric }
4566c0981da4SDimitry Andric
4567c0981da4SDimitry Andric if (!symbols_found) {
4568c0981da4SDimitry Andric result.AppendError(
4569c0981da4SDimitry Andric "unable to find debug symbols in the current call stack");
4570c0981da4SDimitry Andric return false;
4571c0981da4SDimitry Andric }
4572c0981da4SDimitry Andric
4573c0981da4SDimitry Andric return true;
4574c0981da4SDimitry Andric }
4575c0981da4SDimitry Andric
DoExecute(Args & args,CommandReturnObject & result)4576b1c73532SDimitry Andric void DoExecute(Args &args, CommandReturnObject &result) override {
4577f034231aSEd Maste Target *target = m_exe_ctx.GetTargetPtr();
4578f034231aSEd Maste result.SetStatus(eReturnStatusFailed);
4579f034231aSEd Maste bool flush = false;
4580f034231aSEd Maste ModuleSpec module_spec;
458114f1b3e8SDimitry Andric const bool uuid_option_set =
458214f1b3e8SDimitry Andric m_uuid_option_group.GetOptionValue().OptionWasSet();
4583f034231aSEd Maste const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
458414f1b3e8SDimitry Andric const bool frame_option_set =
458514f1b3e8SDimitry Andric m_current_frame_option.GetOptionValue().OptionWasSet();
4586c0981da4SDimitry Andric const bool stack_option_set =
4587c0981da4SDimitry Andric m_current_stack_option.GetOptionValue().OptionWasSet();
4588f034231aSEd Maste const size_t argc = args.GetArgumentCount();
4589f3fbd1c0SDimitry Andric
459014f1b3e8SDimitry Andric if (argc == 0) {
4591c0981da4SDimitry Andric if (uuid_option_set)
4592c0981da4SDimitry Andric AddSymbolsForUUID(result, flush);
4593c0981da4SDimitry Andric else if (file_option_set)
4594c0981da4SDimitry Andric AddSymbolsForFile(result, flush);
4595c0981da4SDimitry Andric else if (frame_option_set)
4596c0981da4SDimitry Andric AddSymbolsForFrame(result, flush);
4597c0981da4SDimitry Andric else if (stack_option_set)
4598c0981da4SDimitry Andric AddSymbolsForStack(result, flush);
4599c0981da4SDimitry Andric else
460014f1b3e8SDimitry Andric result.AppendError("one or more symbol file paths must be specified, "
460114f1b3e8SDimitry Andric "or options must be specified");
460214f1b3e8SDimitry Andric } else {
460314f1b3e8SDimitry Andric if (uuid_option_set) {
460414f1b3e8SDimitry Andric result.AppendError("specify either one or more paths to symbol files "
460514f1b3e8SDimitry Andric "or use the --uuid option without arguments");
460614f1b3e8SDimitry Andric } else if (frame_option_set) {
460714f1b3e8SDimitry Andric result.AppendError("specify either one or more paths to symbol files "
460814f1b3e8SDimitry Andric "or use the --frame option without arguments");
4609ef5d0b5eSDimitry Andric } else if (file_option_set && argc > 1) {
4610ef5d0b5eSDimitry Andric result.AppendError("specify at most one symbol file path when "
4611ef5d0b5eSDimitry Andric "--shlib option is set");
461214f1b3e8SDimitry Andric } else {
4613f034231aSEd Maste PlatformSP platform_sp(target->GetPlatform());
4614f034231aSEd Maste
461514f1b3e8SDimitry Andric for (auto &entry : args.entries()) {
4616ead24645SDimitry Andric if (!entry.ref().empty()) {
461794994d37SDimitry Andric auto &symbol_file_spec = module_spec.GetSymbolFileSpec();
4618ead24645SDimitry Andric symbol_file_spec.SetFile(entry.ref(), FileSpec::Style::native);
461994994d37SDimitry Andric FileSystem::Instance().Resolve(symbol_file_spec);
4620ef5d0b5eSDimitry Andric if (file_option_set) {
4621ef5d0b5eSDimitry Andric module_spec.GetFileSpec() =
4622ef5d0b5eSDimitry Andric m_file_option.GetOptionValue().GetCurrentValue();
4623ef5d0b5eSDimitry Andric }
462414f1b3e8SDimitry Andric if (platform_sp) {
4625f034231aSEd Maste FileSpec symfile_spec;
462614f1b3e8SDimitry Andric if (platform_sp
462714f1b3e8SDimitry Andric ->ResolveSymbolFile(*target, module_spec, symfile_spec)
462814f1b3e8SDimitry Andric .Success())
4629f034231aSEd Maste module_spec.GetSymbolFileSpec() = symfile_spec;
4630f034231aSEd Maste }
4631f034231aSEd Maste
463294994d37SDimitry Andric bool symfile_exists =
463394994d37SDimitry Andric FileSystem::Instance().Exists(module_spec.GetSymbolFileSpec());
4634f034231aSEd Maste
463514f1b3e8SDimitry Andric if (symfile_exists) {
4636f034231aSEd Maste if (!AddModuleSymbols(target, module_spec, flush, result))
4637f034231aSEd Maste break;
463814f1b3e8SDimitry Andric } else {
463914f1b3e8SDimitry Andric std::string resolved_symfile_path =
464014f1b3e8SDimitry Andric module_spec.GetSymbolFileSpec().GetPath();
4641ead24645SDimitry Andric if (resolved_symfile_path != entry.ref()) {
464214f1b3e8SDimitry Andric result.AppendErrorWithFormat(
464314f1b3e8SDimitry Andric "invalid module path '%s' with resolved path '%s'\n",
464414f1b3e8SDimitry Andric entry.c_str(), resolved_symfile_path.c_str());
4645f034231aSEd Maste break;
4646f034231aSEd Maste }
464714f1b3e8SDimitry Andric result.AppendErrorWithFormat("invalid module path '%s'\n",
464814f1b3e8SDimitry Andric entry.c_str());
4649f034231aSEd Maste break;
4650f034231aSEd Maste }
4651f034231aSEd Maste }
4652f034231aSEd Maste }
4653f034231aSEd Maste }
4654f034231aSEd Maste }
4655f034231aSEd Maste
465614f1b3e8SDimitry Andric if (flush) {
4657f034231aSEd Maste Process *process = m_exe_ctx.GetProcessPtr();
4658f034231aSEd Maste if (process)
4659f034231aSEd Maste process->Flush();
4660f034231aSEd Maste }
4661f034231aSEd Maste }
4662f034231aSEd Maste
4663f034231aSEd Maste OptionGroupOptions m_option_group;
4664f034231aSEd Maste OptionGroupUUID m_uuid_option_group;
4665f034231aSEd Maste OptionGroupFile m_file_option;
4666f034231aSEd Maste OptionGroupBoolean m_current_frame_option;
4667c0981da4SDimitry Andric OptionGroupBoolean m_current_stack_option;
4668f034231aSEd Maste };
4669f034231aSEd Maste
4670f034231aSEd Maste #pragma mark CommandObjectTargetSymbols
4671f034231aSEd Maste
4672f034231aSEd Maste // CommandObjectTargetSymbols
4673f034231aSEd Maste
467414f1b3e8SDimitry Andric class CommandObjectTargetSymbols : public CommandObjectMultiword {
4675f034231aSEd Maste public:
4676f034231aSEd Maste // Constructors and Destructors
CommandObjectTargetSymbols(CommandInterpreter & interpreter)4677f3fbd1c0SDimitry Andric CommandObjectTargetSymbols(CommandInterpreter &interpreter)
467814f1b3e8SDimitry Andric : CommandObjectMultiword(
467914f1b3e8SDimitry Andric interpreter, "target symbols",
468014f1b3e8SDimitry Andric "Commands for adding and managing debug symbol files.",
468114f1b3e8SDimitry Andric "target symbols <sub-command> ...") {
468214f1b3e8SDimitry Andric LoadSubCommand(
468314f1b3e8SDimitry Andric "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter)));
4684f034231aSEd Maste }
4685e81d9d49SDimitry Andric
4686f3fbd1c0SDimitry Andric ~CommandObjectTargetSymbols() override = default;
4687f034231aSEd Maste
4688f034231aSEd Maste private:
4689f034231aSEd Maste // For CommandObjectTargetModules only
4690cfca06d7SDimitry Andric CommandObjectTargetSymbols(const CommandObjectTargetSymbols &) = delete;
4691cfca06d7SDimitry Andric const CommandObjectTargetSymbols &
4692cfca06d7SDimitry Andric operator=(const CommandObjectTargetSymbols &) = delete;
4693f034231aSEd Maste };
4694f034231aSEd Maste
4695f034231aSEd Maste #pragma mark CommandObjectTargetStopHookAdd
4696f034231aSEd Maste
4697f034231aSEd Maste // CommandObjectTargetStopHookAdd
4698ead24645SDimitry Andric #define LLDB_OPTIONS_target_stop_hook_add
4699ead24645SDimitry Andric #include "CommandOptions.inc"
470014f1b3e8SDimitry Andric
470114f1b3e8SDimitry Andric class CommandObjectTargetStopHookAdd : public CommandObjectParsed,
470214f1b3e8SDimitry Andric public IOHandlerDelegateMultiline {
4703f034231aSEd Maste public:
4704b60736ecSDimitry Andric class CommandOptions : public OptionGroup {
4705f034231aSEd Maste public:
CommandOptions()47066f8fc217SDimitry Andric CommandOptions() : m_line_end(UINT_MAX) {}
4707f034231aSEd Maste
4708f3fbd1c0SDimitry Andric ~CommandOptions() override = default;
4709f034231aSEd Maste
GetDefinitions()471014f1b3e8SDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
4711e3b55780SDimitry Andric return llvm::ArrayRef(g_target_stop_hook_add_options);
4712f034231aSEd Maste }
4713f034231aSEd Maste
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)4714b76161e4SDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
471514f1b3e8SDimitry Andric ExecutionContext *execution_context) override {
4716b76161e4SDimitry Andric Status error;
4717b60736ecSDimitry Andric const int short_option =
4718b60736ecSDimitry Andric g_target_stop_hook_add_options[option_idx].short_option;
4719f034231aSEd Maste
472014f1b3e8SDimitry Andric switch (short_option) {
4721f034231aSEd Maste case 'c':
4722cfca06d7SDimitry Andric m_class_name = std::string(option_arg);
4723f034231aSEd Maste m_sym_ctx_specified = true;
4724f034231aSEd Maste break;
4725f034231aSEd Maste
4726f034231aSEd Maste case 'e':
472714f1b3e8SDimitry Andric if (option_arg.getAsInteger(0, m_line_end)) {
472814f1b3e8SDimitry Andric error.SetErrorStringWithFormat("invalid end line number: \"%s\"",
472914f1b3e8SDimitry Andric option_arg.str().c_str());
4730f034231aSEd Maste break;
4731f034231aSEd Maste }
4732f034231aSEd Maste m_sym_ctx_specified = true;
4733f034231aSEd Maste break;
4734f034231aSEd Maste
47355f29bb8aSDimitry Andric case 'G': {
47365f29bb8aSDimitry Andric bool value, success;
47375f29bb8aSDimitry Andric value = OptionArgParser::ToBoolean(option_arg, false, &success);
47385f29bb8aSDimitry Andric if (success) {
47395f29bb8aSDimitry Andric m_auto_continue = value;
47405f29bb8aSDimitry Andric } else
47415f29bb8aSDimitry Andric error.SetErrorStringWithFormat(
47425f29bb8aSDimitry Andric "invalid boolean value '%s' passed for -G option",
47435f29bb8aSDimitry Andric option_arg.str().c_str());
4744706b4fc4SDimitry Andric } break;
4745f034231aSEd Maste case 'l':
474614f1b3e8SDimitry Andric if (option_arg.getAsInteger(0, m_line_start)) {
474714f1b3e8SDimitry Andric error.SetErrorStringWithFormat("invalid start line number: \"%s\"",
474814f1b3e8SDimitry Andric option_arg.str().c_str());
4749f034231aSEd Maste break;
4750f034231aSEd Maste }
4751f034231aSEd Maste m_sym_ctx_specified = true;
4752f034231aSEd Maste break;
4753f034231aSEd Maste
4754f034231aSEd Maste case 'i':
4755f034231aSEd Maste m_no_inlines = true;
4756f034231aSEd Maste break;
4757f034231aSEd Maste
4758f034231aSEd Maste case 'n':
4759cfca06d7SDimitry Andric m_function_name = std::string(option_arg);
4760f034231aSEd Maste m_func_name_type_mask |= eFunctionNameTypeAuto;
4761f034231aSEd Maste m_sym_ctx_specified = true;
4762f034231aSEd Maste break;
4763f034231aSEd Maste
4764f034231aSEd Maste case 'f':
4765cfca06d7SDimitry Andric m_file_name = std::string(option_arg);
4766f034231aSEd Maste m_sym_ctx_specified = true;
4767f034231aSEd Maste break;
4768f3fbd1c0SDimitry Andric
4769f034231aSEd Maste case 's':
4770cfca06d7SDimitry Andric m_module_name = std::string(option_arg);
4771f034231aSEd Maste m_sym_ctx_specified = true;
4772f034231aSEd Maste break;
4773f3fbd1c0SDimitry Andric
4774f034231aSEd Maste case 't':
477514f1b3e8SDimitry Andric if (option_arg.getAsInteger(0, m_thread_id))
477614f1b3e8SDimitry Andric error.SetErrorStringWithFormat("invalid thread id string '%s'",
477714f1b3e8SDimitry Andric option_arg.str().c_str());
4778f034231aSEd Maste m_thread_specified = true;
4779f034231aSEd Maste break;
4780f3fbd1c0SDimitry Andric
4781f034231aSEd Maste case 'T':
4782cfca06d7SDimitry Andric m_thread_name = std::string(option_arg);
4783f034231aSEd Maste m_thread_specified = true;
4784f034231aSEd Maste break;
4785f3fbd1c0SDimitry Andric
4786f034231aSEd Maste case 'q':
4787cfca06d7SDimitry Andric m_queue_name = std::string(option_arg);
4788f034231aSEd Maste m_thread_specified = true;
4789f034231aSEd Maste break;
4790f3fbd1c0SDimitry Andric
4791f034231aSEd Maste case 'x':
479214f1b3e8SDimitry Andric if (option_arg.getAsInteger(0, m_thread_index))
479314f1b3e8SDimitry Andric error.SetErrorStringWithFormat("invalid thread index string '%s'",
479414f1b3e8SDimitry Andric option_arg.str().c_str());
4795f034231aSEd Maste m_thread_specified = true;
4796f034231aSEd Maste break;
4797f3fbd1c0SDimitry Andric
4798f034231aSEd Maste case 'o':
4799f034231aSEd Maste m_use_one_liner = true;
4800cfca06d7SDimitry Andric m_one_liner.push_back(std::string(option_arg));
4801f034231aSEd Maste break;
4802f3fbd1c0SDimitry Andric
4803f034231aSEd Maste default:
4804ead24645SDimitry Andric llvm_unreachable("Unimplemented option");
4805f034231aSEd Maste }
4806f034231aSEd Maste return error;
4807f034231aSEd Maste }
4808f034231aSEd Maste
OptionParsingStarting(ExecutionContext * execution_context)480914f1b3e8SDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override {
4810f034231aSEd Maste m_class_name.clear();
4811f034231aSEd Maste m_function_name.clear();
4812f034231aSEd Maste m_line_start = 0;
48134b4fe385SDimitry Andric m_line_end = LLDB_INVALID_LINE_NUMBER;
4814f034231aSEd Maste m_file_name.clear();
4815f034231aSEd Maste m_module_name.clear();
4816f034231aSEd Maste m_func_name_type_mask = eFunctionNameTypeAuto;
4817f034231aSEd Maste m_thread_id = LLDB_INVALID_THREAD_ID;
4818f034231aSEd Maste m_thread_index = UINT32_MAX;
4819f034231aSEd Maste m_thread_name.clear();
4820f034231aSEd Maste m_queue_name.clear();
4821f034231aSEd Maste
4822f034231aSEd Maste m_no_inlines = false;
4823f034231aSEd Maste m_sym_ctx_specified = false;
4824f034231aSEd Maste m_thread_specified = false;
4825f034231aSEd Maste
4826f034231aSEd Maste m_use_one_liner = false;
4827f034231aSEd Maste m_one_liner.clear();
48285f29bb8aSDimitry Andric m_auto_continue = false;
4829f034231aSEd Maste }
4830f034231aSEd Maste
4831f034231aSEd Maste std::string m_class_name;
4832f034231aSEd Maste std::string m_function_name;
4833344a3780SDimitry Andric uint32_t m_line_start = 0;
48344b4fe385SDimitry Andric uint32_t m_line_end = LLDB_INVALID_LINE_NUMBER;
4835f034231aSEd Maste std::string m_file_name;
4836f034231aSEd Maste std::string m_module_name;
4837344a3780SDimitry Andric uint32_t m_func_name_type_mask =
4838344a3780SDimitry Andric eFunctionNameTypeAuto; // A pick from lldb::FunctionNameType.
48394b4fe385SDimitry Andric lldb::tid_t m_thread_id = LLDB_INVALID_THREAD_ID;
48404b4fe385SDimitry Andric uint32_t m_thread_index = UINT32_MAX;
4841f034231aSEd Maste std::string m_thread_name;
4842f034231aSEd Maste std::string m_queue_name;
4843344a3780SDimitry Andric bool m_sym_ctx_specified = false;
48444b4fe385SDimitry Andric bool m_no_inlines = false;
4845344a3780SDimitry Andric bool m_thread_specified = false;
4846f034231aSEd Maste // Instance variables to hold the values for one_liner options.
4847344a3780SDimitry Andric bool m_use_one_liner = false;
48485f29bb8aSDimitry Andric std::vector<std::string> m_one_liner;
4849b60736ecSDimitry Andric
48504b4fe385SDimitry Andric bool m_auto_continue = false;
4851f034231aSEd Maste };
4852f034231aSEd Maste
CommandObjectTargetStopHookAdd(CommandInterpreter & interpreter)485314f1b3e8SDimitry Andric CommandObjectTargetStopHookAdd(CommandInterpreter &interpreter)
485414f1b3e8SDimitry Andric : CommandObjectParsed(interpreter, "target stop-hook add",
4855b60736ecSDimitry Andric "Add a hook to be executed when the target stops."
4856b60736ecSDimitry Andric "The hook can either be a list of commands or an "
4857b60736ecSDimitry Andric "appropriately defined Python class. You can also "
4858b60736ecSDimitry Andric "add filters so the hook only runs a certain stop "
4859b60736ecSDimitry Andric "points.",
4860f034231aSEd Maste "target stop-hook add"),
486114f1b3e8SDimitry Andric IOHandlerDelegateMultiline("DONE",
486214f1b3e8SDimitry Andric IOHandlerDelegate::Completion::LLDBCommand),
48636f8fc217SDimitry Andric m_python_class_options("scripted stop-hook", true, 'P') {
4864b60736ecSDimitry Andric SetHelpLong(
4865b60736ecSDimitry Andric R"(
4866b60736ecSDimitry Andric Command Based stop-hooks:
4867b60736ecSDimitry Andric -------------------------
4868b60736ecSDimitry Andric Stop hooks can run a list of lldb commands by providing one or more
4869b60736ecSDimitry Andric --one-line-command options. The commands will get run in the order they are
4870b60736ecSDimitry Andric added. Or you can provide no commands, in which case you will enter a
4871b60736ecSDimitry Andric command editor where you can enter the commands to be run.
4872b60736ecSDimitry Andric
4873b60736ecSDimitry Andric Python Based Stop Hooks:
4874b60736ecSDimitry Andric ------------------------
4875b60736ecSDimitry Andric Stop hooks can be implemented with a suitably defined Python class, whose name
4876b60736ecSDimitry Andric is passed in the --python-class option.
4877b60736ecSDimitry Andric
4878b60736ecSDimitry Andric When the stop hook is added, the class is initialized by calling:
4879b60736ecSDimitry Andric
4880344a3780SDimitry Andric def __init__(self, target, extra_args, internal_dict):
4881b60736ecSDimitry Andric
4882b60736ecSDimitry Andric target: The target that the stop hook is being added to.
4883b60736ecSDimitry Andric extra_args: An SBStructuredData Dictionary filled with the -key -value
4884b60736ecSDimitry Andric option pairs passed to the command.
4885b60736ecSDimitry Andric dict: An implementation detail provided by lldb.
4886b60736ecSDimitry Andric
4887b60736ecSDimitry Andric Then when the stop-hook triggers, lldb will run the 'handle_stop' method.
4888b60736ecSDimitry Andric The method has the signature:
4889b60736ecSDimitry Andric
4890b60736ecSDimitry Andric def handle_stop(self, exe_ctx, stream):
4891b60736ecSDimitry Andric
4892b60736ecSDimitry Andric exe_ctx: An SBExecutionContext for the thread that has stopped.
4893b60736ecSDimitry Andric stream: An SBStream, anything written to this stream will be printed in the
4894b60736ecSDimitry Andric the stop message when the process stops.
4895b60736ecSDimitry Andric
4896b60736ecSDimitry Andric Return Value: The method returns "should_stop". If should_stop is false
4897b60736ecSDimitry Andric from all the stop hook executions on threads that stopped
4898b60736ecSDimitry Andric with a reason, then the process will continue. Note that this
4899b60736ecSDimitry Andric will happen only after all the stop hooks are run.
4900b60736ecSDimitry Andric
4901b60736ecSDimitry Andric Filter Options:
4902b60736ecSDimitry Andric ---------------
4903b60736ecSDimitry Andric Stop hooks can be set to always run, or to only run when the stopped thread
4904b60736ecSDimitry Andric matches the filter options passed on the command line. The available filter
4905b60736ecSDimitry Andric options include a shared library or a thread or queue specification,
4906b60736ecSDimitry Andric a line range in a source file, a function name or a class name.
4907b60736ecSDimitry Andric )");
4908b60736ecSDimitry Andric m_all_options.Append(&m_python_class_options,
4909b60736ecSDimitry Andric LLDB_OPT_SET_1 | LLDB_OPT_SET_2,
4910b60736ecSDimitry Andric LLDB_OPT_SET_FROM_TO(4, 6));
4911b60736ecSDimitry Andric m_all_options.Append(&m_options);
4912b60736ecSDimitry Andric m_all_options.Finalize();
4913b60736ecSDimitry Andric }
4914f034231aSEd Maste
4915f3fbd1c0SDimitry Andric ~CommandObjectTargetStopHookAdd() override = default;
4916f3fbd1c0SDimitry Andric
GetOptions()4917b60736ecSDimitry Andric Options *GetOptions() override { return &m_all_options; }
4918f034231aSEd Maste
4919f034231aSEd Maste protected:
IOHandlerActivated(IOHandler & io_handler,bool interactive)49205f29bb8aSDimitry Andric void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
4921ead24645SDimitry Andric StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
49225f29bb8aSDimitry Andric if (output_sp && interactive) {
492314f1b3e8SDimitry Andric output_sp->PutCString(
492414f1b3e8SDimitry Andric "Enter your stop hook command(s). Type 'DONE' to end.\n");
4925866dcdacSEd Maste output_sp->Flush();
4926866dcdacSEd Maste }
4927866dcdacSEd Maste }
4928866dcdacSEd Maste
IOHandlerInputComplete(IOHandler & io_handler,std::string & line)492914f1b3e8SDimitry Andric void IOHandlerInputComplete(IOHandler &io_handler,
493014f1b3e8SDimitry Andric std::string &line) override {
493114f1b3e8SDimitry Andric if (m_stop_hook_sp) {
493214f1b3e8SDimitry Andric if (line.empty()) {
4933ead24645SDimitry Andric StreamFileSP error_sp(io_handler.GetErrorStreamFileSP());
493414f1b3e8SDimitry Andric if (error_sp) {
493514f1b3e8SDimitry Andric error_sp->Printf("error: stop hook #%" PRIu64
493614f1b3e8SDimitry Andric " aborted, no commands.\n",
493714f1b3e8SDimitry Andric m_stop_hook_sp->GetID());
4938866dcdacSEd Maste error_sp->Flush();
4939866dcdacSEd Maste }
49405f29bb8aSDimitry Andric Target *target = GetDebugger().GetSelectedTarget().get();
4941b60736ecSDimitry Andric if (target) {
4942b60736ecSDimitry Andric target->UndoCreateStopHook(m_stop_hook_sp->GetID());
4943b60736ecSDimitry Andric }
494414f1b3e8SDimitry Andric } else {
4945b60736ecSDimitry Andric // The IOHandler editor is only for command lines stop hooks:
4946b60736ecSDimitry Andric Target::StopHookCommandLine *hook_ptr =
4947b60736ecSDimitry Andric static_cast<Target::StopHookCommandLine *>(m_stop_hook_sp.get());
4948b60736ecSDimitry Andric
4949b60736ecSDimitry Andric hook_ptr->SetActionFromString(line);
4950ead24645SDimitry Andric StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
495114f1b3e8SDimitry Andric if (output_sp) {
495214f1b3e8SDimitry Andric output_sp->Printf("Stop hook #%" PRIu64 " added.\n",
495314f1b3e8SDimitry Andric m_stop_hook_sp->GetID());
4954866dcdacSEd Maste output_sp->Flush();
4955866dcdacSEd Maste }
4956866dcdacSEd Maste }
4957866dcdacSEd Maste m_stop_hook_sp.reset();
4958866dcdacSEd Maste }
4959866dcdacSEd Maste io_handler.SetIsDone(true);
4960866dcdacSEd Maste }
4961866dcdacSEd Maste
DoExecute(Args & command,CommandReturnObject & result)4962b1c73532SDimitry Andric void DoExecute(Args &command, CommandReturnObject &result) override {
4963866dcdacSEd Maste m_stop_hook_sp.reset();
4964866dcdacSEd Maste
4965ead24645SDimitry Andric Target &target = GetSelectedOrDummyTarget();
4966b60736ecSDimitry Andric Target::StopHookSP new_hook_sp =
4967b60736ecSDimitry Andric target.CreateStopHook(m_python_class_options.GetName().empty() ?
4968b60736ecSDimitry Andric Target::StopHook::StopHookKind::CommandBased
4969b60736ecSDimitry Andric : Target::StopHook::StopHookKind::ScriptBased);
4970f034231aSEd Maste
4971f034231aSEd Maste // First step, make the specifier.
49725f29bb8aSDimitry Andric std::unique_ptr<SymbolContextSpecifier> specifier_up;
497314f1b3e8SDimitry Andric if (m_options.m_sym_ctx_specified) {
4974cfca06d7SDimitry Andric specifier_up = std::make_unique<SymbolContextSpecifier>(
4975cfca06d7SDimitry Andric GetDebugger().GetSelectedTarget());
4976f034231aSEd Maste
497714f1b3e8SDimitry Andric if (!m_options.m_module_name.empty()) {
49785f29bb8aSDimitry Andric specifier_up->AddSpecification(
497914f1b3e8SDimitry Andric m_options.m_module_name.c_str(),
498014f1b3e8SDimitry Andric SymbolContextSpecifier::eModuleSpecified);
4981f034231aSEd Maste }
4982f034231aSEd Maste
498314f1b3e8SDimitry Andric if (!m_options.m_class_name.empty()) {
49845f29bb8aSDimitry Andric specifier_up->AddSpecification(
498514f1b3e8SDimitry Andric m_options.m_class_name.c_str(),
498614f1b3e8SDimitry Andric SymbolContextSpecifier::eClassOrNamespaceSpecified);
4987f034231aSEd Maste }
4988f034231aSEd Maste
498914f1b3e8SDimitry Andric if (!m_options.m_file_name.empty()) {
4990ead24645SDimitry Andric specifier_up->AddSpecification(m_options.m_file_name.c_str(),
499114f1b3e8SDimitry Andric SymbolContextSpecifier::eFileSpecified);
4992f034231aSEd Maste }
4993f034231aSEd Maste
499414f1b3e8SDimitry Andric if (m_options.m_line_start != 0) {
49955f29bb8aSDimitry Andric specifier_up->AddLineSpecification(
499614f1b3e8SDimitry Andric m_options.m_line_start,
499714f1b3e8SDimitry Andric SymbolContextSpecifier::eLineStartSpecified);
4998f034231aSEd Maste }
4999f034231aSEd Maste
500014f1b3e8SDimitry Andric if (m_options.m_line_end != UINT_MAX) {
50015f29bb8aSDimitry Andric specifier_up->AddLineSpecification(
500214f1b3e8SDimitry Andric m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
5003f034231aSEd Maste }
5004f034231aSEd Maste
500514f1b3e8SDimitry Andric if (!m_options.m_function_name.empty()) {
50065f29bb8aSDimitry Andric specifier_up->AddSpecification(
500714f1b3e8SDimitry Andric m_options.m_function_name.c_str(),
500814f1b3e8SDimitry Andric SymbolContextSpecifier::eFunctionSpecified);
5009f034231aSEd Maste }
5010f034231aSEd Maste }
5011f034231aSEd Maste
50125f29bb8aSDimitry Andric if (specifier_up)
50135f29bb8aSDimitry Andric new_hook_sp->SetSpecifier(specifier_up.release());
5014f034231aSEd Maste
5015f034231aSEd Maste // Next see if any of the thread options have been entered:
5016f034231aSEd Maste
501714f1b3e8SDimitry Andric if (m_options.m_thread_specified) {
5018f034231aSEd Maste ThreadSpec *thread_spec = new ThreadSpec();
5019f034231aSEd Maste
502014f1b3e8SDimitry Andric if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) {
5021f034231aSEd Maste thread_spec->SetTID(m_options.m_thread_id);
5022f034231aSEd Maste }
5023f034231aSEd Maste
5024f034231aSEd Maste if (m_options.m_thread_index != UINT32_MAX)
5025f034231aSEd Maste thread_spec->SetIndex(m_options.m_thread_index);
5026f034231aSEd Maste
5027f034231aSEd Maste if (!m_options.m_thread_name.empty())
5028f034231aSEd Maste thread_spec->SetName(m_options.m_thread_name.c_str());
5029f034231aSEd Maste
5030f034231aSEd Maste if (!m_options.m_queue_name.empty())
5031f034231aSEd Maste thread_spec->SetQueueName(m_options.m_queue_name.c_str());
5032f034231aSEd Maste
5033f034231aSEd Maste new_hook_sp->SetThreadSpecifier(thread_spec);
5034f034231aSEd Maste }
50355f29bb8aSDimitry Andric
50365f29bb8aSDimitry Andric new_hook_sp->SetAutoContinue(m_options.m_auto_continue);
503714f1b3e8SDimitry Andric if (m_options.m_use_one_liner) {
5038b60736ecSDimitry Andric // This is a command line stop hook:
5039b60736ecSDimitry Andric Target::StopHookCommandLine *hook_ptr =
5040b60736ecSDimitry Andric static_cast<Target::StopHookCommandLine *>(new_hook_sp.get());
5041b60736ecSDimitry Andric hook_ptr->SetActionFromStrings(m_options.m_one_liner);
504214f1b3e8SDimitry Andric result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
504314f1b3e8SDimitry Andric new_hook_sp->GetID());
5044b60736ecSDimitry Andric } else if (!m_python_class_options.GetName().empty()) {
5045b60736ecSDimitry Andric // This is a scripted stop hook:
5046b60736ecSDimitry Andric Target::StopHookScripted *hook_ptr =
5047b60736ecSDimitry Andric static_cast<Target::StopHookScripted *>(new_hook_sp.get());
5048b60736ecSDimitry Andric Status error = hook_ptr->SetScriptCallback(
5049b60736ecSDimitry Andric m_python_class_options.GetName(),
5050b60736ecSDimitry Andric m_python_class_options.GetStructuredData());
5051b60736ecSDimitry Andric if (error.Success())
5052b60736ecSDimitry Andric result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
5053b60736ecSDimitry Andric new_hook_sp->GetID());
5054b60736ecSDimitry Andric else {
5055b60736ecSDimitry Andric // FIXME: Set the stop hook ID counter back.
5056b60736ecSDimitry Andric result.AppendErrorWithFormat("Couldn't add stop hook: %s",
5057b60736ecSDimitry Andric error.AsCString());
5058b60736ecSDimitry Andric target.UndoCreateStopHook(new_hook_sp->GetID());
5059b1c73532SDimitry Andric return;
5060b60736ecSDimitry Andric }
506114f1b3e8SDimitry Andric } else {
5062866dcdacSEd Maste m_stop_hook_sp = new_hook_sp;
5063706b4fc4SDimitry Andric m_interpreter.GetLLDBCommandsFromIOHandler("> ", // Prompt
5064706b4fc4SDimitry Andric *this); // IOHandlerDelegate
5065f034231aSEd Maste }
5066f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishNoResult);
5067f034231aSEd Maste }
5068f3fbd1c0SDimitry Andric
5069f034231aSEd Maste private:
5070f034231aSEd Maste CommandOptions m_options;
5071b60736ecSDimitry Andric OptionGroupPythonClassWithDict m_python_class_options;
5072b60736ecSDimitry Andric OptionGroupOptions m_all_options;
5073b60736ecSDimitry Andric
5074866dcdacSEd Maste Target::StopHookSP m_stop_hook_sp;
5075f034231aSEd Maste };
5076f034231aSEd Maste
5077f034231aSEd Maste #pragma mark CommandObjectTargetStopHookDelete
5078f034231aSEd Maste
5079f034231aSEd Maste // CommandObjectTargetStopHookDelete
5080f034231aSEd Maste
508114f1b3e8SDimitry Andric class CommandObjectTargetStopHookDelete : public CommandObjectParsed {
5082f034231aSEd Maste public:
CommandObjectTargetStopHookDelete(CommandInterpreter & interpreter)508314f1b3e8SDimitry Andric CommandObjectTargetStopHookDelete(CommandInterpreter &interpreter)
508414f1b3e8SDimitry Andric : CommandObjectParsed(interpreter, "target stop-hook delete",
5085f034231aSEd Maste "Delete a stop-hook.",
5086145449b1SDimitry Andric "target stop-hook delete [<idx>]") {
5087ac9a064cSDimitry Andric AddSimpleArgumentList(eArgTypeStopHookID, eArgRepeatStar);
5088145449b1SDimitry Andric }
5089f034231aSEd Maste
5090f3fbd1c0SDimitry Andric ~CommandObjectTargetStopHookDelete() override = default;
5091f034231aSEd Maste
5092b60736ecSDimitry Andric void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)5093b60736ecSDimitry Andric HandleArgumentCompletion(CompletionRequest &request,
5094b60736ecSDimitry Andric OptionElementVector &opt_element_vector) override {
5095b1c73532SDimitry Andric if (request.GetCursorIndex())
5096b1c73532SDimitry Andric return;
5097ac9a064cSDimitry Andric CommandObject::HandleArgumentCompletion(request, opt_element_vector);
5098b60736ecSDimitry Andric }
5099b60736ecSDimitry Andric
5100f034231aSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)5101b1c73532SDimitry Andric void DoExecute(Args &command, CommandReturnObject &result) override {
5102ead24645SDimitry Andric Target &target = GetSelectedOrDummyTarget();
5103f034231aSEd Maste // FIXME: see if we can use the breakpoint id style parser?
5104f034231aSEd Maste size_t num_args = command.GetArgumentCount();
510514f1b3e8SDimitry Andric if (num_args == 0) {
510614f1b3e8SDimitry Andric if (!m_interpreter.Confirm("Delete all stop hooks?", true)) {
5107f034231aSEd Maste result.SetStatus(eReturnStatusFailed);
5108b1c73532SDimitry Andric return;
510914f1b3e8SDimitry Andric } else {
5110ead24645SDimitry Andric target.RemoveAllStopHooks();
5111f034231aSEd Maste }
511214f1b3e8SDimitry Andric } else {
511314f1b3e8SDimitry Andric for (size_t i = 0; i < num_args; i++) {
5114cfca06d7SDimitry Andric lldb::user_id_t user_id;
5115cfca06d7SDimitry Andric if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
511614f1b3e8SDimitry Andric result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
511714f1b3e8SDimitry Andric command.GetArgumentAtIndex(i));
5118b1c73532SDimitry Andric return;
5119f034231aSEd Maste }
5120cfca06d7SDimitry Andric if (!target.RemoveStopHookByID(user_id)) {
512114f1b3e8SDimitry Andric result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
512214f1b3e8SDimitry Andric command.GetArgumentAtIndex(i));
5123b1c73532SDimitry Andric return;
5124f034231aSEd Maste }
5125f034231aSEd Maste }
5126f034231aSEd Maste }
5127f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishNoResult);
5128f034231aSEd Maste }
5129f034231aSEd Maste };
5130f3fbd1c0SDimitry Andric
5131f034231aSEd Maste #pragma mark CommandObjectTargetStopHookEnableDisable
5132f034231aSEd Maste
5133f034231aSEd Maste // CommandObjectTargetStopHookEnableDisable
5134f034231aSEd Maste
513514f1b3e8SDimitry Andric class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed {
5136f034231aSEd Maste public:
CommandObjectTargetStopHookEnableDisable(CommandInterpreter & interpreter,bool enable,const char * name,const char * help,const char * syntax)513714f1b3e8SDimitry Andric CommandObjectTargetStopHookEnableDisable(CommandInterpreter &interpreter,
513814f1b3e8SDimitry Andric bool enable, const char *name,
513914f1b3e8SDimitry Andric const char *help, const char *syntax)
514014f1b3e8SDimitry Andric : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable) {
5141ac9a064cSDimitry Andric AddSimpleArgumentList(eArgTypeStopHookID, eArgRepeatStar);
5142f034231aSEd Maste }
5143f034231aSEd Maste
5144f3fbd1c0SDimitry Andric ~CommandObjectTargetStopHookEnableDisable() override = default;
5145f034231aSEd Maste
5146b60736ecSDimitry Andric void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)5147b60736ecSDimitry Andric HandleArgumentCompletion(CompletionRequest &request,
5148b60736ecSDimitry Andric OptionElementVector &opt_element_vector) override {
5149b60736ecSDimitry Andric if (request.GetCursorIndex())
5150b60736ecSDimitry Andric return;
5151ac9a064cSDimitry Andric CommandObject::HandleArgumentCompletion(request, opt_element_vector);
5152b60736ecSDimitry Andric }
5153b60736ecSDimitry Andric
5154f034231aSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)5155b1c73532SDimitry Andric void DoExecute(Args &command, CommandReturnObject &result) override {
5156ead24645SDimitry Andric Target &target = GetSelectedOrDummyTarget();
5157f034231aSEd Maste // FIXME: see if we can use the breakpoint id style parser?
5158f034231aSEd Maste size_t num_args = command.GetArgumentCount();
5159f034231aSEd Maste bool success;
5160f034231aSEd Maste
516114f1b3e8SDimitry Andric if (num_args == 0) {
5162ead24645SDimitry Andric target.SetAllStopHooksActiveState(m_enable);
516314f1b3e8SDimitry Andric } else {
516414f1b3e8SDimitry Andric for (size_t i = 0; i < num_args; i++) {
5165cfca06d7SDimitry Andric lldb::user_id_t user_id;
5166cfca06d7SDimitry Andric if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
516714f1b3e8SDimitry Andric result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
516814f1b3e8SDimitry Andric command.GetArgumentAtIndex(i));
5169b1c73532SDimitry Andric return;
5170f034231aSEd Maste }
5171ead24645SDimitry Andric success = target.SetStopHookActiveStateByID(user_id, m_enable);
517214f1b3e8SDimitry Andric if (!success) {
517314f1b3e8SDimitry Andric result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
517414f1b3e8SDimitry Andric command.GetArgumentAtIndex(i));
5175b1c73532SDimitry Andric return;
5176f034231aSEd Maste }
5177f034231aSEd Maste }
5178f034231aSEd Maste }
5179f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishNoResult);
5180f034231aSEd Maste }
518114f1b3e8SDimitry Andric
5182f034231aSEd Maste private:
5183f034231aSEd Maste bool m_enable;
5184f034231aSEd Maste };
5185f034231aSEd Maste
5186f034231aSEd Maste #pragma mark CommandObjectTargetStopHookList
5187f034231aSEd Maste
5188f034231aSEd Maste // CommandObjectTargetStopHookList
5189f034231aSEd Maste
519014f1b3e8SDimitry Andric class CommandObjectTargetStopHookList : public CommandObjectParsed {
5191f034231aSEd Maste public:
CommandObjectTargetStopHookList(CommandInterpreter & interpreter)519214f1b3e8SDimitry Andric CommandObjectTargetStopHookList(CommandInterpreter &interpreter)
519314f1b3e8SDimitry Andric : CommandObjectParsed(interpreter, "target stop-hook list",
5194145449b1SDimitry Andric "List all stop-hooks.", "target stop-hook list") {}
5195f034231aSEd Maste
5196f3fbd1c0SDimitry Andric ~CommandObjectTargetStopHookList() override = default;
5197f034231aSEd Maste
5198f034231aSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)5199b1c73532SDimitry Andric void DoExecute(Args &command, CommandReturnObject &result) override {
5200ead24645SDimitry Andric Target &target = GetSelectedOrDummyTarget();
5201f034231aSEd Maste
5202ead24645SDimitry Andric size_t num_hooks = target.GetNumStopHooks();
520314f1b3e8SDimitry Andric if (num_hooks == 0) {
5204f034231aSEd Maste result.GetOutputStream().PutCString("No stop hooks.\n");
520514f1b3e8SDimitry Andric } else {
520614f1b3e8SDimitry Andric for (size_t i = 0; i < num_hooks; i++) {
5207ead24645SDimitry Andric Target::StopHookSP this_hook = target.GetStopHookAtIndex(i);
5208f034231aSEd Maste if (i > 0)
5209f034231aSEd Maste result.GetOutputStream().PutCString("\n");
52107fa27ce4SDimitry Andric this_hook->GetDescription(result.GetOutputStream(),
521114f1b3e8SDimitry Andric eDescriptionLevelFull);
5212f034231aSEd Maste }
5213f034231aSEd Maste }
5214f034231aSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
5215f034231aSEd Maste }
5216f034231aSEd Maste };
5217f034231aSEd Maste
5218f034231aSEd Maste #pragma mark CommandObjectMultiwordTargetStopHooks
5219f3fbd1c0SDimitry Andric
5220f034231aSEd Maste // CommandObjectMultiwordTargetStopHooks
5221f034231aSEd Maste
522214f1b3e8SDimitry Andric class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword {
5223f034231aSEd Maste public:
CommandObjectMultiwordTargetStopHooks(CommandInterpreter & interpreter)5224f3fbd1c0SDimitry Andric CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter)
522514f1b3e8SDimitry Andric : CommandObjectMultiword(
522614f1b3e8SDimitry Andric interpreter, "target stop-hook",
5227f3fbd1c0SDimitry Andric "Commands for operating on debugger target stop-hooks.",
522814f1b3e8SDimitry Andric "target stop-hook <subcommand> [<subcommand-options>]") {
522914f1b3e8SDimitry Andric LoadSubCommand("add", CommandObjectSP(
523014f1b3e8SDimitry Andric new CommandObjectTargetStopHookAdd(interpreter)));
523114f1b3e8SDimitry Andric LoadSubCommand(
523214f1b3e8SDimitry Andric "delete",
523314f1b3e8SDimitry Andric CommandObjectSP(new CommandObjectTargetStopHookDelete(interpreter)));
523414f1b3e8SDimitry Andric LoadSubCommand("disable",
523514f1b3e8SDimitry Andric CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
523614f1b3e8SDimitry Andric interpreter, false, "target stop-hook disable [<id>]",
523714f1b3e8SDimitry Andric "Disable a stop-hook.", "target stop-hook disable")));
523814f1b3e8SDimitry Andric LoadSubCommand("enable",
523914f1b3e8SDimitry Andric CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
524014f1b3e8SDimitry Andric interpreter, true, "target stop-hook enable [<id>]",
524114f1b3e8SDimitry Andric "Enable a stop-hook.", "target stop-hook enable")));
524214f1b3e8SDimitry Andric LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetStopHookList(
524314f1b3e8SDimitry Andric interpreter)));
5244f034231aSEd Maste }
5245f034231aSEd Maste
5246f3fbd1c0SDimitry Andric ~CommandObjectMultiwordTargetStopHooks() override = default;
5247f034231aSEd Maste };
5248f034231aSEd Maste
5249c0981da4SDimitry Andric #pragma mark CommandObjectTargetDumpTypesystem
5250c0981da4SDimitry Andric
5251c0981da4SDimitry Andric /// Dumps the TypeSystem of the selected Target.
5252c0981da4SDimitry Andric class CommandObjectTargetDumpTypesystem : public CommandObjectParsed {
5253c0981da4SDimitry Andric public:
CommandObjectTargetDumpTypesystem(CommandInterpreter & interpreter)5254c0981da4SDimitry Andric CommandObjectTargetDumpTypesystem(CommandInterpreter &interpreter)
5255c0981da4SDimitry Andric : CommandObjectParsed(
5256c0981da4SDimitry Andric interpreter, "target dump typesystem",
52577fa27ce4SDimitry Andric "Dump the state of the target's internal type system. Intended to "
52587fa27ce4SDimitry Andric "be used for debugging LLDB itself.",
5259c0981da4SDimitry Andric nullptr, eCommandRequiresTarget) {}
5260c0981da4SDimitry Andric
5261c0981da4SDimitry Andric ~CommandObjectTargetDumpTypesystem() override = default;
5262c0981da4SDimitry Andric
5263c0981da4SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)5264b1c73532SDimitry Andric void DoExecute(Args &command, CommandReturnObject &result) override {
5265c0981da4SDimitry Andric // Go over every scratch TypeSystem and dump to the command output.
5266e3b55780SDimitry Andric for (lldb::TypeSystemSP ts : GetSelectedTarget().GetScratchTypeSystems())
5267e3b55780SDimitry Andric if (ts)
5268c0981da4SDimitry Andric ts->Dump(result.GetOutputStream().AsRawOstream());
5269c0981da4SDimitry Andric
5270c0981da4SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
5271c0981da4SDimitry Andric }
5272c0981da4SDimitry Andric };
5273c0981da4SDimitry Andric
52747fa27ce4SDimitry Andric #pragma mark CommandObjectTargetDumpSectionLoadList
52757fa27ce4SDimitry Andric
52767fa27ce4SDimitry Andric /// Dumps the SectionLoadList of the selected Target.
52777fa27ce4SDimitry Andric class CommandObjectTargetDumpSectionLoadList : public CommandObjectParsed {
52787fa27ce4SDimitry Andric public:
CommandObjectTargetDumpSectionLoadList(CommandInterpreter & interpreter)52797fa27ce4SDimitry Andric CommandObjectTargetDumpSectionLoadList(CommandInterpreter &interpreter)
52807fa27ce4SDimitry Andric : CommandObjectParsed(
52817fa27ce4SDimitry Andric interpreter, "target dump section-load-list",
52827fa27ce4SDimitry Andric "Dump the state of the target's internal section load list. "
52837fa27ce4SDimitry Andric "Intended to be used for debugging LLDB itself.",
52847fa27ce4SDimitry Andric nullptr, eCommandRequiresTarget) {}
52857fa27ce4SDimitry Andric
52867fa27ce4SDimitry Andric ~CommandObjectTargetDumpSectionLoadList() override = default;
52877fa27ce4SDimitry Andric
52887fa27ce4SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)5289b1c73532SDimitry Andric void DoExecute(Args &command, CommandReturnObject &result) override {
52907fa27ce4SDimitry Andric Target &target = GetSelectedTarget();
52917fa27ce4SDimitry Andric target.GetSectionLoadList().Dump(result.GetOutputStream(), &target);
52927fa27ce4SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
52937fa27ce4SDimitry Andric }
52947fa27ce4SDimitry Andric };
52957fa27ce4SDimitry Andric
5296c0981da4SDimitry Andric #pragma mark CommandObjectTargetDump
5297c0981da4SDimitry Andric
5298c0981da4SDimitry Andric /// Multi-word command for 'target dump'.
5299c0981da4SDimitry Andric class CommandObjectTargetDump : public CommandObjectMultiword {
5300c0981da4SDimitry Andric public:
5301c0981da4SDimitry Andric // Constructors and Destructors
CommandObjectTargetDump(CommandInterpreter & interpreter)5302c0981da4SDimitry Andric CommandObjectTargetDump(CommandInterpreter &interpreter)
5303c0981da4SDimitry Andric : CommandObjectMultiword(
5304c0981da4SDimitry Andric interpreter, "target dump",
5305c0981da4SDimitry Andric "Commands for dumping information about the target.",
53067fa27ce4SDimitry Andric "target dump [typesystem|section-load-list]") {
5307c0981da4SDimitry Andric LoadSubCommand(
5308c0981da4SDimitry Andric "typesystem",
5309c0981da4SDimitry Andric CommandObjectSP(new CommandObjectTargetDumpTypesystem(interpreter)));
53107fa27ce4SDimitry Andric LoadSubCommand("section-load-list",
53117fa27ce4SDimitry Andric CommandObjectSP(new CommandObjectTargetDumpSectionLoadList(
53127fa27ce4SDimitry Andric interpreter)));
5313c0981da4SDimitry Andric }
5314c0981da4SDimitry Andric
5315c0981da4SDimitry Andric ~CommandObjectTargetDump() override = default;
5316c0981da4SDimitry Andric };
5317c0981da4SDimitry Andric
5318f034231aSEd Maste #pragma mark CommandObjectMultiwordTarget
5319f034231aSEd Maste
5320f034231aSEd Maste // CommandObjectMultiwordTarget
5321f034231aSEd Maste
CommandObjectMultiwordTarget(CommandInterpreter & interpreter)532214f1b3e8SDimitry Andric CommandObjectMultiwordTarget::CommandObjectMultiwordTarget(
532314f1b3e8SDimitry Andric CommandInterpreter &interpreter)
532414f1b3e8SDimitry Andric : CommandObjectMultiword(interpreter, "target",
532514f1b3e8SDimitry Andric "Commands for operating on debugger targets.",
532614f1b3e8SDimitry Andric "target <subcommand> [<subcommand-options>]") {
532714f1b3e8SDimitry Andric LoadSubCommand("create",
532814f1b3e8SDimitry Andric CommandObjectSP(new CommandObjectTargetCreate(interpreter)));
532914f1b3e8SDimitry Andric LoadSubCommand("delete",
533014f1b3e8SDimitry Andric CommandObjectSP(new CommandObjectTargetDelete(interpreter)));
5331c0981da4SDimitry Andric LoadSubCommand("dump",
5332c0981da4SDimitry Andric CommandObjectSP(new CommandObjectTargetDump(interpreter)));
533314f1b3e8SDimitry Andric LoadSubCommand("list",
533414f1b3e8SDimitry Andric CommandObjectSP(new CommandObjectTargetList(interpreter)));
533514f1b3e8SDimitry Andric LoadSubCommand("select",
533614f1b3e8SDimitry Andric CommandObjectSP(new CommandObjectTargetSelect(interpreter)));
5337cfca06d7SDimitry Andric LoadSubCommand("show-launch-environment",
5338cfca06d7SDimitry Andric CommandObjectSP(new CommandObjectTargetShowLaunchEnvironment(
5339cfca06d7SDimitry Andric interpreter)));
534014f1b3e8SDimitry Andric LoadSubCommand(
534114f1b3e8SDimitry Andric "stop-hook",
534214f1b3e8SDimitry Andric CommandObjectSP(new CommandObjectMultiwordTargetStopHooks(interpreter)));
534314f1b3e8SDimitry Andric LoadSubCommand("modules",
534414f1b3e8SDimitry Andric CommandObjectSP(new CommandObjectTargetModules(interpreter)));
534514f1b3e8SDimitry Andric LoadSubCommand("symbols",
534614f1b3e8SDimitry Andric CommandObjectSP(new CommandObjectTargetSymbols(interpreter)));
534714f1b3e8SDimitry Andric LoadSubCommand("variable",
534814f1b3e8SDimitry Andric CommandObjectSP(new CommandObjectTargetVariable(interpreter)));
5349f034231aSEd Maste }
5350f034231aSEd Maste
5351f3fbd1c0SDimitry Andric CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget() = default;
5352