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 
110b57cec5SDimitry Andric #include "lldb/Core/Debugger.h"
120b57cec5SDimitry Andric #include "lldb/Core/IOHandler.h"
130b57cec5SDimitry Andric #include "lldb/Core/Module.h"
140b57cec5SDimitry Andric #include "lldb/Core/ModuleSpec.h"
150b57cec5SDimitry Andric #include "lldb/Core/Section.h"
160b57cec5SDimitry Andric #include "lldb/Core/ValueObjectVariable.h"
170b57cec5SDimitry Andric #include "lldb/DataFormatters/ValueObjectPrinter.h"
180b57cec5SDimitry Andric #include "lldb/Host/OptionParser.h"
190b57cec5SDimitry Andric #include "lldb/Interpreter/CommandInterpreter.h"
20fcaf7f86SDimitry Andric #include "lldb/Interpreter/CommandOptionArgumentTable.h"
210b57cec5SDimitry Andric #include "lldb/Interpreter/CommandReturnObject.h"
220b57cec5SDimitry Andric #include "lldb/Interpreter/OptionArgParser.h"
230b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupArchitecture.h"
240b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupBoolean.h"
250b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupFile.h"
260b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupFormat.h"
27e8d8bef9SDimitry Andric #include "lldb/Interpreter/OptionGroupPlatform.h"
28e8d8bef9SDimitry Andric #include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
290b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupString.h"
300b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupUInt64.h"
310b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupUUID.h"
320b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
330b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupVariable.h"
340b57cec5SDimitry Andric #include "lldb/Interpreter/Options.h"
350b57cec5SDimitry Andric #include "lldb/Symbol/CompileUnit.h"
360b57cec5SDimitry Andric #include "lldb/Symbol/FuncUnwinders.h"
370b57cec5SDimitry Andric #include "lldb/Symbol/LineTable.h"
380b57cec5SDimitry Andric #include "lldb/Symbol/LocateSymbolFile.h"
390b57cec5SDimitry Andric #include "lldb/Symbol/ObjectFile.h"
400b57cec5SDimitry Andric #include "lldb/Symbol/SymbolFile.h"
410b57cec5SDimitry Andric #include "lldb/Symbol/UnwindPlan.h"
420b57cec5SDimitry Andric #include "lldb/Symbol/VariableList.h"
430b57cec5SDimitry Andric #include "lldb/Target/ABI.h"
440b57cec5SDimitry Andric #include "lldb/Target/Process.h"
450b57cec5SDimitry Andric #include "lldb/Target/RegisterContext.h"
460b57cec5SDimitry Andric #include "lldb/Target/SectionLoadList.h"
470b57cec5SDimitry Andric #include "lldb/Target/StackFrame.h"
480b57cec5SDimitry Andric #include "lldb/Target/Thread.h"
490b57cec5SDimitry Andric #include "lldb/Target/ThreadSpec.h"
500b57cec5SDimitry Andric #include "lldb/Utility/Args.h"
51753f127fSDimitry Andric #include "lldb/Utility/ConstString.h"
52753f127fSDimitry Andric #include "lldb/Utility/FileSpec.h"
5381ad6265SDimitry Andric #include "lldb/Utility/LLDBLog.h"
540b57cec5SDimitry Andric #include "lldb/Utility/State.h"
550b57cec5SDimitry Andric #include "lldb/Utility/Timer.h"
5681ad6265SDimitry Andric #include "lldb/lldb-enumerations.h"
5781ad6265SDimitry Andric #include "lldb/lldb-private-enumerations.h"
580b57cec5SDimitry Andric 
59753f127fSDimitry Andric #include "clang/CodeGen/ObjectFilePCHContainerOperations.h"
60753f127fSDimitry Andric #include "clang/Frontend/CompilerInstance.h"
61753f127fSDimitry Andric #include "clang/Frontend/CompilerInvocation.h"
62753f127fSDimitry Andric #include "clang/Frontend/FrontendActions.h"
63e8d8bef9SDimitry Andric #include "llvm/ADT/ScopeExit.h"
640b57cec5SDimitry Andric #include "llvm/Support/FileSystem.h"
650b57cec5SDimitry Andric #include "llvm/Support/FormatAdapters.h"
660b57cec5SDimitry Andric 
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric using namespace lldb;
690b57cec5SDimitry Andric using namespace lldb_private;
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric static void DumpTargetInfo(uint32_t target_idx, Target *target,
720b57cec5SDimitry Andric                            const char *prefix_cstr,
730b57cec5SDimitry Andric                            bool show_stopped_process_status, Stream &strm) {
740b57cec5SDimitry Andric   const ArchSpec &target_arch = target->GetArchitecture();
750b57cec5SDimitry Andric 
760b57cec5SDimitry Andric   Module *exe_module = target->GetExecutableModulePointer();
770b57cec5SDimitry Andric   char exe_path[PATH_MAX];
780b57cec5SDimitry Andric   bool exe_valid = false;
790b57cec5SDimitry Andric   if (exe_module)
800b57cec5SDimitry Andric     exe_valid = exe_module->GetFileSpec().GetPath(exe_path, sizeof(exe_path));
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric   if (!exe_valid)
830b57cec5SDimitry Andric     ::strcpy(exe_path, "<none>");
840b57cec5SDimitry Andric 
85*fe013be4SDimitry Andric   std::string formatted_label = "";
86*fe013be4SDimitry Andric   const std::string &label = target->GetLabel();
87*fe013be4SDimitry Andric   if (!label.empty()) {
88*fe013be4SDimitry Andric     formatted_label = " (" + label + ")";
89*fe013be4SDimitry Andric   }
90*fe013be4SDimitry Andric 
91*fe013be4SDimitry Andric   strm.Printf("%starget #%u%s: %s", prefix_cstr ? prefix_cstr : "", target_idx,
92*fe013be4SDimitry Andric               formatted_label.data(), exe_path);
930b57cec5SDimitry Andric 
940b57cec5SDimitry Andric   uint32_t properties = 0;
950b57cec5SDimitry Andric   if (target_arch.IsValid()) {
960b57cec5SDimitry Andric     strm.Printf("%sarch=", properties++ > 0 ? ", " : " ( ");
97480093f4SDimitry Andric     target_arch.DumpTriple(strm.AsRawOstream());
980b57cec5SDimitry Andric     properties++;
990b57cec5SDimitry Andric   }
1000b57cec5SDimitry Andric   PlatformSP platform_sp(target->GetPlatform());
1010b57cec5SDimitry Andric   if (platform_sp)
10281ad6265SDimitry Andric     strm.Format("{0}platform={1}", properties++ > 0 ? ", " : " ( ",
10381ad6265SDimitry Andric                 platform_sp->GetName());
1040b57cec5SDimitry Andric 
1050b57cec5SDimitry Andric   ProcessSP process_sp(target->GetProcessSP());
1060b57cec5SDimitry Andric   bool show_process_status = false;
1070b57cec5SDimitry Andric   if (process_sp) {
1080b57cec5SDimitry Andric     lldb::pid_t pid = process_sp->GetID();
1090b57cec5SDimitry Andric     StateType state = process_sp->GetState();
1100b57cec5SDimitry Andric     if (show_stopped_process_status)
1110b57cec5SDimitry Andric       show_process_status = StateIsStoppedState(state, true);
1120b57cec5SDimitry Andric     const char *state_cstr = StateAsCString(state);
1130b57cec5SDimitry Andric     if (pid != LLDB_INVALID_PROCESS_ID)
1140b57cec5SDimitry Andric       strm.Printf("%spid=%" PRIu64, properties++ > 0 ? ", " : " ( ", pid);
1150b57cec5SDimitry Andric     strm.Printf("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
1160b57cec5SDimitry Andric   }
1170b57cec5SDimitry Andric   if (properties > 0)
1180b57cec5SDimitry Andric     strm.PutCString(" )\n");
1190b57cec5SDimitry Andric   else
1200b57cec5SDimitry Andric     strm.EOL();
1210b57cec5SDimitry Andric   if (show_process_status) {
1220b57cec5SDimitry Andric     const bool only_threads_with_stop_reason = true;
1230b57cec5SDimitry Andric     const uint32_t start_frame = 0;
1240b57cec5SDimitry Andric     const uint32_t num_frames = 1;
1250b57cec5SDimitry Andric     const uint32_t num_frames_with_source = 1;
1260b57cec5SDimitry Andric     const bool stop_format = false;
1270b57cec5SDimitry Andric     process_sp->GetStatus(strm);
1280b57cec5SDimitry Andric     process_sp->GetThreadStatus(strm, only_threads_with_stop_reason,
129480093f4SDimitry Andric                                 start_frame, num_frames, num_frames_with_source,
130480093f4SDimitry Andric                                 stop_format);
1310b57cec5SDimitry Andric   }
1320b57cec5SDimitry Andric }
1330b57cec5SDimitry Andric 
1340b57cec5SDimitry Andric static uint32_t DumpTargetList(TargetList &target_list,
1350b57cec5SDimitry Andric                                bool show_stopped_process_status, Stream &strm) {
1360b57cec5SDimitry Andric   const uint32_t num_targets = target_list.GetNumTargets();
1370b57cec5SDimitry Andric   if (num_targets) {
1380b57cec5SDimitry Andric     TargetSP selected_target_sp(target_list.GetSelectedTarget());
1390b57cec5SDimitry Andric     strm.PutCString("Current targets:\n");
1400b57cec5SDimitry Andric     for (uint32_t i = 0; i < num_targets; ++i) {
1410b57cec5SDimitry Andric       TargetSP target_sp(target_list.GetTargetAtIndex(i));
1420b57cec5SDimitry Andric       if (target_sp) {
1430b57cec5SDimitry Andric         bool is_selected = target_sp.get() == selected_target_sp.get();
1440b57cec5SDimitry Andric         DumpTargetInfo(i, target_sp.get(), is_selected ? "* " : "  ",
1450b57cec5SDimitry Andric                        show_stopped_process_status, strm);
1460b57cec5SDimitry Andric       }
1470b57cec5SDimitry Andric     }
1480b57cec5SDimitry Andric   }
1490b57cec5SDimitry Andric   return num_targets;
1500b57cec5SDimitry Andric }
1510b57cec5SDimitry Andric 
1529dba64beSDimitry Andric #define LLDB_OPTIONS_target_dependents
1539dba64beSDimitry Andric #include "CommandOptions.inc"
1540b57cec5SDimitry Andric 
1550b57cec5SDimitry Andric class OptionGroupDependents : public OptionGroup {
1560b57cec5SDimitry Andric public:
157fe6060f1SDimitry Andric   OptionGroupDependents() = default;
1580b57cec5SDimitry Andric 
159fe6060f1SDimitry Andric   ~OptionGroupDependents() override = default;
1600b57cec5SDimitry Andric 
1610b57cec5SDimitry Andric   llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
162bdd1243dSDimitry Andric     return llvm::ArrayRef(g_target_dependents_options);
1630b57cec5SDimitry Andric   }
1640b57cec5SDimitry Andric 
1650b57cec5SDimitry Andric   Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
1660b57cec5SDimitry Andric                         ExecutionContext *execution_context) override {
1670b57cec5SDimitry Andric     Status error;
1680b57cec5SDimitry Andric 
1690b57cec5SDimitry Andric     // For compatibility no value means don't load dependents.
1700b57cec5SDimitry Andric     if (option_value.empty()) {
1710b57cec5SDimitry Andric       m_load_dependent_files = eLoadDependentsNo;
1720b57cec5SDimitry Andric       return error;
1730b57cec5SDimitry Andric     }
1740b57cec5SDimitry Andric 
1759dba64beSDimitry Andric     const char short_option =
1769dba64beSDimitry Andric         g_target_dependents_options[option_idx].short_option;
1770b57cec5SDimitry Andric     if (short_option == 'd') {
1780b57cec5SDimitry Andric       LoadDependentFiles tmp_load_dependents;
1790b57cec5SDimitry Andric       tmp_load_dependents = (LoadDependentFiles)OptionArgParser::ToOptionEnum(
1809dba64beSDimitry Andric           option_value, g_target_dependents_options[option_idx].enum_values, 0,
1819dba64beSDimitry Andric           error);
1820b57cec5SDimitry Andric       if (error.Success())
1830b57cec5SDimitry Andric         m_load_dependent_files = tmp_load_dependents;
1840b57cec5SDimitry Andric     } else {
1850b57cec5SDimitry Andric       error.SetErrorStringWithFormat("unrecognized short option '%c'",
1860b57cec5SDimitry Andric                                      short_option);
1870b57cec5SDimitry Andric     }
1880b57cec5SDimitry Andric 
1890b57cec5SDimitry Andric     return error;
1900b57cec5SDimitry Andric   }
1910b57cec5SDimitry Andric 
1920b57cec5SDimitry Andric   Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete;
1930b57cec5SDimitry Andric 
1940b57cec5SDimitry Andric   void OptionParsingStarting(ExecutionContext *execution_context) override {
1950b57cec5SDimitry Andric     m_load_dependent_files = eLoadDependentsDefault;
1960b57cec5SDimitry Andric   }
1970b57cec5SDimitry Andric 
1980b57cec5SDimitry Andric   LoadDependentFiles m_load_dependent_files;
1990b57cec5SDimitry Andric 
2000b57cec5SDimitry Andric private:
2015ffd83dbSDimitry Andric   OptionGroupDependents(const OptionGroupDependents &) = delete;
2025ffd83dbSDimitry Andric   const OptionGroupDependents &
2035ffd83dbSDimitry Andric   operator=(const OptionGroupDependents &) = delete;
2040b57cec5SDimitry Andric };
2050b57cec5SDimitry Andric 
2060b57cec5SDimitry Andric #pragma mark CommandObjectTargetCreate
2070b57cec5SDimitry Andric 
2080b57cec5SDimitry Andric class CommandObjectTargetCreate : public CommandObjectParsed {
2090b57cec5SDimitry Andric public:
2100b57cec5SDimitry Andric   CommandObjectTargetCreate(CommandInterpreter &interpreter)
2110b57cec5SDimitry Andric       : CommandObjectParsed(
2120b57cec5SDimitry Andric             interpreter, "target create",
2130b57cec5SDimitry Andric             "Create a target using the argument as the main executable.",
2140b57cec5SDimitry Andric             nullptr),
215e8d8bef9SDimitry Andric         m_platform_options(true), // Include the --platform option.
2160b57cec5SDimitry Andric         m_core_file(LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename,
2170b57cec5SDimitry Andric                     "Fullpath to a core file to use for this target."),
218*fe013be4SDimitry Andric         m_label(LLDB_OPT_SET_1, false, "label", 'l', 0, eArgTypeName,
219*fe013be4SDimitry Andric                 "Optional name for this target.", nullptr),
2200b57cec5SDimitry Andric         m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
2210b57cec5SDimitry Andric                       eArgTypeFilename,
2220b57cec5SDimitry Andric                       "Fullpath to a stand alone debug "
2230b57cec5SDimitry Andric                       "symbols file for when debug symbols "
2240b57cec5SDimitry Andric                       "are not in the executable."),
2250b57cec5SDimitry Andric         m_remote_file(
2260b57cec5SDimitry Andric             LLDB_OPT_SET_1, false, "remote-file", 'r', 0, eArgTypeFilename,
22704eeddc0SDimitry Andric             "Fullpath to the file on the remote host if debugging remotely.") {
2280b57cec5SDimitry Andric     CommandArgumentEntry arg;
2290b57cec5SDimitry Andric     CommandArgumentData file_arg;
2300b57cec5SDimitry Andric 
2310b57cec5SDimitry Andric     // Define the first (and only) variant of this arg.
2320b57cec5SDimitry Andric     file_arg.arg_type = eArgTypeFilename;
2330b57cec5SDimitry Andric     file_arg.arg_repetition = eArgRepeatPlain;
2340b57cec5SDimitry Andric 
2350b57cec5SDimitry Andric     // There is only one variant this argument could be; put it into the
2360b57cec5SDimitry Andric     // argument entry.
2370b57cec5SDimitry Andric     arg.push_back(file_arg);
2380b57cec5SDimitry Andric 
2390b57cec5SDimitry Andric     // Push the data for the first argument into the m_arguments vector.
2400b57cec5SDimitry Andric     m_arguments.push_back(arg);
2410b57cec5SDimitry Andric 
2420b57cec5SDimitry Andric     m_option_group.Append(&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
243e8d8bef9SDimitry Andric     m_option_group.Append(&m_platform_options, LLDB_OPT_SET_ALL, 1);
2440b57cec5SDimitry Andric     m_option_group.Append(&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
245*fe013be4SDimitry Andric     m_option_group.Append(&m_label, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2460b57cec5SDimitry Andric     m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2470b57cec5SDimitry Andric     m_option_group.Append(&m_remote_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2480b57cec5SDimitry Andric     m_option_group.Append(&m_add_dependents, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2490b57cec5SDimitry Andric     m_option_group.Finalize();
2500b57cec5SDimitry Andric   }
2510b57cec5SDimitry Andric 
2520b57cec5SDimitry Andric   ~CommandObjectTargetCreate() override = default;
2530b57cec5SDimitry Andric 
2540b57cec5SDimitry Andric   Options *GetOptions() override { return &m_option_group; }
2550b57cec5SDimitry Andric 
2569dba64beSDimitry Andric   void
2579dba64beSDimitry Andric   HandleArgumentCompletion(CompletionRequest &request,
2580b57cec5SDimitry Andric                            OptionElementVector &opt_element_vector) override {
259*fe013be4SDimitry Andric     lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
260*fe013be4SDimitry Andric         GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr);
2610b57cec5SDimitry Andric   }
2620b57cec5SDimitry Andric 
2630b57cec5SDimitry Andric protected:
2640b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
2650b57cec5SDimitry Andric     const size_t argc = command.GetArgumentCount();
2660b57cec5SDimitry Andric     FileSpec core_file(m_core_file.GetOptionValue().GetCurrentValue());
2670b57cec5SDimitry Andric     FileSpec remote_file(m_remote_file.GetOptionValue().GetCurrentValue());
2680b57cec5SDimitry Andric 
2690b57cec5SDimitry Andric     if (core_file) {
2705ffd83dbSDimitry Andric       auto file = FileSystem::Instance().Open(
271349cc55cSDimitry Andric           core_file, lldb_private::File::eOpenOptionReadOnly);
2725ffd83dbSDimitry Andric 
2735ffd83dbSDimitry Andric       if (!file) {
2745ffd83dbSDimitry Andric         result.AppendErrorWithFormatv("Cannot open '{0}': {1}.",
2755ffd83dbSDimitry Andric                                       core_file.GetPath(),
2765ffd83dbSDimitry Andric                                       llvm::toString(file.takeError()));
2770b57cec5SDimitry Andric         return false;
2780b57cec5SDimitry Andric       }
2790b57cec5SDimitry Andric     }
2800b57cec5SDimitry Andric 
2810b57cec5SDimitry Andric     if (argc == 1 || core_file || remote_file) {
2820b57cec5SDimitry Andric       FileSpec symfile(m_symbol_file.GetOptionValue().GetCurrentValue());
2830b57cec5SDimitry Andric       if (symfile) {
2845ffd83dbSDimitry Andric         auto file = FileSystem::Instance().Open(
285349cc55cSDimitry Andric             symfile, lldb_private::File::eOpenOptionReadOnly);
2865ffd83dbSDimitry Andric 
2875ffd83dbSDimitry Andric         if (!file) {
2885ffd83dbSDimitry Andric           result.AppendErrorWithFormatv("Cannot open '{0}': {1}.",
2895ffd83dbSDimitry Andric                                         symfile.GetPath(),
2905ffd83dbSDimitry Andric                                         llvm::toString(file.takeError()));
2910b57cec5SDimitry Andric           return false;
2920b57cec5SDimitry Andric         }
2930b57cec5SDimitry Andric       }
2940b57cec5SDimitry Andric 
2950b57cec5SDimitry Andric       const char *file_path = command.GetArgumentAtIndex(0);
296e8d8bef9SDimitry Andric       LLDB_SCOPED_TIMERF("(lldb) target create '%s'", file_path);
2970b57cec5SDimitry Andric 
2980b57cec5SDimitry Andric       bool must_set_platform_path = false;
2990b57cec5SDimitry Andric 
3000b57cec5SDimitry Andric       Debugger &debugger = GetDebugger();
3010b57cec5SDimitry Andric 
3020b57cec5SDimitry Andric       TargetSP target_sp;
3030b57cec5SDimitry Andric       llvm::StringRef arch_cstr = m_arch_option.GetArchitectureName();
3040b57cec5SDimitry Andric       Status error(debugger.GetTargetList().CreateTarget(
3050b57cec5SDimitry Andric           debugger, file_path, arch_cstr,
306e8d8bef9SDimitry Andric           m_add_dependents.m_load_dependent_files, &m_platform_options,
307e8d8bef9SDimitry Andric           target_sp));
3080b57cec5SDimitry Andric 
309e8d8bef9SDimitry Andric       if (!target_sp) {
310e8d8bef9SDimitry Andric         result.AppendError(error.AsCString());
311e8d8bef9SDimitry Andric         return false;
312e8d8bef9SDimitry Andric       }
313e8d8bef9SDimitry Andric 
314*fe013be4SDimitry Andric       const llvm::StringRef label =
315*fe013be4SDimitry Andric           m_label.GetOptionValue().GetCurrentValueAsRef();
316*fe013be4SDimitry Andric       if (!label.empty()) {
317*fe013be4SDimitry Andric         if (auto E = target_sp->SetLabel(label))
318*fe013be4SDimitry Andric           result.SetError(std::move(E));
319*fe013be4SDimitry Andric         return false;
320*fe013be4SDimitry Andric       }
321*fe013be4SDimitry Andric 
322e8d8bef9SDimitry Andric       auto on_error = llvm::make_scope_exit(
323e8d8bef9SDimitry Andric           [&target_list = debugger.GetTargetList(), &target_sp]() {
324e8d8bef9SDimitry Andric             target_list.DeleteTarget(target_sp);
325e8d8bef9SDimitry Andric           });
326e8d8bef9SDimitry Andric 
3270b57cec5SDimitry Andric       // Only get the platform after we create the target because we might
3280b57cec5SDimitry Andric       // have switched platforms depending on what the arguments were to
3290b57cec5SDimitry Andric       // CreateTarget() we can't rely on the selected platform.
3300b57cec5SDimitry Andric 
3310b57cec5SDimitry Andric       PlatformSP platform_sp = target_sp->GetPlatform();
3320b57cec5SDimitry Andric 
33381ad6265SDimitry Andric       FileSpec file_spec;
33481ad6265SDimitry Andric       if (file_path) {
33581ad6265SDimitry Andric         file_spec.SetFile(file_path, FileSpec::Style::native);
33681ad6265SDimitry Andric         FileSystem::Instance().Resolve(file_spec);
33781ad6265SDimitry Andric 
33881ad6265SDimitry Andric         // Try to resolve the exe based on PATH and/or platform-specific
33981ad6265SDimitry Andric         // suffixes, but only if using the host platform.
34081ad6265SDimitry Andric         if (platform_sp && platform_sp->IsHost() &&
34181ad6265SDimitry Andric             !FileSystem::Instance().Exists(file_spec))
34281ad6265SDimitry Andric           FileSystem::Instance().ResolveExecutableLocation(file_spec);
34381ad6265SDimitry Andric       }
34481ad6265SDimitry Andric 
3450b57cec5SDimitry Andric       if (remote_file) {
3460b57cec5SDimitry Andric         if (platform_sp) {
3470b57cec5SDimitry Andric           // I have a remote file.. two possible cases
3480b57cec5SDimitry Andric           if (file_spec && FileSystem::Instance().Exists(file_spec)) {
3490b57cec5SDimitry Andric             // if the remote file does not exist, push it there
3500b57cec5SDimitry Andric             if (!platform_sp->GetFileExists(remote_file)) {
3510b57cec5SDimitry Andric               Status err = platform_sp->PutFile(file_spec, remote_file);
3520b57cec5SDimitry Andric               if (err.Fail()) {
3530b57cec5SDimitry Andric                 result.AppendError(err.AsCString());
3540b57cec5SDimitry Andric                 return false;
3550b57cec5SDimitry Andric               }
3560b57cec5SDimitry Andric             }
3570b57cec5SDimitry Andric           } else {
3580b57cec5SDimitry Andric             // there is no local file and we need one
3590b57cec5SDimitry Andric             // in order to make the remote ---> local transfer we need a
3600b57cec5SDimitry Andric             // platform
3610b57cec5SDimitry Andric             // TODO: if the user has passed in a --platform argument, use it
3620b57cec5SDimitry Andric             // to fetch the right platform
3630b57cec5SDimitry Andric             if (file_path) {
3640b57cec5SDimitry Andric               // copy the remote file to the local file
3650b57cec5SDimitry Andric               Status err = platform_sp->GetFile(remote_file, file_spec);
3660b57cec5SDimitry Andric               if (err.Fail()) {
3670b57cec5SDimitry Andric                 result.AppendError(err.AsCString());
3680b57cec5SDimitry Andric                 return false;
3690b57cec5SDimitry Andric               }
3700b57cec5SDimitry Andric             } else {
37181ad6265SDimitry Andric               // If the remote file exists, we can debug reading that out of
37281ad6265SDimitry Andric               // memory.  If the platform is already connected to an lldb-server
37381ad6265SDimitry Andric               // then we can at least check the file exists remotely.  Otherwise
37481ad6265SDimitry Andric               // we'll just have to trust that it will be there when we do
37581ad6265SDimitry Andric               // process connect.
37681ad6265SDimitry Andric               // I don't do this for the host platform because it seems odd to
37781ad6265SDimitry Andric               // support supplying a remote file but no local file for a local
37881ad6265SDimitry Andric               // debug session.
37981ad6265SDimitry Andric               if (platform_sp->IsHost()) {
38081ad6265SDimitry Andric                 result.AppendError("Supply a local file, not a remote file, "
38181ad6265SDimitry Andric                                    "when debugging on the host.");
38281ad6265SDimitry Andric                 return false;
38381ad6265SDimitry Andric               }
38481ad6265SDimitry Andric               if (platform_sp->IsConnected() && !platform_sp->GetFileExists(remote_file)) {
3850b57cec5SDimitry Andric                 result.AppendError("remote --> local transfer without local "
3860b57cec5SDimitry Andric                                  "path is not implemented yet");
3870b57cec5SDimitry Andric                 return false;
3880b57cec5SDimitry Andric               }
38981ad6265SDimitry Andric               // Since there's only a remote file, we need to set the executable
39081ad6265SDimitry Andric               // file spec to the remote one.
39181ad6265SDimitry Andric               ProcessLaunchInfo launch_info = target_sp->GetProcessLaunchInfo();
39281ad6265SDimitry Andric               launch_info.SetExecutableFile(FileSpec(remote_file), true);
39381ad6265SDimitry Andric               target_sp->SetProcessLaunchInfo(launch_info);
39481ad6265SDimitry Andric             }
3950b57cec5SDimitry Andric           }
3960b57cec5SDimitry Andric         } else {
3970b57cec5SDimitry Andric           result.AppendError("no platform found for target");
3980b57cec5SDimitry Andric           return false;
3990b57cec5SDimitry Andric         }
4000b57cec5SDimitry Andric       }
4010b57cec5SDimitry Andric 
4020b57cec5SDimitry Andric       if (symfile || remote_file) {
4030b57cec5SDimitry Andric         ModuleSP module_sp(target_sp->GetExecutableModule());
4040b57cec5SDimitry Andric         if (module_sp) {
4050b57cec5SDimitry Andric           if (symfile)
4060b57cec5SDimitry Andric             module_sp->SetSymbolFileFileSpec(symfile);
4070b57cec5SDimitry Andric           if (remote_file) {
4080b57cec5SDimitry Andric             std::string remote_path = remote_file.GetPath();
4090b57cec5SDimitry Andric             target_sp->SetArg0(remote_path.c_str());
4100b57cec5SDimitry Andric             module_sp->SetPlatformFileSpec(remote_file);
4110b57cec5SDimitry Andric           }
4120b57cec5SDimitry Andric         }
4130b57cec5SDimitry Andric       }
4140b57cec5SDimitry Andric 
4150b57cec5SDimitry Andric       if (must_set_platform_path) {
4160b57cec5SDimitry Andric         ModuleSpec main_module_spec(file_spec);
417480093f4SDimitry Andric         ModuleSP module_sp =
418480093f4SDimitry Andric             target_sp->GetOrCreateModule(main_module_spec, true /* notify */);
4190b57cec5SDimitry Andric         if (module_sp)
4200b57cec5SDimitry Andric           module_sp->SetPlatformFileSpec(remote_file);
4210b57cec5SDimitry Andric       }
4225ffd83dbSDimitry Andric 
4230b57cec5SDimitry Andric       if (core_file) {
4240b57cec5SDimitry Andric         FileSpec core_file_dir;
425bdd1243dSDimitry Andric         core_file_dir.SetDirectory(core_file.GetDirectory());
4260b57cec5SDimitry Andric         target_sp->AppendExecutableSearchPaths(core_file_dir);
4270b57cec5SDimitry Andric 
4280b57cec5SDimitry Andric         ProcessSP process_sp(target_sp->CreateProcess(
429e8d8bef9SDimitry Andric             GetDebugger().GetListener(), llvm::StringRef(), &core_file, false));
4300b57cec5SDimitry Andric 
4310b57cec5SDimitry Andric         if (process_sp) {
4320b57cec5SDimitry Andric           // Seems weird that we Launch a core file, but that is what we
4330b57cec5SDimitry Andric           // do!
4340b57cec5SDimitry Andric           error = process_sp->LoadCore();
4350b57cec5SDimitry Andric 
4360b57cec5SDimitry Andric           if (error.Fail()) {
4370b57cec5SDimitry Andric             result.AppendError(
4380b57cec5SDimitry Andric                 error.AsCString("can't find plug-in for core file"));
4390b57cec5SDimitry Andric             return false;
4400b57cec5SDimitry Andric           } else {
441e8d8bef9SDimitry Andric             result.AppendMessageWithFormatv(
442e8d8bef9SDimitry Andric                 "Core file '{0}' ({1}) was loaded.\n", core_file.GetPath(),
4430b57cec5SDimitry Andric                 target_sp->GetArchitecture().GetArchitectureName());
4440b57cec5SDimitry Andric             result.SetStatus(eReturnStatusSuccessFinishNoResult);
445e8d8bef9SDimitry Andric             on_error.release();
4460b57cec5SDimitry Andric           }
4470b57cec5SDimitry Andric         } else {
4485ffd83dbSDimitry Andric           result.AppendErrorWithFormatv(
4495ffd83dbSDimitry Andric               "Unable to find process plug-in for core file '{0}'\n",
4505ffd83dbSDimitry Andric               core_file.GetPath());
4510b57cec5SDimitry Andric         }
4520b57cec5SDimitry Andric       } else {
4530b57cec5SDimitry Andric         result.AppendMessageWithFormat(
4549dba64beSDimitry Andric             "Current executable set to '%s' (%s).\n",
4559dba64beSDimitry Andric             file_spec.GetPath().c_str(),
4560b57cec5SDimitry Andric             target_sp->GetArchitecture().GetArchitectureName());
4570b57cec5SDimitry Andric         result.SetStatus(eReturnStatusSuccessFinishNoResult);
458e8d8bef9SDimitry Andric         on_error.release();
4590b57cec5SDimitry Andric       }
4600b57cec5SDimitry Andric     } else {
4610b57cec5SDimitry Andric       result.AppendErrorWithFormat("'%s' takes exactly one executable path "
4620b57cec5SDimitry Andric                                    "argument, or use the --core option.\n",
4630b57cec5SDimitry Andric                                    m_cmd_name.c_str());
4640b57cec5SDimitry Andric     }
465e8d8bef9SDimitry Andric 
4660b57cec5SDimitry Andric     return result.Succeeded();
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;
474*fe013be4SDimitry 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:
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:
4930b57cec5SDimitry Andric   bool 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     return result.Succeeded();
5030b57cec5SDimitry Andric   }
5040b57cec5SDimitry Andric };
5050b57cec5SDimitry Andric 
5060b57cec5SDimitry Andric #pragma mark CommandObjectTargetSelect
5070b57cec5SDimitry Andric 
5080b57cec5SDimitry Andric class CommandObjectTargetSelect : public CommandObjectParsed {
5090b57cec5SDimitry Andric public:
5100b57cec5SDimitry Andric   CommandObjectTargetSelect(CommandInterpreter &interpreter)
5110b57cec5SDimitry Andric       : CommandObjectParsed(
5120b57cec5SDimitry Andric             interpreter, "target select",
5130b57cec5SDimitry Andric             "Select a target as the current target by target index.", nullptr) {
51481ad6265SDimitry Andric     CommandArgumentData target_arg{eArgTypeTargetID, eArgRepeatPlain};
51581ad6265SDimitry Andric     m_arguments.push_back({target_arg});
5160b57cec5SDimitry Andric   }
5170b57cec5SDimitry Andric 
5180b57cec5SDimitry Andric   ~CommandObjectTargetSelect() override = default;
5190b57cec5SDimitry Andric 
5200b57cec5SDimitry Andric protected:
5210b57cec5SDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
5220b57cec5SDimitry Andric     if (args.GetArgumentCount() == 1) {
523*fe013be4SDimitry Andric       const char *target_identifier = args.GetArgumentAtIndex(0);
524*fe013be4SDimitry Andric       uint32_t target_idx = LLDB_INVALID_INDEX32;
5250b57cec5SDimitry Andric       TargetList &target_list = GetDebugger().GetTargetList();
5260b57cec5SDimitry Andric       const uint32_t num_targets = target_list.GetNumTargets();
527*fe013be4SDimitry Andric       if (llvm::to_integer(target_identifier, target_idx)) {
5280b57cec5SDimitry Andric         if (target_idx < num_targets) {
529e8d8bef9SDimitry Andric           target_list.SetSelectedTarget(target_idx);
5300b57cec5SDimitry Andric           Stream &strm = result.GetOutputStream();
5310b57cec5SDimitry Andric           bool show_stopped_process_status = false;
5320b57cec5SDimitry Andric           DumpTargetList(target_list, show_stopped_process_status, strm);
5330b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishResult);
5340b57cec5SDimitry Andric         } else {
5350b57cec5SDimitry Andric           if (num_targets > 0) {
5360b57cec5SDimitry Andric             result.AppendErrorWithFormat(
5370b57cec5SDimitry Andric                 "index %u is out of range, valid target indexes are 0 - %u\n",
5380b57cec5SDimitry Andric                 target_idx, num_targets - 1);
5390b57cec5SDimitry Andric           } else {
5400b57cec5SDimitry Andric             result.AppendErrorWithFormat(
5410b57cec5SDimitry Andric                 "index %u is out of range since there are no active targets\n",
5420b57cec5SDimitry Andric                 target_idx);
5430b57cec5SDimitry Andric           }
5440b57cec5SDimitry Andric         }
5450b57cec5SDimitry Andric       } else {
546*fe013be4SDimitry Andric         for (size_t i = 0; i < num_targets; i++) {
547*fe013be4SDimitry Andric           if (TargetSP target_sp = target_list.GetTargetAtIndex(i)) {
548*fe013be4SDimitry Andric             const std::string &label = target_sp->GetLabel();
549*fe013be4SDimitry Andric             if (!label.empty() && label == target_identifier) {
550*fe013be4SDimitry Andric               target_idx = i;
551*fe013be4SDimitry Andric               break;
552*fe013be4SDimitry Andric             }
553*fe013be4SDimitry Andric           }
554*fe013be4SDimitry Andric         }
555*fe013be4SDimitry Andric 
556*fe013be4SDimitry Andric         if (target_idx != LLDB_INVALID_INDEX32) {
557*fe013be4SDimitry Andric           target_list.SetSelectedTarget(target_idx);
558*fe013be4SDimitry Andric           Stream &strm = result.GetOutputStream();
559*fe013be4SDimitry Andric           bool show_stopped_process_status = false;
560*fe013be4SDimitry Andric           DumpTargetList(target_list, show_stopped_process_status, strm);
561*fe013be4SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishResult);
562*fe013be4SDimitry Andric         } else {
5630b57cec5SDimitry Andric           result.AppendErrorWithFormat("invalid index string value '%s'\n",
564*fe013be4SDimitry Andric                                        target_identifier);
565*fe013be4SDimitry Andric         }
5660b57cec5SDimitry Andric       }
5670b57cec5SDimitry Andric     } else {
5680b57cec5SDimitry Andric       result.AppendError(
5690b57cec5SDimitry Andric           "'target select' takes a single argument: a target index\n");
5700b57cec5SDimitry Andric     }
5710b57cec5SDimitry Andric     return result.Succeeded();
5720b57cec5SDimitry Andric   }
5730b57cec5SDimitry Andric };
5740b57cec5SDimitry Andric 
5755ffd83dbSDimitry Andric #pragma mark CommandObjectTargetDelete
5760b57cec5SDimitry Andric 
5770b57cec5SDimitry Andric class CommandObjectTargetDelete : public CommandObjectParsed {
5780b57cec5SDimitry Andric public:
5790b57cec5SDimitry Andric   CommandObjectTargetDelete(CommandInterpreter &interpreter)
5800b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "target delete",
5810b57cec5SDimitry Andric                             "Delete one or more targets by target index.",
5820b57cec5SDimitry Andric                             nullptr),
58304eeddc0SDimitry Andric         m_all_option(LLDB_OPT_SET_1, false, "all", 'a', "Delete all targets.",
58404eeddc0SDimitry Andric                      false, true),
5850b57cec5SDimitry Andric         m_cleanup_option(
5860b57cec5SDimitry Andric             LLDB_OPT_SET_1, false, "clean", 'c',
5870b57cec5SDimitry Andric             "Perform extra cleanup to minimize memory consumption after "
5880b57cec5SDimitry Andric             "deleting the target.  "
5890b57cec5SDimitry Andric             "By default, LLDB will keep in memory any modules previously "
5900b57cec5SDimitry Andric             "loaded by the target as well "
5910b57cec5SDimitry Andric             "as all of its debug info.  Specifying --clean will unload all of "
5920b57cec5SDimitry Andric             "these shared modules and "
5930b57cec5SDimitry Andric             "cause them to be reparsed again the next time the target is run",
5940b57cec5SDimitry Andric             false, true) {
5950b57cec5SDimitry Andric     m_option_group.Append(&m_all_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
5960b57cec5SDimitry Andric     m_option_group.Append(&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
5970b57cec5SDimitry Andric     m_option_group.Finalize();
59881ad6265SDimitry Andric     CommandArgumentData target_arg{eArgTypeTargetID, eArgRepeatStar};
59981ad6265SDimitry Andric     m_arguments.push_back({target_arg});
6000b57cec5SDimitry Andric   }
6010b57cec5SDimitry Andric 
6020b57cec5SDimitry Andric   ~CommandObjectTargetDelete() override = default;
6030b57cec5SDimitry Andric 
6040b57cec5SDimitry Andric   Options *GetOptions() override { return &m_option_group; }
6050b57cec5SDimitry Andric 
6060b57cec5SDimitry Andric protected:
6070b57cec5SDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
6080b57cec5SDimitry Andric     const size_t argc = args.GetArgumentCount();
6090b57cec5SDimitry Andric     std::vector<TargetSP> delete_target_list;
6100b57cec5SDimitry Andric     TargetList &target_list = GetDebugger().GetTargetList();
6110b57cec5SDimitry Andric     TargetSP target_sp;
6120b57cec5SDimitry Andric 
6130b57cec5SDimitry Andric     if (m_all_option.GetOptionValue()) {
614*fe013be4SDimitry Andric       for (size_t i = 0; i < target_list.GetNumTargets(); ++i)
6150b57cec5SDimitry Andric         delete_target_list.push_back(target_list.GetTargetAtIndex(i));
6160b57cec5SDimitry Andric     } else if (argc > 0) {
6170b57cec5SDimitry Andric       const uint32_t num_targets = target_list.GetNumTargets();
6180b57cec5SDimitry Andric       // Bail out if don't have any targets.
6190b57cec5SDimitry Andric       if (num_targets == 0) {
6200b57cec5SDimitry Andric         result.AppendError("no targets to delete");
6210b57cec5SDimitry Andric         return false;
6220b57cec5SDimitry Andric       }
6230b57cec5SDimitry Andric 
6240b57cec5SDimitry Andric       for (auto &entry : args.entries()) {
6250b57cec5SDimitry Andric         uint32_t target_idx;
6269dba64beSDimitry Andric         if (entry.ref().getAsInteger(0, target_idx)) {
6270b57cec5SDimitry Andric           result.AppendErrorWithFormat("invalid target index '%s'\n",
6280b57cec5SDimitry Andric                                        entry.c_str());
6290b57cec5SDimitry Andric           return false;
6300b57cec5SDimitry Andric         }
6310b57cec5SDimitry Andric         if (target_idx < num_targets) {
6320b57cec5SDimitry Andric           target_sp = target_list.GetTargetAtIndex(target_idx);
6330b57cec5SDimitry Andric           if (target_sp) {
6340b57cec5SDimitry Andric             delete_target_list.push_back(target_sp);
6350b57cec5SDimitry Andric             continue;
6360b57cec5SDimitry Andric           }
6370b57cec5SDimitry Andric         }
6380b57cec5SDimitry Andric         if (num_targets > 1)
6390b57cec5SDimitry Andric           result.AppendErrorWithFormat("target index %u is out of range, valid "
6400b57cec5SDimitry Andric                                        "target indexes are 0 - %u\n",
6410b57cec5SDimitry Andric                                        target_idx, num_targets - 1);
6420b57cec5SDimitry Andric         else
6430b57cec5SDimitry Andric           result.AppendErrorWithFormat(
6440b57cec5SDimitry Andric               "target index %u is out of range, the only valid index is 0\n",
6450b57cec5SDimitry Andric               target_idx);
6460b57cec5SDimitry Andric 
6470b57cec5SDimitry Andric         return false;
6480b57cec5SDimitry Andric       }
6490b57cec5SDimitry Andric     } else {
6500b57cec5SDimitry Andric       target_sp = target_list.GetSelectedTarget();
6510b57cec5SDimitry Andric       if (!target_sp) {
6520b57cec5SDimitry Andric         result.AppendErrorWithFormat("no target is currently selected\n");
6530b57cec5SDimitry Andric         return false;
6540b57cec5SDimitry Andric       }
6550b57cec5SDimitry Andric       delete_target_list.push_back(target_sp);
6560b57cec5SDimitry Andric     }
6570b57cec5SDimitry Andric 
6580b57cec5SDimitry Andric     const size_t num_targets_to_delete = delete_target_list.size();
6590b57cec5SDimitry Andric     for (size_t idx = 0; idx < num_targets_to_delete; ++idx) {
6600b57cec5SDimitry Andric       target_sp = delete_target_list[idx];
6610b57cec5SDimitry Andric       target_list.DeleteTarget(target_sp);
6620b57cec5SDimitry Andric       target_sp->Destroy();
6630b57cec5SDimitry Andric     }
6640b57cec5SDimitry Andric     // If "--clean" was specified, prune any orphaned shared modules from the
6650b57cec5SDimitry Andric     // global shared module list
6660b57cec5SDimitry Andric     if (m_cleanup_option.GetOptionValue()) {
6670b57cec5SDimitry Andric       const bool mandatory = true;
6680b57cec5SDimitry Andric       ModuleList::RemoveOrphanSharedModules(mandatory);
6690b57cec5SDimitry Andric     }
6700b57cec5SDimitry Andric     result.GetOutputStream().Printf("%u targets deleted.\n",
6710b57cec5SDimitry Andric                                     (uint32_t)num_targets_to_delete);
6720b57cec5SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishResult);
6730b57cec5SDimitry Andric 
6740b57cec5SDimitry Andric     return true;
6750b57cec5SDimitry Andric   }
6760b57cec5SDimitry Andric 
6770b57cec5SDimitry Andric   OptionGroupOptions m_option_group;
6780b57cec5SDimitry Andric   OptionGroupBoolean m_all_option;
6790b57cec5SDimitry Andric   OptionGroupBoolean m_cleanup_option;
6800b57cec5SDimitry Andric };
6810b57cec5SDimitry Andric 
6825ffd83dbSDimitry Andric class CommandObjectTargetShowLaunchEnvironment : public CommandObjectParsed {
6835ffd83dbSDimitry Andric public:
6845ffd83dbSDimitry Andric   CommandObjectTargetShowLaunchEnvironment(CommandInterpreter &interpreter)
6855ffd83dbSDimitry Andric       : CommandObjectParsed(
6865ffd83dbSDimitry Andric             interpreter, "target show-launch-environment",
6875ffd83dbSDimitry Andric             "Shows the environment being passed to the process when launched, "
6885ffd83dbSDimitry Andric             "taking info account 3 settings: target.env-vars, "
6895ffd83dbSDimitry Andric             "target.inherit-env and target.unset-env-vars.",
6905ffd83dbSDimitry Andric             nullptr, eCommandRequiresTarget) {}
6915ffd83dbSDimitry Andric 
6925ffd83dbSDimitry Andric   ~CommandObjectTargetShowLaunchEnvironment() override = default;
6935ffd83dbSDimitry Andric 
6945ffd83dbSDimitry Andric protected:
6955ffd83dbSDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
6965ffd83dbSDimitry Andric     Target *target = m_exe_ctx.GetTargetPtr();
6975ffd83dbSDimitry Andric     Environment env = target->GetEnvironment();
6985ffd83dbSDimitry Andric 
6995ffd83dbSDimitry Andric     std::vector<Environment::value_type *> env_vector;
7005ffd83dbSDimitry Andric     env_vector.reserve(env.size());
7015ffd83dbSDimitry Andric     for (auto &KV : env)
7025ffd83dbSDimitry Andric       env_vector.push_back(&KV);
7035ffd83dbSDimitry Andric     std::sort(env_vector.begin(), env_vector.end(),
7045ffd83dbSDimitry Andric               [](Environment::value_type *a, Environment::value_type *b) {
7055ffd83dbSDimitry Andric                 return a->first() < b->first();
7065ffd83dbSDimitry Andric               });
7075ffd83dbSDimitry Andric 
7085ffd83dbSDimitry Andric     auto &strm = result.GetOutputStream();
7095ffd83dbSDimitry Andric     for (auto &KV : env_vector)
7105ffd83dbSDimitry Andric       strm.Format("{0}={1}\n", KV->first(), KV->second);
7115ffd83dbSDimitry Andric 
7125ffd83dbSDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishResult);
7135ffd83dbSDimitry Andric     return result.Succeeded();
7145ffd83dbSDimitry Andric   }
7155ffd83dbSDimitry Andric };
7165ffd83dbSDimitry Andric 
7170b57cec5SDimitry Andric #pragma mark CommandObjectTargetVariable
7180b57cec5SDimitry Andric 
7190b57cec5SDimitry Andric class CommandObjectTargetVariable : public CommandObjectParsed {
7200b57cec5SDimitry Andric   static const uint32_t SHORT_OPTION_FILE = 0x66696c65; // 'file'
7210b57cec5SDimitry Andric   static const uint32_t SHORT_OPTION_SHLB = 0x73686c62; // 'shlb'
7220b57cec5SDimitry Andric 
7230b57cec5SDimitry Andric public:
7240b57cec5SDimitry Andric   CommandObjectTargetVariable(CommandInterpreter &interpreter)
7250b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "target variable",
7260b57cec5SDimitry Andric                             "Read global variables for the current target, "
7270b57cec5SDimitry Andric                             "before or while running a process.",
7280b57cec5SDimitry Andric                             nullptr, eCommandRequiresTarget),
7290b57cec5SDimitry Andric         m_option_variable(false), // Don't include frame options
7300b57cec5SDimitry Andric         m_option_format(eFormatDefault),
7310b57cec5SDimitry Andric         m_option_compile_units(LLDB_OPT_SET_1, false, "file", SHORT_OPTION_FILE,
7320b57cec5SDimitry Andric                                0, eArgTypeFilename,
7330b57cec5SDimitry Andric                                "A basename or fullpath to a file that contains "
7340b57cec5SDimitry Andric                                "global variables. This option can be "
7350b57cec5SDimitry Andric                                "specified multiple times."),
7360b57cec5SDimitry Andric         m_option_shared_libraries(
7370b57cec5SDimitry Andric             LLDB_OPT_SET_1, false, "shlib", SHORT_OPTION_SHLB, 0,
7380b57cec5SDimitry Andric             eArgTypeFilename,
7390b57cec5SDimitry Andric             "A basename or fullpath to a shared library to use in the search "
7400b57cec5SDimitry Andric             "for global "
74104eeddc0SDimitry Andric             "variables. This option can be specified multiple times.") {
7420b57cec5SDimitry Andric     CommandArgumentEntry arg;
7430b57cec5SDimitry Andric     CommandArgumentData var_name_arg;
7440b57cec5SDimitry Andric 
7450b57cec5SDimitry Andric     // Define the first (and only) variant of this arg.
7460b57cec5SDimitry Andric     var_name_arg.arg_type = eArgTypeVarName;
7470b57cec5SDimitry Andric     var_name_arg.arg_repetition = eArgRepeatPlus;
7480b57cec5SDimitry Andric 
7490b57cec5SDimitry Andric     // There is only one variant this argument could be; put it into the
7500b57cec5SDimitry Andric     // argument entry.
7510b57cec5SDimitry Andric     arg.push_back(var_name_arg);
7520b57cec5SDimitry Andric 
7530b57cec5SDimitry Andric     // Push the data for the first argument into the m_arguments vector.
7540b57cec5SDimitry Andric     m_arguments.push_back(arg);
7550b57cec5SDimitry Andric 
7560b57cec5SDimitry Andric     m_option_group.Append(&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
7570b57cec5SDimitry Andric     m_option_group.Append(&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
7580b57cec5SDimitry Andric     m_option_group.Append(&m_option_format,
7590b57cec5SDimitry Andric                           OptionGroupFormat::OPTION_GROUP_FORMAT |
7600b57cec5SDimitry Andric                               OptionGroupFormat::OPTION_GROUP_GDB_FMT,
7610b57cec5SDimitry Andric                           LLDB_OPT_SET_1);
7620b57cec5SDimitry Andric     m_option_group.Append(&m_option_compile_units, LLDB_OPT_SET_ALL,
7630b57cec5SDimitry Andric                           LLDB_OPT_SET_1);
7640b57cec5SDimitry Andric     m_option_group.Append(&m_option_shared_libraries, LLDB_OPT_SET_ALL,
7650b57cec5SDimitry Andric                           LLDB_OPT_SET_1);
7660b57cec5SDimitry Andric     m_option_group.Finalize();
7670b57cec5SDimitry Andric   }
7680b57cec5SDimitry Andric 
7690b57cec5SDimitry Andric   ~CommandObjectTargetVariable() override = default;
7700b57cec5SDimitry Andric 
7710b57cec5SDimitry Andric   void DumpValueObject(Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp,
7720b57cec5SDimitry Andric                        const char *root_name) {
7730b57cec5SDimitry Andric     DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions());
7740b57cec5SDimitry Andric 
7750b57cec5SDimitry Andric     if (!valobj_sp->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
7760b57cec5SDimitry Andric         valobj_sp->IsRuntimeSupportValue())
7770b57cec5SDimitry Andric       return;
7780b57cec5SDimitry Andric 
7790b57cec5SDimitry Andric     switch (var_sp->GetScope()) {
7800b57cec5SDimitry Andric     case eValueTypeVariableGlobal:
7810b57cec5SDimitry Andric       if (m_option_variable.show_scope)
7820b57cec5SDimitry Andric         s.PutCString("GLOBAL: ");
7830b57cec5SDimitry Andric       break;
7840b57cec5SDimitry Andric 
7850b57cec5SDimitry Andric     case eValueTypeVariableStatic:
7860b57cec5SDimitry Andric       if (m_option_variable.show_scope)
7870b57cec5SDimitry Andric         s.PutCString("STATIC: ");
7880b57cec5SDimitry Andric       break;
7890b57cec5SDimitry Andric 
7900b57cec5SDimitry Andric     case eValueTypeVariableArgument:
7910b57cec5SDimitry Andric       if (m_option_variable.show_scope)
7920b57cec5SDimitry Andric         s.PutCString("   ARG: ");
7930b57cec5SDimitry Andric       break;
7940b57cec5SDimitry Andric 
7950b57cec5SDimitry Andric     case eValueTypeVariableLocal:
7960b57cec5SDimitry Andric       if (m_option_variable.show_scope)
7970b57cec5SDimitry Andric         s.PutCString(" LOCAL: ");
7980b57cec5SDimitry Andric       break;
7990b57cec5SDimitry Andric 
8000b57cec5SDimitry Andric     case eValueTypeVariableThreadLocal:
8010b57cec5SDimitry Andric       if (m_option_variable.show_scope)
8020b57cec5SDimitry Andric         s.PutCString("THREAD: ");
8030b57cec5SDimitry Andric       break;
8040b57cec5SDimitry Andric 
8050b57cec5SDimitry Andric     default:
8060b57cec5SDimitry Andric       break;
8070b57cec5SDimitry Andric     }
8080b57cec5SDimitry Andric 
8090b57cec5SDimitry Andric     if (m_option_variable.show_decl) {
8100b57cec5SDimitry Andric       bool show_fullpaths = false;
8110b57cec5SDimitry Andric       bool show_module = true;
8120b57cec5SDimitry Andric       if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
8130b57cec5SDimitry Andric         s.PutCString(": ");
8140b57cec5SDimitry Andric     }
8150b57cec5SDimitry Andric 
8160b57cec5SDimitry Andric     const Format format = m_option_format.GetFormat();
8170b57cec5SDimitry Andric     if (format != eFormatDefault)
8180b57cec5SDimitry Andric       options.SetFormat(format);
8190b57cec5SDimitry Andric 
8200b57cec5SDimitry Andric     options.SetRootValueObjectName(root_name);
8210b57cec5SDimitry Andric 
8220b57cec5SDimitry Andric     valobj_sp->Dump(s, options);
8230b57cec5SDimitry Andric   }
8240b57cec5SDimitry Andric 
8250b57cec5SDimitry Andric   static size_t GetVariableCallback(void *baton, const char *name,
8260b57cec5SDimitry Andric                                     VariableList &variable_list) {
8279dba64beSDimitry Andric     size_t old_size = variable_list.GetSize();
8280b57cec5SDimitry Andric     Target *target = static_cast<Target *>(baton);
8299dba64beSDimitry Andric     if (target)
8309dba64beSDimitry Andric       target->GetImages().FindGlobalVariables(ConstString(name), UINT32_MAX,
8319dba64beSDimitry Andric                                               variable_list);
8329dba64beSDimitry Andric     return variable_list.GetSize() - old_size;
8330b57cec5SDimitry Andric   }
8340b57cec5SDimitry Andric 
8350b57cec5SDimitry Andric   Options *GetOptions() override { return &m_option_group; }
8360b57cec5SDimitry Andric 
8370b57cec5SDimitry Andric protected:
8380b57cec5SDimitry Andric   void DumpGlobalVariableList(const ExecutionContext &exe_ctx,
8390b57cec5SDimitry Andric                               const SymbolContext &sc,
8400b57cec5SDimitry Andric                               const VariableList &variable_list, Stream &s) {
841480093f4SDimitry Andric     if (variable_list.Empty())
842480093f4SDimitry Andric       return;
8430b57cec5SDimitry Andric     if (sc.module_sp) {
8440b57cec5SDimitry Andric       if (sc.comp_unit) {
845480093f4SDimitry Andric         s.Format("Global variables for {0} in {1}:\n",
846480093f4SDimitry Andric                  sc.comp_unit->GetPrimaryFile(), sc.module_sp->GetFileSpec());
8470b57cec5SDimitry Andric       } else {
8480b57cec5SDimitry Andric         s.Printf("Global variables for %s\n",
8490b57cec5SDimitry Andric                  sc.module_sp->GetFileSpec().GetPath().c_str());
8500b57cec5SDimitry Andric       }
8510b57cec5SDimitry Andric     } else if (sc.comp_unit) {
852480093f4SDimitry Andric       s.Format("Global variables for {0}\n", sc.comp_unit->GetPrimaryFile());
8530b57cec5SDimitry Andric     }
8540b57cec5SDimitry Andric 
855480093f4SDimitry Andric     for (VariableSP var_sp : variable_list) {
856480093f4SDimitry Andric       if (!var_sp)
857480093f4SDimitry Andric         continue;
8580b57cec5SDimitry Andric       ValueObjectSP valobj_sp(ValueObjectVariable::Create(
8590b57cec5SDimitry Andric           exe_ctx.GetBestExecutionContextScope(), var_sp));
8600b57cec5SDimitry Andric 
8610b57cec5SDimitry Andric       if (valobj_sp)
862480093f4SDimitry Andric         DumpValueObject(s, var_sp, valobj_sp, var_sp->GetName().GetCString());
8630b57cec5SDimitry Andric     }
8640b57cec5SDimitry Andric   }
8650b57cec5SDimitry Andric 
8660b57cec5SDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
8670b57cec5SDimitry Andric     Target *target = m_exe_ctx.GetTargetPtr();
8680b57cec5SDimitry Andric     const size_t argc = args.GetArgumentCount();
8690b57cec5SDimitry Andric     Stream &s = result.GetOutputStream();
8700b57cec5SDimitry Andric 
8710b57cec5SDimitry Andric     if (argc > 0) {
8725ffd83dbSDimitry Andric       for (const Args::ArgEntry &arg : args) {
8730b57cec5SDimitry Andric         VariableList variable_list;
8740b57cec5SDimitry Andric         ValueObjectList valobj_list;
8750b57cec5SDimitry Andric 
8760b57cec5SDimitry Andric         size_t matches = 0;
8770b57cec5SDimitry Andric         bool use_var_name = false;
8780b57cec5SDimitry Andric         if (m_option_variable.use_regex) {
879fe6060f1SDimitry Andric           RegularExpression regex(arg.ref());
8800b57cec5SDimitry Andric           if (!regex.IsValid()) {
8810b57cec5SDimitry Andric             result.GetErrorStream().Printf(
8825ffd83dbSDimitry Andric                 "error: invalid regular expression: '%s'\n", arg.c_str());
8830b57cec5SDimitry Andric             return false;
8840b57cec5SDimitry Andric           }
8850b57cec5SDimitry Andric           use_var_name = true;
8869dba64beSDimitry Andric           target->GetImages().FindGlobalVariables(regex, UINT32_MAX,
8870b57cec5SDimitry Andric                                                   variable_list);
8889dba64beSDimitry Andric           matches = variable_list.GetSize();
8890b57cec5SDimitry Andric         } else {
8900b57cec5SDimitry Andric           Status error(Variable::GetValuesForVariableExpressionPath(
8915ffd83dbSDimitry Andric               arg.c_str(), m_exe_ctx.GetBestExecutionContextScope(),
8920b57cec5SDimitry Andric               GetVariableCallback, target, variable_list, valobj_list));
8930b57cec5SDimitry Andric           matches = variable_list.GetSize();
8940b57cec5SDimitry Andric         }
8950b57cec5SDimitry Andric 
8960b57cec5SDimitry Andric         if (matches == 0) {
897fe6060f1SDimitry Andric           result.AppendErrorWithFormat("can't find global variable '%s'",
898fe6060f1SDimitry Andric                                        arg.c_str());
8990b57cec5SDimitry Andric           return false;
9000b57cec5SDimitry Andric         } else {
9010b57cec5SDimitry Andric           for (uint32_t global_idx = 0; global_idx < matches; ++global_idx) {
9020b57cec5SDimitry Andric             VariableSP var_sp(variable_list.GetVariableAtIndex(global_idx));
9030b57cec5SDimitry Andric             if (var_sp) {
9040b57cec5SDimitry Andric               ValueObjectSP valobj_sp(
9050b57cec5SDimitry Andric                   valobj_list.GetValueObjectAtIndex(global_idx));
9060b57cec5SDimitry Andric               if (!valobj_sp)
9070b57cec5SDimitry Andric                 valobj_sp = ValueObjectVariable::Create(
9080b57cec5SDimitry Andric                     m_exe_ctx.GetBestExecutionContextScope(), var_sp);
9090b57cec5SDimitry Andric 
9100b57cec5SDimitry Andric               if (valobj_sp)
9110b57cec5SDimitry Andric                 DumpValueObject(s, var_sp, valobj_sp,
9120b57cec5SDimitry Andric                                 use_var_name ? var_sp->GetName().GetCString()
9135ffd83dbSDimitry Andric                                              : arg.c_str());
9140b57cec5SDimitry Andric             }
9150b57cec5SDimitry Andric           }
9160b57cec5SDimitry Andric         }
9170b57cec5SDimitry Andric       }
9180b57cec5SDimitry Andric     } else {
9190b57cec5SDimitry Andric       const FileSpecList &compile_units =
9200b57cec5SDimitry Andric           m_option_compile_units.GetOptionValue().GetCurrentValue();
9210b57cec5SDimitry Andric       const FileSpecList &shlibs =
9220b57cec5SDimitry Andric           m_option_shared_libraries.GetOptionValue().GetCurrentValue();
9230b57cec5SDimitry Andric       SymbolContextList sc_list;
9240b57cec5SDimitry Andric       const size_t num_compile_units = compile_units.GetSize();
9250b57cec5SDimitry Andric       const size_t num_shlibs = shlibs.GetSize();
9260b57cec5SDimitry Andric       if (num_compile_units == 0 && num_shlibs == 0) {
9270b57cec5SDimitry Andric         bool success = false;
9280b57cec5SDimitry Andric         StackFrame *frame = m_exe_ctx.GetFramePtr();
9290b57cec5SDimitry Andric         CompileUnit *comp_unit = nullptr;
9300b57cec5SDimitry Andric         if (frame) {
9310b57cec5SDimitry Andric           SymbolContext sc = frame->GetSymbolContext(eSymbolContextCompUnit);
932e8d8bef9SDimitry Andric           comp_unit = sc.comp_unit;
9330b57cec5SDimitry Andric           if (sc.comp_unit) {
9340b57cec5SDimitry Andric             const bool can_create = true;
9350b57cec5SDimitry Andric             VariableListSP comp_unit_varlist_sp(
9360b57cec5SDimitry Andric                 sc.comp_unit->GetVariableList(can_create));
9370b57cec5SDimitry Andric             if (comp_unit_varlist_sp) {
9380b57cec5SDimitry Andric               size_t count = comp_unit_varlist_sp->GetSize();
9390b57cec5SDimitry Andric               if (count > 0) {
9400b57cec5SDimitry Andric                 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
9410b57cec5SDimitry Andric                 success = true;
9420b57cec5SDimitry Andric               }
9430b57cec5SDimitry Andric             }
9440b57cec5SDimitry Andric           }
9450b57cec5SDimitry Andric         }
9460b57cec5SDimitry Andric         if (!success) {
9470b57cec5SDimitry Andric           if (frame) {
9480b57cec5SDimitry Andric             if (comp_unit)
949480093f4SDimitry Andric               result.AppendErrorWithFormatv(
950480093f4SDimitry Andric                   "no global variables in current compile unit: {0}\n",
951480093f4SDimitry Andric                   comp_unit->GetPrimaryFile());
9520b57cec5SDimitry Andric             else
9530b57cec5SDimitry Andric               result.AppendErrorWithFormat(
9540b57cec5SDimitry Andric                   "no debug information for frame %u\n",
9550b57cec5SDimitry Andric                   frame->GetFrameIndex());
9560b57cec5SDimitry Andric           } else
9570b57cec5SDimitry Andric             result.AppendError("'target variable' takes one or more global "
9580b57cec5SDimitry Andric                                "variable names as arguments\n");
9590b57cec5SDimitry Andric         }
9600b57cec5SDimitry Andric       } else {
9610b57cec5SDimitry Andric         SymbolContextList sc_list;
9620b57cec5SDimitry Andric         // We have one or more compile unit or shlib
9630b57cec5SDimitry Andric         if (num_shlibs > 0) {
9640b57cec5SDimitry Andric           for (size_t shlib_idx = 0; shlib_idx < num_shlibs; ++shlib_idx) {
9650b57cec5SDimitry Andric             const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx));
9660b57cec5SDimitry Andric             ModuleSpec module_spec(module_file);
9670b57cec5SDimitry Andric 
9680b57cec5SDimitry Andric             ModuleSP module_sp(
9690b57cec5SDimitry Andric                 target->GetImages().FindFirstModule(module_spec));
9700b57cec5SDimitry Andric             if (module_sp) {
9710b57cec5SDimitry Andric               if (num_compile_units > 0) {
9720b57cec5SDimitry Andric                 for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
9730b57cec5SDimitry Andric                   module_sp->FindCompileUnits(
9749dba64beSDimitry Andric                       compile_units.GetFileSpecAtIndex(cu_idx), sc_list);
9750b57cec5SDimitry Andric               } else {
9760b57cec5SDimitry Andric                 SymbolContext sc;
9770b57cec5SDimitry Andric                 sc.module_sp = module_sp;
9780b57cec5SDimitry Andric                 sc_list.Append(sc);
9790b57cec5SDimitry Andric               }
9800b57cec5SDimitry Andric             } else {
9810b57cec5SDimitry Andric               // Didn't find matching shlib/module in target...
9820b57cec5SDimitry Andric               result.AppendErrorWithFormat(
9830b57cec5SDimitry Andric                   "target doesn't contain the specified shared library: %s\n",
9840b57cec5SDimitry Andric                   module_file.GetPath().c_str());
9850b57cec5SDimitry Andric             }
9860b57cec5SDimitry Andric           }
9870b57cec5SDimitry Andric         } else {
9880b57cec5SDimitry Andric           // No shared libraries, we just want to find globals for the compile
9890b57cec5SDimitry Andric           // units files that were specified
9900b57cec5SDimitry Andric           for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
9910b57cec5SDimitry Andric             target->GetImages().FindCompileUnits(
9929dba64beSDimitry Andric                 compile_units.GetFileSpecAtIndex(cu_idx), sc_list);
9930b57cec5SDimitry Andric         }
9940b57cec5SDimitry Andric 
995*fe013be4SDimitry Andric         for (const SymbolContext &sc : sc_list) {
9960b57cec5SDimitry Andric           if (sc.comp_unit) {
9970b57cec5SDimitry Andric             const bool can_create = true;
9980b57cec5SDimitry Andric             VariableListSP comp_unit_varlist_sp(
9990b57cec5SDimitry Andric                 sc.comp_unit->GetVariableList(can_create));
10000b57cec5SDimitry Andric             if (comp_unit_varlist_sp)
1001*fe013be4SDimitry Andric               DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
10020b57cec5SDimitry Andric           } else if (sc.module_sp) {
10030b57cec5SDimitry Andric             // Get all global variables for this module
10040b57cec5SDimitry Andric             lldb_private::RegularExpression all_globals_regex(
1005*fe013be4SDimitry Andric                 llvm::StringRef(".")); // Any global with at least one character
10060b57cec5SDimitry Andric             VariableList variable_list;
10070b57cec5SDimitry Andric             sc.module_sp->FindGlobalVariables(all_globals_regex, UINT32_MAX,
10080b57cec5SDimitry Andric                                               variable_list);
10090b57cec5SDimitry Andric             DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s);
10100b57cec5SDimitry Andric           }
10110b57cec5SDimitry Andric         }
10120b57cec5SDimitry Andric       }
10130b57cec5SDimitry Andric     }
10140b57cec5SDimitry Andric 
101581ad6265SDimitry Andric     m_interpreter.PrintWarningsIfNecessary(result.GetOutputStream(),
101681ad6265SDimitry Andric                                            m_cmd_name);
10170b57cec5SDimitry Andric 
10180b57cec5SDimitry Andric     return result.Succeeded();
10190b57cec5SDimitry Andric   }
10200b57cec5SDimitry Andric 
10210b57cec5SDimitry Andric   OptionGroupOptions m_option_group;
10220b57cec5SDimitry Andric   OptionGroupVariable m_option_variable;
10230b57cec5SDimitry Andric   OptionGroupFormat m_option_format;
10240b57cec5SDimitry Andric   OptionGroupFileList m_option_compile_units;
10250b57cec5SDimitry Andric   OptionGroupFileList m_option_shared_libraries;
10260b57cec5SDimitry Andric   OptionGroupValueObjectDisplay m_varobj_options;
10270b57cec5SDimitry Andric };
10280b57cec5SDimitry Andric 
10290b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesSearchPathsAdd
10300b57cec5SDimitry Andric 
10310b57cec5SDimitry Andric class CommandObjectTargetModulesSearchPathsAdd : public CommandObjectParsed {
10320b57cec5SDimitry Andric public:
10330b57cec5SDimitry Andric   CommandObjectTargetModulesSearchPathsAdd(CommandInterpreter &interpreter)
10340b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "target modules search-paths add",
10350b57cec5SDimitry Andric                             "Add new image search paths substitution pairs to "
10360b57cec5SDimitry Andric                             "the current target.",
10379dba64beSDimitry Andric                             nullptr, eCommandRequiresTarget) {
10380b57cec5SDimitry Andric     CommandArgumentEntry arg;
10390b57cec5SDimitry Andric     CommandArgumentData old_prefix_arg;
10400b57cec5SDimitry Andric     CommandArgumentData new_prefix_arg;
10410b57cec5SDimitry Andric 
10420b57cec5SDimitry Andric     // Define the first variant of this arg pair.
10430b57cec5SDimitry Andric     old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
10440b57cec5SDimitry Andric     old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
10450b57cec5SDimitry Andric 
10460b57cec5SDimitry Andric     // Define the first variant of this arg pair.
10470b57cec5SDimitry Andric     new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
10480b57cec5SDimitry Andric     new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
10490b57cec5SDimitry Andric 
10500b57cec5SDimitry Andric     // There are two required arguments that must always occur together, i.e.
10510b57cec5SDimitry Andric     // an argument "pair".  Because they must always occur together, they are
10520b57cec5SDimitry Andric     // treated as two variants of one argument rather than two independent
10530b57cec5SDimitry Andric     // arguments.  Push them both into the first argument position for
10540b57cec5SDimitry Andric     // m_arguments...
10550b57cec5SDimitry Andric 
10560b57cec5SDimitry Andric     arg.push_back(old_prefix_arg);
10570b57cec5SDimitry Andric     arg.push_back(new_prefix_arg);
10580b57cec5SDimitry Andric 
10590b57cec5SDimitry Andric     m_arguments.push_back(arg);
10600b57cec5SDimitry Andric   }
10610b57cec5SDimitry Andric 
10620b57cec5SDimitry Andric   ~CommandObjectTargetModulesSearchPathsAdd() override = default;
10630b57cec5SDimitry Andric 
10640b57cec5SDimitry Andric protected:
10650b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
10669dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
10670b57cec5SDimitry Andric     const size_t argc = command.GetArgumentCount();
10680b57cec5SDimitry Andric     if (argc & 1) {
10690b57cec5SDimitry Andric       result.AppendError("add requires an even number of arguments\n");
10700b57cec5SDimitry Andric     } else {
10710b57cec5SDimitry Andric       for (size_t i = 0; i < argc; i += 2) {
10720b57cec5SDimitry Andric         const char *from = command.GetArgumentAtIndex(i);
10730b57cec5SDimitry Andric         const char *to = command.GetArgumentAtIndex(i + 1);
10740b57cec5SDimitry Andric 
10750b57cec5SDimitry Andric         if (from[0] && to[0]) {
107681ad6265SDimitry Andric           Log *log = GetLog(LLDBLog::Host);
10770b57cec5SDimitry Andric           if (log) {
10789dba64beSDimitry Andric             LLDB_LOGF(log,
10799dba64beSDimitry Andric                       "target modules search path adding ImageSearchPath "
10800b57cec5SDimitry Andric                       "pair: '%s' -> '%s'",
10810b57cec5SDimitry Andric                       from, to);
10820b57cec5SDimitry Andric           }
10830b57cec5SDimitry Andric           bool last_pair = ((argc - i) == 2);
10840b57cec5SDimitry Andric           target->GetImageSearchPathList().Append(
1085349cc55cSDimitry Andric               from, to, last_pair); // Notify if this is the last pair
10860b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishNoResult);
10870b57cec5SDimitry Andric         } else {
10880b57cec5SDimitry Andric           if (from[0])
10890b57cec5SDimitry Andric             result.AppendError("<path-prefix> can't be empty\n");
10900b57cec5SDimitry Andric           else
10910b57cec5SDimitry Andric             result.AppendError("<new-path-prefix> can't be empty\n");
10920b57cec5SDimitry Andric         }
10930b57cec5SDimitry Andric       }
10940b57cec5SDimitry Andric     }
10950b57cec5SDimitry Andric     return result.Succeeded();
10960b57cec5SDimitry Andric   }
10970b57cec5SDimitry Andric };
10980b57cec5SDimitry Andric 
10990b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesSearchPathsClear
11000b57cec5SDimitry Andric 
11010b57cec5SDimitry Andric class CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed {
11020b57cec5SDimitry Andric public:
11030b57cec5SDimitry Andric   CommandObjectTargetModulesSearchPathsClear(CommandInterpreter &interpreter)
11040b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "target modules search-paths clear",
11050b57cec5SDimitry Andric                             "Clear all current image search path substitution "
11060b57cec5SDimitry Andric                             "pairs from the current target.",
11079dba64beSDimitry Andric                             "target modules search-paths clear",
11089dba64beSDimitry Andric                             eCommandRequiresTarget) {}
11090b57cec5SDimitry Andric 
11100b57cec5SDimitry Andric   ~CommandObjectTargetModulesSearchPathsClear() override = default;
11110b57cec5SDimitry Andric 
11120b57cec5SDimitry Andric protected:
11130b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
11149dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
11150b57cec5SDimitry Andric     bool notify = true;
11160b57cec5SDimitry Andric     target->GetImageSearchPathList().Clear(notify);
11170b57cec5SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishNoResult);
11180b57cec5SDimitry Andric     return result.Succeeded();
11190b57cec5SDimitry Andric   }
11200b57cec5SDimitry Andric };
11210b57cec5SDimitry Andric 
11220b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesSearchPathsInsert
11230b57cec5SDimitry Andric 
11240b57cec5SDimitry Andric class CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed {
11250b57cec5SDimitry Andric public:
11260b57cec5SDimitry Andric   CommandObjectTargetModulesSearchPathsInsert(CommandInterpreter &interpreter)
11270b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "target modules search-paths insert",
11280b57cec5SDimitry Andric                             "Insert a new image search path substitution pair "
11290b57cec5SDimitry Andric                             "into the current target at the specified index.",
11309dba64beSDimitry Andric                             nullptr, eCommandRequiresTarget) {
11310b57cec5SDimitry Andric     CommandArgumentEntry arg1;
11320b57cec5SDimitry Andric     CommandArgumentEntry arg2;
11330b57cec5SDimitry Andric     CommandArgumentData index_arg;
11340b57cec5SDimitry Andric     CommandArgumentData old_prefix_arg;
11350b57cec5SDimitry Andric     CommandArgumentData new_prefix_arg;
11360b57cec5SDimitry Andric 
11370b57cec5SDimitry Andric     // Define the first and only variant of this arg.
11380b57cec5SDimitry Andric     index_arg.arg_type = eArgTypeIndex;
11390b57cec5SDimitry Andric     index_arg.arg_repetition = eArgRepeatPlain;
11400b57cec5SDimitry Andric 
11410b57cec5SDimitry Andric     // Put the one and only variant into the first arg for m_arguments:
11420b57cec5SDimitry Andric     arg1.push_back(index_arg);
11430b57cec5SDimitry Andric 
11440b57cec5SDimitry Andric     // Define the first variant of this arg pair.
11450b57cec5SDimitry Andric     old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
11460b57cec5SDimitry Andric     old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
11470b57cec5SDimitry Andric 
11480b57cec5SDimitry Andric     // Define the first variant of this arg pair.
11490b57cec5SDimitry Andric     new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
11500b57cec5SDimitry Andric     new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
11510b57cec5SDimitry Andric 
11520b57cec5SDimitry Andric     // There are two required arguments that must always occur together, i.e.
11530b57cec5SDimitry Andric     // an argument "pair".  Because they must always occur together, they are
11540b57cec5SDimitry Andric     // treated as two variants of one argument rather than two independent
11550b57cec5SDimitry Andric     // arguments.  Push them both into the same argument position for
11560b57cec5SDimitry Andric     // m_arguments...
11570b57cec5SDimitry Andric 
11580b57cec5SDimitry Andric     arg2.push_back(old_prefix_arg);
11590b57cec5SDimitry Andric     arg2.push_back(new_prefix_arg);
11600b57cec5SDimitry Andric 
11610b57cec5SDimitry Andric     // Add arguments to m_arguments.
11620b57cec5SDimitry Andric     m_arguments.push_back(arg1);
11630b57cec5SDimitry Andric     m_arguments.push_back(arg2);
11640b57cec5SDimitry Andric   }
11650b57cec5SDimitry Andric 
11660b57cec5SDimitry Andric   ~CommandObjectTargetModulesSearchPathsInsert() override = default;
11670b57cec5SDimitry Andric 
1168e8d8bef9SDimitry Andric   void
1169e8d8bef9SDimitry Andric   HandleArgumentCompletion(CompletionRequest &request,
1170e8d8bef9SDimitry Andric                            OptionElementVector &opt_element_vector) override {
1171e8d8bef9SDimitry Andric     if (!m_exe_ctx.HasTargetScope() || request.GetCursorIndex() != 0)
1172e8d8bef9SDimitry Andric       return;
1173e8d8bef9SDimitry Andric 
1174e8d8bef9SDimitry Andric     Target *target = m_exe_ctx.GetTargetPtr();
1175e8d8bef9SDimitry Andric     const PathMappingList &list = target->GetImageSearchPathList();
1176e8d8bef9SDimitry Andric     const size_t num = list.GetSize();
1177e8d8bef9SDimitry Andric     ConstString old_path, new_path;
1178e8d8bef9SDimitry Andric     for (size_t i = 0; i < num; ++i) {
1179e8d8bef9SDimitry Andric       if (!list.GetPathsAtIndex(i, old_path, new_path))
1180e8d8bef9SDimitry Andric         break;
1181e8d8bef9SDimitry Andric       StreamString strm;
1182e8d8bef9SDimitry Andric       strm << old_path << " -> " << new_path;
1183e8d8bef9SDimitry Andric       request.TryCompleteCurrentArg(std::to_string(i), strm.GetString());
1184e8d8bef9SDimitry Andric     }
1185e8d8bef9SDimitry Andric   }
1186e8d8bef9SDimitry Andric 
11870b57cec5SDimitry Andric protected:
11880b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
11899dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
11900b57cec5SDimitry Andric     size_t argc = command.GetArgumentCount();
11910b57cec5SDimitry Andric     // check for at least 3 arguments and an odd number of parameters
11920b57cec5SDimitry Andric     if (argc >= 3 && argc & 1) {
11935ffd83dbSDimitry Andric       uint32_t insert_idx;
11940b57cec5SDimitry Andric 
11955ffd83dbSDimitry Andric       if (!llvm::to_integer(command.GetArgumentAtIndex(0), insert_idx)) {
11960b57cec5SDimitry Andric         result.AppendErrorWithFormat(
11970b57cec5SDimitry Andric             "<index> parameter is not an integer: '%s'.\n",
11980b57cec5SDimitry Andric             command.GetArgumentAtIndex(0));
11990b57cec5SDimitry Andric         return result.Succeeded();
12000b57cec5SDimitry Andric       }
12010b57cec5SDimitry Andric 
12020b57cec5SDimitry Andric       // shift off the index
12030b57cec5SDimitry Andric       command.Shift();
12040b57cec5SDimitry Andric       argc = command.GetArgumentCount();
12050b57cec5SDimitry Andric 
12060b57cec5SDimitry Andric       for (uint32_t i = 0; i < argc; i += 2, ++insert_idx) {
12070b57cec5SDimitry Andric         const char *from = command.GetArgumentAtIndex(i);
12080b57cec5SDimitry Andric         const char *to = command.GetArgumentAtIndex(i + 1);
12090b57cec5SDimitry Andric 
12100b57cec5SDimitry Andric         if (from[0] && to[0]) {
12110b57cec5SDimitry Andric           bool last_pair = ((argc - i) == 2);
1212349cc55cSDimitry Andric           target->GetImageSearchPathList().Insert(from, to, insert_idx,
1213349cc55cSDimitry Andric                                                   last_pair);
12140b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishNoResult);
12150b57cec5SDimitry Andric         } else {
12160b57cec5SDimitry Andric           if (from[0])
12170b57cec5SDimitry Andric             result.AppendError("<path-prefix> can't be empty\n");
12180b57cec5SDimitry Andric           else
12190b57cec5SDimitry Andric             result.AppendError("<new-path-prefix> can't be empty\n");
12200b57cec5SDimitry Andric           return false;
12210b57cec5SDimitry Andric         }
12220b57cec5SDimitry Andric       }
12230b57cec5SDimitry Andric     } else {
12240b57cec5SDimitry Andric       result.AppendError("insert requires at least three arguments\n");
12250b57cec5SDimitry Andric       return result.Succeeded();
12260b57cec5SDimitry Andric     }
12270b57cec5SDimitry Andric     return result.Succeeded();
12280b57cec5SDimitry Andric   }
12290b57cec5SDimitry Andric };
12300b57cec5SDimitry Andric 
12310b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesSearchPathsList
12320b57cec5SDimitry Andric 
12330b57cec5SDimitry Andric class CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed {
12340b57cec5SDimitry Andric public:
12350b57cec5SDimitry Andric   CommandObjectTargetModulesSearchPathsList(CommandInterpreter &interpreter)
12360b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "target modules search-paths list",
12370b57cec5SDimitry Andric                             "List all current image search path substitution "
12380b57cec5SDimitry Andric                             "pairs in the current target.",
12399dba64beSDimitry Andric                             "target modules search-paths list",
12409dba64beSDimitry Andric                             eCommandRequiresTarget) {}
12410b57cec5SDimitry Andric 
12420b57cec5SDimitry Andric   ~CommandObjectTargetModulesSearchPathsList() override = default;
12430b57cec5SDimitry Andric 
12440b57cec5SDimitry Andric protected:
12450b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
12469dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
12470b57cec5SDimitry Andric 
12480b57cec5SDimitry Andric     target->GetImageSearchPathList().Dump(&result.GetOutputStream());
12490b57cec5SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishResult);
12500b57cec5SDimitry Andric     return result.Succeeded();
12510b57cec5SDimitry Andric   }
12520b57cec5SDimitry Andric };
12530b57cec5SDimitry Andric 
12540b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesSearchPathsQuery
12550b57cec5SDimitry Andric 
12560b57cec5SDimitry Andric class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed {
12570b57cec5SDimitry Andric public:
12580b57cec5SDimitry Andric   CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter &interpreter)
12590b57cec5SDimitry Andric       : CommandObjectParsed(
12600b57cec5SDimitry Andric             interpreter, "target modules search-paths query",
12610b57cec5SDimitry Andric             "Transform a path using the first applicable image search path.",
12629dba64beSDimitry Andric             nullptr, eCommandRequiresTarget) {
12630b57cec5SDimitry Andric     CommandArgumentEntry arg;
12640b57cec5SDimitry Andric     CommandArgumentData path_arg;
12650b57cec5SDimitry Andric 
12660b57cec5SDimitry Andric     // Define the first (and only) variant of this arg.
12670b57cec5SDimitry Andric     path_arg.arg_type = eArgTypeDirectoryName;
12680b57cec5SDimitry Andric     path_arg.arg_repetition = eArgRepeatPlain;
12690b57cec5SDimitry Andric 
12700b57cec5SDimitry Andric     // There is only one variant this argument could be; put it into the
12710b57cec5SDimitry Andric     // argument entry.
12720b57cec5SDimitry Andric     arg.push_back(path_arg);
12730b57cec5SDimitry Andric 
12740b57cec5SDimitry Andric     // Push the data for the first argument into the m_arguments vector.
12750b57cec5SDimitry Andric     m_arguments.push_back(arg);
12760b57cec5SDimitry Andric   }
12770b57cec5SDimitry Andric 
12780b57cec5SDimitry Andric   ~CommandObjectTargetModulesSearchPathsQuery() override = default;
12790b57cec5SDimitry Andric 
12800b57cec5SDimitry Andric protected:
12810b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
12829dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
12830b57cec5SDimitry Andric     if (command.GetArgumentCount() != 1) {
12840b57cec5SDimitry Andric       result.AppendError("query requires one argument\n");
12850b57cec5SDimitry Andric       return result.Succeeded();
12860b57cec5SDimitry Andric     }
12870b57cec5SDimitry Andric 
12880b57cec5SDimitry Andric     ConstString orig(command.GetArgumentAtIndex(0));
12890b57cec5SDimitry Andric     ConstString transformed;
12900b57cec5SDimitry Andric     if (target->GetImageSearchPathList().RemapPath(orig, transformed))
12910b57cec5SDimitry Andric       result.GetOutputStream().Printf("%s\n", transformed.GetCString());
12920b57cec5SDimitry Andric     else
12930b57cec5SDimitry Andric       result.GetOutputStream().Printf("%s\n", orig.GetCString());
12940b57cec5SDimitry Andric 
12950b57cec5SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishResult);
12960b57cec5SDimitry Andric     return result.Succeeded();
12970b57cec5SDimitry Andric   }
12980b57cec5SDimitry Andric };
12990b57cec5SDimitry Andric 
13000b57cec5SDimitry Andric // Static Helper functions
13010b57cec5SDimitry Andric static void DumpModuleArchitecture(Stream &strm, Module *module,
13020b57cec5SDimitry Andric                                    bool full_triple, uint32_t width) {
13030b57cec5SDimitry Andric   if (module) {
13040b57cec5SDimitry Andric     StreamString arch_strm;
13050b57cec5SDimitry Andric 
13060b57cec5SDimitry Andric     if (full_triple)
1307480093f4SDimitry Andric       module->GetArchitecture().DumpTriple(arch_strm.AsRawOstream());
13080b57cec5SDimitry Andric     else
13090b57cec5SDimitry Andric       arch_strm.PutCString(module->GetArchitecture().GetArchitectureName());
13105ffd83dbSDimitry Andric     std::string arch_str = std::string(arch_strm.GetString());
13110b57cec5SDimitry Andric 
13120b57cec5SDimitry Andric     if (width)
13130b57cec5SDimitry Andric       strm.Printf("%-*s", width, arch_str.c_str());
13140b57cec5SDimitry Andric     else
13150b57cec5SDimitry Andric       strm.PutCString(arch_str);
13160b57cec5SDimitry Andric   }
13170b57cec5SDimitry Andric }
13180b57cec5SDimitry Andric 
13190b57cec5SDimitry Andric static void DumpModuleUUID(Stream &strm, Module *module) {
13200b57cec5SDimitry Andric   if (module && module->GetUUID().IsValid())
1321*fe013be4SDimitry Andric     module->GetUUID().Dump(strm);
13220b57cec5SDimitry Andric   else
13230b57cec5SDimitry Andric     strm.PutCString("                                    ");
13240b57cec5SDimitry Andric }
13250b57cec5SDimitry Andric 
13260b57cec5SDimitry Andric static uint32_t DumpCompileUnitLineTable(CommandInterpreter &interpreter,
13270b57cec5SDimitry Andric                                          Stream &strm, Module *module,
13280b57cec5SDimitry Andric                                          const FileSpec &file_spec,
13290b57cec5SDimitry Andric                                          lldb::DescriptionLevel desc_level) {
13300b57cec5SDimitry Andric   uint32_t num_matches = 0;
13310b57cec5SDimitry Andric   if (module) {
13320b57cec5SDimitry Andric     SymbolContextList sc_list;
13330b57cec5SDimitry Andric     num_matches = module->ResolveSymbolContextsForFileSpec(
13340b57cec5SDimitry Andric         file_spec, 0, false, eSymbolContextCompUnit, sc_list);
13350b57cec5SDimitry Andric 
1336*fe013be4SDimitry Andric     bool first_module = true;
1337*fe013be4SDimitry Andric     for (const SymbolContext &sc : sc_list) {
1338*fe013be4SDimitry Andric       if (!first_module)
13390b57cec5SDimitry Andric         strm << "\n\n";
13400b57cec5SDimitry Andric 
1341480093f4SDimitry Andric       strm << "Line table for " << sc.comp_unit->GetPrimaryFile() << " in `"
1342480093f4SDimitry Andric            << module->GetFileSpec().GetFilename() << "\n";
13430b57cec5SDimitry Andric       LineTable *line_table = sc.comp_unit->GetLineTable();
13440b57cec5SDimitry Andric       if (line_table)
13450b57cec5SDimitry Andric         line_table->GetDescription(
13460b57cec5SDimitry Andric             &strm, interpreter.GetExecutionContext().GetTargetPtr(),
13470b57cec5SDimitry Andric             desc_level);
13480b57cec5SDimitry Andric       else
13490b57cec5SDimitry Andric         strm << "No line table";
1350*fe013be4SDimitry Andric 
1351*fe013be4SDimitry Andric       first_module = false;
13520b57cec5SDimitry Andric     }
13530b57cec5SDimitry Andric   }
13540b57cec5SDimitry Andric   return num_matches;
13550b57cec5SDimitry Andric }
13560b57cec5SDimitry Andric 
13570b57cec5SDimitry Andric static void DumpFullpath(Stream &strm, const FileSpec *file_spec_ptr,
13580b57cec5SDimitry Andric                          uint32_t width) {
13590b57cec5SDimitry Andric   if (file_spec_ptr) {
13600b57cec5SDimitry Andric     if (width > 0) {
13610b57cec5SDimitry Andric       std::string fullpath = file_spec_ptr->GetPath();
13620b57cec5SDimitry Andric       strm.Printf("%-*s", width, fullpath.c_str());
13630b57cec5SDimitry Andric       return;
13640b57cec5SDimitry Andric     } else {
1365480093f4SDimitry Andric       file_spec_ptr->Dump(strm.AsRawOstream());
13660b57cec5SDimitry Andric       return;
13670b57cec5SDimitry Andric     }
13680b57cec5SDimitry Andric   }
13690b57cec5SDimitry Andric   // Keep the width spacing correct if things go wrong...
13700b57cec5SDimitry Andric   if (width > 0)
13710b57cec5SDimitry Andric     strm.Printf("%-*s", width, "");
13720b57cec5SDimitry Andric }
13730b57cec5SDimitry Andric 
13740b57cec5SDimitry Andric static void DumpDirectory(Stream &strm, const FileSpec *file_spec_ptr,
13750b57cec5SDimitry Andric                           uint32_t width) {
13760b57cec5SDimitry Andric   if (file_spec_ptr) {
13770b57cec5SDimitry Andric     if (width > 0)
13780b57cec5SDimitry Andric       strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
13790b57cec5SDimitry Andric     else
13800b57cec5SDimitry Andric       file_spec_ptr->GetDirectory().Dump(&strm);
13810b57cec5SDimitry Andric     return;
13820b57cec5SDimitry Andric   }
13830b57cec5SDimitry Andric   // Keep the width spacing correct if things go wrong...
13840b57cec5SDimitry Andric   if (width > 0)
13850b57cec5SDimitry Andric     strm.Printf("%-*s", width, "");
13860b57cec5SDimitry Andric }
13870b57cec5SDimitry Andric 
13880b57cec5SDimitry Andric static void DumpBasename(Stream &strm, const FileSpec *file_spec_ptr,
13890b57cec5SDimitry Andric                          uint32_t width) {
13900b57cec5SDimitry Andric   if (file_spec_ptr) {
13910b57cec5SDimitry Andric     if (width > 0)
13920b57cec5SDimitry Andric       strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
13930b57cec5SDimitry Andric     else
13940b57cec5SDimitry Andric       file_spec_ptr->GetFilename().Dump(&strm);
13950b57cec5SDimitry Andric     return;
13960b57cec5SDimitry Andric   }
13970b57cec5SDimitry Andric   // Keep the width spacing correct if things go wrong...
13980b57cec5SDimitry Andric   if (width > 0)
13990b57cec5SDimitry Andric     strm.Printf("%-*s", width, "");
14000b57cec5SDimitry Andric }
14010b57cec5SDimitry Andric 
14020b57cec5SDimitry Andric static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) {
14030b57cec5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
14040b57cec5SDimitry Andric   const size_t num_modules = module_list.GetSize();
1405e8d8bef9SDimitry Andric   if (num_modules == 0)
1406e8d8bef9SDimitry Andric     return 0;
1407e8d8bef9SDimitry Andric 
1408e8d8bef9SDimitry Andric   size_t num_dumped = 0;
1409e8d8bef9SDimitry Andric   strm.Format("Dumping headers for {0} module(s).\n", num_modules);
14100b57cec5SDimitry Andric   strm.IndentMore();
1411e8d8bef9SDimitry Andric   for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
1412e8d8bef9SDimitry Andric     if (module_sp) {
14130b57cec5SDimitry Andric       if (num_dumped++ > 0) {
14140b57cec5SDimitry Andric         strm.EOL();
14150b57cec5SDimitry Andric         strm.EOL();
14160b57cec5SDimitry Andric       }
1417e8d8bef9SDimitry Andric       ObjectFile *objfile = module_sp->GetObjectFile();
14180b57cec5SDimitry Andric       if (objfile)
14190b57cec5SDimitry Andric         objfile->Dump(&strm);
14200b57cec5SDimitry Andric       else {
14210b57cec5SDimitry Andric         strm.Format("No object file for module: {0:F}\n",
1422e8d8bef9SDimitry Andric                     module_sp->GetFileSpec());
14230b57cec5SDimitry Andric       }
14240b57cec5SDimitry Andric     }
14250b57cec5SDimitry Andric   }
14260b57cec5SDimitry Andric   strm.IndentLess();
14270b57cec5SDimitry Andric   return num_dumped;
14280b57cec5SDimitry Andric }
14290b57cec5SDimitry Andric 
14300b57cec5SDimitry Andric static void DumpModuleSymtab(CommandInterpreter &interpreter, Stream &strm,
1431480093f4SDimitry Andric                              Module *module, SortOrder sort_order,
1432480093f4SDimitry Andric                              Mangled::NamePreference name_preference) {
14339dba64beSDimitry Andric   if (!module)
14349dba64beSDimitry Andric     return;
14359dba64beSDimitry Andric   if (Symtab *symtab = module->GetSymtab())
14360b57cec5SDimitry Andric     symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(),
1437480093f4SDimitry Andric                  sort_order, name_preference);
14380b57cec5SDimitry Andric }
14390b57cec5SDimitry Andric 
14400b57cec5SDimitry Andric static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm,
14410b57cec5SDimitry Andric                                Module *module) {
14420b57cec5SDimitry Andric   if (module) {
14430b57cec5SDimitry Andric     SectionList *section_list = module->GetSectionList();
14440b57cec5SDimitry Andric     if (section_list) {
14450b57cec5SDimitry Andric       strm.Printf("Sections for '%s' (%s):\n",
14460b57cec5SDimitry Andric                   module->GetSpecificationDescription().c_str(),
14470b57cec5SDimitry Andric                   module->GetArchitecture().GetArchitectureName());
14485ffd83dbSDimitry Andric       section_list->Dump(strm.AsRawOstream(), strm.GetIndentLevel() + 2,
14490b57cec5SDimitry Andric                          interpreter.GetExecutionContext().GetTargetPtr(), true,
14500b57cec5SDimitry Andric                          UINT32_MAX);
14510b57cec5SDimitry Andric     }
14520b57cec5SDimitry Andric   }
14530b57cec5SDimitry Andric }
14540b57cec5SDimitry Andric 
14559dba64beSDimitry Andric static bool DumpModuleSymbolFile(Stream &strm, Module *module) {
14560b57cec5SDimitry Andric   if (module) {
14579dba64beSDimitry Andric     if (SymbolFile *symbol_file = module->GetSymbolFile(true)) {
14589dba64beSDimitry Andric       symbol_file->Dump(strm);
14590b57cec5SDimitry Andric       return true;
14600b57cec5SDimitry Andric     }
14610b57cec5SDimitry Andric   }
14620b57cec5SDimitry Andric   return false;
14630b57cec5SDimitry Andric }
14640b57cec5SDimitry Andric 
14650b57cec5SDimitry Andric static void DumpAddress(ExecutionContextScope *exe_scope,
146681ad6265SDimitry Andric                         const Address &so_addr, bool verbose, bool all_ranges,
146781ad6265SDimitry Andric                         Stream &strm) {
14680b57cec5SDimitry Andric   strm.IndentMore();
14690b57cec5SDimitry Andric   strm.Indent("    Address: ");
14700b57cec5SDimitry Andric   so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
14710b57cec5SDimitry Andric   strm.PutCString(" (");
14720b57cec5SDimitry Andric   so_addr.Dump(&strm, exe_scope, Address::DumpStyleSectionNameOffset);
14730b57cec5SDimitry Andric   strm.PutCString(")\n");
14740b57cec5SDimitry Andric   strm.Indent("    Summary: ");
14750b57cec5SDimitry Andric   const uint32_t save_indent = strm.GetIndentLevel();
14760b57cec5SDimitry Andric   strm.SetIndentLevel(save_indent + 13);
14770b57cec5SDimitry Andric   so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription);
14780b57cec5SDimitry Andric   strm.SetIndentLevel(save_indent);
14790b57cec5SDimitry Andric   // Print out detailed address information when verbose is enabled
14800b57cec5SDimitry Andric   if (verbose) {
14810b57cec5SDimitry Andric     strm.EOL();
148281ad6265SDimitry Andric     so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext,
148381ad6265SDimitry Andric                  Address::DumpStyleInvalid, UINT32_MAX, all_ranges);
14840b57cec5SDimitry Andric   }
14850b57cec5SDimitry Andric   strm.IndentLess();
14860b57cec5SDimitry Andric }
14870b57cec5SDimitry Andric 
14880b57cec5SDimitry Andric static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm,
14890b57cec5SDimitry Andric                                   Module *module, uint32_t resolve_mask,
14900b57cec5SDimitry Andric                                   lldb::addr_t raw_addr, lldb::addr_t offset,
149181ad6265SDimitry Andric                                   bool verbose, bool all_ranges) {
14920b57cec5SDimitry Andric   if (module) {
14930b57cec5SDimitry Andric     lldb::addr_t addr = raw_addr - offset;
14940b57cec5SDimitry Andric     Address so_addr;
14950b57cec5SDimitry Andric     SymbolContext sc;
14960b57cec5SDimitry Andric     Target *target = interpreter.GetExecutionContext().GetTargetPtr();
14970b57cec5SDimitry Andric     if (target && !target->GetSectionLoadList().IsEmpty()) {
14980b57cec5SDimitry Andric       if (!target->GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
14990b57cec5SDimitry Andric         return false;
15000b57cec5SDimitry Andric       else if (so_addr.GetModule().get() != module)
15010b57cec5SDimitry Andric         return false;
15020b57cec5SDimitry Andric     } else {
15030b57cec5SDimitry Andric       if (!module->ResolveFileAddress(addr, so_addr))
15040b57cec5SDimitry Andric         return false;
15050b57cec5SDimitry Andric     }
15060b57cec5SDimitry Andric 
15070b57cec5SDimitry Andric     ExecutionContextScope *exe_scope =
15080b57cec5SDimitry Andric         interpreter.GetExecutionContext().GetBestExecutionContextScope();
150981ad6265SDimitry Andric     DumpAddress(exe_scope, so_addr, verbose, all_ranges, strm);
15100b57cec5SDimitry Andric     return true;
15110b57cec5SDimitry Andric   }
15120b57cec5SDimitry Andric 
15130b57cec5SDimitry Andric   return false;
15140b57cec5SDimitry Andric }
15150b57cec5SDimitry Andric 
15160b57cec5SDimitry Andric static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
15170b57cec5SDimitry Andric                                      Stream &strm, Module *module,
15180b57cec5SDimitry Andric                                      const char *name, bool name_is_regex,
151981ad6265SDimitry Andric                                      bool verbose, bool all_ranges) {
15209dba64beSDimitry Andric   if (!module)
15219dba64beSDimitry Andric     return 0;
15220b57cec5SDimitry Andric 
15239dba64beSDimitry Andric   Symtab *symtab = module->GetSymtab();
15249dba64beSDimitry Andric   if (!symtab)
15259dba64beSDimitry Andric     return 0;
15269dba64beSDimitry Andric 
15279dba64beSDimitry Andric   SymbolContext sc;
15280b57cec5SDimitry Andric   std::vector<uint32_t> match_indexes;
15290b57cec5SDimitry Andric   ConstString symbol_name(name);
15300b57cec5SDimitry Andric   uint32_t num_matches = 0;
15310b57cec5SDimitry Andric   if (name_is_regex) {
15320b57cec5SDimitry Andric     RegularExpression name_regexp(symbol_name.GetStringRef());
15330b57cec5SDimitry Andric     num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType(
15340b57cec5SDimitry Andric         name_regexp, eSymbolTypeAny, match_indexes);
15350b57cec5SDimitry Andric   } else {
15360b57cec5SDimitry Andric     num_matches =
15370b57cec5SDimitry Andric         symtab->AppendSymbolIndexesWithName(symbol_name, match_indexes);
15380b57cec5SDimitry Andric   }
15390b57cec5SDimitry Andric 
15400b57cec5SDimitry Andric   if (num_matches > 0) {
15410b57cec5SDimitry Andric     strm.Indent();
15420b57cec5SDimitry Andric     strm.Printf("%u symbols match %s'%s' in ", num_matches,
15430b57cec5SDimitry Andric                 name_is_regex ? "the regular expression " : "", name);
15440b57cec5SDimitry Andric     DumpFullpath(strm, &module->GetFileSpec(), 0);
15450b57cec5SDimitry Andric     strm.PutCString(":\n");
15460b57cec5SDimitry Andric     strm.IndentMore();
15470b57cec5SDimitry Andric     for (uint32_t i = 0; i < num_matches; ++i) {
15480b57cec5SDimitry Andric       Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
1549bdd1243dSDimitry Andric       if (symbol) {
1550bdd1243dSDimitry Andric         if (symbol->ValueIsAddress()) {
15519dba64beSDimitry Andric           DumpAddress(
15529dba64beSDimitry Andric               interpreter.GetExecutionContext().GetBestExecutionContextScope(),
155381ad6265SDimitry Andric               symbol->GetAddressRef(), verbose, all_ranges, strm);
1554bdd1243dSDimitry Andric           strm.EOL();
1555bdd1243dSDimitry Andric         } else {
1556bdd1243dSDimitry Andric           strm.IndentMore();
1557bdd1243dSDimitry Andric           strm.Indent("    Name: ");
1558bdd1243dSDimitry Andric           strm.PutCString(symbol->GetDisplayName().GetStringRef());
1559bdd1243dSDimitry Andric           strm.EOL();
1560bdd1243dSDimitry Andric           strm.Indent("    Value: ");
1561bdd1243dSDimitry Andric           strm.Printf("0x%16.16" PRIx64 "\n", symbol->GetRawValue());
1562bdd1243dSDimitry Andric           if (symbol->GetByteSizeIsValid()) {
1563bdd1243dSDimitry Andric             strm.Indent("    Size: ");
1564bdd1243dSDimitry Andric             strm.Printf("0x%16.16" PRIx64 "\n", symbol->GetByteSize());
1565bdd1243dSDimitry Andric           }
1566bdd1243dSDimitry Andric           strm.IndentLess();
1567bdd1243dSDimitry Andric         }
15680b57cec5SDimitry Andric       }
15690b57cec5SDimitry Andric     }
15700b57cec5SDimitry Andric     strm.IndentLess();
15719dba64beSDimitry Andric   }
15720b57cec5SDimitry Andric   return num_matches;
15730b57cec5SDimitry Andric }
15740b57cec5SDimitry Andric 
15750b57cec5SDimitry Andric static void DumpSymbolContextList(ExecutionContextScope *exe_scope,
1576*fe013be4SDimitry Andric                                   Stream &strm,
1577*fe013be4SDimitry Andric                                   const SymbolContextList &sc_list,
157881ad6265SDimitry Andric                                   bool verbose, bool all_ranges) {
15790b57cec5SDimitry Andric   strm.IndentMore();
1580*fe013be4SDimitry Andric   bool first_module = true;
1581*fe013be4SDimitry Andric   for (const SymbolContext &sc : sc_list) {
1582*fe013be4SDimitry Andric     if (!first_module)
1583*fe013be4SDimitry Andric       strm.EOL();
15840b57cec5SDimitry Andric 
15850b57cec5SDimitry Andric     AddressRange range;
15860b57cec5SDimitry Andric 
15870b57cec5SDimitry Andric     sc.GetAddressRange(eSymbolContextEverything, 0, true, range);
15880b57cec5SDimitry Andric 
158981ad6265SDimitry Andric     DumpAddress(exe_scope, range.GetBaseAddress(), verbose, all_ranges, strm);
1590*fe013be4SDimitry Andric     first_module = false;
15910b57cec5SDimitry Andric   }
15920b57cec5SDimitry Andric   strm.IndentLess();
15930b57cec5SDimitry Andric }
15940b57cec5SDimitry Andric 
15950b57cec5SDimitry Andric static size_t LookupFunctionInModule(CommandInterpreter &interpreter,
15960b57cec5SDimitry Andric                                      Stream &strm, Module *module,
15970b57cec5SDimitry Andric                                      const char *name, bool name_is_regex,
1598349cc55cSDimitry Andric                                      const ModuleFunctionSearchOptions &options,
159981ad6265SDimitry Andric                                      bool verbose, bool all_ranges) {
16000b57cec5SDimitry Andric   if (module && name && name[0]) {
16010b57cec5SDimitry Andric     SymbolContextList sc_list;
16020b57cec5SDimitry Andric     size_t num_matches = 0;
16030b57cec5SDimitry Andric     if (name_is_regex) {
16040b57cec5SDimitry Andric       RegularExpression function_name_regex((llvm::StringRef(name)));
1605349cc55cSDimitry Andric       module->FindFunctions(function_name_regex, options, sc_list);
16060b57cec5SDimitry Andric     } else {
16070b57cec5SDimitry Andric       ConstString function_name(name);
16085ffd83dbSDimitry Andric       module->FindFunctions(function_name, CompilerDeclContext(),
1609349cc55cSDimitry Andric                             eFunctionNameTypeAuto, options, sc_list);
16100b57cec5SDimitry Andric     }
16119dba64beSDimitry Andric     num_matches = sc_list.GetSize();
16120b57cec5SDimitry Andric     if (num_matches) {
16130b57cec5SDimitry Andric       strm.Indent();
16140b57cec5SDimitry Andric       strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
16150b57cec5SDimitry Andric                   num_matches > 1 ? "es" : "");
16160b57cec5SDimitry Andric       DumpFullpath(strm, &module->GetFileSpec(), 0);
16170b57cec5SDimitry Andric       strm.PutCString(":\n");
16180b57cec5SDimitry Andric       DumpSymbolContextList(
16190b57cec5SDimitry Andric           interpreter.GetExecutionContext().GetBestExecutionContextScope(),
162081ad6265SDimitry Andric           strm, sc_list, verbose, all_ranges);
16210b57cec5SDimitry Andric     }
16220b57cec5SDimitry Andric     return num_matches;
16230b57cec5SDimitry Andric   }
16240b57cec5SDimitry Andric   return 0;
16250b57cec5SDimitry Andric }
16260b57cec5SDimitry Andric 
1627e8d8bef9SDimitry Andric static size_t LookupTypeInModule(Target *target,
1628e8d8bef9SDimitry Andric                                  CommandInterpreter &interpreter, Stream &strm,
16290b57cec5SDimitry Andric                                  Module *module, const char *name_cstr,
16300b57cec5SDimitry Andric                                  bool name_is_regex) {
16310b57cec5SDimitry Andric   TypeList type_list;
16329dba64beSDimitry Andric   if (module && name_cstr && name_cstr[0]) {
16330b57cec5SDimitry Andric     const uint32_t max_num_matches = UINT32_MAX;
16340b57cec5SDimitry Andric     bool name_is_fully_qualified = false;
16350b57cec5SDimitry Andric 
16360b57cec5SDimitry Andric     ConstString name(name_cstr);
16370b57cec5SDimitry Andric     llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
16380b57cec5SDimitry Andric     module->FindTypes(name, name_is_fully_qualified, max_num_matches,
16390b57cec5SDimitry Andric                       searched_symbol_files, type_list);
16400b57cec5SDimitry Andric 
16419dba64beSDimitry Andric     if (type_list.Empty())
16429dba64beSDimitry Andric       return 0;
16439dba64beSDimitry Andric 
164404eeddc0SDimitry Andric     const uint64_t num_matches = type_list.GetSize();
164504eeddc0SDimitry Andric 
16460b57cec5SDimitry Andric     strm.Indent();
164704eeddc0SDimitry Andric     strm.Printf("%" PRIu64 " match%s found in ", num_matches,
16480b57cec5SDimitry Andric                 num_matches > 1 ? "es" : "");
16490b57cec5SDimitry Andric     DumpFullpath(strm, &module->GetFileSpec(), 0);
16500b57cec5SDimitry Andric     strm.PutCString(":\n");
16510b57cec5SDimitry Andric     for (TypeSP type_sp : type_list.Types()) {
16529dba64beSDimitry Andric       if (!type_sp)
16539dba64beSDimitry Andric         continue;
16540b57cec5SDimitry Andric       // Resolve the clang type so that any forward references to types
16550b57cec5SDimitry Andric       // that haven't yet been parsed will get parsed.
16560b57cec5SDimitry Andric       type_sp->GetFullCompilerType();
1657e8d8bef9SDimitry Andric       type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target);
16580b57cec5SDimitry Andric       // Print all typedef chains
16590b57cec5SDimitry Andric       TypeSP typedef_type_sp(type_sp);
16600b57cec5SDimitry Andric       TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
16610b57cec5SDimitry Andric       while (typedefed_type_sp) {
16620b57cec5SDimitry Andric         strm.EOL();
16630b57cec5SDimitry Andric         strm.Printf("     typedef '%s': ",
16640b57cec5SDimitry Andric                     typedef_type_sp->GetName().GetCString());
16650b57cec5SDimitry Andric         typedefed_type_sp->GetFullCompilerType();
1666e8d8bef9SDimitry Andric         typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true,
1667e8d8bef9SDimitry Andric                                           target);
16680b57cec5SDimitry Andric         typedef_type_sp = typedefed_type_sp;
16690b57cec5SDimitry Andric         typedefed_type_sp = typedef_type_sp->GetTypedefType();
16700b57cec5SDimitry Andric       }
16710b57cec5SDimitry Andric       strm.EOL();
16720b57cec5SDimitry Andric     }
1673bdd1243dSDimitry Andric   }
16749dba64beSDimitry Andric   return type_list.GetSize();
16750b57cec5SDimitry Andric }
16760b57cec5SDimitry Andric 
1677e8d8bef9SDimitry Andric static size_t LookupTypeHere(Target *target, CommandInterpreter &interpreter,
1678e8d8bef9SDimitry Andric                              Stream &strm, Module &module,
1679e8d8bef9SDimitry Andric                              const char *name_cstr, bool name_is_regex) {
16800b57cec5SDimitry Andric   TypeList type_list;
16810b57cec5SDimitry Andric   const uint32_t max_num_matches = UINT32_MAX;
16820b57cec5SDimitry Andric   bool name_is_fully_qualified = false;
16830b57cec5SDimitry Andric 
16840b57cec5SDimitry Andric   ConstString name(name_cstr);
16850b57cec5SDimitry Andric   llvm::DenseSet<SymbolFile *> searched_symbol_files;
16869dba64beSDimitry Andric   module.FindTypes(name, name_is_fully_qualified, max_num_matches,
16870b57cec5SDimitry Andric                    searched_symbol_files, type_list);
16880b57cec5SDimitry Andric 
16899dba64beSDimitry Andric   if (type_list.Empty())
16909dba64beSDimitry Andric     return 0;
16919dba64beSDimitry Andric 
16920b57cec5SDimitry Andric   strm.Indent();
16930b57cec5SDimitry Andric   strm.PutCString("Best match found in ");
16940b57cec5SDimitry Andric   DumpFullpath(strm, &module.GetFileSpec(), 0);
16950b57cec5SDimitry Andric   strm.PutCString(":\n");
16960b57cec5SDimitry Andric 
16970b57cec5SDimitry Andric   TypeSP type_sp(type_list.GetTypeAtIndex(0));
16980b57cec5SDimitry Andric   if (type_sp) {
16990b57cec5SDimitry Andric     // Resolve the clang type so that any forward references to types that
17000b57cec5SDimitry Andric     // haven't yet been parsed will get parsed.
17010b57cec5SDimitry Andric     type_sp->GetFullCompilerType();
1702e8d8bef9SDimitry Andric     type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target);
1703e8d8bef9SDimitry Andric     // Print all typedef chains.
17040b57cec5SDimitry Andric     TypeSP typedef_type_sp(type_sp);
17050b57cec5SDimitry Andric     TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
17060b57cec5SDimitry Andric     while (typedefed_type_sp) {
17070b57cec5SDimitry Andric       strm.EOL();
17080b57cec5SDimitry Andric       strm.Printf("     typedef '%s': ",
17090b57cec5SDimitry Andric                   typedef_type_sp->GetName().GetCString());
17100b57cec5SDimitry Andric       typedefed_type_sp->GetFullCompilerType();
1711e8d8bef9SDimitry Andric       typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true,
1712e8d8bef9SDimitry Andric                                         target);
17130b57cec5SDimitry Andric       typedef_type_sp = typedefed_type_sp;
17140b57cec5SDimitry Andric       typedefed_type_sp = typedef_type_sp->GetTypedefType();
17150b57cec5SDimitry Andric     }
17160b57cec5SDimitry Andric   }
17170b57cec5SDimitry Andric   strm.EOL();
17189dba64beSDimitry Andric   return type_list.GetSize();
17190b57cec5SDimitry Andric }
17200b57cec5SDimitry Andric 
17210b57cec5SDimitry Andric static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter,
17220b57cec5SDimitry Andric                                           Stream &strm, Module *module,
17230b57cec5SDimitry Andric                                           const FileSpec &file_spec,
17240b57cec5SDimitry Andric                                           uint32_t line, bool check_inlines,
172581ad6265SDimitry Andric                                           bool verbose, bool all_ranges) {
17260b57cec5SDimitry Andric   if (module && file_spec) {
17270b57cec5SDimitry Andric     SymbolContextList sc_list;
17280b57cec5SDimitry Andric     const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(
17290b57cec5SDimitry Andric         file_spec, line, check_inlines, eSymbolContextEverything, sc_list);
17300b57cec5SDimitry Andric     if (num_matches > 0) {
17310b57cec5SDimitry Andric       strm.Indent();
17320b57cec5SDimitry Andric       strm.Printf("%u match%s found in ", num_matches,
17330b57cec5SDimitry Andric                   num_matches > 1 ? "es" : "");
17340b57cec5SDimitry Andric       strm << file_spec;
17350b57cec5SDimitry Andric       if (line > 0)
17360b57cec5SDimitry Andric         strm.Printf(":%u", line);
17370b57cec5SDimitry Andric       strm << " in ";
17380b57cec5SDimitry Andric       DumpFullpath(strm, &module->GetFileSpec(), 0);
17390b57cec5SDimitry Andric       strm.PutCString(":\n");
17400b57cec5SDimitry Andric       DumpSymbolContextList(
17410b57cec5SDimitry Andric           interpreter.GetExecutionContext().GetBestExecutionContextScope(),
174281ad6265SDimitry Andric           strm, sc_list, verbose, all_ranges);
17430b57cec5SDimitry Andric       return num_matches;
17440b57cec5SDimitry Andric     }
17450b57cec5SDimitry Andric   }
17460b57cec5SDimitry Andric   return 0;
17470b57cec5SDimitry Andric }
17480b57cec5SDimitry Andric 
17490b57cec5SDimitry Andric static size_t FindModulesByName(Target *target, const char *module_name,
17500b57cec5SDimitry Andric                                 ModuleList &module_list,
17510b57cec5SDimitry Andric                                 bool check_global_list) {
17520b57cec5SDimitry Andric   FileSpec module_file_spec(module_name);
17530b57cec5SDimitry Andric   ModuleSpec module_spec(module_file_spec);
17540b57cec5SDimitry Andric 
17550b57cec5SDimitry Andric   const size_t initial_size = module_list.GetSize();
17560b57cec5SDimitry Andric 
17570b57cec5SDimitry Andric   if (check_global_list) {
17580b57cec5SDimitry Andric     // Check the global list
17590b57cec5SDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
17600b57cec5SDimitry Andric         Module::GetAllocationModuleCollectionMutex());
17610b57cec5SDimitry Andric     const size_t num_modules = Module::GetNumberAllocatedModules();
17620b57cec5SDimitry Andric     ModuleSP module_sp;
17630b57cec5SDimitry Andric     for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
17640b57cec5SDimitry Andric       Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
17650b57cec5SDimitry Andric 
17660b57cec5SDimitry Andric       if (module) {
17670b57cec5SDimitry Andric         if (module->MatchesModuleSpec(module_spec)) {
17680b57cec5SDimitry Andric           module_sp = module->shared_from_this();
17690b57cec5SDimitry Andric           module_list.AppendIfNeeded(module_sp);
17700b57cec5SDimitry Andric         }
17710b57cec5SDimitry Andric       }
17720b57cec5SDimitry Andric     }
17730b57cec5SDimitry Andric   } else {
17740b57cec5SDimitry Andric     if (target) {
17750b57cec5SDimitry Andric       target->GetImages().FindModules(module_spec, module_list);
17769dba64beSDimitry Andric       const size_t num_matches = module_list.GetSize();
17770b57cec5SDimitry Andric 
17780b57cec5SDimitry Andric       // Not found in our module list for our target, check the main shared
17790b57cec5SDimitry Andric       // module list in case it is a extra file used somewhere else
17800b57cec5SDimitry Andric       if (num_matches == 0) {
17810b57cec5SDimitry Andric         module_spec.GetArchitecture() = target->GetArchitecture();
17820b57cec5SDimitry Andric         ModuleList::FindSharedModules(module_spec, module_list);
17830b57cec5SDimitry Andric       }
17840b57cec5SDimitry Andric     } else {
17850b57cec5SDimitry Andric       ModuleList::FindSharedModules(module_spec, module_list);
17860b57cec5SDimitry Andric     }
17870b57cec5SDimitry Andric   }
17880b57cec5SDimitry Andric 
17890b57cec5SDimitry Andric   return module_list.GetSize() - initial_size;
17900b57cec5SDimitry Andric }
17910b57cec5SDimitry Andric 
17920b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesModuleAutoComplete
17930b57cec5SDimitry Andric 
17940b57cec5SDimitry Andric // A base command object class that can auto complete with module file
17950b57cec5SDimitry Andric // paths
17960b57cec5SDimitry Andric 
17970b57cec5SDimitry Andric class CommandObjectTargetModulesModuleAutoComplete
17980b57cec5SDimitry Andric     : public CommandObjectParsed {
17990b57cec5SDimitry Andric public:
18000b57cec5SDimitry Andric   CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter &interpreter,
18010b57cec5SDimitry Andric                                                const char *name,
18020b57cec5SDimitry Andric                                                const char *help,
18039dba64beSDimitry Andric                                                const char *syntax,
18049dba64beSDimitry Andric                                                uint32_t flags = 0)
18059dba64beSDimitry Andric       : CommandObjectParsed(interpreter, name, help, syntax, flags) {
18060b57cec5SDimitry Andric     CommandArgumentEntry arg;
18070b57cec5SDimitry Andric     CommandArgumentData file_arg;
18080b57cec5SDimitry Andric 
18090b57cec5SDimitry Andric     // Define the first (and only) variant of this arg.
18100b57cec5SDimitry Andric     file_arg.arg_type = eArgTypeFilename;
18110b57cec5SDimitry Andric     file_arg.arg_repetition = eArgRepeatStar;
18120b57cec5SDimitry Andric 
18130b57cec5SDimitry Andric     // There is only one variant this argument could be; put it into the
18140b57cec5SDimitry Andric     // argument entry.
18150b57cec5SDimitry Andric     arg.push_back(file_arg);
18160b57cec5SDimitry Andric 
18170b57cec5SDimitry Andric     // Push the data for the first argument into the m_arguments vector.
18180b57cec5SDimitry Andric     m_arguments.push_back(arg);
18190b57cec5SDimitry Andric   }
18200b57cec5SDimitry Andric 
18210b57cec5SDimitry Andric   ~CommandObjectTargetModulesModuleAutoComplete() override = default;
18220b57cec5SDimitry Andric 
18239dba64beSDimitry Andric   void
18249dba64beSDimitry Andric   HandleArgumentCompletion(CompletionRequest &request,
18250b57cec5SDimitry Andric                            OptionElementVector &opt_element_vector) override {
1826*fe013be4SDimitry Andric     lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
1827*fe013be4SDimitry Andric         GetCommandInterpreter(), lldb::eModuleCompletion, request, nullptr);
18280b57cec5SDimitry Andric   }
18290b57cec5SDimitry Andric };
18300b57cec5SDimitry Andric 
18310b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesSourceFileAutoComplete
18320b57cec5SDimitry Andric 
18330b57cec5SDimitry Andric // A base command object class that can auto complete with module source
18340b57cec5SDimitry Andric // file paths
18350b57cec5SDimitry Andric 
18360b57cec5SDimitry Andric class CommandObjectTargetModulesSourceFileAutoComplete
18370b57cec5SDimitry Andric     : public CommandObjectParsed {
18380b57cec5SDimitry Andric public:
18390b57cec5SDimitry Andric   CommandObjectTargetModulesSourceFileAutoComplete(
18400b57cec5SDimitry Andric       CommandInterpreter &interpreter, const char *name, const char *help,
18410b57cec5SDimitry Andric       const char *syntax, uint32_t flags)
18420b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, name, help, syntax, flags) {
18430b57cec5SDimitry Andric     CommandArgumentEntry arg;
18440b57cec5SDimitry Andric     CommandArgumentData source_file_arg;
18450b57cec5SDimitry Andric 
18460b57cec5SDimitry Andric     // Define the first (and only) variant of this arg.
18470b57cec5SDimitry Andric     source_file_arg.arg_type = eArgTypeSourceFile;
18480b57cec5SDimitry Andric     source_file_arg.arg_repetition = eArgRepeatPlus;
18490b57cec5SDimitry Andric 
18500b57cec5SDimitry Andric     // There is only one variant this argument could be; put it into the
18510b57cec5SDimitry Andric     // argument entry.
18520b57cec5SDimitry Andric     arg.push_back(source_file_arg);
18530b57cec5SDimitry Andric 
18540b57cec5SDimitry Andric     // Push the data for the first argument into the m_arguments vector.
18550b57cec5SDimitry Andric     m_arguments.push_back(arg);
18560b57cec5SDimitry Andric   }
18570b57cec5SDimitry Andric 
18580b57cec5SDimitry Andric   ~CommandObjectTargetModulesSourceFileAutoComplete() override = default;
18590b57cec5SDimitry Andric 
18609dba64beSDimitry Andric   void
18619dba64beSDimitry Andric   HandleArgumentCompletion(CompletionRequest &request,
18620b57cec5SDimitry Andric                            OptionElementVector &opt_element_vector) override {
1863*fe013be4SDimitry Andric     lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
1864*fe013be4SDimitry Andric         GetCommandInterpreter(), lldb::eSourceFileCompletion, request, nullptr);
18650b57cec5SDimitry Andric   }
18660b57cec5SDimitry Andric };
18670b57cec5SDimitry Andric 
18680b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesDumpObjfile
18690b57cec5SDimitry Andric 
18700b57cec5SDimitry Andric class CommandObjectTargetModulesDumpObjfile
18710b57cec5SDimitry Andric     : public CommandObjectTargetModulesModuleAutoComplete {
18720b57cec5SDimitry Andric public:
18730b57cec5SDimitry Andric   CommandObjectTargetModulesDumpObjfile(CommandInterpreter &interpreter)
18740b57cec5SDimitry Andric       : CommandObjectTargetModulesModuleAutoComplete(
18750b57cec5SDimitry Andric             interpreter, "target modules dump objfile",
18760b57cec5SDimitry Andric             "Dump the object file headers from one or more target modules.",
18779dba64beSDimitry Andric             nullptr, eCommandRequiresTarget) {}
18780b57cec5SDimitry Andric 
18790b57cec5SDimitry Andric   ~CommandObjectTargetModulesDumpObjfile() override = default;
18800b57cec5SDimitry Andric 
18810b57cec5SDimitry Andric protected:
18820b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
18839dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
18840b57cec5SDimitry Andric 
18850b57cec5SDimitry Andric     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
18860b57cec5SDimitry Andric     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
18870b57cec5SDimitry Andric     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
18880b57cec5SDimitry Andric 
18890b57cec5SDimitry Andric     size_t num_dumped = 0;
18900b57cec5SDimitry Andric     if (command.GetArgumentCount() == 0) {
18910b57cec5SDimitry Andric       // Dump all headers for all modules images
18920b57cec5SDimitry Andric       num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(),
18930b57cec5SDimitry Andric                                             target->GetImages());
18940b57cec5SDimitry Andric       if (num_dumped == 0) {
18950b57cec5SDimitry Andric         result.AppendError("the target has no associated executable images");
18960b57cec5SDimitry Andric       }
18970b57cec5SDimitry Andric     } else {
18980b57cec5SDimitry Andric       // Find the modules that match the basename or full path.
18990b57cec5SDimitry Andric       ModuleList module_list;
19000b57cec5SDimitry Andric       const char *arg_cstr;
19010b57cec5SDimitry Andric       for (int arg_idx = 0;
19020b57cec5SDimitry Andric            (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
19030b57cec5SDimitry Andric            ++arg_idx) {
19040b57cec5SDimitry Andric         size_t num_matched =
19050b57cec5SDimitry Andric             FindModulesByName(target, arg_cstr, module_list, true);
19060b57cec5SDimitry Andric         if (num_matched == 0) {
19070b57cec5SDimitry Andric           result.AppendWarningWithFormat(
19080b57cec5SDimitry Andric               "Unable to find an image that matches '%s'.\n", arg_cstr);
19090b57cec5SDimitry Andric         }
19100b57cec5SDimitry Andric       }
19110b57cec5SDimitry Andric       // Dump all the modules we found.
19120b57cec5SDimitry Andric       num_dumped =
19130b57cec5SDimitry Andric           DumpModuleObjfileHeaders(result.GetOutputStream(), module_list);
19140b57cec5SDimitry Andric     }
19150b57cec5SDimitry Andric 
19160b57cec5SDimitry Andric     if (num_dumped > 0) {
19170b57cec5SDimitry Andric       result.SetStatus(eReturnStatusSuccessFinishResult);
19180b57cec5SDimitry Andric     } else {
19190b57cec5SDimitry Andric       result.AppendError("no matching executable images found");
19200b57cec5SDimitry Andric     }
19210b57cec5SDimitry Andric     return result.Succeeded();
19220b57cec5SDimitry Andric   }
19230b57cec5SDimitry Andric };
19240b57cec5SDimitry Andric 
19250b57cec5SDimitry Andric #define LLDB_OPTIONS_target_modules_dump_symtab
19260b57cec5SDimitry Andric #include "CommandOptions.inc"
19270b57cec5SDimitry Andric 
19280b57cec5SDimitry Andric class CommandObjectTargetModulesDumpSymtab
19290b57cec5SDimitry Andric     : public CommandObjectTargetModulesModuleAutoComplete {
19300b57cec5SDimitry Andric public:
19310b57cec5SDimitry Andric   CommandObjectTargetModulesDumpSymtab(CommandInterpreter &interpreter)
19320b57cec5SDimitry Andric       : CommandObjectTargetModulesModuleAutoComplete(
19330b57cec5SDimitry Andric             interpreter, "target modules dump symtab",
19349dba64beSDimitry Andric             "Dump the symbol table from one or more target modules.", nullptr,
193504eeddc0SDimitry Andric             eCommandRequiresTarget) {}
19360b57cec5SDimitry Andric 
19370b57cec5SDimitry Andric   ~CommandObjectTargetModulesDumpSymtab() override = default;
19380b57cec5SDimitry Andric 
19390b57cec5SDimitry Andric   Options *GetOptions() override { return &m_options; }
19400b57cec5SDimitry Andric 
19410b57cec5SDimitry Andric   class CommandOptions : public Options {
19420b57cec5SDimitry Andric   public:
194381ad6265SDimitry Andric     CommandOptions() = default;
19440b57cec5SDimitry Andric 
19450b57cec5SDimitry Andric     ~CommandOptions() override = default;
19460b57cec5SDimitry Andric 
19470b57cec5SDimitry Andric     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
19480b57cec5SDimitry Andric                           ExecutionContext *execution_context) override {
19490b57cec5SDimitry Andric       Status error;
19500b57cec5SDimitry Andric       const int short_option = m_getopt_table[option_idx].val;
19510b57cec5SDimitry Andric 
19520b57cec5SDimitry Andric       switch (short_option) {
1953480093f4SDimitry Andric       case 'm':
1954480093f4SDimitry Andric         m_prefer_mangled.SetCurrentValue(true);
1955480093f4SDimitry Andric         m_prefer_mangled.SetOptionWasSet();
1956480093f4SDimitry Andric         break;
1957480093f4SDimitry Andric 
19580b57cec5SDimitry Andric       case 's':
19590b57cec5SDimitry Andric         m_sort_order = (SortOrder)OptionArgParser::ToOptionEnum(
19600b57cec5SDimitry Andric             option_arg, GetDefinitions()[option_idx].enum_values,
19610b57cec5SDimitry Andric             eSortOrderNone, error);
19620b57cec5SDimitry Andric         break;
19630b57cec5SDimitry Andric 
19640b57cec5SDimitry Andric       default:
19659dba64beSDimitry Andric         llvm_unreachable("Unimplemented option");
19660b57cec5SDimitry Andric       }
19670b57cec5SDimitry Andric       return error;
19680b57cec5SDimitry Andric     }
19690b57cec5SDimitry Andric 
19700b57cec5SDimitry Andric     void OptionParsingStarting(ExecutionContext *execution_context) override {
19710b57cec5SDimitry Andric       m_sort_order = eSortOrderNone;
1972480093f4SDimitry Andric       m_prefer_mangled.Clear();
19730b57cec5SDimitry Andric     }
19740b57cec5SDimitry Andric 
19750b57cec5SDimitry Andric     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1976bdd1243dSDimitry Andric       return llvm::ArrayRef(g_target_modules_dump_symtab_options);
19770b57cec5SDimitry Andric     }
19780b57cec5SDimitry Andric 
1979fe6060f1SDimitry Andric     SortOrder m_sort_order = eSortOrderNone;
1980480093f4SDimitry Andric     OptionValueBoolean m_prefer_mangled = {false, false};
19810b57cec5SDimitry Andric   };
19820b57cec5SDimitry Andric 
19830b57cec5SDimitry Andric protected:
19840b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
19859dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
19860b57cec5SDimitry Andric     uint32_t num_dumped = 0;
1987480093f4SDimitry Andric     Mangled::NamePreference name_preference =
1988480093f4SDimitry Andric         (m_options.m_prefer_mangled ? Mangled::ePreferMangled
1989480093f4SDimitry Andric                                     : Mangled::ePreferDemangled);
19900b57cec5SDimitry Andric 
19910b57cec5SDimitry Andric     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
19920b57cec5SDimitry Andric     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
19930b57cec5SDimitry Andric     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
19940b57cec5SDimitry Andric 
19950b57cec5SDimitry Andric     if (command.GetArgumentCount() == 0) {
19960b57cec5SDimitry Andric       // Dump all sections for all modules images
1997e8d8bef9SDimitry Andric       const ModuleList &module_list = target->GetImages();
1998e8d8bef9SDimitry Andric       std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
1999e8d8bef9SDimitry Andric       const size_t num_modules = module_list.GetSize();
20000b57cec5SDimitry Andric       if (num_modules > 0) {
2001e8d8bef9SDimitry Andric         result.GetOutputStream().Format(
2002e8d8bef9SDimitry Andric             "Dumping symbol table for {0} modules.\n", num_modules);
2003e8d8bef9SDimitry Andric         for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
20040b57cec5SDimitry Andric           if (num_dumped > 0) {
20050b57cec5SDimitry Andric             result.GetOutputStream().EOL();
20060b57cec5SDimitry Andric             result.GetOutputStream().EOL();
20070b57cec5SDimitry Andric           }
2008*fe013be4SDimitry Andric           if (INTERRUPT_REQUESTED(GetDebugger(),
2009*fe013be4SDimitry Andric                                   "Interrupted in dump all symtabs with {0} "
2010*fe013be4SDimitry Andric                                   "of {1} dumped.", num_dumped, num_modules))
20110b57cec5SDimitry Andric             break;
2012*fe013be4SDimitry Andric 
20130b57cec5SDimitry Andric           num_dumped++;
2014e8d8bef9SDimitry Andric           DumpModuleSymtab(m_interpreter, result.GetOutputStream(),
2015e8d8bef9SDimitry Andric                            module_sp.get(), m_options.m_sort_order,
2016e8d8bef9SDimitry Andric                            name_preference);
20170b57cec5SDimitry Andric         }
20180b57cec5SDimitry Andric       } else {
20190b57cec5SDimitry Andric         result.AppendError("the target has no associated executable images");
20200b57cec5SDimitry Andric         return false;
20210b57cec5SDimitry Andric       }
20220b57cec5SDimitry Andric     } else {
20230b57cec5SDimitry Andric       // Dump specified images (by basename or fullpath)
20240b57cec5SDimitry Andric       const char *arg_cstr;
20250b57cec5SDimitry Andric       for (int arg_idx = 0;
20260b57cec5SDimitry Andric            (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
20270b57cec5SDimitry Andric            ++arg_idx) {
20280b57cec5SDimitry Andric         ModuleList module_list;
20290b57cec5SDimitry Andric         const size_t num_matches =
20300b57cec5SDimitry Andric             FindModulesByName(target, arg_cstr, module_list, true);
20310b57cec5SDimitry Andric         if (num_matches > 0) {
2032e8d8bef9SDimitry Andric           for (ModuleSP module_sp : module_list.Modules()) {
2033e8d8bef9SDimitry Andric             if (module_sp) {
20340b57cec5SDimitry Andric               if (num_dumped > 0) {
20350b57cec5SDimitry Andric                 result.GetOutputStream().EOL();
20360b57cec5SDimitry Andric                 result.GetOutputStream().EOL();
20370b57cec5SDimitry Andric               }
2038*fe013be4SDimitry Andric               if (INTERRUPT_REQUESTED(GetDebugger(),
2039*fe013be4SDimitry Andric                     "Interrupted in dump symtab list with {0} of {1} dumped.",
2040*fe013be4SDimitry Andric                     num_dumped, num_matches))
20410b57cec5SDimitry Andric                 break;
2042*fe013be4SDimitry Andric 
20430b57cec5SDimitry Andric               num_dumped++;
2044e8d8bef9SDimitry Andric               DumpModuleSymtab(m_interpreter, result.GetOutputStream(),
2045e8d8bef9SDimitry Andric                                module_sp.get(), m_options.m_sort_order,
2046e8d8bef9SDimitry Andric                                name_preference);
20470b57cec5SDimitry Andric             }
20480b57cec5SDimitry Andric           }
20490b57cec5SDimitry Andric         } else
20500b57cec5SDimitry Andric           result.AppendWarningWithFormat(
20510b57cec5SDimitry Andric               "Unable to find an image that matches '%s'.\n", arg_cstr);
20520b57cec5SDimitry Andric       }
20530b57cec5SDimitry Andric     }
20540b57cec5SDimitry Andric 
20550b57cec5SDimitry Andric     if (num_dumped > 0)
20560b57cec5SDimitry Andric       result.SetStatus(eReturnStatusSuccessFinishResult);
20570b57cec5SDimitry Andric     else {
20580b57cec5SDimitry Andric       result.AppendError("no matching executable images found");
20590b57cec5SDimitry Andric     }
20600b57cec5SDimitry Andric     return result.Succeeded();
20610b57cec5SDimitry Andric   }
20620b57cec5SDimitry Andric 
20630b57cec5SDimitry Andric   CommandOptions m_options;
20640b57cec5SDimitry Andric };
20650b57cec5SDimitry Andric 
20660b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesDumpSections
20670b57cec5SDimitry Andric 
20680b57cec5SDimitry Andric // Image section dumping command
20690b57cec5SDimitry Andric 
20700b57cec5SDimitry Andric class CommandObjectTargetModulesDumpSections
20710b57cec5SDimitry Andric     : public CommandObjectTargetModulesModuleAutoComplete {
20720b57cec5SDimitry Andric public:
20730b57cec5SDimitry Andric   CommandObjectTargetModulesDumpSections(CommandInterpreter &interpreter)
20740b57cec5SDimitry Andric       : CommandObjectTargetModulesModuleAutoComplete(
20750b57cec5SDimitry Andric             interpreter, "target modules dump sections",
20760b57cec5SDimitry Andric             "Dump the sections from one or more target modules.",
20770b57cec5SDimitry Andric             //"target modules dump sections [<file1> ...]")
20789dba64beSDimitry Andric             nullptr, eCommandRequiresTarget) {}
20790b57cec5SDimitry Andric 
20800b57cec5SDimitry Andric   ~CommandObjectTargetModulesDumpSections() override = default;
20810b57cec5SDimitry Andric 
20820b57cec5SDimitry Andric protected:
20830b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
20849dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
20850b57cec5SDimitry Andric     uint32_t num_dumped = 0;
20860b57cec5SDimitry Andric 
20870b57cec5SDimitry Andric     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
20880b57cec5SDimitry Andric     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
20890b57cec5SDimitry Andric     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
20900b57cec5SDimitry Andric 
20910b57cec5SDimitry Andric     if (command.GetArgumentCount() == 0) {
20920b57cec5SDimitry Andric       // Dump all sections for all modules images
20930b57cec5SDimitry Andric       const size_t num_modules = target->GetImages().GetSize();
2094e8d8bef9SDimitry Andric       if (num_modules == 0) {
2095e8d8bef9SDimitry Andric         result.AppendError("the target has no associated executable images");
2096e8d8bef9SDimitry Andric         return false;
2097e8d8bef9SDimitry Andric       }
2098e8d8bef9SDimitry Andric 
2099e8d8bef9SDimitry Andric       result.GetOutputStream().Format("Dumping sections for {0} modules.\n",
2100e8d8bef9SDimitry Andric                                       num_modules);
21010b57cec5SDimitry Andric       for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2102*fe013be4SDimitry Andric         if (INTERRUPT_REQUESTED(GetDebugger(),
2103*fe013be4SDimitry Andric               "Interrupted in dump all sections with {0} of {1} dumped",
2104*fe013be4SDimitry Andric               image_idx, num_modules))
21050b57cec5SDimitry Andric           break;
2106*fe013be4SDimitry Andric 
21070b57cec5SDimitry Andric         num_dumped++;
21080b57cec5SDimitry Andric         DumpModuleSections(
21090b57cec5SDimitry Andric             m_interpreter, result.GetOutputStream(),
21100b57cec5SDimitry Andric             target->GetImages().GetModulePointerAtIndex(image_idx));
21110b57cec5SDimitry Andric       }
21120b57cec5SDimitry Andric     } else {
21130b57cec5SDimitry Andric       // Dump specified images (by basename or fullpath)
21140b57cec5SDimitry Andric       const char *arg_cstr;
21150b57cec5SDimitry Andric       for (int arg_idx = 0;
21160b57cec5SDimitry Andric            (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
21170b57cec5SDimitry Andric            ++arg_idx) {
21180b57cec5SDimitry Andric         ModuleList module_list;
21190b57cec5SDimitry Andric         const size_t num_matches =
21200b57cec5SDimitry Andric             FindModulesByName(target, arg_cstr, module_list, true);
21210b57cec5SDimitry Andric         if (num_matches > 0) {
21220b57cec5SDimitry Andric           for (size_t i = 0; i < num_matches; ++i) {
2123*fe013be4SDimitry Andric             if (INTERRUPT_REQUESTED(GetDebugger(),
2124*fe013be4SDimitry Andric                   "Interrupted in dump section list with {0} of {1} dumped.",
2125*fe013be4SDimitry Andric                   i, num_matches))
21260b57cec5SDimitry Andric               break;
2127*fe013be4SDimitry Andric 
21280b57cec5SDimitry Andric             Module *module = module_list.GetModulePointerAtIndex(i);
21290b57cec5SDimitry Andric             if (module) {
21300b57cec5SDimitry Andric               num_dumped++;
21310b57cec5SDimitry Andric               DumpModuleSections(m_interpreter, result.GetOutputStream(),
21320b57cec5SDimitry Andric                                  module);
21330b57cec5SDimitry Andric             }
21340b57cec5SDimitry Andric           }
21350b57cec5SDimitry Andric         } else {
21360b57cec5SDimitry Andric           // Check the global list
21370b57cec5SDimitry Andric           std::lock_guard<std::recursive_mutex> guard(
21380b57cec5SDimitry Andric               Module::GetAllocationModuleCollectionMutex());
21390b57cec5SDimitry Andric 
21400b57cec5SDimitry Andric           result.AppendWarningWithFormat(
21410b57cec5SDimitry Andric               "Unable to find an image that matches '%s'.\n", arg_cstr);
21420b57cec5SDimitry Andric         }
21430b57cec5SDimitry Andric       }
21440b57cec5SDimitry Andric     }
21450b57cec5SDimitry Andric 
21460b57cec5SDimitry Andric     if (num_dumped > 0)
21470b57cec5SDimitry Andric       result.SetStatus(eReturnStatusSuccessFinishResult);
21480b57cec5SDimitry Andric     else {
21490b57cec5SDimitry Andric       result.AppendError("no matching executable images found");
21500b57cec5SDimitry Andric     }
21510b57cec5SDimitry Andric     return result.Succeeded();
21520b57cec5SDimitry Andric   }
21530b57cec5SDimitry Andric };
21540b57cec5SDimitry Andric 
2155753f127fSDimitry Andric class CommandObjectTargetModulesDumpClangPCMInfo : public CommandObjectParsed {
2156753f127fSDimitry Andric public:
2157753f127fSDimitry Andric   CommandObjectTargetModulesDumpClangPCMInfo(CommandInterpreter &interpreter)
2158753f127fSDimitry Andric       : CommandObjectParsed(
2159753f127fSDimitry Andric             interpreter, "target modules dump pcm-info",
2160753f127fSDimitry Andric             "Dump information about the given clang module (pcm).") {
2161753f127fSDimitry Andric     // Take a single file argument.
2162753f127fSDimitry Andric     CommandArgumentData arg{eArgTypeFilename, eArgRepeatPlain};
2163753f127fSDimitry Andric     m_arguments.push_back({arg});
2164753f127fSDimitry Andric   }
2165753f127fSDimitry Andric 
2166753f127fSDimitry Andric   ~CommandObjectTargetModulesDumpClangPCMInfo() override = default;
2167753f127fSDimitry Andric 
2168753f127fSDimitry Andric protected:
2169753f127fSDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
2170753f127fSDimitry Andric     if (command.GetArgumentCount() != 1) {
2171753f127fSDimitry Andric       result.AppendErrorWithFormat("'%s' takes exactly one pcm path argument.",
2172753f127fSDimitry Andric                                    m_cmd_name.c_str());
2173753f127fSDimitry Andric       return false;
2174753f127fSDimitry Andric     }
2175753f127fSDimitry Andric 
2176753f127fSDimitry Andric     const char *pcm_path = command.GetArgumentAtIndex(0);
2177*fe013be4SDimitry Andric     const FileSpec pcm_file{pcm_path};
2178753f127fSDimitry Andric 
2179*fe013be4SDimitry Andric     if (pcm_file.GetFileNameExtension() != ".pcm") {
2180753f127fSDimitry Andric       result.AppendError("file must have a .pcm extension");
2181753f127fSDimitry Andric       return false;
2182753f127fSDimitry Andric     }
2183753f127fSDimitry Andric 
2184753f127fSDimitry Andric     if (!FileSystem::Instance().Exists(pcm_file)) {
2185753f127fSDimitry Andric       result.AppendError("pcm file does not exist");
2186753f127fSDimitry Andric       return false;
2187753f127fSDimitry Andric     }
2188753f127fSDimitry Andric 
2189753f127fSDimitry Andric     clang::CompilerInstance compiler;
2190753f127fSDimitry Andric     compiler.createDiagnostics();
2191753f127fSDimitry Andric 
2192753f127fSDimitry Andric     const char *clang_args[] = {"clang", pcm_path};
2193753f127fSDimitry Andric     compiler.setInvocation(clang::createInvocation(clang_args));
2194753f127fSDimitry Andric 
2195*fe013be4SDimitry Andric     // Pass empty deleter to not attempt to free memory that was allocated
2196*fe013be4SDimitry Andric     // outside of the current scope, possibly statically.
2197*fe013be4SDimitry Andric     std::shared_ptr<llvm::raw_ostream> Out(
2198*fe013be4SDimitry Andric         &result.GetOutputStream().AsRawOstream(), [](llvm::raw_ostream *) {});
2199*fe013be4SDimitry Andric     clang::DumpModuleInfoAction dump_module_info(Out);
2200753f127fSDimitry Andric     // DumpModuleInfoAction requires ObjectFilePCHContainerReader.
2201753f127fSDimitry Andric     compiler.getPCHContainerOperations()->registerReader(
2202753f127fSDimitry Andric         std::make_unique<clang::ObjectFilePCHContainerReader>());
2203753f127fSDimitry Andric 
2204753f127fSDimitry Andric     if (compiler.ExecuteAction(dump_module_info))
2205753f127fSDimitry Andric       result.SetStatus(eReturnStatusSuccessFinishResult);
2206753f127fSDimitry Andric 
2207753f127fSDimitry Andric     return result.Succeeded();
2208753f127fSDimitry Andric   }
2209753f127fSDimitry Andric };
2210753f127fSDimitry Andric 
22115ffd83dbSDimitry Andric #pragma mark CommandObjectTargetModulesDumpClangAST
22120b57cec5SDimitry Andric 
22130b57cec5SDimitry Andric // Clang AST dumping command
22140b57cec5SDimitry Andric 
22150b57cec5SDimitry Andric class CommandObjectTargetModulesDumpClangAST
22160b57cec5SDimitry Andric     : public CommandObjectTargetModulesModuleAutoComplete {
22170b57cec5SDimitry Andric public:
22180b57cec5SDimitry Andric   CommandObjectTargetModulesDumpClangAST(CommandInterpreter &interpreter)
22190b57cec5SDimitry Andric       : CommandObjectTargetModulesModuleAutoComplete(
22200b57cec5SDimitry Andric             interpreter, "target modules dump ast",
22210b57cec5SDimitry Andric             "Dump the clang ast for a given module's symbol file.",
22220b57cec5SDimitry Andric             //"target modules dump ast [<file1> ...]")
22239dba64beSDimitry Andric             nullptr, eCommandRequiresTarget) {}
22240b57cec5SDimitry Andric 
22250b57cec5SDimitry Andric   ~CommandObjectTargetModulesDumpClangAST() override = default;
22260b57cec5SDimitry Andric 
22270b57cec5SDimitry Andric protected:
22280b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
22299dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
22300b57cec5SDimitry Andric 
2231e8d8bef9SDimitry Andric     const ModuleList &module_list = target->GetImages();
2232e8d8bef9SDimitry Andric     const size_t num_modules = module_list.GetSize();
22330b57cec5SDimitry Andric     if (num_modules == 0) {
22340b57cec5SDimitry Andric       result.AppendError("the target has no associated executable images");
22350b57cec5SDimitry Andric       return false;
22360b57cec5SDimitry Andric     }
22370b57cec5SDimitry Andric 
22380b57cec5SDimitry Andric     if (command.GetArgumentCount() == 0) {
22390b57cec5SDimitry Andric       // Dump all ASTs for all modules images
2240e8d8bef9SDimitry Andric       result.GetOutputStream().Format("Dumping clang ast for {0} modules.\n",
2241e8d8bef9SDimitry Andric                                       num_modules);
2242e8d8bef9SDimitry Andric       for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
2243*fe013be4SDimitry Andric         if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted dumping clang ast"))
22440b57cec5SDimitry Andric           break;
2245e8d8bef9SDimitry Andric         if (SymbolFile *sf = module_sp->GetSymbolFile())
22460b57cec5SDimitry Andric           sf->DumpClangAST(result.GetOutputStream());
22470b57cec5SDimitry Andric       }
22480b57cec5SDimitry Andric       result.SetStatus(eReturnStatusSuccessFinishResult);
22490b57cec5SDimitry Andric       return true;
22500b57cec5SDimitry Andric     }
22510b57cec5SDimitry Andric 
22520b57cec5SDimitry Andric     // Dump specified ASTs (by basename or fullpath)
22530b57cec5SDimitry Andric     for (const Args::ArgEntry &arg : command.entries()) {
22540b57cec5SDimitry Andric       ModuleList module_list;
22550b57cec5SDimitry Andric       const size_t num_matches =
22560b57cec5SDimitry Andric           FindModulesByName(target, arg.c_str(), module_list, true);
22570b57cec5SDimitry Andric       if (num_matches == 0) {
22580b57cec5SDimitry Andric         // Check the global list
22590b57cec5SDimitry Andric         std::lock_guard<std::recursive_mutex> guard(
22600b57cec5SDimitry Andric             Module::GetAllocationModuleCollectionMutex());
22610b57cec5SDimitry Andric 
22620b57cec5SDimitry Andric         result.AppendWarningWithFormat(
22630b57cec5SDimitry Andric             "Unable to find an image that matches '%s'.\n", arg.c_str());
22640b57cec5SDimitry Andric         continue;
22650b57cec5SDimitry Andric       }
22660b57cec5SDimitry Andric 
22670b57cec5SDimitry Andric       for (size_t i = 0; i < num_matches; ++i) {
2268*fe013be4SDimitry Andric         if (INTERRUPT_REQUESTED(GetDebugger(),
2269*fe013be4SDimitry Andric               "Interrupted in dump clang ast list with {0} of {1} dumped.",
2270*fe013be4SDimitry Andric               i, num_matches))
22710b57cec5SDimitry Andric           break;
2272*fe013be4SDimitry Andric 
22730b57cec5SDimitry Andric         Module *m = module_list.GetModulePointerAtIndex(i);
22749dba64beSDimitry Andric         if (SymbolFile *sf = m->GetSymbolFile())
22750b57cec5SDimitry Andric           sf->DumpClangAST(result.GetOutputStream());
22760b57cec5SDimitry Andric       }
22770b57cec5SDimitry Andric     }
22780b57cec5SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishResult);
22790b57cec5SDimitry Andric     return true;
22800b57cec5SDimitry Andric   }
22810b57cec5SDimitry Andric };
22820b57cec5SDimitry Andric 
22830b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesDumpSymfile
22840b57cec5SDimitry Andric 
22850b57cec5SDimitry Andric // Image debug symbol dumping command
22860b57cec5SDimitry Andric 
22870b57cec5SDimitry Andric class CommandObjectTargetModulesDumpSymfile
22880b57cec5SDimitry Andric     : public CommandObjectTargetModulesModuleAutoComplete {
22890b57cec5SDimitry Andric public:
22900b57cec5SDimitry Andric   CommandObjectTargetModulesDumpSymfile(CommandInterpreter &interpreter)
22910b57cec5SDimitry Andric       : CommandObjectTargetModulesModuleAutoComplete(
22920b57cec5SDimitry Andric             interpreter, "target modules dump symfile",
22930b57cec5SDimitry Andric             "Dump the debug symbol file for one or more target modules.",
22940b57cec5SDimitry Andric             //"target modules dump symfile [<file1> ...]")
22959dba64beSDimitry Andric             nullptr, eCommandRequiresTarget) {}
22960b57cec5SDimitry Andric 
22970b57cec5SDimitry Andric   ~CommandObjectTargetModulesDumpSymfile() override = default;
22980b57cec5SDimitry Andric 
22990b57cec5SDimitry Andric protected:
23000b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
23019dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
23020b57cec5SDimitry Andric     uint32_t num_dumped = 0;
23030b57cec5SDimitry Andric 
23040b57cec5SDimitry Andric     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
23050b57cec5SDimitry Andric     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
23060b57cec5SDimitry Andric     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
23070b57cec5SDimitry Andric 
23080b57cec5SDimitry Andric     if (command.GetArgumentCount() == 0) {
23090b57cec5SDimitry Andric       // Dump all sections for all modules images
23100b57cec5SDimitry Andric       const ModuleList &target_modules = target->GetImages();
23110b57cec5SDimitry Andric       std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
23120b57cec5SDimitry Andric       const size_t num_modules = target_modules.GetSize();
2313e8d8bef9SDimitry Andric       if (num_modules == 0) {
23140b57cec5SDimitry Andric         result.AppendError("the target has no associated executable images");
23150b57cec5SDimitry Andric         return false;
23160b57cec5SDimitry Andric       }
2317e8d8bef9SDimitry Andric       result.GetOutputStream().Format(
2318e8d8bef9SDimitry Andric           "Dumping debug symbols for {0} modules.\n", num_modules);
2319e8d8bef9SDimitry Andric       for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
2320*fe013be4SDimitry Andric         if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted in dumping all "
2321*fe013be4SDimitry Andric                                 "debug symbols with {0} of {1} modules dumped",
2322*fe013be4SDimitry Andric                                  num_dumped, num_modules))
2323e8d8bef9SDimitry Andric           break;
2324*fe013be4SDimitry Andric 
2325e8d8bef9SDimitry Andric         if (DumpModuleSymbolFile(result.GetOutputStream(), module_sp.get()))
2326e8d8bef9SDimitry Andric           num_dumped++;
2327e8d8bef9SDimitry Andric       }
23280b57cec5SDimitry Andric     } else {
23290b57cec5SDimitry Andric       // Dump specified images (by basename or fullpath)
23300b57cec5SDimitry Andric       const char *arg_cstr;
23310b57cec5SDimitry Andric       for (int arg_idx = 0;
23320b57cec5SDimitry Andric            (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
23330b57cec5SDimitry Andric            ++arg_idx) {
23340b57cec5SDimitry Andric         ModuleList module_list;
23350b57cec5SDimitry Andric         const size_t num_matches =
23360b57cec5SDimitry Andric             FindModulesByName(target, arg_cstr, module_list, true);
23370b57cec5SDimitry Andric         if (num_matches > 0) {
23380b57cec5SDimitry Andric           for (size_t i = 0; i < num_matches; ++i) {
2339*fe013be4SDimitry Andric             if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted dumping {0} "
2340*fe013be4SDimitry Andric                                                    "of {1} requested modules",
2341*fe013be4SDimitry Andric                                                    i, num_matches))
23420b57cec5SDimitry Andric               break;
23430b57cec5SDimitry Andric             Module *module = module_list.GetModulePointerAtIndex(i);
23440b57cec5SDimitry Andric             if (module) {
23459dba64beSDimitry Andric               if (DumpModuleSymbolFile(result.GetOutputStream(), module))
23460b57cec5SDimitry Andric                 num_dumped++;
23470b57cec5SDimitry Andric             }
23480b57cec5SDimitry Andric           }
23490b57cec5SDimitry Andric         } else
23500b57cec5SDimitry Andric           result.AppendWarningWithFormat(
23510b57cec5SDimitry Andric               "Unable to find an image that matches '%s'.\n", arg_cstr);
23520b57cec5SDimitry Andric       }
23530b57cec5SDimitry Andric     }
23540b57cec5SDimitry Andric 
23550b57cec5SDimitry Andric     if (num_dumped > 0)
23560b57cec5SDimitry Andric       result.SetStatus(eReturnStatusSuccessFinishResult);
23570b57cec5SDimitry Andric     else {
23580b57cec5SDimitry Andric       result.AppendError("no matching executable images found");
23590b57cec5SDimitry Andric     }
23600b57cec5SDimitry Andric     return result.Succeeded();
23610b57cec5SDimitry Andric   }
23620b57cec5SDimitry Andric };
23630b57cec5SDimitry Andric 
23640b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesDumpLineTable
23659dba64beSDimitry Andric #define LLDB_OPTIONS_target_modules_dump
23669dba64beSDimitry Andric #include "CommandOptions.inc"
23670b57cec5SDimitry Andric 
23680b57cec5SDimitry Andric // Image debug line table dumping command
23690b57cec5SDimitry Andric 
23700b57cec5SDimitry Andric class CommandObjectTargetModulesDumpLineTable
23710b57cec5SDimitry Andric     : public CommandObjectTargetModulesSourceFileAutoComplete {
23720b57cec5SDimitry Andric public:
23730b57cec5SDimitry Andric   CommandObjectTargetModulesDumpLineTable(CommandInterpreter &interpreter)
23740b57cec5SDimitry Andric       : CommandObjectTargetModulesSourceFileAutoComplete(
23750b57cec5SDimitry Andric             interpreter, "target modules dump line-table",
23760b57cec5SDimitry Andric             "Dump the line table for one or more compilation units.", nullptr,
23770b57cec5SDimitry Andric             eCommandRequiresTarget) {}
23780b57cec5SDimitry Andric 
23790b57cec5SDimitry Andric   ~CommandObjectTargetModulesDumpLineTable() override = default;
23800b57cec5SDimitry Andric 
23810b57cec5SDimitry Andric   Options *GetOptions() override { return &m_options; }
23820b57cec5SDimitry Andric 
23830b57cec5SDimitry Andric protected:
23840b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
23850b57cec5SDimitry Andric     Target *target = m_exe_ctx.GetTargetPtr();
23860b57cec5SDimitry Andric     uint32_t total_num_dumped = 0;
23870b57cec5SDimitry Andric 
23880b57cec5SDimitry Andric     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
23890b57cec5SDimitry Andric     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
23900b57cec5SDimitry Andric     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
23910b57cec5SDimitry Andric 
23920b57cec5SDimitry Andric     if (command.GetArgumentCount() == 0) {
23930b57cec5SDimitry Andric       result.AppendError("file option must be specified.");
23940b57cec5SDimitry Andric       return result.Succeeded();
23950b57cec5SDimitry Andric     } else {
23960b57cec5SDimitry Andric       // Dump specified images (by basename or fullpath)
23970b57cec5SDimitry Andric       const char *arg_cstr;
23980b57cec5SDimitry Andric       for (int arg_idx = 0;
23990b57cec5SDimitry Andric            (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
24000b57cec5SDimitry Andric            ++arg_idx) {
24010b57cec5SDimitry Andric         FileSpec file_spec(arg_cstr);
24020b57cec5SDimitry Andric 
24030b57cec5SDimitry Andric         const ModuleList &target_modules = target->GetImages();
24040b57cec5SDimitry Andric         std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2405*fe013be4SDimitry Andric         size_t num_modules = target_modules.GetSize();
2406*fe013be4SDimitry Andric         if (num_modules > 0) {
24070b57cec5SDimitry Andric           uint32_t num_dumped = 0;
2408e8d8bef9SDimitry Andric           for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
2409*fe013be4SDimitry Andric             if (INTERRUPT_REQUESTED(GetDebugger(),
2410*fe013be4SDimitry Andric                                     "Interrupted in dump all line tables with "
2411*fe013be4SDimitry Andric                                     "{0} of {1} dumped", num_dumped,
2412*fe013be4SDimitry Andric                                     num_modules))
24130b57cec5SDimitry Andric               break;
2414*fe013be4SDimitry Andric 
24150b57cec5SDimitry Andric             if (DumpCompileUnitLineTable(
2416e8d8bef9SDimitry Andric                     m_interpreter, result.GetOutputStream(), module_sp.get(),
24170b57cec5SDimitry Andric                     file_spec,
24180b57cec5SDimitry Andric                     m_options.m_verbose ? eDescriptionLevelFull
24190b57cec5SDimitry Andric                                         : eDescriptionLevelBrief))
24200b57cec5SDimitry Andric               num_dumped++;
24210b57cec5SDimitry Andric           }
24220b57cec5SDimitry Andric           if (num_dumped == 0)
24230b57cec5SDimitry Andric             result.AppendWarningWithFormat(
24240b57cec5SDimitry Andric                 "No source filenames matched '%s'.\n", arg_cstr);
24250b57cec5SDimitry Andric           else
24260b57cec5SDimitry Andric             total_num_dumped += num_dumped;
24270b57cec5SDimitry Andric         }
24280b57cec5SDimitry Andric       }
24290b57cec5SDimitry Andric     }
24300b57cec5SDimitry Andric 
24310b57cec5SDimitry Andric     if (total_num_dumped > 0)
24320b57cec5SDimitry Andric       result.SetStatus(eReturnStatusSuccessFinishResult);
24330b57cec5SDimitry Andric     else {
24340b57cec5SDimitry Andric       result.AppendError("no source filenames matched any command arguments");
24350b57cec5SDimitry Andric     }
24360b57cec5SDimitry Andric     return result.Succeeded();
24370b57cec5SDimitry Andric   }
24380b57cec5SDimitry Andric 
24390b57cec5SDimitry Andric   class CommandOptions : public Options {
24400b57cec5SDimitry Andric   public:
244104eeddc0SDimitry Andric     CommandOptions() { OptionParsingStarting(nullptr); }
24420b57cec5SDimitry Andric 
24430b57cec5SDimitry Andric     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
24440b57cec5SDimitry Andric                           ExecutionContext *execution_context) override {
24450b57cec5SDimitry Andric       assert(option_idx == 0 && "We only have one option.");
24460b57cec5SDimitry Andric       m_verbose = true;
24470b57cec5SDimitry Andric 
24480b57cec5SDimitry Andric       return Status();
24490b57cec5SDimitry Andric     }
24500b57cec5SDimitry Andric 
24510b57cec5SDimitry Andric     void OptionParsingStarting(ExecutionContext *execution_context) override {
24520b57cec5SDimitry Andric       m_verbose = false;
24530b57cec5SDimitry Andric     }
24540b57cec5SDimitry Andric 
24550b57cec5SDimitry Andric     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2456bdd1243dSDimitry Andric       return llvm::ArrayRef(g_target_modules_dump_options);
24570b57cec5SDimitry Andric     }
24580b57cec5SDimitry Andric 
24590b57cec5SDimitry Andric     bool m_verbose;
24600b57cec5SDimitry Andric   };
24610b57cec5SDimitry Andric 
24620b57cec5SDimitry Andric   CommandOptions m_options;
24630b57cec5SDimitry Andric };
24640b57cec5SDimitry Andric 
24650b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesDump
24660b57cec5SDimitry Andric 
24670b57cec5SDimitry Andric // Dump multi-word command for target modules
24680b57cec5SDimitry Andric 
24690b57cec5SDimitry Andric class CommandObjectTargetModulesDump : public CommandObjectMultiword {
24700b57cec5SDimitry Andric public:
24710b57cec5SDimitry Andric   // Constructors and Destructors
24720b57cec5SDimitry Andric   CommandObjectTargetModulesDump(CommandInterpreter &interpreter)
24730b57cec5SDimitry Andric       : CommandObjectMultiword(
24740b57cec5SDimitry Andric             interpreter, "target modules dump",
2475753f127fSDimitry Andric             "Commands for dumping information about one or more target "
2476753f127fSDimitry Andric             "modules.",
24770b57cec5SDimitry Andric             "target modules dump "
2478753f127fSDimitry Andric             "[objfile|symtab|sections|ast|symfile|line-table|pcm-info] "
24790b57cec5SDimitry Andric             "[<file1> <file2> ...]") {
24800b57cec5SDimitry Andric     LoadSubCommand("objfile",
24810b57cec5SDimitry Andric                    CommandObjectSP(
24820b57cec5SDimitry Andric                        new CommandObjectTargetModulesDumpObjfile(interpreter)));
24830b57cec5SDimitry Andric     LoadSubCommand(
24840b57cec5SDimitry Andric         "symtab",
24850b57cec5SDimitry Andric         CommandObjectSP(new CommandObjectTargetModulesDumpSymtab(interpreter)));
24860b57cec5SDimitry Andric     LoadSubCommand("sections",
24870b57cec5SDimitry Andric                    CommandObjectSP(new CommandObjectTargetModulesDumpSections(
24880b57cec5SDimitry Andric                        interpreter)));
24890b57cec5SDimitry Andric     LoadSubCommand("symfile",
24900b57cec5SDimitry Andric                    CommandObjectSP(
24910b57cec5SDimitry Andric                        new CommandObjectTargetModulesDumpSymfile(interpreter)));
24920b57cec5SDimitry Andric     LoadSubCommand(
24930b57cec5SDimitry Andric         "ast", CommandObjectSP(
24940b57cec5SDimitry Andric                    new CommandObjectTargetModulesDumpClangAST(interpreter)));
24950b57cec5SDimitry Andric     LoadSubCommand("line-table",
24960b57cec5SDimitry Andric                    CommandObjectSP(new CommandObjectTargetModulesDumpLineTable(
24970b57cec5SDimitry Andric                        interpreter)));
2498753f127fSDimitry Andric     LoadSubCommand(
2499753f127fSDimitry Andric         "pcm-info",
2500753f127fSDimitry Andric         CommandObjectSP(
2501753f127fSDimitry Andric             new CommandObjectTargetModulesDumpClangPCMInfo(interpreter)));
25020b57cec5SDimitry Andric   }
25030b57cec5SDimitry Andric 
25040b57cec5SDimitry Andric   ~CommandObjectTargetModulesDump() override = default;
25050b57cec5SDimitry Andric };
25060b57cec5SDimitry Andric 
25070b57cec5SDimitry Andric class CommandObjectTargetModulesAdd : public CommandObjectParsed {
25080b57cec5SDimitry Andric public:
25090b57cec5SDimitry Andric   CommandObjectTargetModulesAdd(CommandInterpreter &interpreter)
25100b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "target modules add",
25110b57cec5SDimitry Andric                             "Add a new module to the current target's modules.",
25129dba64beSDimitry Andric                             "target modules add [<module>]",
25139dba64beSDimitry Andric                             eCommandRequiresTarget),
251404eeddc0SDimitry Andric         m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
251504eeddc0SDimitry Andric                       eArgTypeFilename,
25169dba64beSDimitry Andric                       "Fullpath to a stand alone debug "
25170b57cec5SDimitry Andric                       "symbols file for when debug symbols "
25180b57cec5SDimitry Andric                       "are not in the executable.") {
25190b57cec5SDimitry Andric     m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
25200b57cec5SDimitry Andric                           LLDB_OPT_SET_1);
25210b57cec5SDimitry Andric     m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
25220b57cec5SDimitry Andric     m_option_group.Finalize();
252381ad6265SDimitry Andric     CommandArgumentData module_arg{eArgTypePath, eArgRepeatStar};
252481ad6265SDimitry Andric     m_arguments.push_back({module_arg});
25250b57cec5SDimitry Andric   }
25260b57cec5SDimitry Andric 
25270b57cec5SDimitry Andric   ~CommandObjectTargetModulesAdd() override = default;
25280b57cec5SDimitry Andric 
25290b57cec5SDimitry Andric   Options *GetOptions() override { return &m_option_group; }
25300b57cec5SDimitry Andric 
25319dba64beSDimitry Andric   void
25329dba64beSDimitry Andric   HandleArgumentCompletion(CompletionRequest &request,
25330b57cec5SDimitry Andric                            OptionElementVector &opt_element_vector) override {
2534*fe013be4SDimitry Andric     lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
2535*fe013be4SDimitry Andric         GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr);
25360b57cec5SDimitry Andric   }
25370b57cec5SDimitry Andric 
25380b57cec5SDimitry Andric protected:
25390b57cec5SDimitry Andric   OptionGroupOptions m_option_group;
25400b57cec5SDimitry Andric   OptionGroupUUID m_uuid_option_group;
25410b57cec5SDimitry Andric   OptionGroupFile m_symbol_file;
25420b57cec5SDimitry Andric 
25430b57cec5SDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
25449dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
25450b57cec5SDimitry Andric     bool flush = false;
25460b57cec5SDimitry Andric 
25470b57cec5SDimitry Andric     const size_t argc = args.GetArgumentCount();
25480b57cec5SDimitry Andric     if (argc == 0) {
25490b57cec5SDimitry Andric       if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
25500b57cec5SDimitry Andric         // We are given a UUID only, go locate the file
25510b57cec5SDimitry Andric         ModuleSpec module_spec;
25520b57cec5SDimitry Andric         module_spec.GetUUID() =
25530b57cec5SDimitry Andric             m_uuid_option_group.GetOptionValue().GetCurrentValue();
25540b57cec5SDimitry Andric         if (m_symbol_file.GetOptionValue().OptionWasSet())
25550b57cec5SDimitry Andric           module_spec.GetSymbolFileSpec() =
25560b57cec5SDimitry Andric               m_symbol_file.GetOptionValue().GetCurrentValue();
255781ad6265SDimitry Andric         Status error;
255881ad6265SDimitry Andric         if (Symbols::DownloadObjectAndSymbolFile(module_spec, error)) {
25599dba64beSDimitry Andric           ModuleSP module_sp(
25609dba64beSDimitry Andric               target->GetOrCreateModule(module_spec, true /* notify */));
25610b57cec5SDimitry Andric           if (module_sp) {
25620b57cec5SDimitry Andric             result.SetStatus(eReturnStatusSuccessFinishResult);
25630b57cec5SDimitry Andric             return true;
25640b57cec5SDimitry Andric           } else {
25650b57cec5SDimitry Andric             StreamString strm;
2566*fe013be4SDimitry Andric             module_spec.GetUUID().Dump(strm);
25670b57cec5SDimitry Andric             if (module_spec.GetFileSpec()) {
25680b57cec5SDimitry Andric               if (module_spec.GetSymbolFileSpec()) {
25690b57cec5SDimitry Andric                 result.AppendErrorWithFormat(
25700b57cec5SDimitry Andric                     "Unable to create the executable or symbol file with "
25710b57cec5SDimitry Andric                     "UUID %s with path %s and symbol file %s",
25729dba64beSDimitry Andric                     strm.GetData(), module_spec.GetFileSpec().GetPath().c_str(),
25730b57cec5SDimitry Andric                     module_spec.GetSymbolFileSpec().GetPath().c_str());
25740b57cec5SDimitry Andric               } else {
25750b57cec5SDimitry Andric                 result.AppendErrorWithFormat(
25760b57cec5SDimitry Andric                     "Unable to create the executable or symbol file with "
25770b57cec5SDimitry Andric                     "UUID %s with path %s",
25780b57cec5SDimitry Andric                     strm.GetData(),
25790b57cec5SDimitry Andric                     module_spec.GetFileSpec().GetPath().c_str());
25800b57cec5SDimitry Andric               }
25810b57cec5SDimitry Andric             } else {
25820b57cec5SDimitry Andric               result.AppendErrorWithFormat("Unable to create the executable "
25830b57cec5SDimitry Andric                                            "or symbol file with UUID %s",
25840b57cec5SDimitry Andric                                            strm.GetData());
25850b57cec5SDimitry Andric             }
25860b57cec5SDimitry Andric             return false;
25870b57cec5SDimitry Andric           }
25880b57cec5SDimitry Andric         } else {
25890b57cec5SDimitry Andric           StreamString strm;
2590*fe013be4SDimitry Andric           module_spec.GetUUID().Dump(strm);
25910b57cec5SDimitry Andric           result.AppendErrorWithFormat(
25920b57cec5SDimitry Andric               "Unable to locate the executable or symbol file with UUID %s",
25930b57cec5SDimitry Andric               strm.GetData());
259481ad6265SDimitry Andric           result.SetError(error);
25950b57cec5SDimitry Andric           return false;
25960b57cec5SDimitry Andric         }
25970b57cec5SDimitry Andric       } else {
25980b57cec5SDimitry Andric         result.AppendError(
25990b57cec5SDimitry Andric             "one or more executable image paths must be specified");
26000b57cec5SDimitry Andric         return false;
26010b57cec5SDimitry Andric       }
26020b57cec5SDimitry Andric     } else {
26030b57cec5SDimitry Andric       for (auto &entry : args.entries()) {
26049dba64beSDimitry Andric         if (entry.ref().empty())
26050b57cec5SDimitry Andric           continue;
26060b57cec5SDimitry Andric 
26079dba64beSDimitry Andric         FileSpec file_spec(entry.ref());
26080b57cec5SDimitry Andric         if (FileSystem::Instance().Exists(file_spec)) {
26090b57cec5SDimitry Andric           ModuleSpec module_spec(file_spec);
26100b57cec5SDimitry Andric           if (m_uuid_option_group.GetOptionValue().OptionWasSet())
26110b57cec5SDimitry Andric             module_spec.GetUUID() =
26120b57cec5SDimitry Andric                 m_uuid_option_group.GetOptionValue().GetCurrentValue();
26130b57cec5SDimitry Andric           if (m_symbol_file.GetOptionValue().OptionWasSet())
26140b57cec5SDimitry Andric             module_spec.GetSymbolFileSpec() =
26150b57cec5SDimitry Andric                 m_symbol_file.GetOptionValue().GetCurrentValue();
26160b57cec5SDimitry Andric           if (!module_spec.GetArchitecture().IsValid())
26170b57cec5SDimitry Andric             module_spec.GetArchitecture() = target->GetArchitecture();
26180b57cec5SDimitry Andric           Status error;
26199dba64beSDimitry Andric           ModuleSP module_sp(target->GetOrCreateModule(
26209dba64beSDimitry Andric               module_spec, true /* notify */, &error));
26210b57cec5SDimitry Andric           if (!module_sp) {
26220b57cec5SDimitry Andric             const char *error_cstr = error.AsCString();
26230b57cec5SDimitry Andric             if (error_cstr)
26240b57cec5SDimitry Andric               result.AppendError(error_cstr);
26250b57cec5SDimitry Andric             else
26260b57cec5SDimitry Andric               result.AppendErrorWithFormat("unsupported module: %s",
26270b57cec5SDimitry Andric                                            entry.c_str());
26280b57cec5SDimitry Andric             return false;
26290b57cec5SDimitry Andric           } else {
26300b57cec5SDimitry Andric             flush = true;
26310b57cec5SDimitry Andric           }
26320b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishResult);
26330b57cec5SDimitry Andric         } else {
26340b57cec5SDimitry Andric           std::string resolved_path = file_spec.GetPath();
26359dba64beSDimitry Andric           if (resolved_path != entry.ref()) {
26360b57cec5SDimitry Andric             result.AppendErrorWithFormat(
26370b57cec5SDimitry Andric                 "invalid module path '%s' with resolved path '%s'\n",
26389dba64beSDimitry Andric                 entry.ref().str().c_str(), resolved_path.c_str());
26390b57cec5SDimitry Andric             break;
26400b57cec5SDimitry Andric           }
26410b57cec5SDimitry Andric           result.AppendErrorWithFormat("invalid module path '%s'\n",
26420b57cec5SDimitry Andric                                        entry.c_str());
26430b57cec5SDimitry Andric           break;
26440b57cec5SDimitry Andric         }
26450b57cec5SDimitry Andric       }
26460b57cec5SDimitry Andric     }
26470b57cec5SDimitry Andric 
26480b57cec5SDimitry Andric     if (flush) {
26490b57cec5SDimitry Andric       ProcessSP process = target->GetProcessSP();
26500b57cec5SDimitry Andric       if (process)
26510b57cec5SDimitry Andric         process->Flush();
26520b57cec5SDimitry Andric     }
26530b57cec5SDimitry Andric 
26540b57cec5SDimitry Andric     return result.Succeeded();
26550b57cec5SDimitry Andric   }
26560b57cec5SDimitry Andric };
26570b57cec5SDimitry Andric 
26580b57cec5SDimitry Andric class CommandObjectTargetModulesLoad
26590b57cec5SDimitry Andric     : public CommandObjectTargetModulesModuleAutoComplete {
26600b57cec5SDimitry Andric public:
26610b57cec5SDimitry Andric   CommandObjectTargetModulesLoad(CommandInterpreter &interpreter)
26620b57cec5SDimitry Andric       : CommandObjectTargetModulesModuleAutoComplete(
26639dba64beSDimitry Andric             interpreter, "target modules load",
26649dba64beSDimitry Andric             "Set the load addresses for one or more sections in a target "
26659dba64beSDimitry Andric             "module.",
26660b57cec5SDimitry Andric             "target modules load [--file <module> --uuid <uuid>] <sect-name> "
26679dba64beSDimitry Andric             "<address> [<sect-name> <address> ....]",
26689dba64beSDimitry Andric             eCommandRequiresTarget),
26690b57cec5SDimitry Andric         m_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName,
26700b57cec5SDimitry Andric                       "Fullpath or basename for module to load.", ""),
26710b57cec5SDimitry Andric         m_load_option(LLDB_OPT_SET_1, false, "load", 'l',
26720b57cec5SDimitry Andric                       "Write file contents to the memory.", false, true),
26730b57cec5SDimitry Andric         m_pc_option(LLDB_OPT_SET_1, false, "set-pc-to-entry", 'p',
26740b57cec5SDimitry Andric                     "Set PC to the entry point."
26750b57cec5SDimitry Andric                     " Only applicable with '--load' option.",
26760b57cec5SDimitry Andric                     false, true),
26770b57cec5SDimitry Andric         m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset,
26780b57cec5SDimitry Andric                        "Set the load address for all sections to be the "
26790b57cec5SDimitry Andric                        "virtual address in the file plus the offset.",
26800b57cec5SDimitry Andric                        0) {
26810b57cec5SDimitry Andric     m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
26820b57cec5SDimitry Andric                           LLDB_OPT_SET_1);
26830b57cec5SDimitry Andric     m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
26840b57cec5SDimitry Andric     m_option_group.Append(&m_load_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
26850b57cec5SDimitry Andric     m_option_group.Append(&m_pc_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
26860b57cec5SDimitry Andric     m_option_group.Append(&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
26870b57cec5SDimitry Andric     m_option_group.Finalize();
26880b57cec5SDimitry Andric   }
26890b57cec5SDimitry Andric 
26900b57cec5SDimitry Andric   ~CommandObjectTargetModulesLoad() override = default;
26910b57cec5SDimitry Andric 
26920b57cec5SDimitry Andric   Options *GetOptions() override { return &m_option_group; }
26930b57cec5SDimitry Andric 
26940b57cec5SDimitry Andric protected:
26950b57cec5SDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
26969dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
26970b57cec5SDimitry Andric     const bool load = m_load_option.GetOptionValue().GetCurrentValue();
26980b57cec5SDimitry Andric     const bool set_pc = m_pc_option.GetOptionValue().GetCurrentValue();
26999dba64beSDimitry Andric 
27000b57cec5SDimitry Andric     const size_t argc = args.GetArgumentCount();
27010b57cec5SDimitry Andric     ModuleSpec module_spec;
27020b57cec5SDimitry Andric     bool search_using_module_spec = false;
27030b57cec5SDimitry Andric 
27040b57cec5SDimitry Andric     // Allow "load" option to work without --file or --uuid option.
27050b57cec5SDimitry Andric     if (load) {
27060b57cec5SDimitry Andric       if (!m_file_option.GetOptionValue().OptionWasSet() &&
27070b57cec5SDimitry Andric           !m_uuid_option_group.GetOptionValue().OptionWasSet()) {
27080b57cec5SDimitry Andric         ModuleList &module_list = target->GetImages();
27090b57cec5SDimitry Andric         if (module_list.GetSize() == 1) {
27100b57cec5SDimitry Andric           search_using_module_spec = true;
27110b57cec5SDimitry Andric           module_spec.GetFileSpec() =
27120b57cec5SDimitry Andric               module_list.GetModuleAtIndex(0)->GetFileSpec();
27130b57cec5SDimitry Andric         }
27140b57cec5SDimitry Andric       }
27150b57cec5SDimitry Andric     }
27160b57cec5SDimitry Andric 
27170b57cec5SDimitry Andric     if (m_file_option.GetOptionValue().OptionWasSet()) {
27180b57cec5SDimitry Andric       search_using_module_spec = true;
27190b57cec5SDimitry Andric       const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
27200b57cec5SDimitry Andric       const bool use_global_module_list = true;
27210b57cec5SDimitry Andric       ModuleList module_list;
27220b57cec5SDimitry Andric       const size_t num_matches = FindModulesByName(
27230b57cec5SDimitry Andric           target, arg_cstr, module_list, use_global_module_list);
27240b57cec5SDimitry Andric       if (num_matches == 1) {
27250b57cec5SDimitry Andric         module_spec.GetFileSpec() =
27260b57cec5SDimitry Andric             module_list.GetModuleAtIndex(0)->GetFileSpec();
27270b57cec5SDimitry Andric       } else if (num_matches > 1) {
27280b57cec5SDimitry Andric         search_using_module_spec = false;
27290b57cec5SDimitry Andric         result.AppendErrorWithFormat(
27300b57cec5SDimitry Andric             "more than 1 module matched by name '%s'\n", arg_cstr);
27310b57cec5SDimitry Andric       } else {
27320b57cec5SDimitry Andric         search_using_module_spec = false;
27330b57cec5SDimitry Andric         result.AppendErrorWithFormat("no object file for module '%s'\n",
27340b57cec5SDimitry Andric                                      arg_cstr);
27350b57cec5SDimitry Andric       }
27360b57cec5SDimitry Andric     }
27370b57cec5SDimitry Andric 
27380b57cec5SDimitry Andric     if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
27390b57cec5SDimitry Andric       search_using_module_spec = true;
27400b57cec5SDimitry Andric       module_spec.GetUUID() =
27410b57cec5SDimitry Andric           m_uuid_option_group.GetOptionValue().GetCurrentValue();
27420b57cec5SDimitry Andric     }
27430b57cec5SDimitry Andric 
27440b57cec5SDimitry Andric     if (search_using_module_spec) {
27450b57cec5SDimitry Andric       ModuleList matching_modules;
27460b57cec5SDimitry Andric       target->GetImages().FindModules(module_spec, matching_modules);
27479dba64beSDimitry Andric       const size_t num_matches = matching_modules.GetSize();
27480b57cec5SDimitry Andric 
27490b57cec5SDimitry Andric       char path[PATH_MAX];
27500b57cec5SDimitry Andric       if (num_matches == 1) {
27510b57cec5SDimitry Andric         Module *module = matching_modules.GetModulePointerAtIndex(0);
27520b57cec5SDimitry Andric         if (module) {
27530b57cec5SDimitry Andric           ObjectFile *objfile = module->GetObjectFile();
27540b57cec5SDimitry Andric           if (objfile) {
27550b57cec5SDimitry Andric             SectionList *section_list = module->GetSectionList();
27560b57cec5SDimitry Andric             if (section_list) {
27570b57cec5SDimitry Andric               bool changed = false;
27580b57cec5SDimitry Andric               if (argc == 0) {
27590b57cec5SDimitry Andric                 if (m_slide_option.GetOptionValue().OptionWasSet()) {
27600b57cec5SDimitry Andric                   const addr_t slide =
27610b57cec5SDimitry Andric                       m_slide_option.GetOptionValue().GetCurrentValue();
27620b57cec5SDimitry Andric                   const bool slide_is_offset = true;
27630b57cec5SDimitry Andric                   module->SetLoadAddress(*target, slide, slide_is_offset,
27640b57cec5SDimitry Andric                                          changed);
27650b57cec5SDimitry Andric                 } else {
27660b57cec5SDimitry Andric                   result.AppendError("one or more section name + load "
27670b57cec5SDimitry Andric                                      "address pair must be specified");
27680b57cec5SDimitry Andric                   return false;
27690b57cec5SDimitry Andric                 }
27700b57cec5SDimitry Andric               } else {
27710b57cec5SDimitry Andric                 if (m_slide_option.GetOptionValue().OptionWasSet()) {
27720b57cec5SDimitry Andric                   result.AppendError("The \"--slide <offset>\" option can't "
27730b57cec5SDimitry Andric                                      "be used in conjunction with setting "
27740b57cec5SDimitry Andric                                      "section load addresses.\n");
27750b57cec5SDimitry Andric                   return false;
27760b57cec5SDimitry Andric                 }
27770b57cec5SDimitry Andric 
27780b57cec5SDimitry Andric                 for (size_t i = 0; i < argc; i += 2) {
27790b57cec5SDimitry Andric                   const char *sect_name = args.GetArgumentAtIndex(i);
27800b57cec5SDimitry Andric                   const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1);
27810b57cec5SDimitry Andric                   if (sect_name && load_addr_cstr) {
27820b57cec5SDimitry Andric                     ConstString const_sect_name(sect_name);
27835ffd83dbSDimitry Andric                     addr_t load_addr;
27845ffd83dbSDimitry Andric                     if (llvm::to_integer(load_addr_cstr, load_addr)) {
27850b57cec5SDimitry Andric                       SectionSP section_sp(
27860b57cec5SDimitry Andric                           section_list->FindSectionByName(const_sect_name));
27870b57cec5SDimitry Andric                       if (section_sp) {
27880b57cec5SDimitry Andric                         if (section_sp->IsThreadSpecific()) {
27890b57cec5SDimitry Andric                           result.AppendErrorWithFormat(
27900b57cec5SDimitry Andric                               "thread specific sections are not yet "
27910b57cec5SDimitry Andric                               "supported (section '%s')\n",
27920b57cec5SDimitry Andric                               sect_name);
27930b57cec5SDimitry Andric                           break;
27940b57cec5SDimitry Andric                         } else {
27950b57cec5SDimitry Andric                           if (target->GetSectionLoadList()
27969dba64beSDimitry Andric                                   .SetSectionLoadAddress(section_sp, load_addr))
27970b57cec5SDimitry Andric                             changed = true;
27980b57cec5SDimitry Andric                           result.AppendMessageWithFormat(
27990b57cec5SDimitry Andric                               "section '%s' loaded at 0x%" PRIx64 "\n",
28000b57cec5SDimitry Andric                               sect_name, load_addr);
28010b57cec5SDimitry Andric                         }
28020b57cec5SDimitry Andric                       } else {
28030b57cec5SDimitry Andric                         result.AppendErrorWithFormat("no section found that "
28040b57cec5SDimitry Andric                                                      "matches the section "
28050b57cec5SDimitry Andric                                                      "name '%s'\n",
28060b57cec5SDimitry Andric                                                      sect_name);
28070b57cec5SDimitry Andric                         break;
28080b57cec5SDimitry Andric                       }
28090b57cec5SDimitry Andric                     } else {
28100b57cec5SDimitry Andric                       result.AppendErrorWithFormat(
28119dba64beSDimitry Andric                           "invalid load address string '%s'\n", load_addr_cstr);
28120b57cec5SDimitry Andric                       break;
28130b57cec5SDimitry Andric                     }
28140b57cec5SDimitry Andric                   } else {
28150b57cec5SDimitry Andric                     if (sect_name)
28160b57cec5SDimitry Andric                       result.AppendError("section names must be followed by "
28170b57cec5SDimitry Andric                                          "a load address.\n");
28180b57cec5SDimitry Andric                     else
28190b57cec5SDimitry Andric                       result.AppendError("one or more section name + load "
28200b57cec5SDimitry Andric                                          "address pair must be specified.\n");
28210b57cec5SDimitry Andric                     break;
28220b57cec5SDimitry Andric                   }
28230b57cec5SDimitry Andric                 }
28240b57cec5SDimitry Andric               }
28250b57cec5SDimitry Andric 
28260b57cec5SDimitry Andric               if (changed) {
28270b57cec5SDimitry Andric                 target->ModulesDidLoad(matching_modules);
28280b57cec5SDimitry Andric                 Process *process = m_exe_ctx.GetProcessPtr();
28290b57cec5SDimitry Andric                 if (process)
28300b57cec5SDimitry Andric                   process->Flush();
28310b57cec5SDimitry Andric               }
28320b57cec5SDimitry Andric               if (load) {
28330b57cec5SDimitry Andric                 ProcessSP process = target->CalculateProcess();
28340b57cec5SDimitry Andric                 Address file_entry = objfile->GetEntryPointAddress();
28350b57cec5SDimitry Andric                 if (!process) {
28360b57cec5SDimitry Andric                   result.AppendError("No process");
28370b57cec5SDimitry Andric                   return false;
28380b57cec5SDimitry Andric                 }
28390b57cec5SDimitry Andric                 if (set_pc && !file_entry.IsValid()) {
28400b57cec5SDimitry Andric                   result.AppendError("No entry address in object file");
28410b57cec5SDimitry Andric                   return false;
28420b57cec5SDimitry Andric                 }
28430b57cec5SDimitry Andric                 std::vector<ObjectFile::LoadableData> loadables(
28440b57cec5SDimitry Andric                     objfile->GetLoadableData(*target));
28450b57cec5SDimitry Andric                 if (loadables.size() == 0) {
28460b57cec5SDimitry Andric                   result.AppendError("No loadable sections");
28470b57cec5SDimitry Andric                   return false;
28480b57cec5SDimitry Andric                 }
28490b57cec5SDimitry Andric                 Status error = process->WriteObjectFile(std::move(loadables));
28500b57cec5SDimitry Andric                 if (error.Fail()) {
28510b57cec5SDimitry Andric                   result.AppendError(error.AsCString());
28520b57cec5SDimitry Andric                   return false;
28530b57cec5SDimitry Andric                 }
28540b57cec5SDimitry Andric                 if (set_pc) {
28550b57cec5SDimitry Andric                   ThreadList &thread_list = process->GetThreadList();
28560b57cec5SDimitry Andric                   RegisterContextSP reg_context(
28570b57cec5SDimitry Andric                       thread_list.GetSelectedThread()->GetRegisterContext());
28580b57cec5SDimitry Andric                   addr_t file_entry_addr = file_entry.GetLoadAddress(target);
28590b57cec5SDimitry Andric                   if (!reg_context->SetPC(file_entry_addr)) {
28600b57cec5SDimitry Andric                     result.AppendErrorWithFormat("failed to set PC value to "
28610b57cec5SDimitry Andric                                                  "0x%" PRIx64 "\n",
28620b57cec5SDimitry Andric                                                  file_entry_addr);
28630b57cec5SDimitry Andric                   }
28640b57cec5SDimitry Andric                 }
28650b57cec5SDimitry Andric               }
28660b57cec5SDimitry Andric             } else {
28670b57cec5SDimitry Andric               module->GetFileSpec().GetPath(path, sizeof(path));
28689dba64beSDimitry Andric               result.AppendErrorWithFormat("no sections in object file '%s'\n",
28699dba64beSDimitry Andric                                            path);
28700b57cec5SDimitry Andric             }
28710b57cec5SDimitry Andric           } else {
28720b57cec5SDimitry Andric             module->GetFileSpec().GetPath(path, sizeof(path));
28730b57cec5SDimitry Andric             result.AppendErrorWithFormat("no object file for module '%s'\n",
28740b57cec5SDimitry Andric                                          path);
28750b57cec5SDimitry Andric           }
28760b57cec5SDimitry Andric         } else {
28770b57cec5SDimitry Andric           FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
28780b57cec5SDimitry Andric           if (module_spec_file) {
28790b57cec5SDimitry Andric             module_spec_file->GetPath(path, sizeof(path));
28800b57cec5SDimitry Andric             result.AppendErrorWithFormat("invalid module '%s'.\n", path);
28810b57cec5SDimitry Andric           } else
28820b57cec5SDimitry Andric             result.AppendError("no module spec");
28830b57cec5SDimitry Andric         }
28840b57cec5SDimitry Andric       } else {
28850b57cec5SDimitry Andric         std::string uuid_str;
28860b57cec5SDimitry Andric 
28870b57cec5SDimitry Andric         if (module_spec.GetFileSpec())
28880b57cec5SDimitry Andric           module_spec.GetFileSpec().GetPath(path, sizeof(path));
28890b57cec5SDimitry Andric         else
28900b57cec5SDimitry Andric           path[0] = '\0';
28910b57cec5SDimitry Andric 
28920b57cec5SDimitry Andric         if (module_spec.GetUUIDPtr())
28930b57cec5SDimitry Andric           uuid_str = module_spec.GetUUID().GetAsString();
28940b57cec5SDimitry Andric         if (num_matches > 1) {
28950b57cec5SDimitry Andric           result.AppendErrorWithFormat(
28960b57cec5SDimitry Andric               "multiple modules match%s%s%s%s:\n", path[0] ? " file=" : "",
28970b57cec5SDimitry Andric               path, !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
28980b57cec5SDimitry Andric           for (size_t i = 0; i < num_matches; ++i) {
28990b57cec5SDimitry Andric             if (matching_modules.GetModulePointerAtIndex(i)
29000b57cec5SDimitry Andric                     ->GetFileSpec()
29010b57cec5SDimitry Andric                     .GetPath(path, sizeof(path)))
29020b57cec5SDimitry Andric               result.AppendMessageWithFormat("%s\n", path);
29030b57cec5SDimitry Andric           }
29040b57cec5SDimitry Andric         } else {
29050b57cec5SDimitry Andric           result.AppendErrorWithFormat(
29060b57cec5SDimitry Andric               "no modules were found  that match%s%s%s%s.\n",
29079dba64beSDimitry Andric               path[0] ? " file=" : "", path, !uuid_str.empty() ? " uuid=" : "",
29089dba64beSDimitry Andric               uuid_str.c_str());
29090b57cec5SDimitry Andric         }
29100b57cec5SDimitry Andric       }
29110b57cec5SDimitry Andric     } else {
29120b57cec5SDimitry Andric       result.AppendError("either the \"--file <module>\" or the \"--uuid "
29130b57cec5SDimitry Andric                          "<uuid>\" option must be specified.\n");
29140b57cec5SDimitry Andric       return false;
29150b57cec5SDimitry Andric     }
29160b57cec5SDimitry Andric     return result.Succeeded();
29170b57cec5SDimitry Andric   }
29180b57cec5SDimitry Andric 
29190b57cec5SDimitry Andric   OptionGroupOptions m_option_group;
29200b57cec5SDimitry Andric   OptionGroupUUID m_uuid_option_group;
29210b57cec5SDimitry Andric   OptionGroupString m_file_option;
29220b57cec5SDimitry Andric   OptionGroupBoolean m_load_option;
29230b57cec5SDimitry Andric   OptionGroupBoolean m_pc_option;
29240b57cec5SDimitry Andric   OptionGroupUInt64 m_slide_option;
29250b57cec5SDimitry Andric };
29260b57cec5SDimitry Andric 
2927349cc55cSDimitry Andric #pragma mark CommandObjectTargetModulesList
29280b57cec5SDimitry Andric // List images with associated information
29299dba64beSDimitry Andric #define LLDB_OPTIONS_target_modules_list
29309dba64beSDimitry Andric #include "CommandOptions.inc"
29310b57cec5SDimitry Andric 
29320b57cec5SDimitry Andric class CommandObjectTargetModulesList : public CommandObjectParsed {
29330b57cec5SDimitry Andric public:
29340b57cec5SDimitry Andric   class CommandOptions : public Options {
29350b57cec5SDimitry Andric   public:
293681ad6265SDimitry Andric     CommandOptions() = default;
29370b57cec5SDimitry Andric 
29380b57cec5SDimitry Andric     ~CommandOptions() override = default;
29390b57cec5SDimitry Andric 
29400b57cec5SDimitry Andric     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
29410b57cec5SDimitry Andric                           ExecutionContext *execution_context) override {
29420b57cec5SDimitry Andric       Status error;
29430b57cec5SDimitry Andric 
29440b57cec5SDimitry Andric       const int short_option = m_getopt_table[option_idx].val;
29450b57cec5SDimitry Andric       if (short_option == 'g') {
29460b57cec5SDimitry Andric         m_use_global_module_list = true;
29470b57cec5SDimitry Andric       } else if (short_option == 'a') {
29480b57cec5SDimitry Andric         m_module_addr = OptionArgParser::ToAddress(
29490b57cec5SDimitry Andric             execution_context, option_arg, LLDB_INVALID_ADDRESS, &error);
29500b57cec5SDimitry Andric       } else {
29510b57cec5SDimitry Andric         unsigned long width = 0;
29520b57cec5SDimitry Andric         option_arg.getAsInteger(0, width);
29530b57cec5SDimitry Andric         m_format_array.push_back(std::make_pair(short_option, width));
29540b57cec5SDimitry Andric       }
29550b57cec5SDimitry Andric       return error;
29560b57cec5SDimitry Andric     }
29570b57cec5SDimitry Andric 
29580b57cec5SDimitry Andric     void OptionParsingStarting(ExecutionContext *execution_context) override {
29590b57cec5SDimitry Andric       m_format_array.clear();
29600b57cec5SDimitry Andric       m_use_global_module_list = false;
29610b57cec5SDimitry Andric       m_module_addr = LLDB_INVALID_ADDRESS;
29620b57cec5SDimitry Andric     }
29630b57cec5SDimitry Andric 
29640b57cec5SDimitry Andric     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2965bdd1243dSDimitry Andric       return llvm::ArrayRef(g_target_modules_list_options);
29660b57cec5SDimitry Andric     }
29670b57cec5SDimitry Andric 
29680b57cec5SDimitry Andric     // Instance variables to hold the values for command options.
29690b57cec5SDimitry Andric     typedef std::vector<std::pair<char, uint32_t>> FormatWidthCollection;
29700b57cec5SDimitry Andric     FormatWidthCollection m_format_array;
2971fe6060f1SDimitry Andric     bool m_use_global_module_list = false;
2972fe6060f1SDimitry Andric     lldb::addr_t m_module_addr = LLDB_INVALID_ADDRESS;
29730b57cec5SDimitry Andric   };
29740b57cec5SDimitry Andric 
29750b57cec5SDimitry Andric   CommandObjectTargetModulesList(CommandInterpreter &interpreter)
29760b57cec5SDimitry Andric       : CommandObjectParsed(
29770b57cec5SDimitry Andric             interpreter, "target modules list",
297881ad6265SDimitry Andric             "List current executable and dependent shared library images.") {
297981ad6265SDimitry Andric     CommandArgumentData module_arg{eArgTypeShlibName, eArgRepeatStar};
298081ad6265SDimitry Andric     m_arguments.push_back({module_arg});
298181ad6265SDimitry Andric   }
29820b57cec5SDimitry Andric 
29830b57cec5SDimitry Andric   ~CommandObjectTargetModulesList() override = default;
29840b57cec5SDimitry Andric 
29850b57cec5SDimitry Andric   Options *GetOptions() override { return &m_options; }
29860b57cec5SDimitry Andric 
29870b57cec5SDimitry Andric protected:
29880b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
29890b57cec5SDimitry Andric     Target *target = GetDebugger().GetSelectedTarget().get();
29900b57cec5SDimitry Andric     const bool use_global_module_list = m_options.m_use_global_module_list;
29910b57cec5SDimitry Andric     // Define a local module list here to ensure it lives longer than any
29920b57cec5SDimitry Andric     // "locker" object which might lock its contents below (through the
29930b57cec5SDimitry Andric     // "module_list_ptr" variable).
29940b57cec5SDimitry Andric     ModuleList module_list;
29950b57cec5SDimitry Andric     if (target == nullptr && !use_global_module_list) {
29960b57cec5SDimitry Andric       result.AppendError("invalid target, create a debug target using the "
29970b57cec5SDimitry Andric                          "'target create' command");
29980b57cec5SDimitry Andric       return false;
29990b57cec5SDimitry Andric     } else {
30000b57cec5SDimitry Andric       if (target) {
30010b57cec5SDimitry Andric         uint32_t addr_byte_size =
30020b57cec5SDimitry Andric             target->GetArchitecture().GetAddressByteSize();
30030b57cec5SDimitry Andric         result.GetOutputStream().SetAddressByteSize(addr_byte_size);
30040b57cec5SDimitry Andric         result.GetErrorStream().SetAddressByteSize(addr_byte_size);
30050b57cec5SDimitry Andric       }
30060b57cec5SDimitry Andric       // Dump all sections for all modules images
30070b57cec5SDimitry Andric       Stream &strm = result.GetOutputStream();
30080b57cec5SDimitry Andric 
30090b57cec5SDimitry Andric       if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) {
30100b57cec5SDimitry Andric         if (target) {
30110b57cec5SDimitry Andric           Address module_address;
30120b57cec5SDimitry Andric           if (module_address.SetLoadAddress(m_options.m_module_addr, target)) {
30130b57cec5SDimitry Andric             ModuleSP module_sp(module_address.GetModule());
30140b57cec5SDimitry Andric             if (module_sp) {
30150b57cec5SDimitry Andric               PrintModule(target, module_sp.get(), 0, strm);
30160b57cec5SDimitry Andric               result.SetStatus(eReturnStatusSuccessFinishResult);
30170b57cec5SDimitry Andric             } else {
30180b57cec5SDimitry Andric               result.AppendErrorWithFormat(
30190b57cec5SDimitry Andric                   "Couldn't find module matching address: 0x%" PRIx64 ".",
30200b57cec5SDimitry Andric                   m_options.m_module_addr);
30210b57cec5SDimitry Andric             }
30220b57cec5SDimitry Andric           } else {
30230b57cec5SDimitry Andric             result.AppendErrorWithFormat(
30240b57cec5SDimitry Andric                 "Couldn't find module containing address: 0x%" PRIx64 ".",
30250b57cec5SDimitry Andric                 m_options.m_module_addr);
30260b57cec5SDimitry Andric           }
30270b57cec5SDimitry Andric         } else {
30280b57cec5SDimitry Andric           result.AppendError(
30290b57cec5SDimitry Andric               "Can only look up modules by address with a valid target.");
30300b57cec5SDimitry Andric         }
30310b57cec5SDimitry Andric         return result.Succeeded();
30320b57cec5SDimitry Andric       }
30330b57cec5SDimitry Andric 
30340b57cec5SDimitry Andric       size_t num_modules = 0;
30350b57cec5SDimitry Andric 
30360b57cec5SDimitry Andric       // This locker will be locked on the mutex in module_list_ptr if it is
30370b57cec5SDimitry Andric       // non-nullptr. Otherwise it will lock the
30380b57cec5SDimitry Andric       // AllocationModuleCollectionMutex when accessing the global module list
30390b57cec5SDimitry Andric       // directly.
30400b57cec5SDimitry Andric       std::unique_lock<std::recursive_mutex> guard(
30410b57cec5SDimitry Andric           Module::GetAllocationModuleCollectionMutex(), std::defer_lock);
30420b57cec5SDimitry Andric 
30430b57cec5SDimitry Andric       const ModuleList *module_list_ptr = nullptr;
30440b57cec5SDimitry Andric       const size_t argc = command.GetArgumentCount();
30450b57cec5SDimitry Andric       if (argc == 0) {
30460b57cec5SDimitry Andric         if (use_global_module_list) {
30470b57cec5SDimitry Andric           guard.lock();
30480b57cec5SDimitry Andric           num_modules = Module::GetNumberAllocatedModules();
30490b57cec5SDimitry Andric         } else {
30500b57cec5SDimitry Andric           module_list_ptr = &target->GetImages();
30510b57cec5SDimitry Andric         }
30520b57cec5SDimitry Andric       } else {
30535ffd83dbSDimitry Andric         for (const Args::ArgEntry &arg : command) {
30540b57cec5SDimitry Andric           // Dump specified images (by basename or fullpath)
30550b57cec5SDimitry Andric           const size_t num_matches = FindModulesByName(
30565ffd83dbSDimitry Andric               target, arg.c_str(), module_list, use_global_module_list);
30570b57cec5SDimitry Andric           if (num_matches == 0) {
30580b57cec5SDimitry Andric             if (argc == 1) {
30590b57cec5SDimitry Andric               result.AppendErrorWithFormat("no modules found that match '%s'",
30605ffd83dbSDimitry Andric                                            arg.c_str());
30610b57cec5SDimitry Andric               return false;
30620b57cec5SDimitry Andric             }
30630b57cec5SDimitry Andric           }
30640b57cec5SDimitry Andric         }
30650b57cec5SDimitry Andric 
30660b57cec5SDimitry Andric         module_list_ptr = &module_list;
30670b57cec5SDimitry Andric       }
30680b57cec5SDimitry Andric 
30690b57cec5SDimitry Andric       std::unique_lock<std::recursive_mutex> lock;
30700b57cec5SDimitry Andric       if (module_list_ptr != nullptr) {
30710b57cec5SDimitry Andric         lock =
30720b57cec5SDimitry Andric             std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex());
30730b57cec5SDimitry Andric 
30740b57cec5SDimitry Andric         num_modules = module_list_ptr->GetSize();
30750b57cec5SDimitry Andric       }
30760b57cec5SDimitry Andric 
30770b57cec5SDimitry Andric       if (num_modules > 0) {
30780b57cec5SDimitry Andric         for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
30790b57cec5SDimitry Andric           ModuleSP module_sp;
30800b57cec5SDimitry Andric           Module *module;
30810b57cec5SDimitry Andric           if (module_list_ptr) {
30820b57cec5SDimitry Andric             module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
30830b57cec5SDimitry Andric             module = module_sp.get();
30840b57cec5SDimitry Andric           } else {
30850b57cec5SDimitry Andric             module = Module::GetAllocatedModuleAtIndex(image_idx);
30860b57cec5SDimitry Andric             module_sp = module->shared_from_this();
30870b57cec5SDimitry Andric           }
30880b57cec5SDimitry Andric 
30890b57cec5SDimitry Andric           const size_t indent = strm.Printf("[%3u] ", image_idx);
30900b57cec5SDimitry Andric           PrintModule(target, module, indent, strm);
30910b57cec5SDimitry Andric         }
30920b57cec5SDimitry Andric         result.SetStatus(eReturnStatusSuccessFinishResult);
30930b57cec5SDimitry Andric       } else {
30940b57cec5SDimitry Andric         if (argc) {
30950b57cec5SDimitry Andric           if (use_global_module_list)
30960b57cec5SDimitry Andric             result.AppendError(
30970b57cec5SDimitry Andric                 "the global module list has no matching modules");
30980b57cec5SDimitry Andric           else
30990b57cec5SDimitry Andric             result.AppendError("the target has no matching modules");
31000b57cec5SDimitry Andric         } else {
31010b57cec5SDimitry Andric           if (use_global_module_list)
31020b57cec5SDimitry Andric             result.AppendError("the global module list is empty");
31030b57cec5SDimitry Andric           else
31040b57cec5SDimitry Andric             result.AppendError(
31050b57cec5SDimitry Andric                 "the target has no associated executable images");
31060b57cec5SDimitry Andric         }
31070b57cec5SDimitry Andric         return false;
31080b57cec5SDimitry Andric       }
31090b57cec5SDimitry Andric     }
31100b57cec5SDimitry Andric     return result.Succeeded();
31110b57cec5SDimitry Andric   }
31120b57cec5SDimitry Andric 
31130b57cec5SDimitry Andric   void PrintModule(Target *target, Module *module, int indent, Stream &strm) {
31140b57cec5SDimitry Andric     if (module == nullptr) {
31150b57cec5SDimitry Andric       strm.PutCString("Null module");
31160b57cec5SDimitry Andric       return;
31170b57cec5SDimitry Andric     }
31180b57cec5SDimitry Andric 
31190b57cec5SDimitry Andric     bool dump_object_name = false;
31200b57cec5SDimitry Andric     if (m_options.m_format_array.empty()) {
31210b57cec5SDimitry Andric       m_options.m_format_array.push_back(std::make_pair('u', 0));
31220b57cec5SDimitry Andric       m_options.m_format_array.push_back(std::make_pair('h', 0));
31230b57cec5SDimitry Andric       m_options.m_format_array.push_back(std::make_pair('f', 0));
31240b57cec5SDimitry Andric       m_options.m_format_array.push_back(std::make_pair('S', 0));
31250b57cec5SDimitry Andric     }
31260b57cec5SDimitry Andric     const size_t num_entries = m_options.m_format_array.size();
31270b57cec5SDimitry Andric     bool print_space = false;
31280b57cec5SDimitry Andric     for (size_t i = 0; i < num_entries; ++i) {
31290b57cec5SDimitry Andric       if (print_space)
31300b57cec5SDimitry Andric         strm.PutChar(' ');
31310b57cec5SDimitry Andric       print_space = true;
31320b57cec5SDimitry Andric       const char format_char = m_options.m_format_array[i].first;
31330b57cec5SDimitry Andric       uint32_t width = m_options.m_format_array[i].second;
31340b57cec5SDimitry Andric       switch (format_char) {
31350b57cec5SDimitry Andric       case 'A':
31360b57cec5SDimitry Andric         DumpModuleArchitecture(strm, module, false, width);
31370b57cec5SDimitry Andric         break;
31380b57cec5SDimitry Andric 
31390b57cec5SDimitry Andric       case 't':
31400b57cec5SDimitry Andric         DumpModuleArchitecture(strm, module, true, width);
31410b57cec5SDimitry Andric         break;
31420b57cec5SDimitry Andric 
31430b57cec5SDimitry Andric       case 'f':
31440b57cec5SDimitry Andric         DumpFullpath(strm, &module->GetFileSpec(), width);
31450b57cec5SDimitry Andric         dump_object_name = true;
31460b57cec5SDimitry Andric         break;
31470b57cec5SDimitry Andric 
31480b57cec5SDimitry Andric       case 'd':
31490b57cec5SDimitry Andric         DumpDirectory(strm, &module->GetFileSpec(), width);
31500b57cec5SDimitry Andric         break;
31510b57cec5SDimitry Andric 
31520b57cec5SDimitry Andric       case 'b':
31530b57cec5SDimitry Andric         DumpBasename(strm, &module->GetFileSpec(), width);
31540b57cec5SDimitry Andric         dump_object_name = true;
31550b57cec5SDimitry Andric         break;
31560b57cec5SDimitry Andric 
31570b57cec5SDimitry Andric       case 'h':
31580b57cec5SDimitry Andric       case 'o':
31590b57cec5SDimitry Andric         // Image header address
31600b57cec5SDimitry Andric         {
31610b57cec5SDimitry Andric           uint32_t addr_nibble_width =
31620b57cec5SDimitry Andric               target ? (target->GetArchitecture().GetAddressByteSize() * 2)
31630b57cec5SDimitry Andric                      : 16;
31640b57cec5SDimitry Andric 
31650b57cec5SDimitry Andric           ObjectFile *objfile = module->GetObjectFile();
31660b57cec5SDimitry Andric           if (objfile) {
31670b57cec5SDimitry Andric             Address base_addr(objfile->GetBaseAddress());
31680b57cec5SDimitry Andric             if (base_addr.IsValid()) {
31690b57cec5SDimitry Andric               if (target && !target->GetSectionLoadList().IsEmpty()) {
3170480093f4SDimitry Andric                 lldb::addr_t load_addr = base_addr.GetLoadAddress(target);
31710b57cec5SDimitry Andric                 if (load_addr == LLDB_INVALID_ADDRESS) {
31720b57cec5SDimitry Andric                   base_addr.Dump(&strm, target,
31730b57cec5SDimitry Andric                                  Address::DumpStyleModuleWithFileAddress,
31740b57cec5SDimitry Andric                                  Address::DumpStyleFileAddress);
31750b57cec5SDimitry Andric                 } else {
31760b57cec5SDimitry Andric                   if (format_char == 'o') {
31770b57cec5SDimitry Andric                     // Show the offset of slide for the image
3178480093f4SDimitry Andric                     strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3179480093f4SDimitry Andric                                 addr_nibble_width,
31800b57cec5SDimitry Andric                                 load_addr - base_addr.GetFileAddress());
31810b57cec5SDimitry Andric                   } else {
31820b57cec5SDimitry Andric                     // Show the load address of the image
31830b57cec5SDimitry Andric                     strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
31840b57cec5SDimitry Andric                                 addr_nibble_width, load_addr);
31850b57cec5SDimitry Andric                   }
31860b57cec5SDimitry Andric                 }
31870b57cec5SDimitry Andric                 break;
31880b57cec5SDimitry Andric               }
31890b57cec5SDimitry Andric               // The address was valid, but the image isn't loaded, output the
31900b57cec5SDimitry Andric               // address in an appropriate format
31910b57cec5SDimitry Andric               base_addr.Dump(&strm, target, Address::DumpStyleFileAddress);
31920b57cec5SDimitry Andric               break;
31930b57cec5SDimitry Andric             }
31940b57cec5SDimitry Andric           }
31950b57cec5SDimitry Andric           strm.Printf("%*s", addr_nibble_width + 2, "");
31960b57cec5SDimitry Andric         }
31970b57cec5SDimitry Andric         break;
31980b57cec5SDimitry Andric 
31990b57cec5SDimitry Andric       case 'r': {
32000b57cec5SDimitry Andric         size_t ref_count = 0;
32010b57cec5SDimitry Andric         ModuleSP module_sp(module->shared_from_this());
32020b57cec5SDimitry Andric         if (module_sp) {
32030b57cec5SDimitry Andric           // Take one away to make sure we don't count our local "module_sp"
32040b57cec5SDimitry Andric           ref_count = module_sp.use_count() - 1;
32050b57cec5SDimitry Andric         }
32060b57cec5SDimitry Andric         if (width)
32070b57cec5SDimitry Andric           strm.Printf("{%*" PRIu64 "}", width, (uint64_t)ref_count);
32080b57cec5SDimitry Andric         else
32090b57cec5SDimitry Andric           strm.Printf("{%" PRIu64 "}", (uint64_t)ref_count);
32100b57cec5SDimitry Andric       } break;
32110b57cec5SDimitry Andric 
32120b57cec5SDimitry Andric       case 's':
32130b57cec5SDimitry Andric       case 'S': {
32149dba64beSDimitry Andric         if (const SymbolFile *symbol_file = module->GetSymbolFile()) {
32159dba64beSDimitry Andric           const FileSpec symfile_spec =
32169dba64beSDimitry Andric               symbol_file->GetObjectFile()->GetFileSpec();
32170b57cec5SDimitry Andric           if (format_char == 'S') {
32180b57cec5SDimitry Andric             // Dump symbol file only if different from module file
32190b57cec5SDimitry Andric             if (!symfile_spec || symfile_spec == module->GetFileSpec()) {
32200b57cec5SDimitry Andric               print_space = false;
32210b57cec5SDimitry Andric               break;
32220b57cec5SDimitry Andric             }
32230b57cec5SDimitry Andric             // Add a newline and indent past the index
32240b57cec5SDimitry Andric             strm.Printf("\n%*s", indent, "");
32250b57cec5SDimitry Andric           }
32260b57cec5SDimitry Andric           DumpFullpath(strm, &symfile_spec, width);
32270b57cec5SDimitry Andric           dump_object_name = true;
32280b57cec5SDimitry Andric           break;
32290b57cec5SDimitry Andric         }
32300b57cec5SDimitry Andric         strm.Printf("%.*s", width, "<NONE>");
32310b57cec5SDimitry Andric       } break;
32320b57cec5SDimitry Andric 
32330b57cec5SDimitry Andric       case 'm':
32340b57cec5SDimitry Andric         strm.Format("{0:%c}", llvm::fmt_align(module->GetModificationTime(),
32350b57cec5SDimitry Andric                                               llvm::AlignStyle::Left, width));
32360b57cec5SDimitry Andric         break;
32370b57cec5SDimitry Andric 
32380b57cec5SDimitry Andric       case 'p':
32390b57cec5SDimitry Andric         strm.Printf("%p", static_cast<void *>(module));
32400b57cec5SDimitry Andric         break;
32410b57cec5SDimitry Andric 
32420b57cec5SDimitry Andric       case 'u':
32430b57cec5SDimitry Andric         DumpModuleUUID(strm, module);
32440b57cec5SDimitry Andric         break;
32450b57cec5SDimitry Andric 
32460b57cec5SDimitry Andric       default:
32470b57cec5SDimitry Andric         break;
32480b57cec5SDimitry Andric       }
32490b57cec5SDimitry Andric     }
32500b57cec5SDimitry Andric     if (dump_object_name) {
32510b57cec5SDimitry Andric       const char *object_name = module->GetObjectName().GetCString();
32520b57cec5SDimitry Andric       if (object_name)
32530b57cec5SDimitry Andric         strm.Printf("(%s)", object_name);
32540b57cec5SDimitry Andric     }
32550b57cec5SDimitry Andric     strm.EOL();
32560b57cec5SDimitry Andric   }
32570b57cec5SDimitry Andric 
32580b57cec5SDimitry Andric   CommandOptions m_options;
32590b57cec5SDimitry Andric };
32600b57cec5SDimitry Andric 
32610b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesShowUnwind
32620b57cec5SDimitry Andric 
32630b57cec5SDimitry Andric // Lookup unwind information in images
32649dba64beSDimitry Andric #define LLDB_OPTIONS_target_modules_show_unwind
32659dba64beSDimitry Andric #include "CommandOptions.inc"
32660b57cec5SDimitry Andric 
32670b57cec5SDimitry Andric class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {
32680b57cec5SDimitry Andric public:
32690b57cec5SDimitry Andric   enum {
32700b57cec5SDimitry Andric     eLookupTypeInvalid = -1,
32710b57cec5SDimitry Andric     eLookupTypeAddress = 0,
32720b57cec5SDimitry Andric     eLookupTypeSymbol,
32730b57cec5SDimitry Andric     eLookupTypeFunction,
32740b57cec5SDimitry Andric     eLookupTypeFunctionOrSymbol,
32750b57cec5SDimitry Andric     kNumLookupTypes
32760b57cec5SDimitry Andric   };
32770b57cec5SDimitry Andric 
32780b57cec5SDimitry Andric   class CommandOptions : public Options {
32790b57cec5SDimitry Andric   public:
328081ad6265SDimitry Andric     CommandOptions() = default;
32810b57cec5SDimitry Andric 
32820b57cec5SDimitry Andric     ~CommandOptions() override = default;
32830b57cec5SDimitry Andric 
32840b57cec5SDimitry Andric     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
32850b57cec5SDimitry Andric                           ExecutionContext *execution_context) override {
32860b57cec5SDimitry Andric       Status error;
32870b57cec5SDimitry Andric 
32880b57cec5SDimitry Andric       const int short_option = m_getopt_table[option_idx].val;
32890b57cec5SDimitry Andric 
32900b57cec5SDimitry Andric       switch (short_option) {
32910b57cec5SDimitry Andric       case 'a': {
32925ffd83dbSDimitry Andric         m_str = std::string(option_arg);
32930b57cec5SDimitry Andric         m_type = eLookupTypeAddress;
32940b57cec5SDimitry Andric         m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
32950b57cec5SDimitry Andric                                             LLDB_INVALID_ADDRESS, &error);
32960b57cec5SDimitry Andric         if (m_addr == LLDB_INVALID_ADDRESS)
32970b57cec5SDimitry Andric           error.SetErrorStringWithFormat("invalid address string '%s'",
32980b57cec5SDimitry Andric                                          option_arg.str().c_str());
32990b57cec5SDimitry Andric         break;
33000b57cec5SDimitry Andric       }
33010b57cec5SDimitry Andric 
33020b57cec5SDimitry Andric       case 'n':
33035ffd83dbSDimitry Andric         m_str = std::string(option_arg);
33040b57cec5SDimitry Andric         m_type = eLookupTypeFunctionOrSymbol;
33050b57cec5SDimitry Andric         break;
33060b57cec5SDimitry Andric 
33070b57cec5SDimitry Andric       default:
33089dba64beSDimitry Andric         llvm_unreachable("Unimplemented option");
33090b57cec5SDimitry Andric       }
33100b57cec5SDimitry Andric 
33110b57cec5SDimitry Andric       return error;
33120b57cec5SDimitry Andric     }
33130b57cec5SDimitry Andric 
33140b57cec5SDimitry Andric     void OptionParsingStarting(ExecutionContext *execution_context) override {
33150b57cec5SDimitry Andric       m_type = eLookupTypeInvalid;
33160b57cec5SDimitry Andric       m_str.clear();
33170b57cec5SDimitry Andric       m_addr = LLDB_INVALID_ADDRESS;
33180b57cec5SDimitry Andric     }
33190b57cec5SDimitry Andric 
33200b57cec5SDimitry Andric     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3321bdd1243dSDimitry Andric       return llvm::ArrayRef(g_target_modules_show_unwind_options);
33220b57cec5SDimitry Andric     }
33230b57cec5SDimitry Andric 
33240b57cec5SDimitry Andric     // Instance variables to hold the values for command options.
33250b57cec5SDimitry Andric 
3326fe6060f1SDimitry Andric     int m_type = eLookupTypeInvalid; // Should be a eLookupTypeXXX enum after
3327fe6060f1SDimitry Andric                                      // parsing options
33280b57cec5SDimitry Andric     std::string m_str; // Holds name lookup
3329fe6060f1SDimitry Andric     lldb::addr_t m_addr = LLDB_INVALID_ADDRESS; // Holds the address to lookup
33300b57cec5SDimitry Andric   };
33310b57cec5SDimitry Andric 
33320b57cec5SDimitry Andric   CommandObjectTargetModulesShowUnwind(CommandInterpreter &interpreter)
33330b57cec5SDimitry Andric       : CommandObjectParsed(
33340b57cec5SDimitry Andric             interpreter, "target modules show-unwind",
33350b57cec5SDimitry Andric             "Show synthesized unwind instructions for a function.", nullptr,
33360b57cec5SDimitry Andric             eCommandRequiresTarget | eCommandRequiresProcess |
333704eeddc0SDimitry Andric                 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {}
33380b57cec5SDimitry Andric 
33390b57cec5SDimitry Andric   ~CommandObjectTargetModulesShowUnwind() override = default;
33400b57cec5SDimitry Andric 
33410b57cec5SDimitry Andric   Options *GetOptions() override { return &m_options; }
33420b57cec5SDimitry Andric 
33430b57cec5SDimitry Andric protected:
33440b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
33450b57cec5SDimitry Andric     Target *target = m_exe_ctx.GetTargetPtr();
33460b57cec5SDimitry Andric     Process *process = m_exe_ctx.GetProcessPtr();
33470b57cec5SDimitry Andric     ABI *abi = nullptr;
33480b57cec5SDimitry Andric     if (process)
33490b57cec5SDimitry Andric       abi = process->GetABI().get();
33500b57cec5SDimitry Andric 
33510b57cec5SDimitry Andric     if (process == nullptr) {
33520b57cec5SDimitry Andric       result.AppendError(
33530b57cec5SDimitry Andric           "You must have a process running to use this command.");
33540b57cec5SDimitry Andric       return false;
33550b57cec5SDimitry Andric     }
33560b57cec5SDimitry Andric 
33570b57cec5SDimitry Andric     ThreadList threads(process->GetThreadList());
33580b57cec5SDimitry Andric     if (threads.GetSize() == 0) {
33590b57cec5SDimitry Andric       result.AppendError("The process must be paused to use this command.");
33600b57cec5SDimitry Andric       return false;
33610b57cec5SDimitry Andric     }
33620b57cec5SDimitry Andric 
33630b57cec5SDimitry Andric     ThreadSP thread(threads.GetThreadAtIndex(0));
33640b57cec5SDimitry Andric     if (!thread) {
33650b57cec5SDimitry Andric       result.AppendError("The process must be paused to use this command.");
33660b57cec5SDimitry Andric       return false;
33670b57cec5SDimitry Andric     }
33680b57cec5SDimitry Andric 
33690b57cec5SDimitry Andric     SymbolContextList sc_list;
33700b57cec5SDimitry Andric 
33710b57cec5SDimitry Andric     if (m_options.m_type == eLookupTypeFunctionOrSymbol) {
33720b57cec5SDimitry Andric       ConstString function_name(m_options.m_str.c_str());
3373349cc55cSDimitry Andric       ModuleFunctionSearchOptions function_options;
3374349cc55cSDimitry Andric       function_options.include_symbols = true;
3375349cc55cSDimitry Andric       function_options.include_inlines = false;
33760b57cec5SDimitry Andric       target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto,
3377349cc55cSDimitry Andric                                         function_options, sc_list);
33780b57cec5SDimitry Andric     } else if (m_options.m_type == eLookupTypeAddress && target) {
33790b57cec5SDimitry Andric       Address addr;
33800b57cec5SDimitry Andric       if (target->GetSectionLoadList().ResolveLoadAddress(m_options.m_addr,
33810b57cec5SDimitry Andric                                                           addr)) {
33820b57cec5SDimitry Andric         SymbolContext sc;
33830b57cec5SDimitry Andric         ModuleSP module_sp(addr.GetModule());
33840b57cec5SDimitry Andric         module_sp->ResolveSymbolContextForAddress(addr,
33850b57cec5SDimitry Andric                                                   eSymbolContextEverything, sc);
33860b57cec5SDimitry Andric         if (sc.function || sc.symbol) {
33870b57cec5SDimitry Andric           sc_list.Append(sc);
33880b57cec5SDimitry Andric         }
33890b57cec5SDimitry Andric       }
33900b57cec5SDimitry Andric     } else {
33910b57cec5SDimitry Andric       result.AppendError(
33920b57cec5SDimitry Andric           "address-expression or function name option must be specified.");
33930b57cec5SDimitry Andric       return false;
33940b57cec5SDimitry Andric     }
33950b57cec5SDimitry Andric 
3396*fe013be4SDimitry Andric     if (sc_list.GetSize() == 0) {
33970b57cec5SDimitry Andric       result.AppendErrorWithFormat("no unwind data found that matches '%s'.",
33980b57cec5SDimitry Andric                                    m_options.m_str.c_str());
33990b57cec5SDimitry Andric       return false;
34000b57cec5SDimitry Andric     }
34010b57cec5SDimitry Andric 
3402*fe013be4SDimitry Andric     for (const SymbolContext &sc : sc_list) {
34030b57cec5SDimitry Andric       if (sc.symbol == nullptr && sc.function == nullptr)
34040b57cec5SDimitry Andric         continue;
34050b57cec5SDimitry Andric       if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr)
34060b57cec5SDimitry Andric         continue;
34070b57cec5SDimitry Andric       AddressRange range;
34080b57cec5SDimitry Andric       if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,
34090b57cec5SDimitry Andric                               false, range))
34100b57cec5SDimitry Andric         continue;
34110b57cec5SDimitry Andric       if (!range.GetBaseAddress().IsValid())
34120b57cec5SDimitry Andric         continue;
34130b57cec5SDimitry Andric       ConstString funcname(sc.GetFunctionName());
34140b57cec5SDimitry Andric       if (funcname.IsEmpty())
34150b57cec5SDimitry Andric         continue;
34160b57cec5SDimitry Andric       addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
34170b57cec5SDimitry Andric       if (abi)
34180b57cec5SDimitry Andric         start_addr = abi->FixCodeAddress(start_addr);
34190b57cec5SDimitry Andric 
34200b57cec5SDimitry Andric       FuncUnwindersSP func_unwinders_sp(
34210b57cec5SDimitry Andric           sc.module_sp->GetUnwindTable()
34220b57cec5SDimitry Andric               .GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
34230b57cec5SDimitry Andric       if (!func_unwinders_sp)
34240b57cec5SDimitry Andric         continue;
34250b57cec5SDimitry Andric 
34260b57cec5SDimitry Andric       result.GetOutputStream().Printf(
3427e8d8bef9SDimitry Andric           "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n",
34280b57cec5SDimitry Andric           sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(),
34290b57cec5SDimitry Andric           funcname.AsCString(), start_addr);
34300b57cec5SDimitry Andric 
3431e8d8bef9SDimitry Andric       Args args;
3432e8d8bef9SDimitry Andric       target->GetUserSpecifiedTrapHandlerNames(args);
3433e8d8bef9SDimitry Andric       size_t count = args.GetArgumentCount();
3434e8d8bef9SDimitry Andric       for (size_t i = 0; i < count; i++) {
3435e8d8bef9SDimitry Andric         const char *trap_func_name = args.GetArgumentAtIndex(i);
3436e8d8bef9SDimitry Andric         if (strcmp(funcname.GetCString(), trap_func_name) == 0)
3437e8d8bef9SDimitry Andric           result.GetOutputStream().Printf(
3438e8d8bef9SDimitry Andric               "This function is "
3439e8d8bef9SDimitry Andric               "treated as a trap handler function via user setting.\n");
3440e8d8bef9SDimitry Andric       }
3441e8d8bef9SDimitry Andric       PlatformSP platform_sp(target->GetPlatform());
3442e8d8bef9SDimitry Andric       if (platform_sp) {
3443e8d8bef9SDimitry Andric         const std::vector<ConstString> trap_handler_names(
3444e8d8bef9SDimitry Andric             platform_sp->GetTrapHandlerSymbolNames());
3445e8d8bef9SDimitry Andric         for (ConstString trap_name : trap_handler_names) {
3446e8d8bef9SDimitry Andric           if (trap_name == funcname) {
3447e8d8bef9SDimitry Andric             result.GetOutputStream().Printf(
3448e8d8bef9SDimitry Andric                 "This function's "
3449e8d8bef9SDimitry Andric                 "name is listed by the platform as a trap handler.\n");
3450e8d8bef9SDimitry Andric           }
3451e8d8bef9SDimitry Andric         }
3452e8d8bef9SDimitry Andric       }
3453e8d8bef9SDimitry Andric 
3454e8d8bef9SDimitry Andric       result.GetOutputStream().Printf("\n");
3455e8d8bef9SDimitry Andric 
34560b57cec5SDimitry Andric       UnwindPlanSP non_callsite_unwind_plan =
34570b57cec5SDimitry Andric           func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread);
34580b57cec5SDimitry Andric       if (non_callsite_unwind_plan) {
34590b57cec5SDimitry Andric         result.GetOutputStream().Printf(
34600b57cec5SDimitry Andric             "Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n",
34610b57cec5SDimitry Andric             non_callsite_unwind_plan->GetSourceName().AsCString());
34620b57cec5SDimitry Andric       }
34630b57cec5SDimitry Andric       UnwindPlanSP callsite_unwind_plan =
34640b57cec5SDimitry Andric           func_unwinders_sp->GetUnwindPlanAtCallSite(*target, *thread);
34650b57cec5SDimitry Andric       if (callsite_unwind_plan) {
34660b57cec5SDimitry Andric         result.GetOutputStream().Printf(
34670b57cec5SDimitry Andric             "Synchronous (restricted to call-sites) UnwindPlan is '%s'\n",
34680b57cec5SDimitry Andric             callsite_unwind_plan->GetSourceName().AsCString());
34690b57cec5SDimitry Andric       }
34700b57cec5SDimitry Andric       UnwindPlanSP fast_unwind_plan =
34710b57cec5SDimitry Andric           func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread);
34720b57cec5SDimitry Andric       if (fast_unwind_plan) {
34730b57cec5SDimitry Andric         result.GetOutputStream().Printf(
34740b57cec5SDimitry Andric             "Fast UnwindPlan is '%s'\n",
34750b57cec5SDimitry Andric             fast_unwind_plan->GetSourceName().AsCString());
34760b57cec5SDimitry Andric       }
34770b57cec5SDimitry Andric 
34780b57cec5SDimitry Andric       result.GetOutputStream().Printf("\n");
34790b57cec5SDimitry Andric 
34800b57cec5SDimitry Andric       UnwindPlanSP assembly_sp =
34810b57cec5SDimitry Andric           func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread);
34820b57cec5SDimitry Andric       if (assembly_sp) {
34830b57cec5SDimitry Andric         result.GetOutputStream().Printf(
34840b57cec5SDimitry Andric             "Assembly language inspection UnwindPlan:\n");
34850b57cec5SDimitry Andric         assembly_sp->Dump(result.GetOutputStream(), thread.get(),
34860b57cec5SDimitry Andric                           LLDB_INVALID_ADDRESS);
34870b57cec5SDimitry Andric         result.GetOutputStream().Printf("\n");
34880b57cec5SDimitry Andric       }
34890b57cec5SDimitry Andric 
34909dba64beSDimitry Andric       UnwindPlanSP of_unwind_sp =
34919dba64beSDimitry Andric           func_unwinders_sp->GetObjectFileUnwindPlan(*target);
34929dba64beSDimitry Andric       if (of_unwind_sp) {
34939dba64beSDimitry Andric         result.GetOutputStream().Printf("object file UnwindPlan:\n");
34949dba64beSDimitry Andric         of_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
34959dba64beSDimitry Andric                            LLDB_INVALID_ADDRESS);
34969dba64beSDimitry Andric         result.GetOutputStream().Printf("\n");
34979dba64beSDimitry Andric       }
34989dba64beSDimitry Andric 
34999dba64beSDimitry Andric       UnwindPlanSP of_unwind_augmented_sp =
3500480093f4SDimitry Andric           func_unwinders_sp->GetObjectFileAugmentedUnwindPlan(*target, *thread);
35019dba64beSDimitry Andric       if (of_unwind_augmented_sp) {
35029dba64beSDimitry Andric         result.GetOutputStream().Printf("object file augmented UnwindPlan:\n");
35039dba64beSDimitry Andric         of_unwind_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
35049dba64beSDimitry Andric                                      LLDB_INVALID_ADDRESS);
35059dba64beSDimitry Andric         result.GetOutputStream().Printf("\n");
35069dba64beSDimitry Andric       }
35079dba64beSDimitry Andric 
35080b57cec5SDimitry Andric       UnwindPlanSP ehframe_sp =
35090b57cec5SDimitry Andric           func_unwinders_sp->GetEHFrameUnwindPlan(*target);
35100b57cec5SDimitry Andric       if (ehframe_sp) {
35110b57cec5SDimitry Andric         result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
35120b57cec5SDimitry Andric         ehframe_sp->Dump(result.GetOutputStream(), thread.get(),
35130b57cec5SDimitry Andric                          LLDB_INVALID_ADDRESS);
35140b57cec5SDimitry Andric         result.GetOutputStream().Printf("\n");
35150b57cec5SDimitry Andric       }
35160b57cec5SDimitry Andric 
35170b57cec5SDimitry Andric       UnwindPlanSP ehframe_augmented_sp =
35180b57cec5SDimitry Andric           func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread);
35190b57cec5SDimitry Andric       if (ehframe_augmented_sp) {
35200b57cec5SDimitry Andric         result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
35210b57cec5SDimitry Andric         ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
35220b57cec5SDimitry Andric                                    LLDB_INVALID_ADDRESS);
35230b57cec5SDimitry Andric         result.GetOutputStream().Printf("\n");
35240b57cec5SDimitry Andric       }
35250b57cec5SDimitry Andric 
35260b57cec5SDimitry Andric       if (UnwindPlanSP plan_sp =
35270b57cec5SDimitry Andric               func_unwinders_sp->GetDebugFrameUnwindPlan(*target)) {
35280b57cec5SDimitry Andric         result.GetOutputStream().Printf("debug_frame UnwindPlan:\n");
35290b57cec5SDimitry Andric         plan_sp->Dump(result.GetOutputStream(), thread.get(),
35300b57cec5SDimitry Andric                       LLDB_INVALID_ADDRESS);
35310b57cec5SDimitry Andric         result.GetOutputStream().Printf("\n");
35320b57cec5SDimitry Andric       }
35330b57cec5SDimitry Andric 
35340b57cec5SDimitry Andric       if (UnwindPlanSP plan_sp =
35350b57cec5SDimitry Andric               func_unwinders_sp->GetDebugFrameAugmentedUnwindPlan(*target,
35360b57cec5SDimitry Andric                                                                   *thread)) {
35370b57cec5SDimitry Andric         result.GetOutputStream().Printf("debug_frame augmented UnwindPlan:\n");
35380b57cec5SDimitry Andric         plan_sp->Dump(result.GetOutputStream(), thread.get(),
35390b57cec5SDimitry Andric                       LLDB_INVALID_ADDRESS);
35400b57cec5SDimitry Andric         result.GetOutputStream().Printf("\n");
35410b57cec5SDimitry Andric       }
35420b57cec5SDimitry Andric 
35430b57cec5SDimitry Andric       UnwindPlanSP arm_unwind_sp =
35440b57cec5SDimitry Andric           func_unwinders_sp->GetArmUnwindUnwindPlan(*target);
35450b57cec5SDimitry Andric       if (arm_unwind_sp) {
35460b57cec5SDimitry Andric         result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
35470b57cec5SDimitry Andric         arm_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
35480b57cec5SDimitry Andric                             LLDB_INVALID_ADDRESS);
35490b57cec5SDimitry Andric         result.GetOutputStream().Printf("\n");
35500b57cec5SDimitry Andric       }
35510b57cec5SDimitry Andric 
35520b57cec5SDimitry Andric       if (UnwindPlanSP symfile_plan_sp =
35530b57cec5SDimitry Andric               func_unwinders_sp->GetSymbolFileUnwindPlan(*thread)) {
35540b57cec5SDimitry Andric         result.GetOutputStream().Printf("Symbol file UnwindPlan:\n");
35550b57cec5SDimitry Andric         symfile_plan_sp->Dump(result.GetOutputStream(), thread.get(),
35560b57cec5SDimitry Andric                               LLDB_INVALID_ADDRESS);
35570b57cec5SDimitry Andric         result.GetOutputStream().Printf("\n");
35580b57cec5SDimitry Andric       }
35590b57cec5SDimitry Andric 
35600b57cec5SDimitry Andric       UnwindPlanSP compact_unwind_sp =
35610b57cec5SDimitry Andric           func_unwinders_sp->GetCompactUnwindUnwindPlan(*target);
35620b57cec5SDimitry Andric       if (compact_unwind_sp) {
35630b57cec5SDimitry Andric         result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
35640b57cec5SDimitry Andric         compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
35650b57cec5SDimitry Andric                                 LLDB_INVALID_ADDRESS);
35660b57cec5SDimitry Andric         result.GetOutputStream().Printf("\n");
35670b57cec5SDimitry Andric       }
35680b57cec5SDimitry Andric 
35690b57cec5SDimitry Andric       if (fast_unwind_plan) {
35700b57cec5SDimitry Andric         result.GetOutputStream().Printf("Fast UnwindPlan:\n");
35710b57cec5SDimitry Andric         fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(),
35720b57cec5SDimitry Andric                                LLDB_INVALID_ADDRESS);
35730b57cec5SDimitry Andric         result.GetOutputStream().Printf("\n");
35740b57cec5SDimitry Andric       }
35750b57cec5SDimitry Andric 
35760b57cec5SDimitry Andric       ABISP abi_sp = process->GetABI();
35770b57cec5SDimitry Andric       if (abi_sp) {
35780b57cec5SDimitry Andric         UnwindPlan arch_default(lldb::eRegisterKindGeneric);
35790b57cec5SDimitry Andric         if (abi_sp->CreateDefaultUnwindPlan(arch_default)) {
35800b57cec5SDimitry Andric           result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
35810b57cec5SDimitry Andric           arch_default.Dump(result.GetOutputStream(), thread.get(),
35820b57cec5SDimitry Andric                             LLDB_INVALID_ADDRESS);
35830b57cec5SDimitry Andric           result.GetOutputStream().Printf("\n");
35840b57cec5SDimitry Andric         }
35850b57cec5SDimitry Andric 
35860b57cec5SDimitry Andric         UnwindPlan arch_entry(lldb::eRegisterKindGeneric);
35870b57cec5SDimitry Andric         if (abi_sp->CreateFunctionEntryUnwindPlan(arch_entry)) {
35880b57cec5SDimitry Andric           result.GetOutputStream().Printf(
35890b57cec5SDimitry Andric               "Arch default at entry point UnwindPlan:\n");
35900b57cec5SDimitry Andric           arch_entry.Dump(result.GetOutputStream(), thread.get(),
35910b57cec5SDimitry Andric                           LLDB_INVALID_ADDRESS);
35920b57cec5SDimitry Andric           result.GetOutputStream().Printf("\n");
35930b57cec5SDimitry Andric         }
35940b57cec5SDimitry Andric       }
35950b57cec5SDimitry Andric 
35960b57cec5SDimitry Andric       result.GetOutputStream().Printf("\n");
35970b57cec5SDimitry Andric     }
35980b57cec5SDimitry Andric     return result.Succeeded();
35990b57cec5SDimitry Andric   }
36000b57cec5SDimitry Andric 
36010b57cec5SDimitry Andric   CommandOptions m_options;
36020b57cec5SDimitry Andric };
36030b57cec5SDimitry Andric 
36040b57cec5SDimitry Andric // Lookup information in images
36059dba64beSDimitry Andric #define LLDB_OPTIONS_target_modules_lookup
36069dba64beSDimitry Andric #include "CommandOptions.inc"
36070b57cec5SDimitry Andric 
36080b57cec5SDimitry Andric class CommandObjectTargetModulesLookup : public CommandObjectParsed {
36090b57cec5SDimitry Andric public:
36100b57cec5SDimitry Andric   enum {
36110b57cec5SDimitry Andric     eLookupTypeInvalid = -1,
36120b57cec5SDimitry Andric     eLookupTypeAddress = 0,
36130b57cec5SDimitry Andric     eLookupTypeSymbol,
36140b57cec5SDimitry Andric     eLookupTypeFileLine, // Line is optional
36150b57cec5SDimitry Andric     eLookupTypeFunction,
36160b57cec5SDimitry Andric     eLookupTypeFunctionOrSymbol,
36170b57cec5SDimitry Andric     eLookupTypeType,
36180b57cec5SDimitry Andric     kNumLookupTypes
36190b57cec5SDimitry Andric   };
36200b57cec5SDimitry Andric 
36210b57cec5SDimitry Andric   class CommandOptions : public Options {
36220b57cec5SDimitry Andric   public:
362304eeddc0SDimitry Andric     CommandOptions() { OptionParsingStarting(nullptr); }
36240b57cec5SDimitry Andric 
36250b57cec5SDimitry Andric     ~CommandOptions() override = default;
36260b57cec5SDimitry Andric 
36270b57cec5SDimitry Andric     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
36280b57cec5SDimitry Andric                           ExecutionContext *execution_context) override {
36290b57cec5SDimitry Andric       Status error;
36300b57cec5SDimitry Andric 
36310b57cec5SDimitry Andric       const int short_option = m_getopt_table[option_idx].val;
36320b57cec5SDimitry Andric 
36330b57cec5SDimitry Andric       switch (short_option) {
36340b57cec5SDimitry Andric       case 'a': {
36350b57cec5SDimitry Andric         m_type = eLookupTypeAddress;
36360b57cec5SDimitry Andric         m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
36370b57cec5SDimitry Andric                                             LLDB_INVALID_ADDRESS, &error);
36380b57cec5SDimitry Andric       } break;
36390b57cec5SDimitry Andric 
36400b57cec5SDimitry Andric       case 'o':
36410b57cec5SDimitry Andric         if (option_arg.getAsInteger(0, m_offset))
36420b57cec5SDimitry Andric           error.SetErrorStringWithFormat("invalid offset string '%s'",
36430b57cec5SDimitry Andric                                          option_arg.str().c_str());
36440b57cec5SDimitry Andric         break;
36450b57cec5SDimitry Andric 
36460b57cec5SDimitry Andric       case 's':
36475ffd83dbSDimitry Andric         m_str = std::string(option_arg);
36480b57cec5SDimitry Andric         m_type = eLookupTypeSymbol;
36490b57cec5SDimitry Andric         break;
36500b57cec5SDimitry Andric 
36510b57cec5SDimitry Andric       case 'f':
36520b57cec5SDimitry Andric         m_file.SetFile(option_arg, FileSpec::Style::native);
36530b57cec5SDimitry Andric         m_type = eLookupTypeFileLine;
36540b57cec5SDimitry Andric         break;
36550b57cec5SDimitry Andric 
36560b57cec5SDimitry Andric       case 'i':
36570b57cec5SDimitry Andric         m_include_inlines = false;
36580b57cec5SDimitry Andric         break;
36590b57cec5SDimitry Andric 
36600b57cec5SDimitry Andric       case 'l':
36610b57cec5SDimitry Andric         if (option_arg.getAsInteger(0, m_line_number))
36620b57cec5SDimitry Andric           error.SetErrorStringWithFormat("invalid line number string '%s'",
36630b57cec5SDimitry Andric                                          option_arg.str().c_str());
36640b57cec5SDimitry Andric         else if (m_line_number == 0)
36650b57cec5SDimitry Andric           error.SetErrorString("zero is an invalid line number");
36660b57cec5SDimitry Andric         m_type = eLookupTypeFileLine;
36670b57cec5SDimitry Andric         break;
36680b57cec5SDimitry Andric 
36690b57cec5SDimitry Andric       case 'F':
36705ffd83dbSDimitry Andric         m_str = std::string(option_arg);
36710b57cec5SDimitry Andric         m_type = eLookupTypeFunction;
36720b57cec5SDimitry Andric         break;
36730b57cec5SDimitry Andric 
36740b57cec5SDimitry Andric       case 'n':
36755ffd83dbSDimitry Andric         m_str = std::string(option_arg);
36760b57cec5SDimitry Andric         m_type = eLookupTypeFunctionOrSymbol;
36770b57cec5SDimitry Andric         break;
36780b57cec5SDimitry Andric 
36790b57cec5SDimitry Andric       case 't':
36805ffd83dbSDimitry Andric         m_str = std::string(option_arg);
36810b57cec5SDimitry Andric         m_type = eLookupTypeType;
36820b57cec5SDimitry Andric         break;
36830b57cec5SDimitry Andric 
36840b57cec5SDimitry Andric       case 'v':
36850b57cec5SDimitry Andric         m_verbose = true;
36860b57cec5SDimitry Andric         break;
36870b57cec5SDimitry Andric 
36880b57cec5SDimitry Andric       case 'A':
36890b57cec5SDimitry Andric         m_print_all = true;
36900b57cec5SDimitry Andric         break;
36910b57cec5SDimitry Andric 
36920b57cec5SDimitry Andric       case 'r':
36930b57cec5SDimitry Andric         m_use_regex = true;
36940b57cec5SDimitry Andric         break;
369581ad6265SDimitry Andric 
369681ad6265SDimitry Andric       case '\x01':
369781ad6265SDimitry Andric         m_all_ranges = true;
369881ad6265SDimitry Andric         break;
36999dba64beSDimitry Andric       default:
37009dba64beSDimitry Andric         llvm_unreachable("Unimplemented option");
37010b57cec5SDimitry Andric       }
37020b57cec5SDimitry Andric 
37030b57cec5SDimitry Andric       return error;
37040b57cec5SDimitry Andric     }
37050b57cec5SDimitry Andric 
37060b57cec5SDimitry Andric     void OptionParsingStarting(ExecutionContext *execution_context) override {
37070b57cec5SDimitry Andric       m_type = eLookupTypeInvalid;
37080b57cec5SDimitry Andric       m_str.clear();
37090b57cec5SDimitry Andric       m_file.Clear();
37100b57cec5SDimitry Andric       m_addr = LLDB_INVALID_ADDRESS;
37110b57cec5SDimitry Andric       m_offset = 0;
37120b57cec5SDimitry Andric       m_line_number = 0;
37130b57cec5SDimitry Andric       m_use_regex = false;
37140b57cec5SDimitry Andric       m_include_inlines = true;
371581ad6265SDimitry Andric       m_all_ranges = false;
37160b57cec5SDimitry Andric       m_verbose = false;
37170b57cec5SDimitry Andric       m_print_all = false;
37180b57cec5SDimitry Andric     }
37190b57cec5SDimitry Andric 
372081ad6265SDimitry Andric     Status OptionParsingFinished(ExecutionContext *execution_context) override {
372181ad6265SDimitry Andric       Status status;
372281ad6265SDimitry Andric       if (m_all_ranges && !m_verbose) {
372381ad6265SDimitry Andric         status.SetErrorString("--show-variable-ranges must be used in "
372481ad6265SDimitry Andric                               "conjunction with --verbose.");
372581ad6265SDimitry Andric       }
372681ad6265SDimitry Andric       return status;
372781ad6265SDimitry Andric     }
372881ad6265SDimitry Andric 
37290b57cec5SDimitry Andric     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3730bdd1243dSDimitry Andric       return llvm::ArrayRef(g_target_modules_lookup_options);
37310b57cec5SDimitry Andric     }
37320b57cec5SDimitry Andric 
37330b57cec5SDimitry Andric     int m_type;        // Should be a eLookupTypeXXX enum after parsing options
37340b57cec5SDimitry Andric     std::string m_str; // Holds name lookup
37350b57cec5SDimitry Andric     FileSpec m_file;   // Files for file lookups
37360b57cec5SDimitry Andric     lldb::addr_t m_addr; // Holds the address to lookup
37370b57cec5SDimitry Andric     lldb::addr_t
37380b57cec5SDimitry Andric         m_offset; // Subtract this offset from m_addr before doing lookups.
37390b57cec5SDimitry Andric     uint32_t m_line_number; // Line number for file+line lookups
37400b57cec5SDimitry Andric     bool m_use_regex;       // Name lookups in m_str are regular expressions.
37410b57cec5SDimitry Andric     bool m_include_inlines; // Check for inline entries when looking up by
37420b57cec5SDimitry Andric                             // file/line.
374381ad6265SDimitry Andric     bool m_all_ranges;      // Print all ranges or single range.
37440b57cec5SDimitry Andric     bool m_verbose;         // Enable verbose lookup info
37450b57cec5SDimitry Andric     bool m_print_all; // Print all matches, even in cases where there's a best
37460b57cec5SDimitry Andric                       // match.
37470b57cec5SDimitry Andric   };
37480b57cec5SDimitry Andric 
37490b57cec5SDimitry Andric   CommandObjectTargetModulesLookup(CommandInterpreter &interpreter)
37500b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "target modules lookup",
37510b57cec5SDimitry Andric                             "Look up information within executable and "
37520b57cec5SDimitry Andric                             "dependent shared library images.",
375304eeddc0SDimitry Andric                             nullptr, eCommandRequiresTarget) {
37540b57cec5SDimitry Andric     CommandArgumentEntry arg;
37550b57cec5SDimitry Andric     CommandArgumentData file_arg;
37560b57cec5SDimitry Andric 
37570b57cec5SDimitry Andric     // Define the first (and only) variant of this arg.
37580b57cec5SDimitry Andric     file_arg.arg_type = eArgTypeFilename;
37590b57cec5SDimitry Andric     file_arg.arg_repetition = eArgRepeatStar;
37600b57cec5SDimitry Andric 
37610b57cec5SDimitry Andric     // There is only one variant this argument could be; put it into the
37620b57cec5SDimitry Andric     // argument entry.
37630b57cec5SDimitry Andric     arg.push_back(file_arg);
37640b57cec5SDimitry Andric 
37650b57cec5SDimitry Andric     // Push the data for the first argument into the m_arguments vector.
37660b57cec5SDimitry Andric     m_arguments.push_back(arg);
37670b57cec5SDimitry Andric   }
37680b57cec5SDimitry Andric 
37690b57cec5SDimitry Andric   ~CommandObjectTargetModulesLookup() override = default;
37700b57cec5SDimitry Andric 
37710b57cec5SDimitry Andric   Options *GetOptions() override { return &m_options; }
37720b57cec5SDimitry Andric 
37730b57cec5SDimitry Andric   bool LookupHere(CommandInterpreter &interpreter, CommandReturnObject &result,
37740b57cec5SDimitry Andric                   bool &syntax_error) {
37750b57cec5SDimitry Andric     switch (m_options.m_type) {
37760b57cec5SDimitry Andric     case eLookupTypeAddress:
37770b57cec5SDimitry Andric     case eLookupTypeFileLine:
37780b57cec5SDimitry Andric     case eLookupTypeFunction:
37790b57cec5SDimitry Andric     case eLookupTypeFunctionOrSymbol:
37800b57cec5SDimitry Andric     case eLookupTypeSymbol:
37810b57cec5SDimitry Andric     default:
37820b57cec5SDimitry Andric       return false;
37830b57cec5SDimitry Andric     case eLookupTypeType:
37840b57cec5SDimitry Andric       break;
37850b57cec5SDimitry Andric     }
37860b57cec5SDimitry Andric 
37870b57cec5SDimitry Andric     StackFrameSP frame = m_exe_ctx.GetFrameSP();
37880b57cec5SDimitry Andric 
37890b57cec5SDimitry Andric     if (!frame)
37900b57cec5SDimitry Andric       return false;
37910b57cec5SDimitry Andric 
37920b57cec5SDimitry Andric     const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
37930b57cec5SDimitry Andric 
37940b57cec5SDimitry Andric     if (!sym_ctx.module_sp)
37950b57cec5SDimitry Andric       return false;
37960b57cec5SDimitry Andric 
37970b57cec5SDimitry Andric     switch (m_options.m_type) {
37980b57cec5SDimitry Andric     default:
37990b57cec5SDimitry Andric       return false;
38000b57cec5SDimitry Andric     case eLookupTypeType:
38010b57cec5SDimitry Andric       if (!m_options.m_str.empty()) {
3802e8d8bef9SDimitry Andric         if (LookupTypeHere(&GetSelectedTarget(), m_interpreter,
3803e8d8bef9SDimitry Andric                            result.GetOutputStream(), *sym_ctx.module_sp,
3804e8d8bef9SDimitry Andric                            m_options.m_str.c_str(), m_options.m_use_regex)) {
38050b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishResult);
38060b57cec5SDimitry Andric           return true;
38070b57cec5SDimitry Andric         }
38080b57cec5SDimitry Andric       }
38090b57cec5SDimitry Andric       break;
38100b57cec5SDimitry Andric     }
38110b57cec5SDimitry Andric 
3812480093f4SDimitry Andric     return false;
38130b57cec5SDimitry Andric   }
38140b57cec5SDimitry Andric 
38150b57cec5SDimitry Andric   bool LookupInModule(CommandInterpreter &interpreter, Module *module,
38160b57cec5SDimitry Andric                       CommandReturnObject &result, bool &syntax_error) {
38170b57cec5SDimitry Andric     switch (m_options.m_type) {
38180b57cec5SDimitry Andric     case eLookupTypeAddress:
38190b57cec5SDimitry Andric       if (m_options.m_addr != LLDB_INVALID_ADDRESS) {
38200b57cec5SDimitry Andric         if (LookupAddressInModule(
38210b57cec5SDimitry Andric                 m_interpreter, result.GetOutputStream(), module,
38220b57cec5SDimitry Andric                 eSymbolContextEverything |
38230b57cec5SDimitry Andric                     (m_options.m_verbose
38240b57cec5SDimitry Andric                          ? static_cast<int>(eSymbolContextVariable)
38250b57cec5SDimitry Andric                          : 0),
382681ad6265SDimitry Andric                 m_options.m_addr, m_options.m_offset, m_options.m_verbose,
382781ad6265SDimitry Andric                 m_options.m_all_ranges)) {
38280b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishResult);
38290b57cec5SDimitry Andric           return true;
38300b57cec5SDimitry Andric         }
38310b57cec5SDimitry Andric       }
38320b57cec5SDimitry Andric       break;
38330b57cec5SDimitry Andric 
38340b57cec5SDimitry Andric     case eLookupTypeSymbol:
38350b57cec5SDimitry Andric       if (!m_options.m_str.empty()) {
38360b57cec5SDimitry Andric         if (LookupSymbolInModule(m_interpreter, result.GetOutputStream(),
38370b57cec5SDimitry Andric                                  module, m_options.m_str.c_str(),
383881ad6265SDimitry Andric                                  m_options.m_use_regex, m_options.m_verbose,
383981ad6265SDimitry Andric                                  m_options.m_all_ranges)) {
38400b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishResult);
38410b57cec5SDimitry Andric           return true;
38420b57cec5SDimitry Andric         }
38430b57cec5SDimitry Andric       }
38440b57cec5SDimitry Andric       break;
38450b57cec5SDimitry Andric 
38460b57cec5SDimitry Andric     case eLookupTypeFileLine:
38470b57cec5SDimitry Andric       if (m_options.m_file) {
38480b57cec5SDimitry Andric         if (LookupFileAndLineInModule(
38490b57cec5SDimitry Andric                 m_interpreter, result.GetOutputStream(), module,
38500b57cec5SDimitry Andric                 m_options.m_file, m_options.m_line_number,
385181ad6265SDimitry Andric                 m_options.m_include_inlines, m_options.m_verbose,
385281ad6265SDimitry Andric                 m_options.m_all_ranges)) {
38530b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishResult);
38540b57cec5SDimitry Andric           return true;
38550b57cec5SDimitry Andric         }
38560b57cec5SDimitry Andric       }
38570b57cec5SDimitry Andric       break;
38580b57cec5SDimitry Andric 
38590b57cec5SDimitry Andric     case eLookupTypeFunctionOrSymbol:
38600b57cec5SDimitry Andric     case eLookupTypeFunction:
38610b57cec5SDimitry Andric       if (!m_options.m_str.empty()) {
3862349cc55cSDimitry Andric         ModuleFunctionSearchOptions function_options;
3863349cc55cSDimitry Andric         function_options.include_symbols =
3864349cc55cSDimitry Andric             m_options.m_type == eLookupTypeFunctionOrSymbol;
3865349cc55cSDimitry Andric         function_options.include_inlines = m_options.m_include_inlines;
3866349cc55cSDimitry Andric 
3867349cc55cSDimitry Andric         if (LookupFunctionInModule(m_interpreter, result.GetOutputStream(),
3868349cc55cSDimitry Andric                                    module, m_options.m_str.c_str(),
3869349cc55cSDimitry Andric                                    m_options.m_use_regex, function_options,
387081ad6265SDimitry Andric                                    m_options.m_verbose,
387181ad6265SDimitry Andric                                    m_options.m_all_ranges)) {
38720b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishResult);
38730b57cec5SDimitry Andric           return true;
38740b57cec5SDimitry Andric         }
38750b57cec5SDimitry Andric       }
38760b57cec5SDimitry Andric       break;
38770b57cec5SDimitry Andric 
38780b57cec5SDimitry Andric     case eLookupTypeType:
38790b57cec5SDimitry Andric       if (!m_options.m_str.empty()) {
3880e8d8bef9SDimitry Andric         if (LookupTypeInModule(
3881e8d8bef9SDimitry Andric                 &GetSelectedTarget(), m_interpreter, result.GetOutputStream(),
3882e8d8bef9SDimitry Andric                 module, m_options.m_str.c_str(), m_options.m_use_regex)) {
38830b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishResult);
38840b57cec5SDimitry Andric           return true;
38850b57cec5SDimitry Andric         }
38860b57cec5SDimitry Andric       }
38870b57cec5SDimitry Andric       break;
38880b57cec5SDimitry Andric 
38890b57cec5SDimitry Andric     default:
38900b57cec5SDimitry Andric       m_options.GenerateOptionUsage(
389181ad6265SDimitry Andric           result.GetErrorStream(), *this,
38920b57cec5SDimitry Andric           GetCommandInterpreter().GetDebugger().GetTerminalWidth());
38930b57cec5SDimitry Andric       syntax_error = true;
38940b57cec5SDimitry Andric       break;
38950b57cec5SDimitry Andric     }
38960b57cec5SDimitry Andric 
38970b57cec5SDimitry Andric     result.SetStatus(eReturnStatusFailed);
38980b57cec5SDimitry Andric     return false;
38990b57cec5SDimitry Andric   }
39000b57cec5SDimitry Andric 
39010b57cec5SDimitry Andric protected:
39020b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
39039dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
39040b57cec5SDimitry Andric     bool syntax_error = false;
39050b57cec5SDimitry Andric     uint32_t i;
39060b57cec5SDimitry Andric     uint32_t num_successful_lookups = 0;
39070b57cec5SDimitry Andric     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
39080b57cec5SDimitry Andric     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
39090b57cec5SDimitry Andric     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
39100b57cec5SDimitry Andric     // Dump all sections for all modules images
39110b57cec5SDimitry Andric 
39120b57cec5SDimitry Andric     if (command.GetArgumentCount() == 0) {
39130b57cec5SDimitry Andric       ModuleSP current_module;
39140b57cec5SDimitry Andric 
39150b57cec5SDimitry Andric       // Where it is possible to look in the current symbol context first,
39160b57cec5SDimitry Andric       // try that.  If this search was successful and --all was not passed,
39170b57cec5SDimitry Andric       // don't print anything else.
39180b57cec5SDimitry Andric       if (LookupHere(m_interpreter, result, syntax_error)) {
39190b57cec5SDimitry Andric         result.GetOutputStream().EOL();
39200b57cec5SDimitry Andric         num_successful_lookups++;
39210b57cec5SDimitry Andric         if (!m_options.m_print_all) {
39220b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishResult);
39230b57cec5SDimitry Andric           return result.Succeeded();
39240b57cec5SDimitry Andric         }
39250b57cec5SDimitry Andric       }
39260b57cec5SDimitry Andric 
39270b57cec5SDimitry Andric       // Dump all sections for all other modules
39280b57cec5SDimitry Andric 
39290b57cec5SDimitry Andric       const ModuleList &target_modules = target->GetImages();
39300b57cec5SDimitry Andric       std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
3931e8d8bef9SDimitry Andric       if (target_modules.GetSize() == 0) {
39320b57cec5SDimitry Andric         result.AppendError("the target has no associated executable images");
39330b57cec5SDimitry Andric         return false;
39340b57cec5SDimitry Andric       }
3935e8d8bef9SDimitry Andric 
3936e8d8bef9SDimitry Andric       for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
3937e8d8bef9SDimitry Andric         if (module_sp != current_module &&
3938e8d8bef9SDimitry Andric             LookupInModule(m_interpreter, module_sp.get(), result,
3939e8d8bef9SDimitry Andric                            syntax_error)) {
3940e8d8bef9SDimitry Andric           result.GetOutputStream().EOL();
3941e8d8bef9SDimitry Andric           num_successful_lookups++;
3942e8d8bef9SDimitry Andric         }
3943e8d8bef9SDimitry Andric       }
39440b57cec5SDimitry Andric     } else {
39450b57cec5SDimitry Andric       // Dump specified images (by basename or fullpath)
39460b57cec5SDimitry Andric       const char *arg_cstr;
39470b57cec5SDimitry Andric       for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr &&
39480b57cec5SDimitry Andric                   !syntax_error;
39490b57cec5SDimitry Andric            ++i) {
39500b57cec5SDimitry Andric         ModuleList module_list;
39510b57cec5SDimitry Andric         const size_t num_matches =
39520b57cec5SDimitry Andric             FindModulesByName(target, arg_cstr, module_list, false);
39530b57cec5SDimitry Andric         if (num_matches > 0) {
39540b57cec5SDimitry Andric           for (size_t j = 0; j < num_matches; ++j) {
39550b57cec5SDimitry Andric             Module *module = module_list.GetModulePointerAtIndex(j);
39560b57cec5SDimitry Andric             if (module) {
39579dba64beSDimitry Andric               if (LookupInModule(m_interpreter, module, result, syntax_error)) {
39580b57cec5SDimitry Andric                 result.GetOutputStream().EOL();
39590b57cec5SDimitry Andric                 num_successful_lookups++;
39600b57cec5SDimitry Andric               }
39610b57cec5SDimitry Andric             }
39620b57cec5SDimitry Andric           }
39630b57cec5SDimitry Andric         } else
39640b57cec5SDimitry Andric           result.AppendWarningWithFormat(
39650b57cec5SDimitry Andric               "Unable to find an image that matches '%s'.\n", arg_cstr);
39660b57cec5SDimitry Andric       }
39670b57cec5SDimitry Andric     }
39680b57cec5SDimitry Andric 
39690b57cec5SDimitry Andric     if (num_successful_lookups > 0)
39700b57cec5SDimitry Andric       result.SetStatus(eReturnStatusSuccessFinishResult);
39710b57cec5SDimitry Andric     else
39720b57cec5SDimitry Andric       result.SetStatus(eReturnStatusFailed);
39730b57cec5SDimitry Andric     return result.Succeeded();
39740b57cec5SDimitry Andric   }
39750b57cec5SDimitry Andric 
39760b57cec5SDimitry Andric   CommandOptions m_options;
39770b57cec5SDimitry Andric };
39780b57cec5SDimitry Andric 
39790b57cec5SDimitry Andric #pragma mark CommandObjectMultiwordImageSearchPaths
39800b57cec5SDimitry Andric 
39810b57cec5SDimitry Andric // CommandObjectMultiwordImageSearchPaths
39820b57cec5SDimitry Andric 
39830b57cec5SDimitry Andric class CommandObjectTargetModulesImageSearchPaths
39840b57cec5SDimitry Andric     : public CommandObjectMultiword {
39850b57cec5SDimitry Andric public:
39860b57cec5SDimitry Andric   CommandObjectTargetModulesImageSearchPaths(CommandInterpreter &interpreter)
39870b57cec5SDimitry Andric       : CommandObjectMultiword(
39880b57cec5SDimitry Andric             interpreter, "target modules search-paths",
39890b57cec5SDimitry Andric             "Commands for managing module search paths for a target.",
39900b57cec5SDimitry Andric             "target modules search-paths <subcommand> [<subcommand-options>]") {
39910b57cec5SDimitry Andric     LoadSubCommand(
39920b57cec5SDimitry Andric         "add", CommandObjectSP(
39930b57cec5SDimitry Andric                    new CommandObjectTargetModulesSearchPathsAdd(interpreter)));
39940b57cec5SDimitry Andric     LoadSubCommand(
39950b57cec5SDimitry Andric         "clear", CommandObjectSP(new CommandObjectTargetModulesSearchPathsClear(
39960b57cec5SDimitry Andric                      interpreter)));
39970b57cec5SDimitry Andric     LoadSubCommand(
39980b57cec5SDimitry Andric         "insert",
39990b57cec5SDimitry Andric         CommandObjectSP(
40000b57cec5SDimitry Andric             new CommandObjectTargetModulesSearchPathsInsert(interpreter)));
40010b57cec5SDimitry Andric     LoadSubCommand(
40020b57cec5SDimitry Andric         "list", CommandObjectSP(new CommandObjectTargetModulesSearchPathsList(
40030b57cec5SDimitry Andric                     interpreter)));
40040b57cec5SDimitry Andric     LoadSubCommand(
40050b57cec5SDimitry Andric         "query", CommandObjectSP(new CommandObjectTargetModulesSearchPathsQuery(
40060b57cec5SDimitry Andric                      interpreter)));
40070b57cec5SDimitry Andric   }
40080b57cec5SDimitry Andric 
40090b57cec5SDimitry Andric   ~CommandObjectTargetModulesImageSearchPaths() override = default;
40100b57cec5SDimitry Andric };
40110b57cec5SDimitry Andric 
40120b57cec5SDimitry Andric #pragma mark CommandObjectTargetModules
40130b57cec5SDimitry Andric 
40140b57cec5SDimitry Andric // CommandObjectTargetModules
40150b57cec5SDimitry Andric 
40160b57cec5SDimitry Andric class CommandObjectTargetModules : public CommandObjectMultiword {
40170b57cec5SDimitry Andric public:
40180b57cec5SDimitry Andric   // Constructors and Destructors
40190b57cec5SDimitry Andric   CommandObjectTargetModules(CommandInterpreter &interpreter)
40200b57cec5SDimitry Andric       : CommandObjectMultiword(interpreter, "target modules",
40210b57cec5SDimitry Andric                                "Commands for accessing information for one or "
40220b57cec5SDimitry Andric                                "more target modules.",
40230b57cec5SDimitry Andric                                "target modules <sub-command> ...") {
40240b57cec5SDimitry Andric     LoadSubCommand(
40250b57cec5SDimitry Andric         "add", CommandObjectSP(new CommandObjectTargetModulesAdd(interpreter)));
40260b57cec5SDimitry Andric     LoadSubCommand("load", CommandObjectSP(new CommandObjectTargetModulesLoad(
40270b57cec5SDimitry Andric                                interpreter)));
40280b57cec5SDimitry Andric     LoadSubCommand("dump", CommandObjectSP(new CommandObjectTargetModulesDump(
40290b57cec5SDimitry Andric                                interpreter)));
40300b57cec5SDimitry Andric     LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetModulesList(
40310b57cec5SDimitry Andric                                interpreter)));
40320b57cec5SDimitry Andric     LoadSubCommand(
40330b57cec5SDimitry Andric         "lookup",
40340b57cec5SDimitry Andric         CommandObjectSP(new CommandObjectTargetModulesLookup(interpreter)));
40350b57cec5SDimitry Andric     LoadSubCommand(
40360b57cec5SDimitry Andric         "search-paths",
40370b57cec5SDimitry Andric         CommandObjectSP(
40380b57cec5SDimitry Andric             new CommandObjectTargetModulesImageSearchPaths(interpreter)));
40390b57cec5SDimitry Andric     LoadSubCommand(
40400b57cec5SDimitry Andric         "show-unwind",
40410b57cec5SDimitry Andric         CommandObjectSP(new CommandObjectTargetModulesShowUnwind(interpreter)));
40420b57cec5SDimitry Andric   }
40430b57cec5SDimitry Andric 
40440b57cec5SDimitry Andric   ~CommandObjectTargetModules() override = default;
40450b57cec5SDimitry Andric 
40460b57cec5SDimitry Andric private:
40470b57cec5SDimitry Andric   // For CommandObjectTargetModules only
40485ffd83dbSDimitry Andric   CommandObjectTargetModules(const CommandObjectTargetModules &) = delete;
40495ffd83dbSDimitry Andric   const CommandObjectTargetModules &
40505ffd83dbSDimitry Andric   operator=(const CommandObjectTargetModules &) = delete;
40510b57cec5SDimitry Andric };
40520b57cec5SDimitry Andric 
40530b57cec5SDimitry Andric class CommandObjectTargetSymbolsAdd : public CommandObjectParsed {
40540b57cec5SDimitry Andric public:
40550b57cec5SDimitry Andric   CommandObjectTargetSymbolsAdd(CommandInterpreter &interpreter)
40560b57cec5SDimitry Andric       : CommandObjectParsed(
40570b57cec5SDimitry Andric             interpreter, "target symbols add",
40580b57cec5SDimitry Andric             "Add a debug symbol file to one of the target's current modules by "
40595ffd83dbSDimitry Andric             "specifying a path to a debug symbols file or by using the options "
40605ffd83dbSDimitry Andric             "to specify a module.",
40610b57cec5SDimitry Andric             "target symbols add <cmd-options> [<symfile>]",
40620b57cec5SDimitry Andric             eCommandRequiresTarget),
40630b57cec5SDimitry Andric         m_file_option(
4064*fe013be4SDimitry Andric             LLDB_OPT_SET_1, false, "shlib", 's', lldb::eModuleCompletion,
4065*fe013be4SDimitry Andric             eArgTypeShlibName,
40665ffd83dbSDimitry Andric             "Locate the debug symbols for the shared library specified by "
40675ffd83dbSDimitry Andric             "name."),
40680b57cec5SDimitry Andric         m_current_frame_option(
40690b57cec5SDimitry Andric             LLDB_OPT_SET_2, false, "frame", 'F',
4070349cc55cSDimitry Andric             "Locate the debug symbols for the currently selected frame.", false,
4071349cc55cSDimitry Andric             true),
4072349cc55cSDimitry Andric         m_current_stack_option(LLDB_OPT_SET_2, false, "stack", 'S',
4073349cc55cSDimitry Andric                                "Locate the debug symbols for every frame in "
4074349cc55cSDimitry Andric                                "the current call stack.",
40755ffd83dbSDimitry Andric                                false, true)
40760b57cec5SDimitry Andric 
40770b57cec5SDimitry Andric   {
40780b57cec5SDimitry Andric     m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
40790b57cec5SDimitry Andric                           LLDB_OPT_SET_1);
40800b57cec5SDimitry Andric     m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
40810b57cec5SDimitry Andric     m_option_group.Append(&m_current_frame_option, LLDB_OPT_SET_2,
40820b57cec5SDimitry Andric                           LLDB_OPT_SET_2);
4083349cc55cSDimitry Andric     m_option_group.Append(&m_current_stack_option, LLDB_OPT_SET_2,
4084349cc55cSDimitry Andric                           LLDB_OPT_SET_2);
40850b57cec5SDimitry Andric     m_option_group.Finalize();
408681ad6265SDimitry Andric     CommandArgumentData module_arg{eArgTypeShlibName, eArgRepeatPlain};
408781ad6265SDimitry Andric     m_arguments.push_back({module_arg});
40880b57cec5SDimitry Andric   }
40890b57cec5SDimitry Andric 
40900b57cec5SDimitry Andric   ~CommandObjectTargetSymbolsAdd() override = default;
40910b57cec5SDimitry Andric 
40929dba64beSDimitry Andric   void
40939dba64beSDimitry Andric   HandleArgumentCompletion(CompletionRequest &request,
40940b57cec5SDimitry Andric                            OptionElementVector &opt_element_vector) override {
4095*fe013be4SDimitry Andric     lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
4096*fe013be4SDimitry Andric         GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr);
40970b57cec5SDimitry Andric   }
40980b57cec5SDimitry Andric 
40990b57cec5SDimitry Andric   Options *GetOptions() override { return &m_option_group; }
41000b57cec5SDimitry Andric 
41010b57cec5SDimitry Andric protected:
41020b57cec5SDimitry Andric   bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush,
41030b57cec5SDimitry Andric                         CommandReturnObject &result) {
41040b57cec5SDimitry Andric     const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
4105480093f4SDimitry Andric     if (!symbol_fspec) {
4106480093f4SDimitry Andric       result.AppendError(
4107480093f4SDimitry Andric           "one or more executable image paths must be specified");
4108480093f4SDimitry Andric       return false;
4109480093f4SDimitry Andric     }
4110480093f4SDimitry Andric 
41110b57cec5SDimitry Andric     char symfile_path[PATH_MAX];
41120b57cec5SDimitry Andric     symbol_fspec.GetPath(symfile_path, sizeof(symfile_path));
41130b57cec5SDimitry Andric 
41140b57cec5SDimitry Andric     if (!module_spec.GetUUID().IsValid()) {
41150b57cec5SDimitry Andric       if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
4116bdd1243dSDimitry Andric         module_spec.GetFileSpec().SetFilename(symbol_fspec.GetFilename());
41170b57cec5SDimitry Andric     }
4118480093f4SDimitry Andric 
41195ffd83dbSDimitry Andric     // Now module_spec represents a symbol file for a module that might exist
41205ffd83dbSDimitry Andric     // in the current target.  Let's find possible matches.
41215ffd83dbSDimitry Andric     ModuleList matching_modules;
41220b57cec5SDimitry Andric 
41230b57cec5SDimitry Andric     // First extract all module specs from the symbol file
41240b57cec5SDimitry Andric     lldb_private::ModuleSpecList symfile_module_specs;
41250b57cec5SDimitry Andric     if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(),
41260b57cec5SDimitry Andric                                             0, 0, symfile_module_specs)) {
41270b57cec5SDimitry Andric       // Now extract the module spec that matches the target architecture
41280b57cec5SDimitry Andric       ModuleSpec target_arch_module_spec;
41290b57cec5SDimitry Andric       ModuleSpec symfile_module_spec;
41300b57cec5SDimitry Andric       target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
41310b57cec5SDimitry Andric       if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec,
41320b57cec5SDimitry Andric                                                       symfile_module_spec)) {
41330b57cec5SDimitry Andric         if (symfile_module_spec.GetUUID().IsValid()) {
41340b57cec5SDimitry Andric           // It has a UUID, look for this UUID in the target modules
41350b57cec5SDimitry Andric           ModuleSpec symfile_uuid_module_spec;
41360b57cec5SDimitry Andric           symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
41379dba64beSDimitry Andric           target->GetImages().FindModules(symfile_uuid_module_spec,
41385ffd83dbSDimitry Andric                                           matching_modules);
41390b57cec5SDimitry Andric         }
41400b57cec5SDimitry Andric       }
41410b57cec5SDimitry Andric 
41425ffd83dbSDimitry Andric       if (matching_modules.IsEmpty()) {
41435ffd83dbSDimitry Andric         // No matches yet.  Iterate through the module specs to find a UUID
41445ffd83dbSDimitry Andric         // value that we can match up to an image in our target.
41455ffd83dbSDimitry Andric         const size_t num_symfile_module_specs = symfile_module_specs.GetSize();
41465ffd83dbSDimitry Andric         for (size_t i = 0;
41475ffd83dbSDimitry Andric              i < num_symfile_module_specs && matching_modules.IsEmpty(); ++i) {
41480b57cec5SDimitry Andric           if (symfile_module_specs.GetModuleSpecAtIndex(
41490b57cec5SDimitry Andric                   i, symfile_module_spec)) {
41500b57cec5SDimitry Andric             if (symfile_module_spec.GetUUID().IsValid()) {
41515ffd83dbSDimitry Andric               // It has a UUID.  Look for this UUID in the target modules.
41520b57cec5SDimitry Andric               ModuleSpec symfile_uuid_module_spec;
41530b57cec5SDimitry Andric               symfile_uuid_module_spec.GetUUID() =
41540b57cec5SDimitry Andric                   symfile_module_spec.GetUUID();
41559dba64beSDimitry Andric               target->GetImages().FindModules(symfile_uuid_module_spec,
41565ffd83dbSDimitry Andric                                               matching_modules);
41570b57cec5SDimitry Andric             }
41580b57cec5SDimitry Andric           }
41590b57cec5SDimitry Andric         }
41600b57cec5SDimitry Andric       }
41610b57cec5SDimitry Andric     }
41620b57cec5SDimitry Andric 
41630b57cec5SDimitry Andric     // Just try to match up the file by basename if we have no matches at
41645ffd83dbSDimitry Andric     // this point.  For example, module foo might have symbols in foo.debug.
41655ffd83dbSDimitry Andric     if (matching_modules.IsEmpty())
41665ffd83dbSDimitry Andric       target->GetImages().FindModules(module_spec, matching_modules);
41670b57cec5SDimitry Andric 
41685ffd83dbSDimitry Andric     while (matching_modules.IsEmpty()) {
41690b57cec5SDimitry Andric       ConstString filename_no_extension(
41700b57cec5SDimitry Andric           module_spec.GetFileSpec().GetFileNameStrippingExtension());
4171480093f4SDimitry Andric       // Empty string returned, let's bail
41720b57cec5SDimitry Andric       if (!filename_no_extension)
41730b57cec5SDimitry Andric         break;
41740b57cec5SDimitry Andric 
4175480093f4SDimitry Andric       // Check if there was no extension to strip and the basename is the same
41760b57cec5SDimitry Andric       if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
41770b57cec5SDimitry Andric         break;
41780b57cec5SDimitry Andric 
4179480093f4SDimitry Andric       // Replace basename with one fewer extension
4180bdd1243dSDimitry Andric       module_spec.GetFileSpec().SetFilename(filename_no_extension);
41815ffd83dbSDimitry Andric       target->GetImages().FindModules(module_spec, matching_modules);
41820b57cec5SDimitry Andric     }
41830b57cec5SDimitry Andric 
41845ffd83dbSDimitry Andric     if (matching_modules.GetSize() > 1) {
41850b57cec5SDimitry Andric       result.AppendErrorWithFormat("multiple modules match symbol file '%s', "
41860b57cec5SDimitry Andric                                    "use the --uuid option to resolve the "
41870b57cec5SDimitry Andric                                    "ambiguity.\n",
41880b57cec5SDimitry Andric                                    symfile_path);
41895ffd83dbSDimitry Andric       return false;
41905ffd83dbSDimitry Andric     }
41915ffd83dbSDimitry Andric 
41925ffd83dbSDimitry Andric     if (matching_modules.GetSize() == 1) {
41935ffd83dbSDimitry Andric       ModuleSP module_sp(matching_modules.GetModuleAtIndex(0));
41940b57cec5SDimitry Andric 
41950b57cec5SDimitry Andric       // The module has not yet created its symbol vendor, we can just give
41960b57cec5SDimitry Andric       // the existing target module the symfile path to use for when it
41970b57cec5SDimitry Andric       // decides to create it!
41980b57cec5SDimitry Andric       module_sp->SetSymbolFileFileSpec(symbol_fspec);
41990b57cec5SDimitry Andric 
42009dba64beSDimitry Andric       SymbolFile *symbol_file =
42019dba64beSDimitry Andric           module_sp->GetSymbolFile(true, &result.GetErrorStream());
42020b57cec5SDimitry Andric       if (symbol_file) {
42030b57cec5SDimitry Andric         ObjectFile *object_file = symbol_file->GetObjectFile();
42040b57cec5SDimitry Andric         if (object_file && object_file->GetFileSpec() == symbol_fspec) {
42050b57cec5SDimitry Andric           // Provide feedback that the symfile has been successfully added.
42060b57cec5SDimitry Andric           const FileSpec &module_fs = module_sp->GetFileSpec();
42070b57cec5SDimitry Andric           result.AppendMessageWithFormat(
42080b57cec5SDimitry Andric               "symbol file '%s' has been added to '%s'\n", symfile_path,
42090b57cec5SDimitry Andric               module_fs.GetPath().c_str());
42100b57cec5SDimitry Andric 
42110b57cec5SDimitry Andric           // Let clients know something changed in the module if it is
42120b57cec5SDimitry Andric           // currently loaded
42130b57cec5SDimitry Andric           ModuleList module_list;
42140b57cec5SDimitry Andric           module_list.Append(module_sp);
42150b57cec5SDimitry Andric           target->SymbolsDidLoad(module_list);
42160b57cec5SDimitry Andric 
42170b57cec5SDimitry Andric           // Make sure we load any scripting resources that may be embedded
42180b57cec5SDimitry Andric           // in the debug info files in case the platform supports that.
42190b57cec5SDimitry Andric           Status error;
42200b57cec5SDimitry Andric           StreamString feedback_stream;
42210b57cec5SDimitry Andric           module_sp->LoadScriptingResourceInTarget(target, error,
4222*fe013be4SDimitry Andric                                                    feedback_stream);
42230b57cec5SDimitry Andric           if (error.Fail() && error.AsCString())
42240b57cec5SDimitry Andric             result.AppendWarningWithFormat(
42250b57cec5SDimitry Andric                 "unable to load scripting data for module %s - error "
42260b57cec5SDimitry Andric                 "reported was %s",
42270b57cec5SDimitry Andric                 module_sp->GetFileSpec()
42280b57cec5SDimitry Andric                     .GetFileNameStrippingExtension()
42290b57cec5SDimitry Andric                     .GetCString(),
42300b57cec5SDimitry Andric                 error.AsCString());
42310b57cec5SDimitry Andric           else if (feedback_stream.GetSize())
42325ffd83dbSDimitry Andric             result.AppendWarning(feedback_stream.GetData());
42330b57cec5SDimitry Andric 
42340b57cec5SDimitry Andric           flush = true;
42350b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishResult);
42360b57cec5SDimitry Andric           return true;
42370b57cec5SDimitry Andric         }
42380b57cec5SDimitry Andric       }
42390b57cec5SDimitry Andric       // Clear the symbol file spec if anything went wrong
42400b57cec5SDimitry Andric       module_sp->SetSymbolFileFileSpec(FileSpec());
42410b57cec5SDimitry Andric     }
42420b57cec5SDimitry Andric 
42430b57cec5SDimitry Andric     StreamString ss_symfile_uuid;
4244480093f4SDimitry Andric     if (module_spec.GetUUID().IsValid()) {
4245480093f4SDimitry Andric       ss_symfile_uuid << " (";
4246*fe013be4SDimitry Andric       module_spec.GetUUID().Dump(ss_symfile_uuid);
4247480093f4SDimitry Andric       ss_symfile_uuid << ')';
4248480093f4SDimitry Andric     }
42490b57cec5SDimitry Andric     result.AppendErrorWithFormat(
4250480093f4SDimitry Andric         "symbol file '%s'%s does not match any existing module%s\n",
42510b57cec5SDimitry Andric         symfile_path, ss_symfile_uuid.GetData(),
42525ffd83dbSDimitry Andric         !llvm::sys::fs::is_regular_file(symbol_fspec.GetPath())
42530b57cec5SDimitry Andric             ? "\n       please specify the full path to the symbol file"
42540b57cec5SDimitry Andric             : "");
42550b57cec5SDimitry Andric     return false;
42560b57cec5SDimitry Andric   }
42570b57cec5SDimitry Andric 
4258349cc55cSDimitry Andric   bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
4259349cc55cSDimitry Andric                                    CommandReturnObject &result, bool &flush) {
426081ad6265SDimitry Andric     Status error;
426181ad6265SDimitry Andric     if (Symbols::DownloadObjectAndSymbolFile(module_spec, error)) {
4262349cc55cSDimitry Andric       if (module_spec.GetSymbolFileSpec())
4263349cc55cSDimitry Andric         return AddModuleSymbols(m_exe_ctx.GetTargetPtr(), module_spec, flush,
4264349cc55cSDimitry Andric                                 result);
426581ad6265SDimitry Andric     } else {
426681ad6265SDimitry Andric       result.SetError(error);
4267349cc55cSDimitry Andric     }
4268349cc55cSDimitry Andric     return false;
4269349cc55cSDimitry Andric   }
4270349cc55cSDimitry Andric 
4271349cc55cSDimitry Andric   bool AddSymbolsForUUID(CommandReturnObject &result, bool &flush) {
4272349cc55cSDimitry Andric     assert(m_uuid_option_group.GetOptionValue().OptionWasSet());
4273349cc55cSDimitry Andric 
4274349cc55cSDimitry Andric     ModuleSpec module_spec;
4275349cc55cSDimitry Andric     module_spec.GetUUID() =
4276349cc55cSDimitry Andric         m_uuid_option_group.GetOptionValue().GetCurrentValue();
4277349cc55cSDimitry Andric 
4278349cc55cSDimitry Andric     if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) {
4279349cc55cSDimitry Andric       StreamString error_strm;
4280349cc55cSDimitry Andric       error_strm.PutCString("unable to find debug symbols for UUID ");
4281*fe013be4SDimitry Andric       module_spec.GetUUID().Dump(error_strm);
4282349cc55cSDimitry Andric       result.AppendError(error_strm.GetString());
4283349cc55cSDimitry Andric       return false;
4284349cc55cSDimitry Andric     }
4285349cc55cSDimitry Andric 
4286349cc55cSDimitry Andric     return true;
4287349cc55cSDimitry Andric   }
4288349cc55cSDimitry Andric 
4289349cc55cSDimitry Andric   bool AddSymbolsForFile(CommandReturnObject &result, bool &flush) {
4290349cc55cSDimitry Andric     assert(m_file_option.GetOptionValue().OptionWasSet());
4291349cc55cSDimitry Andric 
4292349cc55cSDimitry Andric     ModuleSpec module_spec;
4293349cc55cSDimitry Andric     module_spec.GetFileSpec() =
4294349cc55cSDimitry Andric         m_file_option.GetOptionValue().GetCurrentValue();
4295349cc55cSDimitry Andric 
4296349cc55cSDimitry Andric     Target *target = m_exe_ctx.GetTargetPtr();
4297349cc55cSDimitry Andric     ModuleSP module_sp(target->GetImages().FindFirstModule(module_spec));
4298349cc55cSDimitry Andric     if (module_sp) {
4299349cc55cSDimitry Andric       module_spec.GetFileSpec() = module_sp->GetFileSpec();
4300349cc55cSDimitry Andric       module_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec();
4301349cc55cSDimitry Andric       module_spec.GetUUID() = module_sp->GetUUID();
4302349cc55cSDimitry Andric       module_spec.GetArchitecture() = module_sp->GetArchitecture();
4303349cc55cSDimitry Andric     } else {
4304349cc55cSDimitry Andric       module_spec.GetArchitecture() = target->GetArchitecture();
4305349cc55cSDimitry Andric     }
4306349cc55cSDimitry Andric 
4307349cc55cSDimitry Andric     if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) {
4308349cc55cSDimitry Andric       StreamString error_strm;
4309349cc55cSDimitry Andric       error_strm.PutCString(
4310349cc55cSDimitry Andric           "unable to find debug symbols for the executable file ");
4311349cc55cSDimitry Andric       error_strm << module_spec.GetFileSpec();
4312349cc55cSDimitry Andric       result.AppendError(error_strm.GetString());
4313349cc55cSDimitry Andric       return false;
4314349cc55cSDimitry Andric     }
4315349cc55cSDimitry Andric 
4316349cc55cSDimitry Andric     return true;
4317349cc55cSDimitry Andric   }
4318349cc55cSDimitry Andric 
4319349cc55cSDimitry Andric   bool AddSymbolsForFrame(CommandReturnObject &result, bool &flush) {
4320349cc55cSDimitry Andric     assert(m_current_frame_option.GetOptionValue().OptionWasSet());
4321349cc55cSDimitry Andric 
4322349cc55cSDimitry Andric     Process *process = m_exe_ctx.GetProcessPtr();
4323349cc55cSDimitry Andric     if (!process) {
4324349cc55cSDimitry Andric       result.AppendError(
4325349cc55cSDimitry Andric           "a process must exist in order to use the --frame option");
4326349cc55cSDimitry Andric       return false;
4327349cc55cSDimitry Andric     }
4328349cc55cSDimitry Andric 
4329349cc55cSDimitry Andric     const StateType process_state = process->GetState();
4330349cc55cSDimitry Andric     if (!StateIsStoppedState(process_state, true)) {
4331349cc55cSDimitry Andric       result.AppendErrorWithFormat("process is not stopped: %s",
4332349cc55cSDimitry Andric                                    StateAsCString(process_state));
4333349cc55cSDimitry Andric       return false;
4334349cc55cSDimitry Andric     }
4335349cc55cSDimitry Andric 
4336349cc55cSDimitry Andric     StackFrame *frame = m_exe_ctx.GetFramePtr();
4337349cc55cSDimitry Andric     if (!frame) {
4338349cc55cSDimitry Andric       result.AppendError("invalid current frame");
4339349cc55cSDimitry Andric       return false;
4340349cc55cSDimitry Andric     }
4341349cc55cSDimitry Andric 
4342349cc55cSDimitry Andric     ModuleSP frame_module_sp(
4343349cc55cSDimitry Andric         frame->GetSymbolContext(eSymbolContextModule).module_sp);
4344349cc55cSDimitry Andric     if (!frame_module_sp) {
4345349cc55cSDimitry Andric       result.AppendError("frame has no module");
4346349cc55cSDimitry Andric       return false;
4347349cc55cSDimitry Andric     }
4348349cc55cSDimitry Andric 
4349349cc55cSDimitry Andric     ModuleSpec module_spec;
4350349cc55cSDimitry Andric     module_spec.GetUUID() = frame_module_sp->GetUUID();
4351349cc55cSDimitry Andric 
4352349cc55cSDimitry Andric     if (FileSystem::Instance().Exists(frame_module_sp->GetPlatformFileSpec())) {
4353349cc55cSDimitry Andric       module_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
4354349cc55cSDimitry Andric       module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
4355349cc55cSDimitry Andric     }
4356349cc55cSDimitry Andric 
4357349cc55cSDimitry Andric     if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) {
4358349cc55cSDimitry Andric       result.AppendError("unable to find debug symbols for the current frame");
4359349cc55cSDimitry Andric       return false;
4360349cc55cSDimitry Andric     }
4361349cc55cSDimitry Andric 
4362349cc55cSDimitry Andric     return true;
4363349cc55cSDimitry Andric   }
4364349cc55cSDimitry Andric 
4365349cc55cSDimitry Andric   bool AddSymbolsForStack(CommandReturnObject &result, bool &flush) {
4366349cc55cSDimitry Andric     assert(m_current_stack_option.GetOptionValue().OptionWasSet());
4367349cc55cSDimitry Andric 
4368349cc55cSDimitry Andric     Process *process = m_exe_ctx.GetProcessPtr();
4369349cc55cSDimitry Andric     if (!process) {
4370349cc55cSDimitry Andric       result.AppendError(
4371349cc55cSDimitry Andric           "a process must exist in order to use the --stack option");
4372349cc55cSDimitry Andric       return false;
4373349cc55cSDimitry Andric     }
4374349cc55cSDimitry Andric 
4375349cc55cSDimitry Andric     const StateType process_state = process->GetState();
4376349cc55cSDimitry Andric     if (!StateIsStoppedState(process_state, true)) {
4377349cc55cSDimitry Andric       result.AppendErrorWithFormat("process is not stopped: %s",
4378349cc55cSDimitry Andric                                    StateAsCString(process_state));
4379349cc55cSDimitry Andric       return false;
4380349cc55cSDimitry Andric     }
4381349cc55cSDimitry Andric 
4382349cc55cSDimitry Andric     Thread *thread = m_exe_ctx.GetThreadPtr();
4383349cc55cSDimitry Andric     if (!thread) {
4384349cc55cSDimitry Andric       result.AppendError("invalid current thread");
4385349cc55cSDimitry Andric       return false;
4386349cc55cSDimitry Andric     }
4387349cc55cSDimitry Andric 
4388349cc55cSDimitry Andric     bool symbols_found = false;
4389349cc55cSDimitry Andric     uint32_t frame_count = thread->GetStackFrameCount();
4390349cc55cSDimitry Andric     for (uint32_t i = 0; i < frame_count; ++i) {
4391349cc55cSDimitry Andric       lldb::StackFrameSP frame_sp = thread->GetStackFrameAtIndex(i);
4392349cc55cSDimitry Andric 
4393349cc55cSDimitry Andric       ModuleSP frame_module_sp(
4394349cc55cSDimitry Andric           frame_sp->GetSymbolContext(eSymbolContextModule).module_sp);
4395349cc55cSDimitry Andric       if (!frame_module_sp)
4396349cc55cSDimitry Andric         continue;
4397349cc55cSDimitry Andric 
4398349cc55cSDimitry Andric       ModuleSpec module_spec;
4399349cc55cSDimitry Andric       module_spec.GetUUID() = frame_module_sp->GetUUID();
4400349cc55cSDimitry Andric 
4401349cc55cSDimitry Andric       if (FileSystem::Instance().Exists(
4402349cc55cSDimitry Andric               frame_module_sp->GetPlatformFileSpec())) {
4403349cc55cSDimitry Andric         module_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
4404349cc55cSDimitry Andric         module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
4405349cc55cSDimitry Andric       }
4406349cc55cSDimitry Andric 
4407349cc55cSDimitry Andric       bool current_frame_flush = false;
4408349cc55cSDimitry Andric       if (DownloadObjectAndSymbolFile(module_spec, result, current_frame_flush))
4409349cc55cSDimitry Andric         symbols_found = true;
4410349cc55cSDimitry Andric       flush |= current_frame_flush;
4411349cc55cSDimitry Andric     }
4412349cc55cSDimitry Andric 
4413349cc55cSDimitry Andric     if (!symbols_found) {
4414349cc55cSDimitry Andric       result.AppendError(
4415349cc55cSDimitry Andric           "unable to find debug symbols in the current call stack");
4416349cc55cSDimitry Andric       return false;
4417349cc55cSDimitry Andric     }
4418349cc55cSDimitry Andric 
4419349cc55cSDimitry Andric     return true;
4420349cc55cSDimitry Andric   }
4421349cc55cSDimitry Andric 
44220b57cec5SDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
44230b57cec5SDimitry Andric     Target *target = m_exe_ctx.GetTargetPtr();
44240b57cec5SDimitry Andric     result.SetStatus(eReturnStatusFailed);
44250b57cec5SDimitry Andric     bool flush = false;
44260b57cec5SDimitry Andric     ModuleSpec module_spec;
44270b57cec5SDimitry Andric     const bool uuid_option_set =
44280b57cec5SDimitry Andric         m_uuid_option_group.GetOptionValue().OptionWasSet();
44290b57cec5SDimitry Andric     const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
44300b57cec5SDimitry Andric     const bool frame_option_set =
44310b57cec5SDimitry Andric         m_current_frame_option.GetOptionValue().OptionWasSet();
4432349cc55cSDimitry Andric     const bool stack_option_set =
4433349cc55cSDimitry Andric         m_current_stack_option.GetOptionValue().OptionWasSet();
44340b57cec5SDimitry Andric     const size_t argc = args.GetArgumentCount();
44350b57cec5SDimitry Andric 
44360b57cec5SDimitry Andric     if (argc == 0) {
4437349cc55cSDimitry Andric       if (uuid_option_set)
4438349cc55cSDimitry Andric         AddSymbolsForUUID(result, flush);
4439349cc55cSDimitry Andric       else if (file_option_set)
4440349cc55cSDimitry Andric         AddSymbolsForFile(result, flush);
4441349cc55cSDimitry Andric       else if (frame_option_set)
4442349cc55cSDimitry Andric         AddSymbolsForFrame(result, flush);
4443349cc55cSDimitry Andric       else if (stack_option_set)
4444349cc55cSDimitry Andric         AddSymbolsForStack(result, flush);
4445349cc55cSDimitry Andric       else
44460b57cec5SDimitry Andric         result.AppendError("one or more symbol file paths must be specified, "
44470b57cec5SDimitry Andric                            "or options must be specified");
44480b57cec5SDimitry Andric     } else {
44490b57cec5SDimitry Andric       if (uuid_option_set) {
44500b57cec5SDimitry Andric         result.AppendError("specify either one or more paths to symbol files "
44510b57cec5SDimitry Andric                            "or use the --uuid option without arguments");
44520b57cec5SDimitry Andric       } else if (frame_option_set) {
44530b57cec5SDimitry Andric         result.AppendError("specify either one or more paths to symbol files "
44540b57cec5SDimitry Andric                            "or use the --frame option without arguments");
44550b57cec5SDimitry Andric       } else if (file_option_set && argc > 1) {
44560b57cec5SDimitry Andric         result.AppendError("specify at most one symbol file path when "
44570b57cec5SDimitry Andric                            "--shlib option is set");
44580b57cec5SDimitry Andric       } else {
44590b57cec5SDimitry Andric         PlatformSP platform_sp(target->GetPlatform());
44600b57cec5SDimitry Andric 
44610b57cec5SDimitry Andric         for (auto &entry : args.entries()) {
44629dba64beSDimitry Andric           if (!entry.ref().empty()) {
44630b57cec5SDimitry Andric             auto &symbol_file_spec = module_spec.GetSymbolFileSpec();
44649dba64beSDimitry Andric             symbol_file_spec.SetFile(entry.ref(), FileSpec::Style::native);
44650b57cec5SDimitry Andric             FileSystem::Instance().Resolve(symbol_file_spec);
44660b57cec5SDimitry Andric             if (file_option_set) {
44670b57cec5SDimitry Andric               module_spec.GetFileSpec() =
44680b57cec5SDimitry Andric                   m_file_option.GetOptionValue().GetCurrentValue();
44690b57cec5SDimitry Andric             }
44700b57cec5SDimitry Andric             if (platform_sp) {
44710b57cec5SDimitry Andric               FileSpec symfile_spec;
44720b57cec5SDimitry Andric               if (platform_sp
44730b57cec5SDimitry Andric                       ->ResolveSymbolFile(*target, module_spec, symfile_spec)
44740b57cec5SDimitry Andric                       .Success())
44750b57cec5SDimitry Andric                 module_spec.GetSymbolFileSpec() = symfile_spec;
44760b57cec5SDimitry Andric             }
44770b57cec5SDimitry Andric 
44780b57cec5SDimitry Andric             bool symfile_exists =
44790b57cec5SDimitry Andric                 FileSystem::Instance().Exists(module_spec.GetSymbolFileSpec());
44800b57cec5SDimitry Andric 
44810b57cec5SDimitry Andric             if (symfile_exists) {
44820b57cec5SDimitry Andric               if (!AddModuleSymbols(target, module_spec, flush, result))
44830b57cec5SDimitry Andric                 break;
44840b57cec5SDimitry Andric             } else {
44850b57cec5SDimitry Andric               std::string resolved_symfile_path =
44860b57cec5SDimitry Andric                   module_spec.GetSymbolFileSpec().GetPath();
44879dba64beSDimitry Andric               if (resolved_symfile_path != entry.ref()) {
44880b57cec5SDimitry Andric                 result.AppendErrorWithFormat(
44890b57cec5SDimitry Andric                     "invalid module path '%s' with resolved path '%s'\n",
44900b57cec5SDimitry Andric                     entry.c_str(), resolved_symfile_path.c_str());
44910b57cec5SDimitry Andric                 break;
44920b57cec5SDimitry Andric               }
44930b57cec5SDimitry Andric               result.AppendErrorWithFormat("invalid module path '%s'\n",
44940b57cec5SDimitry Andric                                            entry.c_str());
44950b57cec5SDimitry Andric               break;
44960b57cec5SDimitry Andric             }
44970b57cec5SDimitry Andric           }
44980b57cec5SDimitry Andric         }
44990b57cec5SDimitry Andric       }
45000b57cec5SDimitry Andric     }
45010b57cec5SDimitry Andric 
45020b57cec5SDimitry Andric     if (flush) {
45030b57cec5SDimitry Andric       Process *process = m_exe_ctx.GetProcessPtr();
45040b57cec5SDimitry Andric       if (process)
45050b57cec5SDimitry Andric         process->Flush();
45060b57cec5SDimitry Andric     }
45070b57cec5SDimitry Andric     return result.Succeeded();
45080b57cec5SDimitry Andric   }
45090b57cec5SDimitry Andric 
45100b57cec5SDimitry Andric   OptionGroupOptions m_option_group;
45110b57cec5SDimitry Andric   OptionGroupUUID m_uuid_option_group;
45120b57cec5SDimitry Andric   OptionGroupFile m_file_option;
45130b57cec5SDimitry Andric   OptionGroupBoolean m_current_frame_option;
4514349cc55cSDimitry Andric   OptionGroupBoolean m_current_stack_option;
45150b57cec5SDimitry Andric };
45160b57cec5SDimitry Andric 
45170b57cec5SDimitry Andric #pragma mark CommandObjectTargetSymbols
45180b57cec5SDimitry Andric 
45190b57cec5SDimitry Andric // CommandObjectTargetSymbols
45200b57cec5SDimitry Andric 
45210b57cec5SDimitry Andric class CommandObjectTargetSymbols : public CommandObjectMultiword {
45220b57cec5SDimitry Andric public:
45230b57cec5SDimitry Andric   // Constructors and Destructors
45240b57cec5SDimitry Andric   CommandObjectTargetSymbols(CommandInterpreter &interpreter)
45250b57cec5SDimitry Andric       : CommandObjectMultiword(
45260b57cec5SDimitry Andric             interpreter, "target symbols",
45270b57cec5SDimitry Andric             "Commands for adding and managing debug symbol files.",
45280b57cec5SDimitry Andric             "target symbols <sub-command> ...") {
45290b57cec5SDimitry Andric     LoadSubCommand(
45300b57cec5SDimitry Andric         "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter)));
45310b57cec5SDimitry Andric   }
45320b57cec5SDimitry Andric 
45330b57cec5SDimitry Andric   ~CommandObjectTargetSymbols() override = default;
45340b57cec5SDimitry Andric 
45350b57cec5SDimitry Andric private:
45360b57cec5SDimitry Andric   // For CommandObjectTargetModules only
45375ffd83dbSDimitry Andric   CommandObjectTargetSymbols(const CommandObjectTargetSymbols &) = delete;
45385ffd83dbSDimitry Andric   const CommandObjectTargetSymbols &
45395ffd83dbSDimitry Andric   operator=(const CommandObjectTargetSymbols &) = delete;
45400b57cec5SDimitry Andric };
45410b57cec5SDimitry Andric 
45420b57cec5SDimitry Andric #pragma mark CommandObjectTargetStopHookAdd
45430b57cec5SDimitry Andric 
45440b57cec5SDimitry Andric // CommandObjectTargetStopHookAdd
45459dba64beSDimitry Andric #define LLDB_OPTIONS_target_stop_hook_add
45469dba64beSDimitry Andric #include "CommandOptions.inc"
45470b57cec5SDimitry Andric 
45480b57cec5SDimitry Andric class CommandObjectTargetStopHookAdd : public CommandObjectParsed,
45490b57cec5SDimitry Andric                                        public IOHandlerDelegateMultiline {
45500b57cec5SDimitry Andric public:
4551e8d8bef9SDimitry Andric   class CommandOptions : public OptionGroup {
45520b57cec5SDimitry Andric   public:
455304eeddc0SDimitry Andric     CommandOptions() : m_line_end(UINT_MAX) {}
45540b57cec5SDimitry Andric 
45550b57cec5SDimitry Andric     ~CommandOptions() override = default;
45560b57cec5SDimitry Andric 
45570b57cec5SDimitry Andric     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
4558bdd1243dSDimitry Andric       return llvm::ArrayRef(g_target_stop_hook_add_options);
45590b57cec5SDimitry Andric     }
45600b57cec5SDimitry Andric 
45610b57cec5SDimitry Andric     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
45620b57cec5SDimitry Andric                           ExecutionContext *execution_context) override {
45630b57cec5SDimitry Andric       Status error;
4564e8d8bef9SDimitry Andric       const int short_option =
4565e8d8bef9SDimitry Andric           g_target_stop_hook_add_options[option_idx].short_option;
45660b57cec5SDimitry Andric 
45670b57cec5SDimitry Andric       switch (short_option) {
45680b57cec5SDimitry Andric       case 'c':
45695ffd83dbSDimitry Andric         m_class_name = std::string(option_arg);
45700b57cec5SDimitry Andric         m_sym_ctx_specified = true;
45710b57cec5SDimitry Andric         break;
45720b57cec5SDimitry Andric 
45730b57cec5SDimitry Andric       case 'e':
45740b57cec5SDimitry Andric         if (option_arg.getAsInteger(0, m_line_end)) {
45750b57cec5SDimitry Andric           error.SetErrorStringWithFormat("invalid end line number: \"%s\"",
45760b57cec5SDimitry Andric                                          option_arg.str().c_str());
45770b57cec5SDimitry Andric           break;
45780b57cec5SDimitry Andric         }
45790b57cec5SDimitry Andric         m_sym_ctx_specified = true;
45800b57cec5SDimitry Andric         break;
45810b57cec5SDimitry Andric 
45820b57cec5SDimitry Andric       case 'G': {
45830b57cec5SDimitry Andric         bool value, success;
45840b57cec5SDimitry Andric         value = OptionArgParser::ToBoolean(option_arg, false, &success);
45850b57cec5SDimitry Andric         if (success) {
45860b57cec5SDimitry Andric           m_auto_continue = value;
45870b57cec5SDimitry Andric         } else
45880b57cec5SDimitry Andric           error.SetErrorStringWithFormat(
45890b57cec5SDimitry Andric               "invalid boolean value '%s' passed for -G option",
45900b57cec5SDimitry Andric               option_arg.str().c_str());
4591480093f4SDimitry Andric       } break;
45920b57cec5SDimitry Andric       case 'l':
45930b57cec5SDimitry Andric         if (option_arg.getAsInteger(0, m_line_start)) {
45940b57cec5SDimitry Andric           error.SetErrorStringWithFormat("invalid start line number: \"%s\"",
45950b57cec5SDimitry Andric                                          option_arg.str().c_str());
45960b57cec5SDimitry Andric           break;
45970b57cec5SDimitry Andric         }
45980b57cec5SDimitry Andric         m_sym_ctx_specified = true;
45990b57cec5SDimitry Andric         break;
46000b57cec5SDimitry Andric 
46010b57cec5SDimitry Andric       case 'i':
46020b57cec5SDimitry Andric         m_no_inlines = true;
46030b57cec5SDimitry Andric         break;
46040b57cec5SDimitry Andric 
46050b57cec5SDimitry Andric       case 'n':
46065ffd83dbSDimitry Andric         m_function_name = std::string(option_arg);
46070b57cec5SDimitry Andric         m_func_name_type_mask |= eFunctionNameTypeAuto;
46080b57cec5SDimitry Andric         m_sym_ctx_specified = true;
46090b57cec5SDimitry Andric         break;
46100b57cec5SDimitry Andric 
46110b57cec5SDimitry Andric       case 'f':
46125ffd83dbSDimitry Andric         m_file_name = std::string(option_arg);
46130b57cec5SDimitry Andric         m_sym_ctx_specified = true;
46140b57cec5SDimitry Andric         break;
46150b57cec5SDimitry Andric 
46160b57cec5SDimitry Andric       case 's':
46175ffd83dbSDimitry Andric         m_module_name = std::string(option_arg);
46180b57cec5SDimitry Andric         m_sym_ctx_specified = true;
46190b57cec5SDimitry Andric         break;
46200b57cec5SDimitry Andric 
46210b57cec5SDimitry Andric       case 't':
46220b57cec5SDimitry Andric         if (option_arg.getAsInteger(0, m_thread_id))
46230b57cec5SDimitry Andric           error.SetErrorStringWithFormat("invalid thread id string '%s'",
46240b57cec5SDimitry Andric                                          option_arg.str().c_str());
46250b57cec5SDimitry Andric         m_thread_specified = true;
46260b57cec5SDimitry Andric         break;
46270b57cec5SDimitry Andric 
46280b57cec5SDimitry Andric       case 'T':
46295ffd83dbSDimitry Andric         m_thread_name = std::string(option_arg);
46300b57cec5SDimitry Andric         m_thread_specified = true;
46310b57cec5SDimitry Andric         break;
46320b57cec5SDimitry Andric 
46330b57cec5SDimitry Andric       case 'q':
46345ffd83dbSDimitry Andric         m_queue_name = std::string(option_arg);
46350b57cec5SDimitry Andric         m_thread_specified = true;
46360b57cec5SDimitry Andric         break;
46370b57cec5SDimitry Andric 
46380b57cec5SDimitry Andric       case 'x':
46390b57cec5SDimitry Andric         if (option_arg.getAsInteger(0, m_thread_index))
46400b57cec5SDimitry Andric           error.SetErrorStringWithFormat("invalid thread index string '%s'",
46410b57cec5SDimitry Andric                                          option_arg.str().c_str());
46420b57cec5SDimitry Andric         m_thread_specified = true;
46430b57cec5SDimitry Andric         break;
46440b57cec5SDimitry Andric 
46450b57cec5SDimitry Andric       case 'o':
46460b57cec5SDimitry Andric         m_use_one_liner = true;
46475ffd83dbSDimitry Andric         m_one_liner.push_back(std::string(option_arg));
46480b57cec5SDimitry Andric         break;
46490b57cec5SDimitry Andric 
46500b57cec5SDimitry Andric       default:
46519dba64beSDimitry Andric         llvm_unreachable("Unimplemented option");
46520b57cec5SDimitry Andric       }
46530b57cec5SDimitry Andric       return error;
46540b57cec5SDimitry Andric     }
46550b57cec5SDimitry Andric 
46560b57cec5SDimitry Andric     void OptionParsingStarting(ExecutionContext *execution_context) override {
46570b57cec5SDimitry Andric       m_class_name.clear();
46580b57cec5SDimitry Andric       m_function_name.clear();
46590b57cec5SDimitry Andric       m_line_start = 0;
4660fcaf7f86SDimitry Andric       m_line_end = LLDB_INVALID_LINE_NUMBER;
46610b57cec5SDimitry Andric       m_file_name.clear();
46620b57cec5SDimitry Andric       m_module_name.clear();
46630b57cec5SDimitry Andric       m_func_name_type_mask = eFunctionNameTypeAuto;
46640b57cec5SDimitry Andric       m_thread_id = LLDB_INVALID_THREAD_ID;
46650b57cec5SDimitry Andric       m_thread_index = UINT32_MAX;
46660b57cec5SDimitry Andric       m_thread_name.clear();
46670b57cec5SDimitry Andric       m_queue_name.clear();
46680b57cec5SDimitry Andric 
46690b57cec5SDimitry Andric       m_no_inlines = false;
46700b57cec5SDimitry Andric       m_sym_ctx_specified = false;
46710b57cec5SDimitry Andric       m_thread_specified = false;
46720b57cec5SDimitry Andric 
46730b57cec5SDimitry Andric       m_use_one_liner = false;
46740b57cec5SDimitry Andric       m_one_liner.clear();
46750b57cec5SDimitry Andric       m_auto_continue = false;
46760b57cec5SDimitry Andric     }
46770b57cec5SDimitry Andric 
46780b57cec5SDimitry Andric     std::string m_class_name;
46790b57cec5SDimitry Andric     std::string m_function_name;
4680fe6060f1SDimitry Andric     uint32_t m_line_start = 0;
4681fcaf7f86SDimitry Andric     uint32_t m_line_end = LLDB_INVALID_LINE_NUMBER;
46820b57cec5SDimitry Andric     std::string m_file_name;
46830b57cec5SDimitry Andric     std::string m_module_name;
4684fe6060f1SDimitry Andric     uint32_t m_func_name_type_mask =
4685fe6060f1SDimitry Andric         eFunctionNameTypeAuto; // A pick from lldb::FunctionNameType.
4686fcaf7f86SDimitry Andric     lldb::tid_t m_thread_id = LLDB_INVALID_THREAD_ID;
4687fcaf7f86SDimitry Andric     uint32_t m_thread_index = UINT32_MAX;
46880b57cec5SDimitry Andric     std::string m_thread_name;
46890b57cec5SDimitry Andric     std::string m_queue_name;
4690fe6060f1SDimitry Andric     bool m_sym_ctx_specified = false;
4691fcaf7f86SDimitry Andric     bool m_no_inlines = false;
4692fe6060f1SDimitry Andric     bool m_thread_specified = false;
46930b57cec5SDimitry Andric     // Instance variables to hold the values for one_liner options.
4694fe6060f1SDimitry Andric     bool m_use_one_liner = false;
46950b57cec5SDimitry Andric     std::vector<std::string> m_one_liner;
4696e8d8bef9SDimitry Andric 
4697fcaf7f86SDimitry Andric     bool m_auto_continue = false;
46980b57cec5SDimitry Andric   };
46990b57cec5SDimitry Andric 
47000b57cec5SDimitry Andric   CommandObjectTargetStopHookAdd(CommandInterpreter &interpreter)
47010b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "target stop-hook add",
4702e8d8bef9SDimitry Andric                             "Add a hook to be executed when the target stops."
4703e8d8bef9SDimitry Andric                             "The hook can either be a list of commands or an "
4704e8d8bef9SDimitry Andric                             "appropriately defined Python class.  You can also "
4705e8d8bef9SDimitry Andric                             "add filters so the hook only runs a certain stop "
4706e8d8bef9SDimitry Andric                             "points.",
47070b57cec5SDimitry Andric                             "target stop-hook add"),
47080b57cec5SDimitry Andric         IOHandlerDelegateMultiline("DONE",
47090b57cec5SDimitry Andric                                    IOHandlerDelegate::Completion::LLDBCommand),
471004eeddc0SDimitry Andric         m_python_class_options("scripted stop-hook", true, 'P') {
4711e8d8bef9SDimitry Andric     SetHelpLong(
4712e8d8bef9SDimitry Andric         R"(
4713e8d8bef9SDimitry Andric Command Based stop-hooks:
4714e8d8bef9SDimitry Andric -------------------------
4715e8d8bef9SDimitry Andric   Stop hooks can run a list of lldb commands by providing one or more
4716e8d8bef9SDimitry Andric   --one-line-command options.  The commands will get run in the order they are
4717e8d8bef9SDimitry Andric   added.  Or you can provide no commands, in which case you will enter a
4718e8d8bef9SDimitry Andric   command editor where you can enter the commands to be run.
4719e8d8bef9SDimitry Andric 
4720e8d8bef9SDimitry Andric Python Based Stop Hooks:
4721e8d8bef9SDimitry Andric ------------------------
4722e8d8bef9SDimitry Andric   Stop hooks can be implemented with a suitably defined Python class, whose name
4723e8d8bef9SDimitry Andric   is passed in the --python-class option.
4724e8d8bef9SDimitry Andric 
4725e8d8bef9SDimitry Andric   When the stop hook is added, the class is initialized by calling:
4726e8d8bef9SDimitry Andric 
4727fe6060f1SDimitry Andric     def __init__(self, target, extra_args, internal_dict):
4728e8d8bef9SDimitry Andric 
4729e8d8bef9SDimitry Andric     target: The target that the stop hook is being added to.
4730e8d8bef9SDimitry Andric     extra_args: An SBStructuredData Dictionary filled with the -key -value
4731e8d8bef9SDimitry Andric                 option pairs passed to the command.
4732e8d8bef9SDimitry Andric     dict: An implementation detail provided by lldb.
4733e8d8bef9SDimitry Andric 
4734e8d8bef9SDimitry Andric   Then when the stop-hook triggers, lldb will run the 'handle_stop' method.
4735e8d8bef9SDimitry Andric   The method has the signature:
4736e8d8bef9SDimitry Andric 
4737e8d8bef9SDimitry Andric     def handle_stop(self, exe_ctx, stream):
4738e8d8bef9SDimitry Andric 
4739e8d8bef9SDimitry Andric     exe_ctx: An SBExecutionContext for the thread that has stopped.
4740e8d8bef9SDimitry Andric     stream: An SBStream, anything written to this stream will be printed in the
4741e8d8bef9SDimitry Andric             the stop message when the process stops.
4742e8d8bef9SDimitry Andric 
4743e8d8bef9SDimitry Andric     Return Value: The method returns "should_stop".  If should_stop is false
4744e8d8bef9SDimitry Andric                   from all the stop hook executions on threads that stopped
4745e8d8bef9SDimitry Andric                   with a reason, then the process will continue.  Note that this
4746e8d8bef9SDimitry Andric                   will happen only after all the stop hooks are run.
4747e8d8bef9SDimitry Andric 
4748e8d8bef9SDimitry Andric Filter Options:
4749e8d8bef9SDimitry Andric ---------------
4750e8d8bef9SDimitry Andric   Stop hooks can be set to always run, or to only run when the stopped thread
4751e8d8bef9SDimitry Andric   matches the filter options passed on the command line.  The available filter
4752e8d8bef9SDimitry Andric   options include a shared library or a thread or queue specification,
4753e8d8bef9SDimitry Andric   a line range in a source file, a function name or a class name.
4754e8d8bef9SDimitry Andric             )");
4755e8d8bef9SDimitry Andric     m_all_options.Append(&m_python_class_options,
4756e8d8bef9SDimitry Andric                          LLDB_OPT_SET_1 | LLDB_OPT_SET_2,
4757e8d8bef9SDimitry Andric                          LLDB_OPT_SET_FROM_TO(4, 6));
4758e8d8bef9SDimitry Andric     m_all_options.Append(&m_options);
4759e8d8bef9SDimitry Andric     m_all_options.Finalize();
4760e8d8bef9SDimitry Andric   }
47610b57cec5SDimitry Andric 
47620b57cec5SDimitry Andric   ~CommandObjectTargetStopHookAdd() override = default;
47630b57cec5SDimitry Andric 
4764e8d8bef9SDimitry Andric   Options *GetOptions() override { return &m_all_options; }
47650b57cec5SDimitry Andric 
47660b57cec5SDimitry Andric protected:
47670b57cec5SDimitry Andric   void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
47689dba64beSDimitry Andric     StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
47690b57cec5SDimitry Andric     if (output_sp && interactive) {
47700b57cec5SDimitry Andric       output_sp->PutCString(
47710b57cec5SDimitry Andric           "Enter your stop hook command(s).  Type 'DONE' to end.\n");
47720b57cec5SDimitry Andric       output_sp->Flush();
47730b57cec5SDimitry Andric     }
47740b57cec5SDimitry Andric   }
47750b57cec5SDimitry Andric 
47760b57cec5SDimitry Andric   void IOHandlerInputComplete(IOHandler &io_handler,
47770b57cec5SDimitry Andric                               std::string &line) override {
47780b57cec5SDimitry Andric     if (m_stop_hook_sp) {
47790b57cec5SDimitry Andric       if (line.empty()) {
47809dba64beSDimitry Andric         StreamFileSP error_sp(io_handler.GetErrorStreamFileSP());
47810b57cec5SDimitry Andric         if (error_sp) {
47820b57cec5SDimitry Andric           error_sp->Printf("error: stop hook #%" PRIu64
47830b57cec5SDimitry Andric                            " aborted, no commands.\n",
47840b57cec5SDimitry Andric                            m_stop_hook_sp->GetID());
47850b57cec5SDimitry Andric           error_sp->Flush();
47860b57cec5SDimitry Andric         }
47870b57cec5SDimitry Andric         Target *target = GetDebugger().GetSelectedTarget().get();
4788e8d8bef9SDimitry Andric         if (target) {
4789e8d8bef9SDimitry Andric           target->UndoCreateStopHook(m_stop_hook_sp->GetID());
4790e8d8bef9SDimitry Andric         }
47910b57cec5SDimitry Andric       } else {
4792e8d8bef9SDimitry Andric         // The IOHandler editor is only for command lines stop hooks:
4793e8d8bef9SDimitry Andric         Target::StopHookCommandLine *hook_ptr =
4794e8d8bef9SDimitry Andric             static_cast<Target::StopHookCommandLine *>(m_stop_hook_sp.get());
4795e8d8bef9SDimitry Andric 
4796e8d8bef9SDimitry Andric         hook_ptr->SetActionFromString(line);
47979dba64beSDimitry Andric         StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
47980b57cec5SDimitry Andric         if (output_sp) {
47990b57cec5SDimitry Andric           output_sp->Printf("Stop hook #%" PRIu64 " added.\n",
48000b57cec5SDimitry Andric                             m_stop_hook_sp->GetID());
48010b57cec5SDimitry Andric           output_sp->Flush();
48020b57cec5SDimitry Andric         }
48030b57cec5SDimitry Andric       }
48040b57cec5SDimitry Andric       m_stop_hook_sp.reset();
48050b57cec5SDimitry Andric     }
48060b57cec5SDimitry Andric     io_handler.SetIsDone(true);
48070b57cec5SDimitry Andric   }
48080b57cec5SDimitry Andric 
48090b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
48100b57cec5SDimitry Andric     m_stop_hook_sp.reset();
48110b57cec5SDimitry Andric 
48129dba64beSDimitry Andric     Target &target = GetSelectedOrDummyTarget();
4813e8d8bef9SDimitry Andric     Target::StopHookSP new_hook_sp =
4814e8d8bef9SDimitry Andric         target.CreateStopHook(m_python_class_options.GetName().empty() ?
4815e8d8bef9SDimitry Andric                                Target::StopHook::StopHookKind::CommandBased
4816e8d8bef9SDimitry Andric                                : Target::StopHook::StopHookKind::ScriptBased);
48170b57cec5SDimitry Andric 
48180b57cec5SDimitry Andric     //  First step, make the specifier.
48190b57cec5SDimitry Andric     std::unique_ptr<SymbolContextSpecifier> specifier_up;
48200b57cec5SDimitry Andric     if (m_options.m_sym_ctx_specified) {
48215ffd83dbSDimitry Andric       specifier_up = std::make_unique<SymbolContextSpecifier>(
48225ffd83dbSDimitry Andric           GetDebugger().GetSelectedTarget());
48230b57cec5SDimitry Andric 
48240b57cec5SDimitry Andric       if (!m_options.m_module_name.empty()) {
48250b57cec5SDimitry Andric         specifier_up->AddSpecification(
48260b57cec5SDimitry Andric             m_options.m_module_name.c_str(),
48270b57cec5SDimitry Andric             SymbolContextSpecifier::eModuleSpecified);
48280b57cec5SDimitry Andric       }
48290b57cec5SDimitry Andric 
48300b57cec5SDimitry Andric       if (!m_options.m_class_name.empty()) {
48310b57cec5SDimitry Andric         specifier_up->AddSpecification(
48320b57cec5SDimitry Andric             m_options.m_class_name.c_str(),
48330b57cec5SDimitry Andric             SymbolContextSpecifier::eClassOrNamespaceSpecified);
48340b57cec5SDimitry Andric       }
48350b57cec5SDimitry Andric 
48360b57cec5SDimitry Andric       if (!m_options.m_file_name.empty()) {
48379dba64beSDimitry Andric         specifier_up->AddSpecification(m_options.m_file_name.c_str(),
48380b57cec5SDimitry Andric                                        SymbolContextSpecifier::eFileSpecified);
48390b57cec5SDimitry Andric       }
48400b57cec5SDimitry Andric 
48410b57cec5SDimitry Andric       if (m_options.m_line_start != 0) {
48420b57cec5SDimitry Andric         specifier_up->AddLineSpecification(
48430b57cec5SDimitry Andric             m_options.m_line_start,
48440b57cec5SDimitry Andric             SymbolContextSpecifier::eLineStartSpecified);
48450b57cec5SDimitry Andric       }
48460b57cec5SDimitry Andric 
48470b57cec5SDimitry Andric       if (m_options.m_line_end != UINT_MAX) {
48480b57cec5SDimitry Andric         specifier_up->AddLineSpecification(
48490b57cec5SDimitry Andric             m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
48500b57cec5SDimitry Andric       }
48510b57cec5SDimitry Andric 
48520b57cec5SDimitry Andric       if (!m_options.m_function_name.empty()) {
48530b57cec5SDimitry Andric         specifier_up->AddSpecification(
48540b57cec5SDimitry Andric             m_options.m_function_name.c_str(),
48550b57cec5SDimitry Andric             SymbolContextSpecifier::eFunctionSpecified);
48560b57cec5SDimitry Andric       }
48570b57cec5SDimitry Andric     }
48580b57cec5SDimitry Andric 
48590b57cec5SDimitry Andric     if (specifier_up)
48600b57cec5SDimitry Andric       new_hook_sp->SetSpecifier(specifier_up.release());
48610b57cec5SDimitry Andric 
48620b57cec5SDimitry Andric     // Next see if any of the thread options have been entered:
48630b57cec5SDimitry Andric 
48640b57cec5SDimitry Andric     if (m_options.m_thread_specified) {
48650b57cec5SDimitry Andric       ThreadSpec *thread_spec = new ThreadSpec();
48660b57cec5SDimitry Andric 
48670b57cec5SDimitry Andric       if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) {
48680b57cec5SDimitry Andric         thread_spec->SetTID(m_options.m_thread_id);
48690b57cec5SDimitry Andric       }
48700b57cec5SDimitry Andric 
48710b57cec5SDimitry Andric       if (m_options.m_thread_index != UINT32_MAX)
48720b57cec5SDimitry Andric         thread_spec->SetIndex(m_options.m_thread_index);
48730b57cec5SDimitry Andric 
48740b57cec5SDimitry Andric       if (!m_options.m_thread_name.empty())
48750b57cec5SDimitry Andric         thread_spec->SetName(m_options.m_thread_name.c_str());
48760b57cec5SDimitry Andric 
48770b57cec5SDimitry Andric       if (!m_options.m_queue_name.empty())
48780b57cec5SDimitry Andric         thread_spec->SetQueueName(m_options.m_queue_name.c_str());
48790b57cec5SDimitry Andric 
48800b57cec5SDimitry Andric       new_hook_sp->SetThreadSpecifier(thread_spec);
48810b57cec5SDimitry Andric     }
48820b57cec5SDimitry Andric 
48830b57cec5SDimitry Andric     new_hook_sp->SetAutoContinue(m_options.m_auto_continue);
48840b57cec5SDimitry Andric     if (m_options.m_use_one_liner) {
4885e8d8bef9SDimitry Andric       // This is a command line stop hook:
4886e8d8bef9SDimitry Andric       Target::StopHookCommandLine *hook_ptr =
4887e8d8bef9SDimitry Andric           static_cast<Target::StopHookCommandLine *>(new_hook_sp.get());
4888e8d8bef9SDimitry Andric       hook_ptr->SetActionFromStrings(m_options.m_one_liner);
48890b57cec5SDimitry Andric       result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
48900b57cec5SDimitry Andric                                      new_hook_sp->GetID());
4891e8d8bef9SDimitry Andric     } else if (!m_python_class_options.GetName().empty()) {
4892e8d8bef9SDimitry Andric       // This is a scripted stop hook:
4893e8d8bef9SDimitry Andric       Target::StopHookScripted *hook_ptr =
4894e8d8bef9SDimitry Andric           static_cast<Target::StopHookScripted *>(new_hook_sp.get());
4895e8d8bef9SDimitry Andric       Status error = hook_ptr->SetScriptCallback(
4896e8d8bef9SDimitry Andric           m_python_class_options.GetName(),
4897e8d8bef9SDimitry Andric           m_python_class_options.GetStructuredData());
4898e8d8bef9SDimitry Andric       if (error.Success())
4899e8d8bef9SDimitry Andric         result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
4900e8d8bef9SDimitry Andric                                        new_hook_sp->GetID());
4901e8d8bef9SDimitry Andric       else {
4902e8d8bef9SDimitry Andric         // FIXME: Set the stop hook ID counter back.
4903e8d8bef9SDimitry Andric         result.AppendErrorWithFormat("Couldn't add stop hook: %s",
4904e8d8bef9SDimitry Andric                                      error.AsCString());
4905e8d8bef9SDimitry Andric         target.UndoCreateStopHook(new_hook_sp->GetID());
4906e8d8bef9SDimitry Andric         return false;
4907e8d8bef9SDimitry Andric       }
49080b57cec5SDimitry Andric     } else {
49090b57cec5SDimitry Andric       m_stop_hook_sp = new_hook_sp;
4910480093f4SDimitry Andric       m_interpreter.GetLLDBCommandsFromIOHandler("> ",   // Prompt
4911480093f4SDimitry Andric                                                  *this); // IOHandlerDelegate
49120b57cec5SDimitry Andric     }
49130b57cec5SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishNoResult);
49140b57cec5SDimitry Andric 
49150b57cec5SDimitry Andric     return result.Succeeded();
49160b57cec5SDimitry Andric   }
49170b57cec5SDimitry Andric 
49180b57cec5SDimitry Andric private:
49190b57cec5SDimitry Andric   CommandOptions m_options;
4920e8d8bef9SDimitry Andric   OptionGroupPythonClassWithDict m_python_class_options;
4921e8d8bef9SDimitry Andric   OptionGroupOptions m_all_options;
4922e8d8bef9SDimitry Andric 
49230b57cec5SDimitry Andric   Target::StopHookSP m_stop_hook_sp;
49240b57cec5SDimitry Andric };
49250b57cec5SDimitry Andric 
49260b57cec5SDimitry Andric #pragma mark CommandObjectTargetStopHookDelete
49270b57cec5SDimitry Andric 
49280b57cec5SDimitry Andric // CommandObjectTargetStopHookDelete
49290b57cec5SDimitry Andric 
49300b57cec5SDimitry Andric class CommandObjectTargetStopHookDelete : public CommandObjectParsed {
49310b57cec5SDimitry Andric public:
49320b57cec5SDimitry Andric   CommandObjectTargetStopHookDelete(CommandInterpreter &interpreter)
49330b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "target stop-hook delete",
49340b57cec5SDimitry Andric                             "Delete a stop-hook.",
493581ad6265SDimitry Andric                             "target stop-hook delete [<idx>]") {
493681ad6265SDimitry Andric     CommandArgumentData hook_arg{eArgTypeStopHookID, eArgRepeatStar};
493781ad6265SDimitry Andric     m_arguments.push_back({hook_arg});
493881ad6265SDimitry Andric   }
49390b57cec5SDimitry Andric 
49400b57cec5SDimitry Andric   ~CommandObjectTargetStopHookDelete() override = default;
49410b57cec5SDimitry Andric 
4942e8d8bef9SDimitry Andric   void
4943e8d8bef9SDimitry Andric   HandleArgumentCompletion(CompletionRequest &request,
4944e8d8bef9SDimitry Andric                            OptionElementVector &opt_element_vector) override {
4945*fe013be4SDimitry Andric     lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
4946*fe013be4SDimitry Andric         GetCommandInterpreter(), lldb::eStopHookIDCompletion, request, nullptr);
4947e8d8bef9SDimitry Andric   }
4948e8d8bef9SDimitry Andric 
49490b57cec5SDimitry Andric protected:
49500b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
49519dba64beSDimitry Andric     Target &target = GetSelectedOrDummyTarget();
49520b57cec5SDimitry Andric     // FIXME: see if we can use the breakpoint id style parser?
49530b57cec5SDimitry Andric     size_t num_args = command.GetArgumentCount();
49540b57cec5SDimitry Andric     if (num_args == 0) {
49550b57cec5SDimitry Andric       if (!m_interpreter.Confirm("Delete all stop hooks?", true)) {
49560b57cec5SDimitry Andric         result.SetStatus(eReturnStatusFailed);
49570b57cec5SDimitry Andric         return false;
49580b57cec5SDimitry Andric       } else {
49599dba64beSDimitry Andric         target.RemoveAllStopHooks();
49600b57cec5SDimitry Andric       }
49610b57cec5SDimitry Andric     } else {
49620b57cec5SDimitry Andric       for (size_t i = 0; i < num_args; i++) {
49635ffd83dbSDimitry Andric         lldb::user_id_t user_id;
49645ffd83dbSDimitry Andric         if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
49650b57cec5SDimitry Andric           result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
49660b57cec5SDimitry Andric                                        command.GetArgumentAtIndex(i));
49670b57cec5SDimitry Andric           return false;
49680b57cec5SDimitry Andric         }
49695ffd83dbSDimitry Andric         if (!target.RemoveStopHookByID(user_id)) {
49700b57cec5SDimitry Andric           result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
49710b57cec5SDimitry Andric                                        command.GetArgumentAtIndex(i));
49720b57cec5SDimitry Andric           return false;
49730b57cec5SDimitry Andric         }
49740b57cec5SDimitry Andric       }
49750b57cec5SDimitry Andric     }
49760b57cec5SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishNoResult);
49770b57cec5SDimitry Andric     return result.Succeeded();
49780b57cec5SDimitry Andric   }
49790b57cec5SDimitry Andric };
49800b57cec5SDimitry Andric 
49810b57cec5SDimitry Andric #pragma mark CommandObjectTargetStopHookEnableDisable
49820b57cec5SDimitry Andric 
49830b57cec5SDimitry Andric // CommandObjectTargetStopHookEnableDisable
49840b57cec5SDimitry Andric 
49850b57cec5SDimitry Andric class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed {
49860b57cec5SDimitry Andric public:
49870b57cec5SDimitry Andric   CommandObjectTargetStopHookEnableDisable(CommandInterpreter &interpreter,
49880b57cec5SDimitry Andric                                            bool enable, const char *name,
49890b57cec5SDimitry Andric                                            const char *help, const char *syntax)
49900b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable) {
499181ad6265SDimitry Andric     CommandArgumentData hook_arg{eArgTypeStopHookID, eArgRepeatStar};
499281ad6265SDimitry Andric     m_arguments.push_back({hook_arg});
49930b57cec5SDimitry Andric   }
49940b57cec5SDimitry Andric 
49950b57cec5SDimitry Andric   ~CommandObjectTargetStopHookEnableDisable() override = default;
49960b57cec5SDimitry Andric 
4997e8d8bef9SDimitry Andric   void
4998e8d8bef9SDimitry Andric   HandleArgumentCompletion(CompletionRequest &request,
4999e8d8bef9SDimitry Andric                            OptionElementVector &opt_element_vector) override {
5000e8d8bef9SDimitry Andric     if (request.GetCursorIndex())
5001e8d8bef9SDimitry Andric       return;
5002*fe013be4SDimitry Andric     lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
5003*fe013be4SDimitry Andric         GetCommandInterpreter(), lldb::eStopHookIDCompletion, request, nullptr);
5004e8d8bef9SDimitry Andric   }
5005e8d8bef9SDimitry Andric 
50060b57cec5SDimitry Andric protected:
50070b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
50089dba64beSDimitry Andric     Target &target = GetSelectedOrDummyTarget();
50090b57cec5SDimitry Andric     // FIXME: see if we can use the breakpoint id style parser?
50100b57cec5SDimitry Andric     size_t num_args = command.GetArgumentCount();
50110b57cec5SDimitry Andric     bool success;
50120b57cec5SDimitry Andric 
50130b57cec5SDimitry Andric     if (num_args == 0) {
50149dba64beSDimitry Andric       target.SetAllStopHooksActiveState(m_enable);
50150b57cec5SDimitry Andric     } else {
50160b57cec5SDimitry Andric       for (size_t i = 0; i < num_args; i++) {
50175ffd83dbSDimitry Andric         lldb::user_id_t user_id;
50185ffd83dbSDimitry Andric         if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
50190b57cec5SDimitry Andric           result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
50200b57cec5SDimitry Andric                                        command.GetArgumentAtIndex(i));
50210b57cec5SDimitry Andric           return false;
50220b57cec5SDimitry Andric         }
50239dba64beSDimitry Andric         success = target.SetStopHookActiveStateByID(user_id, m_enable);
50240b57cec5SDimitry Andric         if (!success) {
50250b57cec5SDimitry Andric           result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
50260b57cec5SDimitry Andric                                        command.GetArgumentAtIndex(i));
50270b57cec5SDimitry Andric           return false;
50280b57cec5SDimitry Andric         }
50290b57cec5SDimitry Andric       }
50300b57cec5SDimitry Andric     }
50310b57cec5SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishNoResult);
50320b57cec5SDimitry Andric     return result.Succeeded();
50330b57cec5SDimitry Andric   }
50340b57cec5SDimitry Andric 
50350b57cec5SDimitry Andric private:
50360b57cec5SDimitry Andric   bool m_enable;
50370b57cec5SDimitry Andric };
50380b57cec5SDimitry Andric 
50390b57cec5SDimitry Andric #pragma mark CommandObjectTargetStopHookList
50400b57cec5SDimitry Andric 
50410b57cec5SDimitry Andric // CommandObjectTargetStopHookList
50420b57cec5SDimitry Andric 
50430b57cec5SDimitry Andric class CommandObjectTargetStopHookList : public CommandObjectParsed {
50440b57cec5SDimitry Andric public:
50450b57cec5SDimitry Andric   CommandObjectTargetStopHookList(CommandInterpreter &interpreter)
50460b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "target stop-hook list",
504781ad6265SDimitry Andric                             "List all stop-hooks.", "target stop-hook list") {}
50480b57cec5SDimitry Andric 
50490b57cec5SDimitry Andric   ~CommandObjectTargetStopHookList() override = default;
50500b57cec5SDimitry Andric 
50510b57cec5SDimitry Andric protected:
50520b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
50539dba64beSDimitry Andric     Target &target = GetSelectedOrDummyTarget();
50540b57cec5SDimitry Andric 
50559dba64beSDimitry Andric     size_t num_hooks = target.GetNumStopHooks();
50560b57cec5SDimitry Andric     if (num_hooks == 0) {
50570b57cec5SDimitry Andric       result.GetOutputStream().PutCString("No stop hooks.\n");
50580b57cec5SDimitry Andric     } else {
50590b57cec5SDimitry Andric       for (size_t i = 0; i < num_hooks; i++) {
50609dba64beSDimitry Andric         Target::StopHookSP this_hook = target.GetStopHookAtIndex(i);
50610b57cec5SDimitry Andric         if (i > 0)
50620b57cec5SDimitry Andric           result.GetOutputStream().PutCString("\n");
5063*fe013be4SDimitry Andric         this_hook->GetDescription(result.GetOutputStream(),
50640b57cec5SDimitry Andric                                   eDescriptionLevelFull);
50650b57cec5SDimitry Andric       }
50660b57cec5SDimitry Andric     }
50670b57cec5SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishResult);
50680b57cec5SDimitry Andric     return result.Succeeded();
50690b57cec5SDimitry Andric   }
50700b57cec5SDimitry Andric };
50710b57cec5SDimitry Andric 
50720b57cec5SDimitry Andric #pragma mark CommandObjectMultiwordTargetStopHooks
50730b57cec5SDimitry Andric 
50740b57cec5SDimitry Andric // CommandObjectMultiwordTargetStopHooks
50750b57cec5SDimitry Andric 
50760b57cec5SDimitry Andric class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword {
50770b57cec5SDimitry Andric public:
50780b57cec5SDimitry Andric   CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter)
50790b57cec5SDimitry Andric       : CommandObjectMultiword(
50800b57cec5SDimitry Andric             interpreter, "target stop-hook",
50810b57cec5SDimitry Andric             "Commands for operating on debugger target stop-hooks.",
50820b57cec5SDimitry Andric             "target stop-hook <subcommand> [<subcommand-options>]") {
50830b57cec5SDimitry Andric     LoadSubCommand("add", CommandObjectSP(
50840b57cec5SDimitry Andric                               new CommandObjectTargetStopHookAdd(interpreter)));
50850b57cec5SDimitry Andric     LoadSubCommand(
50860b57cec5SDimitry Andric         "delete",
50870b57cec5SDimitry Andric         CommandObjectSP(new CommandObjectTargetStopHookDelete(interpreter)));
50880b57cec5SDimitry Andric     LoadSubCommand("disable",
50890b57cec5SDimitry Andric                    CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
50900b57cec5SDimitry Andric                        interpreter, false, "target stop-hook disable [<id>]",
50910b57cec5SDimitry Andric                        "Disable a stop-hook.", "target stop-hook disable")));
50920b57cec5SDimitry Andric     LoadSubCommand("enable",
50930b57cec5SDimitry Andric                    CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
50940b57cec5SDimitry Andric                        interpreter, true, "target stop-hook enable [<id>]",
50950b57cec5SDimitry Andric                        "Enable a stop-hook.", "target stop-hook enable")));
50960b57cec5SDimitry Andric     LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetStopHookList(
50970b57cec5SDimitry Andric                                interpreter)));
50980b57cec5SDimitry Andric   }
50990b57cec5SDimitry Andric 
51000b57cec5SDimitry Andric   ~CommandObjectMultiwordTargetStopHooks() override = default;
51010b57cec5SDimitry Andric };
51020b57cec5SDimitry Andric 
5103349cc55cSDimitry Andric #pragma mark CommandObjectTargetDumpTypesystem
5104349cc55cSDimitry Andric 
5105349cc55cSDimitry Andric /// Dumps the TypeSystem of the selected Target.
5106349cc55cSDimitry Andric class CommandObjectTargetDumpTypesystem : public CommandObjectParsed {
5107349cc55cSDimitry Andric public:
5108349cc55cSDimitry Andric   CommandObjectTargetDumpTypesystem(CommandInterpreter &interpreter)
5109349cc55cSDimitry Andric       : CommandObjectParsed(
5110349cc55cSDimitry Andric             interpreter, "target dump typesystem",
5111*fe013be4SDimitry Andric             "Dump the state of the target's internal type system. Intended to "
5112*fe013be4SDimitry Andric             "be used for debugging LLDB itself.",
5113349cc55cSDimitry Andric             nullptr, eCommandRequiresTarget) {}
5114349cc55cSDimitry Andric 
5115349cc55cSDimitry Andric   ~CommandObjectTargetDumpTypesystem() override = default;
5116349cc55cSDimitry Andric 
5117349cc55cSDimitry Andric protected:
5118349cc55cSDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
5119349cc55cSDimitry Andric     // Go over every scratch TypeSystem and dump to the command output.
5120bdd1243dSDimitry Andric     for (lldb::TypeSystemSP ts : GetSelectedTarget().GetScratchTypeSystems())
5121bdd1243dSDimitry Andric       if (ts)
5122349cc55cSDimitry Andric         ts->Dump(result.GetOutputStream().AsRawOstream());
5123349cc55cSDimitry Andric 
5124349cc55cSDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishResult);
5125349cc55cSDimitry Andric     return result.Succeeded();
5126349cc55cSDimitry Andric   }
5127349cc55cSDimitry Andric };
5128349cc55cSDimitry Andric 
5129*fe013be4SDimitry Andric #pragma mark CommandObjectTargetDumpSectionLoadList
5130*fe013be4SDimitry Andric 
5131*fe013be4SDimitry Andric /// Dumps the SectionLoadList of the selected Target.
5132*fe013be4SDimitry Andric class CommandObjectTargetDumpSectionLoadList : public CommandObjectParsed {
5133*fe013be4SDimitry Andric public:
5134*fe013be4SDimitry Andric   CommandObjectTargetDumpSectionLoadList(CommandInterpreter &interpreter)
5135*fe013be4SDimitry Andric       : CommandObjectParsed(
5136*fe013be4SDimitry Andric             interpreter, "target dump section-load-list",
5137*fe013be4SDimitry Andric             "Dump the state of the target's internal section load list. "
5138*fe013be4SDimitry Andric             "Intended to be used for debugging LLDB itself.",
5139*fe013be4SDimitry Andric             nullptr, eCommandRequiresTarget) {}
5140*fe013be4SDimitry Andric 
5141*fe013be4SDimitry Andric   ~CommandObjectTargetDumpSectionLoadList() override = default;
5142*fe013be4SDimitry Andric 
5143*fe013be4SDimitry Andric protected:
5144*fe013be4SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
5145*fe013be4SDimitry Andric     Target &target = GetSelectedTarget();
5146*fe013be4SDimitry Andric     target.GetSectionLoadList().Dump(result.GetOutputStream(), &target);
5147*fe013be4SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishResult);
5148*fe013be4SDimitry Andric     return result.Succeeded();
5149*fe013be4SDimitry Andric   }
5150*fe013be4SDimitry Andric };
5151*fe013be4SDimitry Andric 
5152349cc55cSDimitry Andric #pragma mark CommandObjectTargetDump
5153349cc55cSDimitry Andric 
5154349cc55cSDimitry Andric /// Multi-word command for 'target dump'.
5155349cc55cSDimitry Andric class CommandObjectTargetDump : public CommandObjectMultiword {
5156349cc55cSDimitry Andric public:
5157349cc55cSDimitry Andric   // Constructors and Destructors
5158349cc55cSDimitry Andric   CommandObjectTargetDump(CommandInterpreter &interpreter)
5159349cc55cSDimitry Andric       : CommandObjectMultiword(
5160349cc55cSDimitry Andric             interpreter, "target dump",
5161349cc55cSDimitry Andric             "Commands for dumping information about the target.",
5162*fe013be4SDimitry Andric             "target dump [typesystem|section-load-list]") {
5163349cc55cSDimitry Andric     LoadSubCommand(
5164349cc55cSDimitry Andric         "typesystem",
5165349cc55cSDimitry Andric         CommandObjectSP(new CommandObjectTargetDumpTypesystem(interpreter)));
5166*fe013be4SDimitry Andric     LoadSubCommand("section-load-list",
5167*fe013be4SDimitry Andric                    CommandObjectSP(new CommandObjectTargetDumpSectionLoadList(
5168*fe013be4SDimitry Andric                        interpreter)));
5169349cc55cSDimitry Andric   }
5170349cc55cSDimitry Andric 
5171349cc55cSDimitry Andric   ~CommandObjectTargetDump() override = default;
5172349cc55cSDimitry Andric };
5173349cc55cSDimitry Andric 
51740b57cec5SDimitry Andric #pragma mark CommandObjectMultiwordTarget
51750b57cec5SDimitry Andric 
51760b57cec5SDimitry Andric // CommandObjectMultiwordTarget
51770b57cec5SDimitry Andric 
51780b57cec5SDimitry Andric CommandObjectMultiwordTarget::CommandObjectMultiwordTarget(
51790b57cec5SDimitry Andric     CommandInterpreter &interpreter)
51800b57cec5SDimitry Andric     : CommandObjectMultiword(interpreter, "target",
51810b57cec5SDimitry Andric                              "Commands for operating on debugger targets.",
51820b57cec5SDimitry Andric                              "target <subcommand> [<subcommand-options>]") {
51830b57cec5SDimitry Andric   LoadSubCommand("create",
51840b57cec5SDimitry Andric                  CommandObjectSP(new CommandObjectTargetCreate(interpreter)));
51850b57cec5SDimitry Andric   LoadSubCommand("delete",
51860b57cec5SDimitry Andric                  CommandObjectSP(new CommandObjectTargetDelete(interpreter)));
5187349cc55cSDimitry Andric   LoadSubCommand("dump",
5188349cc55cSDimitry Andric                  CommandObjectSP(new CommandObjectTargetDump(interpreter)));
51890b57cec5SDimitry Andric   LoadSubCommand("list",
51900b57cec5SDimitry Andric                  CommandObjectSP(new CommandObjectTargetList(interpreter)));
51910b57cec5SDimitry Andric   LoadSubCommand("select",
51920b57cec5SDimitry Andric                  CommandObjectSP(new CommandObjectTargetSelect(interpreter)));
51935ffd83dbSDimitry Andric   LoadSubCommand("show-launch-environment",
51945ffd83dbSDimitry Andric                  CommandObjectSP(new CommandObjectTargetShowLaunchEnvironment(
51955ffd83dbSDimitry Andric                      interpreter)));
51960b57cec5SDimitry Andric   LoadSubCommand(
51970b57cec5SDimitry Andric       "stop-hook",
51980b57cec5SDimitry Andric       CommandObjectSP(new CommandObjectMultiwordTargetStopHooks(interpreter)));
51990b57cec5SDimitry Andric   LoadSubCommand("modules",
52000b57cec5SDimitry Andric                  CommandObjectSP(new CommandObjectTargetModules(interpreter)));
52010b57cec5SDimitry Andric   LoadSubCommand("symbols",
52020b57cec5SDimitry Andric                  CommandObjectSP(new CommandObjectTargetSymbols(interpreter)));
52030b57cec5SDimitry Andric   LoadSubCommand("variable",
52040b57cec5SDimitry Andric                  CommandObjectSP(new CommandObjectTargetVariable(interpreter)));
52050b57cec5SDimitry Andric }
52060b57cec5SDimitry Andric 
52070b57cec5SDimitry Andric CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget() = default;
5208