xref: /src/contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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