15ffd83dbSDimitry Andric //===-- CommandObjectTarget.cpp -------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "CommandObjectTarget.h"
100b57cec5SDimitry Andric 
11c9157d92SDimitry Andric #include "lldb/Core/Address.h"
120b57cec5SDimitry Andric #include "lldb/Core/Debugger.h"
130b57cec5SDimitry Andric #include "lldb/Core/IOHandler.h"
140b57cec5SDimitry Andric #include "lldb/Core/Module.h"
150b57cec5SDimitry Andric #include "lldb/Core/ModuleSpec.h"
16c9157d92SDimitry Andric #include "lldb/Core/PluginManager.h"
170b57cec5SDimitry Andric #include "lldb/Core/Section.h"
180b57cec5SDimitry Andric #include "lldb/Core/ValueObjectVariable.h"
190b57cec5SDimitry Andric #include "lldb/DataFormatters/ValueObjectPrinter.h"
200b57cec5SDimitry Andric #include "lldb/Host/OptionParser.h"
210b57cec5SDimitry Andric #include "lldb/Interpreter/CommandInterpreter.h"
22fcaf7f86SDimitry Andric #include "lldb/Interpreter/CommandOptionArgumentTable.h"
230b57cec5SDimitry Andric #include "lldb/Interpreter/CommandReturnObject.h"
240b57cec5SDimitry Andric #include "lldb/Interpreter/OptionArgParser.h"
250b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupArchitecture.h"
260b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupBoolean.h"
270b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupFile.h"
280b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupFormat.h"
29e8d8bef9SDimitry Andric #include "lldb/Interpreter/OptionGroupPlatform.h"
30e8d8bef9SDimitry Andric #include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
310b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupString.h"
320b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupUInt64.h"
330b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupUUID.h"
340b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
350b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupVariable.h"
360b57cec5SDimitry Andric #include "lldb/Interpreter/Options.h"
370b57cec5SDimitry Andric #include "lldb/Symbol/CompileUnit.h"
380b57cec5SDimitry Andric #include "lldb/Symbol/FuncUnwinders.h"
390b57cec5SDimitry Andric #include "lldb/Symbol/LineTable.h"
400b57cec5SDimitry Andric #include "lldb/Symbol/ObjectFile.h"
410b57cec5SDimitry Andric #include "lldb/Symbol/SymbolFile.h"
420b57cec5SDimitry Andric #include "lldb/Symbol/UnwindPlan.h"
430b57cec5SDimitry Andric #include "lldb/Symbol/VariableList.h"
440b57cec5SDimitry Andric #include "lldb/Target/ABI.h"
450b57cec5SDimitry Andric #include "lldb/Target/Process.h"
460b57cec5SDimitry Andric #include "lldb/Target/RegisterContext.h"
470b57cec5SDimitry Andric #include "lldb/Target/SectionLoadList.h"
480b57cec5SDimitry Andric #include "lldb/Target/StackFrame.h"
490b57cec5SDimitry Andric #include "lldb/Target/Thread.h"
500b57cec5SDimitry Andric #include "lldb/Target/ThreadSpec.h"
510b57cec5SDimitry Andric #include "lldb/Utility/Args.h"
52753f127fSDimitry Andric #include "lldb/Utility/ConstString.h"
53753f127fSDimitry Andric #include "lldb/Utility/FileSpec.h"
5481ad6265SDimitry Andric #include "lldb/Utility/LLDBLog.h"
550b57cec5SDimitry Andric #include "lldb/Utility/State.h"
56*a58f00eaSDimitry Andric #include "lldb/Utility/Stream.h"
57c9157d92SDimitry Andric #include "lldb/Utility/StructuredData.h"
580b57cec5SDimitry Andric #include "lldb/Utility/Timer.h"
5981ad6265SDimitry Andric #include "lldb/lldb-enumerations.h"
6081ad6265SDimitry Andric #include "lldb/lldb-private-enumerations.h"
610b57cec5SDimitry Andric 
62753f127fSDimitry Andric #include "clang/CodeGen/ObjectFilePCHContainerOperations.h"
63753f127fSDimitry Andric #include "clang/Frontend/CompilerInstance.h"
64753f127fSDimitry Andric #include "clang/Frontend/CompilerInvocation.h"
65753f127fSDimitry Andric #include "clang/Frontend/FrontendActions.h"
66e8d8bef9SDimitry Andric #include "llvm/ADT/ScopeExit.h"
67c9157d92SDimitry Andric #include "llvm/ADT/StringRef.h"
680b57cec5SDimitry Andric #include "llvm/Support/FileSystem.h"
690b57cec5SDimitry Andric #include "llvm/Support/FormatAdapters.h"
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric 
720b57cec5SDimitry Andric using namespace lldb;
730b57cec5SDimitry Andric using namespace lldb_private;
740b57cec5SDimitry Andric 
DumpTargetInfo(uint32_t target_idx,Target * target,const char * prefix_cstr,bool show_stopped_process_status,Stream & strm)750b57cec5SDimitry Andric static void DumpTargetInfo(uint32_t target_idx, Target *target,
760b57cec5SDimitry Andric                            const char *prefix_cstr,
770b57cec5SDimitry Andric                            bool show_stopped_process_status, Stream &strm) {
780b57cec5SDimitry Andric   const ArchSpec &target_arch = target->GetArchitecture();
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric   Module *exe_module = target->GetExecutableModulePointer();
810b57cec5SDimitry Andric   char exe_path[PATH_MAX];
820b57cec5SDimitry Andric   bool exe_valid = false;
830b57cec5SDimitry Andric   if (exe_module)
840b57cec5SDimitry Andric     exe_valid = exe_module->GetFileSpec().GetPath(exe_path, sizeof(exe_path));
850b57cec5SDimitry Andric 
860b57cec5SDimitry Andric   if (!exe_valid)
870b57cec5SDimitry Andric     ::strcpy(exe_path, "<none>");
880b57cec5SDimitry Andric 
89fe013be4SDimitry Andric   std::string formatted_label = "";
90fe013be4SDimitry Andric   const std::string &label = target->GetLabel();
91fe013be4SDimitry Andric   if (!label.empty()) {
92fe013be4SDimitry Andric     formatted_label = " (" + label + ")";
93fe013be4SDimitry Andric   }
94fe013be4SDimitry Andric 
95fe013be4SDimitry Andric   strm.Printf("%starget #%u%s: %s", prefix_cstr ? prefix_cstr : "", target_idx,
96fe013be4SDimitry Andric               formatted_label.data(), exe_path);
970b57cec5SDimitry Andric 
980b57cec5SDimitry Andric   uint32_t properties = 0;
990b57cec5SDimitry Andric   if (target_arch.IsValid()) {
1000b57cec5SDimitry Andric     strm.Printf("%sarch=", properties++ > 0 ? ", " : " ( ");
101480093f4SDimitry Andric     target_arch.DumpTriple(strm.AsRawOstream());
1020b57cec5SDimitry Andric     properties++;
1030b57cec5SDimitry Andric   }
1040b57cec5SDimitry Andric   PlatformSP platform_sp(target->GetPlatform());
1050b57cec5SDimitry Andric   if (platform_sp)
10681ad6265SDimitry Andric     strm.Format("{0}platform={1}", properties++ > 0 ? ", " : " ( ",
10781ad6265SDimitry Andric                 platform_sp->GetName());
1080b57cec5SDimitry Andric 
1090b57cec5SDimitry Andric   ProcessSP process_sp(target->GetProcessSP());
1100b57cec5SDimitry Andric   bool show_process_status = false;
1110b57cec5SDimitry Andric   if (process_sp) {
1120b57cec5SDimitry Andric     lldb::pid_t pid = process_sp->GetID();
1130b57cec5SDimitry Andric     StateType state = process_sp->GetState();
1140b57cec5SDimitry Andric     if (show_stopped_process_status)
1150b57cec5SDimitry Andric       show_process_status = StateIsStoppedState(state, true);
1160b57cec5SDimitry Andric     const char *state_cstr = StateAsCString(state);
1170b57cec5SDimitry Andric     if (pid != LLDB_INVALID_PROCESS_ID)
1180b57cec5SDimitry Andric       strm.Printf("%spid=%" PRIu64, properties++ > 0 ? ", " : " ( ", pid);
1190b57cec5SDimitry Andric     strm.Printf("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
1200b57cec5SDimitry Andric   }
1210b57cec5SDimitry Andric   if (properties > 0)
1220b57cec5SDimitry Andric     strm.PutCString(" )\n");
1230b57cec5SDimitry Andric   else
1240b57cec5SDimitry Andric     strm.EOL();
1250b57cec5SDimitry Andric   if (show_process_status) {
1260b57cec5SDimitry Andric     const bool only_threads_with_stop_reason = true;
1270b57cec5SDimitry Andric     const uint32_t start_frame = 0;
1280b57cec5SDimitry Andric     const uint32_t num_frames = 1;
1290b57cec5SDimitry Andric     const uint32_t num_frames_with_source = 1;
1300b57cec5SDimitry Andric     const bool stop_format = false;
1310b57cec5SDimitry Andric     process_sp->GetStatus(strm);
1320b57cec5SDimitry Andric     process_sp->GetThreadStatus(strm, only_threads_with_stop_reason,
133480093f4SDimitry Andric                                 start_frame, num_frames, num_frames_with_source,
134480093f4SDimitry Andric                                 stop_format);
1350b57cec5SDimitry Andric   }
1360b57cec5SDimitry Andric }
1370b57cec5SDimitry Andric 
DumpTargetList(TargetList & target_list,bool show_stopped_process_status,Stream & strm)1380b57cec5SDimitry Andric static uint32_t DumpTargetList(TargetList &target_list,
1390b57cec5SDimitry Andric                                bool show_stopped_process_status, Stream &strm) {
1400b57cec5SDimitry Andric   const uint32_t num_targets = target_list.GetNumTargets();
1410b57cec5SDimitry Andric   if (num_targets) {
1420b57cec5SDimitry Andric     TargetSP selected_target_sp(target_list.GetSelectedTarget());
1430b57cec5SDimitry Andric     strm.PutCString("Current targets:\n");
1440b57cec5SDimitry Andric     for (uint32_t i = 0; i < num_targets; ++i) {
1450b57cec5SDimitry Andric       TargetSP target_sp(target_list.GetTargetAtIndex(i));
1460b57cec5SDimitry Andric       if (target_sp) {
1470b57cec5SDimitry Andric         bool is_selected = target_sp.get() == selected_target_sp.get();
1480b57cec5SDimitry Andric         DumpTargetInfo(i, target_sp.get(), is_selected ? "* " : "  ",
1490b57cec5SDimitry Andric                        show_stopped_process_status, strm);
1500b57cec5SDimitry Andric       }
1510b57cec5SDimitry Andric     }
1520b57cec5SDimitry Andric   }
1530b57cec5SDimitry Andric   return num_targets;
1540b57cec5SDimitry Andric }
1550b57cec5SDimitry Andric 
1569dba64beSDimitry Andric #define LLDB_OPTIONS_target_dependents
1579dba64beSDimitry Andric #include "CommandOptions.inc"
1580b57cec5SDimitry Andric 
1590b57cec5SDimitry Andric class OptionGroupDependents : public OptionGroup {
1600b57cec5SDimitry Andric public:
161fe6060f1SDimitry Andric   OptionGroupDependents() = default;
1620b57cec5SDimitry Andric 
163fe6060f1SDimitry Andric   ~OptionGroupDependents() override = default;
1640b57cec5SDimitry Andric 
GetDefinitions()1650b57cec5SDimitry Andric   llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
166bdd1243dSDimitry Andric     return llvm::ArrayRef(g_target_dependents_options);
1670b57cec5SDimitry Andric   }
1680b57cec5SDimitry Andric 
SetOptionValue(uint32_t option_idx,llvm::StringRef option_value,ExecutionContext * execution_context)1690b57cec5SDimitry Andric   Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
1700b57cec5SDimitry Andric                         ExecutionContext *execution_context) override {
1710b57cec5SDimitry Andric     Status error;
1720b57cec5SDimitry Andric 
1730b57cec5SDimitry Andric     // For compatibility no value means don't load dependents.
1740b57cec5SDimitry Andric     if (option_value.empty()) {
1750b57cec5SDimitry Andric       m_load_dependent_files = eLoadDependentsNo;
1760b57cec5SDimitry Andric       return error;
1770b57cec5SDimitry Andric     }
1780b57cec5SDimitry Andric 
1799dba64beSDimitry Andric     const char short_option =
1809dba64beSDimitry Andric         g_target_dependents_options[option_idx].short_option;
1810b57cec5SDimitry Andric     if (short_option == 'd') {
1820b57cec5SDimitry Andric       LoadDependentFiles tmp_load_dependents;
1830b57cec5SDimitry Andric       tmp_load_dependents = (LoadDependentFiles)OptionArgParser::ToOptionEnum(
1849dba64beSDimitry Andric           option_value, g_target_dependents_options[option_idx].enum_values, 0,
1859dba64beSDimitry Andric           error);
1860b57cec5SDimitry Andric       if (error.Success())
1870b57cec5SDimitry Andric         m_load_dependent_files = tmp_load_dependents;
1880b57cec5SDimitry Andric     } else {
1890b57cec5SDimitry Andric       error.SetErrorStringWithFormat("unrecognized short option '%c'",
1900b57cec5SDimitry Andric                                      short_option);
1910b57cec5SDimitry Andric     }
1920b57cec5SDimitry Andric 
1930b57cec5SDimitry Andric     return error;
1940b57cec5SDimitry Andric   }
1950b57cec5SDimitry Andric 
1960b57cec5SDimitry Andric   Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete;
1970b57cec5SDimitry Andric 
OptionParsingStarting(ExecutionContext * execution_context)1980b57cec5SDimitry Andric   void OptionParsingStarting(ExecutionContext *execution_context) override {
1990b57cec5SDimitry Andric     m_load_dependent_files = eLoadDependentsDefault;
2000b57cec5SDimitry Andric   }
2010b57cec5SDimitry Andric 
2020b57cec5SDimitry Andric   LoadDependentFiles m_load_dependent_files;
2030b57cec5SDimitry Andric 
2040b57cec5SDimitry Andric private:
2055ffd83dbSDimitry Andric   OptionGroupDependents(const OptionGroupDependents &) = delete;
2065ffd83dbSDimitry Andric   const OptionGroupDependents &
2075ffd83dbSDimitry Andric   operator=(const OptionGroupDependents &) = delete;
2080b57cec5SDimitry Andric };
2090b57cec5SDimitry Andric 
2100b57cec5SDimitry Andric #pragma mark CommandObjectTargetCreate
2110b57cec5SDimitry Andric 
2120b57cec5SDimitry Andric class CommandObjectTargetCreate : public CommandObjectParsed {
2130b57cec5SDimitry Andric public:
CommandObjectTargetCreate(CommandInterpreter & interpreter)2140b57cec5SDimitry Andric   CommandObjectTargetCreate(CommandInterpreter &interpreter)
2150b57cec5SDimitry Andric       : CommandObjectParsed(
2160b57cec5SDimitry Andric             interpreter, "target create",
2170b57cec5SDimitry Andric             "Create a target using the argument as the main executable.",
2180b57cec5SDimitry Andric             nullptr),
219e8d8bef9SDimitry Andric         m_platform_options(true), // Include the --platform option.
2200b57cec5SDimitry Andric         m_core_file(LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename,
2210b57cec5SDimitry Andric                     "Fullpath to a core file to use for this target."),
222fe013be4SDimitry Andric         m_label(LLDB_OPT_SET_1, false, "label", 'l', 0, eArgTypeName,
223fe013be4SDimitry Andric                 "Optional name for this target.", nullptr),
2240b57cec5SDimitry Andric         m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
2250b57cec5SDimitry Andric                       eArgTypeFilename,
2260b57cec5SDimitry Andric                       "Fullpath to a stand alone debug "
2270b57cec5SDimitry Andric                       "symbols file for when debug symbols "
2280b57cec5SDimitry Andric                       "are not in the executable."),
2290b57cec5SDimitry Andric         m_remote_file(
2300b57cec5SDimitry Andric             LLDB_OPT_SET_1, false, "remote-file", 'r', 0, eArgTypeFilename,
23104eeddc0SDimitry Andric             "Fullpath to the file on the remote host if debugging remotely.") {
2320b57cec5SDimitry Andric     CommandArgumentEntry arg;
2330b57cec5SDimitry Andric     CommandArgumentData file_arg;
2340b57cec5SDimitry Andric 
2350b57cec5SDimitry Andric     // Define the first (and only) variant of this arg.
2360b57cec5SDimitry Andric     file_arg.arg_type = eArgTypeFilename;
2370b57cec5SDimitry Andric     file_arg.arg_repetition = eArgRepeatPlain;
2380b57cec5SDimitry Andric 
2390b57cec5SDimitry Andric     // There is only one variant this argument could be; put it into the
2400b57cec5SDimitry Andric     // argument entry.
2410b57cec5SDimitry Andric     arg.push_back(file_arg);
2420b57cec5SDimitry Andric 
2430b57cec5SDimitry Andric     // Push the data for the first argument into the m_arguments vector.
2440b57cec5SDimitry Andric     m_arguments.push_back(arg);
2450b57cec5SDimitry Andric 
2460b57cec5SDimitry Andric     m_option_group.Append(&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
247e8d8bef9SDimitry Andric     m_option_group.Append(&m_platform_options, LLDB_OPT_SET_ALL, 1);
2480b57cec5SDimitry Andric     m_option_group.Append(&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
249fe013be4SDimitry Andric     m_option_group.Append(&m_label, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2500b57cec5SDimitry Andric     m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2510b57cec5SDimitry Andric     m_option_group.Append(&m_remote_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2520b57cec5SDimitry Andric     m_option_group.Append(&m_add_dependents, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2530b57cec5SDimitry Andric     m_option_group.Finalize();
2540b57cec5SDimitry Andric   }
2550b57cec5SDimitry Andric 
2560b57cec5SDimitry Andric   ~CommandObjectTargetCreate() override = default;
2570b57cec5SDimitry Andric 
GetOptions()2580b57cec5SDimitry Andric   Options *GetOptions() override { return &m_option_group; }
2590b57cec5SDimitry Andric 
2609dba64beSDimitry Andric   void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)2619dba64beSDimitry Andric   HandleArgumentCompletion(CompletionRequest &request,
2620b57cec5SDimitry Andric                            OptionElementVector &opt_element_vector) override {
263fe013be4SDimitry Andric     lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
264fe013be4SDimitry Andric         GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr);
2650b57cec5SDimitry Andric   }
2660b57cec5SDimitry Andric 
2670b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)268c9157d92SDimitry Andric   void DoExecute(Args &command, CommandReturnObject &result) override {
2690b57cec5SDimitry Andric     const size_t argc = command.GetArgumentCount();
2700b57cec5SDimitry Andric     FileSpec core_file(m_core_file.GetOptionValue().GetCurrentValue());
2710b57cec5SDimitry Andric     FileSpec remote_file(m_remote_file.GetOptionValue().GetCurrentValue());
2720b57cec5SDimitry Andric 
2730b57cec5SDimitry Andric     if (core_file) {
2745ffd83dbSDimitry Andric       auto file = FileSystem::Instance().Open(
275349cc55cSDimitry Andric           core_file, lldb_private::File::eOpenOptionReadOnly);
2765ffd83dbSDimitry Andric 
2775ffd83dbSDimitry Andric       if (!file) {
2785ffd83dbSDimitry Andric         result.AppendErrorWithFormatv("Cannot open '{0}': {1}.",
2795ffd83dbSDimitry Andric                                       core_file.GetPath(),
2805ffd83dbSDimitry Andric                                       llvm::toString(file.takeError()));
281c9157d92SDimitry Andric         return;
2820b57cec5SDimitry Andric       }
2830b57cec5SDimitry Andric     }
2840b57cec5SDimitry Andric 
2850b57cec5SDimitry Andric     if (argc == 1 || core_file || remote_file) {
2860b57cec5SDimitry Andric       FileSpec symfile(m_symbol_file.GetOptionValue().GetCurrentValue());
2870b57cec5SDimitry Andric       if (symfile) {
2885ffd83dbSDimitry Andric         auto file = FileSystem::Instance().Open(
289349cc55cSDimitry Andric             symfile, lldb_private::File::eOpenOptionReadOnly);
2905ffd83dbSDimitry Andric 
2915ffd83dbSDimitry Andric         if (!file) {
2925ffd83dbSDimitry Andric           result.AppendErrorWithFormatv("Cannot open '{0}': {1}.",
2935ffd83dbSDimitry Andric                                         symfile.GetPath(),
2945ffd83dbSDimitry Andric                                         llvm::toString(file.takeError()));
295c9157d92SDimitry Andric           return;
2960b57cec5SDimitry Andric         }
2970b57cec5SDimitry Andric       }
2980b57cec5SDimitry Andric 
2990b57cec5SDimitry Andric       const char *file_path = command.GetArgumentAtIndex(0);
300e8d8bef9SDimitry Andric       LLDB_SCOPED_TIMERF("(lldb) target create '%s'", file_path);
3010b57cec5SDimitry Andric 
3020b57cec5SDimitry Andric       bool must_set_platform_path = false;
3030b57cec5SDimitry Andric 
3040b57cec5SDimitry Andric       Debugger &debugger = GetDebugger();
3050b57cec5SDimitry Andric 
3060b57cec5SDimitry Andric       TargetSP target_sp;
3070b57cec5SDimitry Andric       llvm::StringRef arch_cstr = m_arch_option.GetArchitectureName();
3080b57cec5SDimitry Andric       Status error(debugger.GetTargetList().CreateTarget(
3090b57cec5SDimitry Andric           debugger, file_path, arch_cstr,
310e8d8bef9SDimitry Andric           m_add_dependents.m_load_dependent_files, &m_platform_options,
311e8d8bef9SDimitry Andric           target_sp));
3120b57cec5SDimitry Andric 
313e8d8bef9SDimitry Andric       if (!target_sp) {
314e8d8bef9SDimitry Andric         result.AppendError(error.AsCString());
315c9157d92SDimitry Andric         return;
316e8d8bef9SDimitry Andric       }
317e8d8bef9SDimitry Andric 
318fe013be4SDimitry Andric       const llvm::StringRef label =
319fe013be4SDimitry Andric           m_label.GetOptionValue().GetCurrentValueAsRef();
320fe013be4SDimitry Andric       if (!label.empty()) {
321fe013be4SDimitry Andric         if (auto E = target_sp->SetLabel(label))
322fe013be4SDimitry Andric           result.SetError(std::move(E));
323c9157d92SDimitry Andric         return;
324fe013be4SDimitry Andric       }
325fe013be4SDimitry Andric 
326e8d8bef9SDimitry Andric       auto on_error = llvm::make_scope_exit(
327e8d8bef9SDimitry Andric           [&target_list = debugger.GetTargetList(), &target_sp]() {
328e8d8bef9SDimitry Andric             target_list.DeleteTarget(target_sp);
329e8d8bef9SDimitry Andric           });
330e8d8bef9SDimitry Andric 
3310b57cec5SDimitry Andric       // Only get the platform after we create the target because we might
3320b57cec5SDimitry Andric       // have switched platforms depending on what the arguments were to
3330b57cec5SDimitry Andric       // CreateTarget() we can't rely on the selected platform.
3340b57cec5SDimitry Andric 
3350b57cec5SDimitry Andric       PlatformSP platform_sp = target_sp->GetPlatform();
3360b57cec5SDimitry Andric 
33781ad6265SDimitry Andric       FileSpec file_spec;
33881ad6265SDimitry Andric       if (file_path) {
33981ad6265SDimitry Andric         file_spec.SetFile(file_path, FileSpec::Style::native);
34081ad6265SDimitry Andric         FileSystem::Instance().Resolve(file_spec);
34181ad6265SDimitry Andric 
34281ad6265SDimitry Andric         // Try to resolve the exe based on PATH and/or platform-specific
34381ad6265SDimitry Andric         // suffixes, but only if using the host platform.
34481ad6265SDimitry Andric         if (platform_sp && platform_sp->IsHost() &&
34581ad6265SDimitry Andric             !FileSystem::Instance().Exists(file_spec))
34681ad6265SDimitry Andric           FileSystem::Instance().ResolveExecutableLocation(file_spec);
34781ad6265SDimitry Andric       }
34881ad6265SDimitry Andric 
3490b57cec5SDimitry Andric       if (remote_file) {
3500b57cec5SDimitry Andric         if (platform_sp) {
3510b57cec5SDimitry Andric           // I have a remote file.. two possible cases
3520b57cec5SDimitry Andric           if (file_spec && FileSystem::Instance().Exists(file_spec)) {
3530b57cec5SDimitry Andric             // if the remote file does not exist, push it there
3540b57cec5SDimitry Andric             if (!platform_sp->GetFileExists(remote_file)) {
3550b57cec5SDimitry Andric               Status err = platform_sp->PutFile(file_spec, remote_file);
3560b57cec5SDimitry Andric               if (err.Fail()) {
3570b57cec5SDimitry Andric                 result.AppendError(err.AsCString());
358c9157d92SDimitry Andric                 return;
3590b57cec5SDimitry Andric               }
3600b57cec5SDimitry Andric             }
3610b57cec5SDimitry Andric           } else {
3620b57cec5SDimitry Andric             // there is no local file and we need one
3630b57cec5SDimitry Andric             // in order to make the remote ---> local transfer we need a
3640b57cec5SDimitry Andric             // platform
3650b57cec5SDimitry Andric             // TODO: if the user has passed in a --platform argument, use it
3660b57cec5SDimitry Andric             // to fetch the right platform
3670b57cec5SDimitry Andric             if (file_path) {
3680b57cec5SDimitry Andric               // copy the remote file to the local file
3690b57cec5SDimitry Andric               Status err = platform_sp->GetFile(remote_file, file_spec);
3700b57cec5SDimitry Andric               if (err.Fail()) {
3710b57cec5SDimitry Andric                 result.AppendError(err.AsCString());
372c9157d92SDimitry Andric                 return;
3730b57cec5SDimitry Andric               }
3740b57cec5SDimitry Andric             } else {
37581ad6265SDimitry Andric               // If the remote file exists, we can debug reading that out of
37681ad6265SDimitry Andric               // memory.  If the platform is already connected to an lldb-server
37781ad6265SDimitry Andric               // then we can at least check the file exists remotely.  Otherwise
37881ad6265SDimitry Andric               // we'll just have to trust that it will be there when we do
37981ad6265SDimitry Andric               // process connect.
38081ad6265SDimitry Andric               // I don't do this for the host platform because it seems odd to
38181ad6265SDimitry Andric               // support supplying a remote file but no local file for a local
38281ad6265SDimitry Andric               // debug session.
38381ad6265SDimitry Andric               if (platform_sp->IsHost()) {
38481ad6265SDimitry Andric                 result.AppendError("Supply a local file, not a remote file, "
38581ad6265SDimitry Andric                                    "when debugging on the host.");
386c9157d92SDimitry Andric                 return;
38781ad6265SDimitry Andric               }
38881ad6265SDimitry Andric               if (platform_sp->IsConnected() && !platform_sp->GetFileExists(remote_file)) {
3890b57cec5SDimitry Andric                 result.AppendError("remote --> local transfer without local "
3900b57cec5SDimitry Andric                                  "path is not implemented yet");
391c9157d92SDimitry Andric                 return;
3920b57cec5SDimitry Andric               }
39381ad6265SDimitry Andric               // Since there's only a remote file, we need to set the executable
39481ad6265SDimitry Andric               // file spec to the remote one.
39581ad6265SDimitry Andric               ProcessLaunchInfo launch_info = target_sp->GetProcessLaunchInfo();
39681ad6265SDimitry Andric               launch_info.SetExecutableFile(FileSpec(remote_file), true);
39781ad6265SDimitry Andric               target_sp->SetProcessLaunchInfo(launch_info);
39881ad6265SDimitry Andric             }
3990b57cec5SDimitry Andric           }
4000b57cec5SDimitry Andric         } else {
4010b57cec5SDimitry Andric           result.AppendError("no platform found for target");
402c9157d92SDimitry Andric           return;
4030b57cec5SDimitry Andric         }
4040b57cec5SDimitry Andric       }
4050b57cec5SDimitry Andric 
4060b57cec5SDimitry Andric       if (symfile || remote_file) {
4070b57cec5SDimitry Andric         ModuleSP module_sp(target_sp->GetExecutableModule());
4080b57cec5SDimitry Andric         if (module_sp) {
4090b57cec5SDimitry Andric           if (symfile)
4100b57cec5SDimitry Andric             module_sp->SetSymbolFileFileSpec(symfile);
4110b57cec5SDimitry Andric           if (remote_file) {
4120b57cec5SDimitry Andric             std::string remote_path = remote_file.GetPath();
4130b57cec5SDimitry Andric             target_sp->SetArg0(remote_path.c_str());
4140b57cec5SDimitry Andric             module_sp->SetPlatformFileSpec(remote_file);
4150b57cec5SDimitry Andric           }
4160b57cec5SDimitry Andric         }
4170b57cec5SDimitry Andric       }
4180b57cec5SDimitry Andric 
4190b57cec5SDimitry Andric       if (must_set_platform_path) {
4200b57cec5SDimitry Andric         ModuleSpec main_module_spec(file_spec);
421480093f4SDimitry Andric         ModuleSP module_sp =
422480093f4SDimitry Andric             target_sp->GetOrCreateModule(main_module_spec, true /* notify */);
4230b57cec5SDimitry Andric         if (module_sp)
4240b57cec5SDimitry Andric           module_sp->SetPlatformFileSpec(remote_file);
4250b57cec5SDimitry Andric       }
4265ffd83dbSDimitry Andric 
4270b57cec5SDimitry Andric       if (core_file) {
4280b57cec5SDimitry Andric         FileSpec core_file_dir;
429bdd1243dSDimitry Andric         core_file_dir.SetDirectory(core_file.GetDirectory());
4300b57cec5SDimitry Andric         target_sp->AppendExecutableSearchPaths(core_file_dir);
4310b57cec5SDimitry Andric 
4320b57cec5SDimitry Andric         ProcessSP process_sp(target_sp->CreateProcess(
433e8d8bef9SDimitry Andric             GetDebugger().GetListener(), llvm::StringRef(), &core_file, false));
4340b57cec5SDimitry Andric 
4350b57cec5SDimitry Andric         if (process_sp) {
4360b57cec5SDimitry Andric           // Seems weird that we Launch a core file, but that is what we
4370b57cec5SDimitry Andric           // do!
4380b57cec5SDimitry Andric           error = process_sp->LoadCore();
4390b57cec5SDimitry Andric 
4400b57cec5SDimitry Andric           if (error.Fail()) {
441c9157d92SDimitry Andric             result.AppendError(error.AsCString("unknown core file format"));
442c9157d92SDimitry Andric             return;
4430b57cec5SDimitry Andric           } else {
444e8d8bef9SDimitry Andric             result.AppendMessageWithFormatv(
445e8d8bef9SDimitry Andric                 "Core file '{0}' ({1}) was loaded.\n", core_file.GetPath(),
4460b57cec5SDimitry Andric                 target_sp->GetArchitecture().GetArchitectureName());
4470b57cec5SDimitry Andric             result.SetStatus(eReturnStatusSuccessFinishNoResult);
448e8d8bef9SDimitry Andric             on_error.release();
4490b57cec5SDimitry Andric           }
4500b57cec5SDimitry Andric         } else {
451c9157d92SDimitry Andric           result.AppendErrorWithFormatv("Unknown core file format '{0}'\n",
4525ffd83dbSDimitry Andric                                         core_file.GetPath());
4530b57cec5SDimitry Andric         }
4540b57cec5SDimitry Andric       } else {
4550b57cec5SDimitry Andric         result.AppendMessageWithFormat(
4569dba64beSDimitry Andric             "Current executable set to '%s' (%s).\n",
4579dba64beSDimitry Andric             file_spec.GetPath().c_str(),
4580b57cec5SDimitry Andric             target_sp->GetArchitecture().GetArchitectureName());
4590b57cec5SDimitry Andric         result.SetStatus(eReturnStatusSuccessFinishNoResult);
460e8d8bef9SDimitry Andric         on_error.release();
4610b57cec5SDimitry Andric       }
4620b57cec5SDimitry Andric     } else {
4630b57cec5SDimitry Andric       result.AppendErrorWithFormat("'%s' takes exactly one executable path "
4640b57cec5SDimitry Andric                                    "argument, or use the --core option.\n",
4650b57cec5SDimitry Andric                                    m_cmd_name.c_str());
4660b57cec5SDimitry Andric     }
4670b57cec5SDimitry Andric   }
4680b57cec5SDimitry Andric 
4690b57cec5SDimitry Andric private:
4700b57cec5SDimitry Andric   OptionGroupOptions m_option_group;
4710b57cec5SDimitry Andric   OptionGroupArchitecture m_arch_option;
472e8d8bef9SDimitry Andric   OptionGroupPlatform m_platform_options;
4730b57cec5SDimitry Andric   OptionGroupFile m_core_file;
474fe013be4SDimitry Andric   OptionGroupString m_label;
4750b57cec5SDimitry Andric   OptionGroupFile m_symbol_file;
4760b57cec5SDimitry Andric   OptionGroupFile m_remote_file;
4770b57cec5SDimitry Andric   OptionGroupDependents m_add_dependents;
4780b57cec5SDimitry Andric };
4790b57cec5SDimitry Andric 
4800b57cec5SDimitry Andric #pragma mark CommandObjectTargetList
4810b57cec5SDimitry Andric 
4820b57cec5SDimitry Andric class CommandObjectTargetList : public CommandObjectParsed {
4830b57cec5SDimitry Andric public:
CommandObjectTargetList(CommandInterpreter & interpreter)4840b57cec5SDimitry Andric   CommandObjectTargetList(CommandInterpreter &interpreter)
4850b57cec5SDimitry Andric       : CommandObjectParsed(
4860b57cec5SDimitry Andric             interpreter, "target list",
4870b57cec5SDimitry Andric             "List all current targets in the current debug session.", nullptr) {
4880b57cec5SDimitry Andric   }
4890b57cec5SDimitry Andric 
4900b57cec5SDimitry Andric   ~CommandObjectTargetList() override = default;
4910b57cec5SDimitry Andric 
4920b57cec5SDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)493c9157d92SDimitry Andric   void DoExecute(Args &args, CommandReturnObject &result) override {
4940b57cec5SDimitry Andric     Stream &strm = result.GetOutputStream();
4950b57cec5SDimitry Andric 
4960b57cec5SDimitry Andric     bool show_stopped_process_status = false;
4970b57cec5SDimitry Andric     if (DumpTargetList(GetDebugger().GetTargetList(),
4980b57cec5SDimitry Andric                        show_stopped_process_status, strm) == 0) {
4990b57cec5SDimitry Andric       strm.PutCString("No targets.\n");
5000b57cec5SDimitry Andric     }
5010b57cec5SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishResult);
5020b57cec5SDimitry Andric   }
5030b57cec5SDimitry Andric };
5040b57cec5SDimitry Andric 
5050b57cec5SDimitry Andric #pragma mark CommandObjectTargetSelect
5060b57cec5SDimitry Andric 
5070b57cec5SDimitry Andric class CommandObjectTargetSelect : public CommandObjectParsed {
5080b57cec5SDimitry Andric public:
CommandObjectTargetSelect(CommandInterpreter & interpreter)5090b57cec5SDimitry Andric   CommandObjectTargetSelect(CommandInterpreter &interpreter)
5100b57cec5SDimitry Andric       : CommandObjectParsed(
5110b57cec5SDimitry Andric             interpreter, "target select",
5120b57cec5SDimitry Andric             "Select a target as the current target by target index.", nullptr) {
51381ad6265SDimitry Andric     CommandArgumentData target_arg{eArgTypeTargetID, eArgRepeatPlain};
51481ad6265SDimitry Andric     m_arguments.push_back({target_arg});
5150b57cec5SDimitry Andric   }
5160b57cec5SDimitry Andric 
5170b57cec5SDimitry Andric   ~CommandObjectTargetSelect() override = default;
5180b57cec5SDimitry Andric 
5190b57cec5SDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)520c9157d92SDimitry Andric   void DoExecute(Args &args, CommandReturnObject &result) override {
5210b57cec5SDimitry Andric     if (args.GetArgumentCount() == 1) {
522fe013be4SDimitry Andric       const char *target_identifier = args.GetArgumentAtIndex(0);
523fe013be4SDimitry Andric       uint32_t target_idx = LLDB_INVALID_INDEX32;
5240b57cec5SDimitry Andric       TargetList &target_list = GetDebugger().GetTargetList();
5250b57cec5SDimitry Andric       const uint32_t num_targets = target_list.GetNumTargets();
526fe013be4SDimitry Andric       if (llvm::to_integer(target_identifier, target_idx)) {
5270b57cec5SDimitry Andric         if (target_idx < num_targets) {
528e8d8bef9SDimitry Andric           target_list.SetSelectedTarget(target_idx);
5290b57cec5SDimitry Andric           Stream &strm = result.GetOutputStream();
5300b57cec5SDimitry Andric           bool show_stopped_process_status = false;
5310b57cec5SDimitry Andric           DumpTargetList(target_list, show_stopped_process_status, strm);
5320b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishResult);
5330b57cec5SDimitry Andric         } else {
5340b57cec5SDimitry Andric           if (num_targets > 0) {
5350b57cec5SDimitry Andric             result.AppendErrorWithFormat(
5360b57cec5SDimitry Andric                 "index %u is out of range, valid target indexes are 0 - %u\n",
5370b57cec5SDimitry Andric                 target_idx, num_targets - 1);
5380b57cec5SDimitry Andric           } else {
5390b57cec5SDimitry Andric             result.AppendErrorWithFormat(
5400b57cec5SDimitry Andric                 "index %u is out of range since there are no active targets\n",
5410b57cec5SDimitry Andric                 target_idx);
5420b57cec5SDimitry Andric           }
5430b57cec5SDimitry Andric         }
5440b57cec5SDimitry Andric       } else {
545fe013be4SDimitry Andric         for (size_t i = 0; i < num_targets; i++) {
546fe013be4SDimitry Andric           if (TargetSP target_sp = target_list.GetTargetAtIndex(i)) {
547fe013be4SDimitry Andric             const std::string &label = target_sp->GetLabel();
548fe013be4SDimitry Andric             if (!label.empty() && label == target_identifier) {
549fe013be4SDimitry Andric               target_idx = i;
550fe013be4SDimitry Andric               break;
551fe013be4SDimitry Andric             }
552fe013be4SDimitry Andric           }
553fe013be4SDimitry Andric         }
554fe013be4SDimitry Andric 
555fe013be4SDimitry Andric         if (target_idx != LLDB_INVALID_INDEX32) {
556fe013be4SDimitry Andric           target_list.SetSelectedTarget(target_idx);
557fe013be4SDimitry Andric           Stream &strm = result.GetOutputStream();
558fe013be4SDimitry Andric           bool show_stopped_process_status = false;
559fe013be4SDimitry Andric           DumpTargetList(target_list, show_stopped_process_status, strm);
560fe013be4SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishResult);
561fe013be4SDimitry Andric         } else {
5620b57cec5SDimitry Andric           result.AppendErrorWithFormat("invalid index string value '%s'\n",
563fe013be4SDimitry Andric                                        target_identifier);
564fe013be4SDimitry Andric         }
5650b57cec5SDimitry Andric       }
5660b57cec5SDimitry Andric     } else {
5670b57cec5SDimitry Andric       result.AppendError(
5680b57cec5SDimitry Andric           "'target select' takes a single argument: a target index\n");
5690b57cec5SDimitry Andric     }
5700b57cec5SDimitry Andric   }
5710b57cec5SDimitry Andric };
5720b57cec5SDimitry Andric 
5735ffd83dbSDimitry Andric #pragma mark CommandObjectTargetDelete
5740b57cec5SDimitry Andric 
5750b57cec5SDimitry Andric class CommandObjectTargetDelete : public CommandObjectParsed {
5760b57cec5SDimitry Andric public:
CommandObjectTargetDelete(CommandInterpreter & interpreter)5770b57cec5SDimitry Andric   CommandObjectTargetDelete(CommandInterpreter &interpreter)
5780b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "target delete",
5790b57cec5SDimitry Andric                             "Delete one or more targets by target index.",
5800b57cec5SDimitry Andric                             nullptr),
58104eeddc0SDimitry Andric         m_all_option(LLDB_OPT_SET_1, false, "all", 'a', "Delete all targets.",
58204eeddc0SDimitry Andric                      false, true),
5830b57cec5SDimitry Andric         m_cleanup_option(
5840b57cec5SDimitry Andric             LLDB_OPT_SET_1, false, "clean", 'c',
5850b57cec5SDimitry Andric             "Perform extra cleanup to minimize memory consumption after "
5860b57cec5SDimitry Andric             "deleting the target.  "
5870b57cec5SDimitry Andric             "By default, LLDB will keep in memory any modules previously "
5880b57cec5SDimitry Andric             "loaded by the target as well "
5890b57cec5SDimitry Andric             "as all of its debug info.  Specifying --clean will unload all of "
5900b57cec5SDimitry Andric             "these shared modules and "
5910b57cec5SDimitry Andric             "cause them to be reparsed again the next time the target is run",
5920b57cec5SDimitry Andric             false, true) {
5930b57cec5SDimitry Andric     m_option_group.Append(&m_all_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
5940b57cec5SDimitry Andric     m_option_group.Append(&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
5950b57cec5SDimitry Andric     m_option_group.Finalize();
59681ad6265SDimitry Andric     CommandArgumentData target_arg{eArgTypeTargetID, eArgRepeatStar};
59781ad6265SDimitry Andric     m_arguments.push_back({target_arg});
5980b57cec5SDimitry Andric   }
5990b57cec5SDimitry Andric 
6000b57cec5SDimitry Andric   ~CommandObjectTargetDelete() override = default;
6010b57cec5SDimitry Andric 
GetOptions()6020b57cec5SDimitry Andric   Options *GetOptions() override { return &m_option_group; }
6030b57cec5SDimitry Andric 
6040b57cec5SDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)605c9157d92SDimitry Andric   void DoExecute(Args &args, CommandReturnObject &result) override {
6060b57cec5SDimitry Andric     const size_t argc = args.GetArgumentCount();
6070b57cec5SDimitry Andric     std::vector<TargetSP> delete_target_list;
6080b57cec5SDimitry Andric     TargetList &target_list = GetDebugger().GetTargetList();
6090b57cec5SDimitry Andric     TargetSP target_sp;
6100b57cec5SDimitry Andric 
6110b57cec5SDimitry Andric     if (m_all_option.GetOptionValue()) {
612fe013be4SDimitry Andric       for (size_t i = 0; i < target_list.GetNumTargets(); ++i)
6130b57cec5SDimitry Andric         delete_target_list.push_back(target_list.GetTargetAtIndex(i));
6140b57cec5SDimitry Andric     } else if (argc > 0) {
6150b57cec5SDimitry Andric       const uint32_t num_targets = target_list.GetNumTargets();
6160b57cec5SDimitry Andric       // Bail out if don't have any targets.
6170b57cec5SDimitry Andric       if (num_targets == 0) {
6180b57cec5SDimitry Andric         result.AppendError("no targets to delete");
619c9157d92SDimitry Andric         return;
6200b57cec5SDimitry Andric       }
6210b57cec5SDimitry Andric 
6220b57cec5SDimitry Andric       for (auto &entry : args.entries()) {
6230b57cec5SDimitry Andric         uint32_t target_idx;
6249dba64beSDimitry Andric         if (entry.ref().getAsInteger(0, target_idx)) {
6250b57cec5SDimitry Andric           result.AppendErrorWithFormat("invalid target index '%s'\n",
6260b57cec5SDimitry Andric                                        entry.c_str());
627c9157d92SDimitry Andric           return;
6280b57cec5SDimitry Andric         }
6290b57cec5SDimitry Andric         if (target_idx < num_targets) {
6300b57cec5SDimitry Andric           target_sp = target_list.GetTargetAtIndex(target_idx);
6310b57cec5SDimitry Andric           if (target_sp) {
6320b57cec5SDimitry Andric             delete_target_list.push_back(target_sp);
6330b57cec5SDimitry Andric             continue;
6340b57cec5SDimitry Andric           }
6350b57cec5SDimitry Andric         }
6360b57cec5SDimitry Andric         if (num_targets > 1)
6370b57cec5SDimitry Andric           result.AppendErrorWithFormat("target index %u is out of range, valid "
6380b57cec5SDimitry Andric                                        "target indexes are 0 - %u\n",
6390b57cec5SDimitry Andric                                        target_idx, num_targets - 1);
6400b57cec5SDimitry Andric         else
6410b57cec5SDimitry Andric           result.AppendErrorWithFormat(
6420b57cec5SDimitry Andric               "target index %u is out of range, the only valid index is 0\n",
6430b57cec5SDimitry Andric               target_idx);
6440b57cec5SDimitry Andric 
645c9157d92SDimitry Andric         return;
6460b57cec5SDimitry Andric       }
6470b57cec5SDimitry Andric     } else {
6480b57cec5SDimitry Andric       target_sp = target_list.GetSelectedTarget();
6490b57cec5SDimitry Andric       if (!target_sp) {
6500b57cec5SDimitry Andric         result.AppendErrorWithFormat("no target is currently selected\n");
651c9157d92SDimitry Andric         return;
6520b57cec5SDimitry Andric       }
6530b57cec5SDimitry Andric       delete_target_list.push_back(target_sp);
6540b57cec5SDimitry Andric     }
6550b57cec5SDimitry Andric 
6560b57cec5SDimitry Andric     const size_t num_targets_to_delete = delete_target_list.size();
6570b57cec5SDimitry Andric     for (size_t idx = 0; idx < num_targets_to_delete; ++idx) {
6580b57cec5SDimitry Andric       target_sp = delete_target_list[idx];
6590b57cec5SDimitry Andric       target_list.DeleteTarget(target_sp);
6600b57cec5SDimitry Andric       target_sp->Destroy();
6610b57cec5SDimitry Andric     }
6620b57cec5SDimitry Andric     // If "--clean" was specified, prune any orphaned shared modules from the
6630b57cec5SDimitry Andric     // global shared module list
6640b57cec5SDimitry Andric     if (m_cleanup_option.GetOptionValue()) {
6650b57cec5SDimitry Andric       const bool mandatory = true;
6660b57cec5SDimitry Andric       ModuleList::RemoveOrphanSharedModules(mandatory);
6670b57cec5SDimitry Andric     }
6680b57cec5SDimitry Andric     result.GetOutputStream().Printf("%u targets deleted.\n",
6690b57cec5SDimitry Andric                                     (uint32_t)num_targets_to_delete);
6700b57cec5SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishResult);
6710b57cec5SDimitry Andric 
672c9157d92SDimitry Andric     return;
6730b57cec5SDimitry Andric   }
6740b57cec5SDimitry Andric 
6750b57cec5SDimitry Andric   OptionGroupOptions m_option_group;
6760b57cec5SDimitry Andric   OptionGroupBoolean m_all_option;
6770b57cec5SDimitry Andric   OptionGroupBoolean m_cleanup_option;
6780b57cec5SDimitry Andric };
6790b57cec5SDimitry Andric 
6805ffd83dbSDimitry Andric class CommandObjectTargetShowLaunchEnvironment : public CommandObjectParsed {
6815ffd83dbSDimitry Andric public:
CommandObjectTargetShowLaunchEnvironment(CommandInterpreter & interpreter)6825ffd83dbSDimitry Andric   CommandObjectTargetShowLaunchEnvironment(CommandInterpreter &interpreter)
6835ffd83dbSDimitry Andric       : CommandObjectParsed(
6845ffd83dbSDimitry Andric             interpreter, "target show-launch-environment",
6855ffd83dbSDimitry Andric             "Shows the environment being passed to the process when launched, "
6865ffd83dbSDimitry Andric             "taking info account 3 settings: target.env-vars, "
6875ffd83dbSDimitry Andric             "target.inherit-env and target.unset-env-vars.",
6885ffd83dbSDimitry Andric             nullptr, eCommandRequiresTarget) {}
6895ffd83dbSDimitry Andric 
6905ffd83dbSDimitry Andric   ~CommandObjectTargetShowLaunchEnvironment() override = default;
6915ffd83dbSDimitry Andric 
6925ffd83dbSDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)693c9157d92SDimitry Andric   void DoExecute(Args &args, CommandReturnObject &result) override {
6945ffd83dbSDimitry Andric     Target *target = m_exe_ctx.GetTargetPtr();
6955ffd83dbSDimitry Andric     Environment env = target->GetEnvironment();
6965ffd83dbSDimitry Andric 
6975ffd83dbSDimitry Andric     std::vector<Environment::value_type *> env_vector;
6985ffd83dbSDimitry Andric     env_vector.reserve(env.size());
6995ffd83dbSDimitry Andric     for (auto &KV : env)
7005ffd83dbSDimitry Andric       env_vector.push_back(&KV);
7015ffd83dbSDimitry Andric     std::sort(env_vector.begin(), env_vector.end(),
7025ffd83dbSDimitry Andric               [](Environment::value_type *a, Environment::value_type *b) {
7035ffd83dbSDimitry Andric                 return a->first() < b->first();
7045ffd83dbSDimitry Andric               });
7055ffd83dbSDimitry Andric 
7065ffd83dbSDimitry Andric     auto &strm = result.GetOutputStream();
7075ffd83dbSDimitry Andric     for (auto &KV : env_vector)
7085ffd83dbSDimitry Andric       strm.Format("{0}={1}\n", KV->first(), KV->second);
7095ffd83dbSDimitry Andric 
7105ffd83dbSDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishResult);
7115ffd83dbSDimitry Andric   }
7125ffd83dbSDimitry Andric };
7135ffd83dbSDimitry Andric 
7140b57cec5SDimitry Andric #pragma mark CommandObjectTargetVariable
7150b57cec5SDimitry Andric 
7160b57cec5SDimitry Andric class CommandObjectTargetVariable : public CommandObjectParsed {
7170b57cec5SDimitry Andric   static const uint32_t SHORT_OPTION_FILE = 0x66696c65; // 'file'
7180b57cec5SDimitry Andric   static const uint32_t SHORT_OPTION_SHLB = 0x73686c62; // 'shlb'
7190b57cec5SDimitry Andric 
7200b57cec5SDimitry Andric public:
CommandObjectTargetVariable(CommandInterpreter & interpreter)7210b57cec5SDimitry Andric   CommandObjectTargetVariable(CommandInterpreter &interpreter)
7220b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "target variable",
7230b57cec5SDimitry Andric                             "Read global variables for the current target, "
7240b57cec5SDimitry Andric                             "before or while running a process.",
7250b57cec5SDimitry Andric                             nullptr, eCommandRequiresTarget),
7260b57cec5SDimitry Andric         m_option_variable(false), // Don't include frame options
7270b57cec5SDimitry Andric         m_option_format(eFormatDefault),
7280b57cec5SDimitry Andric         m_option_compile_units(LLDB_OPT_SET_1, false, "file", SHORT_OPTION_FILE,
7290b57cec5SDimitry Andric                                0, eArgTypeFilename,
7300b57cec5SDimitry Andric                                "A basename or fullpath to a file that contains "
7310b57cec5SDimitry Andric                                "global variables. This option can be "
7320b57cec5SDimitry Andric                                "specified multiple times."),
7330b57cec5SDimitry Andric         m_option_shared_libraries(
7340b57cec5SDimitry Andric             LLDB_OPT_SET_1, false, "shlib", SHORT_OPTION_SHLB, 0,
7350b57cec5SDimitry Andric             eArgTypeFilename,
7360b57cec5SDimitry Andric             "A basename or fullpath to a shared library to use in the search "
7370b57cec5SDimitry Andric             "for global "
73804eeddc0SDimitry Andric             "variables. This option can be specified multiple times.") {
7390b57cec5SDimitry Andric     CommandArgumentEntry arg;
7400b57cec5SDimitry Andric     CommandArgumentData var_name_arg;
7410b57cec5SDimitry Andric 
7420b57cec5SDimitry Andric     // Define the first (and only) variant of this arg.
7430b57cec5SDimitry Andric     var_name_arg.arg_type = eArgTypeVarName;
7440b57cec5SDimitry Andric     var_name_arg.arg_repetition = eArgRepeatPlus;
7450b57cec5SDimitry Andric 
7460b57cec5SDimitry Andric     // There is only one variant this argument could be; put it into the
7470b57cec5SDimitry Andric     // argument entry.
7480b57cec5SDimitry Andric     arg.push_back(var_name_arg);
7490b57cec5SDimitry Andric 
7500b57cec5SDimitry Andric     // Push the data for the first argument into the m_arguments vector.
7510b57cec5SDimitry Andric     m_arguments.push_back(arg);
7520b57cec5SDimitry Andric 
7530b57cec5SDimitry Andric     m_option_group.Append(&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
7540b57cec5SDimitry Andric     m_option_group.Append(&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
7550b57cec5SDimitry Andric     m_option_group.Append(&m_option_format,
7560b57cec5SDimitry Andric                           OptionGroupFormat::OPTION_GROUP_FORMAT |
7570b57cec5SDimitry Andric                               OptionGroupFormat::OPTION_GROUP_GDB_FMT,
7580b57cec5SDimitry Andric                           LLDB_OPT_SET_1);
7590b57cec5SDimitry Andric     m_option_group.Append(&m_option_compile_units, LLDB_OPT_SET_ALL,
7600b57cec5SDimitry Andric                           LLDB_OPT_SET_1);
7610b57cec5SDimitry Andric     m_option_group.Append(&m_option_shared_libraries, LLDB_OPT_SET_ALL,
7620b57cec5SDimitry Andric                           LLDB_OPT_SET_1);
7630b57cec5SDimitry Andric     m_option_group.Finalize();
7640b57cec5SDimitry Andric   }
7650b57cec5SDimitry Andric 
7660b57cec5SDimitry Andric   ~CommandObjectTargetVariable() override = default;
7670b57cec5SDimitry Andric 
DumpValueObject(Stream & s,VariableSP & var_sp,ValueObjectSP & valobj_sp,const char * root_name)7680b57cec5SDimitry Andric   void DumpValueObject(Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp,
7690b57cec5SDimitry Andric                        const char *root_name) {
7700b57cec5SDimitry Andric     DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions());
7710b57cec5SDimitry Andric 
7720b57cec5SDimitry Andric     if (!valobj_sp->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
7730b57cec5SDimitry Andric         valobj_sp->IsRuntimeSupportValue())
7740b57cec5SDimitry Andric       return;
7750b57cec5SDimitry Andric 
7760b57cec5SDimitry Andric     switch (var_sp->GetScope()) {
7770b57cec5SDimitry Andric     case eValueTypeVariableGlobal:
7780b57cec5SDimitry Andric       if (m_option_variable.show_scope)
7790b57cec5SDimitry Andric         s.PutCString("GLOBAL: ");
7800b57cec5SDimitry Andric       break;
7810b57cec5SDimitry Andric 
7820b57cec5SDimitry Andric     case eValueTypeVariableStatic:
7830b57cec5SDimitry Andric       if (m_option_variable.show_scope)
7840b57cec5SDimitry Andric         s.PutCString("STATIC: ");
7850b57cec5SDimitry Andric       break;
7860b57cec5SDimitry Andric 
7870b57cec5SDimitry Andric     case eValueTypeVariableArgument:
7880b57cec5SDimitry Andric       if (m_option_variable.show_scope)
7890b57cec5SDimitry Andric         s.PutCString("   ARG: ");
7900b57cec5SDimitry Andric       break;
7910b57cec5SDimitry Andric 
7920b57cec5SDimitry Andric     case eValueTypeVariableLocal:
7930b57cec5SDimitry Andric       if (m_option_variable.show_scope)
7940b57cec5SDimitry Andric         s.PutCString(" LOCAL: ");
7950b57cec5SDimitry Andric       break;
7960b57cec5SDimitry Andric 
7970b57cec5SDimitry Andric     case eValueTypeVariableThreadLocal:
7980b57cec5SDimitry Andric       if (m_option_variable.show_scope)
7990b57cec5SDimitry Andric         s.PutCString("THREAD: ");
8000b57cec5SDimitry Andric       break;
8010b57cec5SDimitry Andric 
8020b57cec5SDimitry Andric     default:
8030b57cec5SDimitry Andric       break;
8040b57cec5SDimitry Andric     }
8050b57cec5SDimitry Andric 
8060b57cec5SDimitry Andric     if (m_option_variable.show_decl) {
8070b57cec5SDimitry Andric       bool show_fullpaths = false;
8080b57cec5SDimitry Andric       bool show_module = true;
8090b57cec5SDimitry Andric       if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
8100b57cec5SDimitry Andric         s.PutCString(": ");
8110b57cec5SDimitry Andric     }
8120b57cec5SDimitry Andric 
8130b57cec5SDimitry Andric     const Format format = m_option_format.GetFormat();
8140b57cec5SDimitry Andric     if (format != eFormatDefault)
8150b57cec5SDimitry Andric       options.SetFormat(format);
8160b57cec5SDimitry Andric 
8170b57cec5SDimitry Andric     options.SetRootValueObjectName(root_name);
8180b57cec5SDimitry Andric 
8190b57cec5SDimitry Andric     valobj_sp->Dump(s, options);
8200b57cec5SDimitry Andric   }
8210b57cec5SDimitry Andric 
GetVariableCallback(void * baton,const char * name,VariableList & variable_list)8220b57cec5SDimitry Andric   static size_t GetVariableCallback(void *baton, const char *name,
8230b57cec5SDimitry Andric                                     VariableList &variable_list) {
8249dba64beSDimitry Andric     size_t old_size = variable_list.GetSize();
8250b57cec5SDimitry Andric     Target *target = static_cast<Target *>(baton);
8269dba64beSDimitry Andric     if (target)
8279dba64beSDimitry Andric       target->GetImages().FindGlobalVariables(ConstString(name), UINT32_MAX,
8289dba64beSDimitry Andric                                               variable_list);
8299dba64beSDimitry Andric     return variable_list.GetSize() - old_size;
8300b57cec5SDimitry Andric   }
8310b57cec5SDimitry Andric 
GetOptions()8320b57cec5SDimitry Andric   Options *GetOptions() override { return &m_option_group; }
8330b57cec5SDimitry Andric 
8340b57cec5SDimitry Andric protected:
DumpGlobalVariableList(const ExecutionContext & exe_ctx,const SymbolContext & sc,const VariableList & variable_list,Stream & s)8350b57cec5SDimitry Andric   void DumpGlobalVariableList(const ExecutionContext &exe_ctx,
8360b57cec5SDimitry Andric                               const SymbolContext &sc,
8370b57cec5SDimitry Andric                               const VariableList &variable_list, Stream &s) {
838480093f4SDimitry Andric     if (variable_list.Empty())
839480093f4SDimitry Andric       return;
8400b57cec5SDimitry Andric     if (sc.module_sp) {
8410b57cec5SDimitry Andric       if (sc.comp_unit) {
842480093f4SDimitry Andric         s.Format("Global variables for {0} in {1}:\n",
843480093f4SDimitry Andric                  sc.comp_unit->GetPrimaryFile(), sc.module_sp->GetFileSpec());
8440b57cec5SDimitry Andric       } else {
8450b57cec5SDimitry Andric         s.Printf("Global variables for %s\n",
8460b57cec5SDimitry Andric                  sc.module_sp->GetFileSpec().GetPath().c_str());
8470b57cec5SDimitry Andric       }
8480b57cec5SDimitry Andric     } else if (sc.comp_unit) {
849480093f4SDimitry Andric       s.Format("Global variables for {0}\n", sc.comp_unit->GetPrimaryFile());
8500b57cec5SDimitry Andric     }
8510b57cec5SDimitry Andric 
852480093f4SDimitry Andric     for (VariableSP var_sp : variable_list) {
853480093f4SDimitry Andric       if (!var_sp)
854480093f4SDimitry Andric         continue;
8550b57cec5SDimitry Andric       ValueObjectSP valobj_sp(ValueObjectVariable::Create(
8560b57cec5SDimitry Andric           exe_ctx.GetBestExecutionContextScope(), var_sp));
8570b57cec5SDimitry Andric 
8580b57cec5SDimitry Andric       if (valobj_sp)
859480093f4SDimitry Andric         DumpValueObject(s, var_sp, valobj_sp, var_sp->GetName().GetCString());
8600b57cec5SDimitry Andric     }
8610b57cec5SDimitry Andric   }
8620b57cec5SDimitry Andric 
DoExecute(Args & args,CommandReturnObject & result)863c9157d92SDimitry Andric   void DoExecute(Args &args, CommandReturnObject &result) override {
8640b57cec5SDimitry Andric     Target *target = m_exe_ctx.GetTargetPtr();
8650b57cec5SDimitry Andric     const size_t argc = args.GetArgumentCount();
8660b57cec5SDimitry Andric     Stream &s = result.GetOutputStream();
8670b57cec5SDimitry Andric 
8680b57cec5SDimitry Andric     if (argc > 0) {
8695ffd83dbSDimitry Andric       for (const Args::ArgEntry &arg : args) {
8700b57cec5SDimitry Andric         VariableList variable_list;
8710b57cec5SDimitry Andric         ValueObjectList valobj_list;
8720b57cec5SDimitry Andric 
8730b57cec5SDimitry Andric         size_t matches = 0;
8740b57cec5SDimitry Andric         bool use_var_name = false;
8750b57cec5SDimitry Andric         if (m_option_variable.use_regex) {
876fe6060f1SDimitry Andric           RegularExpression regex(arg.ref());
8770b57cec5SDimitry Andric           if (!regex.IsValid()) {
8780b57cec5SDimitry Andric             result.GetErrorStream().Printf(
8795ffd83dbSDimitry Andric                 "error: invalid regular expression: '%s'\n", arg.c_str());
880c9157d92SDimitry Andric             return;
8810b57cec5SDimitry Andric           }
8820b57cec5SDimitry Andric           use_var_name = true;
8839dba64beSDimitry Andric           target->GetImages().FindGlobalVariables(regex, UINT32_MAX,
8840b57cec5SDimitry Andric                                                   variable_list);
8859dba64beSDimitry Andric           matches = variable_list.GetSize();
8860b57cec5SDimitry Andric         } else {
8870b57cec5SDimitry Andric           Status error(Variable::GetValuesForVariableExpressionPath(
8885ffd83dbSDimitry Andric               arg.c_str(), m_exe_ctx.GetBestExecutionContextScope(),
8890b57cec5SDimitry Andric               GetVariableCallback, target, variable_list, valobj_list));
8900b57cec5SDimitry Andric           matches = variable_list.GetSize();
8910b57cec5SDimitry Andric         }
8920b57cec5SDimitry Andric 
8930b57cec5SDimitry Andric         if (matches == 0) {
894fe6060f1SDimitry Andric           result.AppendErrorWithFormat("can't find global variable '%s'",
895fe6060f1SDimitry Andric                                        arg.c_str());
896c9157d92SDimitry Andric           return;
8970b57cec5SDimitry Andric         } else {
8980b57cec5SDimitry Andric           for (uint32_t global_idx = 0; global_idx < matches; ++global_idx) {
8990b57cec5SDimitry Andric             VariableSP var_sp(variable_list.GetVariableAtIndex(global_idx));
9000b57cec5SDimitry Andric             if (var_sp) {
9010b57cec5SDimitry Andric               ValueObjectSP valobj_sp(
9020b57cec5SDimitry Andric                   valobj_list.GetValueObjectAtIndex(global_idx));
9030b57cec5SDimitry Andric               if (!valobj_sp)
9040b57cec5SDimitry Andric                 valobj_sp = ValueObjectVariable::Create(
9050b57cec5SDimitry Andric                     m_exe_ctx.GetBestExecutionContextScope(), var_sp);
9060b57cec5SDimitry Andric 
9070b57cec5SDimitry Andric               if (valobj_sp)
9080b57cec5SDimitry Andric                 DumpValueObject(s, var_sp, valobj_sp,
9090b57cec5SDimitry Andric                                 use_var_name ? var_sp->GetName().GetCString()
9105ffd83dbSDimitry Andric                                              : arg.c_str());
9110b57cec5SDimitry Andric             }
9120b57cec5SDimitry Andric           }
9130b57cec5SDimitry Andric         }
9140b57cec5SDimitry Andric       }
9150b57cec5SDimitry Andric     } else {
9160b57cec5SDimitry Andric       const FileSpecList &compile_units =
9170b57cec5SDimitry Andric           m_option_compile_units.GetOptionValue().GetCurrentValue();
9180b57cec5SDimitry Andric       const FileSpecList &shlibs =
9190b57cec5SDimitry Andric           m_option_shared_libraries.GetOptionValue().GetCurrentValue();
9200b57cec5SDimitry Andric       SymbolContextList sc_list;
9210b57cec5SDimitry Andric       const size_t num_compile_units = compile_units.GetSize();
9220b57cec5SDimitry Andric       const size_t num_shlibs = shlibs.GetSize();
9230b57cec5SDimitry Andric       if (num_compile_units == 0 && num_shlibs == 0) {
9240b57cec5SDimitry Andric         bool success = false;
9250b57cec5SDimitry Andric         StackFrame *frame = m_exe_ctx.GetFramePtr();
9260b57cec5SDimitry Andric         CompileUnit *comp_unit = nullptr;
9270b57cec5SDimitry Andric         if (frame) {
9280b57cec5SDimitry Andric           SymbolContext sc = frame->GetSymbolContext(eSymbolContextCompUnit);
929e8d8bef9SDimitry Andric           comp_unit = sc.comp_unit;
9300b57cec5SDimitry Andric           if (sc.comp_unit) {
9310b57cec5SDimitry Andric             const bool can_create = true;
9320b57cec5SDimitry Andric             VariableListSP comp_unit_varlist_sp(
9330b57cec5SDimitry Andric                 sc.comp_unit->GetVariableList(can_create));
9340b57cec5SDimitry Andric             if (comp_unit_varlist_sp) {
9350b57cec5SDimitry Andric               size_t count = comp_unit_varlist_sp->GetSize();
9360b57cec5SDimitry Andric               if (count > 0) {
9370b57cec5SDimitry Andric                 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
9380b57cec5SDimitry Andric                 success = true;
9390b57cec5SDimitry Andric               }
9400b57cec5SDimitry Andric             }
9410b57cec5SDimitry Andric           }
9420b57cec5SDimitry Andric         }
9430b57cec5SDimitry Andric         if (!success) {
9440b57cec5SDimitry Andric           if (frame) {
9450b57cec5SDimitry Andric             if (comp_unit)
946480093f4SDimitry Andric               result.AppendErrorWithFormatv(
947480093f4SDimitry Andric                   "no global variables in current compile unit: {0}\n",
948480093f4SDimitry Andric                   comp_unit->GetPrimaryFile());
9490b57cec5SDimitry Andric             else
9500b57cec5SDimitry Andric               result.AppendErrorWithFormat(
9510b57cec5SDimitry Andric                   "no debug information for frame %u\n",
9520b57cec5SDimitry Andric                   frame->GetFrameIndex());
9530b57cec5SDimitry Andric           } else
9540b57cec5SDimitry Andric             result.AppendError("'target variable' takes one or more global "
9550b57cec5SDimitry Andric                                "variable names as arguments\n");
9560b57cec5SDimitry Andric         }
9570b57cec5SDimitry Andric       } else {
9580b57cec5SDimitry Andric         SymbolContextList sc_list;
9590b57cec5SDimitry Andric         // We have one or more compile unit or shlib
9600b57cec5SDimitry Andric         if (num_shlibs > 0) {
9610b57cec5SDimitry Andric           for (size_t shlib_idx = 0; shlib_idx < num_shlibs; ++shlib_idx) {
9620b57cec5SDimitry Andric             const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx));
9630b57cec5SDimitry Andric             ModuleSpec module_spec(module_file);
9640b57cec5SDimitry Andric 
9650b57cec5SDimitry Andric             ModuleSP module_sp(
9660b57cec5SDimitry Andric                 target->GetImages().FindFirstModule(module_spec));
9670b57cec5SDimitry Andric             if (module_sp) {
9680b57cec5SDimitry Andric               if (num_compile_units > 0) {
9690b57cec5SDimitry Andric                 for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
9700b57cec5SDimitry Andric                   module_sp->FindCompileUnits(
9719dba64beSDimitry Andric                       compile_units.GetFileSpecAtIndex(cu_idx), sc_list);
9720b57cec5SDimitry Andric               } else {
9730b57cec5SDimitry Andric                 SymbolContext sc;
9740b57cec5SDimitry Andric                 sc.module_sp = module_sp;
9750b57cec5SDimitry Andric                 sc_list.Append(sc);
9760b57cec5SDimitry Andric               }
9770b57cec5SDimitry Andric             } else {
9780b57cec5SDimitry Andric               // Didn't find matching shlib/module in target...
9790b57cec5SDimitry Andric               result.AppendErrorWithFormat(
9800b57cec5SDimitry Andric                   "target doesn't contain the specified shared library: %s\n",
9810b57cec5SDimitry Andric                   module_file.GetPath().c_str());
9820b57cec5SDimitry Andric             }
9830b57cec5SDimitry Andric           }
9840b57cec5SDimitry Andric         } else {
9850b57cec5SDimitry Andric           // No shared libraries, we just want to find globals for the compile
9860b57cec5SDimitry Andric           // units files that were specified
9870b57cec5SDimitry Andric           for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
9880b57cec5SDimitry Andric             target->GetImages().FindCompileUnits(
9899dba64beSDimitry Andric                 compile_units.GetFileSpecAtIndex(cu_idx), sc_list);
9900b57cec5SDimitry Andric         }
9910b57cec5SDimitry Andric 
992fe013be4SDimitry Andric         for (const SymbolContext &sc : sc_list) {
9930b57cec5SDimitry Andric           if (sc.comp_unit) {
9940b57cec5SDimitry Andric             const bool can_create = true;
9950b57cec5SDimitry Andric             VariableListSP comp_unit_varlist_sp(
9960b57cec5SDimitry Andric                 sc.comp_unit->GetVariableList(can_create));
9970b57cec5SDimitry Andric             if (comp_unit_varlist_sp)
998fe013be4SDimitry Andric               DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
9990b57cec5SDimitry Andric           } else if (sc.module_sp) {
10000b57cec5SDimitry Andric             // Get all global variables for this module
10010b57cec5SDimitry Andric             lldb_private::RegularExpression all_globals_regex(
1002fe013be4SDimitry Andric                 llvm::StringRef(".")); // Any global with at least one character
10030b57cec5SDimitry Andric             VariableList variable_list;
10040b57cec5SDimitry Andric             sc.module_sp->FindGlobalVariables(all_globals_regex, UINT32_MAX,
10050b57cec5SDimitry Andric                                               variable_list);
10060b57cec5SDimitry Andric             DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s);
10070b57cec5SDimitry Andric           }
10080b57cec5SDimitry Andric         }
10090b57cec5SDimitry Andric       }
10100b57cec5SDimitry Andric     }
10110b57cec5SDimitry Andric 
101281ad6265SDimitry Andric     m_interpreter.PrintWarningsIfNecessary(result.GetOutputStream(),
101381ad6265SDimitry Andric                                            m_cmd_name);
10140b57cec5SDimitry Andric   }
10150b57cec5SDimitry Andric 
10160b57cec5SDimitry Andric   OptionGroupOptions m_option_group;
10170b57cec5SDimitry Andric   OptionGroupVariable m_option_variable;
10180b57cec5SDimitry Andric   OptionGroupFormat m_option_format;
10190b57cec5SDimitry Andric   OptionGroupFileList m_option_compile_units;
10200b57cec5SDimitry Andric   OptionGroupFileList m_option_shared_libraries;
10210b57cec5SDimitry Andric   OptionGroupValueObjectDisplay m_varobj_options;
10220b57cec5SDimitry Andric };
10230b57cec5SDimitry Andric 
10240b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesSearchPathsAdd
10250b57cec5SDimitry Andric 
10260b57cec5SDimitry Andric class CommandObjectTargetModulesSearchPathsAdd : public CommandObjectParsed {
10270b57cec5SDimitry Andric public:
CommandObjectTargetModulesSearchPathsAdd(CommandInterpreter & interpreter)10280b57cec5SDimitry Andric   CommandObjectTargetModulesSearchPathsAdd(CommandInterpreter &interpreter)
10290b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "target modules search-paths add",
10300b57cec5SDimitry Andric                             "Add new image search paths substitution pairs to "
10310b57cec5SDimitry Andric                             "the current target.",
10329dba64beSDimitry Andric                             nullptr, eCommandRequiresTarget) {
10330b57cec5SDimitry Andric     CommandArgumentEntry arg;
10340b57cec5SDimitry Andric     CommandArgumentData old_prefix_arg;
10350b57cec5SDimitry Andric     CommandArgumentData new_prefix_arg;
10360b57cec5SDimitry Andric 
10370b57cec5SDimitry Andric     // Define the first variant of this arg pair.
10380b57cec5SDimitry Andric     old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
10390b57cec5SDimitry Andric     old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
10400b57cec5SDimitry Andric 
10410b57cec5SDimitry Andric     // Define the first variant of this arg pair.
10420b57cec5SDimitry Andric     new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
10430b57cec5SDimitry Andric     new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
10440b57cec5SDimitry Andric 
10450b57cec5SDimitry Andric     // There are two required arguments that must always occur together, i.e.
10460b57cec5SDimitry Andric     // an argument "pair".  Because they must always occur together, they are
10470b57cec5SDimitry Andric     // treated as two variants of one argument rather than two independent
10480b57cec5SDimitry Andric     // arguments.  Push them both into the first argument position for
10490b57cec5SDimitry Andric     // m_arguments...
10500b57cec5SDimitry Andric 
10510b57cec5SDimitry Andric     arg.push_back(old_prefix_arg);
10520b57cec5SDimitry Andric     arg.push_back(new_prefix_arg);
10530b57cec5SDimitry Andric 
10540b57cec5SDimitry Andric     m_arguments.push_back(arg);
10550b57cec5SDimitry Andric   }
10560b57cec5SDimitry Andric 
10570b57cec5SDimitry Andric   ~CommandObjectTargetModulesSearchPathsAdd() override = default;
10580b57cec5SDimitry Andric 
10590b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)1060c9157d92SDimitry Andric   void DoExecute(Args &command, CommandReturnObject &result) override {
10619dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
10620b57cec5SDimitry Andric     const size_t argc = command.GetArgumentCount();
10630b57cec5SDimitry Andric     if (argc & 1) {
10640b57cec5SDimitry Andric       result.AppendError("add requires an even number of arguments\n");
10650b57cec5SDimitry Andric     } else {
10660b57cec5SDimitry Andric       for (size_t i = 0; i < argc; i += 2) {
10670b57cec5SDimitry Andric         const char *from = command.GetArgumentAtIndex(i);
10680b57cec5SDimitry Andric         const char *to = command.GetArgumentAtIndex(i + 1);
10690b57cec5SDimitry Andric 
10700b57cec5SDimitry Andric         if (from[0] && to[0]) {
107181ad6265SDimitry Andric           Log *log = GetLog(LLDBLog::Host);
10720b57cec5SDimitry Andric           if (log) {
10739dba64beSDimitry Andric             LLDB_LOGF(log,
10749dba64beSDimitry Andric                       "target modules search path adding ImageSearchPath "
10750b57cec5SDimitry Andric                       "pair: '%s' -> '%s'",
10760b57cec5SDimitry Andric                       from, to);
10770b57cec5SDimitry Andric           }
10780b57cec5SDimitry Andric           bool last_pair = ((argc - i) == 2);
10790b57cec5SDimitry Andric           target->GetImageSearchPathList().Append(
1080349cc55cSDimitry Andric               from, to, last_pair); // Notify if this is the last pair
10810b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishNoResult);
10820b57cec5SDimitry Andric         } else {
10830b57cec5SDimitry Andric           if (from[0])
10840b57cec5SDimitry Andric             result.AppendError("<path-prefix> can't be empty\n");
10850b57cec5SDimitry Andric           else
10860b57cec5SDimitry Andric             result.AppendError("<new-path-prefix> can't be empty\n");
10870b57cec5SDimitry Andric         }
10880b57cec5SDimitry Andric       }
10890b57cec5SDimitry Andric     }
10900b57cec5SDimitry Andric   }
10910b57cec5SDimitry Andric };
10920b57cec5SDimitry Andric 
10930b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesSearchPathsClear
10940b57cec5SDimitry Andric 
10950b57cec5SDimitry Andric class CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed {
10960b57cec5SDimitry Andric public:
CommandObjectTargetModulesSearchPathsClear(CommandInterpreter & interpreter)10970b57cec5SDimitry Andric   CommandObjectTargetModulesSearchPathsClear(CommandInterpreter &interpreter)
10980b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "target modules search-paths clear",
10990b57cec5SDimitry Andric                             "Clear all current image search path substitution "
11000b57cec5SDimitry Andric                             "pairs from the current target.",
11019dba64beSDimitry Andric                             "target modules search-paths clear",
11029dba64beSDimitry Andric                             eCommandRequiresTarget) {}
11030b57cec5SDimitry Andric 
11040b57cec5SDimitry Andric   ~CommandObjectTargetModulesSearchPathsClear() override = default;
11050b57cec5SDimitry Andric 
11060b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)1107c9157d92SDimitry Andric   void DoExecute(Args &command, CommandReturnObject &result) override {
11089dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
11090b57cec5SDimitry Andric     bool notify = true;
11100b57cec5SDimitry Andric     target->GetImageSearchPathList().Clear(notify);
11110b57cec5SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishNoResult);
11120b57cec5SDimitry Andric   }
11130b57cec5SDimitry Andric };
11140b57cec5SDimitry Andric 
11150b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesSearchPathsInsert
11160b57cec5SDimitry Andric 
11170b57cec5SDimitry Andric class CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed {
11180b57cec5SDimitry Andric public:
CommandObjectTargetModulesSearchPathsInsert(CommandInterpreter & interpreter)11190b57cec5SDimitry Andric   CommandObjectTargetModulesSearchPathsInsert(CommandInterpreter &interpreter)
11200b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "target modules search-paths insert",
11210b57cec5SDimitry Andric                             "Insert a new image search path substitution pair "
11220b57cec5SDimitry Andric                             "into the current target at the specified index.",
11239dba64beSDimitry Andric                             nullptr, eCommandRequiresTarget) {
11240b57cec5SDimitry Andric     CommandArgumentEntry arg1;
11250b57cec5SDimitry Andric     CommandArgumentEntry arg2;
11260b57cec5SDimitry Andric     CommandArgumentData index_arg;
11270b57cec5SDimitry Andric     CommandArgumentData old_prefix_arg;
11280b57cec5SDimitry Andric     CommandArgumentData new_prefix_arg;
11290b57cec5SDimitry Andric 
11300b57cec5SDimitry Andric     // Define the first and only variant of this arg.
11310b57cec5SDimitry Andric     index_arg.arg_type = eArgTypeIndex;
11320b57cec5SDimitry Andric     index_arg.arg_repetition = eArgRepeatPlain;
11330b57cec5SDimitry Andric 
11340b57cec5SDimitry Andric     // Put the one and only variant into the first arg for m_arguments:
11350b57cec5SDimitry Andric     arg1.push_back(index_arg);
11360b57cec5SDimitry Andric 
11370b57cec5SDimitry Andric     // Define the first variant of this arg pair.
11380b57cec5SDimitry Andric     old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
11390b57cec5SDimitry Andric     old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
11400b57cec5SDimitry Andric 
11410b57cec5SDimitry Andric     // Define the first variant of this arg pair.
11420b57cec5SDimitry Andric     new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
11430b57cec5SDimitry Andric     new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
11440b57cec5SDimitry Andric 
11450b57cec5SDimitry Andric     // There are two required arguments that must always occur together, i.e.
11460b57cec5SDimitry Andric     // an argument "pair".  Because they must always occur together, they are
11470b57cec5SDimitry Andric     // treated as two variants of one argument rather than two independent
11480b57cec5SDimitry Andric     // arguments.  Push them both into the same argument position for
11490b57cec5SDimitry Andric     // m_arguments...
11500b57cec5SDimitry Andric 
11510b57cec5SDimitry Andric     arg2.push_back(old_prefix_arg);
11520b57cec5SDimitry Andric     arg2.push_back(new_prefix_arg);
11530b57cec5SDimitry Andric 
11540b57cec5SDimitry Andric     // Add arguments to m_arguments.
11550b57cec5SDimitry Andric     m_arguments.push_back(arg1);
11560b57cec5SDimitry Andric     m_arguments.push_back(arg2);
11570b57cec5SDimitry Andric   }
11580b57cec5SDimitry Andric 
11590b57cec5SDimitry Andric   ~CommandObjectTargetModulesSearchPathsInsert() override = default;
11600b57cec5SDimitry Andric 
1161e8d8bef9SDimitry Andric   void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)1162e8d8bef9SDimitry Andric   HandleArgumentCompletion(CompletionRequest &request,
1163e8d8bef9SDimitry Andric                            OptionElementVector &opt_element_vector) override {
1164e8d8bef9SDimitry Andric     if (!m_exe_ctx.HasTargetScope() || request.GetCursorIndex() != 0)
1165e8d8bef9SDimitry Andric       return;
1166e8d8bef9SDimitry Andric 
1167e8d8bef9SDimitry Andric     Target *target = m_exe_ctx.GetTargetPtr();
1168e8d8bef9SDimitry Andric     const PathMappingList &list = target->GetImageSearchPathList();
1169e8d8bef9SDimitry Andric     const size_t num = list.GetSize();
1170e8d8bef9SDimitry Andric     ConstString old_path, new_path;
1171e8d8bef9SDimitry Andric     for (size_t i = 0; i < num; ++i) {
1172e8d8bef9SDimitry Andric       if (!list.GetPathsAtIndex(i, old_path, new_path))
1173e8d8bef9SDimitry Andric         break;
1174e8d8bef9SDimitry Andric       StreamString strm;
1175e8d8bef9SDimitry Andric       strm << old_path << " -> " << new_path;
1176e8d8bef9SDimitry Andric       request.TryCompleteCurrentArg(std::to_string(i), strm.GetString());
1177e8d8bef9SDimitry Andric     }
1178e8d8bef9SDimitry Andric   }
1179e8d8bef9SDimitry Andric 
11800b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)1181c9157d92SDimitry Andric   void DoExecute(Args &command, CommandReturnObject &result) override {
11829dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
11830b57cec5SDimitry Andric     size_t argc = command.GetArgumentCount();
11840b57cec5SDimitry Andric     // check for at least 3 arguments and an odd number of parameters
11850b57cec5SDimitry Andric     if (argc >= 3 && argc & 1) {
11865ffd83dbSDimitry Andric       uint32_t insert_idx;
11870b57cec5SDimitry Andric 
11885ffd83dbSDimitry Andric       if (!llvm::to_integer(command.GetArgumentAtIndex(0), insert_idx)) {
11890b57cec5SDimitry Andric         result.AppendErrorWithFormat(
11900b57cec5SDimitry Andric             "<index> parameter is not an integer: '%s'.\n",
11910b57cec5SDimitry Andric             command.GetArgumentAtIndex(0));
1192c9157d92SDimitry Andric         return;
11930b57cec5SDimitry Andric       }
11940b57cec5SDimitry Andric 
11950b57cec5SDimitry Andric       // shift off the index
11960b57cec5SDimitry Andric       command.Shift();
11970b57cec5SDimitry Andric       argc = command.GetArgumentCount();
11980b57cec5SDimitry Andric 
11990b57cec5SDimitry Andric       for (uint32_t i = 0; i < argc; i += 2, ++insert_idx) {
12000b57cec5SDimitry Andric         const char *from = command.GetArgumentAtIndex(i);
12010b57cec5SDimitry Andric         const char *to = command.GetArgumentAtIndex(i + 1);
12020b57cec5SDimitry Andric 
12030b57cec5SDimitry Andric         if (from[0] && to[0]) {
12040b57cec5SDimitry Andric           bool last_pair = ((argc - i) == 2);
1205349cc55cSDimitry Andric           target->GetImageSearchPathList().Insert(from, to, insert_idx,
1206349cc55cSDimitry Andric                                                   last_pair);
12070b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishNoResult);
12080b57cec5SDimitry Andric         } else {
12090b57cec5SDimitry Andric           if (from[0])
12100b57cec5SDimitry Andric             result.AppendError("<path-prefix> can't be empty\n");
12110b57cec5SDimitry Andric           else
12120b57cec5SDimitry Andric             result.AppendError("<new-path-prefix> can't be empty\n");
1213c9157d92SDimitry Andric           return;
12140b57cec5SDimitry Andric         }
12150b57cec5SDimitry Andric       }
12160b57cec5SDimitry Andric     } else {
12170b57cec5SDimitry Andric       result.AppendError("insert requires at least three arguments\n");
12180b57cec5SDimitry Andric     }
12190b57cec5SDimitry Andric   }
12200b57cec5SDimitry Andric };
12210b57cec5SDimitry Andric 
12220b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesSearchPathsList
12230b57cec5SDimitry Andric 
12240b57cec5SDimitry Andric class CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed {
12250b57cec5SDimitry Andric public:
CommandObjectTargetModulesSearchPathsList(CommandInterpreter & interpreter)12260b57cec5SDimitry Andric   CommandObjectTargetModulesSearchPathsList(CommandInterpreter &interpreter)
12270b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "target modules search-paths list",
12280b57cec5SDimitry Andric                             "List all current image search path substitution "
12290b57cec5SDimitry Andric                             "pairs in the current target.",
12309dba64beSDimitry Andric                             "target modules search-paths list",
12319dba64beSDimitry Andric                             eCommandRequiresTarget) {}
12320b57cec5SDimitry Andric 
12330b57cec5SDimitry Andric   ~CommandObjectTargetModulesSearchPathsList() override = default;
12340b57cec5SDimitry Andric 
12350b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)1236c9157d92SDimitry Andric   void DoExecute(Args &command, CommandReturnObject &result) override {
12379dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
12380b57cec5SDimitry Andric 
12390b57cec5SDimitry Andric     target->GetImageSearchPathList().Dump(&result.GetOutputStream());
12400b57cec5SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishResult);
12410b57cec5SDimitry Andric   }
12420b57cec5SDimitry Andric };
12430b57cec5SDimitry Andric 
12440b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesSearchPathsQuery
12450b57cec5SDimitry Andric 
12460b57cec5SDimitry Andric class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed {
12470b57cec5SDimitry Andric public:
CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter & interpreter)12480b57cec5SDimitry Andric   CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter &interpreter)
12490b57cec5SDimitry Andric       : CommandObjectParsed(
12500b57cec5SDimitry Andric             interpreter, "target modules search-paths query",
12510b57cec5SDimitry Andric             "Transform a path using the first applicable image search path.",
12529dba64beSDimitry Andric             nullptr, eCommandRequiresTarget) {
12530b57cec5SDimitry Andric     CommandArgumentEntry arg;
12540b57cec5SDimitry Andric     CommandArgumentData path_arg;
12550b57cec5SDimitry Andric 
12560b57cec5SDimitry Andric     // Define the first (and only) variant of this arg.
12570b57cec5SDimitry Andric     path_arg.arg_type = eArgTypeDirectoryName;
12580b57cec5SDimitry Andric     path_arg.arg_repetition = eArgRepeatPlain;
12590b57cec5SDimitry Andric 
12600b57cec5SDimitry Andric     // There is only one variant this argument could be; put it into the
12610b57cec5SDimitry Andric     // argument entry.
12620b57cec5SDimitry Andric     arg.push_back(path_arg);
12630b57cec5SDimitry Andric 
12640b57cec5SDimitry Andric     // Push the data for the first argument into the m_arguments vector.
12650b57cec5SDimitry Andric     m_arguments.push_back(arg);
12660b57cec5SDimitry Andric   }
12670b57cec5SDimitry Andric 
12680b57cec5SDimitry Andric   ~CommandObjectTargetModulesSearchPathsQuery() override = default;
12690b57cec5SDimitry Andric 
12700b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)1271c9157d92SDimitry Andric   void DoExecute(Args &command, CommandReturnObject &result) override {
12729dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
12730b57cec5SDimitry Andric     if (command.GetArgumentCount() != 1) {
12740b57cec5SDimitry Andric       result.AppendError("query requires one argument\n");
1275c9157d92SDimitry Andric       return;
12760b57cec5SDimitry Andric     }
12770b57cec5SDimitry Andric 
12780b57cec5SDimitry Andric     ConstString orig(command.GetArgumentAtIndex(0));
12790b57cec5SDimitry Andric     ConstString transformed;
12800b57cec5SDimitry Andric     if (target->GetImageSearchPathList().RemapPath(orig, transformed))
12810b57cec5SDimitry Andric       result.GetOutputStream().Printf("%s\n", transformed.GetCString());
12820b57cec5SDimitry Andric     else
12830b57cec5SDimitry Andric       result.GetOutputStream().Printf("%s\n", orig.GetCString());
12840b57cec5SDimitry Andric 
12850b57cec5SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishResult);
12860b57cec5SDimitry Andric   }
12870b57cec5SDimitry Andric };
12880b57cec5SDimitry Andric 
12890b57cec5SDimitry Andric // Static Helper functions
DumpModuleArchitecture(Stream & strm,Module * module,bool full_triple,uint32_t width)12900b57cec5SDimitry Andric static void DumpModuleArchitecture(Stream &strm, Module *module,
12910b57cec5SDimitry Andric                                    bool full_triple, uint32_t width) {
12920b57cec5SDimitry Andric   if (module) {
12930b57cec5SDimitry Andric     StreamString arch_strm;
12940b57cec5SDimitry Andric 
12950b57cec5SDimitry Andric     if (full_triple)
1296480093f4SDimitry Andric       module->GetArchitecture().DumpTriple(arch_strm.AsRawOstream());
12970b57cec5SDimitry Andric     else
12980b57cec5SDimitry Andric       arch_strm.PutCString(module->GetArchitecture().GetArchitectureName());
12995ffd83dbSDimitry Andric     std::string arch_str = std::string(arch_strm.GetString());
13000b57cec5SDimitry Andric 
13010b57cec5SDimitry Andric     if (width)
13020b57cec5SDimitry Andric       strm.Printf("%-*s", width, arch_str.c_str());
13030b57cec5SDimitry Andric     else
13040b57cec5SDimitry Andric       strm.PutCString(arch_str);
13050b57cec5SDimitry Andric   }
13060b57cec5SDimitry Andric }
13070b57cec5SDimitry Andric 
DumpModuleUUID(Stream & strm,Module * module)13080b57cec5SDimitry Andric static void DumpModuleUUID(Stream &strm, Module *module) {
13090b57cec5SDimitry Andric   if (module && module->GetUUID().IsValid())
1310fe013be4SDimitry Andric     module->GetUUID().Dump(strm);
13110b57cec5SDimitry Andric   else
13120b57cec5SDimitry Andric     strm.PutCString("                                    ");
13130b57cec5SDimitry Andric }
13140b57cec5SDimitry Andric 
DumpCompileUnitLineTable(CommandInterpreter & interpreter,Stream & strm,Module * module,const FileSpec & file_spec,lldb::DescriptionLevel desc_level)13150b57cec5SDimitry Andric static uint32_t DumpCompileUnitLineTable(CommandInterpreter &interpreter,
13160b57cec5SDimitry Andric                                          Stream &strm, Module *module,
13170b57cec5SDimitry Andric                                          const FileSpec &file_spec,
13180b57cec5SDimitry Andric                                          lldb::DescriptionLevel desc_level) {
13190b57cec5SDimitry Andric   uint32_t num_matches = 0;
13200b57cec5SDimitry Andric   if (module) {
13210b57cec5SDimitry Andric     SymbolContextList sc_list;
13220b57cec5SDimitry Andric     num_matches = module->ResolveSymbolContextsForFileSpec(
13230b57cec5SDimitry Andric         file_spec, 0, false, eSymbolContextCompUnit, sc_list);
13240b57cec5SDimitry Andric 
1325fe013be4SDimitry Andric     bool first_module = true;
1326fe013be4SDimitry Andric     for (const SymbolContext &sc : sc_list) {
1327fe013be4SDimitry Andric       if (!first_module)
13280b57cec5SDimitry Andric         strm << "\n\n";
13290b57cec5SDimitry Andric 
1330480093f4SDimitry Andric       strm << "Line table for " << sc.comp_unit->GetPrimaryFile() << " in `"
1331480093f4SDimitry Andric            << module->GetFileSpec().GetFilename() << "\n";
13320b57cec5SDimitry Andric       LineTable *line_table = sc.comp_unit->GetLineTable();
13330b57cec5SDimitry Andric       if (line_table)
13340b57cec5SDimitry Andric         line_table->GetDescription(
13350b57cec5SDimitry Andric             &strm, interpreter.GetExecutionContext().GetTargetPtr(),
13360b57cec5SDimitry Andric             desc_level);
13370b57cec5SDimitry Andric       else
13380b57cec5SDimitry Andric         strm << "No line table";
1339fe013be4SDimitry Andric 
1340fe013be4SDimitry Andric       first_module = false;
13410b57cec5SDimitry Andric     }
13420b57cec5SDimitry Andric   }
13430b57cec5SDimitry Andric   return num_matches;
13440b57cec5SDimitry Andric }
13450b57cec5SDimitry Andric 
DumpFullpath(Stream & strm,const FileSpec * file_spec_ptr,uint32_t width)13460b57cec5SDimitry Andric static void DumpFullpath(Stream &strm, const FileSpec *file_spec_ptr,
13470b57cec5SDimitry Andric                          uint32_t width) {
13480b57cec5SDimitry Andric   if (file_spec_ptr) {
13490b57cec5SDimitry Andric     if (width > 0) {
13500b57cec5SDimitry Andric       std::string fullpath = file_spec_ptr->GetPath();
13510b57cec5SDimitry Andric       strm.Printf("%-*s", width, fullpath.c_str());
13520b57cec5SDimitry Andric       return;
13530b57cec5SDimitry Andric     } else {
1354480093f4SDimitry Andric       file_spec_ptr->Dump(strm.AsRawOstream());
13550b57cec5SDimitry Andric       return;
13560b57cec5SDimitry Andric     }
13570b57cec5SDimitry Andric   }
13580b57cec5SDimitry Andric   // Keep the width spacing correct if things go wrong...
13590b57cec5SDimitry Andric   if (width > 0)
13600b57cec5SDimitry Andric     strm.Printf("%-*s", width, "");
13610b57cec5SDimitry Andric }
13620b57cec5SDimitry Andric 
DumpDirectory(Stream & strm,const FileSpec * file_spec_ptr,uint32_t width)13630b57cec5SDimitry Andric static void DumpDirectory(Stream &strm, const FileSpec *file_spec_ptr,
13640b57cec5SDimitry Andric                           uint32_t width) {
13650b57cec5SDimitry Andric   if (file_spec_ptr) {
13660b57cec5SDimitry Andric     if (width > 0)
13670b57cec5SDimitry Andric       strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
13680b57cec5SDimitry Andric     else
13690b57cec5SDimitry Andric       file_spec_ptr->GetDirectory().Dump(&strm);
13700b57cec5SDimitry Andric     return;
13710b57cec5SDimitry Andric   }
13720b57cec5SDimitry Andric   // Keep the width spacing correct if things go wrong...
13730b57cec5SDimitry Andric   if (width > 0)
13740b57cec5SDimitry Andric     strm.Printf("%-*s", width, "");
13750b57cec5SDimitry Andric }
13760b57cec5SDimitry Andric 
DumpBasename(Stream & strm,const FileSpec * file_spec_ptr,uint32_t width)13770b57cec5SDimitry Andric static void DumpBasename(Stream &strm, const FileSpec *file_spec_ptr,
13780b57cec5SDimitry Andric                          uint32_t width) {
13790b57cec5SDimitry Andric   if (file_spec_ptr) {
13800b57cec5SDimitry Andric     if (width > 0)
13810b57cec5SDimitry Andric       strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
13820b57cec5SDimitry Andric     else
13830b57cec5SDimitry Andric       file_spec_ptr->GetFilename().Dump(&strm);
13840b57cec5SDimitry Andric     return;
13850b57cec5SDimitry Andric   }
13860b57cec5SDimitry Andric   // Keep the width spacing correct if things go wrong...
13870b57cec5SDimitry Andric   if (width > 0)
13880b57cec5SDimitry Andric     strm.Printf("%-*s", width, "");
13890b57cec5SDimitry Andric }
13900b57cec5SDimitry Andric 
DumpModuleObjfileHeaders(Stream & strm,ModuleList & module_list)13910b57cec5SDimitry Andric static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) {
13920b57cec5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
13930b57cec5SDimitry Andric   const size_t num_modules = module_list.GetSize();
1394e8d8bef9SDimitry Andric   if (num_modules == 0)
1395e8d8bef9SDimitry Andric     return 0;
1396e8d8bef9SDimitry Andric 
1397e8d8bef9SDimitry Andric   size_t num_dumped = 0;
1398e8d8bef9SDimitry Andric   strm.Format("Dumping headers for {0} module(s).\n", num_modules);
13990b57cec5SDimitry Andric   strm.IndentMore();
1400e8d8bef9SDimitry Andric   for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
1401e8d8bef9SDimitry Andric     if (module_sp) {
14020b57cec5SDimitry Andric       if (num_dumped++ > 0) {
14030b57cec5SDimitry Andric         strm.EOL();
14040b57cec5SDimitry Andric         strm.EOL();
14050b57cec5SDimitry Andric       }
1406e8d8bef9SDimitry Andric       ObjectFile *objfile = module_sp->GetObjectFile();
14070b57cec5SDimitry Andric       if (objfile)
14080b57cec5SDimitry Andric         objfile->Dump(&strm);
14090b57cec5SDimitry Andric       else {
14100b57cec5SDimitry Andric         strm.Format("No object file for module: {0:F}\n",
1411e8d8bef9SDimitry Andric                     module_sp->GetFileSpec());
14120b57cec5SDimitry Andric       }
14130b57cec5SDimitry Andric     }
14140b57cec5SDimitry Andric   }
14150b57cec5SDimitry Andric   strm.IndentLess();
14160b57cec5SDimitry Andric   return num_dumped;
14170b57cec5SDimitry Andric }
14180b57cec5SDimitry Andric 
DumpModuleSymtab(CommandInterpreter & interpreter,Stream & strm,Module * module,SortOrder sort_order,Mangled::NamePreference name_preference)14190b57cec5SDimitry Andric static void DumpModuleSymtab(CommandInterpreter &interpreter, Stream &strm,
1420480093f4SDimitry Andric                              Module *module, SortOrder sort_order,
1421480093f4SDimitry Andric                              Mangled::NamePreference name_preference) {
14229dba64beSDimitry Andric   if (!module)
14239dba64beSDimitry Andric     return;
14249dba64beSDimitry Andric   if (Symtab *symtab = module->GetSymtab())
14250b57cec5SDimitry Andric     symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(),
1426480093f4SDimitry Andric                  sort_order, name_preference);
14270b57cec5SDimitry Andric }
14280b57cec5SDimitry Andric 
DumpModuleSections(CommandInterpreter & interpreter,Stream & strm,Module * module)14290b57cec5SDimitry Andric static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm,
14300b57cec5SDimitry Andric                                Module *module) {
14310b57cec5SDimitry Andric   if (module) {
14320b57cec5SDimitry Andric     SectionList *section_list = module->GetSectionList();
14330b57cec5SDimitry Andric     if (section_list) {
14340b57cec5SDimitry Andric       strm.Printf("Sections for '%s' (%s):\n",
14350b57cec5SDimitry Andric                   module->GetSpecificationDescription().c_str(),
14360b57cec5SDimitry Andric                   module->GetArchitecture().GetArchitectureName());
14375ffd83dbSDimitry Andric       section_list->Dump(strm.AsRawOstream(), strm.GetIndentLevel() + 2,
14380b57cec5SDimitry Andric                          interpreter.GetExecutionContext().GetTargetPtr(), true,
14390b57cec5SDimitry Andric                          UINT32_MAX);
14400b57cec5SDimitry Andric     }
14410b57cec5SDimitry Andric   }
14420b57cec5SDimitry Andric }
14430b57cec5SDimitry Andric 
DumpModuleSymbolFile(Stream & strm,Module * module)14449dba64beSDimitry Andric static bool DumpModuleSymbolFile(Stream &strm, Module *module) {
14450b57cec5SDimitry Andric   if (module) {
14469dba64beSDimitry Andric     if (SymbolFile *symbol_file = module->GetSymbolFile(true)) {
14479dba64beSDimitry Andric       symbol_file->Dump(strm);
14480b57cec5SDimitry Andric       return true;
14490b57cec5SDimitry Andric     }
14500b57cec5SDimitry Andric   }
14510b57cec5SDimitry Andric   return false;
14520b57cec5SDimitry Andric }
14530b57cec5SDimitry Andric 
GetSeparateDebugInfoList(StructuredData::Array & list,Module * module,bool errors_only)1454c9157d92SDimitry Andric static bool GetSeparateDebugInfoList(StructuredData::Array &list,
1455c9157d92SDimitry Andric                                      Module *module, bool errors_only) {
1456c9157d92SDimitry Andric   if (module) {
1457c9157d92SDimitry Andric     if (SymbolFile *symbol_file = module->GetSymbolFile(/*can_create=*/true)) {
1458c9157d92SDimitry Andric       StructuredData::Dictionary d;
1459c9157d92SDimitry Andric       if (symbol_file->GetSeparateDebugInfo(d, errors_only)) {
1460c9157d92SDimitry Andric         list.AddItem(
1461c9157d92SDimitry Andric             std::make_shared<StructuredData::Dictionary>(std::move(d)));
1462c9157d92SDimitry Andric         return true;
1463c9157d92SDimitry Andric       }
1464c9157d92SDimitry Andric     }
1465c9157d92SDimitry Andric   }
1466c9157d92SDimitry Andric   return false;
1467c9157d92SDimitry Andric }
1468c9157d92SDimitry Andric 
DumpDwoFilesTable(Stream & strm,StructuredData::Array & dwo_listings)1469c9157d92SDimitry Andric static void DumpDwoFilesTable(Stream &strm,
1470c9157d92SDimitry Andric                               StructuredData::Array &dwo_listings) {
1471c9157d92SDimitry Andric   strm.PutCString("Dwo ID             Err Dwo Path");
1472c9157d92SDimitry Andric   strm.EOL();
1473c9157d92SDimitry Andric   strm.PutCString(
1474c9157d92SDimitry Andric       "------------------ --- -----------------------------------------");
1475c9157d92SDimitry Andric   strm.EOL();
1476c9157d92SDimitry Andric   dwo_listings.ForEach([&strm](StructuredData::Object *dwo) {
1477c9157d92SDimitry Andric     StructuredData::Dictionary *dict = dwo->GetAsDictionary();
1478c9157d92SDimitry Andric     if (!dict)
1479c9157d92SDimitry Andric       return false;
1480c9157d92SDimitry Andric 
1481c9157d92SDimitry Andric     uint64_t dwo_id;
1482c9157d92SDimitry Andric     if (dict->GetValueForKeyAsInteger("dwo_id", dwo_id))
1483c9157d92SDimitry Andric       strm.Printf("0x%16.16" PRIx64 " ", dwo_id);
1484c9157d92SDimitry Andric     else
1485c9157d92SDimitry Andric       strm.Printf("0x???????????????? ");
1486c9157d92SDimitry Andric 
1487c9157d92SDimitry Andric     llvm::StringRef error;
1488c9157d92SDimitry Andric     if (dict->GetValueForKeyAsString("error", error))
1489c9157d92SDimitry Andric       strm << "E   " << error;
1490c9157d92SDimitry Andric     else {
1491c9157d92SDimitry Andric       llvm::StringRef resolved_dwo_path;
1492c9157d92SDimitry Andric       if (dict->GetValueForKeyAsString("resolved_dwo_path",
1493c9157d92SDimitry Andric                                        resolved_dwo_path)) {
1494c9157d92SDimitry Andric         strm << "    " << resolved_dwo_path;
1495c9157d92SDimitry Andric         if (resolved_dwo_path.ends_with(".dwp")) {
1496c9157d92SDimitry Andric           llvm::StringRef dwo_name;
1497c9157d92SDimitry Andric           if (dict->GetValueForKeyAsString("dwo_name", dwo_name))
1498c9157d92SDimitry Andric             strm << "(" << dwo_name << ")";
1499c9157d92SDimitry Andric         }
1500c9157d92SDimitry Andric       }
1501c9157d92SDimitry Andric     }
1502c9157d92SDimitry Andric     strm.EOL();
1503c9157d92SDimitry Andric     return true;
1504c9157d92SDimitry Andric   });
1505c9157d92SDimitry Andric }
1506c9157d92SDimitry Andric 
DumpOsoFilesTable(Stream & strm,StructuredData::Array & oso_listings)1507c9157d92SDimitry Andric static void DumpOsoFilesTable(Stream &strm,
1508c9157d92SDimitry Andric                               StructuredData::Array &oso_listings) {
1509c9157d92SDimitry Andric   strm.PutCString("Mod Time           Err Oso Path");
1510c9157d92SDimitry Andric   strm.EOL();
1511c9157d92SDimitry Andric   strm.PutCString("------------------ --- ---------------------");
1512c9157d92SDimitry Andric   strm.EOL();
1513c9157d92SDimitry Andric   oso_listings.ForEach([&strm](StructuredData::Object *oso) {
1514c9157d92SDimitry Andric     StructuredData::Dictionary *dict = oso->GetAsDictionary();
1515c9157d92SDimitry Andric     if (!dict)
1516c9157d92SDimitry Andric       return false;
1517c9157d92SDimitry Andric 
1518c9157d92SDimitry Andric     uint32_t oso_mod_time;
1519c9157d92SDimitry Andric     if (dict->GetValueForKeyAsInteger("oso_mod_time", oso_mod_time))
1520c9157d92SDimitry Andric       strm.Printf("0x%16.16" PRIx32 " ", oso_mod_time);
1521c9157d92SDimitry Andric 
1522c9157d92SDimitry Andric     llvm::StringRef error;
1523c9157d92SDimitry Andric     if (dict->GetValueForKeyAsString("error", error))
1524c9157d92SDimitry Andric       strm << "E   " << error;
1525c9157d92SDimitry Andric     else {
1526c9157d92SDimitry Andric       llvm::StringRef oso_path;
1527c9157d92SDimitry Andric       if (dict->GetValueForKeyAsString("oso_path", oso_path))
1528c9157d92SDimitry Andric         strm << "    " << oso_path;
1529c9157d92SDimitry Andric     }
1530c9157d92SDimitry Andric     strm.EOL();
1531c9157d92SDimitry Andric     return true;
1532c9157d92SDimitry Andric   });
1533c9157d92SDimitry Andric }
1534c9157d92SDimitry Andric 
1535*a58f00eaSDimitry 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)1536*a58f00eaSDimitry Andric DumpAddress(ExecutionContextScope *exe_scope, const Address &so_addr,
1537*a58f00eaSDimitry Andric             bool verbose, bool all_ranges, Stream &strm,
1538*a58f00eaSDimitry Andric             std::optional<Stream::HighlightSettings> settings = std::nullopt) {
15390b57cec5SDimitry Andric   strm.IndentMore();
15400b57cec5SDimitry Andric   strm.Indent("    Address: ");
15410b57cec5SDimitry Andric   so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
15420b57cec5SDimitry Andric   strm.PutCString(" (");
15430b57cec5SDimitry Andric   so_addr.Dump(&strm, exe_scope, Address::DumpStyleSectionNameOffset);
15440b57cec5SDimitry Andric   strm.PutCString(")\n");
15450b57cec5SDimitry Andric   strm.Indent("    Summary: ");
15460b57cec5SDimitry Andric   const uint32_t save_indent = strm.GetIndentLevel();
15470b57cec5SDimitry Andric   strm.SetIndentLevel(save_indent + 13);
1548c9157d92SDimitry Andric   so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription,
1549*a58f00eaSDimitry Andric                Address::DumpStyleInvalid, UINT32_MAX, false, settings);
15500b57cec5SDimitry Andric   strm.SetIndentLevel(save_indent);
15510b57cec5SDimitry Andric   // Print out detailed address information when verbose is enabled
15520b57cec5SDimitry Andric   if (verbose) {
15530b57cec5SDimitry Andric     strm.EOL();
155481ad6265SDimitry Andric     so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext,
1555*a58f00eaSDimitry Andric                  Address::DumpStyleInvalid, UINT32_MAX, all_ranges, settings);
15560b57cec5SDimitry Andric   }
15570b57cec5SDimitry Andric   strm.IndentLess();
15580b57cec5SDimitry Andric }
15590b57cec5SDimitry Andric 
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)15600b57cec5SDimitry Andric static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm,
15610b57cec5SDimitry Andric                                   Module *module, uint32_t resolve_mask,
15620b57cec5SDimitry Andric                                   lldb::addr_t raw_addr, lldb::addr_t offset,
156381ad6265SDimitry Andric                                   bool verbose, bool all_ranges) {
15640b57cec5SDimitry Andric   if (module) {
15650b57cec5SDimitry Andric     lldb::addr_t addr = raw_addr - offset;
15660b57cec5SDimitry Andric     Address so_addr;
15670b57cec5SDimitry Andric     SymbolContext sc;
15680b57cec5SDimitry Andric     Target *target = interpreter.GetExecutionContext().GetTargetPtr();
15690b57cec5SDimitry Andric     if (target && !target->GetSectionLoadList().IsEmpty()) {
15700b57cec5SDimitry Andric       if (!target->GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
15710b57cec5SDimitry Andric         return false;
15720b57cec5SDimitry Andric       else if (so_addr.GetModule().get() != module)
15730b57cec5SDimitry Andric         return false;
15740b57cec5SDimitry Andric     } else {
15750b57cec5SDimitry Andric       if (!module->ResolveFileAddress(addr, so_addr))
15760b57cec5SDimitry Andric         return false;
15770b57cec5SDimitry Andric     }
15780b57cec5SDimitry Andric 
15790b57cec5SDimitry Andric     ExecutionContextScope *exe_scope =
15800b57cec5SDimitry Andric         interpreter.GetExecutionContext().GetBestExecutionContextScope();
158181ad6265SDimitry Andric     DumpAddress(exe_scope, so_addr, verbose, all_ranges, strm);
15820b57cec5SDimitry Andric     return true;
15830b57cec5SDimitry Andric   }
15840b57cec5SDimitry Andric 
15850b57cec5SDimitry Andric   return false;
15860b57cec5SDimitry Andric }
15870b57cec5SDimitry Andric 
LookupSymbolInModule(CommandInterpreter & interpreter,Stream & strm,Module * module,const char * name,bool name_is_regex,bool verbose,bool all_ranges)15880b57cec5SDimitry Andric static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
15890b57cec5SDimitry Andric                                      Stream &strm, Module *module,
15900b57cec5SDimitry Andric                                      const char *name, bool name_is_regex,
159181ad6265SDimitry Andric                                      bool verbose, bool all_ranges) {
15929dba64beSDimitry Andric   if (!module)
15939dba64beSDimitry Andric     return 0;
15940b57cec5SDimitry Andric 
15959dba64beSDimitry Andric   Symtab *symtab = module->GetSymtab();
15969dba64beSDimitry Andric   if (!symtab)
15979dba64beSDimitry Andric     return 0;
15989dba64beSDimitry Andric 
15999dba64beSDimitry Andric   SymbolContext sc;
1600c9157d92SDimitry Andric   const bool use_color = interpreter.GetDebugger().GetUseColor();
16010b57cec5SDimitry Andric   std::vector<uint32_t> match_indexes;
16020b57cec5SDimitry Andric   ConstString symbol_name(name);
16030b57cec5SDimitry Andric   uint32_t num_matches = 0;
16040b57cec5SDimitry Andric   if (name_is_regex) {
16050b57cec5SDimitry Andric     RegularExpression name_regexp(symbol_name.GetStringRef());
16060b57cec5SDimitry Andric     num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType(
16070b57cec5SDimitry Andric         name_regexp, eSymbolTypeAny, match_indexes);
16080b57cec5SDimitry Andric   } else {
16090b57cec5SDimitry Andric     num_matches =
16100b57cec5SDimitry Andric         symtab->AppendSymbolIndexesWithName(symbol_name, match_indexes);
16110b57cec5SDimitry Andric   }
16120b57cec5SDimitry Andric 
16130b57cec5SDimitry Andric   if (num_matches > 0) {
16140b57cec5SDimitry Andric     strm.Indent();
16150b57cec5SDimitry Andric     strm.Printf("%u symbols match %s'%s' in ", num_matches,
16160b57cec5SDimitry Andric                 name_is_regex ? "the regular expression " : "", name);
16170b57cec5SDimitry Andric     DumpFullpath(strm, &module->GetFileSpec(), 0);
16180b57cec5SDimitry Andric     strm.PutCString(":\n");
16190b57cec5SDimitry Andric     strm.IndentMore();
1620*a58f00eaSDimitry Andric     Stream::HighlightSettings settings(
1621*a58f00eaSDimitry Andric         name, interpreter.GetDebugger().GetRegexMatchAnsiPrefix(),
1622*a58f00eaSDimitry Andric         interpreter.GetDebugger().GetRegexMatchAnsiSuffix());
16230b57cec5SDimitry Andric     for (uint32_t i = 0; i < num_matches; ++i) {
16240b57cec5SDimitry Andric       Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
1625bdd1243dSDimitry Andric       if (symbol) {
1626bdd1243dSDimitry Andric         if (symbol->ValueIsAddress()) {
16279dba64beSDimitry Andric           DumpAddress(
16289dba64beSDimitry Andric               interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1629c9157d92SDimitry Andric               symbol->GetAddressRef(), verbose, all_ranges, strm,
1630*a58f00eaSDimitry Andric               use_color && name_is_regex
1631*a58f00eaSDimitry Andric                   ? std::optional<Stream::HighlightSettings>{settings}
1632*a58f00eaSDimitry Andric                   : std::nullopt);
1633bdd1243dSDimitry Andric           strm.EOL();
1634bdd1243dSDimitry Andric         } else {
1635bdd1243dSDimitry Andric           strm.IndentMore();
1636bdd1243dSDimitry Andric           strm.Indent("    Name: ");
1637c9157d92SDimitry Andric           strm.PutCStringColorHighlighted(
1638c9157d92SDimitry Andric               symbol->GetDisplayName().GetStringRef(),
1639*a58f00eaSDimitry Andric               use_color && name_is_regex
1640*a58f00eaSDimitry Andric                   ? std::optional<Stream::HighlightSettings>{settings}
1641*a58f00eaSDimitry Andric                   : std::nullopt);
1642bdd1243dSDimitry Andric           strm.EOL();
1643bdd1243dSDimitry Andric           strm.Indent("    Value: ");
1644bdd1243dSDimitry Andric           strm.Printf("0x%16.16" PRIx64 "\n", symbol->GetRawValue());
1645bdd1243dSDimitry Andric           if (symbol->GetByteSizeIsValid()) {
1646bdd1243dSDimitry Andric             strm.Indent("    Size: ");
1647bdd1243dSDimitry Andric             strm.Printf("0x%16.16" PRIx64 "\n", symbol->GetByteSize());
1648bdd1243dSDimitry Andric           }
1649bdd1243dSDimitry Andric           strm.IndentLess();
1650bdd1243dSDimitry Andric         }
16510b57cec5SDimitry Andric       }
16520b57cec5SDimitry Andric     }
16530b57cec5SDimitry Andric     strm.IndentLess();
16549dba64beSDimitry Andric   }
16550b57cec5SDimitry Andric   return num_matches;
16560b57cec5SDimitry Andric }
16570b57cec5SDimitry Andric 
DumpSymbolContextList(ExecutionContextScope * exe_scope,Stream & strm,const SymbolContextList & sc_list,bool verbose,bool all_ranges,std::optional<Stream::HighlightSettings> settings=std::nullopt)1658*a58f00eaSDimitry Andric static void DumpSymbolContextList(
1659*a58f00eaSDimitry Andric     ExecutionContextScope *exe_scope, Stream &strm,
1660*a58f00eaSDimitry Andric     const SymbolContextList &sc_list, bool verbose, bool all_ranges,
1661*a58f00eaSDimitry Andric     std::optional<Stream::HighlightSettings> settings = std::nullopt) {
16620b57cec5SDimitry Andric   strm.IndentMore();
1663fe013be4SDimitry Andric   bool first_module = true;
1664fe013be4SDimitry Andric   for (const SymbolContext &sc : sc_list) {
1665fe013be4SDimitry Andric     if (!first_module)
1666fe013be4SDimitry Andric       strm.EOL();
16670b57cec5SDimitry Andric 
16680b57cec5SDimitry Andric     AddressRange range;
16690b57cec5SDimitry Andric 
16700b57cec5SDimitry Andric     sc.GetAddressRange(eSymbolContextEverything, 0, true, range);
16710b57cec5SDimitry Andric 
1672*a58f00eaSDimitry Andric     DumpAddress(exe_scope, range.GetBaseAddress(), verbose, all_ranges, strm,
1673*a58f00eaSDimitry Andric                 settings);
1674fe013be4SDimitry Andric     first_module = false;
16750b57cec5SDimitry Andric   }
16760b57cec5SDimitry Andric   strm.IndentLess();
16770b57cec5SDimitry Andric }
16780b57cec5SDimitry Andric 
LookupFunctionInModule(CommandInterpreter & interpreter,Stream & strm,Module * module,const char * name,bool name_is_regex,const ModuleFunctionSearchOptions & options,bool verbose,bool all_ranges)16790b57cec5SDimitry Andric static size_t LookupFunctionInModule(CommandInterpreter &interpreter,
16800b57cec5SDimitry Andric                                      Stream &strm, Module *module,
16810b57cec5SDimitry Andric                                      const char *name, bool name_is_regex,
1682349cc55cSDimitry Andric                                      const ModuleFunctionSearchOptions &options,
168381ad6265SDimitry Andric                                      bool verbose, bool all_ranges) {
16840b57cec5SDimitry Andric   if (module && name && name[0]) {
16850b57cec5SDimitry Andric     SymbolContextList sc_list;
16860b57cec5SDimitry Andric     size_t num_matches = 0;
16870b57cec5SDimitry Andric     if (name_is_regex) {
16880b57cec5SDimitry Andric       RegularExpression function_name_regex((llvm::StringRef(name)));
1689349cc55cSDimitry Andric       module->FindFunctions(function_name_regex, options, sc_list);
16900b57cec5SDimitry Andric     } else {
16910b57cec5SDimitry Andric       ConstString function_name(name);
16925ffd83dbSDimitry Andric       module->FindFunctions(function_name, CompilerDeclContext(),
1693349cc55cSDimitry Andric                             eFunctionNameTypeAuto, options, sc_list);
16940b57cec5SDimitry Andric     }
16959dba64beSDimitry Andric     num_matches = sc_list.GetSize();
16960b57cec5SDimitry Andric     if (num_matches) {
16970b57cec5SDimitry Andric       strm.Indent();
16980b57cec5SDimitry Andric       strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
16990b57cec5SDimitry Andric                   num_matches > 1 ? "es" : "");
17000b57cec5SDimitry Andric       DumpFullpath(strm, &module->GetFileSpec(), 0);
17010b57cec5SDimitry Andric       strm.PutCString(":\n");
17020b57cec5SDimitry Andric       DumpSymbolContextList(
17030b57cec5SDimitry Andric           interpreter.GetExecutionContext().GetBestExecutionContextScope(),
170481ad6265SDimitry Andric           strm, sc_list, verbose, all_ranges);
17050b57cec5SDimitry Andric     }
17060b57cec5SDimitry Andric     return num_matches;
17070b57cec5SDimitry Andric   }
17080b57cec5SDimitry Andric   return 0;
17090b57cec5SDimitry Andric }
17100b57cec5SDimitry Andric 
LookupTypeInModule(Target * target,CommandInterpreter & interpreter,Stream & strm,Module * module,const char * name_cstr,bool name_is_regex)1711e8d8bef9SDimitry Andric static size_t LookupTypeInModule(Target *target,
1712e8d8bef9SDimitry Andric                                  CommandInterpreter &interpreter, Stream &strm,
17130b57cec5SDimitry Andric                                  Module *module, const char *name_cstr,
17140b57cec5SDimitry Andric                                  bool name_is_regex) {
17159dba64beSDimitry Andric   if (module && name_cstr && name_cstr[0]) {
1716c9157d92SDimitry Andric     TypeQuery query(name_cstr);
1717c9157d92SDimitry Andric     TypeResults results;
1718c9157d92SDimitry Andric     module->FindTypes(query, results);
17190b57cec5SDimitry Andric 
1720c9157d92SDimitry Andric     TypeList type_list;
1721c9157d92SDimitry Andric     SymbolContext sc;
1722c9157d92SDimitry Andric     if (module)
1723c9157d92SDimitry Andric       sc.module_sp = module->shared_from_this();
1724c9157d92SDimitry Andric     // Sort the type results and put the results that matched in \a module
1725c9157d92SDimitry Andric     // first if \a module was specified.
1726c9157d92SDimitry Andric     sc.SortTypeList(results.GetTypeMap(), type_list);
17279dba64beSDimitry Andric     if (type_list.Empty())
17289dba64beSDimitry Andric       return 0;
17299dba64beSDimitry Andric 
173004eeddc0SDimitry Andric     const uint64_t num_matches = type_list.GetSize();
173104eeddc0SDimitry Andric 
17320b57cec5SDimitry Andric     strm.Indent();
173304eeddc0SDimitry Andric     strm.Printf("%" PRIu64 " match%s found in ", num_matches,
17340b57cec5SDimitry Andric                 num_matches > 1 ? "es" : "");
17350b57cec5SDimitry Andric     DumpFullpath(strm, &module->GetFileSpec(), 0);
17360b57cec5SDimitry Andric     strm.PutCString(":\n");
17370b57cec5SDimitry Andric     for (TypeSP type_sp : type_list.Types()) {
17389dba64beSDimitry Andric       if (!type_sp)
17399dba64beSDimitry Andric         continue;
17400b57cec5SDimitry Andric       // Resolve the clang type so that any forward references to types
17410b57cec5SDimitry Andric       // that haven't yet been parsed will get parsed.
17420b57cec5SDimitry Andric       type_sp->GetFullCompilerType();
1743e8d8bef9SDimitry Andric       type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target);
17440b57cec5SDimitry Andric       // Print all typedef chains
17450b57cec5SDimitry Andric       TypeSP typedef_type_sp(type_sp);
17460b57cec5SDimitry Andric       TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
17470b57cec5SDimitry Andric       while (typedefed_type_sp) {
17480b57cec5SDimitry Andric         strm.EOL();
17490b57cec5SDimitry Andric         strm.Printf("     typedef '%s': ",
17500b57cec5SDimitry Andric                     typedef_type_sp->GetName().GetCString());
17510b57cec5SDimitry Andric         typedefed_type_sp->GetFullCompilerType();
1752e8d8bef9SDimitry Andric         typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true,
1753e8d8bef9SDimitry Andric                                           target);
17540b57cec5SDimitry Andric         typedef_type_sp = typedefed_type_sp;
17550b57cec5SDimitry Andric         typedefed_type_sp = typedef_type_sp->GetTypedefType();
17560b57cec5SDimitry Andric       }
17570b57cec5SDimitry Andric       strm.EOL();
17580b57cec5SDimitry Andric     }
17599dba64beSDimitry Andric     return type_list.GetSize();
17600b57cec5SDimitry Andric   }
1761c9157d92SDimitry Andric   return 0;
1762c9157d92SDimitry Andric }
17630b57cec5SDimitry Andric 
LookupTypeHere(Target * target,CommandInterpreter & interpreter,Stream & strm,Module & module,const char * name_cstr,bool name_is_regex)1764e8d8bef9SDimitry Andric static size_t LookupTypeHere(Target *target, CommandInterpreter &interpreter,
1765e8d8bef9SDimitry Andric                              Stream &strm, Module &module,
1766e8d8bef9SDimitry Andric                              const char *name_cstr, bool name_is_regex) {
1767c9157d92SDimitry Andric   TypeQuery query(name_cstr);
1768c9157d92SDimitry Andric   TypeResults results;
1769c9157d92SDimitry Andric   module.FindTypes(query, results);
17700b57cec5SDimitry Andric   TypeList type_list;
1771c9157d92SDimitry Andric   SymbolContext sc;
1772c9157d92SDimitry Andric   sc.module_sp = module.shared_from_this();
1773c9157d92SDimitry Andric   sc.SortTypeList(results.GetTypeMap(), type_list);
17749dba64beSDimitry Andric   if (type_list.Empty())
17759dba64beSDimitry Andric     return 0;
17769dba64beSDimitry Andric 
17770b57cec5SDimitry Andric   strm.Indent();
17780b57cec5SDimitry Andric   strm.PutCString("Best match found in ");
17790b57cec5SDimitry Andric   DumpFullpath(strm, &module.GetFileSpec(), 0);
17800b57cec5SDimitry Andric   strm.PutCString(":\n");
17810b57cec5SDimitry Andric 
17820b57cec5SDimitry Andric   TypeSP type_sp(type_list.GetTypeAtIndex(0));
17830b57cec5SDimitry Andric   if (type_sp) {
17840b57cec5SDimitry Andric     // Resolve the clang type so that any forward references to types that
17850b57cec5SDimitry Andric     // haven't yet been parsed will get parsed.
17860b57cec5SDimitry Andric     type_sp->GetFullCompilerType();
1787e8d8bef9SDimitry Andric     type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target);
1788e8d8bef9SDimitry Andric     // Print all typedef chains.
17890b57cec5SDimitry Andric     TypeSP typedef_type_sp(type_sp);
17900b57cec5SDimitry Andric     TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
17910b57cec5SDimitry Andric     while (typedefed_type_sp) {
17920b57cec5SDimitry Andric       strm.EOL();
17930b57cec5SDimitry Andric       strm.Printf("     typedef '%s': ",
17940b57cec5SDimitry Andric                   typedef_type_sp->GetName().GetCString());
17950b57cec5SDimitry Andric       typedefed_type_sp->GetFullCompilerType();
1796e8d8bef9SDimitry Andric       typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true,
1797e8d8bef9SDimitry Andric                                         target);
17980b57cec5SDimitry Andric       typedef_type_sp = typedefed_type_sp;
17990b57cec5SDimitry Andric       typedefed_type_sp = typedef_type_sp->GetTypedefType();
18000b57cec5SDimitry Andric     }
18010b57cec5SDimitry Andric   }
18020b57cec5SDimitry Andric   strm.EOL();
18039dba64beSDimitry Andric   return type_list.GetSize();
18040b57cec5SDimitry Andric }
18050b57cec5SDimitry Andric 
LookupFileAndLineInModule(CommandInterpreter & interpreter,Stream & strm,Module * module,const FileSpec & file_spec,uint32_t line,bool check_inlines,bool verbose,bool all_ranges)18060b57cec5SDimitry Andric static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter,
18070b57cec5SDimitry Andric                                           Stream &strm, Module *module,
18080b57cec5SDimitry Andric                                           const FileSpec &file_spec,
18090b57cec5SDimitry Andric                                           uint32_t line, bool check_inlines,
181081ad6265SDimitry Andric                                           bool verbose, bool all_ranges) {
18110b57cec5SDimitry Andric   if (module && file_spec) {
18120b57cec5SDimitry Andric     SymbolContextList sc_list;
18130b57cec5SDimitry Andric     const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(
18140b57cec5SDimitry Andric         file_spec, line, check_inlines, eSymbolContextEverything, sc_list);
18150b57cec5SDimitry Andric     if (num_matches > 0) {
18160b57cec5SDimitry Andric       strm.Indent();
18170b57cec5SDimitry Andric       strm.Printf("%u match%s found in ", num_matches,
18180b57cec5SDimitry Andric                   num_matches > 1 ? "es" : "");
18190b57cec5SDimitry Andric       strm << file_spec;
18200b57cec5SDimitry Andric       if (line > 0)
18210b57cec5SDimitry Andric         strm.Printf(":%u", line);
18220b57cec5SDimitry Andric       strm << " in ";
18230b57cec5SDimitry Andric       DumpFullpath(strm, &module->GetFileSpec(), 0);
18240b57cec5SDimitry Andric       strm.PutCString(":\n");
18250b57cec5SDimitry Andric       DumpSymbolContextList(
18260b57cec5SDimitry Andric           interpreter.GetExecutionContext().GetBestExecutionContextScope(),
182781ad6265SDimitry Andric           strm, sc_list, verbose, all_ranges);
18280b57cec5SDimitry Andric       return num_matches;
18290b57cec5SDimitry Andric     }
18300b57cec5SDimitry Andric   }
18310b57cec5SDimitry Andric   return 0;
18320b57cec5SDimitry Andric }
18330b57cec5SDimitry Andric 
FindModulesByName(Target * target,const char * module_name,ModuleList & module_list,bool check_global_list)18340b57cec5SDimitry Andric static size_t FindModulesByName(Target *target, const char *module_name,
18350b57cec5SDimitry Andric                                 ModuleList &module_list,
18360b57cec5SDimitry Andric                                 bool check_global_list) {
18370b57cec5SDimitry Andric   FileSpec module_file_spec(module_name);
18380b57cec5SDimitry Andric   ModuleSpec module_spec(module_file_spec);
18390b57cec5SDimitry Andric 
18400b57cec5SDimitry Andric   const size_t initial_size = module_list.GetSize();
18410b57cec5SDimitry Andric 
18420b57cec5SDimitry Andric   if (check_global_list) {
18430b57cec5SDimitry Andric     // Check the global list
18440b57cec5SDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
18450b57cec5SDimitry Andric         Module::GetAllocationModuleCollectionMutex());
18460b57cec5SDimitry Andric     const size_t num_modules = Module::GetNumberAllocatedModules();
18470b57cec5SDimitry Andric     ModuleSP module_sp;
18480b57cec5SDimitry Andric     for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
18490b57cec5SDimitry Andric       Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
18500b57cec5SDimitry Andric 
18510b57cec5SDimitry Andric       if (module) {
18520b57cec5SDimitry Andric         if (module->MatchesModuleSpec(module_spec)) {
18530b57cec5SDimitry Andric           module_sp = module->shared_from_this();
18540b57cec5SDimitry Andric           module_list.AppendIfNeeded(module_sp);
18550b57cec5SDimitry Andric         }
18560b57cec5SDimitry Andric       }
18570b57cec5SDimitry Andric     }
18580b57cec5SDimitry Andric   } else {
18590b57cec5SDimitry Andric     if (target) {
18600b57cec5SDimitry Andric       target->GetImages().FindModules(module_spec, module_list);
18619dba64beSDimitry Andric       const size_t num_matches = module_list.GetSize();
18620b57cec5SDimitry Andric 
18630b57cec5SDimitry Andric       // Not found in our module list for our target, check the main shared
18640b57cec5SDimitry Andric       // module list in case it is a extra file used somewhere else
18650b57cec5SDimitry Andric       if (num_matches == 0) {
18660b57cec5SDimitry Andric         module_spec.GetArchitecture() = target->GetArchitecture();
18670b57cec5SDimitry Andric         ModuleList::FindSharedModules(module_spec, module_list);
18680b57cec5SDimitry Andric       }
18690b57cec5SDimitry Andric     } else {
18700b57cec5SDimitry Andric       ModuleList::FindSharedModules(module_spec, module_list);
18710b57cec5SDimitry Andric     }
18720b57cec5SDimitry Andric   }
18730b57cec5SDimitry Andric 
18740b57cec5SDimitry Andric   return module_list.GetSize() - initial_size;
18750b57cec5SDimitry Andric }
18760b57cec5SDimitry Andric 
18770b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesModuleAutoComplete
18780b57cec5SDimitry Andric 
18790b57cec5SDimitry Andric // A base command object class that can auto complete with module file
18800b57cec5SDimitry Andric // paths
18810b57cec5SDimitry Andric 
18820b57cec5SDimitry Andric class CommandObjectTargetModulesModuleAutoComplete
18830b57cec5SDimitry Andric     : public CommandObjectParsed {
18840b57cec5SDimitry Andric public:
CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter & interpreter,const char * name,const char * help,const char * syntax,uint32_t flags=0)18850b57cec5SDimitry Andric   CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter &interpreter,
18860b57cec5SDimitry Andric                                                const char *name,
18870b57cec5SDimitry Andric                                                const char *help,
18889dba64beSDimitry Andric                                                const char *syntax,
18899dba64beSDimitry Andric                                                uint32_t flags = 0)
18909dba64beSDimitry Andric       : CommandObjectParsed(interpreter, name, help, syntax, flags) {
18910b57cec5SDimitry Andric     CommandArgumentEntry arg;
18920b57cec5SDimitry Andric     CommandArgumentData file_arg;
18930b57cec5SDimitry Andric 
18940b57cec5SDimitry Andric     // Define the first (and only) variant of this arg.
18950b57cec5SDimitry Andric     file_arg.arg_type = eArgTypeFilename;
18960b57cec5SDimitry Andric     file_arg.arg_repetition = eArgRepeatStar;
18970b57cec5SDimitry Andric 
18980b57cec5SDimitry Andric     // There is only one variant this argument could be; put it into the
18990b57cec5SDimitry Andric     // argument entry.
19000b57cec5SDimitry Andric     arg.push_back(file_arg);
19010b57cec5SDimitry Andric 
19020b57cec5SDimitry Andric     // Push the data for the first argument into the m_arguments vector.
19030b57cec5SDimitry Andric     m_arguments.push_back(arg);
19040b57cec5SDimitry Andric   }
19050b57cec5SDimitry Andric 
19060b57cec5SDimitry Andric   ~CommandObjectTargetModulesModuleAutoComplete() override = default;
19070b57cec5SDimitry Andric 
19089dba64beSDimitry Andric   void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)19099dba64beSDimitry Andric   HandleArgumentCompletion(CompletionRequest &request,
19100b57cec5SDimitry Andric                            OptionElementVector &opt_element_vector) override {
1911fe013be4SDimitry Andric     lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
1912fe013be4SDimitry Andric         GetCommandInterpreter(), lldb::eModuleCompletion, request, nullptr);
19130b57cec5SDimitry Andric   }
19140b57cec5SDimitry Andric };
19150b57cec5SDimitry Andric 
19160b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesSourceFileAutoComplete
19170b57cec5SDimitry Andric 
19180b57cec5SDimitry Andric // A base command object class that can auto complete with module source
19190b57cec5SDimitry Andric // file paths
19200b57cec5SDimitry Andric 
19210b57cec5SDimitry Andric class CommandObjectTargetModulesSourceFileAutoComplete
19220b57cec5SDimitry Andric     : public CommandObjectParsed {
19230b57cec5SDimitry Andric public:
CommandObjectTargetModulesSourceFileAutoComplete(CommandInterpreter & interpreter,const char * name,const char * help,const char * syntax,uint32_t flags)19240b57cec5SDimitry Andric   CommandObjectTargetModulesSourceFileAutoComplete(
19250b57cec5SDimitry Andric       CommandInterpreter &interpreter, const char *name, const char *help,
19260b57cec5SDimitry Andric       const char *syntax, uint32_t flags)
19270b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, name, help, syntax, flags) {
19280b57cec5SDimitry Andric     CommandArgumentEntry arg;
19290b57cec5SDimitry Andric     CommandArgumentData source_file_arg;
19300b57cec5SDimitry Andric 
19310b57cec5SDimitry Andric     // Define the first (and only) variant of this arg.
19320b57cec5SDimitry Andric     source_file_arg.arg_type = eArgTypeSourceFile;
19330b57cec5SDimitry Andric     source_file_arg.arg_repetition = eArgRepeatPlus;
19340b57cec5SDimitry Andric 
19350b57cec5SDimitry Andric     // There is only one variant this argument could be; put it into the
19360b57cec5SDimitry Andric     // argument entry.
19370b57cec5SDimitry Andric     arg.push_back(source_file_arg);
19380b57cec5SDimitry Andric 
19390b57cec5SDimitry Andric     // Push the data for the first argument into the m_arguments vector.
19400b57cec5SDimitry Andric     m_arguments.push_back(arg);
19410b57cec5SDimitry Andric   }
19420b57cec5SDimitry Andric 
19430b57cec5SDimitry Andric   ~CommandObjectTargetModulesSourceFileAutoComplete() override = default;
19440b57cec5SDimitry Andric 
19459dba64beSDimitry Andric   void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)19469dba64beSDimitry Andric   HandleArgumentCompletion(CompletionRequest &request,
19470b57cec5SDimitry Andric                            OptionElementVector &opt_element_vector) override {
1948fe013be4SDimitry Andric     lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
1949fe013be4SDimitry Andric         GetCommandInterpreter(), lldb::eSourceFileCompletion, request, nullptr);
19500b57cec5SDimitry Andric   }
19510b57cec5SDimitry Andric };
19520b57cec5SDimitry Andric 
19530b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesDumpObjfile
19540b57cec5SDimitry Andric 
19550b57cec5SDimitry Andric class CommandObjectTargetModulesDumpObjfile
19560b57cec5SDimitry Andric     : public CommandObjectTargetModulesModuleAutoComplete {
19570b57cec5SDimitry Andric public:
CommandObjectTargetModulesDumpObjfile(CommandInterpreter & interpreter)19580b57cec5SDimitry Andric   CommandObjectTargetModulesDumpObjfile(CommandInterpreter &interpreter)
19590b57cec5SDimitry Andric       : CommandObjectTargetModulesModuleAutoComplete(
19600b57cec5SDimitry Andric             interpreter, "target modules dump objfile",
19610b57cec5SDimitry Andric             "Dump the object file headers from one or more target modules.",
19629dba64beSDimitry Andric             nullptr, eCommandRequiresTarget) {}
19630b57cec5SDimitry Andric 
19640b57cec5SDimitry Andric   ~CommandObjectTargetModulesDumpObjfile() override = default;
19650b57cec5SDimitry Andric 
19660b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)1967c9157d92SDimitry Andric   void DoExecute(Args &command, CommandReturnObject &result) override {
19689dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
19690b57cec5SDimitry Andric 
19700b57cec5SDimitry Andric     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
19710b57cec5SDimitry Andric     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
19720b57cec5SDimitry Andric     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
19730b57cec5SDimitry Andric 
19740b57cec5SDimitry Andric     size_t num_dumped = 0;
19750b57cec5SDimitry Andric     if (command.GetArgumentCount() == 0) {
19760b57cec5SDimitry Andric       // Dump all headers for all modules images
19770b57cec5SDimitry Andric       num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(),
19780b57cec5SDimitry Andric                                             target->GetImages());
19790b57cec5SDimitry Andric       if (num_dumped == 0) {
19800b57cec5SDimitry Andric         result.AppendError("the target has no associated executable images");
19810b57cec5SDimitry Andric       }
19820b57cec5SDimitry Andric     } else {
19830b57cec5SDimitry Andric       // Find the modules that match the basename or full path.
19840b57cec5SDimitry Andric       ModuleList module_list;
19850b57cec5SDimitry Andric       const char *arg_cstr;
19860b57cec5SDimitry Andric       for (int arg_idx = 0;
19870b57cec5SDimitry Andric            (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
19880b57cec5SDimitry Andric            ++arg_idx) {
19890b57cec5SDimitry Andric         size_t num_matched =
19900b57cec5SDimitry Andric             FindModulesByName(target, arg_cstr, module_list, true);
19910b57cec5SDimitry Andric         if (num_matched == 0) {
19920b57cec5SDimitry Andric           result.AppendWarningWithFormat(
19930b57cec5SDimitry Andric               "Unable to find an image that matches '%s'.\n", arg_cstr);
19940b57cec5SDimitry Andric         }
19950b57cec5SDimitry Andric       }
19960b57cec5SDimitry Andric       // Dump all the modules we found.
19970b57cec5SDimitry Andric       num_dumped =
19980b57cec5SDimitry Andric           DumpModuleObjfileHeaders(result.GetOutputStream(), module_list);
19990b57cec5SDimitry Andric     }
20000b57cec5SDimitry Andric 
20010b57cec5SDimitry Andric     if (num_dumped > 0) {
20020b57cec5SDimitry Andric       result.SetStatus(eReturnStatusSuccessFinishResult);
20030b57cec5SDimitry Andric     } else {
20040b57cec5SDimitry Andric       result.AppendError("no matching executable images found");
20050b57cec5SDimitry Andric     }
20060b57cec5SDimitry Andric   }
20070b57cec5SDimitry Andric };
20080b57cec5SDimitry Andric 
20090b57cec5SDimitry Andric #define LLDB_OPTIONS_target_modules_dump_symtab
20100b57cec5SDimitry Andric #include "CommandOptions.inc"
20110b57cec5SDimitry Andric 
20120b57cec5SDimitry Andric class CommandObjectTargetModulesDumpSymtab
20130b57cec5SDimitry Andric     : public CommandObjectTargetModulesModuleAutoComplete {
20140b57cec5SDimitry Andric public:
CommandObjectTargetModulesDumpSymtab(CommandInterpreter & interpreter)20150b57cec5SDimitry Andric   CommandObjectTargetModulesDumpSymtab(CommandInterpreter &interpreter)
20160b57cec5SDimitry Andric       : CommandObjectTargetModulesModuleAutoComplete(
20170b57cec5SDimitry Andric             interpreter, "target modules dump symtab",
20189dba64beSDimitry Andric             "Dump the symbol table from one or more target modules.", nullptr,
201904eeddc0SDimitry Andric             eCommandRequiresTarget) {}
20200b57cec5SDimitry Andric 
20210b57cec5SDimitry Andric   ~CommandObjectTargetModulesDumpSymtab() override = default;
20220b57cec5SDimitry Andric 
GetOptions()20230b57cec5SDimitry Andric   Options *GetOptions() override { return &m_options; }
20240b57cec5SDimitry Andric 
20250b57cec5SDimitry Andric   class CommandOptions : public Options {
20260b57cec5SDimitry Andric   public:
202781ad6265SDimitry Andric     CommandOptions() = default;
20280b57cec5SDimitry Andric 
20290b57cec5SDimitry Andric     ~CommandOptions() override = default;
20300b57cec5SDimitry Andric 
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)20310b57cec5SDimitry Andric     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
20320b57cec5SDimitry Andric                           ExecutionContext *execution_context) override {
20330b57cec5SDimitry Andric       Status error;
20340b57cec5SDimitry Andric       const int short_option = m_getopt_table[option_idx].val;
20350b57cec5SDimitry Andric 
20360b57cec5SDimitry Andric       switch (short_option) {
2037480093f4SDimitry Andric       case 'm':
2038480093f4SDimitry Andric         m_prefer_mangled.SetCurrentValue(true);
2039480093f4SDimitry Andric         m_prefer_mangled.SetOptionWasSet();
2040480093f4SDimitry Andric         break;
2041480093f4SDimitry Andric 
20420b57cec5SDimitry Andric       case 's':
20430b57cec5SDimitry Andric         m_sort_order = (SortOrder)OptionArgParser::ToOptionEnum(
20440b57cec5SDimitry Andric             option_arg, GetDefinitions()[option_idx].enum_values,
20450b57cec5SDimitry Andric             eSortOrderNone, error);
20460b57cec5SDimitry Andric         break;
20470b57cec5SDimitry Andric 
20480b57cec5SDimitry Andric       default:
20499dba64beSDimitry Andric         llvm_unreachable("Unimplemented option");
20500b57cec5SDimitry Andric       }
20510b57cec5SDimitry Andric       return error;
20520b57cec5SDimitry Andric     }
20530b57cec5SDimitry Andric 
OptionParsingStarting(ExecutionContext * execution_context)20540b57cec5SDimitry Andric     void OptionParsingStarting(ExecutionContext *execution_context) override {
20550b57cec5SDimitry Andric       m_sort_order = eSortOrderNone;
2056480093f4SDimitry Andric       m_prefer_mangled.Clear();
20570b57cec5SDimitry Andric     }
20580b57cec5SDimitry Andric 
GetDefinitions()20590b57cec5SDimitry Andric     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2060bdd1243dSDimitry Andric       return llvm::ArrayRef(g_target_modules_dump_symtab_options);
20610b57cec5SDimitry Andric     }
20620b57cec5SDimitry Andric 
2063fe6060f1SDimitry Andric     SortOrder m_sort_order = eSortOrderNone;
2064480093f4SDimitry Andric     OptionValueBoolean m_prefer_mangled = {false, false};
20650b57cec5SDimitry Andric   };
20660b57cec5SDimitry Andric 
20670b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)2068c9157d92SDimitry Andric   void DoExecute(Args &command, CommandReturnObject &result) override {
20699dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
20700b57cec5SDimitry Andric     uint32_t num_dumped = 0;
2071480093f4SDimitry Andric     Mangled::NamePreference name_preference =
2072480093f4SDimitry Andric         (m_options.m_prefer_mangled ? Mangled::ePreferMangled
2073480093f4SDimitry Andric                                     : Mangled::ePreferDemangled);
20740b57cec5SDimitry Andric 
20750b57cec5SDimitry Andric     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
20760b57cec5SDimitry Andric     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
20770b57cec5SDimitry Andric     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
20780b57cec5SDimitry Andric 
20790b57cec5SDimitry Andric     if (command.GetArgumentCount() == 0) {
20800b57cec5SDimitry Andric       // Dump all sections for all modules images
2081e8d8bef9SDimitry Andric       const ModuleList &module_list = target->GetImages();
2082e8d8bef9SDimitry Andric       std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
2083e8d8bef9SDimitry Andric       const size_t num_modules = module_list.GetSize();
20840b57cec5SDimitry Andric       if (num_modules > 0) {
2085e8d8bef9SDimitry Andric         result.GetOutputStream().Format(
2086e8d8bef9SDimitry Andric             "Dumping symbol table for {0} modules.\n", num_modules);
2087e8d8bef9SDimitry Andric         for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
20880b57cec5SDimitry Andric           if (num_dumped > 0) {
20890b57cec5SDimitry Andric             result.GetOutputStream().EOL();
20900b57cec5SDimitry Andric             result.GetOutputStream().EOL();
20910b57cec5SDimitry Andric           }
2092fe013be4SDimitry Andric           if (INTERRUPT_REQUESTED(GetDebugger(),
2093fe013be4SDimitry Andric                                   "Interrupted in dump all symtabs with {0} "
2094fe013be4SDimitry Andric                                   "of {1} dumped.", num_dumped, num_modules))
20950b57cec5SDimitry Andric             break;
2096fe013be4SDimitry Andric 
20970b57cec5SDimitry Andric           num_dumped++;
2098e8d8bef9SDimitry Andric           DumpModuleSymtab(m_interpreter, result.GetOutputStream(),
2099e8d8bef9SDimitry Andric                            module_sp.get(), m_options.m_sort_order,
2100e8d8bef9SDimitry Andric                            name_preference);
21010b57cec5SDimitry Andric         }
21020b57cec5SDimitry Andric       } else {
21030b57cec5SDimitry Andric         result.AppendError("the target has no associated executable images");
2104c9157d92SDimitry Andric         return;
21050b57cec5SDimitry Andric       }
21060b57cec5SDimitry Andric     } else {
21070b57cec5SDimitry Andric       // Dump specified images (by basename or fullpath)
21080b57cec5SDimitry Andric       const char *arg_cstr;
21090b57cec5SDimitry Andric       for (int arg_idx = 0;
21100b57cec5SDimitry Andric            (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
21110b57cec5SDimitry Andric            ++arg_idx) {
21120b57cec5SDimitry Andric         ModuleList module_list;
21130b57cec5SDimitry Andric         const size_t num_matches =
21140b57cec5SDimitry Andric             FindModulesByName(target, arg_cstr, module_list, true);
21150b57cec5SDimitry Andric         if (num_matches > 0) {
2116e8d8bef9SDimitry Andric           for (ModuleSP module_sp : module_list.Modules()) {
2117e8d8bef9SDimitry Andric             if (module_sp) {
21180b57cec5SDimitry Andric               if (num_dumped > 0) {
21190b57cec5SDimitry Andric                 result.GetOutputStream().EOL();
21200b57cec5SDimitry Andric                 result.GetOutputStream().EOL();
21210b57cec5SDimitry Andric               }
2122fe013be4SDimitry Andric               if (INTERRUPT_REQUESTED(GetDebugger(),
2123fe013be4SDimitry Andric                     "Interrupted in dump symtab list with {0} of {1} dumped.",
2124fe013be4SDimitry Andric                     num_dumped, num_matches))
21250b57cec5SDimitry Andric                 break;
2126fe013be4SDimitry Andric 
21270b57cec5SDimitry Andric               num_dumped++;
2128e8d8bef9SDimitry Andric               DumpModuleSymtab(m_interpreter, result.GetOutputStream(),
2129e8d8bef9SDimitry Andric                                module_sp.get(), m_options.m_sort_order,
2130e8d8bef9SDimitry Andric                                name_preference);
21310b57cec5SDimitry Andric             }
21320b57cec5SDimitry Andric           }
21330b57cec5SDimitry Andric         } else
21340b57cec5SDimitry Andric           result.AppendWarningWithFormat(
21350b57cec5SDimitry Andric               "Unable to find an image that matches '%s'.\n", arg_cstr);
21360b57cec5SDimitry Andric       }
21370b57cec5SDimitry Andric     }
21380b57cec5SDimitry Andric 
21390b57cec5SDimitry Andric     if (num_dumped > 0)
21400b57cec5SDimitry Andric       result.SetStatus(eReturnStatusSuccessFinishResult);
21410b57cec5SDimitry Andric     else {
21420b57cec5SDimitry Andric       result.AppendError("no matching executable images found");
21430b57cec5SDimitry Andric     }
21440b57cec5SDimitry Andric   }
21450b57cec5SDimitry Andric 
21460b57cec5SDimitry Andric   CommandOptions m_options;
21470b57cec5SDimitry Andric };
21480b57cec5SDimitry Andric 
21490b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesDumpSections
21500b57cec5SDimitry Andric 
21510b57cec5SDimitry Andric // Image section dumping command
21520b57cec5SDimitry Andric 
21530b57cec5SDimitry Andric class CommandObjectTargetModulesDumpSections
21540b57cec5SDimitry Andric     : public CommandObjectTargetModulesModuleAutoComplete {
21550b57cec5SDimitry Andric public:
CommandObjectTargetModulesDumpSections(CommandInterpreter & interpreter)21560b57cec5SDimitry Andric   CommandObjectTargetModulesDumpSections(CommandInterpreter &interpreter)
21570b57cec5SDimitry Andric       : CommandObjectTargetModulesModuleAutoComplete(
21580b57cec5SDimitry Andric             interpreter, "target modules dump sections",
21590b57cec5SDimitry Andric             "Dump the sections from one or more target modules.",
21600b57cec5SDimitry Andric             //"target modules dump sections [<file1> ...]")
21619dba64beSDimitry Andric             nullptr, eCommandRequiresTarget) {}
21620b57cec5SDimitry Andric 
21630b57cec5SDimitry Andric   ~CommandObjectTargetModulesDumpSections() override = default;
21640b57cec5SDimitry Andric 
21650b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)2166c9157d92SDimitry Andric   void DoExecute(Args &command, CommandReturnObject &result) override {
21679dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
21680b57cec5SDimitry Andric     uint32_t num_dumped = 0;
21690b57cec5SDimitry Andric 
21700b57cec5SDimitry Andric     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
21710b57cec5SDimitry Andric     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
21720b57cec5SDimitry Andric     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
21730b57cec5SDimitry Andric 
21740b57cec5SDimitry Andric     if (command.GetArgumentCount() == 0) {
21750b57cec5SDimitry Andric       // Dump all sections for all modules images
21760b57cec5SDimitry Andric       const size_t num_modules = target->GetImages().GetSize();
2177e8d8bef9SDimitry Andric       if (num_modules == 0) {
2178e8d8bef9SDimitry Andric         result.AppendError("the target has no associated executable images");
2179c9157d92SDimitry Andric         return;
2180e8d8bef9SDimitry Andric       }
2181e8d8bef9SDimitry Andric 
2182e8d8bef9SDimitry Andric       result.GetOutputStream().Format("Dumping sections for {0} modules.\n",
2183e8d8bef9SDimitry Andric                                       num_modules);
21840b57cec5SDimitry Andric       for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2185fe013be4SDimitry Andric         if (INTERRUPT_REQUESTED(GetDebugger(),
2186fe013be4SDimitry Andric               "Interrupted in dump all sections with {0} of {1} dumped",
2187fe013be4SDimitry Andric               image_idx, num_modules))
21880b57cec5SDimitry Andric           break;
2189fe013be4SDimitry Andric 
21900b57cec5SDimitry Andric         num_dumped++;
21910b57cec5SDimitry Andric         DumpModuleSections(
21920b57cec5SDimitry Andric             m_interpreter, result.GetOutputStream(),
21930b57cec5SDimitry Andric             target->GetImages().GetModulePointerAtIndex(image_idx));
21940b57cec5SDimitry Andric       }
21950b57cec5SDimitry Andric     } else {
21960b57cec5SDimitry Andric       // Dump specified images (by basename or fullpath)
21970b57cec5SDimitry Andric       const char *arg_cstr;
21980b57cec5SDimitry Andric       for (int arg_idx = 0;
21990b57cec5SDimitry Andric            (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
22000b57cec5SDimitry Andric            ++arg_idx) {
22010b57cec5SDimitry Andric         ModuleList module_list;
22020b57cec5SDimitry Andric         const size_t num_matches =
22030b57cec5SDimitry Andric             FindModulesByName(target, arg_cstr, module_list, true);
22040b57cec5SDimitry Andric         if (num_matches > 0) {
22050b57cec5SDimitry Andric           for (size_t i = 0; i < num_matches; ++i) {
2206fe013be4SDimitry Andric             if (INTERRUPT_REQUESTED(GetDebugger(),
2207fe013be4SDimitry Andric                   "Interrupted in dump section list with {0} of {1} dumped.",
2208fe013be4SDimitry Andric                   i, num_matches))
22090b57cec5SDimitry Andric               break;
2210fe013be4SDimitry Andric 
22110b57cec5SDimitry Andric             Module *module = module_list.GetModulePointerAtIndex(i);
22120b57cec5SDimitry Andric             if (module) {
22130b57cec5SDimitry Andric               num_dumped++;
22140b57cec5SDimitry Andric               DumpModuleSections(m_interpreter, result.GetOutputStream(),
22150b57cec5SDimitry Andric                                  module);
22160b57cec5SDimitry Andric             }
22170b57cec5SDimitry Andric           }
22180b57cec5SDimitry Andric         } else {
22190b57cec5SDimitry Andric           // Check the global list
22200b57cec5SDimitry Andric           std::lock_guard<std::recursive_mutex> guard(
22210b57cec5SDimitry Andric               Module::GetAllocationModuleCollectionMutex());
22220b57cec5SDimitry Andric 
22230b57cec5SDimitry Andric           result.AppendWarningWithFormat(
22240b57cec5SDimitry Andric               "Unable to find an image that matches '%s'.\n", arg_cstr);
22250b57cec5SDimitry Andric         }
22260b57cec5SDimitry Andric       }
22270b57cec5SDimitry Andric     }
22280b57cec5SDimitry Andric 
22290b57cec5SDimitry Andric     if (num_dumped > 0)
22300b57cec5SDimitry Andric       result.SetStatus(eReturnStatusSuccessFinishResult);
22310b57cec5SDimitry Andric     else {
22320b57cec5SDimitry Andric       result.AppendError("no matching executable images found");
22330b57cec5SDimitry Andric     }
22340b57cec5SDimitry Andric   }
22350b57cec5SDimitry Andric };
22360b57cec5SDimitry Andric 
2237753f127fSDimitry Andric class CommandObjectTargetModulesDumpClangPCMInfo : public CommandObjectParsed {
2238753f127fSDimitry Andric public:
CommandObjectTargetModulesDumpClangPCMInfo(CommandInterpreter & interpreter)2239753f127fSDimitry Andric   CommandObjectTargetModulesDumpClangPCMInfo(CommandInterpreter &interpreter)
2240753f127fSDimitry Andric       : CommandObjectParsed(
2241753f127fSDimitry Andric             interpreter, "target modules dump pcm-info",
2242753f127fSDimitry Andric             "Dump information about the given clang module (pcm).") {
2243753f127fSDimitry Andric     // Take a single file argument.
2244753f127fSDimitry Andric     CommandArgumentData arg{eArgTypeFilename, eArgRepeatPlain};
2245753f127fSDimitry Andric     m_arguments.push_back({arg});
2246753f127fSDimitry Andric   }
2247753f127fSDimitry Andric 
2248753f127fSDimitry Andric   ~CommandObjectTargetModulesDumpClangPCMInfo() override = default;
2249753f127fSDimitry Andric 
2250753f127fSDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)2251c9157d92SDimitry Andric   void DoExecute(Args &command, CommandReturnObject &result) override {
2252753f127fSDimitry Andric     if (command.GetArgumentCount() != 1) {
2253753f127fSDimitry Andric       result.AppendErrorWithFormat("'%s' takes exactly one pcm path argument.",
2254753f127fSDimitry Andric                                    m_cmd_name.c_str());
2255c9157d92SDimitry Andric       return;
2256753f127fSDimitry Andric     }
2257753f127fSDimitry Andric 
2258753f127fSDimitry Andric     const char *pcm_path = command.GetArgumentAtIndex(0);
2259fe013be4SDimitry Andric     const FileSpec pcm_file{pcm_path};
2260753f127fSDimitry Andric 
2261fe013be4SDimitry Andric     if (pcm_file.GetFileNameExtension() != ".pcm") {
2262753f127fSDimitry Andric       result.AppendError("file must have a .pcm extension");
2263c9157d92SDimitry Andric       return;
2264753f127fSDimitry Andric     }
2265753f127fSDimitry Andric 
2266753f127fSDimitry Andric     if (!FileSystem::Instance().Exists(pcm_file)) {
2267753f127fSDimitry Andric       result.AppendError("pcm file does not exist");
2268c9157d92SDimitry Andric       return;
2269753f127fSDimitry Andric     }
2270753f127fSDimitry Andric 
2271753f127fSDimitry Andric     clang::CompilerInstance compiler;
2272753f127fSDimitry Andric     compiler.createDiagnostics();
2273753f127fSDimitry Andric 
2274753f127fSDimitry Andric     const char *clang_args[] = {"clang", pcm_path};
2275753f127fSDimitry Andric     compiler.setInvocation(clang::createInvocation(clang_args));
2276753f127fSDimitry Andric 
2277fe013be4SDimitry Andric     // Pass empty deleter to not attempt to free memory that was allocated
2278fe013be4SDimitry Andric     // outside of the current scope, possibly statically.
2279fe013be4SDimitry Andric     std::shared_ptr<llvm::raw_ostream> Out(
2280fe013be4SDimitry Andric         &result.GetOutputStream().AsRawOstream(), [](llvm::raw_ostream *) {});
2281fe013be4SDimitry Andric     clang::DumpModuleInfoAction dump_module_info(Out);
2282753f127fSDimitry Andric     // DumpModuleInfoAction requires ObjectFilePCHContainerReader.
2283753f127fSDimitry Andric     compiler.getPCHContainerOperations()->registerReader(
2284753f127fSDimitry Andric         std::make_unique<clang::ObjectFilePCHContainerReader>());
2285753f127fSDimitry Andric 
2286753f127fSDimitry Andric     if (compiler.ExecuteAction(dump_module_info))
2287753f127fSDimitry Andric       result.SetStatus(eReturnStatusSuccessFinishResult);
2288753f127fSDimitry Andric   }
2289753f127fSDimitry Andric };
2290753f127fSDimitry Andric 
22915ffd83dbSDimitry Andric #pragma mark CommandObjectTargetModulesDumpClangAST
22920b57cec5SDimitry Andric 
22930b57cec5SDimitry Andric // Clang AST dumping command
22940b57cec5SDimitry Andric 
22950b57cec5SDimitry Andric class CommandObjectTargetModulesDumpClangAST
22960b57cec5SDimitry Andric     : public CommandObjectTargetModulesModuleAutoComplete {
22970b57cec5SDimitry Andric public:
CommandObjectTargetModulesDumpClangAST(CommandInterpreter & interpreter)22980b57cec5SDimitry Andric   CommandObjectTargetModulesDumpClangAST(CommandInterpreter &interpreter)
22990b57cec5SDimitry Andric       : CommandObjectTargetModulesModuleAutoComplete(
23000b57cec5SDimitry Andric             interpreter, "target modules dump ast",
23010b57cec5SDimitry Andric             "Dump the clang ast for a given module's symbol file.",
23020b57cec5SDimitry Andric             //"target modules dump ast [<file1> ...]")
23039dba64beSDimitry Andric             nullptr, eCommandRequiresTarget) {}
23040b57cec5SDimitry Andric 
23050b57cec5SDimitry Andric   ~CommandObjectTargetModulesDumpClangAST() override = default;
23060b57cec5SDimitry Andric 
23070b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)2308c9157d92SDimitry Andric   void DoExecute(Args &command, CommandReturnObject &result) override {
23099dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
23100b57cec5SDimitry Andric 
2311e8d8bef9SDimitry Andric     const ModuleList &module_list = target->GetImages();
2312e8d8bef9SDimitry Andric     const size_t num_modules = module_list.GetSize();
23130b57cec5SDimitry Andric     if (num_modules == 0) {
23140b57cec5SDimitry Andric       result.AppendError("the target has no associated executable images");
2315c9157d92SDimitry Andric       return;
23160b57cec5SDimitry Andric     }
23170b57cec5SDimitry Andric 
23180b57cec5SDimitry Andric     if (command.GetArgumentCount() == 0) {
23190b57cec5SDimitry Andric       // Dump all ASTs for all modules images
2320e8d8bef9SDimitry Andric       result.GetOutputStream().Format("Dumping clang ast for {0} modules.\n",
2321e8d8bef9SDimitry Andric                                       num_modules);
2322e8d8bef9SDimitry Andric       for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
2323fe013be4SDimitry Andric         if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted dumping clang ast"))
23240b57cec5SDimitry Andric           break;
2325e8d8bef9SDimitry Andric         if (SymbolFile *sf = module_sp->GetSymbolFile())
23260b57cec5SDimitry Andric           sf->DumpClangAST(result.GetOutputStream());
23270b57cec5SDimitry Andric       }
23280b57cec5SDimitry Andric       result.SetStatus(eReturnStatusSuccessFinishResult);
2329c9157d92SDimitry Andric       return;
23300b57cec5SDimitry Andric     }
23310b57cec5SDimitry Andric 
23320b57cec5SDimitry Andric     // Dump specified ASTs (by basename or fullpath)
23330b57cec5SDimitry Andric     for (const Args::ArgEntry &arg : command.entries()) {
23340b57cec5SDimitry Andric       ModuleList module_list;
23350b57cec5SDimitry Andric       const size_t num_matches =
23360b57cec5SDimitry Andric           FindModulesByName(target, arg.c_str(), module_list, true);
23370b57cec5SDimitry Andric       if (num_matches == 0) {
23380b57cec5SDimitry Andric         // Check the global list
23390b57cec5SDimitry Andric         std::lock_guard<std::recursive_mutex> guard(
23400b57cec5SDimitry Andric             Module::GetAllocationModuleCollectionMutex());
23410b57cec5SDimitry Andric 
23420b57cec5SDimitry Andric         result.AppendWarningWithFormat(
23430b57cec5SDimitry Andric             "Unable to find an image that matches '%s'.\n", arg.c_str());
23440b57cec5SDimitry Andric         continue;
23450b57cec5SDimitry Andric       }
23460b57cec5SDimitry Andric 
23470b57cec5SDimitry Andric       for (size_t i = 0; i < num_matches; ++i) {
2348fe013be4SDimitry Andric         if (INTERRUPT_REQUESTED(GetDebugger(),
2349fe013be4SDimitry Andric               "Interrupted in dump clang ast list with {0} of {1} dumped.",
2350fe013be4SDimitry Andric               i, num_matches))
23510b57cec5SDimitry Andric           break;
2352fe013be4SDimitry Andric 
23530b57cec5SDimitry Andric         Module *m = module_list.GetModulePointerAtIndex(i);
23549dba64beSDimitry Andric         if (SymbolFile *sf = m->GetSymbolFile())
23550b57cec5SDimitry Andric           sf->DumpClangAST(result.GetOutputStream());
23560b57cec5SDimitry Andric       }
23570b57cec5SDimitry Andric     }
23580b57cec5SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishResult);
23590b57cec5SDimitry Andric   }
23600b57cec5SDimitry Andric };
23610b57cec5SDimitry Andric 
23620b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesDumpSymfile
23630b57cec5SDimitry Andric 
23640b57cec5SDimitry Andric // Image debug symbol dumping command
23650b57cec5SDimitry Andric 
23660b57cec5SDimitry Andric class CommandObjectTargetModulesDumpSymfile
23670b57cec5SDimitry Andric     : public CommandObjectTargetModulesModuleAutoComplete {
23680b57cec5SDimitry Andric public:
CommandObjectTargetModulesDumpSymfile(CommandInterpreter & interpreter)23690b57cec5SDimitry Andric   CommandObjectTargetModulesDumpSymfile(CommandInterpreter &interpreter)
23700b57cec5SDimitry Andric       : CommandObjectTargetModulesModuleAutoComplete(
23710b57cec5SDimitry Andric             interpreter, "target modules dump symfile",
23720b57cec5SDimitry Andric             "Dump the debug symbol file for one or more target modules.",
23730b57cec5SDimitry Andric             //"target modules dump symfile [<file1> ...]")
23749dba64beSDimitry Andric             nullptr, eCommandRequiresTarget) {}
23750b57cec5SDimitry Andric 
23760b57cec5SDimitry Andric   ~CommandObjectTargetModulesDumpSymfile() override = default;
23770b57cec5SDimitry Andric 
23780b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)2379c9157d92SDimitry Andric   void DoExecute(Args &command, CommandReturnObject &result) override {
23809dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
23810b57cec5SDimitry Andric     uint32_t num_dumped = 0;
23820b57cec5SDimitry Andric 
23830b57cec5SDimitry Andric     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
23840b57cec5SDimitry Andric     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
23850b57cec5SDimitry Andric     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
23860b57cec5SDimitry Andric 
23870b57cec5SDimitry Andric     if (command.GetArgumentCount() == 0) {
23880b57cec5SDimitry Andric       // Dump all sections for all modules images
23890b57cec5SDimitry Andric       const ModuleList &target_modules = target->GetImages();
23900b57cec5SDimitry Andric       std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
23910b57cec5SDimitry Andric       const size_t num_modules = target_modules.GetSize();
2392e8d8bef9SDimitry Andric       if (num_modules == 0) {
23930b57cec5SDimitry Andric         result.AppendError("the target has no associated executable images");
2394c9157d92SDimitry Andric         return;
23950b57cec5SDimitry Andric       }
2396e8d8bef9SDimitry Andric       result.GetOutputStream().Format(
2397e8d8bef9SDimitry Andric           "Dumping debug symbols for {0} modules.\n", num_modules);
2398e8d8bef9SDimitry Andric       for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
2399fe013be4SDimitry Andric         if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted in dumping all "
2400fe013be4SDimitry Andric                                 "debug symbols with {0} of {1} modules dumped",
2401fe013be4SDimitry Andric                                  num_dumped, num_modules))
2402e8d8bef9SDimitry Andric           break;
2403fe013be4SDimitry Andric 
2404e8d8bef9SDimitry Andric         if (DumpModuleSymbolFile(result.GetOutputStream(), module_sp.get()))
2405e8d8bef9SDimitry Andric           num_dumped++;
2406e8d8bef9SDimitry Andric       }
24070b57cec5SDimitry Andric     } else {
24080b57cec5SDimitry Andric       // Dump specified images (by basename or fullpath)
24090b57cec5SDimitry Andric       const char *arg_cstr;
24100b57cec5SDimitry Andric       for (int arg_idx = 0;
24110b57cec5SDimitry Andric            (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
24120b57cec5SDimitry Andric            ++arg_idx) {
24130b57cec5SDimitry Andric         ModuleList module_list;
24140b57cec5SDimitry Andric         const size_t num_matches =
24150b57cec5SDimitry Andric             FindModulesByName(target, arg_cstr, module_list, true);
24160b57cec5SDimitry Andric         if (num_matches > 0) {
24170b57cec5SDimitry Andric           for (size_t i = 0; i < num_matches; ++i) {
2418fe013be4SDimitry Andric             if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted dumping {0} "
2419fe013be4SDimitry Andric                                                    "of {1} requested modules",
2420fe013be4SDimitry Andric                                                    i, num_matches))
24210b57cec5SDimitry Andric               break;
24220b57cec5SDimitry Andric             Module *module = module_list.GetModulePointerAtIndex(i);
24230b57cec5SDimitry Andric             if (module) {
24249dba64beSDimitry Andric               if (DumpModuleSymbolFile(result.GetOutputStream(), module))
24250b57cec5SDimitry Andric                 num_dumped++;
24260b57cec5SDimitry Andric             }
24270b57cec5SDimitry Andric           }
24280b57cec5SDimitry Andric         } else
24290b57cec5SDimitry Andric           result.AppendWarningWithFormat(
24300b57cec5SDimitry Andric               "Unable to find an image that matches '%s'.\n", arg_cstr);
24310b57cec5SDimitry Andric       }
24320b57cec5SDimitry Andric     }
24330b57cec5SDimitry Andric 
24340b57cec5SDimitry Andric     if (num_dumped > 0)
24350b57cec5SDimitry Andric       result.SetStatus(eReturnStatusSuccessFinishResult);
24360b57cec5SDimitry Andric     else {
24370b57cec5SDimitry Andric       result.AppendError("no matching executable images found");
24380b57cec5SDimitry Andric     }
24390b57cec5SDimitry Andric   }
24400b57cec5SDimitry Andric };
24410b57cec5SDimitry Andric 
24420b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesDumpLineTable
24439dba64beSDimitry Andric #define LLDB_OPTIONS_target_modules_dump
24449dba64beSDimitry Andric #include "CommandOptions.inc"
24450b57cec5SDimitry Andric 
24460b57cec5SDimitry Andric // Image debug line table dumping command
24470b57cec5SDimitry Andric 
24480b57cec5SDimitry Andric class CommandObjectTargetModulesDumpLineTable
24490b57cec5SDimitry Andric     : public CommandObjectTargetModulesSourceFileAutoComplete {
24500b57cec5SDimitry Andric public:
CommandObjectTargetModulesDumpLineTable(CommandInterpreter & interpreter)24510b57cec5SDimitry Andric   CommandObjectTargetModulesDumpLineTable(CommandInterpreter &interpreter)
24520b57cec5SDimitry Andric       : CommandObjectTargetModulesSourceFileAutoComplete(
24530b57cec5SDimitry Andric             interpreter, "target modules dump line-table",
24540b57cec5SDimitry Andric             "Dump the line table for one or more compilation units.", nullptr,
24550b57cec5SDimitry Andric             eCommandRequiresTarget) {}
24560b57cec5SDimitry Andric 
24570b57cec5SDimitry Andric   ~CommandObjectTargetModulesDumpLineTable() override = default;
24580b57cec5SDimitry Andric 
GetOptions()24590b57cec5SDimitry Andric   Options *GetOptions() override { return &m_options; }
24600b57cec5SDimitry Andric 
24610b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)2462c9157d92SDimitry Andric   void DoExecute(Args &command, CommandReturnObject &result) override {
24630b57cec5SDimitry Andric     Target *target = m_exe_ctx.GetTargetPtr();
24640b57cec5SDimitry Andric     uint32_t total_num_dumped = 0;
24650b57cec5SDimitry Andric 
24660b57cec5SDimitry Andric     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
24670b57cec5SDimitry Andric     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
24680b57cec5SDimitry Andric     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
24690b57cec5SDimitry Andric 
24700b57cec5SDimitry Andric     if (command.GetArgumentCount() == 0) {
24710b57cec5SDimitry Andric       result.AppendError("file option must be specified.");
2472c9157d92SDimitry Andric       return;
24730b57cec5SDimitry Andric     } else {
24740b57cec5SDimitry Andric       // Dump specified images (by basename or fullpath)
24750b57cec5SDimitry Andric       const char *arg_cstr;
24760b57cec5SDimitry Andric       for (int arg_idx = 0;
24770b57cec5SDimitry Andric            (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
24780b57cec5SDimitry Andric            ++arg_idx) {
24790b57cec5SDimitry Andric         FileSpec file_spec(arg_cstr);
24800b57cec5SDimitry Andric 
24810b57cec5SDimitry Andric         const ModuleList &target_modules = target->GetImages();
24820b57cec5SDimitry Andric         std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2483fe013be4SDimitry Andric         size_t num_modules = target_modules.GetSize();
2484fe013be4SDimitry Andric         if (num_modules > 0) {
24850b57cec5SDimitry Andric           uint32_t num_dumped = 0;
2486e8d8bef9SDimitry Andric           for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
2487fe013be4SDimitry Andric             if (INTERRUPT_REQUESTED(GetDebugger(),
2488fe013be4SDimitry Andric                                     "Interrupted in dump all line tables with "
2489fe013be4SDimitry Andric                                     "{0} of {1} dumped", num_dumped,
2490fe013be4SDimitry Andric                                     num_modules))
24910b57cec5SDimitry Andric               break;
2492fe013be4SDimitry Andric 
24930b57cec5SDimitry Andric             if (DumpCompileUnitLineTable(
2494e8d8bef9SDimitry Andric                     m_interpreter, result.GetOutputStream(), module_sp.get(),
24950b57cec5SDimitry Andric                     file_spec,
24960b57cec5SDimitry Andric                     m_options.m_verbose ? eDescriptionLevelFull
24970b57cec5SDimitry Andric                                         : eDescriptionLevelBrief))
24980b57cec5SDimitry Andric               num_dumped++;
24990b57cec5SDimitry Andric           }
25000b57cec5SDimitry Andric           if (num_dumped == 0)
25010b57cec5SDimitry Andric             result.AppendWarningWithFormat(
25020b57cec5SDimitry Andric                 "No source filenames matched '%s'.\n", arg_cstr);
25030b57cec5SDimitry Andric           else
25040b57cec5SDimitry Andric             total_num_dumped += num_dumped;
25050b57cec5SDimitry Andric         }
25060b57cec5SDimitry Andric       }
25070b57cec5SDimitry Andric     }
25080b57cec5SDimitry Andric 
25090b57cec5SDimitry Andric     if (total_num_dumped > 0)
25100b57cec5SDimitry Andric       result.SetStatus(eReturnStatusSuccessFinishResult);
25110b57cec5SDimitry Andric     else {
25120b57cec5SDimitry Andric       result.AppendError("no source filenames matched any command arguments");
25130b57cec5SDimitry Andric     }
25140b57cec5SDimitry Andric   }
25150b57cec5SDimitry Andric 
25160b57cec5SDimitry Andric   class CommandOptions : public Options {
25170b57cec5SDimitry Andric   public:
CommandOptions()251804eeddc0SDimitry Andric     CommandOptions() { OptionParsingStarting(nullptr); }
25190b57cec5SDimitry Andric 
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)25200b57cec5SDimitry Andric     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
25210b57cec5SDimitry Andric                           ExecutionContext *execution_context) override {
25220b57cec5SDimitry Andric       assert(option_idx == 0 && "We only have one option.");
25230b57cec5SDimitry Andric       m_verbose = true;
25240b57cec5SDimitry Andric 
25250b57cec5SDimitry Andric       return Status();
25260b57cec5SDimitry Andric     }
25270b57cec5SDimitry Andric 
OptionParsingStarting(ExecutionContext * execution_context)25280b57cec5SDimitry Andric     void OptionParsingStarting(ExecutionContext *execution_context) override {
25290b57cec5SDimitry Andric       m_verbose = false;
25300b57cec5SDimitry Andric     }
25310b57cec5SDimitry Andric 
GetDefinitions()25320b57cec5SDimitry Andric     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2533bdd1243dSDimitry Andric       return llvm::ArrayRef(g_target_modules_dump_options);
25340b57cec5SDimitry Andric     }
25350b57cec5SDimitry Andric 
25360b57cec5SDimitry Andric     bool m_verbose;
25370b57cec5SDimitry Andric   };
25380b57cec5SDimitry Andric 
25390b57cec5SDimitry Andric   CommandOptions m_options;
25400b57cec5SDimitry Andric };
25410b57cec5SDimitry Andric 
2542c9157d92SDimitry Andric #pragma mark CommandObjectTargetModulesDumpSeparateDebugInfoFiles
2543c9157d92SDimitry Andric #define LLDB_OPTIONS_target_modules_dump_separate_debug_info
2544c9157d92SDimitry Andric #include "CommandOptions.inc"
2545c9157d92SDimitry Andric 
2546c9157d92SDimitry Andric // Image debug separate debug info dumping command
2547c9157d92SDimitry Andric 
2548c9157d92SDimitry Andric class CommandObjectTargetModulesDumpSeparateDebugInfoFiles
2549c9157d92SDimitry Andric     : public CommandObjectTargetModulesModuleAutoComplete {
2550c9157d92SDimitry Andric public:
CommandObjectTargetModulesDumpSeparateDebugInfoFiles(CommandInterpreter & interpreter)2551c9157d92SDimitry Andric   CommandObjectTargetModulesDumpSeparateDebugInfoFiles(
2552c9157d92SDimitry Andric       CommandInterpreter &interpreter)
2553c9157d92SDimitry Andric       : CommandObjectTargetModulesModuleAutoComplete(
2554c9157d92SDimitry Andric             interpreter, "target modules dump separate-debug-info",
2555c9157d92SDimitry Andric             "List the separate debug info symbol files for one or more target "
2556c9157d92SDimitry Andric             "modules.",
2557c9157d92SDimitry Andric             nullptr, eCommandRequiresTarget) {}
2558c9157d92SDimitry Andric 
2559c9157d92SDimitry Andric   ~CommandObjectTargetModulesDumpSeparateDebugInfoFiles() override = default;
2560c9157d92SDimitry Andric 
GetOptions()2561c9157d92SDimitry Andric   Options *GetOptions() override { return &m_options; }
2562c9157d92SDimitry Andric 
2563c9157d92SDimitry Andric   class CommandOptions : public Options {
2564c9157d92SDimitry Andric   public:
2565c9157d92SDimitry Andric     CommandOptions() = default;
2566c9157d92SDimitry Andric 
2567c9157d92SDimitry Andric     ~CommandOptions() override = default;
2568c9157d92SDimitry Andric 
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)2569c9157d92SDimitry Andric     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2570c9157d92SDimitry Andric                           ExecutionContext *execution_context) override {
2571c9157d92SDimitry Andric       Status error;
2572c9157d92SDimitry Andric       const int short_option = m_getopt_table[option_idx].val;
2573c9157d92SDimitry Andric 
2574c9157d92SDimitry Andric       switch (short_option) {
2575c9157d92SDimitry Andric       case 'j':
2576c9157d92SDimitry Andric         m_json.SetCurrentValue(true);
2577c9157d92SDimitry Andric         m_json.SetOptionWasSet();
2578c9157d92SDimitry Andric         break;
2579c9157d92SDimitry Andric       case 'e':
2580c9157d92SDimitry Andric         m_errors_only.SetCurrentValue(true);
2581c9157d92SDimitry Andric         m_errors_only.SetOptionWasSet();
2582c9157d92SDimitry Andric         break;
2583c9157d92SDimitry Andric       default:
2584c9157d92SDimitry Andric         llvm_unreachable("Unimplemented option");
2585c9157d92SDimitry Andric       }
2586c9157d92SDimitry Andric       return error;
2587c9157d92SDimitry Andric     }
2588c9157d92SDimitry Andric 
OptionParsingStarting(ExecutionContext * execution_context)2589c9157d92SDimitry Andric     void OptionParsingStarting(ExecutionContext *execution_context) override {
2590c9157d92SDimitry Andric       m_json.Clear();
2591c9157d92SDimitry Andric       m_errors_only.Clear();
2592c9157d92SDimitry Andric     }
2593c9157d92SDimitry Andric 
GetDefinitions()2594c9157d92SDimitry Andric     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2595c9157d92SDimitry Andric       return llvm::ArrayRef(g_target_modules_dump_separate_debug_info_options);
2596c9157d92SDimitry Andric     }
2597c9157d92SDimitry Andric 
2598c9157d92SDimitry Andric     OptionValueBoolean m_json = false;
2599c9157d92SDimitry Andric     OptionValueBoolean m_errors_only = false;
2600c9157d92SDimitry Andric   };
2601c9157d92SDimitry Andric 
2602c9157d92SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)2603c9157d92SDimitry Andric   void DoExecute(Args &command, CommandReturnObject &result) override {
2604c9157d92SDimitry Andric     Target &target = GetSelectedTarget();
2605c9157d92SDimitry Andric     uint32_t num_dumped = 0;
2606c9157d92SDimitry Andric 
2607c9157d92SDimitry Andric     uint32_t addr_byte_size = target.GetArchitecture().GetAddressByteSize();
2608c9157d92SDimitry Andric     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2609c9157d92SDimitry Andric     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2610c9157d92SDimitry Andric 
2611c9157d92SDimitry Andric     StructuredData::Array separate_debug_info_lists_by_module;
2612c9157d92SDimitry Andric     if (command.GetArgumentCount() == 0) {
2613c9157d92SDimitry Andric       // Dump all sections for all modules images
2614c9157d92SDimitry Andric       const ModuleList &target_modules = target.GetImages();
2615c9157d92SDimitry Andric       std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2616c9157d92SDimitry Andric       const size_t num_modules = target_modules.GetSize();
2617c9157d92SDimitry Andric       if (num_modules == 0) {
2618c9157d92SDimitry Andric         result.AppendError("the target has no associated executable images");
2619c9157d92SDimitry Andric         return;
2620c9157d92SDimitry Andric       }
2621c9157d92SDimitry Andric       for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
2622c9157d92SDimitry Andric         if (INTERRUPT_REQUESTED(
2623c9157d92SDimitry Andric                 GetDebugger(),
2624c9157d92SDimitry Andric                 "Interrupted in dumping all "
2625c9157d92SDimitry Andric                 "separate debug info with {0} of {1} modules dumped",
2626c9157d92SDimitry Andric                 num_dumped, num_modules))
2627c9157d92SDimitry Andric           break;
2628c9157d92SDimitry Andric 
2629c9157d92SDimitry Andric         if (GetSeparateDebugInfoList(separate_debug_info_lists_by_module,
2630c9157d92SDimitry Andric                                      module_sp.get(),
2631c9157d92SDimitry Andric                                      bool(m_options.m_errors_only)))
2632c9157d92SDimitry Andric           num_dumped++;
2633c9157d92SDimitry Andric       }
2634c9157d92SDimitry Andric     } else {
2635c9157d92SDimitry Andric       // Dump specified images (by basename or fullpath)
2636c9157d92SDimitry Andric       const char *arg_cstr;
2637c9157d92SDimitry Andric       for (int arg_idx = 0;
2638c9157d92SDimitry Andric            (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2639c9157d92SDimitry Andric            ++arg_idx) {
2640c9157d92SDimitry Andric         ModuleList module_list;
2641c9157d92SDimitry Andric         const size_t num_matches =
2642c9157d92SDimitry Andric             FindModulesByName(&target, arg_cstr, module_list, true);
2643c9157d92SDimitry Andric         if (num_matches > 0) {
2644c9157d92SDimitry Andric           for (size_t i = 0; i < num_matches; ++i) {
2645c9157d92SDimitry Andric             if (INTERRUPT_REQUESTED(GetDebugger(),
2646c9157d92SDimitry Andric                                     "Interrupted dumping {0} "
2647c9157d92SDimitry Andric                                     "of {1} requested modules",
2648c9157d92SDimitry Andric                                     i, num_matches))
2649c9157d92SDimitry Andric               break;
2650c9157d92SDimitry Andric             Module *module = module_list.GetModulePointerAtIndex(i);
2651c9157d92SDimitry Andric             if (GetSeparateDebugInfoList(separate_debug_info_lists_by_module,
2652c9157d92SDimitry Andric                                          module, bool(m_options.m_errors_only)))
2653c9157d92SDimitry Andric               num_dumped++;
2654c9157d92SDimitry Andric           }
2655c9157d92SDimitry Andric         } else
2656c9157d92SDimitry Andric           result.AppendWarningWithFormat(
2657c9157d92SDimitry Andric               "Unable to find an image that matches '%s'.\n", arg_cstr);
2658c9157d92SDimitry Andric       }
2659c9157d92SDimitry Andric     }
2660c9157d92SDimitry Andric 
2661c9157d92SDimitry Andric     if (num_dumped > 0) {
2662c9157d92SDimitry Andric       Stream &strm = result.GetOutputStream();
2663c9157d92SDimitry Andric       // Display the debug info files in some format.
2664c9157d92SDimitry Andric       if (m_options.m_json) {
2665c9157d92SDimitry Andric         // JSON format
2666c9157d92SDimitry Andric         separate_debug_info_lists_by_module.Dump(strm,
2667c9157d92SDimitry Andric                                                  /*pretty_print=*/true);
2668c9157d92SDimitry Andric       } else {
2669c9157d92SDimitry Andric         // Human-readable table format
2670c9157d92SDimitry Andric         separate_debug_info_lists_by_module.ForEach(
2671c9157d92SDimitry Andric             [&result, &strm](StructuredData::Object *obj) {
2672c9157d92SDimitry Andric               if (!obj) {
2673c9157d92SDimitry Andric                 return false;
2674c9157d92SDimitry Andric               }
2675c9157d92SDimitry Andric 
2676c9157d92SDimitry Andric               // Each item in `separate_debug_info_lists_by_module` should be a
2677c9157d92SDimitry Andric               // valid structured data dictionary.
2678c9157d92SDimitry Andric               StructuredData::Dictionary *separate_debug_info_list =
2679c9157d92SDimitry Andric                   obj->GetAsDictionary();
2680c9157d92SDimitry Andric               if (!separate_debug_info_list) {
2681c9157d92SDimitry Andric                 return false;
2682c9157d92SDimitry Andric               }
2683c9157d92SDimitry Andric 
2684c9157d92SDimitry Andric               llvm::StringRef type;
2685c9157d92SDimitry Andric               llvm::StringRef symfile;
2686c9157d92SDimitry Andric               StructuredData::Array *files;
2687c9157d92SDimitry Andric               if (!(separate_debug_info_list->GetValueForKeyAsString("type",
2688c9157d92SDimitry Andric                                                                      type) &&
2689c9157d92SDimitry Andric                     separate_debug_info_list->GetValueForKeyAsString("symfile",
2690c9157d92SDimitry Andric                                                                      symfile) &&
2691c9157d92SDimitry Andric                     separate_debug_info_list->GetValueForKeyAsArray(
2692c9157d92SDimitry Andric                         "separate-debug-info-files", files))) {
2693c9157d92SDimitry Andric                 assert(false);
2694c9157d92SDimitry Andric               }
2695c9157d92SDimitry Andric 
2696c9157d92SDimitry Andric               strm << "Symbol file: " << symfile;
2697c9157d92SDimitry Andric               strm.EOL();
2698c9157d92SDimitry Andric               strm << "Type: \"" << type << "\"";
2699c9157d92SDimitry Andric               strm.EOL();
2700c9157d92SDimitry Andric               if (type == "dwo") {
2701c9157d92SDimitry Andric                 DumpDwoFilesTable(strm, *files);
2702c9157d92SDimitry Andric               } else if (type == "oso") {
2703c9157d92SDimitry Andric                 DumpOsoFilesTable(strm, *files);
2704c9157d92SDimitry Andric               } else {
2705c9157d92SDimitry Andric                 result.AppendWarningWithFormat(
2706c9157d92SDimitry Andric                     "Found unsupported debug info type '%s'.\n",
2707c9157d92SDimitry Andric                     type.str().c_str());
2708c9157d92SDimitry Andric               }
2709c9157d92SDimitry Andric               return true;
2710c9157d92SDimitry Andric             });
2711c9157d92SDimitry Andric       }
2712c9157d92SDimitry Andric       result.SetStatus(eReturnStatusSuccessFinishResult);
2713c9157d92SDimitry Andric     } else {
2714c9157d92SDimitry Andric       result.AppendError("no matching executable images found");
2715c9157d92SDimitry Andric     }
2716c9157d92SDimitry Andric   }
2717c9157d92SDimitry Andric 
2718c9157d92SDimitry Andric   CommandOptions m_options;
2719c9157d92SDimitry Andric };
2720c9157d92SDimitry Andric 
27210b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesDump
27220b57cec5SDimitry Andric 
27230b57cec5SDimitry Andric // Dump multi-word command for target modules
27240b57cec5SDimitry Andric 
27250b57cec5SDimitry Andric class CommandObjectTargetModulesDump : public CommandObjectMultiword {
27260b57cec5SDimitry Andric public:
27270b57cec5SDimitry Andric   // Constructors and Destructors
CommandObjectTargetModulesDump(CommandInterpreter & interpreter)27280b57cec5SDimitry Andric   CommandObjectTargetModulesDump(CommandInterpreter &interpreter)
27290b57cec5SDimitry Andric       : CommandObjectMultiword(
27300b57cec5SDimitry Andric             interpreter, "target modules dump",
2731753f127fSDimitry Andric             "Commands for dumping information about one or more target "
2732753f127fSDimitry Andric             "modules.",
27330b57cec5SDimitry Andric             "target modules dump "
2734c9157d92SDimitry Andric             "[objfile|symtab|sections|ast|symfile|line-table|pcm-info|separate-"
2735c9157d92SDimitry Andric             "debug-info] "
27360b57cec5SDimitry Andric             "[<file1> <file2> ...]") {
27370b57cec5SDimitry Andric     LoadSubCommand("objfile",
27380b57cec5SDimitry Andric                    CommandObjectSP(
27390b57cec5SDimitry Andric                        new CommandObjectTargetModulesDumpObjfile(interpreter)));
27400b57cec5SDimitry Andric     LoadSubCommand(
27410b57cec5SDimitry Andric         "symtab",
27420b57cec5SDimitry Andric         CommandObjectSP(new CommandObjectTargetModulesDumpSymtab(interpreter)));
27430b57cec5SDimitry Andric     LoadSubCommand("sections",
27440b57cec5SDimitry Andric                    CommandObjectSP(new CommandObjectTargetModulesDumpSections(
27450b57cec5SDimitry Andric                        interpreter)));
27460b57cec5SDimitry Andric     LoadSubCommand("symfile",
27470b57cec5SDimitry Andric                    CommandObjectSP(
27480b57cec5SDimitry Andric                        new CommandObjectTargetModulesDumpSymfile(interpreter)));
27490b57cec5SDimitry Andric     LoadSubCommand(
27500b57cec5SDimitry Andric         "ast", CommandObjectSP(
27510b57cec5SDimitry Andric                    new CommandObjectTargetModulesDumpClangAST(interpreter)));
27520b57cec5SDimitry Andric     LoadSubCommand("line-table",
27530b57cec5SDimitry Andric                    CommandObjectSP(new CommandObjectTargetModulesDumpLineTable(
27540b57cec5SDimitry Andric                        interpreter)));
2755753f127fSDimitry Andric     LoadSubCommand(
2756753f127fSDimitry Andric         "pcm-info",
2757753f127fSDimitry Andric         CommandObjectSP(
2758753f127fSDimitry Andric             new CommandObjectTargetModulesDumpClangPCMInfo(interpreter)));
2759c9157d92SDimitry Andric     LoadSubCommand("separate-debug-info",
2760c9157d92SDimitry Andric                    CommandObjectSP(
2761c9157d92SDimitry Andric                        new CommandObjectTargetModulesDumpSeparateDebugInfoFiles(
2762c9157d92SDimitry Andric                            interpreter)));
27630b57cec5SDimitry Andric   }
27640b57cec5SDimitry Andric 
27650b57cec5SDimitry Andric   ~CommandObjectTargetModulesDump() override = default;
27660b57cec5SDimitry Andric };
27670b57cec5SDimitry Andric 
27680b57cec5SDimitry Andric class CommandObjectTargetModulesAdd : public CommandObjectParsed {
27690b57cec5SDimitry Andric public:
CommandObjectTargetModulesAdd(CommandInterpreter & interpreter)27700b57cec5SDimitry Andric   CommandObjectTargetModulesAdd(CommandInterpreter &interpreter)
27710b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "target modules add",
27720b57cec5SDimitry Andric                             "Add a new module to the current target's modules.",
27739dba64beSDimitry Andric                             "target modules add [<module>]",
27749dba64beSDimitry Andric                             eCommandRequiresTarget),
277504eeddc0SDimitry Andric         m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
277604eeddc0SDimitry Andric                       eArgTypeFilename,
27779dba64beSDimitry Andric                       "Fullpath to a stand alone debug "
27780b57cec5SDimitry Andric                       "symbols file for when debug symbols "
27790b57cec5SDimitry Andric                       "are not in the executable.") {
27800b57cec5SDimitry Andric     m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
27810b57cec5SDimitry Andric                           LLDB_OPT_SET_1);
27820b57cec5SDimitry Andric     m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
27830b57cec5SDimitry Andric     m_option_group.Finalize();
278481ad6265SDimitry Andric     CommandArgumentData module_arg{eArgTypePath, eArgRepeatStar};
278581ad6265SDimitry Andric     m_arguments.push_back({module_arg});
27860b57cec5SDimitry Andric   }
27870b57cec5SDimitry Andric 
27880b57cec5SDimitry Andric   ~CommandObjectTargetModulesAdd() override = default;
27890b57cec5SDimitry Andric 
GetOptions()27900b57cec5SDimitry Andric   Options *GetOptions() override { return &m_option_group; }
27910b57cec5SDimitry Andric 
27929dba64beSDimitry Andric   void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)27939dba64beSDimitry Andric   HandleArgumentCompletion(CompletionRequest &request,
27940b57cec5SDimitry Andric                            OptionElementVector &opt_element_vector) override {
2795fe013be4SDimitry Andric     lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
2796fe013be4SDimitry Andric         GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr);
27970b57cec5SDimitry Andric   }
27980b57cec5SDimitry Andric 
27990b57cec5SDimitry Andric protected:
28000b57cec5SDimitry Andric   OptionGroupOptions m_option_group;
28010b57cec5SDimitry Andric   OptionGroupUUID m_uuid_option_group;
28020b57cec5SDimitry Andric   OptionGroupFile m_symbol_file;
28030b57cec5SDimitry Andric 
DoExecute(Args & args,CommandReturnObject & result)2804c9157d92SDimitry Andric   void DoExecute(Args &args, CommandReturnObject &result) override {
28059dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
28060b57cec5SDimitry Andric     bool flush = false;
28070b57cec5SDimitry Andric 
28080b57cec5SDimitry Andric     const size_t argc = args.GetArgumentCount();
28090b57cec5SDimitry Andric     if (argc == 0) {
28100b57cec5SDimitry Andric       if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
28110b57cec5SDimitry Andric         // We are given a UUID only, go locate the file
28120b57cec5SDimitry Andric         ModuleSpec module_spec;
28130b57cec5SDimitry Andric         module_spec.GetUUID() =
28140b57cec5SDimitry Andric             m_uuid_option_group.GetOptionValue().GetCurrentValue();
28150b57cec5SDimitry Andric         if (m_symbol_file.GetOptionValue().OptionWasSet())
28160b57cec5SDimitry Andric           module_spec.GetSymbolFileSpec() =
28170b57cec5SDimitry Andric               m_symbol_file.GetOptionValue().GetCurrentValue();
281881ad6265SDimitry Andric         Status error;
2819c9157d92SDimitry Andric         if (PluginManager::DownloadObjectAndSymbolFile(module_spec, error)) {
28209dba64beSDimitry Andric           ModuleSP module_sp(
28219dba64beSDimitry Andric               target->GetOrCreateModule(module_spec, true /* notify */));
28220b57cec5SDimitry Andric           if (module_sp) {
28230b57cec5SDimitry Andric             result.SetStatus(eReturnStatusSuccessFinishResult);
2824c9157d92SDimitry Andric             return;
28250b57cec5SDimitry Andric           } else {
28260b57cec5SDimitry Andric             StreamString strm;
2827fe013be4SDimitry Andric             module_spec.GetUUID().Dump(strm);
28280b57cec5SDimitry Andric             if (module_spec.GetFileSpec()) {
28290b57cec5SDimitry Andric               if (module_spec.GetSymbolFileSpec()) {
28300b57cec5SDimitry Andric                 result.AppendErrorWithFormat(
28310b57cec5SDimitry Andric                     "Unable to create the executable or symbol file with "
28320b57cec5SDimitry Andric                     "UUID %s with path %s and symbol file %s",
28339dba64beSDimitry Andric                     strm.GetData(), module_spec.GetFileSpec().GetPath().c_str(),
28340b57cec5SDimitry Andric                     module_spec.GetSymbolFileSpec().GetPath().c_str());
28350b57cec5SDimitry Andric               } else {
28360b57cec5SDimitry Andric                 result.AppendErrorWithFormat(
28370b57cec5SDimitry Andric                     "Unable to create the executable or symbol file with "
28380b57cec5SDimitry Andric                     "UUID %s with path %s",
28390b57cec5SDimitry Andric                     strm.GetData(),
28400b57cec5SDimitry Andric                     module_spec.GetFileSpec().GetPath().c_str());
28410b57cec5SDimitry Andric               }
28420b57cec5SDimitry Andric             } else {
28430b57cec5SDimitry Andric               result.AppendErrorWithFormat("Unable to create the executable "
28440b57cec5SDimitry Andric                                            "or symbol file with UUID %s",
28450b57cec5SDimitry Andric                                            strm.GetData());
28460b57cec5SDimitry Andric             }
2847c9157d92SDimitry Andric             return;
28480b57cec5SDimitry Andric           }
28490b57cec5SDimitry Andric         } else {
28500b57cec5SDimitry Andric           StreamString strm;
2851fe013be4SDimitry Andric           module_spec.GetUUID().Dump(strm);
28520b57cec5SDimitry Andric           result.AppendErrorWithFormat(
28530b57cec5SDimitry Andric               "Unable to locate the executable or symbol file with UUID %s",
28540b57cec5SDimitry Andric               strm.GetData());
285581ad6265SDimitry Andric           result.SetError(error);
2856c9157d92SDimitry Andric           return;
28570b57cec5SDimitry Andric         }
28580b57cec5SDimitry Andric       } else {
28590b57cec5SDimitry Andric         result.AppendError(
28600b57cec5SDimitry Andric             "one or more executable image paths must be specified");
2861c9157d92SDimitry Andric         return;
28620b57cec5SDimitry Andric       }
28630b57cec5SDimitry Andric     } else {
28640b57cec5SDimitry Andric       for (auto &entry : args.entries()) {
28659dba64beSDimitry Andric         if (entry.ref().empty())
28660b57cec5SDimitry Andric           continue;
28670b57cec5SDimitry Andric 
28689dba64beSDimitry Andric         FileSpec file_spec(entry.ref());
28690b57cec5SDimitry Andric         if (FileSystem::Instance().Exists(file_spec)) {
28700b57cec5SDimitry Andric           ModuleSpec module_spec(file_spec);
28710b57cec5SDimitry Andric           if (m_uuid_option_group.GetOptionValue().OptionWasSet())
28720b57cec5SDimitry Andric             module_spec.GetUUID() =
28730b57cec5SDimitry Andric                 m_uuid_option_group.GetOptionValue().GetCurrentValue();
28740b57cec5SDimitry Andric           if (m_symbol_file.GetOptionValue().OptionWasSet())
28750b57cec5SDimitry Andric             module_spec.GetSymbolFileSpec() =
28760b57cec5SDimitry Andric                 m_symbol_file.GetOptionValue().GetCurrentValue();
28770b57cec5SDimitry Andric           if (!module_spec.GetArchitecture().IsValid())
28780b57cec5SDimitry Andric             module_spec.GetArchitecture() = target->GetArchitecture();
28790b57cec5SDimitry Andric           Status error;
28809dba64beSDimitry Andric           ModuleSP module_sp(target->GetOrCreateModule(
28819dba64beSDimitry Andric               module_spec, true /* notify */, &error));
28820b57cec5SDimitry Andric           if (!module_sp) {
28830b57cec5SDimitry Andric             const char *error_cstr = error.AsCString();
28840b57cec5SDimitry Andric             if (error_cstr)
28850b57cec5SDimitry Andric               result.AppendError(error_cstr);
28860b57cec5SDimitry Andric             else
28870b57cec5SDimitry Andric               result.AppendErrorWithFormat("unsupported module: %s",
28880b57cec5SDimitry Andric                                            entry.c_str());
2889c9157d92SDimitry Andric             return;
28900b57cec5SDimitry Andric           } else {
28910b57cec5SDimitry Andric             flush = true;
28920b57cec5SDimitry Andric           }
28930b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishResult);
28940b57cec5SDimitry Andric         } else {
28950b57cec5SDimitry Andric           std::string resolved_path = file_spec.GetPath();
28969dba64beSDimitry Andric           if (resolved_path != entry.ref()) {
28970b57cec5SDimitry Andric             result.AppendErrorWithFormat(
28980b57cec5SDimitry Andric                 "invalid module path '%s' with resolved path '%s'\n",
28999dba64beSDimitry Andric                 entry.ref().str().c_str(), resolved_path.c_str());
29000b57cec5SDimitry Andric             break;
29010b57cec5SDimitry Andric           }
29020b57cec5SDimitry Andric           result.AppendErrorWithFormat("invalid module path '%s'\n",
29030b57cec5SDimitry Andric                                        entry.c_str());
29040b57cec5SDimitry Andric           break;
29050b57cec5SDimitry Andric         }
29060b57cec5SDimitry Andric       }
29070b57cec5SDimitry Andric     }
29080b57cec5SDimitry Andric 
29090b57cec5SDimitry Andric     if (flush) {
29100b57cec5SDimitry Andric       ProcessSP process = target->GetProcessSP();
29110b57cec5SDimitry Andric       if (process)
29120b57cec5SDimitry Andric         process->Flush();
29130b57cec5SDimitry Andric     }
29140b57cec5SDimitry Andric   }
29150b57cec5SDimitry Andric };
29160b57cec5SDimitry Andric 
29170b57cec5SDimitry Andric class CommandObjectTargetModulesLoad
29180b57cec5SDimitry Andric     : public CommandObjectTargetModulesModuleAutoComplete {
29190b57cec5SDimitry Andric public:
CommandObjectTargetModulesLoad(CommandInterpreter & interpreter)29200b57cec5SDimitry Andric   CommandObjectTargetModulesLoad(CommandInterpreter &interpreter)
29210b57cec5SDimitry Andric       : CommandObjectTargetModulesModuleAutoComplete(
29229dba64beSDimitry Andric             interpreter, "target modules load",
29239dba64beSDimitry Andric             "Set the load addresses for one or more sections in a target "
29249dba64beSDimitry Andric             "module.",
29250b57cec5SDimitry Andric             "target modules load [--file <module> --uuid <uuid>] <sect-name> "
29269dba64beSDimitry Andric             "<address> [<sect-name> <address> ....]",
29279dba64beSDimitry Andric             eCommandRequiresTarget),
29280b57cec5SDimitry Andric         m_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName,
29290b57cec5SDimitry Andric                       "Fullpath or basename for module to load.", ""),
29300b57cec5SDimitry Andric         m_load_option(LLDB_OPT_SET_1, false, "load", 'l',
29310b57cec5SDimitry Andric                       "Write file contents to the memory.", false, true),
29320b57cec5SDimitry Andric         m_pc_option(LLDB_OPT_SET_1, false, "set-pc-to-entry", 'p',
29330b57cec5SDimitry Andric                     "Set PC to the entry point."
29340b57cec5SDimitry Andric                     " Only applicable with '--load' option.",
29350b57cec5SDimitry Andric                     false, true),
29360b57cec5SDimitry Andric         m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset,
29370b57cec5SDimitry Andric                        "Set the load address for all sections to be the "
29380b57cec5SDimitry Andric                        "virtual address in the file plus the offset.",
29390b57cec5SDimitry Andric                        0) {
29400b57cec5SDimitry Andric     m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
29410b57cec5SDimitry Andric                           LLDB_OPT_SET_1);
29420b57cec5SDimitry Andric     m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
29430b57cec5SDimitry Andric     m_option_group.Append(&m_load_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
29440b57cec5SDimitry Andric     m_option_group.Append(&m_pc_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
29450b57cec5SDimitry Andric     m_option_group.Append(&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
29460b57cec5SDimitry Andric     m_option_group.Finalize();
29470b57cec5SDimitry Andric   }
29480b57cec5SDimitry Andric 
29490b57cec5SDimitry Andric   ~CommandObjectTargetModulesLoad() override = default;
29500b57cec5SDimitry Andric 
GetOptions()29510b57cec5SDimitry Andric   Options *GetOptions() override { return &m_option_group; }
29520b57cec5SDimitry Andric 
29530b57cec5SDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)2954c9157d92SDimitry Andric   void DoExecute(Args &args, CommandReturnObject &result) override {
29559dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
29560b57cec5SDimitry Andric     const bool load = m_load_option.GetOptionValue().GetCurrentValue();
29570b57cec5SDimitry Andric     const bool set_pc = m_pc_option.GetOptionValue().GetCurrentValue();
29589dba64beSDimitry Andric 
29590b57cec5SDimitry Andric     const size_t argc = args.GetArgumentCount();
29600b57cec5SDimitry Andric     ModuleSpec module_spec;
29610b57cec5SDimitry Andric     bool search_using_module_spec = false;
29620b57cec5SDimitry Andric 
29630b57cec5SDimitry Andric     // Allow "load" option to work without --file or --uuid option.
29640b57cec5SDimitry Andric     if (load) {
29650b57cec5SDimitry Andric       if (!m_file_option.GetOptionValue().OptionWasSet() &&
29660b57cec5SDimitry Andric           !m_uuid_option_group.GetOptionValue().OptionWasSet()) {
29670b57cec5SDimitry Andric         ModuleList &module_list = target->GetImages();
29680b57cec5SDimitry Andric         if (module_list.GetSize() == 1) {
29690b57cec5SDimitry Andric           search_using_module_spec = true;
29700b57cec5SDimitry Andric           module_spec.GetFileSpec() =
29710b57cec5SDimitry Andric               module_list.GetModuleAtIndex(0)->GetFileSpec();
29720b57cec5SDimitry Andric         }
29730b57cec5SDimitry Andric       }
29740b57cec5SDimitry Andric     }
29750b57cec5SDimitry Andric 
29760b57cec5SDimitry Andric     if (m_file_option.GetOptionValue().OptionWasSet()) {
29770b57cec5SDimitry Andric       search_using_module_spec = true;
29780b57cec5SDimitry Andric       const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
29790b57cec5SDimitry Andric       const bool use_global_module_list = true;
29800b57cec5SDimitry Andric       ModuleList module_list;
29810b57cec5SDimitry Andric       const size_t num_matches = FindModulesByName(
29820b57cec5SDimitry Andric           target, arg_cstr, module_list, use_global_module_list);
29830b57cec5SDimitry Andric       if (num_matches == 1) {
29840b57cec5SDimitry Andric         module_spec.GetFileSpec() =
29850b57cec5SDimitry Andric             module_list.GetModuleAtIndex(0)->GetFileSpec();
29860b57cec5SDimitry Andric       } else if (num_matches > 1) {
29870b57cec5SDimitry Andric         search_using_module_spec = false;
29880b57cec5SDimitry Andric         result.AppendErrorWithFormat(
29890b57cec5SDimitry Andric             "more than 1 module matched by name '%s'\n", arg_cstr);
29900b57cec5SDimitry Andric       } else {
29910b57cec5SDimitry Andric         search_using_module_spec = false;
29920b57cec5SDimitry Andric         result.AppendErrorWithFormat("no object file for module '%s'\n",
29930b57cec5SDimitry Andric                                      arg_cstr);
29940b57cec5SDimitry Andric       }
29950b57cec5SDimitry Andric     }
29960b57cec5SDimitry Andric 
29970b57cec5SDimitry Andric     if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
29980b57cec5SDimitry Andric       search_using_module_spec = true;
29990b57cec5SDimitry Andric       module_spec.GetUUID() =
30000b57cec5SDimitry Andric           m_uuid_option_group.GetOptionValue().GetCurrentValue();
30010b57cec5SDimitry Andric     }
30020b57cec5SDimitry Andric 
30030b57cec5SDimitry Andric     if (search_using_module_spec) {
30040b57cec5SDimitry Andric       ModuleList matching_modules;
30050b57cec5SDimitry Andric       target->GetImages().FindModules(module_spec, matching_modules);
30069dba64beSDimitry Andric       const size_t num_matches = matching_modules.GetSize();
30070b57cec5SDimitry Andric 
30080b57cec5SDimitry Andric       char path[PATH_MAX];
30090b57cec5SDimitry Andric       if (num_matches == 1) {
30100b57cec5SDimitry Andric         Module *module = matching_modules.GetModulePointerAtIndex(0);
30110b57cec5SDimitry Andric         if (module) {
30120b57cec5SDimitry Andric           ObjectFile *objfile = module->GetObjectFile();
30130b57cec5SDimitry Andric           if (objfile) {
30140b57cec5SDimitry Andric             SectionList *section_list = module->GetSectionList();
30150b57cec5SDimitry Andric             if (section_list) {
30160b57cec5SDimitry Andric               bool changed = false;
30170b57cec5SDimitry Andric               if (argc == 0) {
30180b57cec5SDimitry Andric                 if (m_slide_option.GetOptionValue().OptionWasSet()) {
30190b57cec5SDimitry Andric                   const addr_t slide =
30200b57cec5SDimitry Andric                       m_slide_option.GetOptionValue().GetCurrentValue();
30210b57cec5SDimitry Andric                   const bool slide_is_offset = true;
30220b57cec5SDimitry Andric                   module->SetLoadAddress(*target, slide, slide_is_offset,
30230b57cec5SDimitry Andric                                          changed);
30240b57cec5SDimitry Andric                 } else {
30250b57cec5SDimitry Andric                   result.AppendError("one or more section name + load "
30260b57cec5SDimitry Andric                                      "address pair must be specified");
3027c9157d92SDimitry Andric                   return;
30280b57cec5SDimitry Andric                 }
30290b57cec5SDimitry Andric               } else {
30300b57cec5SDimitry Andric                 if (m_slide_option.GetOptionValue().OptionWasSet()) {
30310b57cec5SDimitry Andric                   result.AppendError("The \"--slide <offset>\" option can't "
30320b57cec5SDimitry Andric                                      "be used in conjunction with setting "
30330b57cec5SDimitry Andric                                      "section load addresses.\n");
3034c9157d92SDimitry Andric                   return;
30350b57cec5SDimitry Andric                 }
30360b57cec5SDimitry Andric 
30370b57cec5SDimitry Andric                 for (size_t i = 0; i < argc; i += 2) {
30380b57cec5SDimitry Andric                   const char *sect_name = args.GetArgumentAtIndex(i);
30390b57cec5SDimitry Andric                   const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1);
30400b57cec5SDimitry Andric                   if (sect_name && load_addr_cstr) {
30410b57cec5SDimitry Andric                     ConstString const_sect_name(sect_name);
30425ffd83dbSDimitry Andric                     addr_t load_addr;
30435ffd83dbSDimitry Andric                     if (llvm::to_integer(load_addr_cstr, load_addr)) {
30440b57cec5SDimitry Andric                       SectionSP section_sp(
30450b57cec5SDimitry Andric                           section_list->FindSectionByName(const_sect_name));
30460b57cec5SDimitry Andric                       if (section_sp) {
30470b57cec5SDimitry Andric                         if (section_sp->IsThreadSpecific()) {
30480b57cec5SDimitry Andric                           result.AppendErrorWithFormat(
30490b57cec5SDimitry Andric                               "thread specific sections are not yet "
30500b57cec5SDimitry Andric                               "supported (section '%s')\n",
30510b57cec5SDimitry Andric                               sect_name);
30520b57cec5SDimitry Andric                           break;
30530b57cec5SDimitry Andric                         } else {
30540b57cec5SDimitry Andric                           if (target->GetSectionLoadList()
30559dba64beSDimitry Andric                                   .SetSectionLoadAddress(section_sp, load_addr))
30560b57cec5SDimitry Andric                             changed = true;
30570b57cec5SDimitry Andric                           result.AppendMessageWithFormat(
30580b57cec5SDimitry Andric                               "section '%s' loaded at 0x%" PRIx64 "\n",
30590b57cec5SDimitry Andric                               sect_name, load_addr);
30600b57cec5SDimitry Andric                         }
30610b57cec5SDimitry Andric                       } else {
30620b57cec5SDimitry Andric                         result.AppendErrorWithFormat("no section found that "
30630b57cec5SDimitry Andric                                                      "matches the section "
30640b57cec5SDimitry Andric                                                      "name '%s'\n",
30650b57cec5SDimitry Andric                                                      sect_name);
30660b57cec5SDimitry Andric                         break;
30670b57cec5SDimitry Andric                       }
30680b57cec5SDimitry Andric                     } else {
30690b57cec5SDimitry Andric                       result.AppendErrorWithFormat(
30709dba64beSDimitry Andric                           "invalid load address string '%s'\n", load_addr_cstr);
30710b57cec5SDimitry Andric                       break;
30720b57cec5SDimitry Andric                     }
30730b57cec5SDimitry Andric                   } else {
30740b57cec5SDimitry Andric                     if (sect_name)
30750b57cec5SDimitry Andric                       result.AppendError("section names must be followed by "
30760b57cec5SDimitry Andric                                          "a load address.\n");
30770b57cec5SDimitry Andric                     else
30780b57cec5SDimitry Andric                       result.AppendError("one or more section name + load "
30790b57cec5SDimitry Andric                                          "address pair must be specified.\n");
30800b57cec5SDimitry Andric                     break;
30810b57cec5SDimitry Andric                   }
30820b57cec5SDimitry Andric                 }
30830b57cec5SDimitry Andric               }
30840b57cec5SDimitry Andric 
30850b57cec5SDimitry Andric               if (changed) {
30860b57cec5SDimitry Andric                 target->ModulesDidLoad(matching_modules);
30870b57cec5SDimitry Andric                 Process *process = m_exe_ctx.GetProcessPtr();
30880b57cec5SDimitry Andric                 if (process)
30890b57cec5SDimitry Andric                   process->Flush();
30900b57cec5SDimitry Andric               }
30910b57cec5SDimitry Andric               if (load) {
30920b57cec5SDimitry Andric                 ProcessSP process = target->CalculateProcess();
30930b57cec5SDimitry Andric                 Address file_entry = objfile->GetEntryPointAddress();
30940b57cec5SDimitry Andric                 if (!process) {
30950b57cec5SDimitry Andric                   result.AppendError("No process");
3096c9157d92SDimitry Andric                   return;
30970b57cec5SDimitry Andric                 }
30980b57cec5SDimitry Andric                 if (set_pc && !file_entry.IsValid()) {
30990b57cec5SDimitry Andric                   result.AppendError("No entry address in object file");
3100c9157d92SDimitry Andric                   return;
31010b57cec5SDimitry Andric                 }
31020b57cec5SDimitry Andric                 std::vector<ObjectFile::LoadableData> loadables(
31030b57cec5SDimitry Andric                     objfile->GetLoadableData(*target));
31040b57cec5SDimitry Andric                 if (loadables.size() == 0) {
31050b57cec5SDimitry Andric                   result.AppendError("No loadable sections");
3106c9157d92SDimitry Andric                   return;
31070b57cec5SDimitry Andric                 }
31080b57cec5SDimitry Andric                 Status error = process->WriteObjectFile(std::move(loadables));
31090b57cec5SDimitry Andric                 if (error.Fail()) {
31100b57cec5SDimitry Andric                   result.AppendError(error.AsCString());
3111c9157d92SDimitry Andric                   return;
31120b57cec5SDimitry Andric                 }
31130b57cec5SDimitry Andric                 if (set_pc) {
31140b57cec5SDimitry Andric                   ThreadList &thread_list = process->GetThreadList();
31150b57cec5SDimitry Andric                   RegisterContextSP reg_context(
31160b57cec5SDimitry Andric                       thread_list.GetSelectedThread()->GetRegisterContext());
31170b57cec5SDimitry Andric                   addr_t file_entry_addr = file_entry.GetLoadAddress(target);
31180b57cec5SDimitry Andric                   if (!reg_context->SetPC(file_entry_addr)) {
31190b57cec5SDimitry Andric                     result.AppendErrorWithFormat("failed to set PC value to "
31200b57cec5SDimitry Andric                                                  "0x%" PRIx64 "\n",
31210b57cec5SDimitry Andric                                                  file_entry_addr);
31220b57cec5SDimitry Andric                   }
31230b57cec5SDimitry Andric                 }
31240b57cec5SDimitry Andric               }
31250b57cec5SDimitry Andric             } else {
31260b57cec5SDimitry Andric               module->GetFileSpec().GetPath(path, sizeof(path));
31279dba64beSDimitry Andric               result.AppendErrorWithFormat("no sections in object file '%s'\n",
31289dba64beSDimitry Andric                                            path);
31290b57cec5SDimitry Andric             }
31300b57cec5SDimitry Andric           } else {
31310b57cec5SDimitry Andric             module->GetFileSpec().GetPath(path, sizeof(path));
31320b57cec5SDimitry Andric             result.AppendErrorWithFormat("no object file for module '%s'\n",
31330b57cec5SDimitry Andric                                          path);
31340b57cec5SDimitry Andric           }
31350b57cec5SDimitry Andric         } else {
31360b57cec5SDimitry Andric           FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
31370b57cec5SDimitry Andric           if (module_spec_file) {
31380b57cec5SDimitry Andric             module_spec_file->GetPath(path, sizeof(path));
31390b57cec5SDimitry Andric             result.AppendErrorWithFormat("invalid module '%s'.\n", path);
31400b57cec5SDimitry Andric           } else
31410b57cec5SDimitry Andric             result.AppendError("no module spec");
31420b57cec5SDimitry Andric         }
31430b57cec5SDimitry Andric       } else {
31440b57cec5SDimitry Andric         std::string uuid_str;
31450b57cec5SDimitry Andric 
31460b57cec5SDimitry Andric         if (module_spec.GetFileSpec())
31470b57cec5SDimitry Andric           module_spec.GetFileSpec().GetPath(path, sizeof(path));
31480b57cec5SDimitry Andric         else
31490b57cec5SDimitry Andric           path[0] = '\0';
31500b57cec5SDimitry Andric 
31510b57cec5SDimitry Andric         if (module_spec.GetUUIDPtr())
31520b57cec5SDimitry Andric           uuid_str = module_spec.GetUUID().GetAsString();
31530b57cec5SDimitry Andric         if (num_matches > 1) {
31540b57cec5SDimitry Andric           result.AppendErrorWithFormat(
31550b57cec5SDimitry Andric               "multiple modules match%s%s%s%s:\n", path[0] ? " file=" : "",
31560b57cec5SDimitry Andric               path, !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
31570b57cec5SDimitry Andric           for (size_t i = 0; i < num_matches; ++i) {
31580b57cec5SDimitry Andric             if (matching_modules.GetModulePointerAtIndex(i)
31590b57cec5SDimitry Andric                     ->GetFileSpec()
31600b57cec5SDimitry Andric                     .GetPath(path, sizeof(path)))
31610b57cec5SDimitry Andric               result.AppendMessageWithFormat("%s\n", path);
31620b57cec5SDimitry Andric           }
31630b57cec5SDimitry Andric         } else {
31640b57cec5SDimitry Andric           result.AppendErrorWithFormat(
31650b57cec5SDimitry Andric               "no modules were found  that match%s%s%s%s.\n",
31669dba64beSDimitry Andric               path[0] ? " file=" : "", path, !uuid_str.empty() ? " uuid=" : "",
31679dba64beSDimitry Andric               uuid_str.c_str());
31680b57cec5SDimitry Andric         }
31690b57cec5SDimitry Andric       }
31700b57cec5SDimitry Andric     } else {
31710b57cec5SDimitry Andric       result.AppendError("either the \"--file <module>\" or the \"--uuid "
31720b57cec5SDimitry Andric                          "<uuid>\" option must be specified.\n");
31730b57cec5SDimitry Andric     }
31740b57cec5SDimitry Andric   }
31750b57cec5SDimitry Andric 
31760b57cec5SDimitry Andric   OptionGroupOptions m_option_group;
31770b57cec5SDimitry Andric   OptionGroupUUID m_uuid_option_group;
31780b57cec5SDimitry Andric   OptionGroupString m_file_option;
31790b57cec5SDimitry Andric   OptionGroupBoolean m_load_option;
31800b57cec5SDimitry Andric   OptionGroupBoolean m_pc_option;
31810b57cec5SDimitry Andric   OptionGroupUInt64 m_slide_option;
31820b57cec5SDimitry Andric };
31830b57cec5SDimitry Andric 
3184349cc55cSDimitry Andric #pragma mark CommandObjectTargetModulesList
31850b57cec5SDimitry Andric // List images with associated information
31869dba64beSDimitry Andric #define LLDB_OPTIONS_target_modules_list
31879dba64beSDimitry Andric #include "CommandOptions.inc"
31880b57cec5SDimitry Andric 
31890b57cec5SDimitry Andric class CommandObjectTargetModulesList : public CommandObjectParsed {
31900b57cec5SDimitry Andric public:
31910b57cec5SDimitry Andric   class CommandOptions : public Options {
31920b57cec5SDimitry Andric   public:
319381ad6265SDimitry Andric     CommandOptions() = default;
31940b57cec5SDimitry Andric 
31950b57cec5SDimitry Andric     ~CommandOptions() override = default;
31960b57cec5SDimitry Andric 
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)31970b57cec5SDimitry Andric     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
31980b57cec5SDimitry Andric                           ExecutionContext *execution_context) override {
31990b57cec5SDimitry Andric       Status error;
32000b57cec5SDimitry Andric 
32010b57cec5SDimitry Andric       const int short_option = m_getopt_table[option_idx].val;
32020b57cec5SDimitry Andric       if (short_option == 'g') {
32030b57cec5SDimitry Andric         m_use_global_module_list = true;
32040b57cec5SDimitry Andric       } else if (short_option == 'a') {
32050b57cec5SDimitry Andric         m_module_addr = OptionArgParser::ToAddress(
32060b57cec5SDimitry Andric             execution_context, option_arg, LLDB_INVALID_ADDRESS, &error);
32070b57cec5SDimitry Andric       } else {
32080b57cec5SDimitry Andric         unsigned long width = 0;
32090b57cec5SDimitry Andric         option_arg.getAsInteger(0, width);
32100b57cec5SDimitry Andric         m_format_array.push_back(std::make_pair(short_option, width));
32110b57cec5SDimitry Andric       }
32120b57cec5SDimitry Andric       return error;
32130b57cec5SDimitry Andric     }
32140b57cec5SDimitry Andric 
OptionParsingStarting(ExecutionContext * execution_context)32150b57cec5SDimitry Andric     void OptionParsingStarting(ExecutionContext *execution_context) override {
32160b57cec5SDimitry Andric       m_format_array.clear();
32170b57cec5SDimitry Andric       m_use_global_module_list = false;
32180b57cec5SDimitry Andric       m_module_addr = LLDB_INVALID_ADDRESS;
32190b57cec5SDimitry Andric     }
32200b57cec5SDimitry Andric 
GetDefinitions()32210b57cec5SDimitry Andric     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3222bdd1243dSDimitry Andric       return llvm::ArrayRef(g_target_modules_list_options);
32230b57cec5SDimitry Andric     }
32240b57cec5SDimitry Andric 
32250b57cec5SDimitry Andric     // Instance variables to hold the values for command options.
32260b57cec5SDimitry Andric     typedef std::vector<std::pair<char, uint32_t>> FormatWidthCollection;
32270b57cec5SDimitry Andric     FormatWidthCollection m_format_array;
3228fe6060f1SDimitry Andric     bool m_use_global_module_list = false;
3229fe6060f1SDimitry Andric     lldb::addr_t m_module_addr = LLDB_INVALID_ADDRESS;
32300b57cec5SDimitry Andric   };
32310b57cec5SDimitry Andric 
CommandObjectTargetModulesList(CommandInterpreter & interpreter)32320b57cec5SDimitry Andric   CommandObjectTargetModulesList(CommandInterpreter &interpreter)
32330b57cec5SDimitry Andric       : CommandObjectParsed(
32340b57cec5SDimitry Andric             interpreter, "target modules list",
323581ad6265SDimitry Andric             "List current executable and dependent shared library images.") {
323681ad6265SDimitry Andric     CommandArgumentData module_arg{eArgTypeShlibName, eArgRepeatStar};
323781ad6265SDimitry Andric     m_arguments.push_back({module_arg});
323881ad6265SDimitry Andric   }
32390b57cec5SDimitry Andric 
32400b57cec5SDimitry Andric   ~CommandObjectTargetModulesList() override = default;
32410b57cec5SDimitry Andric 
GetOptions()32420b57cec5SDimitry Andric   Options *GetOptions() override { return &m_options; }
32430b57cec5SDimitry Andric 
32440b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)3245c9157d92SDimitry Andric   void DoExecute(Args &command, CommandReturnObject &result) override {
32460b57cec5SDimitry Andric     Target *target = GetDebugger().GetSelectedTarget().get();
32470b57cec5SDimitry Andric     const bool use_global_module_list = m_options.m_use_global_module_list;
32480b57cec5SDimitry Andric     // Define a local module list here to ensure it lives longer than any
32490b57cec5SDimitry Andric     // "locker" object which might lock its contents below (through the
32500b57cec5SDimitry Andric     // "module_list_ptr" variable).
32510b57cec5SDimitry Andric     ModuleList module_list;
32520b57cec5SDimitry Andric     if (target == nullptr && !use_global_module_list) {
32530b57cec5SDimitry Andric       result.AppendError("invalid target, create a debug target using the "
32540b57cec5SDimitry Andric                          "'target create' command");
3255c9157d92SDimitry Andric       return;
32560b57cec5SDimitry Andric     } else {
32570b57cec5SDimitry Andric       if (target) {
32580b57cec5SDimitry Andric         uint32_t addr_byte_size =
32590b57cec5SDimitry Andric             target->GetArchitecture().GetAddressByteSize();
32600b57cec5SDimitry Andric         result.GetOutputStream().SetAddressByteSize(addr_byte_size);
32610b57cec5SDimitry Andric         result.GetErrorStream().SetAddressByteSize(addr_byte_size);
32620b57cec5SDimitry Andric       }
32630b57cec5SDimitry Andric       // Dump all sections for all modules images
32640b57cec5SDimitry Andric       Stream &strm = result.GetOutputStream();
32650b57cec5SDimitry Andric 
32660b57cec5SDimitry Andric       if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) {
32670b57cec5SDimitry Andric         if (target) {
32680b57cec5SDimitry Andric           Address module_address;
32690b57cec5SDimitry Andric           if (module_address.SetLoadAddress(m_options.m_module_addr, target)) {
32700b57cec5SDimitry Andric             ModuleSP module_sp(module_address.GetModule());
32710b57cec5SDimitry Andric             if (module_sp) {
32720b57cec5SDimitry Andric               PrintModule(target, module_sp.get(), 0, strm);
32730b57cec5SDimitry Andric               result.SetStatus(eReturnStatusSuccessFinishResult);
32740b57cec5SDimitry Andric             } else {
32750b57cec5SDimitry Andric               result.AppendErrorWithFormat(
32760b57cec5SDimitry Andric                   "Couldn't find module matching address: 0x%" PRIx64 ".",
32770b57cec5SDimitry Andric                   m_options.m_module_addr);
32780b57cec5SDimitry Andric             }
32790b57cec5SDimitry Andric           } else {
32800b57cec5SDimitry Andric             result.AppendErrorWithFormat(
32810b57cec5SDimitry Andric                 "Couldn't find module containing address: 0x%" PRIx64 ".",
32820b57cec5SDimitry Andric                 m_options.m_module_addr);
32830b57cec5SDimitry Andric           }
32840b57cec5SDimitry Andric         } else {
32850b57cec5SDimitry Andric           result.AppendError(
32860b57cec5SDimitry Andric               "Can only look up modules by address with a valid target.");
32870b57cec5SDimitry Andric         }
3288c9157d92SDimitry Andric         return;
32890b57cec5SDimitry Andric       }
32900b57cec5SDimitry Andric 
32910b57cec5SDimitry Andric       size_t num_modules = 0;
32920b57cec5SDimitry Andric 
32930b57cec5SDimitry Andric       // This locker will be locked on the mutex in module_list_ptr if it is
32940b57cec5SDimitry Andric       // non-nullptr. Otherwise it will lock the
32950b57cec5SDimitry Andric       // AllocationModuleCollectionMutex when accessing the global module list
32960b57cec5SDimitry Andric       // directly.
32970b57cec5SDimitry Andric       std::unique_lock<std::recursive_mutex> guard(
32980b57cec5SDimitry Andric           Module::GetAllocationModuleCollectionMutex(), std::defer_lock);
32990b57cec5SDimitry Andric 
33000b57cec5SDimitry Andric       const ModuleList *module_list_ptr = nullptr;
33010b57cec5SDimitry Andric       const size_t argc = command.GetArgumentCount();
33020b57cec5SDimitry Andric       if (argc == 0) {
33030b57cec5SDimitry Andric         if (use_global_module_list) {
33040b57cec5SDimitry Andric           guard.lock();
33050b57cec5SDimitry Andric           num_modules = Module::GetNumberAllocatedModules();
33060b57cec5SDimitry Andric         } else {
33070b57cec5SDimitry Andric           module_list_ptr = &target->GetImages();
33080b57cec5SDimitry Andric         }
33090b57cec5SDimitry Andric       } else {
33105ffd83dbSDimitry Andric         for (const Args::ArgEntry &arg : command) {
33110b57cec5SDimitry Andric           // Dump specified images (by basename or fullpath)
33120b57cec5SDimitry Andric           const size_t num_matches = FindModulesByName(
33135ffd83dbSDimitry Andric               target, arg.c_str(), module_list, use_global_module_list);
33140b57cec5SDimitry Andric           if (num_matches == 0) {
33150b57cec5SDimitry Andric             if (argc == 1) {
33160b57cec5SDimitry Andric               result.AppendErrorWithFormat("no modules found that match '%s'",
33175ffd83dbSDimitry Andric                                            arg.c_str());
3318c9157d92SDimitry Andric               return;
33190b57cec5SDimitry Andric             }
33200b57cec5SDimitry Andric           }
33210b57cec5SDimitry Andric         }
33220b57cec5SDimitry Andric 
33230b57cec5SDimitry Andric         module_list_ptr = &module_list;
33240b57cec5SDimitry Andric       }
33250b57cec5SDimitry Andric 
33260b57cec5SDimitry Andric       std::unique_lock<std::recursive_mutex> lock;
33270b57cec5SDimitry Andric       if (module_list_ptr != nullptr) {
33280b57cec5SDimitry Andric         lock =
33290b57cec5SDimitry Andric             std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex());
33300b57cec5SDimitry Andric 
33310b57cec5SDimitry Andric         num_modules = module_list_ptr->GetSize();
33320b57cec5SDimitry Andric       }
33330b57cec5SDimitry Andric 
33340b57cec5SDimitry Andric       if (num_modules > 0) {
33350b57cec5SDimitry Andric         for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
33360b57cec5SDimitry Andric           ModuleSP module_sp;
33370b57cec5SDimitry Andric           Module *module;
33380b57cec5SDimitry Andric           if (module_list_ptr) {
33390b57cec5SDimitry Andric             module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
33400b57cec5SDimitry Andric             module = module_sp.get();
33410b57cec5SDimitry Andric           } else {
33420b57cec5SDimitry Andric             module = Module::GetAllocatedModuleAtIndex(image_idx);
33430b57cec5SDimitry Andric             module_sp = module->shared_from_this();
33440b57cec5SDimitry Andric           }
33450b57cec5SDimitry Andric 
33460b57cec5SDimitry Andric           const size_t indent = strm.Printf("[%3u] ", image_idx);
33470b57cec5SDimitry Andric           PrintModule(target, module, indent, strm);
33480b57cec5SDimitry Andric         }
33490b57cec5SDimitry Andric         result.SetStatus(eReturnStatusSuccessFinishResult);
33500b57cec5SDimitry Andric       } else {
33510b57cec5SDimitry Andric         if (argc) {
33520b57cec5SDimitry Andric           if (use_global_module_list)
33530b57cec5SDimitry Andric             result.AppendError(
33540b57cec5SDimitry Andric                 "the global module list has no matching modules");
33550b57cec5SDimitry Andric           else
33560b57cec5SDimitry Andric             result.AppendError("the target has no matching modules");
33570b57cec5SDimitry Andric         } else {
33580b57cec5SDimitry Andric           if (use_global_module_list)
33590b57cec5SDimitry Andric             result.AppendError("the global module list is empty");
33600b57cec5SDimitry Andric           else
33610b57cec5SDimitry Andric             result.AppendError(
33620b57cec5SDimitry Andric                 "the target has no associated executable images");
33630b57cec5SDimitry Andric         }
3364c9157d92SDimitry Andric         return;
33650b57cec5SDimitry Andric       }
33660b57cec5SDimitry Andric     }
33670b57cec5SDimitry Andric   }
33680b57cec5SDimitry Andric 
PrintModule(Target * target,Module * module,int indent,Stream & strm)33690b57cec5SDimitry Andric   void PrintModule(Target *target, Module *module, int indent, Stream &strm) {
33700b57cec5SDimitry Andric     if (module == nullptr) {
33710b57cec5SDimitry Andric       strm.PutCString("Null module");
33720b57cec5SDimitry Andric       return;
33730b57cec5SDimitry Andric     }
33740b57cec5SDimitry Andric 
33750b57cec5SDimitry Andric     bool dump_object_name = false;
33760b57cec5SDimitry Andric     if (m_options.m_format_array.empty()) {
33770b57cec5SDimitry Andric       m_options.m_format_array.push_back(std::make_pair('u', 0));
33780b57cec5SDimitry Andric       m_options.m_format_array.push_back(std::make_pair('h', 0));
33790b57cec5SDimitry Andric       m_options.m_format_array.push_back(std::make_pair('f', 0));
33800b57cec5SDimitry Andric       m_options.m_format_array.push_back(std::make_pair('S', 0));
33810b57cec5SDimitry Andric     }
33820b57cec5SDimitry Andric     const size_t num_entries = m_options.m_format_array.size();
33830b57cec5SDimitry Andric     bool print_space = false;
33840b57cec5SDimitry Andric     for (size_t i = 0; i < num_entries; ++i) {
33850b57cec5SDimitry Andric       if (print_space)
33860b57cec5SDimitry Andric         strm.PutChar(' ');
33870b57cec5SDimitry Andric       print_space = true;
33880b57cec5SDimitry Andric       const char format_char = m_options.m_format_array[i].first;
33890b57cec5SDimitry Andric       uint32_t width = m_options.m_format_array[i].second;
33900b57cec5SDimitry Andric       switch (format_char) {
33910b57cec5SDimitry Andric       case 'A':
33920b57cec5SDimitry Andric         DumpModuleArchitecture(strm, module, false, width);
33930b57cec5SDimitry Andric         break;
33940b57cec5SDimitry Andric 
33950b57cec5SDimitry Andric       case 't':
33960b57cec5SDimitry Andric         DumpModuleArchitecture(strm, module, true, width);
33970b57cec5SDimitry Andric         break;
33980b57cec5SDimitry Andric 
33990b57cec5SDimitry Andric       case 'f':
34000b57cec5SDimitry Andric         DumpFullpath(strm, &module->GetFileSpec(), width);
34010b57cec5SDimitry Andric         dump_object_name = true;
34020b57cec5SDimitry Andric         break;
34030b57cec5SDimitry Andric 
34040b57cec5SDimitry Andric       case 'd':
34050b57cec5SDimitry Andric         DumpDirectory(strm, &module->GetFileSpec(), width);
34060b57cec5SDimitry Andric         break;
34070b57cec5SDimitry Andric 
34080b57cec5SDimitry Andric       case 'b':
34090b57cec5SDimitry Andric         DumpBasename(strm, &module->GetFileSpec(), width);
34100b57cec5SDimitry Andric         dump_object_name = true;
34110b57cec5SDimitry Andric         break;
34120b57cec5SDimitry Andric 
34130b57cec5SDimitry Andric       case 'h':
34140b57cec5SDimitry Andric       case 'o':
34150b57cec5SDimitry Andric         // Image header address
34160b57cec5SDimitry Andric         {
34170b57cec5SDimitry Andric           uint32_t addr_nibble_width =
34180b57cec5SDimitry Andric               target ? (target->GetArchitecture().GetAddressByteSize() * 2)
34190b57cec5SDimitry Andric                      : 16;
34200b57cec5SDimitry Andric 
34210b57cec5SDimitry Andric           ObjectFile *objfile = module->GetObjectFile();
34220b57cec5SDimitry Andric           if (objfile) {
34230b57cec5SDimitry Andric             Address base_addr(objfile->GetBaseAddress());
34240b57cec5SDimitry Andric             if (base_addr.IsValid()) {
34250b57cec5SDimitry Andric               if (target && !target->GetSectionLoadList().IsEmpty()) {
3426480093f4SDimitry Andric                 lldb::addr_t load_addr = base_addr.GetLoadAddress(target);
34270b57cec5SDimitry Andric                 if (load_addr == LLDB_INVALID_ADDRESS) {
34280b57cec5SDimitry Andric                   base_addr.Dump(&strm, target,
34290b57cec5SDimitry Andric                                  Address::DumpStyleModuleWithFileAddress,
34300b57cec5SDimitry Andric                                  Address::DumpStyleFileAddress);
34310b57cec5SDimitry Andric                 } else {
34320b57cec5SDimitry Andric                   if (format_char == 'o') {
34330b57cec5SDimitry Andric                     // Show the offset of slide for the image
3434480093f4SDimitry Andric                     strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3435480093f4SDimitry Andric                                 addr_nibble_width,
34360b57cec5SDimitry Andric                                 load_addr - base_addr.GetFileAddress());
34370b57cec5SDimitry Andric                   } else {
34380b57cec5SDimitry Andric                     // Show the load address of the image
34390b57cec5SDimitry Andric                     strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
34400b57cec5SDimitry Andric                                 addr_nibble_width, load_addr);
34410b57cec5SDimitry Andric                   }
34420b57cec5SDimitry Andric                 }
34430b57cec5SDimitry Andric                 break;
34440b57cec5SDimitry Andric               }
34450b57cec5SDimitry Andric               // The address was valid, but the image isn't loaded, output the
34460b57cec5SDimitry Andric               // address in an appropriate format
34470b57cec5SDimitry Andric               base_addr.Dump(&strm, target, Address::DumpStyleFileAddress);
34480b57cec5SDimitry Andric               break;
34490b57cec5SDimitry Andric             }
34500b57cec5SDimitry Andric           }
34510b57cec5SDimitry Andric           strm.Printf("%*s", addr_nibble_width + 2, "");
34520b57cec5SDimitry Andric         }
34530b57cec5SDimitry Andric         break;
34540b57cec5SDimitry Andric 
34550b57cec5SDimitry Andric       case 'r': {
34560b57cec5SDimitry Andric         size_t ref_count = 0;
34570b57cec5SDimitry Andric         ModuleSP module_sp(module->shared_from_this());
34580b57cec5SDimitry Andric         if (module_sp) {
34590b57cec5SDimitry Andric           // Take one away to make sure we don't count our local "module_sp"
34600b57cec5SDimitry Andric           ref_count = module_sp.use_count() - 1;
34610b57cec5SDimitry Andric         }
34620b57cec5SDimitry Andric         if (width)
34630b57cec5SDimitry Andric           strm.Printf("{%*" PRIu64 "}", width, (uint64_t)ref_count);
34640b57cec5SDimitry Andric         else
34650b57cec5SDimitry Andric           strm.Printf("{%" PRIu64 "}", (uint64_t)ref_count);
34660b57cec5SDimitry Andric       } break;
34670b57cec5SDimitry Andric 
34680b57cec5SDimitry Andric       case 's':
34690b57cec5SDimitry Andric       case 'S': {
34709dba64beSDimitry Andric         if (const SymbolFile *symbol_file = module->GetSymbolFile()) {
34719dba64beSDimitry Andric           const FileSpec symfile_spec =
34729dba64beSDimitry Andric               symbol_file->GetObjectFile()->GetFileSpec();
34730b57cec5SDimitry Andric           if (format_char == 'S') {
34740b57cec5SDimitry Andric             // Dump symbol file only if different from module file
34750b57cec5SDimitry Andric             if (!symfile_spec || symfile_spec == module->GetFileSpec()) {
34760b57cec5SDimitry Andric               print_space = false;
34770b57cec5SDimitry Andric               break;
34780b57cec5SDimitry Andric             }
34790b57cec5SDimitry Andric             // Add a newline and indent past the index
34800b57cec5SDimitry Andric             strm.Printf("\n%*s", indent, "");
34810b57cec5SDimitry Andric           }
34820b57cec5SDimitry Andric           DumpFullpath(strm, &symfile_spec, width);
34830b57cec5SDimitry Andric           dump_object_name = true;
34840b57cec5SDimitry Andric           break;
34850b57cec5SDimitry Andric         }
34860b57cec5SDimitry Andric         strm.Printf("%.*s", width, "<NONE>");
34870b57cec5SDimitry Andric       } break;
34880b57cec5SDimitry Andric 
34890b57cec5SDimitry Andric       case 'm':
34900b57cec5SDimitry Andric         strm.Format("{0:%c}", llvm::fmt_align(module->GetModificationTime(),
34910b57cec5SDimitry Andric                                               llvm::AlignStyle::Left, width));
34920b57cec5SDimitry Andric         break;
34930b57cec5SDimitry Andric 
34940b57cec5SDimitry Andric       case 'p':
34950b57cec5SDimitry Andric         strm.Printf("%p", static_cast<void *>(module));
34960b57cec5SDimitry Andric         break;
34970b57cec5SDimitry Andric 
34980b57cec5SDimitry Andric       case 'u':
34990b57cec5SDimitry Andric         DumpModuleUUID(strm, module);
35000b57cec5SDimitry Andric         break;
35010b57cec5SDimitry Andric 
35020b57cec5SDimitry Andric       default:
35030b57cec5SDimitry Andric         break;
35040b57cec5SDimitry Andric       }
35050b57cec5SDimitry Andric     }
35060b57cec5SDimitry Andric     if (dump_object_name) {
35070b57cec5SDimitry Andric       const char *object_name = module->GetObjectName().GetCString();
35080b57cec5SDimitry Andric       if (object_name)
35090b57cec5SDimitry Andric         strm.Printf("(%s)", object_name);
35100b57cec5SDimitry Andric     }
35110b57cec5SDimitry Andric     strm.EOL();
35120b57cec5SDimitry Andric   }
35130b57cec5SDimitry Andric 
35140b57cec5SDimitry Andric   CommandOptions m_options;
35150b57cec5SDimitry Andric };
35160b57cec5SDimitry Andric 
35170b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesShowUnwind
35180b57cec5SDimitry Andric 
35190b57cec5SDimitry Andric // Lookup unwind information in images
35209dba64beSDimitry Andric #define LLDB_OPTIONS_target_modules_show_unwind
35219dba64beSDimitry Andric #include "CommandOptions.inc"
35220b57cec5SDimitry Andric 
35230b57cec5SDimitry Andric class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {
35240b57cec5SDimitry Andric public:
35250b57cec5SDimitry Andric   enum {
35260b57cec5SDimitry Andric     eLookupTypeInvalid = -1,
35270b57cec5SDimitry Andric     eLookupTypeAddress = 0,
35280b57cec5SDimitry Andric     eLookupTypeSymbol,
35290b57cec5SDimitry Andric     eLookupTypeFunction,
35300b57cec5SDimitry Andric     eLookupTypeFunctionOrSymbol,
35310b57cec5SDimitry Andric     kNumLookupTypes
35320b57cec5SDimitry Andric   };
35330b57cec5SDimitry Andric 
35340b57cec5SDimitry Andric   class CommandOptions : public Options {
35350b57cec5SDimitry Andric   public:
353681ad6265SDimitry Andric     CommandOptions() = default;
35370b57cec5SDimitry Andric 
35380b57cec5SDimitry Andric     ~CommandOptions() override = default;
35390b57cec5SDimitry Andric 
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)35400b57cec5SDimitry Andric     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
35410b57cec5SDimitry Andric                           ExecutionContext *execution_context) override {
35420b57cec5SDimitry Andric       Status error;
35430b57cec5SDimitry Andric 
35440b57cec5SDimitry Andric       const int short_option = m_getopt_table[option_idx].val;
35450b57cec5SDimitry Andric 
35460b57cec5SDimitry Andric       switch (short_option) {
35470b57cec5SDimitry Andric       case 'a': {
35485ffd83dbSDimitry Andric         m_str = std::string(option_arg);
35490b57cec5SDimitry Andric         m_type = eLookupTypeAddress;
35500b57cec5SDimitry Andric         m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
35510b57cec5SDimitry Andric                                             LLDB_INVALID_ADDRESS, &error);
35520b57cec5SDimitry Andric         if (m_addr == LLDB_INVALID_ADDRESS)
35530b57cec5SDimitry Andric           error.SetErrorStringWithFormat("invalid address string '%s'",
35540b57cec5SDimitry Andric                                          option_arg.str().c_str());
35550b57cec5SDimitry Andric         break;
35560b57cec5SDimitry Andric       }
35570b57cec5SDimitry Andric 
35580b57cec5SDimitry Andric       case 'n':
35595ffd83dbSDimitry Andric         m_str = std::string(option_arg);
35600b57cec5SDimitry Andric         m_type = eLookupTypeFunctionOrSymbol;
35610b57cec5SDimitry Andric         break;
35620b57cec5SDimitry Andric 
35630b57cec5SDimitry Andric       default:
35649dba64beSDimitry Andric         llvm_unreachable("Unimplemented option");
35650b57cec5SDimitry Andric       }
35660b57cec5SDimitry Andric 
35670b57cec5SDimitry Andric       return error;
35680b57cec5SDimitry Andric     }
35690b57cec5SDimitry Andric 
OptionParsingStarting(ExecutionContext * execution_context)35700b57cec5SDimitry Andric     void OptionParsingStarting(ExecutionContext *execution_context) override {
35710b57cec5SDimitry Andric       m_type = eLookupTypeInvalid;
35720b57cec5SDimitry Andric       m_str.clear();
35730b57cec5SDimitry Andric       m_addr = LLDB_INVALID_ADDRESS;
35740b57cec5SDimitry Andric     }
35750b57cec5SDimitry Andric 
GetDefinitions()35760b57cec5SDimitry Andric     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3577bdd1243dSDimitry Andric       return llvm::ArrayRef(g_target_modules_show_unwind_options);
35780b57cec5SDimitry Andric     }
35790b57cec5SDimitry Andric 
35800b57cec5SDimitry Andric     // Instance variables to hold the values for command options.
35810b57cec5SDimitry Andric 
3582fe6060f1SDimitry Andric     int m_type = eLookupTypeInvalid; // Should be a eLookupTypeXXX enum after
3583fe6060f1SDimitry Andric                                      // parsing options
35840b57cec5SDimitry Andric     std::string m_str; // Holds name lookup
3585fe6060f1SDimitry Andric     lldb::addr_t m_addr = LLDB_INVALID_ADDRESS; // Holds the address to lookup
35860b57cec5SDimitry Andric   };
35870b57cec5SDimitry Andric 
CommandObjectTargetModulesShowUnwind(CommandInterpreter & interpreter)35880b57cec5SDimitry Andric   CommandObjectTargetModulesShowUnwind(CommandInterpreter &interpreter)
35890b57cec5SDimitry Andric       : CommandObjectParsed(
35900b57cec5SDimitry Andric             interpreter, "target modules show-unwind",
35910b57cec5SDimitry Andric             "Show synthesized unwind instructions for a function.", nullptr,
35920b57cec5SDimitry Andric             eCommandRequiresTarget | eCommandRequiresProcess |
359304eeddc0SDimitry Andric                 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {}
35940b57cec5SDimitry Andric 
35950b57cec5SDimitry Andric   ~CommandObjectTargetModulesShowUnwind() override = default;
35960b57cec5SDimitry Andric 
GetOptions()35970b57cec5SDimitry Andric   Options *GetOptions() override { return &m_options; }
35980b57cec5SDimitry Andric 
35990b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)3600c9157d92SDimitry Andric   void DoExecute(Args &command, CommandReturnObject &result) override {
36010b57cec5SDimitry Andric     Target *target = m_exe_ctx.GetTargetPtr();
36020b57cec5SDimitry Andric     Process *process = m_exe_ctx.GetProcessPtr();
36030b57cec5SDimitry Andric     ABI *abi = nullptr;
36040b57cec5SDimitry Andric     if (process)
36050b57cec5SDimitry Andric       abi = process->GetABI().get();
36060b57cec5SDimitry Andric 
36070b57cec5SDimitry Andric     if (process == nullptr) {
36080b57cec5SDimitry Andric       result.AppendError(
36090b57cec5SDimitry Andric           "You must have a process running to use this command.");
3610c9157d92SDimitry Andric       return;
36110b57cec5SDimitry Andric     }
36120b57cec5SDimitry Andric 
36130b57cec5SDimitry Andric     ThreadList threads(process->GetThreadList());
36140b57cec5SDimitry Andric     if (threads.GetSize() == 0) {
36150b57cec5SDimitry Andric       result.AppendError("The process must be paused to use this command.");
3616c9157d92SDimitry Andric       return;
36170b57cec5SDimitry Andric     }
36180b57cec5SDimitry Andric 
36190b57cec5SDimitry Andric     ThreadSP thread(threads.GetThreadAtIndex(0));
36200b57cec5SDimitry Andric     if (!thread) {
36210b57cec5SDimitry Andric       result.AppendError("The process must be paused to use this command.");
3622c9157d92SDimitry Andric       return;
36230b57cec5SDimitry Andric     }
36240b57cec5SDimitry Andric 
36250b57cec5SDimitry Andric     SymbolContextList sc_list;
36260b57cec5SDimitry Andric 
36270b57cec5SDimitry Andric     if (m_options.m_type == eLookupTypeFunctionOrSymbol) {
36280b57cec5SDimitry Andric       ConstString function_name(m_options.m_str.c_str());
3629349cc55cSDimitry Andric       ModuleFunctionSearchOptions function_options;
3630349cc55cSDimitry Andric       function_options.include_symbols = true;
3631349cc55cSDimitry Andric       function_options.include_inlines = false;
36320b57cec5SDimitry Andric       target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto,
3633349cc55cSDimitry Andric                                         function_options, sc_list);
36340b57cec5SDimitry Andric     } else if (m_options.m_type == eLookupTypeAddress && target) {
36350b57cec5SDimitry Andric       Address addr;
36360b57cec5SDimitry Andric       if (target->GetSectionLoadList().ResolveLoadAddress(m_options.m_addr,
36370b57cec5SDimitry Andric                                                           addr)) {
36380b57cec5SDimitry Andric         SymbolContext sc;
36390b57cec5SDimitry Andric         ModuleSP module_sp(addr.GetModule());
36400b57cec5SDimitry Andric         module_sp->ResolveSymbolContextForAddress(addr,
36410b57cec5SDimitry Andric                                                   eSymbolContextEverything, sc);
36420b57cec5SDimitry Andric         if (sc.function || sc.symbol) {
36430b57cec5SDimitry Andric           sc_list.Append(sc);
36440b57cec5SDimitry Andric         }
36450b57cec5SDimitry Andric       }
36460b57cec5SDimitry Andric     } else {
36470b57cec5SDimitry Andric       result.AppendError(
36480b57cec5SDimitry Andric           "address-expression or function name option must be specified.");
3649c9157d92SDimitry Andric       return;
36500b57cec5SDimitry Andric     }
36510b57cec5SDimitry Andric 
3652fe013be4SDimitry Andric     if (sc_list.GetSize() == 0) {
36530b57cec5SDimitry Andric       result.AppendErrorWithFormat("no unwind data found that matches '%s'.",
36540b57cec5SDimitry Andric                                    m_options.m_str.c_str());
3655c9157d92SDimitry Andric       return;
36560b57cec5SDimitry Andric     }
36570b57cec5SDimitry Andric 
3658fe013be4SDimitry Andric     for (const SymbolContext &sc : sc_list) {
36590b57cec5SDimitry Andric       if (sc.symbol == nullptr && sc.function == nullptr)
36600b57cec5SDimitry Andric         continue;
36610b57cec5SDimitry Andric       if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr)
36620b57cec5SDimitry Andric         continue;
36630b57cec5SDimitry Andric       AddressRange range;
36640b57cec5SDimitry Andric       if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,
36650b57cec5SDimitry Andric                               false, range))
36660b57cec5SDimitry Andric         continue;
36670b57cec5SDimitry Andric       if (!range.GetBaseAddress().IsValid())
36680b57cec5SDimitry Andric         continue;
36690b57cec5SDimitry Andric       ConstString funcname(sc.GetFunctionName());
36700b57cec5SDimitry Andric       if (funcname.IsEmpty())
36710b57cec5SDimitry Andric         continue;
36720b57cec5SDimitry Andric       addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
36730b57cec5SDimitry Andric       if (abi)
36740b57cec5SDimitry Andric         start_addr = abi->FixCodeAddress(start_addr);
36750b57cec5SDimitry Andric 
36760b57cec5SDimitry Andric       FuncUnwindersSP func_unwinders_sp(
36770b57cec5SDimitry Andric           sc.module_sp->GetUnwindTable()
36780b57cec5SDimitry Andric               .GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
36790b57cec5SDimitry Andric       if (!func_unwinders_sp)
36800b57cec5SDimitry Andric         continue;
36810b57cec5SDimitry Andric 
36820b57cec5SDimitry Andric       result.GetOutputStream().Printf(
3683e8d8bef9SDimitry Andric           "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n",
36840b57cec5SDimitry Andric           sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(),
36850b57cec5SDimitry Andric           funcname.AsCString(), start_addr);
36860b57cec5SDimitry Andric 
3687e8d8bef9SDimitry Andric       Args args;
3688e8d8bef9SDimitry Andric       target->GetUserSpecifiedTrapHandlerNames(args);
3689e8d8bef9SDimitry Andric       size_t count = args.GetArgumentCount();
3690e8d8bef9SDimitry Andric       for (size_t i = 0; i < count; i++) {
3691e8d8bef9SDimitry Andric         const char *trap_func_name = args.GetArgumentAtIndex(i);
3692e8d8bef9SDimitry Andric         if (strcmp(funcname.GetCString(), trap_func_name) == 0)
3693e8d8bef9SDimitry Andric           result.GetOutputStream().Printf(
3694e8d8bef9SDimitry Andric               "This function is "
3695e8d8bef9SDimitry Andric               "treated as a trap handler function via user setting.\n");
3696e8d8bef9SDimitry Andric       }
3697e8d8bef9SDimitry Andric       PlatformSP platform_sp(target->GetPlatform());
3698e8d8bef9SDimitry Andric       if (platform_sp) {
3699e8d8bef9SDimitry Andric         const std::vector<ConstString> trap_handler_names(
3700e8d8bef9SDimitry Andric             platform_sp->GetTrapHandlerSymbolNames());
3701e8d8bef9SDimitry Andric         for (ConstString trap_name : trap_handler_names) {
3702e8d8bef9SDimitry Andric           if (trap_name == funcname) {
3703e8d8bef9SDimitry Andric             result.GetOutputStream().Printf(
3704e8d8bef9SDimitry Andric                 "This function's "
3705e8d8bef9SDimitry Andric                 "name is listed by the platform as a trap handler.\n");
3706e8d8bef9SDimitry Andric           }
3707e8d8bef9SDimitry Andric         }
3708e8d8bef9SDimitry Andric       }
3709e8d8bef9SDimitry Andric 
3710e8d8bef9SDimitry Andric       result.GetOutputStream().Printf("\n");
3711e8d8bef9SDimitry Andric 
37120b57cec5SDimitry Andric       UnwindPlanSP non_callsite_unwind_plan =
37130b57cec5SDimitry Andric           func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread);
37140b57cec5SDimitry Andric       if (non_callsite_unwind_plan) {
37150b57cec5SDimitry Andric         result.GetOutputStream().Printf(
37160b57cec5SDimitry Andric             "Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n",
37170b57cec5SDimitry Andric             non_callsite_unwind_plan->GetSourceName().AsCString());
37180b57cec5SDimitry Andric       }
37190b57cec5SDimitry Andric       UnwindPlanSP callsite_unwind_plan =
37200b57cec5SDimitry Andric           func_unwinders_sp->GetUnwindPlanAtCallSite(*target, *thread);
37210b57cec5SDimitry Andric       if (callsite_unwind_plan) {
37220b57cec5SDimitry Andric         result.GetOutputStream().Printf(
37230b57cec5SDimitry Andric             "Synchronous (restricted to call-sites) UnwindPlan is '%s'\n",
37240b57cec5SDimitry Andric             callsite_unwind_plan->GetSourceName().AsCString());
37250b57cec5SDimitry Andric       }
37260b57cec5SDimitry Andric       UnwindPlanSP fast_unwind_plan =
37270b57cec5SDimitry Andric           func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread);
37280b57cec5SDimitry Andric       if (fast_unwind_plan) {
37290b57cec5SDimitry Andric         result.GetOutputStream().Printf(
37300b57cec5SDimitry Andric             "Fast UnwindPlan is '%s'\n",
37310b57cec5SDimitry Andric             fast_unwind_plan->GetSourceName().AsCString());
37320b57cec5SDimitry Andric       }
37330b57cec5SDimitry Andric 
37340b57cec5SDimitry Andric       result.GetOutputStream().Printf("\n");
37350b57cec5SDimitry Andric 
37360b57cec5SDimitry Andric       UnwindPlanSP assembly_sp =
37370b57cec5SDimitry Andric           func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread);
37380b57cec5SDimitry Andric       if (assembly_sp) {
37390b57cec5SDimitry Andric         result.GetOutputStream().Printf(
37400b57cec5SDimitry Andric             "Assembly language inspection UnwindPlan:\n");
37410b57cec5SDimitry Andric         assembly_sp->Dump(result.GetOutputStream(), thread.get(),
37420b57cec5SDimitry Andric                           LLDB_INVALID_ADDRESS);
37430b57cec5SDimitry Andric         result.GetOutputStream().Printf("\n");
37440b57cec5SDimitry Andric       }
37450b57cec5SDimitry Andric 
37469dba64beSDimitry Andric       UnwindPlanSP of_unwind_sp =
37479dba64beSDimitry Andric           func_unwinders_sp->GetObjectFileUnwindPlan(*target);
37489dba64beSDimitry Andric       if (of_unwind_sp) {
37499dba64beSDimitry Andric         result.GetOutputStream().Printf("object file UnwindPlan:\n");
37509dba64beSDimitry Andric         of_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
37519dba64beSDimitry Andric                            LLDB_INVALID_ADDRESS);
37529dba64beSDimitry Andric         result.GetOutputStream().Printf("\n");
37539dba64beSDimitry Andric       }
37549dba64beSDimitry Andric 
37559dba64beSDimitry Andric       UnwindPlanSP of_unwind_augmented_sp =
3756480093f4SDimitry Andric           func_unwinders_sp->GetObjectFileAugmentedUnwindPlan(*target, *thread);
37579dba64beSDimitry Andric       if (of_unwind_augmented_sp) {
37589dba64beSDimitry Andric         result.GetOutputStream().Printf("object file augmented UnwindPlan:\n");
37599dba64beSDimitry Andric         of_unwind_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
37609dba64beSDimitry Andric                                      LLDB_INVALID_ADDRESS);
37619dba64beSDimitry Andric         result.GetOutputStream().Printf("\n");
37629dba64beSDimitry Andric       }
37639dba64beSDimitry Andric 
37640b57cec5SDimitry Andric       UnwindPlanSP ehframe_sp =
37650b57cec5SDimitry Andric           func_unwinders_sp->GetEHFrameUnwindPlan(*target);
37660b57cec5SDimitry Andric       if (ehframe_sp) {
37670b57cec5SDimitry Andric         result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
37680b57cec5SDimitry Andric         ehframe_sp->Dump(result.GetOutputStream(), thread.get(),
37690b57cec5SDimitry Andric                          LLDB_INVALID_ADDRESS);
37700b57cec5SDimitry Andric         result.GetOutputStream().Printf("\n");
37710b57cec5SDimitry Andric       }
37720b57cec5SDimitry Andric 
37730b57cec5SDimitry Andric       UnwindPlanSP ehframe_augmented_sp =
37740b57cec5SDimitry Andric           func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread);
37750b57cec5SDimitry Andric       if (ehframe_augmented_sp) {
37760b57cec5SDimitry Andric         result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
37770b57cec5SDimitry Andric         ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
37780b57cec5SDimitry Andric                                    LLDB_INVALID_ADDRESS);
37790b57cec5SDimitry Andric         result.GetOutputStream().Printf("\n");
37800b57cec5SDimitry Andric       }
37810b57cec5SDimitry Andric 
37820b57cec5SDimitry Andric       if (UnwindPlanSP plan_sp =
37830b57cec5SDimitry Andric               func_unwinders_sp->GetDebugFrameUnwindPlan(*target)) {
37840b57cec5SDimitry Andric         result.GetOutputStream().Printf("debug_frame UnwindPlan:\n");
37850b57cec5SDimitry Andric         plan_sp->Dump(result.GetOutputStream(), thread.get(),
37860b57cec5SDimitry Andric                       LLDB_INVALID_ADDRESS);
37870b57cec5SDimitry Andric         result.GetOutputStream().Printf("\n");
37880b57cec5SDimitry Andric       }
37890b57cec5SDimitry Andric 
37900b57cec5SDimitry Andric       if (UnwindPlanSP plan_sp =
37910b57cec5SDimitry Andric               func_unwinders_sp->GetDebugFrameAugmentedUnwindPlan(*target,
37920b57cec5SDimitry Andric                                                                   *thread)) {
37930b57cec5SDimitry Andric         result.GetOutputStream().Printf("debug_frame augmented UnwindPlan:\n");
37940b57cec5SDimitry Andric         plan_sp->Dump(result.GetOutputStream(), thread.get(),
37950b57cec5SDimitry Andric                       LLDB_INVALID_ADDRESS);
37960b57cec5SDimitry Andric         result.GetOutputStream().Printf("\n");
37970b57cec5SDimitry Andric       }
37980b57cec5SDimitry Andric 
37990b57cec5SDimitry Andric       UnwindPlanSP arm_unwind_sp =
38000b57cec5SDimitry Andric           func_unwinders_sp->GetArmUnwindUnwindPlan(*target);
38010b57cec5SDimitry Andric       if (arm_unwind_sp) {
38020b57cec5SDimitry Andric         result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
38030b57cec5SDimitry Andric         arm_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
38040b57cec5SDimitry Andric                             LLDB_INVALID_ADDRESS);
38050b57cec5SDimitry Andric         result.GetOutputStream().Printf("\n");
38060b57cec5SDimitry Andric       }
38070b57cec5SDimitry Andric 
38080b57cec5SDimitry Andric       if (UnwindPlanSP symfile_plan_sp =
38090b57cec5SDimitry Andric               func_unwinders_sp->GetSymbolFileUnwindPlan(*thread)) {
38100b57cec5SDimitry Andric         result.GetOutputStream().Printf("Symbol file UnwindPlan:\n");
38110b57cec5SDimitry Andric         symfile_plan_sp->Dump(result.GetOutputStream(), thread.get(),
38120b57cec5SDimitry Andric                               LLDB_INVALID_ADDRESS);
38130b57cec5SDimitry Andric         result.GetOutputStream().Printf("\n");
38140b57cec5SDimitry Andric       }
38150b57cec5SDimitry Andric 
38160b57cec5SDimitry Andric       UnwindPlanSP compact_unwind_sp =
38170b57cec5SDimitry Andric           func_unwinders_sp->GetCompactUnwindUnwindPlan(*target);
38180b57cec5SDimitry Andric       if (compact_unwind_sp) {
38190b57cec5SDimitry Andric         result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
38200b57cec5SDimitry Andric         compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
38210b57cec5SDimitry Andric                                 LLDB_INVALID_ADDRESS);
38220b57cec5SDimitry Andric         result.GetOutputStream().Printf("\n");
38230b57cec5SDimitry Andric       }
38240b57cec5SDimitry Andric 
38250b57cec5SDimitry Andric       if (fast_unwind_plan) {
38260b57cec5SDimitry Andric         result.GetOutputStream().Printf("Fast UnwindPlan:\n");
38270b57cec5SDimitry Andric         fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(),
38280b57cec5SDimitry Andric                                LLDB_INVALID_ADDRESS);
38290b57cec5SDimitry Andric         result.GetOutputStream().Printf("\n");
38300b57cec5SDimitry Andric       }
38310b57cec5SDimitry Andric 
38320b57cec5SDimitry Andric       ABISP abi_sp = process->GetABI();
38330b57cec5SDimitry Andric       if (abi_sp) {
38340b57cec5SDimitry Andric         UnwindPlan arch_default(lldb::eRegisterKindGeneric);
38350b57cec5SDimitry Andric         if (abi_sp->CreateDefaultUnwindPlan(arch_default)) {
38360b57cec5SDimitry Andric           result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
38370b57cec5SDimitry Andric           arch_default.Dump(result.GetOutputStream(), thread.get(),
38380b57cec5SDimitry Andric                             LLDB_INVALID_ADDRESS);
38390b57cec5SDimitry Andric           result.GetOutputStream().Printf("\n");
38400b57cec5SDimitry Andric         }
38410b57cec5SDimitry Andric 
38420b57cec5SDimitry Andric         UnwindPlan arch_entry(lldb::eRegisterKindGeneric);
38430b57cec5SDimitry Andric         if (abi_sp->CreateFunctionEntryUnwindPlan(arch_entry)) {
38440b57cec5SDimitry Andric           result.GetOutputStream().Printf(
38450b57cec5SDimitry Andric               "Arch default at entry point UnwindPlan:\n");
38460b57cec5SDimitry Andric           arch_entry.Dump(result.GetOutputStream(), thread.get(),
38470b57cec5SDimitry Andric                           LLDB_INVALID_ADDRESS);
38480b57cec5SDimitry Andric           result.GetOutputStream().Printf("\n");
38490b57cec5SDimitry Andric         }
38500b57cec5SDimitry Andric       }
38510b57cec5SDimitry Andric 
38520b57cec5SDimitry Andric       result.GetOutputStream().Printf("\n");
38530b57cec5SDimitry Andric     }
38540b57cec5SDimitry Andric   }
38550b57cec5SDimitry Andric 
38560b57cec5SDimitry Andric   CommandOptions m_options;
38570b57cec5SDimitry Andric };
38580b57cec5SDimitry Andric 
38590b57cec5SDimitry Andric // Lookup information in images
38609dba64beSDimitry Andric #define LLDB_OPTIONS_target_modules_lookup
38619dba64beSDimitry Andric #include "CommandOptions.inc"
38620b57cec5SDimitry Andric 
38630b57cec5SDimitry Andric class CommandObjectTargetModulesLookup : public CommandObjectParsed {
38640b57cec5SDimitry Andric public:
38650b57cec5SDimitry Andric   enum {
38660b57cec5SDimitry Andric     eLookupTypeInvalid = -1,
38670b57cec5SDimitry Andric     eLookupTypeAddress = 0,
38680b57cec5SDimitry Andric     eLookupTypeSymbol,
38690b57cec5SDimitry Andric     eLookupTypeFileLine, // Line is optional
38700b57cec5SDimitry Andric     eLookupTypeFunction,
38710b57cec5SDimitry Andric     eLookupTypeFunctionOrSymbol,
38720b57cec5SDimitry Andric     eLookupTypeType,
38730b57cec5SDimitry Andric     kNumLookupTypes
38740b57cec5SDimitry Andric   };
38750b57cec5SDimitry Andric 
38760b57cec5SDimitry Andric   class CommandOptions : public Options {
38770b57cec5SDimitry Andric   public:
CommandOptions()387804eeddc0SDimitry Andric     CommandOptions() { OptionParsingStarting(nullptr); }
38790b57cec5SDimitry Andric 
38800b57cec5SDimitry Andric     ~CommandOptions() override = default;
38810b57cec5SDimitry Andric 
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)38820b57cec5SDimitry Andric     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
38830b57cec5SDimitry Andric                           ExecutionContext *execution_context) override {
38840b57cec5SDimitry Andric       Status error;
38850b57cec5SDimitry Andric 
38860b57cec5SDimitry Andric       const int short_option = m_getopt_table[option_idx].val;
38870b57cec5SDimitry Andric 
38880b57cec5SDimitry Andric       switch (short_option) {
38890b57cec5SDimitry Andric       case 'a': {
38900b57cec5SDimitry Andric         m_type = eLookupTypeAddress;
38910b57cec5SDimitry Andric         m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
38920b57cec5SDimitry Andric                                             LLDB_INVALID_ADDRESS, &error);
38930b57cec5SDimitry Andric       } break;
38940b57cec5SDimitry Andric 
38950b57cec5SDimitry Andric       case 'o':
38960b57cec5SDimitry Andric         if (option_arg.getAsInteger(0, m_offset))
38970b57cec5SDimitry Andric           error.SetErrorStringWithFormat("invalid offset string '%s'",
38980b57cec5SDimitry Andric                                          option_arg.str().c_str());
38990b57cec5SDimitry Andric         break;
39000b57cec5SDimitry Andric 
39010b57cec5SDimitry Andric       case 's':
39025ffd83dbSDimitry Andric         m_str = std::string(option_arg);
39030b57cec5SDimitry Andric         m_type = eLookupTypeSymbol;
39040b57cec5SDimitry Andric         break;
39050b57cec5SDimitry Andric 
39060b57cec5SDimitry Andric       case 'f':
39070b57cec5SDimitry Andric         m_file.SetFile(option_arg, FileSpec::Style::native);
39080b57cec5SDimitry Andric         m_type = eLookupTypeFileLine;
39090b57cec5SDimitry Andric         break;
39100b57cec5SDimitry Andric 
39110b57cec5SDimitry Andric       case 'i':
39120b57cec5SDimitry Andric         m_include_inlines = false;
39130b57cec5SDimitry Andric         break;
39140b57cec5SDimitry Andric 
39150b57cec5SDimitry Andric       case 'l':
39160b57cec5SDimitry Andric         if (option_arg.getAsInteger(0, m_line_number))
39170b57cec5SDimitry Andric           error.SetErrorStringWithFormat("invalid line number string '%s'",
39180b57cec5SDimitry Andric                                          option_arg.str().c_str());
39190b57cec5SDimitry Andric         else if (m_line_number == 0)
39200b57cec5SDimitry Andric           error.SetErrorString("zero is an invalid line number");
39210b57cec5SDimitry Andric         m_type = eLookupTypeFileLine;
39220b57cec5SDimitry Andric         break;
39230b57cec5SDimitry Andric 
39240b57cec5SDimitry Andric       case 'F':
39255ffd83dbSDimitry Andric         m_str = std::string(option_arg);
39260b57cec5SDimitry Andric         m_type = eLookupTypeFunction;
39270b57cec5SDimitry Andric         break;
39280b57cec5SDimitry Andric 
39290b57cec5SDimitry Andric       case 'n':
39305ffd83dbSDimitry Andric         m_str = std::string(option_arg);
39310b57cec5SDimitry Andric         m_type = eLookupTypeFunctionOrSymbol;
39320b57cec5SDimitry Andric         break;
39330b57cec5SDimitry Andric 
39340b57cec5SDimitry Andric       case 't':
39355ffd83dbSDimitry Andric         m_str = std::string(option_arg);
39360b57cec5SDimitry Andric         m_type = eLookupTypeType;
39370b57cec5SDimitry Andric         break;
39380b57cec5SDimitry Andric 
39390b57cec5SDimitry Andric       case 'v':
39400b57cec5SDimitry Andric         m_verbose = true;
39410b57cec5SDimitry Andric         break;
39420b57cec5SDimitry Andric 
39430b57cec5SDimitry Andric       case 'A':
39440b57cec5SDimitry Andric         m_print_all = true;
39450b57cec5SDimitry Andric         break;
39460b57cec5SDimitry Andric 
39470b57cec5SDimitry Andric       case 'r':
39480b57cec5SDimitry Andric         m_use_regex = true;
39490b57cec5SDimitry Andric         break;
395081ad6265SDimitry Andric 
395181ad6265SDimitry Andric       case '\x01':
395281ad6265SDimitry Andric         m_all_ranges = true;
395381ad6265SDimitry Andric         break;
39549dba64beSDimitry Andric       default:
39559dba64beSDimitry Andric         llvm_unreachable("Unimplemented option");
39560b57cec5SDimitry Andric       }
39570b57cec5SDimitry Andric 
39580b57cec5SDimitry Andric       return error;
39590b57cec5SDimitry Andric     }
39600b57cec5SDimitry Andric 
OptionParsingStarting(ExecutionContext * execution_context)39610b57cec5SDimitry Andric     void OptionParsingStarting(ExecutionContext *execution_context) override {
39620b57cec5SDimitry Andric       m_type = eLookupTypeInvalid;
39630b57cec5SDimitry Andric       m_str.clear();
39640b57cec5SDimitry Andric       m_file.Clear();
39650b57cec5SDimitry Andric       m_addr = LLDB_INVALID_ADDRESS;
39660b57cec5SDimitry Andric       m_offset = 0;
39670b57cec5SDimitry Andric       m_line_number = 0;
39680b57cec5SDimitry Andric       m_use_regex = false;
39690b57cec5SDimitry Andric       m_include_inlines = true;
397081ad6265SDimitry Andric       m_all_ranges = false;
39710b57cec5SDimitry Andric       m_verbose = false;
39720b57cec5SDimitry Andric       m_print_all = false;
39730b57cec5SDimitry Andric     }
39740b57cec5SDimitry Andric 
OptionParsingFinished(ExecutionContext * execution_context)397581ad6265SDimitry Andric     Status OptionParsingFinished(ExecutionContext *execution_context) override {
397681ad6265SDimitry Andric       Status status;
397781ad6265SDimitry Andric       if (m_all_ranges && !m_verbose) {
397881ad6265SDimitry Andric         status.SetErrorString("--show-variable-ranges must be used in "
397981ad6265SDimitry Andric                               "conjunction with --verbose.");
398081ad6265SDimitry Andric       }
398181ad6265SDimitry Andric       return status;
398281ad6265SDimitry Andric     }
398381ad6265SDimitry Andric 
GetDefinitions()39840b57cec5SDimitry Andric     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3985bdd1243dSDimitry Andric       return llvm::ArrayRef(g_target_modules_lookup_options);
39860b57cec5SDimitry Andric     }
39870b57cec5SDimitry Andric 
39880b57cec5SDimitry Andric     int m_type;        // Should be a eLookupTypeXXX enum after parsing options
39890b57cec5SDimitry Andric     std::string m_str; // Holds name lookup
39900b57cec5SDimitry Andric     FileSpec m_file;   // Files for file lookups
39910b57cec5SDimitry Andric     lldb::addr_t m_addr; // Holds the address to lookup
39920b57cec5SDimitry Andric     lldb::addr_t
39930b57cec5SDimitry Andric         m_offset; // Subtract this offset from m_addr before doing lookups.
39940b57cec5SDimitry Andric     uint32_t m_line_number; // Line number for file+line lookups
39950b57cec5SDimitry Andric     bool m_use_regex;       // Name lookups in m_str are regular expressions.
39960b57cec5SDimitry Andric     bool m_include_inlines; // Check for inline entries when looking up by
39970b57cec5SDimitry Andric                             // file/line.
399881ad6265SDimitry Andric     bool m_all_ranges;      // Print all ranges or single range.
39990b57cec5SDimitry Andric     bool m_verbose;         // Enable verbose lookup info
40000b57cec5SDimitry Andric     bool m_print_all; // Print all matches, even in cases where there's a best
40010b57cec5SDimitry Andric                       // match.
40020b57cec5SDimitry Andric   };
40030b57cec5SDimitry Andric 
CommandObjectTargetModulesLookup(CommandInterpreter & interpreter)40040b57cec5SDimitry Andric   CommandObjectTargetModulesLookup(CommandInterpreter &interpreter)
40050b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "target modules lookup",
40060b57cec5SDimitry Andric                             "Look up information within executable and "
40070b57cec5SDimitry Andric                             "dependent shared library images.",
400804eeddc0SDimitry Andric                             nullptr, eCommandRequiresTarget) {
40090b57cec5SDimitry Andric     CommandArgumentEntry arg;
40100b57cec5SDimitry Andric     CommandArgumentData file_arg;
40110b57cec5SDimitry Andric 
40120b57cec5SDimitry Andric     // Define the first (and only) variant of this arg.
40130b57cec5SDimitry Andric     file_arg.arg_type = eArgTypeFilename;
40140b57cec5SDimitry Andric     file_arg.arg_repetition = eArgRepeatStar;
40150b57cec5SDimitry Andric 
40160b57cec5SDimitry Andric     // There is only one variant this argument could be; put it into the
40170b57cec5SDimitry Andric     // argument entry.
40180b57cec5SDimitry Andric     arg.push_back(file_arg);
40190b57cec5SDimitry Andric 
40200b57cec5SDimitry Andric     // Push the data for the first argument into the m_arguments vector.
40210b57cec5SDimitry Andric     m_arguments.push_back(arg);
40220b57cec5SDimitry Andric   }
40230b57cec5SDimitry Andric 
40240b57cec5SDimitry Andric   ~CommandObjectTargetModulesLookup() override = default;
40250b57cec5SDimitry Andric 
GetOptions()40260b57cec5SDimitry Andric   Options *GetOptions() override { return &m_options; }
40270b57cec5SDimitry Andric 
LookupHere(CommandInterpreter & interpreter,CommandReturnObject & result,bool & syntax_error)40280b57cec5SDimitry Andric   bool LookupHere(CommandInterpreter &interpreter, CommandReturnObject &result,
40290b57cec5SDimitry Andric                   bool &syntax_error) {
40300b57cec5SDimitry Andric     switch (m_options.m_type) {
40310b57cec5SDimitry Andric     case eLookupTypeAddress:
40320b57cec5SDimitry Andric     case eLookupTypeFileLine:
40330b57cec5SDimitry Andric     case eLookupTypeFunction:
40340b57cec5SDimitry Andric     case eLookupTypeFunctionOrSymbol:
40350b57cec5SDimitry Andric     case eLookupTypeSymbol:
40360b57cec5SDimitry Andric     default:
40370b57cec5SDimitry Andric       return false;
40380b57cec5SDimitry Andric     case eLookupTypeType:
40390b57cec5SDimitry Andric       break;
40400b57cec5SDimitry Andric     }
40410b57cec5SDimitry Andric 
40420b57cec5SDimitry Andric     StackFrameSP frame = m_exe_ctx.GetFrameSP();
40430b57cec5SDimitry Andric 
40440b57cec5SDimitry Andric     if (!frame)
40450b57cec5SDimitry Andric       return false;
40460b57cec5SDimitry Andric 
40470b57cec5SDimitry Andric     const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
40480b57cec5SDimitry Andric 
40490b57cec5SDimitry Andric     if (!sym_ctx.module_sp)
40500b57cec5SDimitry Andric       return false;
40510b57cec5SDimitry Andric 
40520b57cec5SDimitry Andric     switch (m_options.m_type) {
40530b57cec5SDimitry Andric     default:
40540b57cec5SDimitry Andric       return false;
40550b57cec5SDimitry Andric     case eLookupTypeType:
40560b57cec5SDimitry Andric       if (!m_options.m_str.empty()) {
4057e8d8bef9SDimitry Andric         if (LookupTypeHere(&GetSelectedTarget(), m_interpreter,
4058e8d8bef9SDimitry Andric                            result.GetOutputStream(), *sym_ctx.module_sp,
4059e8d8bef9SDimitry Andric                            m_options.m_str.c_str(), m_options.m_use_regex)) {
40600b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishResult);
40610b57cec5SDimitry Andric           return true;
40620b57cec5SDimitry Andric         }
40630b57cec5SDimitry Andric       }
40640b57cec5SDimitry Andric       break;
40650b57cec5SDimitry Andric     }
40660b57cec5SDimitry Andric 
4067480093f4SDimitry Andric     return false;
40680b57cec5SDimitry Andric   }
40690b57cec5SDimitry Andric 
LookupInModule(CommandInterpreter & interpreter,Module * module,CommandReturnObject & result,bool & syntax_error)40700b57cec5SDimitry Andric   bool LookupInModule(CommandInterpreter &interpreter, Module *module,
40710b57cec5SDimitry Andric                       CommandReturnObject &result, bool &syntax_error) {
40720b57cec5SDimitry Andric     switch (m_options.m_type) {
40730b57cec5SDimitry Andric     case eLookupTypeAddress:
40740b57cec5SDimitry Andric       if (m_options.m_addr != LLDB_INVALID_ADDRESS) {
40750b57cec5SDimitry Andric         if (LookupAddressInModule(
40760b57cec5SDimitry Andric                 m_interpreter, result.GetOutputStream(), module,
40770b57cec5SDimitry Andric                 eSymbolContextEverything |
40780b57cec5SDimitry Andric                     (m_options.m_verbose
40790b57cec5SDimitry Andric                          ? static_cast<int>(eSymbolContextVariable)
40800b57cec5SDimitry Andric                          : 0),
408181ad6265SDimitry Andric                 m_options.m_addr, m_options.m_offset, m_options.m_verbose,
408281ad6265SDimitry Andric                 m_options.m_all_ranges)) {
40830b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishResult);
40840b57cec5SDimitry Andric           return true;
40850b57cec5SDimitry Andric         }
40860b57cec5SDimitry Andric       }
40870b57cec5SDimitry Andric       break;
40880b57cec5SDimitry Andric 
40890b57cec5SDimitry Andric     case eLookupTypeSymbol:
40900b57cec5SDimitry Andric       if (!m_options.m_str.empty()) {
40910b57cec5SDimitry Andric         if (LookupSymbolInModule(m_interpreter, result.GetOutputStream(),
40920b57cec5SDimitry Andric                                  module, m_options.m_str.c_str(),
409381ad6265SDimitry Andric                                  m_options.m_use_regex, m_options.m_verbose,
409481ad6265SDimitry Andric                                  m_options.m_all_ranges)) {
40950b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishResult);
40960b57cec5SDimitry Andric           return true;
40970b57cec5SDimitry Andric         }
40980b57cec5SDimitry Andric       }
40990b57cec5SDimitry Andric       break;
41000b57cec5SDimitry Andric 
41010b57cec5SDimitry Andric     case eLookupTypeFileLine:
41020b57cec5SDimitry Andric       if (m_options.m_file) {
41030b57cec5SDimitry Andric         if (LookupFileAndLineInModule(
41040b57cec5SDimitry Andric                 m_interpreter, result.GetOutputStream(), module,
41050b57cec5SDimitry Andric                 m_options.m_file, m_options.m_line_number,
410681ad6265SDimitry Andric                 m_options.m_include_inlines, m_options.m_verbose,
410781ad6265SDimitry Andric                 m_options.m_all_ranges)) {
41080b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishResult);
41090b57cec5SDimitry Andric           return true;
41100b57cec5SDimitry Andric         }
41110b57cec5SDimitry Andric       }
41120b57cec5SDimitry Andric       break;
41130b57cec5SDimitry Andric 
41140b57cec5SDimitry Andric     case eLookupTypeFunctionOrSymbol:
41150b57cec5SDimitry Andric     case eLookupTypeFunction:
41160b57cec5SDimitry Andric       if (!m_options.m_str.empty()) {
4117349cc55cSDimitry Andric         ModuleFunctionSearchOptions function_options;
4118349cc55cSDimitry Andric         function_options.include_symbols =
4119349cc55cSDimitry Andric             m_options.m_type == eLookupTypeFunctionOrSymbol;
4120349cc55cSDimitry Andric         function_options.include_inlines = m_options.m_include_inlines;
4121349cc55cSDimitry Andric 
4122349cc55cSDimitry Andric         if (LookupFunctionInModule(m_interpreter, result.GetOutputStream(),
4123349cc55cSDimitry Andric                                    module, m_options.m_str.c_str(),
4124349cc55cSDimitry Andric                                    m_options.m_use_regex, function_options,
412581ad6265SDimitry Andric                                    m_options.m_verbose,
412681ad6265SDimitry Andric                                    m_options.m_all_ranges)) {
41270b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishResult);
41280b57cec5SDimitry Andric           return true;
41290b57cec5SDimitry Andric         }
41300b57cec5SDimitry Andric       }
41310b57cec5SDimitry Andric       break;
41320b57cec5SDimitry Andric 
41330b57cec5SDimitry Andric     case eLookupTypeType:
41340b57cec5SDimitry Andric       if (!m_options.m_str.empty()) {
4135e8d8bef9SDimitry Andric         if (LookupTypeInModule(
4136e8d8bef9SDimitry Andric                 &GetSelectedTarget(), m_interpreter, result.GetOutputStream(),
4137e8d8bef9SDimitry Andric                 module, m_options.m_str.c_str(), m_options.m_use_regex)) {
41380b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishResult);
41390b57cec5SDimitry Andric           return true;
41400b57cec5SDimitry Andric         }
41410b57cec5SDimitry Andric       }
41420b57cec5SDimitry Andric       break;
41430b57cec5SDimitry Andric 
41440b57cec5SDimitry Andric     default:
41450b57cec5SDimitry Andric       m_options.GenerateOptionUsage(
414681ad6265SDimitry Andric           result.GetErrorStream(), *this,
41470b57cec5SDimitry Andric           GetCommandInterpreter().GetDebugger().GetTerminalWidth());
41480b57cec5SDimitry Andric       syntax_error = true;
41490b57cec5SDimitry Andric       break;
41500b57cec5SDimitry Andric     }
41510b57cec5SDimitry Andric 
41520b57cec5SDimitry Andric     result.SetStatus(eReturnStatusFailed);
41530b57cec5SDimitry Andric     return false;
41540b57cec5SDimitry Andric   }
41550b57cec5SDimitry Andric 
41560b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)4157c9157d92SDimitry Andric   void DoExecute(Args &command, CommandReturnObject &result) override {
41589dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
41590b57cec5SDimitry Andric     bool syntax_error = false;
41600b57cec5SDimitry Andric     uint32_t i;
41610b57cec5SDimitry Andric     uint32_t num_successful_lookups = 0;
41620b57cec5SDimitry Andric     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
41630b57cec5SDimitry Andric     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
41640b57cec5SDimitry Andric     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
41650b57cec5SDimitry Andric     // Dump all sections for all modules images
41660b57cec5SDimitry Andric 
41670b57cec5SDimitry Andric     if (command.GetArgumentCount() == 0) {
41680b57cec5SDimitry Andric       ModuleSP current_module;
41690b57cec5SDimitry Andric 
41700b57cec5SDimitry Andric       // Where it is possible to look in the current symbol context first,
41710b57cec5SDimitry Andric       // try that.  If this search was successful and --all was not passed,
41720b57cec5SDimitry Andric       // don't print anything else.
41730b57cec5SDimitry Andric       if (LookupHere(m_interpreter, result, syntax_error)) {
41740b57cec5SDimitry Andric         result.GetOutputStream().EOL();
41750b57cec5SDimitry Andric         num_successful_lookups++;
41760b57cec5SDimitry Andric         if (!m_options.m_print_all) {
41770b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishResult);
4178c9157d92SDimitry Andric           return;
41790b57cec5SDimitry Andric         }
41800b57cec5SDimitry Andric       }
41810b57cec5SDimitry Andric 
41820b57cec5SDimitry Andric       // Dump all sections for all other modules
41830b57cec5SDimitry Andric 
41840b57cec5SDimitry Andric       const ModuleList &target_modules = target->GetImages();
41850b57cec5SDimitry Andric       std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
4186e8d8bef9SDimitry Andric       if (target_modules.GetSize() == 0) {
41870b57cec5SDimitry Andric         result.AppendError("the target has no associated executable images");
4188c9157d92SDimitry Andric         return;
41890b57cec5SDimitry Andric       }
4190e8d8bef9SDimitry Andric 
4191e8d8bef9SDimitry Andric       for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
4192e8d8bef9SDimitry Andric         if (module_sp != current_module &&
4193e8d8bef9SDimitry Andric             LookupInModule(m_interpreter, module_sp.get(), result,
4194e8d8bef9SDimitry Andric                            syntax_error)) {
4195e8d8bef9SDimitry Andric           result.GetOutputStream().EOL();
4196e8d8bef9SDimitry Andric           num_successful_lookups++;
4197e8d8bef9SDimitry Andric         }
4198e8d8bef9SDimitry Andric       }
41990b57cec5SDimitry Andric     } else {
42000b57cec5SDimitry Andric       // Dump specified images (by basename or fullpath)
42010b57cec5SDimitry Andric       const char *arg_cstr;
42020b57cec5SDimitry Andric       for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr &&
42030b57cec5SDimitry Andric                   !syntax_error;
42040b57cec5SDimitry Andric            ++i) {
42050b57cec5SDimitry Andric         ModuleList module_list;
42060b57cec5SDimitry Andric         const size_t num_matches =
42070b57cec5SDimitry Andric             FindModulesByName(target, arg_cstr, module_list, false);
42080b57cec5SDimitry Andric         if (num_matches > 0) {
42090b57cec5SDimitry Andric           for (size_t j = 0; j < num_matches; ++j) {
42100b57cec5SDimitry Andric             Module *module = module_list.GetModulePointerAtIndex(j);
42110b57cec5SDimitry Andric             if (module) {
42129dba64beSDimitry Andric               if (LookupInModule(m_interpreter, module, result, syntax_error)) {
42130b57cec5SDimitry Andric                 result.GetOutputStream().EOL();
42140b57cec5SDimitry Andric                 num_successful_lookups++;
42150b57cec5SDimitry Andric               }
42160b57cec5SDimitry Andric             }
42170b57cec5SDimitry Andric           }
42180b57cec5SDimitry Andric         } else
42190b57cec5SDimitry Andric           result.AppendWarningWithFormat(
42200b57cec5SDimitry Andric               "Unable to find an image that matches '%s'.\n", arg_cstr);
42210b57cec5SDimitry Andric       }
42220b57cec5SDimitry Andric     }
42230b57cec5SDimitry Andric 
42240b57cec5SDimitry Andric     if (num_successful_lookups > 0)
42250b57cec5SDimitry Andric       result.SetStatus(eReturnStatusSuccessFinishResult);
42260b57cec5SDimitry Andric     else
42270b57cec5SDimitry Andric       result.SetStatus(eReturnStatusFailed);
42280b57cec5SDimitry Andric   }
42290b57cec5SDimitry Andric 
42300b57cec5SDimitry Andric   CommandOptions m_options;
42310b57cec5SDimitry Andric };
42320b57cec5SDimitry Andric 
42330b57cec5SDimitry Andric #pragma mark CommandObjectMultiwordImageSearchPaths
42340b57cec5SDimitry Andric 
42350b57cec5SDimitry Andric // CommandObjectMultiwordImageSearchPaths
42360b57cec5SDimitry Andric 
42370b57cec5SDimitry Andric class CommandObjectTargetModulesImageSearchPaths
42380b57cec5SDimitry Andric     : public CommandObjectMultiword {
42390b57cec5SDimitry Andric public:
CommandObjectTargetModulesImageSearchPaths(CommandInterpreter & interpreter)42400b57cec5SDimitry Andric   CommandObjectTargetModulesImageSearchPaths(CommandInterpreter &interpreter)
42410b57cec5SDimitry Andric       : CommandObjectMultiword(
42420b57cec5SDimitry Andric             interpreter, "target modules search-paths",
42430b57cec5SDimitry Andric             "Commands for managing module search paths for a target.",
42440b57cec5SDimitry Andric             "target modules search-paths <subcommand> [<subcommand-options>]") {
42450b57cec5SDimitry Andric     LoadSubCommand(
42460b57cec5SDimitry Andric         "add", CommandObjectSP(
42470b57cec5SDimitry Andric                    new CommandObjectTargetModulesSearchPathsAdd(interpreter)));
42480b57cec5SDimitry Andric     LoadSubCommand(
42490b57cec5SDimitry Andric         "clear", CommandObjectSP(new CommandObjectTargetModulesSearchPathsClear(
42500b57cec5SDimitry Andric                      interpreter)));
42510b57cec5SDimitry Andric     LoadSubCommand(
42520b57cec5SDimitry Andric         "insert",
42530b57cec5SDimitry Andric         CommandObjectSP(
42540b57cec5SDimitry Andric             new CommandObjectTargetModulesSearchPathsInsert(interpreter)));
42550b57cec5SDimitry Andric     LoadSubCommand(
42560b57cec5SDimitry Andric         "list", CommandObjectSP(new CommandObjectTargetModulesSearchPathsList(
42570b57cec5SDimitry Andric                     interpreter)));
42580b57cec5SDimitry Andric     LoadSubCommand(
42590b57cec5SDimitry Andric         "query", CommandObjectSP(new CommandObjectTargetModulesSearchPathsQuery(
42600b57cec5SDimitry Andric                      interpreter)));
42610b57cec5SDimitry Andric   }
42620b57cec5SDimitry Andric 
42630b57cec5SDimitry Andric   ~CommandObjectTargetModulesImageSearchPaths() override = default;
42640b57cec5SDimitry Andric };
42650b57cec5SDimitry Andric 
42660b57cec5SDimitry Andric #pragma mark CommandObjectTargetModules
42670b57cec5SDimitry Andric 
42680b57cec5SDimitry Andric // CommandObjectTargetModules
42690b57cec5SDimitry Andric 
42700b57cec5SDimitry Andric class CommandObjectTargetModules : public CommandObjectMultiword {
42710b57cec5SDimitry Andric public:
42720b57cec5SDimitry Andric   // Constructors and Destructors
CommandObjectTargetModules(CommandInterpreter & interpreter)42730b57cec5SDimitry Andric   CommandObjectTargetModules(CommandInterpreter &interpreter)
42740b57cec5SDimitry Andric       : CommandObjectMultiword(interpreter, "target modules",
42750b57cec5SDimitry Andric                                "Commands for accessing information for one or "
42760b57cec5SDimitry Andric                                "more target modules.",
42770b57cec5SDimitry Andric                                "target modules <sub-command> ...") {
42780b57cec5SDimitry Andric     LoadSubCommand(
42790b57cec5SDimitry Andric         "add", CommandObjectSP(new CommandObjectTargetModulesAdd(interpreter)));
42800b57cec5SDimitry Andric     LoadSubCommand("load", CommandObjectSP(new CommandObjectTargetModulesLoad(
42810b57cec5SDimitry Andric                                interpreter)));
42820b57cec5SDimitry Andric     LoadSubCommand("dump", CommandObjectSP(new CommandObjectTargetModulesDump(
42830b57cec5SDimitry Andric                                interpreter)));
42840b57cec5SDimitry Andric     LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetModulesList(
42850b57cec5SDimitry Andric                                interpreter)));
42860b57cec5SDimitry Andric     LoadSubCommand(
42870b57cec5SDimitry Andric         "lookup",
42880b57cec5SDimitry Andric         CommandObjectSP(new CommandObjectTargetModulesLookup(interpreter)));
42890b57cec5SDimitry Andric     LoadSubCommand(
42900b57cec5SDimitry Andric         "search-paths",
42910b57cec5SDimitry Andric         CommandObjectSP(
42920b57cec5SDimitry Andric             new CommandObjectTargetModulesImageSearchPaths(interpreter)));
42930b57cec5SDimitry Andric     LoadSubCommand(
42940b57cec5SDimitry Andric         "show-unwind",
42950b57cec5SDimitry Andric         CommandObjectSP(new CommandObjectTargetModulesShowUnwind(interpreter)));
42960b57cec5SDimitry Andric   }
42970b57cec5SDimitry Andric 
42980b57cec5SDimitry Andric   ~CommandObjectTargetModules() override = default;
42990b57cec5SDimitry Andric 
43000b57cec5SDimitry Andric private:
43010b57cec5SDimitry Andric   // For CommandObjectTargetModules only
43025ffd83dbSDimitry Andric   CommandObjectTargetModules(const CommandObjectTargetModules &) = delete;
43035ffd83dbSDimitry Andric   const CommandObjectTargetModules &
43045ffd83dbSDimitry Andric   operator=(const CommandObjectTargetModules &) = delete;
43050b57cec5SDimitry Andric };
43060b57cec5SDimitry Andric 
43070b57cec5SDimitry Andric class CommandObjectTargetSymbolsAdd : public CommandObjectParsed {
43080b57cec5SDimitry Andric public:
CommandObjectTargetSymbolsAdd(CommandInterpreter & interpreter)43090b57cec5SDimitry Andric   CommandObjectTargetSymbolsAdd(CommandInterpreter &interpreter)
43100b57cec5SDimitry Andric       : CommandObjectParsed(
43110b57cec5SDimitry Andric             interpreter, "target symbols add",
43120b57cec5SDimitry Andric             "Add a debug symbol file to one of the target's current modules by "
43135ffd83dbSDimitry Andric             "specifying a path to a debug symbols file or by using the options "
43145ffd83dbSDimitry Andric             "to specify a module.",
43150b57cec5SDimitry Andric             "target symbols add <cmd-options> [<symfile>]",
43160b57cec5SDimitry Andric             eCommandRequiresTarget),
43170b57cec5SDimitry Andric         m_file_option(
4318fe013be4SDimitry Andric             LLDB_OPT_SET_1, false, "shlib", 's', lldb::eModuleCompletion,
4319fe013be4SDimitry Andric             eArgTypeShlibName,
43205ffd83dbSDimitry Andric             "Locate the debug symbols for the shared library specified by "
43215ffd83dbSDimitry Andric             "name."),
43220b57cec5SDimitry Andric         m_current_frame_option(
43230b57cec5SDimitry Andric             LLDB_OPT_SET_2, false, "frame", 'F',
4324349cc55cSDimitry Andric             "Locate the debug symbols for the currently selected frame.", false,
4325349cc55cSDimitry Andric             true),
4326349cc55cSDimitry Andric         m_current_stack_option(LLDB_OPT_SET_2, false, "stack", 'S',
4327349cc55cSDimitry Andric                                "Locate the debug symbols for every frame in "
4328349cc55cSDimitry Andric                                "the current call stack.",
43295ffd83dbSDimitry Andric                                false, true)
43300b57cec5SDimitry Andric 
43310b57cec5SDimitry Andric   {
43320b57cec5SDimitry Andric     m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
43330b57cec5SDimitry Andric                           LLDB_OPT_SET_1);
43340b57cec5SDimitry Andric     m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
43350b57cec5SDimitry Andric     m_option_group.Append(&m_current_frame_option, LLDB_OPT_SET_2,
43360b57cec5SDimitry Andric                           LLDB_OPT_SET_2);
4337349cc55cSDimitry Andric     m_option_group.Append(&m_current_stack_option, LLDB_OPT_SET_2,
4338349cc55cSDimitry Andric                           LLDB_OPT_SET_2);
43390b57cec5SDimitry Andric     m_option_group.Finalize();
434081ad6265SDimitry Andric     CommandArgumentData module_arg{eArgTypeShlibName, eArgRepeatPlain};
434181ad6265SDimitry Andric     m_arguments.push_back({module_arg});
43420b57cec5SDimitry Andric   }
43430b57cec5SDimitry Andric 
43440b57cec5SDimitry Andric   ~CommandObjectTargetSymbolsAdd() override = default;
43450b57cec5SDimitry Andric 
43469dba64beSDimitry Andric   void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)43479dba64beSDimitry Andric   HandleArgumentCompletion(CompletionRequest &request,
43480b57cec5SDimitry Andric                            OptionElementVector &opt_element_vector) override {
4349fe013be4SDimitry Andric     lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
4350fe013be4SDimitry Andric         GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr);
43510b57cec5SDimitry Andric   }
43520b57cec5SDimitry Andric 
GetOptions()43530b57cec5SDimitry Andric   Options *GetOptions() override { return &m_option_group; }
43540b57cec5SDimitry Andric 
43550b57cec5SDimitry Andric protected:
AddModuleSymbols(Target * target,ModuleSpec & module_spec,bool & flush,CommandReturnObject & result)43560b57cec5SDimitry Andric   bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush,
43570b57cec5SDimitry Andric                         CommandReturnObject &result) {
43580b57cec5SDimitry Andric     const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
4359480093f4SDimitry Andric     if (!symbol_fspec) {
4360480093f4SDimitry Andric       result.AppendError(
4361480093f4SDimitry Andric           "one or more executable image paths must be specified");
4362480093f4SDimitry Andric       return false;
4363480093f4SDimitry Andric     }
4364480093f4SDimitry Andric 
43650b57cec5SDimitry Andric     char symfile_path[PATH_MAX];
43660b57cec5SDimitry Andric     symbol_fspec.GetPath(symfile_path, sizeof(symfile_path));
43670b57cec5SDimitry Andric 
43680b57cec5SDimitry Andric     if (!module_spec.GetUUID().IsValid()) {
43690b57cec5SDimitry Andric       if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
4370bdd1243dSDimitry Andric         module_spec.GetFileSpec().SetFilename(symbol_fspec.GetFilename());
43710b57cec5SDimitry Andric     }
4372480093f4SDimitry Andric 
43735ffd83dbSDimitry Andric     // Now module_spec represents a symbol file for a module that might exist
43745ffd83dbSDimitry Andric     // in the current target.  Let's find possible matches.
43755ffd83dbSDimitry Andric     ModuleList matching_modules;
43760b57cec5SDimitry Andric 
43770b57cec5SDimitry Andric     // First extract all module specs from the symbol file
43780b57cec5SDimitry Andric     lldb_private::ModuleSpecList symfile_module_specs;
43790b57cec5SDimitry Andric     if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(),
43800b57cec5SDimitry Andric                                             0, 0, symfile_module_specs)) {
43810b57cec5SDimitry Andric       // Now extract the module spec that matches the target architecture
43820b57cec5SDimitry Andric       ModuleSpec target_arch_module_spec;
43830b57cec5SDimitry Andric       ModuleSpec symfile_module_spec;
43840b57cec5SDimitry Andric       target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
43850b57cec5SDimitry Andric       if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec,
43860b57cec5SDimitry Andric                                                       symfile_module_spec)) {
43870b57cec5SDimitry Andric         if (symfile_module_spec.GetUUID().IsValid()) {
43880b57cec5SDimitry Andric           // It has a UUID, look for this UUID in the target modules
43890b57cec5SDimitry Andric           ModuleSpec symfile_uuid_module_spec;
43900b57cec5SDimitry Andric           symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
43919dba64beSDimitry Andric           target->GetImages().FindModules(symfile_uuid_module_spec,
43925ffd83dbSDimitry Andric                                           matching_modules);
43930b57cec5SDimitry Andric         }
43940b57cec5SDimitry Andric       }
43950b57cec5SDimitry Andric 
43965ffd83dbSDimitry Andric       if (matching_modules.IsEmpty()) {
43975ffd83dbSDimitry Andric         // No matches yet.  Iterate through the module specs to find a UUID
43985ffd83dbSDimitry Andric         // value that we can match up to an image in our target.
43995ffd83dbSDimitry Andric         const size_t num_symfile_module_specs = symfile_module_specs.GetSize();
44005ffd83dbSDimitry Andric         for (size_t i = 0;
44015ffd83dbSDimitry Andric              i < num_symfile_module_specs && matching_modules.IsEmpty(); ++i) {
44020b57cec5SDimitry Andric           if (symfile_module_specs.GetModuleSpecAtIndex(
44030b57cec5SDimitry Andric                   i, symfile_module_spec)) {
44040b57cec5SDimitry Andric             if (symfile_module_spec.GetUUID().IsValid()) {
44055ffd83dbSDimitry Andric               // It has a UUID.  Look for this UUID in the target modules.
44060b57cec5SDimitry Andric               ModuleSpec symfile_uuid_module_spec;
44070b57cec5SDimitry Andric               symfile_uuid_module_spec.GetUUID() =
44080b57cec5SDimitry Andric                   symfile_module_spec.GetUUID();
44099dba64beSDimitry Andric               target->GetImages().FindModules(symfile_uuid_module_spec,
44105ffd83dbSDimitry Andric                                               matching_modules);
44110b57cec5SDimitry Andric             }
44120b57cec5SDimitry Andric           }
44130b57cec5SDimitry Andric         }
44140b57cec5SDimitry Andric       }
44150b57cec5SDimitry Andric     }
44160b57cec5SDimitry Andric 
44170b57cec5SDimitry Andric     // Just try to match up the file by basename if we have no matches at
44185ffd83dbSDimitry Andric     // this point.  For example, module foo might have symbols in foo.debug.
44195ffd83dbSDimitry Andric     if (matching_modules.IsEmpty())
44205ffd83dbSDimitry Andric       target->GetImages().FindModules(module_spec, matching_modules);
44210b57cec5SDimitry Andric 
44225ffd83dbSDimitry Andric     while (matching_modules.IsEmpty()) {
44230b57cec5SDimitry Andric       ConstString filename_no_extension(
44240b57cec5SDimitry Andric           module_spec.GetFileSpec().GetFileNameStrippingExtension());
4425480093f4SDimitry Andric       // Empty string returned, let's bail
44260b57cec5SDimitry Andric       if (!filename_no_extension)
44270b57cec5SDimitry Andric         break;
44280b57cec5SDimitry Andric 
4429480093f4SDimitry Andric       // Check if there was no extension to strip and the basename is the same
44300b57cec5SDimitry Andric       if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
44310b57cec5SDimitry Andric         break;
44320b57cec5SDimitry Andric 
4433480093f4SDimitry Andric       // Replace basename with one fewer extension
4434bdd1243dSDimitry Andric       module_spec.GetFileSpec().SetFilename(filename_no_extension);
44355ffd83dbSDimitry Andric       target->GetImages().FindModules(module_spec, matching_modules);
44360b57cec5SDimitry Andric     }
44370b57cec5SDimitry Andric 
44385ffd83dbSDimitry Andric     if (matching_modules.GetSize() > 1) {
44390b57cec5SDimitry Andric       result.AppendErrorWithFormat("multiple modules match symbol file '%s', "
44400b57cec5SDimitry Andric                                    "use the --uuid option to resolve the "
44410b57cec5SDimitry Andric                                    "ambiguity.\n",
44420b57cec5SDimitry Andric                                    symfile_path);
44435ffd83dbSDimitry Andric       return false;
44445ffd83dbSDimitry Andric     }
44455ffd83dbSDimitry Andric 
44465ffd83dbSDimitry Andric     if (matching_modules.GetSize() == 1) {
44475ffd83dbSDimitry Andric       ModuleSP module_sp(matching_modules.GetModuleAtIndex(0));
44480b57cec5SDimitry Andric 
44490b57cec5SDimitry Andric       // The module has not yet created its symbol vendor, we can just give
44500b57cec5SDimitry Andric       // the existing target module the symfile path to use for when it
44510b57cec5SDimitry Andric       // decides to create it!
44520b57cec5SDimitry Andric       module_sp->SetSymbolFileFileSpec(symbol_fspec);
44530b57cec5SDimitry Andric 
44549dba64beSDimitry Andric       SymbolFile *symbol_file =
44559dba64beSDimitry Andric           module_sp->GetSymbolFile(true, &result.GetErrorStream());
44560b57cec5SDimitry Andric       if (symbol_file) {
44570b57cec5SDimitry Andric         ObjectFile *object_file = symbol_file->GetObjectFile();
44580b57cec5SDimitry Andric         if (object_file && object_file->GetFileSpec() == symbol_fspec) {
44590b57cec5SDimitry Andric           // Provide feedback that the symfile has been successfully added.
44600b57cec5SDimitry Andric           const FileSpec &module_fs = module_sp->GetFileSpec();
44610b57cec5SDimitry Andric           result.AppendMessageWithFormat(
44620b57cec5SDimitry Andric               "symbol file '%s' has been added to '%s'\n", symfile_path,
44630b57cec5SDimitry Andric               module_fs.GetPath().c_str());
44640b57cec5SDimitry Andric 
44650b57cec5SDimitry Andric           // Let clients know something changed in the module if it is
44660b57cec5SDimitry Andric           // currently loaded
44670b57cec5SDimitry Andric           ModuleList module_list;
44680b57cec5SDimitry Andric           module_list.Append(module_sp);
44690b57cec5SDimitry Andric           target->SymbolsDidLoad(module_list);
44700b57cec5SDimitry Andric 
44710b57cec5SDimitry Andric           // Make sure we load any scripting resources that may be embedded
44720b57cec5SDimitry Andric           // in the debug info files in case the platform supports that.
44730b57cec5SDimitry Andric           Status error;
44740b57cec5SDimitry Andric           StreamString feedback_stream;
44750b57cec5SDimitry Andric           module_sp->LoadScriptingResourceInTarget(target, error,
4476fe013be4SDimitry Andric                                                    feedback_stream);
44770b57cec5SDimitry Andric           if (error.Fail() && error.AsCString())
44780b57cec5SDimitry Andric             result.AppendWarningWithFormat(
44790b57cec5SDimitry Andric                 "unable to load scripting data for module %s - error "
44800b57cec5SDimitry Andric                 "reported was %s",
44810b57cec5SDimitry Andric                 module_sp->GetFileSpec()
44820b57cec5SDimitry Andric                     .GetFileNameStrippingExtension()
44830b57cec5SDimitry Andric                     .GetCString(),
44840b57cec5SDimitry Andric                 error.AsCString());
44850b57cec5SDimitry Andric           else if (feedback_stream.GetSize())
44865ffd83dbSDimitry Andric             result.AppendWarning(feedback_stream.GetData());
44870b57cec5SDimitry Andric 
44880b57cec5SDimitry Andric           flush = true;
44890b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishResult);
44900b57cec5SDimitry Andric           return true;
44910b57cec5SDimitry Andric         }
44920b57cec5SDimitry Andric       }
44930b57cec5SDimitry Andric       // Clear the symbol file spec if anything went wrong
44940b57cec5SDimitry Andric       module_sp->SetSymbolFileFileSpec(FileSpec());
44950b57cec5SDimitry Andric     }
44960b57cec5SDimitry Andric 
44970b57cec5SDimitry Andric     StreamString ss_symfile_uuid;
4498480093f4SDimitry Andric     if (module_spec.GetUUID().IsValid()) {
4499480093f4SDimitry Andric       ss_symfile_uuid << " (";
4500fe013be4SDimitry Andric       module_spec.GetUUID().Dump(ss_symfile_uuid);
4501480093f4SDimitry Andric       ss_symfile_uuid << ')';
4502480093f4SDimitry Andric     }
45030b57cec5SDimitry Andric     result.AppendErrorWithFormat(
4504480093f4SDimitry Andric         "symbol file '%s'%s does not match any existing module%s\n",
45050b57cec5SDimitry Andric         symfile_path, ss_symfile_uuid.GetData(),
45065ffd83dbSDimitry Andric         !llvm::sys::fs::is_regular_file(symbol_fspec.GetPath())
45070b57cec5SDimitry Andric             ? "\n       please specify the full path to the symbol file"
45080b57cec5SDimitry Andric             : "");
45090b57cec5SDimitry Andric     return false;
45100b57cec5SDimitry Andric   }
45110b57cec5SDimitry Andric 
DownloadObjectAndSymbolFile(ModuleSpec & module_spec,CommandReturnObject & result,bool & flush)4512349cc55cSDimitry Andric   bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
4513349cc55cSDimitry Andric                                    CommandReturnObject &result, bool &flush) {
451481ad6265SDimitry Andric     Status error;
4515c9157d92SDimitry Andric     if (PluginManager::DownloadObjectAndSymbolFile(module_spec, error)) {
4516349cc55cSDimitry Andric       if (module_spec.GetSymbolFileSpec())
4517349cc55cSDimitry Andric         return AddModuleSymbols(m_exe_ctx.GetTargetPtr(), module_spec, flush,
4518349cc55cSDimitry Andric                                 result);
451981ad6265SDimitry Andric     } else {
452081ad6265SDimitry Andric       result.SetError(error);
4521349cc55cSDimitry Andric     }
4522349cc55cSDimitry Andric     return false;
4523349cc55cSDimitry Andric   }
4524349cc55cSDimitry Andric 
AddSymbolsForUUID(CommandReturnObject & result,bool & flush)4525349cc55cSDimitry Andric   bool AddSymbolsForUUID(CommandReturnObject &result, bool &flush) {
4526349cc55cSDimitry Andric     assert(m_uuid_option_group.GetOptionValue().OptionWasSet());
4527349cc55cSDimitry Andric 
4528349cc55cSDimitry Andric     ModuleSpec module_spec;
4529349cc55cSDimitry Andric     module_spec.GetUUID() =
4530349cc55cSDimitry Andric         m_uuid_option_group.GetOptionValue().GetCurrentValue();
4531349cc55cSDimitry Andric 
4532349cc55cSDimitry Andric     if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) {
4533349cc55cSDimitry Andric       StreamString error_strm;
4534349cc55cSDimitry Andric       error_strm.PutCString("unable to find debug symbols for UUID ");
4535fe013be4SDimitry Andric       module_spec.GetUUID().Dump(error_strm);
4536349cc55cSDimitry Andric       result.AppendError(error_strm.GetString());
4537349cc55cSDimitry Andric       return false;
4538349cc55cSDimitry Andric     }
4539349cc55cSDimitry Andric 
4540349cc55cSDimitry Andric     return true;
4541349cc55cSDimitry Andric   }
4542349cc55cSDimitry Andric 
AddSymbolsForFile(CommandReturnObject & result,bool & flush)4543349cc55cSDimitry Andric   bool AddSymbolsForFile(CommandReturnObject &result, bool &flush) {
4544349cc55cSDimitry Andric     assert(m_file_option.GetOptionValue().OptionWasSet());
4545349cc55cSDimitry Andric 
4546349cc55cSDimitry Andric     ModuleSpec module_spec;
4547349cc55cSDimitry Andric     module_spec.GetFileSpec() =
4548349cc55cSDimitry Andric         m_file_option.GetOptionValue().GetCurrentValue();
4549349cc55cSDimitry Andric 
4550349cc55cSDimitry Andric     Target *target = m_exe_ctx.GetTargetPtr();
4551349cc55cSDimitry Andric     ModuleSP module_sp(target->GetImages().FindFirstModule(module_spec));
4552349cc55cSDimitry Andric     if (module_sp) {
4553349cc55cSDimitry Andric       module_spec.GetFileSpec() = module_sp->GetFileSpec();
4554349cc55cSDimitry Andric       module_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec();
4555349cc55cSDimitry Andric       module_spec.GetUUID() = module_sp->GetUUID();
4556349cc55cSDimitry Andric       module_spec.GetArchitecture() = module_sp->GetArchitecture();
4557349cc55cSDimitry Andric     } else {
4558349cc55cSDimitry Andric       module_spec.GetArchitecture() = target->GetArchitecture();
4559349cc55cSDimitry Andric     }
4560349cc55cSDimitry Andric 
4561349cc55cSDimitry Andric     if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) {
4562349cc55cSDimitry Andric       StreamString error_strm;
4563349cc55cSDimitry Andric       error_strm.PutCString(
4564349cc55cSDimitry Andric           "unable to find debug symbols for the executable file ");
4565349cc55cSDimitry Andric       error_strm << module_spec.GetFileSpec();
4566349cc55cSDimitry Andric       result.AppendError(error_strm.GetString());
4567349cc55cSDimitry Andric       return false;
4568349cc55cSDimitry Andric     }
4569349cc55cSDimitry Andric 
4570349cc55cSDimitry Andric     return true;
4571349cc55cSDimitry Andric   }
4572349cc55cSDimitry Andric 
AddSymbolsForFrame(CommandReturnObject & result,bool & flush)4573349cc55cSDimitry Andric   bool AddSymbolsForFrame(CommandReturnObject &result, bool &flush) {
4574349cc55cSDimitry Andric     assert(m_current_frame_option.GetOptionValue().OptionWasSet());
4575349cc55cSDimitry Andric 
4576349cc55cSDimitry Andric     Process *process = m_exe_ctx.GetProcessPtr();
4577349cc55cSDimitry Andric     if (!process) {
4578349cc55cSDimitry Andric       result.AppendError(
4579349cc55cSDimitry Andric           "a process must exist in order to use the --frame option");
4580349cc55cSDimitry Andric       return false;
4581349cc55cSDimitry Andric     }
4582349cc55cSDimitry Andric 
4583349cc55cSDimitry Andric     const StateType process_state = process->GetState();
4584349cc55cSDimitry Andric     if (!StateIsStoppedState(process_state, true)) {
4585349cc55cSDimitry Andric       result.AppendErrorWithFormat("process is not stopped: %s",
4586349cc55cSDimitry Andric                                    StateAsCString(process_state));
4587349cc55cSDimitry Andric       return false;
4588349cc55cSDimitry Andric     }
4589349cc55cSDimitry Andric 
4590349cc55cSDimitry Andric     StackFrame *frame = m_exe_ctx.GetFramePtr();
4591349cc55cSDimitry Andric     if (!frame) {
4592349cc55cSDimitry Andric       result.AppendError("invalid current frame");
4593349cc55cSDimitry Andric       return false;
4594349cc55cSDimitry Andric     }
4595349cc55cSDimitry Andric 
4596349cc55cSDimitry Andric     ModuleSP frame_module_sp(
4597349cc55cSDimitry Andric         frame->GetSymbolContext(eSymbolContextModule).module_sp);
4598349cc55cSDimitry Andric     if (!frame_module_sp) {
4599349cc55cSDimitry Andric       result.AppendError("frame has no module");
4600349cc55cSDimitry Andric       return false;
4601349cc55cSDimitry Andric     }
4602349cc55cSDimitry Andric 
4603349cc55cSDimitry Andric     ModuleSpec module_spec;
4604349cc55cSDimitry Andric     module_spec.GetUUID() = frame_module_sp->GetUUID();
4605349cc55cSDimitry Andric 
4606349cc55cSDimitry Andric     if (FileSystem::Instance().Exists(frame_module_sp->GetPlatformFileSpec())) {
4607349cc55cSDimitry Andric       module_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
4608349cc55cSDimitry Andric       module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
4609349cc55cSDimitry Andric     }
4610349cc55cSDimitry Andric 
4611349cc55cSDimitry Andric     if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) {
4612349cc55cSDimitry Andric       result.AppendError("unable to find debug symbols for the current frame");
4613349cc55cSDimitry Andric       return false;
4614349cc55cSDimitry Andric     }
4615349cc55cSDimitry Andric 
4616349cc55cSDimitry Andric     return true;
4617349cc55cSDimitry Andric   }
4618349cc55cSDimitry Andric 
AddSymbolsForStack(CommandReturnObject & result,bool & flush)4619349cc55cSDimitry Andric   bool AddSymbolsForStack(CommandReturnObject &result, bool &flush) {
4620349cc55cSDimitry Andric     assert(m_current_stack_option.GetOptionValue().OptionWasSet());
4621349cc55cSDimitry Andric 
4622349cc55cSDimitry Andric     Process *process = m_exe_ctx.GetProcessPtr();
4623349cc55cSDimitry Andric     if (!process) {
4624349cc55cSDimitry Andric       result.AppendError(
4625349cc55cSDimitry Andric           "a process must exist in order to use the --stack option");
4626349cc55cSDimitry Andric       return false;
4627349cc55cSDimitry Andric     }
4628349cc55cSDimitry Andric 
4629349cc55cSDimitry Andric     const StateType process_state = process->GetState();
4630349cc55cSDimitry Andric     if (!StateIsStoppedState(process_state, true)) {
4631349cc55cSDimitry Andric       result.AppendErrorWithFormat("process is not stopped: %s",
4632349cc55cSDimitry Andric                                    StateAsCString(process_state));
4633349cc55cSDimitry Andric       return false;
4634349cc55cSDimitry Andric     }
4635349cc55cSDimitry Andric 
4636349cc55cSDimitry Andric     Thread *thread = m_exe_ctx.GetThreadPtr();
4637349cc55cSDimitry Andric     if (!thread) {
4638349cc55cSDimitry Andric       result.AppendError("invalid current thread");
4639349cc55cSDimitry Andric       return false;
4640349cc55cSDimitry Andric     }
4641349cc55cSDimitry Andric 
4642349cc55cSDimitry Andric     bool symbols_found = false;
4643349cc55cSDimitry Andric     uint32_t frame_count = thread->GetStackFrameCount();
4644349cc55cSDimitry Andric     for (uint32_t i = 0; i < frame_count; ++i) {
4645349cc55cSDimitry Andric       lldb::StackFrameSP frame_sp = thread->GetStackFrameAtIndex(i);
4646349cc55cSDimitry Andric 
4647349cc55cSDimitry Andric       ModuleSP frame_module_sp(
4648349cc55cSDimitry Andric           frame_sp->GetSymbolContext(eSymbolContextModule).module_sp);
4649349cc55cSDimitry Andric       if (!frame_module_sp)
4650349cc55cSDimitry Andric         continue;
4651349cc55cSDimitry Andric 
4652349cc55cSDimitry Andric       ModuleSpec module_spec;
4653349cc55cSDimitry Andric       module_spec.GetUUID() = frame_module_sp->GetUUID();
4654349cc55cSDimitry Andric 
4655349cc55cSDimitry Andric       if (FileSystem::Instance().Exists(
4656349cc55cSDimitry Andric               frame_module_sp->GetPlatformFileSpec())) {
4657349cc55cSDimitry Andric         module_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
4658349cc55cSDimitry Andric         module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
4659349cc55cSDimitry Andric       }
4660349cc55cSDimitry Andric 
4661349cc55cSDimitry Andric       bool current_frame_flush = false;
4662349cc55cSDimitry Andric       if (DownloadObjectAndSymbolFile(module_spec, result, current_frame_flush))
4663349cc55cSDimitry Andric         symbols_found = true;
4664349cc55cSDimitry Andric       flush |= current_frame_flush;
4665349cc55cSDimitry Andric     }
4666349cc55cSDimitry Andric 
4667349cc55cSDimitry Andric     if (!symbols_found) {
4668349cc55cSDimitry Andric       result.AppendError(
4669349cc55cSDimitry Andric           "unable to find debug symbols in the current call stack");
4670349cc55cSDimitry Andric       return false;
4671349cc55cSDimitry Andric     }
4672349cc55cSDimitry Andric 
4673349cc55cSDimitry Andric     return true;
4674349cc55cSDimitry Andric   }
4675349cc55cSDimitry Andric 
DoExecute(Args & args,CommandReturnObject & result)4676c9157d92SDimitry Andric   void DoExecute(Args &args, CommandReturnObject &result) override {
46770b57cec5SDimitry Andric     Target *target = m_exe_ctx.GetTargetPtr();
46780b57cec5SDimitry Andric     result.SetStatus(eReturnStatusFailed);
46790b57cec5SDimitry Andric     bool flush = false;
46800b57cec5SDimitry Andric     ModuleSpec module_spec;
46810b57cec5SDimitry Andric     const bool uuid_option_set =
46820b57cec5SDimitry Andric         m_uuid_option_group.GetOptionValue().OptionWasSet();
46830b57cec5SDimitry Andric     const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
46840b57cec5SDimitry Andric     const bool frame_option_set =
46850b57cec5SDimitry Andric         m_current_frame_option.GetOptionValue().OptionWasSet();
4686349cc55cSDimitry Andric     const bool stack_option_set =
4687349cc55cSDimitry Andric         m_current_stack_option.GetOptionValue().OptionWasSet();
46880b57cec5SDimitry Andric     const size_t argc = args.GetArgumentCount();
46890b57cec5SDimitry Andric 
46900b57cec5SDimitry Andric     if (argc == 0) {
4691349cc55cSDimitry Andric       if (uuid_option_set)
4692349cc55cSDimitry Andric         AddSymbolsForUUID(result, flush);
4693349cc55cSDimitry Andric       else if (file_option_set)
4694349cc55cSDimitry Andric         AddSymbolsForFile(result, flush);
4695349cc55cSDimitry Andric       else if (frame_option_set)
4696349cc55cSDimitry Andric         AddSymbolsForFrame(result, flush);
4697349cc55cSDimitry Andric       else if (stack_option_set)
4698349cc55cSDimitry Andric         AddSymbolsForStack(result, flush);
4699349cc55cSDimitry Andric       else
47000b57cec5SDimitry Andric         result.AppendError("one or more symbol file paths must be specified, "
47010b57cec5SDimitry Andric                            "or options must be specified");
47020b57cec5SDimitry Andric     } else {
47030b57cec5SDimitry Andric       if (uuid_option_set) {
47040b57cec5SDimitry Andric         result.AppendError("specify either one or more paths to symbol files "
47050b57cec5SDimitry Andric                            "or use the --uuid option without arguments");
47060b57cec5SDimitry Andric       } else if (frame_option_set) {
47070b57cec5SDimitry Andric         result.AppendError("specify either one or more paths to symbol files "
47080b57cec5SDimitry Andric                            "or use the --frame option without arguments");
47090b57cec5SDimitry Andric       } else if (file_option_set && argc > 1) {
47100b57cec5SDimitry Andric         result.AppendError("specify at most one symbol file path when "
47110b57cec5SDimitry Andric                            "--shlib option is set");
47120b57cec5SDimitry Andric       } else {
47130b57cec5SDimitry Andric         PlatformSP platform_sp(target->GetPlatform());
47140b57cec5SDimitry Andric 
47150b57cec5SDimitry Andric         for (auto &entry : args.entries()) {
47169dba64beSDimitry Andric           if (!entry.ref().empty()) {
47170b57cec5SDimitry Andric             auto &symbol_file_spec = module_spec.GetSymbolFileSpec();
47189dba64beSDimitry Andric             symbol_file_spec.SetFile(entry.ref(), FileSpec::Style::native);
47190b57cec5SDimitry Andric             FileSystem::Instance().Resolve(symbol_file_spec);
47200b57cec5SDimitry Andric             if (file_option_set) {
47210b57cec5SDimitry Andric               module_spec.GetFileSpec() =
47220b57cec5SDimitry Andric                   m_file_option.GetOptionValue().GetCurrentValue();
47230b57cec5SDimitry Andric             }
47240b57cec5SDimitry Andric             if (platform_sp) {
47250b57cec5SDimitry Andric               FileSpec symfile_spec;
47260b57cec5SDimitry Andric               if (platform_sp
47270b57cec5SDimitry Andric                       ->ResolveSymbolFile(*target, module_spec, symfile_spec)
47280b57cec5SDimitry Andric                       .Success())
47290b57cec5SDimitry Andric                 module_spec.GetSymbolFileSpec() = symfile_spec;
47300b57cec5SDimitry Andric             }
47310b57cec5SDimitry Andric 
47320b57cec5SDimitry Andric             bool symfile_exists =
47330b57cec5SDimitry Andric                 FileSystem::Instance().Exists(module_spec.GetSymbolFileSpec());
47340b57cec5SDimitry Andric 
47350b57cec5SDimitry Andric             if (symfile_exists) {
47360b57cec5SDimitry Andric               if (!AddModuleSymbols(target, module_spec, flush, result))
47370b57cec5SDimitry Andric                 break;
47380b57cec5SDimitry Andric             } else {
47390b57cec5SDimitry Andric               std::string resolved_symfile_path =
47400b57cec5SDimitry Andric                   module_spec.GetSymbolFileSpec().GetPath();
47419dba64beSDimitry Andric               if (resolved_symfile_path != entry.ref()) {
47420b57cec5SDimitry Andric                 result.AppendErrorWithFormat(
47430b57cec5SDimitry Andric                     "invalid module path '%s' with resolved path '%s'\n",
47440b57cec5SDimitry Andric                     entry.c_str(), resolved_symfile_path.c_str());
47450b57cec5SDimitry Andric                 break;
47460b57cec5SDimitry Andric               }
47470b57cec5SDimitry Andric               result.AppendErrorWithFormat("invalid module path '%s'\n",
47480b57cec5SDimitry Andric                                            entry.c_str());
47490b57cec5SDimitry Andric               break;
47500b57cec5SDimitry Andric             }
47510b57cec5SDimitry Andric           }
47520b57cec5SDimitry Andric         }
47530b57cec5SDimitry Andric       }
47540b57cec5SDimitry Andric     }
47550b57cec5SDimitry Andric 
47560b57cec5SDimitry Andric     if (flush) {
47570b57cec5SDimitry Andric       Process *process = m_exe_ctx.GetProcessPtr();
47580b57cec5SDimitry Andric       if (process)
47590b57cec5SDimitry Andric         process->Flush();
47600b57cec5SDimitry Andric     }
47610b57cec5SDimitry Andric   }
47620b57cec5SDimitry Andric 
47630b57cec5SDimitry Andric   OptionGroupOptions m_option_group;
47640b57cec5SDimitry Andric   OptionGroupUUID m_uuid_option_group;
47650b57cec5SDimitry Andric   OptionGroupFile m_file_option;
47660b57cec5SDimitry Andric   OptionGroupBoolean m_current_frame_option;
4767349cc55cSDimitry Andric   OptionGroupBoolean m_current_stack_option;
47680b57cec5SDimitry Andric };
47690b57cec5SDimitry Andric 
47700b57cec5SDimitry Andric #pragma mark CommandObjectTargetSymbols
47710b57cec5SDimitry Andric 
47720b57cec5SDimitry Andric // CommandObjectTargetSymbols
47730b57cec5SDimitry Andric 
47740b57cec5SDimitry Andric class CommandObjectTargetSymbols : public CommandObjectMultiword {
47750b57cec5SDimitry Andric public:
47760b57cec5SDimitry Andric   // Constructors and Destructors
CommandObjectTargetSymbols(CommandInterpreter & interpreter)47770b57cec5SDimitry Andric   CommandObjectTargetSymbols(CommandInterpreter &interpreter)
47780b57cec5SDimitry Andric       : CommandObjectMultiword(
47790b57cec5SDimitry Andric             interpreter, "target symbols",
47800b57cec5SDimitry Andric             "Commands for adding and managing debug symbol files.",
47810b57cec5SDimitry Andric             "target symbols <sub-command> ...") {
47820b57cec5SDimitry Andric     LoadSubCommand(
47830b57cec5SDimitry Andric         "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter)));
47840b57cec5SDimitry Andric   }
47850b57cec5SDimitry Andric 
47860b57cec5SDimitry Andric   ~CommandObjectTargetSymbols() override = default;
47870b57cec5SDimitry Andric 
47880b57cec5SDimitry Andric private:
47890b57cec5SDimitry Andric   // For CommandObjectTargetModules only
47905ffd83dbSDimitry Andric   CommandObjectTargetSymbols(const CommandObjectTargetSymbols &) = delete;
47915ffd83dbSDimitry Andric   const CommandObjectTargetSymbols &
47925ffd83dbSDimitry Andric   operator=(const CommandObjectTargetSymbols &) = delete;
47930b57cec5SDimitry Andric };
47940b57cec5SDimitry Andric 
47950b57cec5SDimitry Andric #pragma mark CommandObjectTargetStopHookAdd
47960b57cec5SDimitry Andric 
47970b57cec5SDimitry Andric // CommandObjectTargetStopHookAdd
47989dba64beSDimitry Andric #define LLDB_OPTIONS_target_stop_hook_add
47999dba64beSDimitry Andric #include "CommandOptions.inc"
48000b57cec5SDimitry Andric 
48010b57cec5SDimitry Andric class CommandObjectTargetStopHookAdd : public CommandObjectParsed,
48020b57cec5SDimitry Andric                                        public IOHandlerDelegateMultiline {
48030b57cec5SDimitry Andric public:
4804e8d8bef9SDimitry Andric   class CommandOptions : public OptionGroup {
48050b57cec5SDimitry Andric   public:
CommandOptions()480604eeddc0SDimitry Andric     CommandOptions() : m_line_end(UINT_MAX) {}
48070b57cec5SDimitry Andric 
48080b57cec5SDimitry Andric     ~CommandOptions() override = default;
48090b57cec5SDimitry Andric 
GetDefinitions()48100b57cec5SDimitry Andric     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
4811bdd1243dSDimitry Andric       return llvm::ArrayRef(g_target_stop_hook_add_options);
48120b57cec5SDimitry Andric     }
48130b57cec5SDimitry Andric 
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)48140b57cec5SDimitry Andric     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
48150b57cec5SDimitry Andric                           ExecutionContext *execution_context) override {
48160b57cec5SDimitry Andric       Status error;
4817e8d8bef9SDimitry Andric       const int short_option =
4818e8d8bef9SDimitry Andric           g_target_stop_hook_add_options[option_idx].short_option;
48190b57cec5SDimitry Andric 
48200b57cec5SDimitry Andric       switch (short_option) {
48210b57cec5SDimitry Andric       case 'c':
48225ffd83dbSDimitry Andric         m_class_name = std::string(option_arg);
48230b57cec5SDimitry Andric         m_sym_ctx_specified = true;
48240b57cec5SDimitry Andric         break;
48250b57cec5SDimitry Andric 
48260b57cec5SDimitry Andric       case 'e':
48270b57cec5SDimitry Andric         if (option_arg.getAsInteger(0, m_line_end)) {
48280b57cec5SDimitry Andric           error.SetErrorStringWithFormat("invalid end line number: \"%s\"",
48290b57cec5SDimitry Andric                                          option_arg.str().c_str());
48300b57cec5SDimitry Andric           break;
48310b57cec5SDimitry Andric         }
48320b57cec5SDimitry Andric         m_sym_ctx_specified = true;
48330b57cec5SDimitry Andric         break;
48340b57cec5SDimitry Andric 
48350b57cec5SDimitry Andric       case 'G': {
48360b57cec5SDimitry Andric         bool value, success;
48370b57cec5SDimitry Andric         value = OptionArgParser::ToBoolean(option_arg, false, &success);
48380b57cec5SDimitry Andric         if (success) {
48390b57cec5SDimitry Andric           m_auto_continue = value;
48400b57cec5SDimitry Andric         } else
48410b57cec5SDimitry Andric           error.SetErrorStringWithFormat(
48420b57cec5SDimitry Andric               "invalid boolean value '%s' passed for -G option",
48430b57cec5SDimitry Andric               option_arg.str().c_str());
4844480093f4SDimitry Andric       } break;
48450b57cec5SDimitry Andric       case 'l':
48460b57cec5SDimitry Andric         if (option_arg.getAsInteger(0, m_line_start)) {
48470b57cec5SDimitry Andric           error.SetErrorStringWithFormat("invalid start line number: \"%s\"",
48480b57cec5SDimitry Andric                                          option_arg.str().c_str());
48490b57cec5SDimitry Andric           break;
48500b57cec5SDimitry Andric         }
48510b57cec5SDimitry Andric         m_sym_ctx_specified = true;
48520b57cec5SDimitry Andric         break;
48530b57cec5SDimitry Andric 
48540b57cec5SDimitry Andric       case 'i':
48550b57cec5SDimitry Andric         m_no_inlines = true;
48560b57cec5SDimitry Andric         break;
48570b57cec5SDimitry Andric 
48580b57cec5SDimitry Andric       case 'n':
48595ffd83dbSDimitry Andric         m_function_name = std::string(option_arg);
48600b57cec5SDimitry Andric         m_func_name_type_mask |= eFunctionNameTypeAuto;
48610b57cec5SDimitry Andric         m_sym_ctx_specified = true;
48620b57cec5SDimitry Andric         break;
48630b57cec5SDimitry Andric 
48640b57cec5SDimitry Andric       case 'f':
48655ffd83dbSDimitry Andric         m_file_name = std::string(option_arg);
48660b57cec5SDimitry Andric         m_sym_ctx_specified = true;
48670b57cec5SDimitry Andric         break;
48680b57cec5SDimitry Andric 
48690b57cec5SDimitry Andric       case 's':
48705ffd83dbSDimitry Andric         m_module_name = std::string(option_arg);
48710b57cec5SDimitry Andric         m_sym_ctx_specified = true;
48720b57cec5SDimitry Andric         break;
48730b57cec5SDimitry Andric 
48740b57cec5SDimitry Andric       case 't':
48750b57cec5SDimitry Andric         if (option_arg.getAsInteger(0, m_thread_id))
48760b57cec5SDimitry Andric           error.SetErrorStringWithFormat("invalid thread id string '%s'",
48770b57cec5SDimitry Andric                                          option_arg.str().c_str());
48780b57cec5SDimitry Andric         m_thread_specified = true;
48790b57cec5SDimitry Andric         break;
48800b57cec5SDimitry Andric 
48810b57cec5SDimitry Andric       case 'T':
48825ffd83dbSDimitry Andric         m_thread_name = std::string(option_arg);
48830b57cec5SDimitry Andric         m_thread_specified = true;
48840b57cec5SDimitry Andric         break;
48850b57cec5SDimitry Andric 
48860b57cec5SDimitry Andric       case 'q':
48875ffd83dbSDimitry Andric         m_queue_name = std::string(option_arg);
48880b57cec5SDimitry Andric         m_thread_specified = true;
48890b57cec5SDimitry Andric         break;
48900b57cec5SDimitry Andric 
48910b57cec5SDimitry Andric       case 'x':
48920b57cec5SDimitry Andric         if (option_arg.getAsInteger(0, m_thread_index))
48930b57cec5SDimitry Andric           error.SetErrorStringWithFormat("invalid thread index string '%s'",
48940b57cec5SDimitry Andric                                          option_arg.str().c_str());
48950b57cec5SDimitry Andric         m_thread_specified = true;
48960b57cec5SDimitry Andric         break;
48970b57cec5SDimitry Andric 
48980b57cec5SDimitry Andric       case 'o':
48990b57cec5SDimitry Andric         m_use_one_liner = true;
49005ffd83dbSDimitry Andric         m_one_liner.push_back(std::string(option_arg));
49010b57cec5SDimitry Andric         break;
49020b57cec5SDimitry Andric 
49030b57cec5SDimitry Andric       default:
49049dba64beSDimitry Andric         llvm_unreachable("Unimplemented option");
49050b57cec5SDimitry Andric       }
49060b57cec5SDimitry Andric       return error;
49070b57cec5SDimitry Andric     }
49080b57cec5SDimitry Andric 
OptionParsingStarting(ExecutionContext * execution_context)49090b57cec5SDimitry Andric     void OptionParsingStarting(ExecutionContext *execution_context) override {
49100b57cec5SDimitry Andric       m_class_name.clear();
49110b57cec5SDimitry Andric       m_function_name.clear();
49120b57cec5SDimitry Andric       m_line_start = 0;
4913fcaf7f86SDimitry Andric       m_line_end = LLDB_INVALID_LINE_NUMBER;
49140b57cec5SDimitry Andric       m_file_name.clear();
49150b57cec5SDimitry Andric       m_module_name.clear();
49160b57cec5SDimitry Andric       m_func_name_type_mask = eFunctionNameTypeAuto;
49170b57cec5SDimitry Andric       m_thread_id = LLDB_INVALID_THREAD_ID;
49180b57cec5SDimitry Andric       m_thread_index = UINT32_MAX;
49190b57cec5SDimitry Andric       m_thread_name.clear();
49200b57cec5SDimitry Andric       m_queue_name.clear();
49210b57cec5SDimitry Andric 
49220b57cec5SDimitry Andric       m_no_inlines = false;
49230b57cec5SDimitry Andric       m_sym_ctx_specified = false;
49240b57cec5SDimitry Andric       m_thread_specified = false;
49250b57cec5SDimitry Andric 
49260b57cec5SDimitry Andric       m_use_one_liner = false;
49270b57cec5SDimitry Andric       m_one_liner.clear();
49280b57cec5SDimitry Andric       m_auto_continue = false;
49290b57cec5SDimitry Andric     }
49300b57cec5SDimitry Andric 
49310b57cec5SDimitry Andric     std::string m_class_name;
49320b57cec5SDimitry Andric     std::string m_function_name;
4933fe6060f1SDimitry Andric     uint32_t m_line_start = 0;
4934fcaf7f86SDimitry Andric     uint32_t m_line_end = LLDB_INVALID_LINE_NUMBER;
49350b57cec5SDimitry Andric     std::string m_file_name;
49360b57cec5SDimitry Andric     std::string m_module_name;
4937fe6060f1SDimitry Andric     uint32_t m_func_name_type_mask =
4938fe6060f1SDimitry Andric         eFunctionNameTypeAuto; // A pick from lldb::FunctionNameType.
4939fcaf7f86SDimitry Andric     lldb::tid_t m_thread_id = LLDB_INVALID_THREAD_ID;
4940fcaf7f86SDimitry Andric     uint32_t m_thread_index = UINT32_MAX;
49410b57cec5SDimitry Andric     std::string m_thread_name;
49420b57cec5SDimitry Andric     std::string m_queue_name;
4943fe6060f1SDimitry Andric     bool m_sym_ctx_specified = false;
4944fcaf7f86SDimitry Andric     bool m_no_inlines = false;
4945fe6060f1SDimitry Andric     bool m_thread_specified = false;
49460b57cec5SDimitry Andric     // Instance variables to hold the values for one_liner options.
4947fe6060f1SDimitry Andric     bool m_use_one_liner = false;
49480b57cec5SDimitry Andric     std::vector<std::string> m_one_liner;
4949e8d8bef9SDimitry Andric 
4950fcaf7f86SDimitry Andric     bool m_auto_continue = false;
49510b57cec5SDimitry Andric   };
49520b57cec5SDimitry Andric 
CommandObjectTargetStopHookAdd(CommandInterpreter & interpreter)49530b57cec5SDimitry Andric   CommandObjectTargetStopHookAdd(CommandInterpreter &interpreter)
49540b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "target stop-hook add",
4955e8d8bef9SDimitry Andric                             "Add a hook to be executed when the target stops."
4956e8d8bef9SDimitry Andric                             "The hook can either be a list of commands or an "
4957e8d8bef9SDimitry Andric                             "appropriately defined Python class.  You can also "
4958e8d8bef9SDimitry Andric                             "add filters so the hook only runs a certain stop "
4959e8d8bef9SDimitry Andric                             "points.",
49600b57cec5SDimitry Andric                             "target stop-hook add"),
49610b57cec5SDimitry Andric         IOHandlerDelegateMultiline("DONE",
49620b57cec5SDimitry Andric                                    IOHandlerDelegate::Completion::LLDBCommand),
496304eeddc0SDimitry Andric         m_python_class_options("scripted stop-hook", true, 'P') {
4964e8d8bef9SDimitry Andric     SetHelpLong(
4965e8d8bef9SDimitry Andric         R"(
4966e8d8bef9SDimitry Andric Command Based stop-hooks:
4967e8d8bef9SDimitry Andric -------------------------
4968e8d8bef9SDimitry Andric   Stop hooks can run a list of lldb commands by providing one or more
4969e8d8bef9SDimitry Andric   --one-line-command options.  The commands will get run in the order they are
4970e8d8bef9SDimitry Andric   added.  Or you can provide no commands, in which case you will enter a
4971e8d8bef9SDimitry Andric   command editor where you can enter the commands to be run.
4972e8d8bef9SDimitry Andric 
4973e8d8bef9SDimitry Andric Python Based Stop Hooks:
4974e8d8bef9SDimitry Andric ------------------------
4975e8d8bef9SDimitry Andric   Stop hooks can be implemented with a suitably defined Python class, whose name
4976e8d8bef9SDimitry Andric   is passed in the --python-class option.
4977e8d8bef9SDimitry Andric 
4978e8d8bef9SDimitry Andric   When the stop hook is added, the class is initialized by calling:
4979e8d8bef9SDimitry Andric 
4980fe6060f1SDimitry Andric     def __init__(self, target, extra_args, internal_dict):
4981e8d8bef9SDimitry Andric 
4982e8d8bef9SDimitry Andric     target: The target that the stop hook is being added to.
4983e8d8bef9SDimitry Andric     extra_args: An SBStructuredData Dictionary filled with the -key -value
4984e8d8bef9SDimitry Andric                 option pairs passed to the command.
4985e8d8bef9SDimitry Andric     dict: An implementation detail provided by lldb.
4986e8d8bef9SDimitry Andric 
4987e8d8bef9SDimitry Andric   Then when the stop-hook triggers, lldb will run the 'handle_stop' method.
4988e8d8bef9SDimitry Andric   The method has the signature:
4989e8d8bef9SDimitry Andric 
4990e8d8bef9SDimitry Andric     def handle_stop(self, exe_ctx, stream):
4991e8d8bef9SDimitry Andric 
4992e8d8bef9SDimitry Andric     exe_ctx: An SBExecutionContext for the thread that has stopped.
4993e8d8bef9SDimitry Andric     stream: An SBStream, anything written to this stream will be printed in the
4994e8d8bef9SDimitry Andric             the stop message when the process stops.
4995e8d8bef9SDimitry Andric 
4996e8d8bef9SDimitry Andric     Return Value: The method returns "should_stop".  If should_stop is false
4997e8d8bef9SDimitry Andric                   from all the stop hook executions on threads that stopped
4998e8d8bef9SDimitry Andric                   with a reason, then the process will continue.  Note that this
4999e8d8bef9SDimitry Andric                   will happen only after all the stop hooks are run.
5000e8d8bef9SDimitry Andric 
5001e8d8bef9SDimitry Andric Filter Options:
5002e8d8bef9SDimitry Andric ---------------
5003e8d8bef9SDimitry Andric   Stop hooks can be set to always run, or to only run when the stopped thread
5004e8d8bef9SDimitry Andric   matches the filter options passed on the command line.  The available filter
5005e8d8bef9SDimitry Andric   options include a shared library or a thread or queue specification,
5006e8d8bef9SDimitry Andric   a line range in a source file, a function name or a class name.
5007e8d8bef9SDimitry Andric             )");
5008e8d8bef9SDimitry Andric     m_all_options.Append(&m_python_class_options,
5009e8d8bef9SDimitry Andric                          LLDB_OPT_SET_1 | LLDB_OPT_SET_2,
5010e8d8bef9SDimitry Andric                          LLDB_OPT_SET_FROM_TO(4, 6));
5011e8d8bef9SDimitry Andric     m_all_options.Append(&m_options);
5012e8d8bef9SDimitry Andric     m_all_options.Finalize();
5013e8d8bef9SDimitry Andric   }
50140b57cec5SDimitry Andric 
50150b57cec5SDimitry Andric   ~CommandObjectTargetStopHookAdd() override = default;
50160b57cec5SDimitry Andric 
GetOptions()5017e8d8bef9SDimitry Andric   Options *GetOptions() override { return &m_all_options; }
50180b57cec5SDimitry Andric 
50190b57cec5SDimitry Andric protected:
IOHandlerActivated(IOHandler & io_handler,bool interactive)50200b57cec5SDimitry Andric   void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
50219dba64beSDimitry Andric     StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
50220b57cec5SDimitry Andric     if (output_sp && interactive) {
50230b57cec5SDimitry Andric       output_sp->PutCString(
50240b57cec5SDimitry Andric           "Enter your stop hook command(s).  Type 'DONE' to end.\n");
50250b57cec5SDimitry Andric       output_sp->Flush();
50260b57cec5SDimitry Andric     }
50270b57cec5SDimitry Andric   }
50280b57cec5SDimitry Andric 
IOHandlerInputComplete(IOHandler & io_handler,std::string & line)50290b57cec5SDimitry Andric   void IOHandlerInputComplete(IOHandler &io_handler,
50300b57cec5SDimitry Andric                               std::string &line) override {
50310b57cec5SDimitry Andric     if (m_stop_hook_sp) {
50320b57cec5SDimitry Andric       if (line.empty()) {
50339dba64beSDimitry Andric         StreamFileSP error_sp(io_handler.GetErrorStreamFileSP());
50340b57cec5SDimitry Andric         if (error_sp) {
50350b57cec5SDimitry Andric           error_sp->Printf("error: stop hook #%" PRIu64
50360b57cec5SDimitry Andric                            " aborted, no commands.\n",
50370b57cec5SDimitry Andric                            m_stop_hook_sp->GetID());
50380b57cec5SDimitry Andric           error_sp->Flush();
50390b57cec5SDimitry Andric         }
50400b57cec5SDimitry Andric         Target *target = GetDebugger().GetSelectedTarget().get();
5041e8d8bef9SDimitry Andric         if (target) {
5042e8d8bef9SDimitry Andric           target->UndoCreateStopHook(m_stop_hook_sp->GetID());
5043e8d8bef9SDimitry Andric         }
50440b57cec5SDimitry Andric       } else {
5045e8d8bef9SDimitry Andric         // The IOHandler editor is only for command lines stop hooks:
5046e8d8bef9SDimitry Andric         Target::StopHookCommandLine *hook_ptr =
5047e8d8bef9SDimitry Andric             static_cast<Target::StopHookCommandLine *>(m_stop_hook_sp.get());
5048e8d8bef9SDimitry Andric 
5049e8d8bef9SDimitry Andric         hook_ptr->SetActionFromString(line);
50509dba64beSDimitry Andric         StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
50510b57cec5SDimitry Andric         if (output_sp) {
50520b57cec5SDimitry Andric           output_sp->Printf("Stop hook #%" PRIu64 " added.\n",
50530b57cec5SDimitry Andric                             m_stop_hook_sp->GetID());
50540b57cec5SDimitry Andric           output_sp->Flush();
50550b57cec5SDimitry Andric         }
50560b57cec5SDimitry Andric       }
50570b57cec5SDimitry Andric       m_stop_hook_sp.reset();
50580b57cec5SDimitry Andric     }
50590b57cec5SDimitry Andric     io_handler.SetIsDone(true);
50600b57cec5SDimitry Andric   }
50610b57cec5SDimitry Andric 
DoExecute(Args & command,CommandReturnObject & result)5062c9157d92SDimitry Andric   void DoExecute(Args &command, CommandReturnObject &result) override {
50630b57cec5SDimitry Andric     m_stop_hook_sp.reset();
50640b57cec5SDimitry Andric 
50659dba64beSDimitry Andric     Target &target = GetSelectedOrDummyTarget();
5066e8d8bef9SDimitry Andric     Target::StopHookSP new_hook_sp =
5067e8d8bef9SDimitry Andric         target.CreateStopHook(m_python_class_options.GetName().empty() ?
5068e8d8bef9SDimitry Andric                                Target::StopHook::StopHookKind::CommandBased
5069e8d8bef9SDimitry Andric                                : Target::StopHook::StopHookKind::ScriptBased);
50700b57cec5SDimitry Andric 
50710b57cec5SDimitry Andric     //  First step, make the specifier.
50720b57cec5SDimitry Andric     std::unique_ptr<SymbolContextSpecifier> specifier_up;
50730b57cec5SDimitry Andric     if (m_options.m_sym_ctx_specified) {
50745ffd83dbSDimitry Andric       specifier_up = std::make_unique<SymbolContextSpecifier>(
50755ffd83dbSDimitry Andric           GetDebugger().GetSelectedTarget());
50760b57cec5SDimitry Andric 
50770b57cec5SDimitry Andric       if (!m_options.m_module_name.empty()) {
50780b57cec5SDimitry Andric         specifier_up->AddSpecification(
50790b57cec5SDimitry Andric             m_options.m_module_name.c_str(),
50800b57cec5SDimitry Andric             SymbolContextSpecifier::eModuleSpecified);
50810b57cec5SDimitry Andric       }
50820b57cec5SDimitry Andric 
50830b57cec5SDimitry Andric       if (!m_options.m_class_name.empty()) {
50840b57cec5SDimitry Andric         specifier_up->AddSpecification(
50850b57cec5SDimitry Andric             m_options.m_class_name.c_str(),
50860b57cec5SDimitry Andric             SymbolContextSpecifier::eClassOrNamespaceSpecified);
50870b57cec5SDimitry Andric       }
50880b57cec5SDimitry Andric 
50890b57cec5SDimitry Andric       if (!m_options.m_file_name.empty()) {
50909dba64beSDimitry Andric         specifier_up->AddSpecification(m_options.m_file_name.c_str(),
50910b57cec5SDimitry Andric                                        SymbolContextSpecifier::eFileSpecified);
50920b57cec5SDimitry Andric       }
50930b57cec5SDimitry Andric 
50940b57cec5SDimitry Andric       if (m_options.m_line_start != 0) {
50950b57cec5SDimitry Andric         specifier_up->AddLineSpecification(
50960b57cec5SDimitry Andric             m_options.m_line_start,
50970b57cec5SDimitry Andric             SymbolContextSpecifier::eLineStartSpecified);
50980b57cec5SDimitry Andric       }
50990b57cec5SDimitry Andric 
51000b57cec5SDimitry Andric       if (m_options.m_line_end != UINT_MAX) {
51010b57cec5SDimitry Andric         specifier_up->AddLineSpecification(
51020b57cec5SDimitry Andric             m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
51030b57cec5SDimitry Andric       }
51040b57cec5SDimitry Andric 
51050b57cec5SDimitry Andric       if (!m_options.m_function_name.empty()) {
51060b57cec5SDimitry Andric         specifier_up->AddSpecification(
51070b57cec5SDimitry Andric             m_options.m_function_name.c_str(),
51080b57cec5SDimitry Andric             SymbolContextSpecifier::eFunctionSpecified);
51090b57cec5SDimitry Andric       }
51100b57cec5SDimitry Andric     }
51110b57cec5SDimitry Andric 
51120b57cec5SDimitry Andric     if (specifier_up)
51130b57cec5SDimitry Andric       new_hook_sp->SetSpecifier(specifier_up.release());
51140b57cec5SDimitry Andric 
51150b57cec5SDimitry Andric     // Next see if any of the thread options have been entered:
51160b57cec5SDimitry Andric 
51170b57cec5SDimitry Andric     if (m_options.m_thread_specified) {
51180b57cec5SDimitry Andric       ThreadSpec *thread_spec = new ThreadSpec();
51190b57cec5SDimitry Andric 
51200b57cec5SDimitry Andric       if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) {
51210b57cec5SDimitry Andric         thread_spec->SetTID(m_options.m_thread_id);
51220b57cec5SDimitry Andric       }
51230b57cec5SDimitry Andric 
51240b57cec5SDimitry Andric       if (m_options.m_thread_index != UINT32_MAX)
51250b57cec5SDimitry Andric         thread_spec->SetIndex(m_options.m_thread_index);
51260b57cec5SDimitry Andric 
51270b57cec5SDimitry Andric       if (!m_options.m_thread_name.empty())
51280b57cec5SDimitry Andric         thread_spec->SetName(m_options.m_thread_name.c_str());
51290b57cec5SDimitry Andric 
51300b57cec5SDimitry Andric       if (!m_options.m_queue_name.empty())
51310b57cec5SDimitry Andric         thread_spec->SetQueueName(m_options.m_queue_name.c_str());
51320b57cec5SDimitry Andric 
51330b57cec5SDimitry Andric       new_hook_sp->SetThreadSpecifier(thread_spec);
51340b57cec5SDimitry Andric     }
51350b57cec5SDimitry Andric 
51360b57cec5SDimitry Andric     new_hook_sp->SetAutoContinue(m_options.m_auto_continue);
51370b57cec5SDimitry Andric     if (m_options.m_use_one_liner) {
5138e8d8bef9SDimitry Andric       // This is a command line stop hook:
5139e8d8bef9SDimitry Andric       Target::StopHookCommandLine *hook_ptr =
5140e8d8bef9SDimitry Andric           static_cast<Target::StopHookCommandLine *>(new_hook_sp.get());
5141e8d8bef9SDimitry Andric       hook_ptr->SetActionFromStrings(m_options.m_one_liner);
51420b57cec5SDimitry Andric       result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
51430b57cec5SDimitry Andric                                      new_hook_sp->GetID());
5144e8d8bef9SDimitry Andric     } else if (!m_python_class_options.GetName().empty()) {
5145e8d8bef9SDimitry Andric       // This is a scripted stop hook:
5146e8d8bef9SDimitry Andric       Target::StopHookScripted *hook_ptr =
5147e8d8bef9SDimitry Andric           static_cast<Target::StopHookScripted *>(new_hook_sp.get());
5148e8d8bef9SDimitry Andric       Status error = hook_ptr->SetScriptCallback(
5149e8d8bef9SDimitry Andric           m_python_class_options.GetName(),
5150e8d8bef9SDimitry Andric           m_python_class_options.GetStructuredData());
5151e8d8bef9SDimitry Andric       if (error.Success())
5152e8d8bef9SDimitry Andric         result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
5153e8d8bef9SDimitry Andric                                        new_hook_sp->GetID());
5154e8d8bef9SDimitry Andric       else {
5155e8d8bef9SDimitry Andric         // FIXME: Set the stop hook ID counter back.
5156e8d8bef9SDimitry Andric         result.AppendErrorWithFormat("Couldn't add stop hook: %s",
5157e8d8bef9SDimitry Andric                                      error.AsCString());
5158e8d8bef9SDimitry Andric         target.UndoCreateStopHook(new_hook_sp->GetID());
5159c9157d92SDimitry Andric         return;
5160e8d8bef9SDimitry Andric       }
51610b57cec5SDimitry Andric     } else {
51620b57cec5SDimitry Andric       m_stop_hook_sp = new_hook_sp;
5163480093f4SDimitry Andric       m_interpreter.GetLLDBCommandsFromIOHandler("> ",   // Prompt
5164480093f4SDimitry Andric                                                  *this); // IOHandlerDelegate
51650b57cec5SDimitry Andric     }
51660b57cec5SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishNoResult);
51670b57cec5SDimitry Andric   }
51680b57cec5SDimitry Andric 
51690b57cec5SDimitry Andric private:
51700b57cec5SDimitry Andric   CommandOptions m_options;
5171e8d8bef9SDimitry Andric   OptionGroupPythonClassWithDict m_python_class_options;
5172e8d8bef9SDimitry Andric   OptionGroupOptions m_all_options;
5173e8d8bef9SDimitry Andric 
51740b57cec5SDimitry Andric   Target::StopHookSP m_stop_hook_sp;
51750b57cec5SDimitry Andric };
51760b57cec5SDimitry Andric 
51770b57cec5SDimitry Andric #pragma mark CommandObjectTargetStopHookDelete
51780b57cec5SDimitry Andric 
51790b57cec5SDimitry Andric // CommandObjectTargetStopHookDelete
51800b57cec5SDimitry Andric 
51810b57cec5SDimitry Andric class CommandObjectTargetStopHookDelete : public CommandObjectParsed {
51820b57cec5SDimitry Andric public:
CommandObjectTargetStopHookDelete(CommandInterpreter & interpreter)51830b57cec5SDimitry Andric   CommandObjectTargetStopHookDelete(CommandInterpreter &interpreter)
51840b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "target stop-hook delete",
51850b57cec5SDimitry Andric                             "Delete a stop-hook.",
518681ad6265SDimitry Andric                             "target stop-hook delete [<idx>]") {
518781ad6265SDimitry Andric     CommandArgumentData hook_arg{eArgTypeStopHookID, eArgRepeatStar};
518881ad6265SDimitry Andric     m_arguments.push_back({hook_arg});
518981ad6265SDimitry Andric   }
51900b57cec5SDimitry Andric 
51910b57cec5SDimitry Andric   ~CommandObjectTargetStopHookDelete() override = default;
51920b57cec5SDimitry Andric 
5193e8d8bef9SDimitry Andric   void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)5194e8d8bef9SDimitry Andric   HandleArgumentCompletion(CompletionRequest &request,
5195e8d8bef9SDimitry Andric                            OptionElementVector &opt_element_vector) override {
5196c9157d92SDimitry Andric     if (request.GetCursorIndex())
5197c9157d92SDimitry Andric       return;
5198fe013be4SDimitry Andric     lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
5199fe013be4SDimitry Andric         GetCommandInterpreter(), lldb::eStopHookIDCompletion, request, nullptr);
5200e8d8bef9SDimitry Andric   }
5201e8d8bef9SDimitry Andric 
52020b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)5203c9157d92SDimitry Andric   void DoExecute(Args &command, CommandReturnObject &result) override {
52049dba64beSDimitry Andric     Target &target = GetSelectedOrDummyTarget();
52050b57cec5SDimitry Andric     // FIXME: see if we can use the breakpoint id style parser?
52060b57cec5SDimitry Andric     size_t num_args = command.GetArgumentCount();
52070b57cec5SDimitry Andric     if (num_args == 0) {
52080b57cec5SDimitry Andric       if (!m_interpreter.Confirm("Delete all stop hooks?", true)) {
52090b57cec5SDimitry Andric         result.SetStatus(eReturnStatusFailed);
5210c9157d92SDimitry Andric         return;
52110b57cec5SDimitry Andric       } else {
52129dba64beSDimitry Andric         target.RemoveAllStopHooks();
52130b57cec5SDimitry Andric       }
52140b57cec5SDimitry Andric     } else {
52150b57cec5SDimitry Andric       for (size_t i = 0; i < num_args; i++) {
52165ffd83dbSDimitry Andric         lldb::user_id_t user_id;
52175ffd83dbSDimitry Andric         if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
52180b57cec5SDimitry Andric           result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
52190b57cec5SDimitry Andric                                        command.GetArgumentAtIndex(i));
5220c9157d92SDimitry Andric           return;
52210b57cec5SDimitry Andric         }
52225ffd83dbSDimitry Andric         if (!target.RemoveStopHookByID(user_id)) {
52230b57cec5SDimitry Andric           result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
52240b57cec5SDimitry Andric                                        command.GetArgumentAtIndex(i));
5225c9157d92SDimitry Andric           return;
52260b57cec5SDimitry Andric         }
52270b57cec5SDimitry Andric       }
52280b57cec5SDimitry Andric     }
52290b57cec5SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishNoResult);
52300b57cec5SDimitry Andric   }
52310b57cec5SDimitry Andric };
52320b57cec5SDimitry Andric 
52330b57cec5SDimitry Andric #pragma mark CommandObjectTargetStopHookEnableDisable
52340b57cec5SDimitry Andric 
52350b57cec5SDimitry Andric // CommandObjectTargetStopHookEnableDisable
52360b57cec5SDimitry Andric 
52370b57cec5SDimitry Andric class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed {
52380b57cec5SDimitry Andric public:
CommandObjectTargetStopHookEnableDisable(CommandInterpreter & interpreter,bool enable,const char * name,const char * help,const char * syntax)52390b57cec5SDimitry Andric   CommandObjectTargetStopHookEnableDisable(CommandInterpreter &interpreter,
52400b57cec5SDimitry Andric                                            bool enable, const char *name,
52410b57cec5SDimitry Andric                                            const char *help, const char *syntax)
52420b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable) {
524381ad6265SDimitry Andric     CommandArgumentData hook_arg{eArgTypeStopHookID, eArgRepeatStar};
524481ad6265SDimitry Andric     m_arguments.push_back({hook_arg});
52450b57cec5SDimitry Andric   }
52460b57cec5SDimitry Andric 
52470b57cec5SDimitry Andric   ~CommandObjectTargetStopHookEnableDisable() override = default;
52480b57cec5SDimitry Andric 
5249e8d8bef9SDimitry Andric   void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)5250e8d8bef9SDimitry Andric   HandleArgumentCompletion(CompletionRequest &request,
5251e8d8bef9SDimitry Andric                            OptionElementVector &opt_element_vector) override {
5252e8d8bef9SDimitry Andric     if (request.GetCursorIndex())
5253e8d8bef9SDimitry Andric       return;
5254fe013be4SDimitry Andric     lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
5255fe013be4SDimitry Andric         GetCommandInterpreter(), lldb::eStopHookIDCompletion, request, nullptr);
5256e8d8bef9SDimitry Andric   }
5257e8d8bef9SDimitry Andric 
52580b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)5259c9157d92SDimitry Andric   void DoExecute(Args &command, CommandReturnObject &result) override {
52609dba64beSDimitry Andric     Target &target = GetSelectedOrDummyTarget();
52610b57cec5SDimitry Andric     // FIXME: see if we can use the breakpoint id style parser?
52620b57cec5SDimitry Andric     size_t num_args = command.GetArgumentCount();
52630b57cec5SDimitry Andric     bool success;
52640b57cec5SDimitry Andric 
52650b57cec5SDimitry Andric     if (num_args == 0) {
52669dba64beSDimitry Andric       target.SetAllStopHooksActiveState(m_enable);
52670b57cec5SDimitry Andric     } else {
52680b57cec5SDimitry Andric       for (size_t i = 0; i < num_args; i++) {
52695ffd83dbSDimitry Andric         lldb::user_id_t user_id;
52705ffd83dbSDimitry Andric         if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
52710b57cec5SDimitry Andric           result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
52720b57cec5SDimitry Andric                                        command.GetArgumentAtIndex(i));
5273c9157d92SDimitry Andric           return;
52740b57cec5SDimitry Andric         }
52759dba64beSDimitry Andric         success = target.SetStopHookActiveStateByID(user_id, m_enable);
52760b57cec5SDimitry Andric         if (!success) {
52770b57cec5SDimitry Andric           result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
52780b57cec5SDimitry Andric                                        command.GetArgumentAtIndex(i));
5279c9157d92SDimitry Andric           return;
52800b57cec5SDimitry Andric         }
52810b57cec5SDimitry Andric       }
52820b57cec5SDimitry Andric     }
52830b57cec5SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishNoResult);
52840b57cec5SDimitry Andric   }
52850b57cec5SDimitry Andric 
52860b57cec5SDimitry Andric private:
52870b57cec5SDimitry Andric   bool m_enable;
52880b57cec5SDimitry Andric };
52890b57cec5SDimitry Andric 
52900b57cec5SDimitry Andric #pragma mark CommandObjectTargetStopHookList
52910b57cec5SDimitry Andric 
52920b57cec5SDimitry Andric // CommandObjectTargetStopHookList
52930b57cec5SDimitry Andric 
52940b57cec5SDimitry Andric class CommandObjectTargetStopHookList : public CommandObjectParsed {
52950b57cec5SDimitry Andric public:
CommandObjectTargetStopHookList(CommandInterpreter & interpreter)52960b57cec5SDimitry Andric   CommandObjectTargetStopHookList(CommandInterpreter &interpreter)
52970b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "target stop-hook list",
529881ad6265SDimitry Andric                             "List all stop-hooks.", "target stop-hook list") {}
52990b57cec5SDimitry Andric 
53000b57cec5SDimitry Andric   ~CommandObjectTargetStopHookList() override = default;
53010b57cec5SDimitry Andric 
53020b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)5303c9157d92SDimitry Andric   void DoExecute(Args &command, CommandReturnObject &result) override {
53049dba64beSDimitry Andric     Target &target = GetSelectedOrDummyTarget();
53050b57cec5SDimitry Andric 
53069dba64beSDimitry Andric     size_t num_hooks = target.GetNumStopHooks();
53070b57cec5SDimitry Andric     if (num_hooks == 0) {
53080b57cec5SDimitry Andric       result.GetOutputStream().PutCString("No stop hooks.\n");
53090b57cec5SDimitry Andric     } else {
53100b57cec5SDimitry Andric       for (size_t i = 0; i < num_hooks; i++) {
53119dba64beSDimitry Andric         Target::StopHookSP this_hook = target.GetStopHookAtIndex(i);
53120b57cec5SDimitry Andric         if (i > 0)
53130b57cec5SDimitry Andric           result.GetOutputStream().PutCString("\n");
5314fe013be4SDimitry Andric         this_hook->GetDescription(result.GetOutputStream(),
53150b57cec5SDimitry Andric                                   eDescriptionLevelFull);
53160b57cec5SDimitry Andric       }
53170b57cec5SDimitry Andric     }
53180b57cec5SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishResult);
53190b57cec5SDimitry Andric   }
53200b57cec5SDimitry Andric };
53210b57cec5SDimitry Andric 
53220b57cec5SDimitry Andric #pragma mark CommandObjectMultiwordTargetStopHooks
53230b57cec5SDimitry Andric 
53240b57cec5SDimitry Andric // CommandObjectMultiwordTargetStopHooks
53250b57cec5SDimitry Andric 
53260b57cec5SDimitry Andric class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword {
53270b57cec5SDimitry Andric public:
CommandObjectMultiwordTargetStopHooks(CommandInterpreter & interpreter)53280b57cec5SDimitry Andric   CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter)
53290b57cec5SDimitry Andric       : CommandObjectMultiword(
53300b57cec5SDimitry Andric             interpreter, "target stop-hook",
53310b57cec5SDimitry Andric             "Commands for operating on debugger target stop-hooks.",
53320b57cec5SDimitry Andric             "target stop-hook <subcommand> [<subcommand-options>]") {
53330b57cec5SDimitry Andric     LoadSubCommand("add", CommandObjectSP(
53340b57cec5SDimitry Andric                               new CommandObjectTargetStopHookAdd(interpreter)));
53350b57cec5SDimitry Andric     LoadSubCommand(
53360b57cec5SDimitry Andric         "delete",
53370b57cec5SDimitry Andric         CommandObjectSP(new CommandObjectTargetStopHookDelete(interpreter)));
53380b57cec5SDimitry Andric     LoadSubCommand("disable",
53390b57cec5SDimitry Andric                    CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
53400b57cec5SDimitry Andric                        interpreter, false, "target stop-hook disable [<id>]",
53410b57cec5SDimitry Andric                        "Disable a stop-hook.", "target stop-hook disable")));
53420b57cec5SDimitry Andric     LoadSubCommand("enable",
53430b57cec5SDimitry Andric                    CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
53440b57cec5SDimitry Andric                        interpreter, true, "target stop-hook enable [<id>]",
53450b57cec5SDimitry Andric                        "Enable a stop-hook.", "target stop-hook enable")));
53460b57cec5SDimitry Andric     LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetStopHookList(
53470b57cec5SDimitry Andric                                interpreter)));
53480b57cec5SDimitry Andric   }
53490b57cec5SDimitry Andric 
53500b57cec5SDimitry Andric   ~CommandObjectMultiwordTargetStopHooks() override = default;
53510b57cec5SDimitry Andric };
53520b57cec5SDimitry Andric 
5353349cc55cSDimitry Andric #pragma mark CommandObjectTargetDumpTypesystem
5354349cc55cSDimitry Andric 
5355349cc55cSDimitry Andric /// Dumps the TypeSystem of the selected Target.
5356349cc55cSDimitry Andric class CommandObjectTargetDumpTypesystem : public CommandObjectParsed {
5357349cc55cSDimitry Andric public:
CommandObjectTargetDumpTypesystem(CommandInterpreter & interpreter)5358349cc55cSDimitry Andric   CommandObjectTargetDumpTypesystem(CommandInterpreter &interpreter)
5359349cc55cSDimitry Andric       : CommandObjectParsed(
5360349cc55cSDimitry Andric             interpreter, "target dump typesystem",
5361fe013be4SDimitry Andric             "Dump the state of the target's internal type system. Intended to "
5362fe013be4SDimitry Andric             "be used for debugging LLDB itself.",
5363349cc55cSDimitry Andric             nullptr, eCommandRequiresTarget) {}
5364349cc55cSDimitry Andric 
5365349cc55cSDimitry Andric   ~CommandObjectTargetDumpTypesystem() override = default;
5366349cc55cSDimitry Andric 
5367349cc55cSDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)5368c9157d92SDimitry Andric   void DoExecute(Args &command, CommandReturnObject &result) override {
5369349cc55cSDimitry Andric     // Go over every scratch TypeSystem and dump to the command output.
5370bdd1243dSDimitry Andric     for (lldb::TypeSystemSP ts : GetSelectedTarget().GetScratchTypeSystems())
5371bdd1243dSDimitry Andric       if (ts)
5372349cc55cSDimitry Andric         ts->Dump(result.GetOutputStream().AsRawOstream());
5373349cc55cSDimitry Andric 
5374349cc55cSDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishResult);
5375349cc55cSDimitry Andric   }
5376349cc55cSDimitry Andric };
5377349cc55cSDimitry Andric 
5378fe013be4SDimitry Andric #pragma mark CommandObjectTargetDumpSectionLoadList
5379fe013be4SDimitry Andric 
5380fe013be4SDimitry Andric /// Dumps the SectionLoadList of the selected Target.
5381fe013be4SDimitry Andric class CommandObjectTargetDumpSectionLoadList : public CommandObjectParsed {
5382fe013be4SDimitry Andric public:
CommandObjectTargetDumpSectionLoadList(CommandInterpreter & interpreter)5383fe013be4SDimitry Andric   CommandObjectTargetDumpSectionLoadList(CommandInterpreter &interpreter)
5384fe013be4SDimitry Andric       : CommandObjectParsed(
5385fe013be4SDimitry Andric             interpreter, "target dump section-load-list",
5386fe013be4SDimitry Andric             "Dump the state of the target's internal section load list. "
5387fe013be4SDimitry Andric             "Intended to be used for debugging LLDB itself.",
5388fe013be4SDimitry Andric             nullptr, eCommandRequiresTarget) {}
5389fe013be4SDimitry Andric 
5390fe013be4SDimitry Andric   ~CommandObjectTargetDumpSectionLoadList() override = default;
5391fe013be4SDimitry Andric 
5392fe013be4SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)5393c9157d92SDimitry Andric   void DoExecute(Args &command, CommandReturnObject &result) override {
5394fe013be4SDimitry Andric     Target &target = GetSelectedTarget();
5395fe013be4SDimitry Andric     target.GetSectionLoadList().Dump(result.GetOutputStream(), &target);
5396fe013be4SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishResult);
5397fe013be4SDimitry Andric   }
5398fe013be4SDimitry Andric };
5399fe013be4SDimitry Andric 
5400349cc55cSDimitry Andric #pragma mark CommandObjectTargetDump
5401349cc55cSDimitry Andric 
5402349cc55cSDimitry Andric /// Multi-word command for 'target dump'.
5403349cc55cSDimitry Andric class CommandObjectTargetDump : public CommandObjectMultiword {
5404349cc55cSDimitry Andric public:
5405349cc55cSDimitry Andric   // Constructors and Destructors
CommandObjectTargetDump(CommandInterpreter & interpreter)5406349cc55cSDimitry Andric   CommandObjectTargetDump(CommandInterpreter &interpreter)
5407349cc55cSDimitry Andric       : CommandObjectMultiword(
5408349cc55cSDimitry Andric             interpreter, "target dump",
5409349cc55cSDimitry Andric             "Commands for dumping information about the target.",
5410fe013be4SDimitry Andric             "target dump [typesystem|section-load-list]") {
5411349cc55cSDimitry Andric     LoadSubCommand(
5412349cc55cSDimitry Andric         "typesystem",
5413349cc55cSDimitry Andric         CommandObjectSP(new CommandObjectTargetDumpTypesystem(interpreter)));
5414fe013be4SDimitry Andric     LoadSubCommand("section-load-list",
5415fe013be4SDimitry Andric                    CommandObjectSP(new CommandObjectTargetDumpSectionLoadList(
5416fe013be4SDimitry Andric                        interpreter)));
5417349cc55cSDimitry Andric   }
5418349cc55cSDimitry Andric 
5419349cc55cSDimitry Andric   ~CommandObjectTargetDump() override = default;
5420349cc55cSDimitry Andric };
5421349cc55cSDimitry Andric 
54220b57cec5SDimitry Andric #pragma mark CommandObjectMultiwordTarget
54230b57cec5SDimitry Andric 
54240b57cec5SDimitry Andric // CommandObjectMultiwordTarget
54250b57cec5SDimitry Andric 
CommandObjectMultiwordTarget(CommandInterpreter & interpreter)54260b57cec5SDimitry Andric CommandObjectMultiwordTarget::CommandObjectMultiwordTarget(
54270b57cec5SDimitry Andric     CommandInterpreter &interpreter)
54280b57cec5SDimitry Andric     : CommandObjectMultiword(interpreter, "target",
54290b57cec5SDimitry Andric                              "Commands for operating on debugger targets.",
54300b57cec5SDimitry Andric                              "target <subcommand> [<subcommand-options>]") {
54310b57cec5SDimitry Andric   LoadSubCommand("create",
54320b57cec5SDimitry Andric                  CommandObjectSP(new CommandObjectTargetCreate(interpreter)));
54330b57cec5SDimitry Andric   LoadSubCommand("delete",
54340b57cec5SDimitry Andric                  CommandObjectSP(new CommandObjectTargetDelete(interpreter)));
5435349cc55cSDimitry Andric   LoadSubCommand("dump",
5436349cc55cSDimitry Andric                  CommandObjectSP(new CommandObjectTargetDump(interpreter)));
54370b57cec5SDimitry Andric   LoadSubCommand("list",
54380b57cec5SDimitry Andric                  CommandObjectSP(new CommandObjectTargetList(interpreter)));
54390b57cec5SDimitry Andric   LoadSubCommand("select",
54400b57cec5SDimitry Andric                  CommandObjectSP(new CommandObjectTargetSelect(interpreter)));
54415ffd83dbSDimitry Andric   LoadSubCommand("show-launch-environment",
54425ffd83dbSDimitry Andric                  CommandObjectSP(new CommandObjectTargetShowLaunchEnvironment(
54435ffd83dbSDimitry Andric                      interpreter)));
54440b57cec5SDimitry Andric   LoadSubCommand(
54450b57cec5SDimitry Andric       "stop-hook",
54460b57cec5SDimitry Andric       CommandObjectSP(new CommandObjectMultiwordTargetStopHooks(interpreter)));
54470b57cec5SDimitry Andric   LoadSubCommand("modules",
54480b57cec5SDimitry Andric                  CommandObjectSP(new CommandObjectTargetModules(interpreter)));
54490b57cec5SDimitry Andric   LoadSubCommand("symbols",
54500b57cec5SDimitry Andric                  CommandObjectSP(new CommandObjectTargetSymbols(interpreter)));
54510b57cec5SDimitry Andric   LoadSubCommand("variable",
54520b57cec5SDimitry Andric                  CommandObjectSP(new CommandObjectTargetVariable(interpreter)));
54530b57cec5SDimitry Andric }
54540b57cec5SDimitry Andric 
54550b57cec5SDimitry Andric CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget() = default;
5456