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"
200b57cec5SDimitry Andric #include "lldb/Interpreter/CommandReturnObject.h"
210b57cec5SDimitry Andric #include "lldb/Interpreter/OptionArgParser.h"
220b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupArchitecture.h"
230b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupBoolean.h"
240b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupFile.h"
250b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupFormat.h"
26af732203SDimitry Andric #include "lldb/Interpreter/OptionGroupPlatform.h"
27af732203SDimitry Andric #include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
280b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupString.h"
290b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupUInt64.h"
300b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupUUID.h"
310b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
320b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupVariable.h"
330b57cec5SDimitry Andric #include "lldb/Interpreter/Options.h"
340b57cec5SDimitry Andric #include "lldb/Symbol/CompileUnit.h"
350b57cec5SDimitry Andric #include "lldb/Symbol/FuncUnwinders.h"
360b57cec5SDimitry Andric #include "lldb/Symbol/LineTable.h"
370b57cec5SDimitry Andric #include "lldb/Symbol/LocateSymbolFile.h"
380b57cec5SDimitry Andric #include "lldb/Symbol/ObjectFile.h"
390b57cec5SDimitry Andric #include "lldb/Symbol/SymbolFile.h"
400b57cec5SDimitry Andric #include "lldb/Symbol/UnwindPlan.h"
410b57cec5SDimitry Andric #include "lldb/Symbol/VariableList.h"
420b57cec5SDimitry Andric #include "lldb/Target/ABI.h"
430b57cec5SDimitry Andric #include "lldb/Target/Process.h"
440b57cec5SDimitry Andric #include "lldb/Target/RegisterContext.h"
450b57cec5SDimitry Andric #include "lldb/Target/SectionLoadList.h"
460b57cec5SDimitry Andric #include "lldb/Target/StackFrame.h"
470b57cec5SDimitry Andric #include "lldb/Target/Thread.h"
480b57cec5SDimitry Andric #include "lldb/Target/ThreadSpec.h"
490b57cec5SDimitry Andric #include "lldb/Utility/Args.h"
500b57cec5SDimitry Andric #include "lldb/Utility/State.h"
510b57cec5SDimitry Andric #include "lldb/Utility/Timer.h"
520b57cec5SDimitry Andric 
53af732203SDimitry Andric #include "llvm/ADT/ScopeExit.h"
540b57cec5SDimitry Andric #include "llvm/Support/FileSystem.h"
550b57cec5SDimitry Andric #include "llvm/Support/FormatAdapters.h"
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric 
580b57cec5SDimitry Andric using namespace lldb;
590b57cec5SDimitry Andric using namespace lldb_private;
600b57cec5SDimitry Andric 
DumpTargetInfo(uint32_t target_idx,Target * target,const char * prefix_cstr,bool show_stopped_process_status,Stream & strm)610b57cec5SDimitry Andric static void DumpTargetInfo(uint32_t target_idx, Target *target,
620b57cec5SDimitry Andric                            const char *prefix_cstr,
630b57cec5SDimitry Andric                            bool show_stopped_process_status, Stream &strm) {
640b57cec5SDimitry Andric   const ArchSpec &target_arch = target->GetArchitecture();
650b57cec5SDimitry Andric 
660b57cec5SDimitry Andric   Module *exe_module = target->GetExecutableModulePointer();
670b57cec5SDimitry Andric   char exe_path[PATH_MAX];
680b57cec5SDimitry Andric   bool exe_valid = false;
690b57cec5SDimitry Andric   if (exe_module)
700b57cec5SDimitry Andric     exe_valid = exe_module->GetFileSpec().GetPath(exe_path, sizeof(exe_path));
710b57cec5SDimitry Andric 
720b57cec5SDimitry Andric   if (!exe_valid)
730b57cec5SDimitry Andric     ::strcpy(exe_path, "<none>");
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric   strm.Printf("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx,
760b57cec5SDimitry Andric               exe_path);
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric   uint32_t properties = 0;
790b57cec5SDimitry Andric   if (target_arch.IsValid()) {
800b57cec5SDimitry Andric     strm.Printf("%sarch=", properties++ > 0 ? ", " : " ( ");
81480093f4SDimitry Andric     target_arch.DumpTriple(strm.AsRawOstream());
820b57cec5SDimitry Andric     properties++;
830b57cec5SDimitry Andric   }
840b57cec5SDimitry Andric   PlatformSP platform_sp(target->GetPlatform());
850b57cec5SDimitry Andric   if (platform_sp)
860b57cec5SDimitry Andric     strm.Printf("%splatform=%s", properties++ > 0 ? ", " : " ( ",
870b57cec5SDimitry Andric                 platform_sp->GetName().GetCString());
880b57cec5SDimitry Andric 
890b57cec5SDimitry Andric   ProcessSP process_sp(target->GetProcessSP());
900b57cec5SDimitry Andric   bool show_process_status = false;
910b57cec5SDimitry Andric   if (process_sp) {
920b57cec5SDimitry Andric     lldb::pid_t pid = process_sp->GetID();
930b57cec5SDimitry Andric     StateType state = process_sp->GetState();
940b57cec5SDimitry Andric     if (show_stopped_process_status)
950b57cec5SDimitry Andric       show_process_status = StateIsStoppedState(state, true);
960b57cec5SDimitry Andric     const char *state_cstr = StateAsCString(state);
970b57cec5SDimitry Andric     if (pid != LLDB_INVALID_PROCESS_ID)
980b57cec5SDimitry Andric       strm.Printf("%spid=%" PRIu64, properties++ > 0 ? ", " : " ( ", pid);
990b57cec5SDimitry Andric     strm.Printf("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
1000b57cec5SDimitry Andric   }
1010b57cec5SDimitry Andric   if (properties > 0)
1020b57cec5SDimitry Andric     strm.PutCString(" )\n");
1030b57cec5SDimitry Andric   else
1040b57cec5SDimitry Andric     strm.EOL();
1050b57cec5SDimitry Andric   if (show_process_status) {
1060b57cec5SDimitry Andric     const bool only_threads_with_stop_reason = true;
1070b57cec5SDimitry Andric     const uint32_t start_frame = 0;
1080b57cec5SDimitry Andric     const uint32_t num_frames = 1;
1090b57cec5SDimitry Andric     const uint32_t num_frames_with_source = 1;
1100b57cec5SDimitry Andric     const bool stop_format = false;
1110b57cec5SDimitry Andric     process_sp->GetStatus(strm);
1120b57cec5SDimitry Andric     process_sp->GetThreadStatus(strm, only_threads_with_stop_reason,
113480093f4SDimitry Andric                                 start_frame, num_frames, num_frames_with_source,
114480093f4SDimitry Andric                                 stop_format);
1150b57cec5SDimitry Andric   }
1160b57cec5SDimitry Andric }
1170b57cec5SDimitry Andric 
DumpTargetList(TargetList & target_list,bool show_stopped_process_status,Stream & strm)1180b57cec5SDimitry Andric static uint32_t DumpTargetList(TargetList &target_list,
1190b57cec5SDimitry Andric                                bool show_stopped_process_status, Stream &strm) {
1200b57cec5SDimitry Andric   const uint32_t num_targets = target_list.GetNumTargets();
1210b57cec5SDimitry Andric   if (num_targets) {
1220b57cec5SDimitry Andric     TargetSP selected_target_sp(target_list.GetSelectedTarget());
1230b57cec5SDimitry Andric     strm.PutCString("Current targets:\n");
1240b57cec5SDimitry Andric     for (uint32_t i = 0; i < num_targets; ++i) {
1250b57cec5SDimitry Andric       TargetSP target_sp(target_list.GetTargetAtIndex(i));
1260b57cec5SDimitry Andric       if (target_sp) {
1270b57cec5SDimitry Andric         bool is_selected = target_sp.get() == selected_target_sp.get();
1280b57cec5SDimitry Andric         DumpTargetInfo(i, target_sp.get(), is_selected ? "* " : "  ",
1290b57cec5SDimitry Andric                        show_stopped_process_status, strm);
1300b57cec5SDimitry Andric       }
1310b57cec5SDimitry Andric     }
1320b57cec5SDimitry Andric   }
1330b57cec5SDimitry Andric   return num_targets;
1340b57cec5SDimitry Andric }
1350b57cec5SDimitry Andric 
1360b57cec5SDimitry Andric // Note that the negation in the argument name causes a slightly confusing
1379dba64beSDimitry Andric // mapping of the enum values.
1380b57cec5SDimitry Andric static constexpr OptionEnumValueElement g_dependents_enumaration[] = {
1399dba64beSDimitry Andric     {
1409dba64beSDimitry Andric         eLoadDependentsDefault,
1419dba64beSDimitry Andric         "default",
1429dba64beSDimitry Andric         "Only load dependents when the target is an executable.",
1439dba64beSDimitry Andric     },
1449dba64beSDimitry Andric     {
1459dba64beSDimitry Andric         eLoadDependentsNo,
1469dba64beSDimitry Andric         "true",
1479dba64beSDimitry Andric         "Don't load dependents, even if the target is an executable.",
1489dba64beSDimitry Andric     },
1499dba64beSDimitry Andric     {
1509dba64beSDimitry Andric         eLoadDependentsYes,
1519dba64beSDimitry Andric         "false",
1529dba64beSDimitry Andric         "Load dependents, even if the target is not an executable.",
1539dba64beSDimitry Andric     },
1549dba64beSDimitry Andric };
1550b57cec5SDimitry Andric 
1569dba64beSDimitry Andric #define LLDB_OPTIONS_target_dependents
1579dba64beSDimitry Andric #include "CommandOptions.inc"
1580b57cec5SDimitry Andric 
1590b57cec5SDimitry Andric class OptionGroupDependents : public OptionGroup {
1600b57cec5SDimitry Andric public:
161*5f7ddb14SDimitry Andric   OptionGroupDependents() = default;
1620b57cec5SDimitry Andric 
163*5f7ddb14SDimitry Andric   ~OptionGroupDependents() override = default;
1640b57cec5SDimitry Andric 
GetDefinitions()1650b57cec5SDimitry Andric   llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1669dba64beSDimitry Andric     return llvm::makeArrayRef(g_target_dependents_options);
1670b57cec5SDimitry Andric   }
1680b57cec5SDimitry Andric 
SetOptionValue(uint32_t option_idx,llvm::StringRef option_value,ExecutionContext * execution_context)1690b57cec5SDimitry Andric   Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
1700b57cec5SDimitry Andric                         ExecutionContext *execution_context) override {
1710b57cec5SDimitry Andric     Status error;
1720b57cec5SDimitry Andric 
1730b57cec5SDimitry Andric     // For compatibility no value means don't load dependents.
1740b57cec5SDimitry Andric     if (option_value.empty()) {
1750b57cec5SDimitry Andric       m_load_dependent_files = eLoadDependentsNo;
1760b57cec5SDimitry Andric       return error;
1770b57cec5SDimitry Andric     }
1780b57cec5SDimitry Andric 
1799dba64beSDimitry Andric     const char short_option =
1809dba64beSDimitry Andric         g_target_dependents_options[option_idx].short_option;
1810b57cec5SDimitry Andric     if (short_option == 'd') {
1820b57cec5SDimitry Andric       LoadDependentFiles tmp_load_dependents;
1830b57cec5SDimitry Andric       tmp_load_dependents = (LoadDependentFiles)OptionArgParser::ToOptionEnum(
1849dba64beSDimitry Andric           option_value, g_target_dependents_options[option_idx].enum_values, 0,
1859dba64beSDimitry Andric           error);
1860b57cec5SDimitry Andric       if (error.Success())
1870b57cec5SDimitry Andric         m_load_dependent_files = tmp_load_dependents;
1880b57cec5SDimitry Andric     } else {
1890b57cec5SDimitry Andric       error.SetErrorStringWithFormat("unrecognized short option '%c'",
1900b57cec5SDimitry Andric                                      short_option);
1910b57cec5SDimitry Andric     }
1920b57cec5SDimitry Andric 
1930b57cec5SDimitry Andric     return error;
1940b57cec5SDimitry Andric   }
1950b57cec5SDimitry Andric 
1960b57cec5SDimitry Andric   Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete;
1970b57cec5SDimitry Andric 
OptionParsingStarting(ExecutionContext * execution_context)1980b57cec5SDimitry Andric   void OptionParsingStarting(ExecutionContext *execution_context) override {
1990b57cec5SDimitry Andric     m_load_dependent_files = eLoadDependentsDefault;
2000b57cec5SDimitry Andric   }
2010b57cec5SDimitry Andric 
2020b57cec5SDimitry Andric   LoadDependentFiles m_load_dependent_files;
2030b57cec5SDimitry Andric 
2040b57cec5SDimitry Andric private:
2055ffd83dbSDimitry Andric   OptionGroupDependents(const OptionGroupDependents &) = delete;
2065ffd83dbSDimitry Andric   const OptionGroupDependents &
2075ffd83dbSDimitry Andric   operator=(const OptionGroupDependents &) = delete;
2080b57cec5SDimitry Andric };
2090b57cec5SDimitry Andric 
2100b57cec5SDimitry Andric #pragma mark CommandObjectTargetCreate
2110b57cec5SDimitry Andric 
2120b57cec5SDimitry Andric class CommandObjectTargetCreate : public CommandObjectParsed {
2130b57cec5SDimitry Andric public:
CommandObjectTargetCreate(CommandInterpreter & interpreter)2140b57cec5SDimitry Andric   CommandObjectTargetCreate(CommandInterpreter &interpreter)
2150b57cec5SDimitry Andric       : CommandObjectParsed(
2160b57cec5SDimitry Andric             interpreter, "target create",
2170b57cec5SDimitry Andric             "Create a target using the argument as the main executable.",
2180b57cec5SDimitry Andric             nullptr),
2190b57cec5SDimitry Andric         m_option_group(), m_arch_option(),
220af732203SDimitry Andric         m_platform_options(true), // Include the --platform option.
2210b57cec5SDimitry Andric         m_core_file(LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename,
2220b57cec5SDimitry Andric                     "Fullpath to a core file to use for this target."),
2230b57cec5SDimitry Andric         m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
2240b57cec5SDimitry Andric                       eArgTypeFilename,
2250b57cec5SDimitry Andric                       "Fullpath to a stand alone debug "
2260b57cec5SDimitry Andric                       "symbols file for when debug symbols "
2270b57cec5SDimitry Andric                       "are not in the executable."),
2280b57cec5SDimitry Andric         m_remote_file(
2290b57cec5SDimitry Andric             LLDB_OPT_SET_1, false, "remote-file", 'r', 0, eArgTypeFilename,
2300b57cec5SDimitry Andric             "Fullpath to the file on the remote host if debugging remotely."),
2310b57cec5SDimitry Andric         m_add_dependents() {
2320b57cec5SDimitry Andric     CommandArgumentEntry arg;
2330b57cec5SDimitry Andric     CommandArgumentData file_arg;
2340b57cec5SDimitry Andric 
2350b57cec5SDimitry Andric     // Define the first (and only) variant of this arg.
2360b57cec5SDimitry Andric     file_arg.arg_type = eArgTypeFilename;
2370b57cec5SDimitry Andric     file_arg.arg_repetition = eArgRepeatPlain;
2380b57cec5SDimitry Andric 
2390b57cec5SDimitry Andric     // There is only one variant this argument could be; put it into the
2400b57cec5SDimitry Andric     // argument entry.
2410b57cec5SDimitry Andric     arg.push_back(file_arg);
2420b57cec5SDimitry Andric 
2430b57cec5SDimitry Andric     // Push the data for the first argument into the m_arguments vector.
2440b57cec5SDimitry Andric     m_arguments.push_back(arg);
2450b57cec5SDimitry Andric 
2460b57cec5SDimitry Andric     m_option_group.Append(&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
247af732203SDimitry Andric     m_option_group.Append(&m_platform_options, LLDB_OPT_SET_ALL, 1);
2480b57cec5SDimitry Andric     m_option_group.Append(&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2490b57cec5SDimitry Andric     m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2500b57cec5SDimitry Andric     m_option_group.Append(&m_remote_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2510b57cec5SDimitry Andric     m_option_group.Append(&m_add_dependents, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2520b57cec5SDimitry Andric     m_option_group.Finalize();
2530b57cec5SDimitry Andric   }
2540b57cec5SDimitry Andric 
2550b57cec5SDimitry Andric   ~CommandObjectTargetCreate() override = default;
2560b57cec5SDimitry Andric 
GetOptions()2570b57cec5SDimitry Andric   Options *GetOptions() override { return &m_option_group; }
2580b57cec5SDimitry Andric 
2599dba64beSDimitry Andric   void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)2609dba64beSDimitry Andric   HandleArgumentCompletion(CompletionRequest &request,
2610b57cec5SDimitry Andric                            OptionElementVector &opt_element_vector) override {
2620b57cec5SDimitry Andric     CommandCompletions::InvokeCommonCompletionCallbacks(
2630b57cec5SDimitry Andric         GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
2640b57cec5SDimitry Andric         request, nullptr);
2650b57cec5SDimitry Andric   }
2660b57cec5SDimitry Andric 
2670b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)2680b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
2690b57cec5SDimitry Andric     const size_t argc = command.GetArgumentCount();
2700b57cec5SDimitry Andric     FileSpec core_file(m_core_file.GetOptionValue().GetCurrentValue());
2710b57cec5SDimitry Andric     FileSpec remote_file(m_remote_file.GetOptionValue().GetCurrentValue());
2720b57cec5SDimitry Andric 
2730b57cec5SDimitry Andric     if (core_file) {
2745ffd83dbSDimitry Andric       auto file = FileSystem::Instance().Open(
2755ffd83dbSDimitry Andric           core_file, lldb_private::File::eOpenOptionRead);
2765ffd83dbSDimitry Andric 
2775ffd83dbSDimitry Andric       if (!file) {
2785ffd83dbSDimitry Andric         result.AppendErrorWithFormatv("Cannot open '{0}': {1}.",
2795ffd83dbSDimitry Andric                                       core_file.GetPath(),
2805ffd83dbSDimitry Andric                                       llvm::toString(file.takeError()));
2810b57cec5SDimitry Andric         return false;
2820b57cec5SDimitry Andric       }
2830b57cec5SDimitry Andric     }
2840b57cec5SDimitry Andric 
2850b57cec5SDimitry Andric     if (argc == 1 || core_file || remote_file) {
2860b57cec5SDimitry Andric       FileSpec symfile(m_symbol_file.GetOptionValue().GetCurrentValue());
2870b57cec5SDimitry Andric       if (symfile) {
2885ffd83dbSDimitry Andric         auto file = FileSystem::Instance().Open(
2895ffd83dbSDimitry Andric             symfile, lldb_private::File::eOpenOptionRead);
2905ffd83dbSDimitry Andric 
2915ffd83dbSDimitry Andric         if (!file) {
2925ffd83dbSDimitry Andric           result.AppendErrorWithFormatv("Cannot open '{0}': {1}.",
2935ffd83dbSDimitry Andric                                         symfile.GetPath(),
2945ffd83dbSDimitry Andric                                         llvm::toString(file.takeError()));
2950b57cec5SDimitry Andric           return false;
2960b57cec5SDimitry Andric         }
2970b57cec5SDimitry Andric       }
2980b57cec5SDimitry Andric 
2990b57cec5SDimitry Andric       const char *file_path = command.GetArgumentAtIndex(0);
300af732203SDimitry Andric       LLDB_SCOPED_TIMERF("(lldb) target create '%s'", file_path);
3010b57cec5SDimitry Andric       FileSpec file_spec;
3020b57cec5SDimitry Andric 
3030b57cec5SDimitry Andric       if (file_path) {
3040b57cec5SDimitry Andric         file_spec.SetFile(file_path, FileSpec::Style::native);
3050b57cec5SDimitry Andric         FileSystem::Instance().Resolve(file_spec);
3060b57cec5SDimitry Andric       }
3070b57cec5SDimitry Andric 
3080b57cec5SDimitry Andric       bool must_set_platform_path = false;
3090b57cec5SDimitry Andric 
3100b57cec5SDimitry Andric       Debugger &debugger = GetDebugger();
3110b57cec5SDimitry Andric 
3120b57cec5SDimitry Andric       TargetSP target_sp;
3130b57cec5SDimitry Andric       llvm::StringRef arch_cstr = m_arch_option.GetArchitectureName();
3140b57cec5SDimitry Andric       Status error(debugger.GetTargetList().CreateTarget(
3150b57cec5SDimitry Andric           debugger, file_path, arch_cstr,
316af732203SDimitry Andric           m_add_dependents.m_load_dependent_files, &m_platform_options,
317af732203SDimitry Andric           target_sp));
3180b57cec5SDimitry Andric 
319af732203SDimitry Andric       if (!target_sp) {
320af732203SDimitry Andric         result.AppendError(error.AsCString());
321af732203SDimitry Andric         return false;
322af732203SDimitry Andric       }
323af732203SDimitry Andric 
324af732203SDimitry Andric       auto on_error = llvm::make_scope_exit(
325af732203SDimitry Andric           [&target_list = debugger.GetTargetList(), &target_sp]() {
326af732203SDimitry Andric             target_list.DeleteTarget(target_sp);
327af732203SDimitry Andric           });
328af732203SDimitry Andric 
3290b57cec5SDimitry Andric       // Only get the platform after we create the target because we might
3300b57cec5SDimitry Andric       // have switched platforms depending on what the arguments were to
3310b57cec5SDimitry Andric       // CreateTarget() we can't rely on the selected platform.
3320b57cec5SDimitry Andric 
3330b57cec5SDimitry Andric       PlatformSP platform_sp = target_sp->GetPlatform();
3340b57cec5SDimitry Andric 
3350b57cec5SDimitry Andric       if (remote_file) {
3360b57cec5SDimitry Andric         if (platform_sp) {
3370b57cec5SDimitry Andric           // I have a remote file.. two possible cases
3380b57cec5SDimitry Andric           if (file_spec && FileSystem::Instance().Exists(file_spec)) {
3390b57cec5SDimitry Andric             // if the remote file does not exist, push it there
3400b57cec5SDimitry Andric             if (!platform_sp->GetFileExists(remote_file)) {
3410b57cec5SDimitry Andric               Status err = platform_sp->PutFile(file_spec, remote_file);
3420b57cec5SDimitry Andric               if (err.Fail()) {
3430b57cec5SDimitry Andric                 result.AppendError(err.AsCString());
3440b57cec5SDimitry Andric                 return false;
3450b57cec5SDimitry Andric               }
3460b57cec5SDimitry Andric             }
3470b57cec5SDimitry Andric           } else {
3480b57cec5SDimitry Andric             // there is no local file and we need one
3490b57cec5SDimitry Andric             // in order to make the remote ---> local transfer we need a
3500b57cec5SDimitry Andric             // platform
3510b57cec5SDimitry Andric             // TODO: if the user has passed in a --platform argument, use it
3520b57cec5SDimitry Andric             // to fetch the right platform
3530b57cec5SDimitry Andric             if (file_path) {
3540b57cec5SDimitry Andric               // copy the remote file to the local file
3550b57cec5SDimitry Andric               Status err = platform_sp->GetFile(remote_file, file_spec);
3560b57cec5SDimitry Andric               if (err.Fail()) {
3570b57cec5SDimitry Andric                 result.AppendError(err.AsCString());
3580b57cec5SDimitry Andric                 return false;
3590b57cec5SDimitry Andric               }
3600b57cec5SDimitry Andric             } else {
3610b57cec5SDimitry Andric               // make up a local file
3620b57cec5SDimitry Andric               result.AppendError("remote --> local transfer without local "
3630b57cec5SDimitry Andric                                  "path is not implemented yet");
3640b57cec5SDimitry Andric               return false;
3650b57cec5SDimitry Andric             }
3660b57cec5SDimitry Andric           }
3670b57cec5SDimitry Andric         } else {
3680b57cec5SDimitry Andric           result.AppendError("no platform found for target");
3690b57cec5SDimitry Andric           return false;
3700b57cec5SDimitry Andric         }
3710b57cec5SDimitry Andric       }
3720b57cec5SDimitry Andric 
3730b57cec5SDimitry Andric       if (symfile || remote_file) {
3740b57cec5SDimitry Andric         ModuleSP module_sp(target_sp->GetExecutableModule());
3750b57cec5SDimitry Andric         if (module_sp) {
3760b57cec5SDimitry Andric           if (symfile)
3770b57cec5SDimitry Andric             module_sp->SetSymbolFileFileSpec(symfile);
3780b57cec5SDimitry Andric           if (remote_file) {
3790b57cec5SDimitry Andric             std::string remote_path = remote_file.GetPath();
3800b57cec5SDimitry Andric             target_sp->SetArg0(remote_path.c_str());
3810b57cec5SDimitry Andric             module_sp->SetPlatformFileSpec(remote_file);
3820b57cec5SDimitry Andric           }
3830b57cec5SDimitry Andric         }
3840b57cec5SDimitry Andric       }
3850b57cec5SDimitry Andric 
3860b57cec5SDimitry Andric       if (must_set_platform_path) {
3870b57cec5SDimitry Andric         ModuleSpec main_module_spec(file_spec);
388480093f4SDimitry Andric         ModuleSP module_sp =
389480093f4SDimitry Andric             target_sp->GetOrCreateModule(main_module_spec, true /* notify */);
3900b57cec5SDimitry Andric         if (module_sp)
3910b57cec5SDimitry Andric           module_sp->SetPlatformFileSpec(remote_file);
3920b57cec5SDimitry Andric       }
3935ffd83dbSDimitry Andric 
3940b57cec5SDimitry Andric       if (core_file) {
3950b57cec5SDimitry Andric         FileSpec core_file_dir;
3960b57cec5SDimitry Andric         core_file_dir.GetDirectory() = core_file.GetDirectory();
3970b57cec5SDimitry Andric         target_sp->AppendExecutableSearchPaths(core_file_dir);
3980b57cec5SDimitry Andric 
3990b57cec5SDimitry Andric         ProcessSP process_sp(target_sp->CreateProcess(
400af732203SDimitry Andric             GetDebugger().GetListener(), llvm::StringRef(), &core_file, false));
4010b57cec5SDimitry Andric 
4020b57cec5SDimitry Andric         if (process_sp) {
4030b57cec5SDimitry Andric           // Seems weird that we Launch a core file, but that is what we
4040b57cec5SDimitry Andric           // do!
4050b57cec5SDimitry Andric           error = process_sp->LoadCore();
4060b57cec5SDimitry Andric 
4070b57cec5SDimitry Andric           if (error.Fail()) {
4080b57cec5SDimitry Andric             result.AppendError(
4090b57cec5SDimitry Andric                 error.AsCString("can't find plug-in for core file"));
4100b57cec5SDimitry Andric             return false;
4110b57cec5SDimitry Andric           } else {
412af732203SDimitry Andric             result.AppendMessageWithFormatv(
413af732203SDimitry Andric                 "Core file '{0}' ({1}) was loaded.\n", core_file.GetPath(),
4140b57cec5SDimitry Andric                 target_sp->GetArchitecture().GetArchitectureName());
4150b57cec5SDimitry Andric             result.SetStatus(eReturnStatusSuccessFinishNoResult);
416af732203SDimitry Andric             on_error.release();
4170b57cec5SDimitry Andric           }
4180b57cec5SDimitry Andric         } else {
4195ffd83dbSDimitry Andric           result.AppendErrorWithFormatv(
4205ffd83dbSDimitry Andric               "Unable to find process plug-in for core file '{0}'\n",
4215ffd83dbSDimitry Andric               core_file.GetPath());
4220b57cec5SDimitry Andric         }
4230b57cec5SDimitry Andric       } else {
4240b57cec5SDimitry Andric         result.AppendMessageWithFormat(
4259dba64beSDimitry Andric             "Current executable set to '%s' (%s).\n",
4269dba64beSDimitry Andric             file_spec.GetPath().c_str(),
4270b57cec5SDimitry Andric             target_sp->GetArchitecture().GetArchitectureName());
4280b57cec5SDimitry Andric         result.SetStatus(eReturnStatusSuccessFinishNoResult);
429af732203SDimitry Andric         on_error.release();
4300b57cec5SDimitry Andric       }
4310b57cec5SDimitry Andric     } else {
4320b57cec5SDimitry Andric       result.AppendErrorWithFormat("'%s' takes exactly one executable path "
4330b57cec5SDimitry Andric                                    "argument, or use the --core option.\n",
4340b57cec5SDimitry Andric                                    m_cmd_name.c_str());
4350b57cec5SDimitry Andric     }
436af732203SDimitry Andric 
4370b57cec5SDimitry Andric     return result.Succeeded();
4380b57cec5SDimitry Andric   }
4390b57cec5SDimitry Andric 
4400b57cec5SDimitry Andric private:
4410b57cec5SDimitry Andric   OptionGroupOptions m_option_group;
4420b57cec5SDimitry Andric   OptionGroupArchitecture m_arch_option;
443af732203SDimitry Andric   OptionGroupPlatform m_platform_options;
4440b57cec5SDimitry Andric   OptionGroupFile m_core_file;
4450b57cec5SDimitry Andric   OptionGroupFile m_symbol_file;
4460b57cec5SDimitry Andric   OptionGroupFile m_remote_file;
4470b57cec5SDimitry Andric   OptionGroupDependents m_add_dependents;
4480b57cec5SDimitry Andric };
4490b57cec5SDimitry Andric 
4500b57cec5SDimitry Andric #pragma mark CommandObjectTargetList
4510b57cec5SDimitry Andric 
4520b57cec5SDimitry Andric class CommandObjectTargetList : public CommandObjectParsed {
4530b57cec5SDimitry Andric public:
CommandObjectTargetList(CommandInterpreter & interpreter)4540b57cec5SDimitry Andric   CommandObjectTargetList(CommandInterpreter &interpreter)
4550b57cec5SDimitry Andric       : CommandObjectParsed(
4560b57cec5SDimitry Andric             interpreter, "target list",
4570b57cec5SDimitry Andric             "List all current targets in the current debug session.", nullptr) {
4580b57cec5SDimitry Andric   }
4590b57cec5SDimitry Andric 
4600b57cec5SDimitry Andric   ~CommandObjectTargetList() override = default;
4610b57cec5SDimitry Andric 
4620b57cec5SDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)4630b57cec5SDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
4640b57cec5SDimitry Andric     if (args.GetArgumentCount() == 0) {
4650b57cec5SDimitry Andric       Stream &strm = result.GetOutputStream();
4660b57cec5SDimitry Andric 
4670b57cec5SDimitry Andric       bool show_stopped_process_status = false;
4680b57cec5SDimitry Andric       if (DumpTargetList(GetDebugger().GetTargetList(),
4690b57cec5SDimitry Andric                          show_stopped_process_status, strm) == 0) {
4700b57cec5SDimitry Andric         strm.PutCString("No targets.\n");
4710b57cec5SDimitry Andric       }
4720b57cec5SDimitry Andric       result.SetStatus(eReturnStatusSuccessFinishResult);
4730b57cec5SDimitry Andric     } else {
4740b57cec5SDimitry Andric       result.AppendError("the 'target list' command takes no arguments\n");
4750b57cec5SDimitry Andric     }
4760b57cec5SDimitry Andric     return result.Succeeded();
4770b57cec5SDimitry Andric   }
4780b57cec5SDimitry Andric };
4790b57cec5SDimitry Andric 
4800b57cec5SDimitry Andric #pragma mark CommandObjectTargetSelect
4810b57cec5SDimitry Andric 
4820b57cec5SDimitry Andric class CommandObjectTargetSelect : public CommandObjectParsed {
4830b57cec5SDimitry Andric public:
CommandObjectTargetSelect(CommandInterpreter & interpreter)4840b57cec5SDimitry Andric   CommandObjectTargetSelect(CommandInterpreter &interpreter)
4850b57cec5SDimitry Andric       : CommandObjectParsed(
4860b57cec5SDimitry Andric             interpreter, "target select",
4870b57cec5SDimitry Andric             "Select a target as the current target by target index.", nullptr) {
4880b57cec5SDimitry Andric   }
4890b57cec5SDimitry Andric 
4900b57cec5SDimitry Andric   ~CommandObjectTargetSelect() override = default;
4910b57cec5SDimitry Andric 
4920b57cec5SDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)4930b57cec5SDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
4940b57cec5SDimitry Andric     if (args.GetArgumentCount() == 1) {
4950b57cec5SDimitry Andric       const char *target_idx_arg = args.GetArgumentAtIndex(0);
4965ffd83dbSDimitry Andric       uint32_t target_idx;
4975ffd83dbSDimitry Andric       if (llvm::to_integer(target_idx_arg, target_idx)) {
4980b57cec5SDimitry Andric         TargetList &target_list = GetDebugger().GetTargetList();
4990b57cec5SDimitry Andric         const uint32_t num_targets = target_list.GetNumTargets();
5000b57cec5SDimitry Andric         if (target_idx < num_targets) {
501af732203SDimitry Andric           target_list.SetSelectedTarget(target_idx);
5020b57cec5SDimitry Andric           Stream &strm = result.GetOutputStream();
5030b57cec5SDimitry Andric           bool show_stopped_process_status = false;
5040b57cec5SDimitry Andric           DumpTargetList(target_list, show_stopped_process_status, strm);
5050b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishResult);
5060b57cec5SDimitry Andric         } else {
5070b57cec5SDimitry Andric           if (num_targets > 0) {
5080b57cec5SDimitry Andric             result.AppendErrorWithFormat(
5090b57cec5SDimitry Andric                 "index %u is out of range, valid target indexes are 0 - %u\n",
5100b57cec5SDimitry Andric                 target_idx, num_targets - 1);
5110b57cec5SDimitry Andric           } else {
5120b57cec5SDimitry Andric             result.AppendErrorWithFormat(
5130b57cec5SDimitry Andric                 "index %u is out of range since there are no active targets\n",
5140b57cec5SDimitry Andric                 target_idx);
5150b57cec5SDimitry Andric           }
5160b57cec5SDimitry Andric         }
5170b57cec5SDimitry Andric       } else {
5180b57cec5SDimitry Andric         result.AppendErrorWithFormat("invalid index string value '%s'\n",
5190b57cec5SDimitry Andric                                      target_idx_arg);
5200b57cec5SDimitry Andric       }
5210b57cec5SDimitry Andric     } else {
5220b57cec5SDimitry Andric       result.AppendError(
5230b57cec5SDimitry Andric           "'target select' takes a single argument: a target index\n");
5240b57cec5SDimitry Andric     }
5250b57cec5SDimitry Andric     return result.Succeeded();
5260b57cec5SDimitry Andric   }
5270b57cec5SDimitry Andric };
5280b57cec5SDimitry Andric 
5295ffd83dbSDimitry Andric #pragma mark CommandObjectTargetDelete
5300b57cec5SDimitry Andric 
5310b57cec5SDimitry Andric class CommandObjectTargetDelete : public CommandObjectParsed {
5320b57cec5SDimitry Andric public:
CommandObjectTargetDelete(CommandInterpreter & interpreter)5330b57cec5SDimitry Andric   CommandObjectTargetDelete(CommandInterpreter &interpreter)
5340b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "target delete",
5350b57cec5SDimitry Andric                             "Delete one or more targets by target index.",
5360b57cec5SDimitry Andric                             nullptr),
5370b57cec5SDimitry Andric         m_option_group(), m_all_option(LLDB_OPT_SET_1, false, "all", 'a',
5380b57cec5SDimitry Andric                                        "Delete all targets.", false, true),
5390b57cec5SDimitry Andric         m_cleanup_option(
5400b57cec5SDimitry Andric             LLDB_OPT_SET_1, false, "clean", 'c',
5410b57cec5SDimitry Andric             "Perform extra cleanup to minimize memory consumption after "
5420b57cec5SDimitry Andric             "deleting the target.  "
5430b57cec5SDimitry Andric             "By default, LLDB will keep in memory any modules previously "
5440b57cec5SDimitry Andric             "loaded by the target as well "
5450b57cec5SDimitry Andric             "as all of its debug info.  Specifying --clean will unload all of "
5460b57cec5SDimitry Andric             "these shared modules and "
5470b57cec5SDimitry Andric             "cause them to be reparsed again the next time the target is run",
5480b57cec5SDimitry Andric             false, true) {
5490b57cec5SDimitry Andric     m_option_group.Append(&m_all_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
5500b57cec5SDimitry Andric     m_option_group.Append(&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
5510b57cec5SDimitry Andric     m_option_group.Finalize();
5520b57cec5SDimitry Andric   }
5530b57cec5SDimitry Andric 
5540b57cec5SDimitry Andric   ~CommandObjectTargetDelete() override = default;
5550b57cec5SDimitry Andric 
GetOptions()5560b57cec5SDimitry Andric   Options *GetOptions() override { return &m_option_group; }
5570b57cec5SDimitry Andric 
5580b57cec5SDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)5590b57cec5SDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
5600b57cec5SDimitry Andric     const size_t argc = args.GetArgumentCount();
5610b57cec5SDimitry Andric     std::vector<TargetSP> delete_target_list;
5620b57cec5SDimitry Andric     TargetList &target_list = GetDebugger().GetTargetList();
5630b57cec5SDimitry Andric     TargetSP target_sp;
5640b57cec5SDimitry Andric 
5650b57cec5SDimitry Andric     if (m_all_option.GetOptionValue()) {
5660b57cec5SDimitry Andric       for (int i = 0; i < target_list.GetNumTargets(); ++i)
5670b57cec5SDimitry Andric         delete_target_list.push_back(target_list.GetTargetAtIndex(i));
5680b57cec5SDimitry Andric     } else if (argc > 0) {
5690b57cec5SDimitry Andric       const uint32_t num_targets = target_list.GetNumTargets();
5700b57cec5SDimitry Andric       // Bail out if don't have any targets.
5710b57cec5SDimitry Andric       if (num_targets == 0) {
5720b57cec5SDimitry Andric         result.AppendError("no targets to delete");
5730b57cec5SDimitry Andric         return false;
5740b57cec5SDimitry Andric       }
5750b57cec5SDimitry Andric 
5760b57cec5SDimitry Andric       for (auto &entry : args.entries()) {
5770b57cec5SDimitry Andric         uint32_t target_idx;
5789dba64beSDimitry Andric         if (entry.ref().getAsInteger(0, target_idx)) {
5790b57cec5SDimitry Andric           result.AppendErrorWithFormat("invalid target index '%s'\n",
5800b57cec5SDimitry Andric                                        entry.c_str());
5810b57cec5SDimitry Andric           return false;
5820b57cec5SDimitry Andric         }
5830b57cec5SDimitry Andric         if (target_idx < num_targets) {
5840b57cec5SDimitry Andric           target_sp = target_list.GetTargetAtIndex(target_idx);
5850b57cec5SDimitry Andric           if (target_sp) {
5860b57cec5SDimitry Andric             delete_target_list.push_back(target_sp);
5870b57cec5SDimitry Andric             continue;
5880b57cec5SDimitry Andric           }
5890b57cec5SDimitry Andric         }
5900b57cec5SDimitry Andric         if (num_targets > 1)
5910b57cec5SDimitry Andric           result.AppendErrorWithFormat("target index %u is out of range, valid "
5920b57cec5SDimitry Andric                                        "target indexes are 0 - %u\n",
5930b57cec5SDimitry Andric                                        target_idx, num_targets - 1);
5940b57cec5SDimitry Andric         else
5950b57cec5SDimitry Andric           result.AppendErrorWithFormat(
5960b57cec5SDimitry Andric               "target index %u is out of range, the only valid index is 0\n",
5970b57cec5SDimitry Andric               target_idx);
5980b57cec5SDimitry Andric 
5990b57cec5SDimitry Andric         return false;
6000b57cec5SDimitry Andric       }
6010b57cec5SDimitry Andric     } else {
6020b57cec5SDimitry Andric       target_sp = target_list.GetSelectedTarget();
6030b57cec5SDimitry Andric       if (!target_sp) {
6040b57cec5SDimitry Andric         result.AppendErrorWithFormat("no target is currently selected\n");
6050b57cec5SDimitry Andric         return false;
6060b57cec5SDimitry Andric       }
6070b57cec5SDimitry Andric       delete_target_list.push_back(target_sp);
6080b57cec5SDimitry Andric     }
6090b57cec5SDimitry Andric 
6100b57cec5SDimitry Andric     const size_t num_targets_to_delete = delete_target_list.size();
6110b57cec5SDimitry Andric     for (size_t idx = 0; idx < num_targets_to_delete; ++idx) {
6120b57cec5SDimitry Andric       target_sp = delete_target_list[idx];
6130b57cec5SDimitry Andric       target_list.DeleteTarget(target_sp);
6140b57cec5SDimitry Andric       target_sp->Destroy();
6150b57cec5SDimitry Andric     }
6160b57cec5SDimitry Andric     // If "--clean" was specified, prune any orphaned shared modules from the
6170b57cec5SDimitry Andric     // global shared module list
6180b57cec5SDimitry Andric     if (m_cleanup_option.GetOptionValue()) {
6190b57cec5SDimitry Andric       const bool mandatory = true;
6200b57cec5SDimitry Andric       ModuleList::RemoveOrphanSharedModules(mandatory);
6210b57cec5SDimitry Andric     }
6220b57cec5SDimitry Andric     result.GetOutputStream().Printf("%u targets deleted.\n",
6230b57cec5SDimitry Andric                                     (uint32_t)num_targets_to_delete);
6240b57cec5SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishResult);
6250b57cec5SDimitry Andric 
6260b57cec5SDimitry Andric     return true;
6270b57cec5SDimitry Andric   }
6280b57cec5SDimitry Andric 
6290b57cec5SDimitry Andric   OptionGroupOptions m_option_group;
6300b57cec5SDimitry Andric   OptionGroupBoolean m_all_option;
6310b57cec5SDimitry Andric   OptionGroupBoolean m_cleanup_option;
6320b57cec5SDimitry Andric };
6330b57cec5SDimitry Andric 
6345ffd83dbSDimitry Andric class CommandObjectTargetShowLaunchEnvironment : public CommandObjectParsed {
6355ffd83dbSDimitry Andric public:
CommandObjectTargetShowLaunchEnvironment(CommandInterpreter & interpreter)6365ffd83dbSDimitry Andric   CommandObjectTargetShowLaunchEnvironment(CommandInterpreter &interpreter)
6375ffd83dbSDimitry Andric       : CommandObjectParsed(
6385ffd83dbSDimitry Andric             interpreter, "target show-launch-environment",
6395ffd83dbSDimitry Andric             "Shows the environment being passed to the process when launched, "
6405ffd83dbSDimitry Andric             "taking info account 3 settings: target.env-vars, "
6415ffd83dbSDimitry Andric             "target.inherit-env and target.unset-env-vars.",
6425ffd83dbSDimitry Andric             nullptr, eCommandRequiresTarget) {}
6435ffd83dbSDimitry Andric 
6445ffd83dbSDimitry Andric   ~CommandObjectTargetShowLaunchEnvironment() override = default;
6455ffd83dbSDimitry Andric 
6465ffd83dbSDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)6475ffd83dbSDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
6485ffd83dbSDimitry Andric     Target *target = m_exe_ctx.GetTargetPtr();
6495ffd83dbSDimitry Andric     Environment env = target->GetEnvironment();
6505ffd83dbSDimitry Andric 
6515ffd83dbSDimitry Andric     std::vector<Environment::value_type *> env_vector;
6525ffd83dbSDimitry Andric     env_vector.reserve(env.size());
6535ffd83dbSDimitry Andric     for (auto &KV : env)
6545ffd83dbSDimitry Andric       env_vector.push_back(&KV);
6555ffd83dbSDimitry Andric     std::sort(env_vector.begin(), env_vector.end(),
6565ffd83dbSDimitry Andric               [](Environment::value_type *a, Environment::value_type *b) {
6575ffd83dbSDimitry Andric                 return a->first() < b->first();
6585ffd83dbSDimitry Andric               });
6595ffd83dbSDimitry Andric 
6605ffd83dbSDimitry Andric     auto &strm = result.GetOutputStream();
6615ffd83dbSDimitry Andric     for (auto &KV : env_vector)
6625ffd83dbSDimitry Andric       strm.Format("{0}={1}\n", KV->first(), KV->second);
6635ffd83dbSDimitry Andric 
6645ffd83dbSDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishResult);
6655ffd83dbSDimitry Andric     return result.Succeeded();
6665ffd83dbSDimitry Andric   }
6675ffd83dbSDimitry Andric };
6685ffd83dbSDimitry Andric 
6690b57cec5SDimitry Andric #pragma mark CommandObjectTargetVariable
6700b57cec5SDimitry Andric 
6710b57cec5SDimitry Andric class CommandObjectTargetVariable : public CommandObjectParsed {
6720b57cec5SDimitry Andric   static const uint32_t SHORT_OPTION_FILE = 0x66696c65; // 'file'
6730b57cec5SDimitry Andric   static const uint32_t SHORT_OPTION_SHLB = 0x73686c62; // 'shlb'
6740b57cec5SDimitry Andric 
6750b57cec5SDimitry Andric public:
CommandObjectTargetVariable(CommandInterpreter & interpreter)6760b57cec5SDimitry Andric   CommandObjectTargetVariable(CommandInterpreter &interpreter)
6770b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "target variable",
6780b57cec5SDimitry Andric                             "Read global variables for the current target, "
6790b57cec5SDimitry Andric                             "before or while running a process.",
6800b57cec5SDimitry Andric                             nullptr, eCommandRequiresTarget),
6810b57cec5SDimitry Andric         m_option_group(),
6820b57cec5SDimitry Andric         m_option_variable(false), // Don't include frame options
6830b57cec5SDimitry Andric         m_option_format(eFormatDefault),
6840b57cec5SDimitry Andric         m_option_compile_units(LLDB_OPT_SET_1, false, "file", SHORT_OPTION_FILE,
6850b57cec5SDimitry Andric                                0, eArgTypeFilename,
6860b57cec5SDimitry Andric                                "A basename or fullpath to a file that contains "
6870b57cec5SDimitry Andric                                "global variables. This option can be "
6880b57cec5SDimitry Andric                                "specified multiple times."),
6890b57cec5SDimitry Andric         m_option_shared_libraries(
6900b57cec5SDimitry Andric             LLDB_OPT_SET_1, false, "shlib", SHORT_OPTION_SHLB, 0,
6910b57cec5SDimitry Andric             eArgTypeFilename,
6920b57cec5SDimitry Andric             "A basename or fullpath to a shared library to use in the search "
6930b57cec5SDimitry Andric             "for global "
6940b57cec5SDimitry Andric             "variables. This option can be specified multiple times."),
6950b57cec5SDimitry Andric         m_varobj_options() {
6960b57cec5SDimitry Andric     CommandArgumentEntry arg;
6970b57cec5SDimitry Andric     CommandArgumentData var_name_arg;
6980b57cec5SDimitry Andric 
6990b57cec5SDimitry Andric     // Define the first (and only) variant of this arg.
7000b57cec5SDimitry Andric     var_name_arg.arg_type = eArgTypeVarName;
7010b57cec5SDimitry Andric     var_name_arg.arg_repetition = eArgRepeatPlus;
7020b57cec5SDimitry Andric 
7030b57cec5SDimitry Andric     // There is only one variant this argument could be; put it into the
7040b57cec5SDimitry Andric     // argument entry.
7050b57cec5SDimitry Andric     arg.push_back(var_name_arg);
7060b57cec5SDimitry Andric 
7070b57cec5SDimitry Andric     // Push the data for the first argument into the m_arguments vector.
7080b57cec5SDimitry Andric     m_arguments.push_back(arg);
7090b57cec5SDimitry Andric 
7100b57cec5SDimitry Andric     m_option_group.Append(&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
7110b57cec5SDimitry Andric     m_option_group.Append(&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
7120b57cec5SDimitry Andric     m_option_group.Append(&m_option_format,
7130b57cec5SDimitry Andric                           OptionGroupFormat::OPTION_GROUP_FORMAT |
7140b57cec5SDimitry Andric                               OptionGroupFormat::OPTION_GROUP_GDB_FMT,
7150b57cec5SDimitry Andric                           LLDB_OPT_SET_1);
7160b57cec5SDimitry Andric     m_option_group.Append(&m_option_compile_units, LLDB_OPT_SET_ALL,
7170b57cec5SDimitry Andric                           LLDB_OPT_SET_1);
7180b57cec5SDimitry Andric     m_option_group.Append(&m_option_shared_libraries, LLDB_OPT_SET_ALL,
7190b57cec5SDimitry Andric                           LLDB_OPT_SET_1);
7200b57cec5SDimitry Andric     m_option_group.Finalize();
7210b57cec5SDimitry Andric   }
7220b57cec5SDimitry Andric 
7230b57cec5SDimitry Andric   ~CommandObjectTargetVariable() override = default;
7240b57cec5SDimitry Andric 
DumpValueObject(Stream & s,VariableSP & var_sp,ValueObjectSP & valobj_sp,const char * root_name)7250b57cec5SDimitry Andric   void DumpValueObject(Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp,
7260b57cec5SDimitry Andric                        const char *root_name) {
7270b57cec5SDimitry Andric     DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions());
7280b57cec5SDimitry Andric 
7290b57cec5SDimitry Andric     if (!valobj_sp->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
7300b57cec5SDimitry Andric         valobj_sp->IsRuntimeSupportValue())
7310b57cec5SDimitry Andric       return;
7320b57cec5SDimitry Andric 
7330b57cec5SDimitry Andric     switch (var_sp->GetScope()) {
7340b57cec5SDimitry Andric     case eValueTypeVariableGlobal:
7350b57cec5SDimitry Andric       if (m_option_variable.show_scope)
7360b57cec5SDimitry Andric         s.PutCString("GLOBAL: ");
7370b57cec5SDimitry Andric       break;
7380b57cec5SDimitry Andric 
7390b57cec5SDimitry Andric     case eValueTypeVariableStatic:
7400b57cec5SDimitry Andric       if (m_option_variable.show_scope)
7410b57cec5SDimitry Andric         s.PutCString("STATIC: ");
7420b57cec5SDimitry Andric       break;
7430b57cec5SDimitry Andric 
7440b57cec5SDimitry Andric     case eValueTypeVariableArgument:
7450b57cec5SDimitry Andric       if (m_option_variable.show_scope)
7460b57cec5SDimitry Andric         s.PutCString("   ARG: ");
7470b57cec5SDimitry Andric       break;
7480b57cec5SDimitry Andric 
7490b57cec5SDimitry Andric     case eValueTypeVariableLocal:
7500b57cec5SDimitry Andric       if (m_option_variable.show_scope)
7510b57cec5SDimitry Andric         s.PutCString(" LOCAL: ");
7520b57cec5SDimitry Andric       break;
7530b57cec5SDimitry Andric 
7540b57cec5SDimitry Andric     case eValueTypeVariableThreadLocal:
7550b57cec5SDimitry Andric       if (m_option_variable.show_scope)
7560b57cec5SDimitry Andric         s.PutCString("THREAD: ");
7570b57cec5SDimitry Andric       break;
7580b57cec5SDimitry Andric 
7590b57cec5SDimitry Andric     default:
7600b57cec5SDimitry Andric       break;
7610b57cec5SDimitry Andric     }
7620b57cec5SDimitry Andric 
7630b57cec5SDimitry Andric     if (m_option_variable.show_decl) {
7640b57cec5SDimitry Andric       bool show_fullpaths = false;
7650b57cec5SDimitry Andric       bool show_module = true;
7660b57cec5SDimitry Andric       if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
7670b57cec5SDimitry Andric         s.PutCString(": ");
7680b57cec5SDimitry Andric     }
7690b57cec5SDimitry Andric 
7700b57cec5SDimitry Andric     const Format format = m_option_format.GetFormat();
7710b57cec5SDimitry Andric     if (format != eFormatDefault)
7720b57cec5SDimitry Andric       options.SetFormat(format);
7730b57cec5SDimitry Andric 
7740b57cec5SDimitry Andric     options.SetRootValueObjectName(root_name);
7750b57cec5SDimitry Andric 
7760b57cec5SDimitry Andric     valobj_sp->Dump(s, options);
7770b57cec5SDimitry Andric   }
7780b57cec5SDimitry Andric 
GetVariableCallback(void * baton,const char * name,VariableList & variable_list)7790b57cec5SDimitry Andric   static size_t GetVariableCallback(void *baton, const char *name,
7800b57cec5SDimitry Andric                                     VariableList &variable_list) {
7819dba64beSDimitry Andric     size_t old_size = variable_list.GetSize();
7820b57cec5SDimitry Andric     Target *target = static_cast<Target *>(baton);
7839dba64beSDimitry Andric     if (target)
7849dba64beSDimitry Andric       target->GetImages().FindGlobalVariables(ConstString(name), UINT32_MAX,
7859dba64beSDimitry Andric                                               variable_list);
7869dba64beSDimitry Andric     return variable_list.GetSize() - old_size;
7870b57cec5SDimitry Andric   }
7880b57cec5SDimitry Andric 
GetOptions()7890b57cec5SDimitry Andric   Options *GetOptions() override { return &m_option_group; }
7900b57cec5SDimitry Andric 
7910b57cec5SDimitry Andric protected:
DumpGlobalVariableList(const ExecutionContext & exe_ctx,const SymbolContext & sc,const VariableList & variable_list,Stream & s)7920b57cec5SDimitry Andric   void DumpGlobalVariableList(const ExecutionContext &exe_ctx,
7930b57cec5SDimitry Andric                               const SymbolContext &sc,
7940b57cec5SDimitry Andric                               const VariableList &variable_list, Stream &s) {
795480093f4SDimitry Andric     if (variable_list.Empty())
796480093f4SDimitry Andric       return;
7970b57cec5SDimitry Andric     if (sc.module_sp) {
7980b57cec5SDimitry Andric       if (sc.comp_unit) {
799480093f4SDimitry Andric         s.Format("Global variables for {0} in {1}:\n",
800480093f4SDimitry Andric                  sc.comp_unit->GetPrimaryFile(), sc.module_sp->GetFileSpec());
8010b57cec5SDimitry Andric       } else {
8020b57cec5SDimitry Andric         s.Printf("Global variables for %s\n",
8030b57cec5SDimitry Andric                  sc.module_sp->GetFileSpec().GetPath().c_str());
8040b57cec5SDimitry Andric       }
8050b57cec5SDimitry Andric     } else if (sc.comp_unit) {
806480093f4SDimitry Andric       s.Format("Global variables for {0}\n", sc.comp_unit->GetPrimaryFile());
8070b57cec5SDimitry Andric     }
8080b57cec5SDimitry Andric 
809480093f4SDimitry Andric     for (VariableSP var_sp : variable_list) {
810480093f4SDimitry Andric       if (!var_sp)
811480093f4SDimitry Andric         continue;
8120b57cec5SDimitry Andric       ValueObjectSP valobj_sp(ValueObjectVariable::Create(
8130b57cec5SDimitry Andric           exe_ctx.GetBestExecutionContextScope(), var_sp));
8140b57cec5SDimitry Andric 
8150b57cec5SDimitry Andric       if (valobj_sp)
816480093f4SDimitry Andric         DumpValueObject(s, var_sp, valobj_sp, var_sp->GetName().GetCString());
8170b57cec5SDimitry Andric     }
8180b57cec5SDimitry Andric   }
8190b57cec5SDimitry Andric 
DoExecute(Args & args,CommandReturnObject & result)8200b57cec5SDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
8210b57cec5SDimitry Andric     Target *target = m_exe_ctx.GetTargetPtr();
8220b57cec5SDimitry Andric     const size_t argc = args.GetArgumentCount();
8230b57cec5SDimitry Andric     Stream &s = result.GetOutputStream();
8240b57cec5SDimitry Andric 
8250b57cec5SDimitry Andric     if (argc > 0) {
8265ffd83dbSDimitry Andric       for (const Args::ArgEntry &arg : args) {
8270b57cec5SDimitry Andric         VariableList variable_list;
8280b57cec5SDimitry Andric         ValueObjectList valobj_list;
8290b57cec5SDimitry Andric 
8300b57cec5SDimitry Andric         size_t matches = 0;
8310b57cec5SDimitry Andric         bool use_var_name = false;
8320b57cec5SDimitry Andric         if (m_option_variable.use_regex) {
833*5f7ddb14SDimitry Andric           RegularExpression regex(arg.ref());
8340b57cec5SDimitry Andric           if (!regex.IsValid()) {
8350b57cec5SDimitry Andric             result.GetErrorStream().Printf(
8365ffd83dbSDimitry Andric                 "error: invalid regular expression: '%s'\n", arg.c_str());
8370b57cec5SDimitry Andric             return false;
8380b57cec5SDimitry Andric           }
8390b57cec5SDimitry Andric           use_var_name = true;
8409dba64beSDimitry Andric           target->GetImages().FindGlobalVariables(regex, UINT32_MAX,
8410b57cec5SDimitry Andric                                                   variable_list);
8429dba64beSDimitry Andric           matches = variable_list.GetSize();
8430b57cec5SDimitry Andric         } else {
8440b57cec5SDimitry Andric           Status error(Variable::GetValuesForVariableExpressionPath(
8455ffd83dbSDimitry Andric               arg.c_str(), m_exe_ctx.GetBestExecutionContextScope(),
8460b57cec5SDimitry Andric               GetVariableCallback, target, variable_list, valobj_list));
8470b57cec5SDimitry Andric           matches = variable_list.GetSize();
8480b57cec5SDimitry Andric         }
8490b57cec5SDimitry Andric 
8500b57cec5SDimitry Andric         if (matches == 0) {
851*5f7ddb14SDimitry Andric           result.AppendErrorWithFormat("can't find global variable '%s'",
852*5f7ddb14SDimitry Andric                                        arg.c_str());
8530b57cec5SDimitry Andric           return false;
8540b57cec5SDimitry Andric         } else {
8550b57cec5SDimitry Andric           for (uint32_t global_idx = 0; global_idx < matches; ++global_idx) {
8560b57cec5SDimitry Andric             VariableSP var_sp(variable_list.GetVariableAtIndex(global_idx));
8570b57cec5SDimitry Andric             if (var_sp) {
8580b57cec5SDimitry Andric               ValueObjectSP valobj_sp(
8590b57cec5SDimitry Andric                   valobj_list.GetValueObjectAtIndex(global_idx));
8600b57cec5SDimitry Andric               if (!valobj_sp)
8610b57cec5SDimitry Andric                 valobj_sp = ValueObjectVariable::Create(
8620b57cec5SDimitry Andric                     m_exe_ctx.GetBestExecutionContextScope(), var_sp);
8630b57cec5SDimitry Andric 
8640b57cec5SDimitry Andric               if (valobj_sp)
8650b57cec5SDimitry Andric                 DumpValueObject(s, var_sp, valobj_sp,
8660b57cec5SDimitry Andric                                 use_var_name ? var_sp->GetName().GetCString()
8675ffd83dbSDimitry Andric                                              : arg.c_str());
8680b57cec5SDimitry Andric             }
8690b57cec5SDimitry Andric           }
8700b57cec5SDimitry Andric         }
8710b57cec5SDimitry Andric       }
8720b57cec5SDimitry Andric     } else {
8730b57cec5SDimitry Andric       const FileSpecList &compile_units =
8740b57cec5SDimitry Andric           m_option_compile_units.GetOptionValue().GetCurrentValue();
8750b57cec5SDimitry Andric       const FileSpecList &shlibs =
8760b57cec5SDimitry Andric           m_option_shared_libraries.GetOptionValue().GetCurrentValue();
8770b57cec5SDimitry Andric       SymbolContextList sc_list;
8780b57cec5SDimitry Andric       const size_t num_compile_units = compile_units.GetSize();
8790b57cec5SDimitry Andric       const size_t num_shlibs = shlibs.GetSize();
8800b57cec5SDimitry Andric       if (num_compile_units == 0 && num_shlibs == 0) {
8810b57cec5SDimitry Andric         bool success = false;
8820b57cec5SDimitry Andric         StackFrame *frame = m_exe_ctx.GetFramePtr();
8830b57cec5SDimitry Andric         CompileUnit *comp_unit = nullptr;
8840b57cec5SDimitry Andric         if (frame) {
8850b57cec5SDimitry Andric           SymbolContext sc = frame->GetSymbolContext(eSymbolContextCompUnit);
886af732203SDimitry Andric           comp_unit = sc.comp_unit;
8870b57cec5SDimitry Andric           if (sc.comp_unit) {
8880b57cec5SDimitry Andric             const bool can_create = true;
8890b57cec5SDimitry Andric             VariableListSP comp_unit_varlist_sp(
8900b57cec5SDimitry Andric                 sc.comp_unit->GetVariableList(can_create));
8910b57cec5SDimitry Andric             if (comp_unit_varlist_sp) {
8920b57cec5SDimitry Andric               size_t count = comp_unit_varlist_sp->GetSize();
8930b57cec5SDimitry Andric               if (count > 0) {
8940b57cec5SDimitry Andric                 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
8950b57cec5SDimitry Andric                 success = true;
8960b57cec5SDimitry Andric               }
8970b57cec5SDimitry Andric             }
8980b57cec5SDimitry Andric           }
8990b57cec5SDimitry Andric         }
9000b57cec5SDimitry Andric         if (!success) {
9010b57cec5SDimitry Andric           if (frame) {
9020b57cec5SDimitry Andric             if (comp_unit)
903480093f4SDimitry Andric               result.AppendErrorWithFormatv(
904480093f4SDimitry Andric                   "no global variables in current compile unit: {0}\n",
905480093f4SDimitry Andric                   comp_unit->GetPrimaryFile());
9060b57cec5SDimitry Andric             else
9070b57cec5SDimitry Andric               result.AppendErrorWithFormat(
9080b57cec5SDimitry Andric                   "no debug information for frame %u\n",
9090b57cec5SDimitry Andric                   frame->GetFrameIndex());
9100b57cec5SDimitry Andric           } else
9110b57cec5SDimitry Andric             result.AppendError("'target variable' takes one or more global "
9120b57cec5SDimitry Andric                                "variable names as arguments\n");
9130b57cec5SDimitry Andric         }
9140b57cec5SDimitry Andric       } else {
9150b57cec5SDimitry Andric         SymbolContextList sc_list;
9160b57cec5SDimitry Andric         // We have one or more compile unit or shlib
9170b57cec5SDimitry Andric         if (num_shlibs > 0) {
9180b57cec5SDimitry Andric           for (size_t shlib_idx = 0; shlib_idx < num_shlibs; ++shlib_idx) {
9190b57cec5SDimitry Andric             const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx));
9200b57cec5SDimitry Andric             ModuleSpec module_spec(module_file);
9210b57cec5SDimitry Andric 
9220b57cec5SDimitry Andric             ModuleSP module_sp(
9230b57cec5SDimitry Andric                 target->GetImages().FindFirstModule(module_spec));
9240b57cec5SDimitry Andric             if (module_sp) {
9250b57cec5SDimitry Andric               if (num_compile_units > 0) {
9260b57cec5SDimitry Andric                 for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
9270b57cec5SDimitry Andric                   module_sp->FindCompileUnits(
9289dba64beSDimitry Andric                       compile_units.GetFileSpecAtIndex(cu_idx), sc_list);
9290b57cec5SDimitry Andric               } else {
9300b57cec5SDimitry Andric                 SymbolContext sc;
9310b57cec5SDimitry Andric                 sc.module_sp = module_sp;
9320b57cec5SDimitry Andric                 sc_list.Append(sc);
9330b57cec5SDimitry Andric               }
9340b57cec5SDimitry Andric             } else {
9350b57cec5SDimitry Andric               // Didn't find matching shlib/module in target...
9360b57cec5SDimitry Andric               result.AppendErrorWithFormat(
9370b57cec5SDimitry Andric                   "target doesn't contain the specified shared library: %s\n",
9380b57cec5SDimitry Andric                   module_file.GetPath().c_str());
9390b57cec5SDimitry Andric             }
9400b57cec5SDimitry Andric           }
9410b57cec5SDimitry Andric         } else {
9420b57cec5SDimitry Andric           // No shared libraries, we just want to find globals for the compile
9430b57cec5SDimitry Andric           // units files that were specified
9440b57cec5SDimitry Andric           for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
9450b57cec5SDimitry Andric             target->GetImages().FindCompileUnits(
9469dba64beSDimitry Andric                 compile_units.GetFileSpecAtIndex(cu_idx), sc_list);
9470b57cec5SDimitry Andric         }
9480b57cec5SDimitry Andric 
9490b57cec5SDimitry Andric         const uint32_t num_scs = sc_list.GetSize();
9500b57cec5SDimitry Andric         if (num_scs > 0) {
9510b57cec5SDimitry Andric           SymbolContext sc;
9520b57cec5SDimitry Andric           for (uint32_t sc_idx = 0; sc_idx < num_scs; ++sc_idx) {
9530b57cec5SDimitry Andric             if (sc_list.GetContextAtIndex(sc_idx, sc)) {
9540b57cec5SDimitry Andric               if (sc.comp_unit) {
9550b57cec5SDimitry Andric                 const bool can_create = true;
9560b57cec5SDimitry Andric                 VariableListSP comp_unit_varlist_sp(
9570b57cec5SDimitry Andric                     sc.comp_unit->GetVariableList(can_create));
9580b57cec5SDimitry Andric                 if (comp_unit_varlist_sp)
9590b57cec5SDimitry Andric                   DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp,
9600b57cec5SDimitry Andric                                          s);
9610b57cec5SDimitry Andric               } else if (sc.module_sp) {
9620b57cec5SDimitry Andric                 // Get all global variables for this module
9630b57cec5SDimitry Andric                 lldb_private::RegularExpression all_globals_regex(
9640b57cec5SDimitry Andric                     llvm::StringRef(
9650b57cec5SDimitry Andric                         ".")); // Any global with at least one character
9660b57cec5SDimitry Andric                 VariableList variable_list;
9670b57cec5SDimitry Andric                 sc.module_sp->FindGlobalVariables(all_globals_regex, UINT32_MAX,
9680b57cec5SDimitry Andric                                                   variable_list);
9690b57cec5SDimitry Andric                 DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s);
9700b57cec5SDimitry Andric               }
9710b57cec5SDimitry Andric             }
9720b57cec5SDimitry Andric           }
9730b57cec5SDimitry Andric         }
9740b57cec5SDimitry Andric       }
9750b57cec5SDimitry Andric     }
9760b57cec5SDimitry Andric 
9770b57cec5SDimitry Andric     if (m_interpreter.TruncationWarningNecessary()) {
9780b57cec5SDimitry Andric       result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(),
9790b57cec5SDimitry Andric                                       m_cmd_name.c_str());
9800b57cec5SDimitry Andric       m_interpreter.TruncationWarningGiven();
9810b57cec5SDimitry Andric     }
9820b57cec5SDimitry Andric 
9830b57cec5SDimitry Andric     return result.Succeeded();
9840b57cec5SDimitry Andric   }
9850b57cec5SDimitry Andric 
9860b57cec5SDimitry Andric   OptionGroupOptions m_option_group;
9870b57cec5SDimitry Andric   OptionGroupVariable m_option_variable;
9880b57cec5SDimitry Andric   OptionGroupFormat m_option_format;
9890b57cec5SDimitry Andric   OptionGroupFileList m_option_compile_units;
9900b57cec5SDimitry Andric   OptionGroupFileList m_option_shared_libraries;
9910b57cec5SDimitry Andric   OptionGroupValueObjectDisplay m_varobj_options;
9920b57cec5SDimitry Andric };
9930b57cec5SDimitry Andric 
9940b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesSearchPathsAdd
9950b57cec5SDimitry Andric 
9960b57cec5SDimitry Andric class CommandObjectTargetModulesSearchPathsAdd : public CommandObjectParsed {
9970b57cec5SDimitry Andric public:
CommandObjectTargetModulesSearchPathsAdd(CommandInterpreter & interpreter)9980b57cec5SDimitry Andric   CommandObjectTargetModulesSearchPathsAdd(CommandInterpreter &interpreter)
9990b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "target modules search-paths add",
10000b57cec5SDimitry Andric                             "Add new image search paths substitution pairs to "
10010b57cec5SDimitry Andric                             "the current target.",
10029dba64beSDimitry Andric                             nullptr, eCommandRequiresTarget) {
10030b57cec5SDimitry Andric     CommandArgumentEntry arg;
10040b57cec5SDimitry Andric     CommandArgumentData old_prefix_arg;
10050b57cec5SDimitry Andric     CommandArgumentData new_prefix_arg;
10060b57cec5SDimitry Andric 
10070b57cec5SDimitry Andric     // Define the first variant of this arg pair.
10080b57cec5SDimitry Andric     old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
10090b57cec5SDimitry Andric     old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
10100b57cec5SDimitry Andric 
10110b57cec5SDimitry Andric     // Define the first variant of this arg pair.
10120b57cec5SDimitry Andric     new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
10130b57cec5SDimitry Andric     new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
10140b57cec5SDimitry Andric 
10150b57cec5SDimitry Andric     // There are two required arguments that must always occur together, i.e.
10160b57cec5SDimitry Andric     // an argument "pair".  Because they must always occur together, they are
10170b57cec5SDimitry Andric     // treated as two variants of one argument rather than two independent
10180b57cec5SDimitry Andric     // arguments.  Push them both into the first argument position for
10190b57cec5SDimitry Andric     // m_arguments...
10200b57cec5SDimitry Andric 
10210b57cec5SDimitry Andric     arg.push_back(old_prefix_arg);
10220b57cec5SDimitry Andric     arg.push_back(new_prefix_arg);
10230b57cec5SDimitry Andric 
10240b57cec5SDimitry Andric     m_arguments.push_back(arg);
10250b57cec5SDimitry Andric   }
10260b57cec5SDimitry Andric 
10270b57cec5SDimitry Andric   ~CommandObjectTargetModulesSearchPathsAdd() override = default;
10280b57cec5SDimitry Andric 
10290b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)10300b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
10319dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
10320b57cec5SDimitry Andric     const size_t argc = command.GetArgumentCount();
10330b57cec5SDimitry Andric     if (argc & 1) {
10340b57cec5SDimitry Andric       result.AppendError("add requires an even number of arguments\n");
10350b57cec5SDimitry Andric     } else {
10360b57cec5SDimitry Andric       for (size_t i = 0; i < argc; i += 2) {
10370b57cec5SDimitry Andric         const char *from = command.GetArgumentAtIndex(i);
10380b57cec5SDimitry Andric         const char *to = command.GetArgumentAtIndex(i + 1);
10390b57cec5SDimitry Andric 
10400b57cec5SDimitry Andric         if (from[0] && to[0]) {
10410b57cec5SDimitry Andric           Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
10420b57cec5SDimitry Andric           if (log) {
10439dba64beSDimitry Andric             LLDB_LOGF(log,
10449dba64beSDimitry Andric                       "target modules search path adding ImageSearchPath "
10450b57cec5SDimitry Andric                       "pair: '%s' -> '%s'",
10460b57cec5SDimitry Andric                       from, to);
10470b57cec5SDimitry Andric           }
10480b57cec5SDimitry Andric           bool last_pair = ((argc - i) == 2);
10490b57cec5SDimitry Andric           target->GetImageSearchPathList().Append(
10500b57cec5SDimitry Andric               ConstString(from), ConstString(to),
10510b57cec5SDimitry Andric               last_pair); // Notify if this is the last pair
10520b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishNoResult);
10530b57cec5SDimitry Andric         } else {
10540b57cec5SDimitry Andric           if (from[0])
10550b57cec5SDimitry Andric             result.AppendError("<path-prefix> can't be empty\n");
10560b57cec5SDimitry Andric           else
10570b57cec5SDimitry Andric             result.AppendError("<new-path-prefix> can't be empty\n");
10580b57cec5SDimitry Andric         }
10590b57cec5SDimitry Andric       }
10600b57cec5SDimitry Andric     }
10610b57cec5SDimitry Andric     return result.Succeeded();
10620b57cec5SDimitry Andric   }
10630b57cec5SDimitry Andric };
10640b57cec5SDimitry Andric 
10650b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesSearchPathsClear
10660b57cec5SDimitry Andric 
10670b57cec5SDimitry Andric class CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed {
10680b57cec5SDimitry Andric public:
CommandObjectTargetModulesSearchPathsClear(CommandInterpreter & interpreter)10690b57cec5SDimitry Andric   CommandObjectTargetModulesSearchPathsClear(CommandInterpreter &interpreter)
10700b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "target modules search-paths clear",
10710b57cec5SDimitry Andric                             "Clear all current image search path substitution "
10720b57cec5SDimitry Andric                             "pairs from the current target.",
10739dba64beSDimitry Andric                             "target modules search-paths clear",
10749dba64beSDimitry Andric                             eCommandRequiresTarget) {}
10750b57cec5SDimitry Andric 
10760b57cec5SDimitry Andric   ~CommandObjectTargetModulesSearchPathsClear() override = default;
10770b57cec5SDimitry Andric 
10780b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)10790b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
10809dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
10810b57cec5SDimitry Andric     bool notify = true;
10820b57cec5SDimitry Andric     target->GetImageSearchPathList().Clear(notify);
10830b57cec5SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishNoResult);
10840b57cec5SDimitry Andric     return result.Succeeded();
10850b57cec5SDimitry Andric   }
10860b57cec5SDimitry Andric };
10870b57cec5SDimitry Andric 
10880b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesSearchPathsInsert
10890b57cec5SDimitry Andric 
10900b57cec5SDimitry Andric class CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed {
10910b57cec5SDimitry Andric public:
CommandObjectTargetModulesSearchPathsInsert(CommandInterpreter & interpreter)10920b57cec5SDimitry Andric   CommandObjectTargetModulesSearchPathsInsert(CommandInterpreter &interpreter)
10930b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "target modules search-paths insert",
10940b57cec5SDimitry Andric                             "Insert a new image search path substitution pair "
10950b57cec5SDimitry Andric                             "into the current target at the specified index.",
10969dba64beSDimitry Andric                             nullptr, eCommandRequiresTarget) {
10970b57cec5SDimitry Andric     CommandArgumentEntry arg1;
10980b57cec5SDimitry Andric     CommandArgumentEntry arg2;
10990b57cec5SDimitry Andric     CommandArgumentData index_arg;
11000b57cec5SDimitry Andric     CommandArgumentData old_prefix_arg;
11010b57cec5SDimitry Andric     CommandArgumentData new_prefix_arg;
11020b57cec5SDimitry Andric 
11030b57cec5SDimitry Andric     // Define the first and only variant of this arg.
11040b57cec5SDimitry Andric     index_arg.arg_type = eArgTypeIndex;
11050b57cec5SDimitry Andric     index_arg.arg_repetition = eArgRepeatPlain;
11060b57cec5SDimitry Andric 
11070b57cec5SDimitry Andric     // Put the one and only variant into the first arg for m_arguments:
11080b57cec5SDimitry Andric     arg1.push_back(index_arg);
11090b57cec5SDimitry Andric 
11100b57cec5SDimitry Andric     // Define the first variant of this arg pair.
11110b57cec5SDimitry Andric     old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
11120b57cec5SDimitry Andric     old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
11130b57cec5SDimitry Andric 
11140b57cec5SDimitry Andric     // Define the first variant of this arg pair.
11150b57cec5SDimitry Andric     new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
11160b57cec5SDimitry Andric     new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
11170b57cec5SDimitry Andric 
11180b57cec5SDimitry Andric     // There are two required arguments that must always occur together, i.e.
11190b57cec5SDimitry Andric     // an argument "pair".  Because they must always occur together, they are
11200b57cec5SDimitry Andric     // treated as two variants of one argument rather than two independent
11210b57cec5SDimitry Andric     // arguments.  Push them both into the same argument position for
11220b57cec5SDimitry Andric     // m_arguments...
11230b57cec5SDimitry Andric 
11240b57cec5SDimitry Andric     arg2.push_back(old_prefix_arg);
11250b57cec5SDimitry Andric     arg2.push_back(new_prefix_arg);
11260b57cec5SDimitry Andric 
11270b57cec5SDimitry Andric     // Add arguments to m_arguments.
11280b57cec5SDimitry Andric     m_arguments.push_back(arg1);
11290b57cec5SDimitry Andric     m_arguments.push_back(arg2);
11300b57cec5SDimitry Andric   }
11310b57cec5SDimitry Andric 
11320b57cec5SDimitry Andric   ~CommandObjectTargetModulesSearchPathsInsert() override = default;
11330b57cec5SDimitry Andric 
1134af732203SDimitry Andric   void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)1135af732203SDimitry Andric   HandleArgumentCompletion(CompletionRequest &request,
1136af732203SDimitry Andric                            OptionElementVector &opt_element_vector) override {
1137af732203SDimitry Andric     if (!m_exe_ctx.HasTargetScope() || request.GetCursorIndex() != 0)
1138af732203SDimitry Andric       return;
1139af732203SDimitry Andric 
1140af732203SDimitry Andric     Target *target = m_exe_ctx.GetTargetPtr();
1141af732203SDimitry Andric     const PathMappingList &list = target->GetImageSearchPathList();
1142af732203SDimitry Andric     const size_t num = list.GetSize();
1143af732203SDimitry Andric     ConstString old_path, new_path;
1144af732203SDimitry Andric     for (size_t i = 0; i < num; ++i) {
1145af732203SDimitry Andric       if (!list.GetPathsAtIndex(i, old_path, new_path))
1146af732203SDimitry Andric         break;
1147af732203SDimitry Andric       StreamString strm;
1148af732203SDimitry Andric       strm << old_path << " -> " << new_path;
1149af732203SDimitry Andric       request.TryCompleteCurrentArg(std::to_string(i), strm.GetString());
1150af732203SDimitry Andric     }
1151af732203SDimitry Andric   }
1152af732203SDimitry Andric 
11530b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)11540b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
11559dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
11560b57cec5SDimitry Andric     size_t argc = command.GetArgumentCount();
11570b57cec5SDimitry Andric     // check for at least 3 arguments and an odd number of parameters
11580b57cec5SDimitry Andric     if (argc >= 3 && argc & 1) {
11595ffd83dbSDimitry Andric       uint32_t insert_idx;
11600b57cec5SDimitry Andric 
11615ffd83dbSDimitry Andric       if (!llvm::to_integer(command.GetArgumentAtIndex(0), insert_idx)) {
11620b57cec5SDimitry Andric         result.AppendErrorWithFormat(
11630b57cec5SDimitry Andric             "<index> parameter is not an integer: '%s'.\n",
11640b57cec5SDimitry Andric             command.GetArgumentAtIndex(0));
11650b57cec5SDimitry Andric         return result.Succeeded();
11660b57cec5SDimitry Andric       }
11670b57cec5SDimitry Andric 
11680b57cec5SDimitry Andric       // shift off the index
11690b57cec5SDimitry Andric       command.Shift();
11700b57cec5SDimitry Andric       argc = command.GetArgumentCount();
11710b57cec5SDimitry Andric 
11720b57cec5SDimitry Andric       for (uint32_t i = 0; i < argc; i += 2, ++insert_idx) {
11730b57cec5SDimitry Andric         const char *from = command.GetArgumentAtIndex(i);
11740b57cec5SDimitry Andric         const char *to = command.GetArgumentAtIndex(i + 1);
11750b57cec5SDimitry Andric 
11760b57cec5SDimitry Andric         if (from[0] && to[0]) {
11770b57cec5SDimitry Andric           bool last_pair = ((argc - i) == 2);
11780b57cec5SDimitry Andric           target->GetImageSearchPathList().Insert(
11790b57cec5SDimitry Andric               ConstString(from), ConstString(to), insert_idx, last_pair);
11800b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishNoResult);
11810b57cec5SDimitry Andric         } else {
11820b57cec5SDimitry Andric           if (from[0])
11830b57cec5SDimitry Andric             result.AppendError("<path-prefix> can't be empty\n");
11840b57cec5SDimitry Andric           else
11850b57cec5SDimitry Andric             result.AppendError("<new-path-prefix> can't be empty\n");
11860b57cec5SDimitry Andric           return false;
11870b57cec5SDimitry Andric         }
11880b57cec5SDimitry Andric       }
11890b57cec5SDimitry Andric     } else {
11900b57cec5SDimitry Andric       result.AppendError("insert requires at least three arguments\n");
11910b57cec5SDimitry Andric       return result.Succeeded();
11920b57cec5SDimitry Andric     }
11930b57cec5SDimitry Andric     return result.Succeeded();
11940b57cec5SDimitry Andric   }
11950b57cec5SDimitry Andric };
11960b57cec5SDimitry Andric 
11970b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesSearchPathsList
11980b57cec5SDimitry Andric 
11990b57cec5SDimitry Andric class CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed {
12000b57cec5SDimitry Andric public:
CommandObjectTargetModulesSearchPathsList(CommandInterpreter & interpreter)12010b57cec5SDimitry Andric   CommandObjectTargetModulesSearchPathsList(CommandInterpreter &interpreter)
12020b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "target modules search-paths list",
12030b57cec5SDimitry Andric                             "List all current image search path substitution "
12040b57cec5SDimitry Andric                             "pairs in the current target.",
12059dba64beSDimitry Andric                             "target modules search-paths list",
12069dba64beSDimitry Andric                             eCommandRequiresTarget) {}
12070b57cec5SDimitry Andric 
12080b57cec5SDimitry Andric   ~CommandObjectTargetModulesSearchPathsList() override = default;
12090b57cec5SDimitry Andric 
12100b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)12110b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
12129dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
12130b57cec5SDimitry Andric     if (command.GetArgumentCount() != 0) {
12140b57cec5SDimitry Andric       result.AppendError("list takes no arguments\n");
12150b57cec5SDimitry Andric       return result.Succeeded();
12160b57cec5SDimitry Andric     }
12170b57cec5SDimitry Andric 
12180b57cec5SDimitry Andric     target->GetImageSearchPathList().Dump(&result.GetOutputStream());
12190b57cec5SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishResult);
12200b57cec5SDimitry Andric     return result.Succeeded();
12210b57cec5SDimitry Andric   }
12220b57cec5SDimitry Andric };
12230b57cec5SDimitry Andric 
12240b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesSearchPathsQuery
12250b57cec5SDimitry Andric 
12260b57cec5SDimitry Andric class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed {
12270b57cec5SDimitry Andric public:
CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter & interpreter)12280b57cec5SDimitry Andric   CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter &interpreter)
12290b57cec5SDimitry Andric       : CommandObjectParsed(
12300b57cec5SDimitry Andric             interpreter, "target modules search-paths query",
12310b57cec5SDimitry Andric             "Transform a path using the first applicable image search path.",
12329dba64beSDimitry Andric             nullptr, eCommandRequiresTarget) {
12330b57cec5SDimitry Andric     CommandArgumentEntry arg;
12340b57cec5SDimitry Andric     CommandArgumentData path_arg;
12350b57cec5SDimitry Andric 
12360b57cec5SDimitry Andric     // Define the first (and only) variant of this arg.
12370b57cec5SDimitry Andric     path_arg.arg_type = eArgTypeDirectoryName;
12380b57cec5SDimitry Andric     path_arg.arg_repetition = eArgRepeatPlain;
12390b57cec5SDimitry Andric 
12400b57cec5SDimitry Andric     // There is only one variant this argument could be; put it into the
12410b57cec5SDimitry Andric     // argument entry.
12420b57cec5SDimitry Andric     arg.push_back(path_arg);
12430b57cec5SDimitry Andric 
12440b57cec5SDimitry Andric     // Push the data for the first argument into the m_arguments vector.
12450b57cec5SDimitry Andric     m_arguments.push_back(arg);
12460b57cec5SDimitry Andric   }
12470b57cec5SDimitry Andric 
12480b57cec5SDimitry Andric   ~CommandObjectTargetModulesSearchPathsQuery() override = default;
12490b57cec5SDimitry Andric 
12500b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)12510b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
12529dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
12530b57cec5SDimitry Andric     if (command.GetArgumentCount() != 1) {
12540b57cec5SDimitry Andric       result.AppendError("query requires one argument\n");
12550b57cec5SDimitry Andric       return result.Succeeded();
12560b57cec5SDimitry Andric     }
12570b57cec5SDimitry Andric 
12580b57cec5SDimitry Andric     ConstString orig(command.GetArgumentAtIndex(0));
12590b57cec5SDimitry Andric     ConstString transformed;
12600b57cec5SDimitry Andric     if (target->GetImageSearchPathList().RemapPath(orig, transformed))
12610b57cec5SDimitry Andric       result.GetOutputStream().Printf("%s\n", transformed.GetCString());
12620b57cec5SDimitry Andric     else
12630b57cec5SDimitry Andric       result.GetOutputStream().Printf("%s\n", orig.GetCString());
12640b57cec5SDimitry Andric 
12650b57cec5SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishResult);
12660b57cec5SDimitry Andric     return result.Succeeded();
12670b57cec5SDimitry Andric   }
12680b57cec5SDimitry Andric };
12690b57cec5SDimitry Andric 
12700b57cec5SDimitry Andric // Static Helper functions
DumpModuleArchitecture(Stream & strm,Module * module,bool full_triple,uint32_t width)12710b57cec5SDimitry Andric static void DumpModuleArchitecture(Stream &strm, Module *module,
12720b57cec5SDimitry Andric                                    bool full_triple, uint32_t width) {
12730b57cec5SDimitry Andric   if (module) {
12740b57cec5SDimitry Andric     StreamString arch_strm;
12750b57cec5SDimitry Andric 
12760b57cec5SDimitry Andric     if (full_triple)
1277480093f4SDimitry Andric       module->GetArchitecture().DumpTriple(arch_strm.AsRawOstream());
12780b57cec5SDimitry Andric     else
12790b57cec5SDimitry Andric       arch_strm.PutCString(module->GetArchitecture().GetArchitectureName());
12805ffd83dbSDimitry Andric     std::string arch_str = std::string(arch_strm.GetString());
12810b57cec5SDimitry Andric 
12820b57cec5SDimitry Andric     if (width)
12830b57cec5SDimitry Andric       strm.Printf("%-*s", width, arch_str.c_str());
12840b57cec5SDimitry Andric     else
12850b57cec5SDimitry Andric       strm.PutCString(arch_str);
12860b57cec5SDimitry Andric   }
12870b57cec5SDimitry Andric }
12880b57cec5SDimitry Andric 
DumpModuleUUID(Stream & strm,Module * module)12890b57cec5SDimitry Andric static void DumpModuleUUID(Stream &strm, Module *module) {
12900b57cec5SDimitry Andric   if (module && module->GetUUID().IsValid())
12910b57cec5SDimitry Andric     module->GetUUID().Dump(&strm);
12920b57cec5SDimitry Andric   else
12930b57cec5SDimitry Andric     strm.PutCString("                                    ");
12940b57cec5SDimitry Andric }
12950b57cec5SDimitry Andric 
DumpCompileUnitLineTable(CommandInterpreter & interpreter,Stream & strm,Module * module,const FileSpec & file_spec,lldb::DescriptionLevel desc_level)12960b57cec5SDimitry Andric static uint32_t DumpCompileUnitLineTable(CommandInterpreter &interpreter,
12970b57cec5SDimitry Andric                                          Stream &strm, Module *module,
12980b57cec5SDimitry Andric                                          const FileSpec &file_spec,
12990b57cec5SDimitry Andric                                          lldb::DescriptionLevel desc_level) {
13000b57cec5SDimitry Andric   uint32_t num_matches = 0;
13010b57cec5SDimitry Andric   if (module) {
13020b57cec5SDimitry Andric     SymbolContextList sc_list;
13030b57cec5SDimitry Andric     num_matches = module->ResolveSymbolContextsForFileSpec(
13040b57cec5SDimitry Andric         file_spec, 0, false, eSymbolContextCompUnit, sc_list);
13050b57cec5SDimitry Andric 
13060b57cec5SDimitry Andric     for (uint32_t i = 0; i < num_matches; ++i) {
13070b57cec5SDimitry Andric       SymbolContext sc;
13080b57cec5SDimitry Andric       if (sc_list.GetContextAtIndex(i, sc)) {
13090b57cec5SDimitry Andric         if (i > 0)
13100b57cec5SDimitry Andric           strm << "\n\n";
13110b57cec5SDimitry Andric 
1312480093f4SDimitry Andric         strm << "Line table for " << sc.comp_unit->GetPrimaryFile() << " in `"
1313480093f4SDimitry Andric              << module->GetFileSpec().GetFilename() << "\n";
13140b57cec5SDimitry Andric         LineTable *line_table = sc.comp_unit->GetLineTable();
13150b57cec5SDimitry Andric         if (line_table)
13160b57cec5SDimitry Andric           line_table->GetDescription(
13170b57cec5SDimitry Andric               &strm, interpreter.GetExecutionContext().GetTargetPtr(),
13180b57cec5SDimitry Andric               desc_level);
13190b57cec5SDimitry Andric         else
13200b57cec5SDimitry Andric           strm << "No line table";
13210b57cec5SDimitry Andric       }
13220b57cec5SDimitry Andric     }
13230b57cec5SDimitry Andric   }
13240b57cec5SDimitry Andric   return num_matches;
13250b57cec5SDimitry Andric }
13260b57cec5SDimitry Andric 
DumpFullpath(Stream & strm,const FileSpec * file_spec_ptr,uint32_t width)13270b57cec5SDimitry Andric static void DumpFullpath(Stream &strm, const FileSpec *file_spec_ptr,
13280b57cec5SDimitry Andric                          uint32_t width) {
13290b57cec5SDimitry Andric   if (file_spec_ptr) {
13300b57cec5SDimitry Andric     if (width > 0) {
13310b57cec5SDimitry Andric       std::string fullpath = file_spec_ptr->GetPath();
13320b57cec5SDimitry Andric       strm.Printf("%-*s", width, fullpath.c_str());
13330b57cec5SDimitry Andric       return;
13340b57cec5SDimitry Andric     } else {
1335480093f4SDimitry Andric       file_spec_ptr->Dump(strm.AsRawOstream());
13360b57cec5SDimitry Andric       return;
13370b57cec5SDimitry Andric     }
13380b57cec5SDimitry Andric   }
13390b57cec5SDimitry Andric   // Keep the width spacing correct if things go wrong...
13400b57cec5SDimitry Andric   if (width > 0)
13410b57cec5SDimitry Andric     strm.Printf("%-*s", width, "");
13420b57cec5SDimitry Andric }
13430b57cec5SDimitry Andric 
DumpDirectory(Stream & strm,const FileSpec * file_spec_ptr,uint32_t width)13440b57cec5SDimitry Andric static void DumpDirectory(Stream &strm, const FileSpec *file_spec_ptr,
13450b57cec5SDimitry Andric                           uint32_t width) {
13460b57cec5SDimitry Andric   if (file_spec_ptr) {
13470b57cec5SDimitry Andric     if (width > 0)
13480b57cec5SDimitry Andric       strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
13490b57cec5SDimitry Andric     else
13500b57cec5SDimitry Andric       file_spec_ptr->GetDirectory().Dump(&strm);
13510b57cec5SDimitry Andric     return;
13520b57cec5SDimitry Andric   }
13530b57cec5SDimitry Andric   // Keep the width spacing correct if things go wrong...
13540b57cec5SDimitry Andric   if (width > 0)
13550b57cec5SDimitry Andric     strm.Printf("%-*s", width, "");
13560b57cec5SDimitry Andric }
13570b57cec5SDimitry Andric 
DumpBasename(Stream & strm,const FileSpec * file_spec_ptr,uint32_t width)13580b57cec5SDimitry Andric static void DumpBasename(Stream &strm, const FileSpec *file_spec_ptr,
13590b57cec5SDimitry Andric                          uint32_t width) {
13600b57cec5SDimitry Andric   if (file_spec_ptr) {
13610b57cec5SDimitry Andric     if (width > 0)
13620b57cec5SDimitry Andric       strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
13630b57cec5SDimitry Andric     else
13640b57cec5SDimitry Andric       file_spec_ptr->GetFilename().Dump(&strm);
13650b57cec5SDimitry Andric     return;
13660b57cec5SDimitry Andric   }
13670b57cec5SDimitry Andric   // Keep the width spacing correct if things go wrong...
13680b57cec5SDimitry Andric   if (width > 0)
13690b57cec5SDimitry Andric     strm.Printf("%-*s", width, "");
13700b57cec5SDimitry Andric }
13710b57cec5SDimitry Andric 
DumpModuleObjfileHeaders(Stream & strm,ModuleList & module_list)13720b57cec5SDimitry Andric static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) {
13730b57cec5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
13740b57cec5SDimitry Andric   const size_t num_modules = module_list.GetSize();
1375af732203SDimitry Andric   if (num_modules == 0)
1376af732203SDimitry Andric     return 0;
1377af732203SDimitry Andric 
1378af732203SDimitry Andric   size_t num_dumped = 0;
1379af732203SDimitry Andric   strm.Format("Dumping headers for {0} module(s).\n", num_modules);
13800b57cec5SDimitry Andric   strm.IndentMore();
1381af732203SDimitry Andric   for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
1382af732203SDimitry Andric     if (module_sp) {
13830b57cec5SDimitry Andric       if (num_dumped++ > 0) {
13840b57cec5SDimitry Andric         strm.EOL();
13850b57cec5SDimitry Andric         strm.EOL();
13860b57cec5SDimitry Andric       }
1387af732203SDimitry Andric       ObjectFile *objfile = module_sp->GetObjectFile();
13880b57cec5SDimitry Andric       if (objfile)
13890b57cec5SDimitry Andric         objfile->Dump(&strm);
13900b57cec5SDimitry Andric       else {
13910b57cec5SDimitry Andric         strm.Format("No object file for module: {0:F}\n",
1392af732203SDimitry Andric                     module_sp->GetFileSpec());
13930b57cec5SDimitry Andric       }
13940b57cec5SDimitry Andric     }
13950b57cec5SDimitry Andric   }
13960b57cec5SDimitry Andric   strm.IndentLess();
13970b57cec5SDimitry Andric   return num_dumped;
13980b57cec5SDimitry Andric }
13990b57cec5SDimitry Andric 
DumpModuleSymtab(CommandInterpreter & interpreter,Stream & strm,Module * module,SortOrder sort_order,Mangled::NamePreference name_preference)14000b57cec5SDimitry Andric static void DumpModuleSymtab(CommandInterpreter &interpreter, Stream &strm,
1401480093f4SDimitry Andric                              Module *module, SortOrder sort_order,
1402480093f4SDimitry Andric                              Mangled::NamePreference name_preference) {
14039dba64beSDimitry Andric   if (!module)
14049dba64beSDimitry Andric     return;
14059dba64beSDimitry Andric   if (Symtab *symtab = module->GetSymtab())
14060b57cec5SDimitry Andric     symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(),
1407480093f4SDimitry Andric                  sort_order, name_preference);
14080b57cec5SDimitry Andric }
14090b57cec5SDimitry Andric 
DumpModuleSections(CommandInterpreter & interpreter,Stream & strm,Module * module)14100b57cec5SDimitry Andric static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm,
14110b57cec5SDimitry Andric                                Module *module) {
14120b57cec5SDimitry Andric   if (module) {
14130b57cec5SDimitry Andric     SectionList *section_list = module->GetSectionList();
14140b57cec5SDimitry Andric     if (section_list) {
14150b57cec5SDimitry Andric       strm.Printf("Sections for '%s' (%s):\n",
14160b57cec5SDimitry Andric                   module->GetSpecificationDescription().c_str(),
14170b57cec5SDimitry Andric                   module->GetArchitecture().GetArchitectureName());
14185ffd83dbSDimitry Andric       section_list->Dump(strm.AsRawOstream(), strm.GetIndentLevel() + 2,
14190b57cec5SDimitry Andric                          interpreter.GetExecutionContext().GetTargetPtr(), true,
14200b57cec5SDimitry Andric                          UINT32_MAX);
14210b57cec5SDimitry Andric     }
14220b57cec5SDimitry Andric   }
14230b57cec5SDimitry Andric }
14240b57cec5SDimitry Andric 
DumpModuleSymbolFile(Stream & strm,Module * module)14259dba64beSDimitry Andric static bool DumpModuleSymbolFile(Stream &strm, Module *module) {
14260b57cec5SDimitry Andric   if (module) {
14279dba64beSDimitry Andric     if (SymbolFile *symbol_file = module->GetSymbolFile(true)) {
14289dba64beSDimitry Andric       symbol_file->Dump(strm);
14290b57cec5SDimitry Andric       return true;
14300b57cec5SDimitry Andric     }
14310b57cec5SDimitry Andric   }
14320b57cec5SDimitry Andric   return false;
14330b57cec5SDimitry Andric }
14340b57cec5SDimitry Andric 
DumpAddress(ExecutionContextScope * exe_scope,const Address & so_addr,bool verbose,Stream & strm)14350b57cec5SDimitry Andric static void DumpAddress(ExecutionContextScope *exe_scope,
14360b57cec5SDimitry Andric                         const Address &so_addr, bool verbose, Stream &strm) {
14370b57cec5SDimitry Andric   strm.IndentMore();
14380b57cec5SDimitry Andric   strm.Indent("    Address: ");
14390b57cec5SDimitry Andric   so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
14400b57cec5SDimitry Andric   strm.PutCString(" (");
14410b57cec5SDimitry Andric   so_addr.Dump(&strm, exe_scope, Address::DumpStyleSectionNameOffset);
14420b57cec5SDimitry Andric   strm.PutCString(")\n");
14430b57cec5SDimitry Andric   strm.Indent("    Summary: ");
14440b57cec5SDimitry Andric   const uint32_t save_indent = strm.GetIndentLevel();
14450b57cec5SDimitry Andric   strm.SetIndentLevel(save_indent + 13);
14460b57cec5SDimitry Andric   so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription);
14470b57cec5SDimitry Andric   strm.SetIndentLevel(save_indent);
14480b57cec5SDimitry Andric   // Print out detailed address information when verbose is enabled
14490b57cec5SDimitry Andric   if (verbose) {
14500b57cec5SDimitry Andric     strm.EOL();
14510b57cec5SDimitry Andric     so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext);
14520b57cec5SDimitry Andric   }
14530b57cec5SDimitry Andric   strm.IndentLess();
14540b57cec5SDimitry Andric }
14550b57cec5SDimitry Andric 
LookupAddressInModule(CommandInterpreter & interpreter,Stream & strm,Module * module,uint32_t resolve_mask,lldb::addr_t raw_addr,lldb::addr_t offset,bool verbose)14560b57cec5SDimitry Andric static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm,
14570b57cec5SDimitry Andric                                   Module *module, uint32_t resolve_mask,
14580b57cec5SDimitry Andric                                   lldb::addr_t raw_addr, lldb::addr_t offset,
14590b57cec5SDimitry Andric                                   bool verbose) {
14600b57cec5SDimitry Andric   if (module) {
14610b57cec5SDimitry Andric     lldb::addr_t addr = raw_addr - offset;
14620b57cec5SDimitry Andric     Address so_addr;
14630b57cec5SDimitry Andric     SymbolContext sc;
14640b57cec5SDimitry Andric     Target *target = interpreter.GetExecutionContext().GetTargetPtr();
14650b57cec5SDimitry Andric     if (target && !target->GetSectionLoadList().IsEmpty()) {
14660b57cec5SDimitry Andric       if (!target->GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
14670b57cec5SDimitry Andric         return false;
14680b57cec5SDimitry Andric       else if (so_addr.GetModule().get() != module)
14690b57cec5SDimitry Andric         return false;
14700b57cec5SDimitry Andric     } else {
14710b57cec5SDimitry Andric       if (!module->ResolveFileAddress(addr, so_addr))
14720b57cec5SDimitry Andric         return false;
14730b57cec5SDimitry Andric     }
14740b57cec5SDimitry Andric 
14750b57cec5SDimitry Andric     ExecutionContextScope *exe_scope =
14760b57cec5SDimitry Andric         interpreter.GetExecutionContext().GetBestExecutionContextScope();
14770b57cec5SDimitry Andric     DumpAddress(exe_scope, so_addr, verbose, strm);
14780b57cec5SDimitry Andric     //        strm.IndentMore();
14790b57cec5SDimitry Andric     //        strm.Indent ("    Address: ");
14800b57cec5SDimitry Andric     //        so_addr.Dump (&strm, exe_scope,
14810b57cec5SDimitry Andric     //        Address::DumpStyleModuleWithFileAddress);
14820b57cec5SDimitry Andric     //        strm.PutCString (" (");
14830b57cec5SDimitry Andric     //        so_addr.Dump (&strm, exe_scope,
14840b57cec5SDimitry Andric     //        Address::DumpStyleSectionNameOffset);
14850b57cec5SDimitry Andric     //        strm.PutCString (")\n");
14860b57cec5SDimitry Andric     //        strm.Indent ("    Summary: ");
14870b57cec5SDimitry Andric     //        const uint32_t save_indent = strm.GetIndentLevel ();
14880b57cec5SDimitry Andric     //        strm.SetIndentLevel (save_indent + 13);
14890b57cec5SDimitry Andric     //        so_addr.Dump (&strm, exe_scope,
14900b57cec5SDimitry Andric     //        Address::DumpStyleResolvedDescription);
14910b57cec5SDimitry Andric     //        strm.SetIndentLevel (save_indent);
14920b57cec5SDimitry Andric     //        // Print out detailed address information when verbose is enabled
14930b57cec5SDimitry Andric     //        if (verbose)
14940b57cec5SDimitry Andric     //        {
14950b57cec5SDimitry Andric     //            strm.EOL();
14960b57cec5SDimitry Andric     //            so_addr.Dump (&strm, exe_scope,
14970b57cec5SDimitry Andric     //            Address::DumpStyleDetailedSymbolContext);
14980b57cec5SDimitry Andric     //        }
14990b57cec5SDimitry Andric     //        strm.IndentLess();
15000b57cec5SDimitry Andric     return true;
15010b57cec5SDimitry Andric   }
15020b57cec5SDimitry Andric 
15030b57cec5SDimitry Andric   return false;
15040b57cec5SDimitry Andric }
15050b57cec5SDimitry Andric 
LookupSymbolInModule(CommandInterpreter & interpreter,Stream & strm,Module * module,const char * name,bool name_is_regex,bool verbose)15060b57cec5SDimitry Andric static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
15070b57cec5SDimitry Andric                                      Stream &strm, Module *module,
15080b57cec5SDimitry Andric                                      const char *name, bool name_is_regex,
15090b57cec5SDimitry Andric                                      bool verbose) {
15109dba64beSDimitry Andric   if (!module)
15119dba64beSDimitry Andric     return 0;
15120b57cec5SDimitry Andric 
15139dba64beSDimitry Andric   Symtab *symtab = module->GetSymtab();
15149dba64beSDimitry Andric   if (!symtab)
15159dba64beSDimitry Andric     return 0;
15169dba64beSDimitry Andric 
15179dba64beSDimitry Andric   SymbolContext sc;
15180b57cec5SDimitry Andric   std::vector<uint32_t> match_indexes;
15190b57cec5SDimitry Andric   ConstString symbol_name(name);
15200b57cec5SDimitry Andric   uint32_t num_matches = 0;
15210b57cec5SDimitry Andric   if (name_is_regex) {
15220b57cec5SDimitry Andric     RegularExpression name_regexp(symbol_name.GetStringRef());
15230b57cec5SDimitry Andric     num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType(
15240b57cec5SDimitry Andric         name_regexp, eSymbolTypeAny, match_indexes);
15250b57cec5SDimitry Andric   } else {
15260b57cec5SDimitry Andric     num_matches =
15270b57cec5SDimitry Andric         symtab->AppendSymbolIndexesWithName(symbol_name, match_indexes);
15280b57cec5SDimitry Andric   }
15290b57cec5SDimitry Andric 
15300b57cec5SDimitry Andric   if (num_matches > 0) {
15310b57cec5SDimitry Andric     strm.Indent();
15320b57cec5SDimitry Andric     strm.Printf("%u symbols match %s'%s' in ", num_matches,
15330b57cec5SDimitry Andric                 name_is_regex ? "the regular expression " : "", name);
15340b57cec5SDimitry Andric     DumpFullpath(strm, &module->GetFileSpec(), 0);
15350b57cec5SDimitry Andric     strm.PutCString(":\n");
15360b57cec5SDimitry Andric     strm.IndentMore();
15370b57cec5SDimitry Andric     for (uint32_t i = 0; i < num_matches; ++i) {
15380b57cec5SDimitry Andric       Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
15390b57cec5SDimitry Andric       if (symbol && symbol->ValueIsAddress()) {
15409dba64beSDimitry Andric         DumpAddress(
15419dba64beSDimitry Andric             interpreter.GetExecutionContext().GetBestExecutionContextScope(),
15420b57cec5SDimitry Andric             symbol->GetAddressRef(), verbose, strm);
15430b57cec5SDimitry Andric       }
15440b57cec5SDimitry Andric     }
15450b57cec5SDimitry Andric     strm.IndentLess();
15469dba64beSDimitry Andric   }
15470b57cec5SDimitry Andric   return num_matches;
15480b57cec5SDimitry Andric }
15490b57cec5SDimitry Andric 
DumpSymbolContextList(ExecutionContextScope * exe_scope,Stream & strm,SymbolContextList & sc_list,bool verbose)15500b57cec5SDimitry Andric static void DumpSymbolContextList(ExecutionContextScope *exe_scope,
15510b57cec5SDimitry Andric                                   Stream &strm, SymbolContextList &sc_list,
15520b57cec5SDimitry Andric                                   bool verbose) {
15530b57cec5SDimitry Andric   strm.IndentMore();
15540b57cec5SDimitry Andric 
15550b57cec5SDimitry Andric   const uint32_t num_matches = sc_list.GetSize();
15560b57cec5SDimitry Andric 
15570b57cec5SDimitry Andric   for (uint32_t i = 0; i < num_matches; ++i) {
15580b57cec5SDimitry Andric     SymbolContext sc;
15590b57cec5SDimitry Andric     if (sc_list.GetContextAtIndex(i, sc)) {
15600b57cec5SDimitry Andric       AddressRange range;
15610b57cec5SDimitry Andric 
15620b57cec5SDimitry Andric       sc.GetAddressRange(eSymbolContextEverything, 0, true, range);
15630b57cec5SDimitry Andric 
15640b57cec5SDimitry Andric       DumpAddress(exe_scope, range.GetBaseAddress(), verbose, strm);
15650b57cec5SDimitry Andric     }
15660b57cec5SDimitry Andric   }
15670b57cec5SDimitry Andric   strm.IndentLess();
15680b57cec5SDimitry Andric }
15690b57cec5SDimitry Andric 
LookupFunctionInModule(CommandInterpreter & interpreter,Stream & strm,Module * module,const char * name,bool name_is_regex,bool include_inlines,bool include_symbols,bool verbose)15700b57cec5SDimitry Andric static size_t LookupFunctionInModule(CommandInterpreter &interpreter,
15710b57cec5SDimitry Andric                                      Stream &strm, Module *module,
15720b57cec5SDimitry Andric                                      const char *name, bool name_is_regex,
15730b57cec5SDimitry Andric                                      bool include_inlines, bool include_symbols,
15740b57cec5SDimitry Andric                                      bool verbose) {
15750b57cec5SDimitry Andric   if (module && name && name[0]) {
15760b57cec5SDimitry Andric     SymbolContextList sc_list;
15770b57cec5SDimitry Andric     size_t num_matches = 0;
15780b57cec5SDimitry Andric     if (name_is_regex) {
15790b57cec5SDimitry Andric       RegularExpression function_name_regex((llvm::StringRef(name)));
15809dba64beSDimitry Andric       module->FindFunctions(function_name_regex, include_symbols,
15819dba64beSDimitry Andric                             include_inlines, sc_list);
15820b57cec5SDimitry Andric     } else {
15830b57cec5SDimitry Andric       ConstString function_name(name);
15845ffd83dbSDimitry Andric       module->FindFunctions(function_name, CompilerDeclContext(),
15855ffd83dbSDimitry Andric                             eFunctionNameTypeAuto, include_symbols,
15865ffd83dbSDimitry Andric                             include_inlines, sc_list);
15870b57cec5SDimitry Andric     }
15889dba64beSDimitry Andric     num_matches = sc_list.GetSize();
15890b57cec5SDimitry Andric     if (num_matches) {
15900b57cec5SDimitry Andric       strm.Indent();
15910b57cec5SDimitry Andric       strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
15920b57cec5SDimitry Andric                   num_matches > 1 ? "es" : "");
15930b57cec5SDimitry Andric       DumpFullpath(strm, &module->GetFileSpec(), 0);
15940b57cec5SDimitry Andric       strm.PutCString(":\n");
15950b57cec5SDimitry Andric       DumpSymbolContextList(
15960b57cec5SDimitry Andric           interpreter.GetExecutionContext().GetBestExecutionContextScope(),
15970b57cec5SDimitry Andric           strm, sc_list, verbose);
15980b57cec5SDimitry Andric     }
15990b57cec5SDimitry Andric     return num_matches;
16000b57cec5SDimitry Andric   }
16010b57cec5SDimitry Andric   return 0;
16020b57cec5SDimitry Andric }
16030b57cec5SDimitry Andric 
LookupTypeInModule(Target * target,CommandInterpreter & interpreter,Stream & strm,Module * module,const char * name_cstr,bool name_is_regex)1604af732203SDimitry Andric static size_t LookupTypeInModule(Target *target,
1605af732203SDimitry Andric                                  CommandInterpreter &interpreter, Stream &strm,
16060b57cec5SDimitry Andric                                  Module *module, const char *name_cstr,
16070b57cec5SDimitry Andric                                  bool name_is_regex) {
16080b57cec5SDimitry Andric   TypeList type_list;
16099dba64beSDimitry Andric   if (module && name_cstr && name_cstr[0]) {
16100b57cec5SDimitry Andric     const uint32_t max_num_matches = UINT32_MAX;
16110b57cec5SDimitry Andric     size_t num_matches = 0;
16120b57cec5SDimitry Andric     bool name_is_fully_qualified = false;
16130b57cec5SDimitry Andric 
16140b57cec5SDimitry Andric     ConstString name(name_cstr);
16150b57cec5SDimitry Andric     llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
16160b57cec5SDimitry Andric     module->FindTypes(name, name_is_fully_qualified, max_num_matches,
16170b57cec5SDimitry Andric                       searched_symbol_files, type_list);
16180b57cec5SDimitry Andric 
16199dba64beSDimitry Andric     if (type_list.Empty())
16209dba64beSDimitry Andric       return 0;
16219dba64beSDimitry Andric 
16220b57cec5SDimitry Andric     strm.Indent();
16230b57cec5SDimitry Andric     strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
16240b57cec5SDimitry Andric                 num_matches > 1 ? "es" : "");
16250b57cec5SDimitry Andric     DumpFullpath(strm, &module->GetFileSpec(), 0);
16260b57cec5SDimitry Andric     strm.PutCString(":\n");
16270b57cec5SDimitry Andric     for (TypeSP type_sp : type_list.Types()) {
16289dba64beSDimitry Andric       if (!type_sp)
16299dba64beSDimitry Andric         continue;
16300b57cec5SDimitry Andric       // Resolve the clang type so that any forward references to types
16310b57cec5SDimitry Andric       // that haven't yet been parsed will get parsed.
16320b57cec5SDimitry Andric       type_sp->GetFullCompilerType();
1633af732203SDimitry Andric       type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target);
16340b57cec5SDimitry Andric       // Print all typedef chains
16350b57cec5SDimitry Andric       TypeSP typedef_type_sp(type_sp);
16360b57cec5SDimitry Andric       TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
16370b57cec5SDimitry Andric       while (typedefed_type_sp) {
16380b57cec5SDimitry Andric         strm.EOL();
16390b57cec5SDimitry Andric         strm.Printf("     typedef '%s': ",
16400b57cec5SDimitry Andric                     typedef_type_sp->GetName().GetCString());
16410b57cec5SDimitry Andric         typedefed_type_sp->GetFullCompilerType();
1642af732203SDimitry Andric         typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true,
1643af732203SDimitry Andric                                           target);
16440b57cec5SDimitry Andric         typedef_type_sp = typedefed_type_sp;
16450b57cec5SDimitry Andric         typedefed_type_sp = typedef_type_sp->GetTypedefType();
16460b57cec5SDimitry Andric       }
16470b57cec5SDimitry Andric     }
16480b57cec5SDimitry Andric     strm.EOL();
16490b57cec5SDimitry Andric   }
16509dba64beSDimitry Andric   return type_list.GetSize();
16510b57cec5SDimitry Andric }
16520b57cec5SDimitry Andric 
LookupTypeHere(Target * target,CommandInterpreter & interpreter,Stream & strm,Module & module,const char * name_cstr,bool name_is_regex)1653af732203SDimitry Andric static size_t LookupTypeHere(Target *target, CommandInterpreter &interpreter,
1654af732203SDimitry Andric                              Stream &strm, Module &module,
1655af732203SDimitry Andric                              const char *name_cstr, bool name_is_regex) {
16560b57cec5SDimitry Andric   TypeList type_list;
16570b57cec5SDimitry Andric   const uint32_t max_num_matches = UINT32_MAX;
16580b57cec5SDimitry Andric   bool name_is_fully_qualified = false;
16590b57cec5SDimitry Andric 
16600b57cec5SDimitry Andric   ConstString name(name_cstr);
16610b57cec5SDimitry Andric   llvm::DenseSet<SymbolFile *> searched_symbol_files;
16629dba64beSDimitry Andric   module.FindTypes(name, name_is_fully_qualified, max_num_matches,
16630b57cec5SDimitry Andric                    searched_symbol_files, type_list);
16640b57cec5SDimitry Andric 
16659dba64beSDimitry Andric   if (type_list.Empty())
16669dba64beSDimitry Andric     return 0;
16679dba64beSDimitry Andric 
16680b57cec5SDimitry Andric   strm.Indent();
16690b57cec5SDimitry Andric   strm.PutCString("Best match found in ");
16700b57cec5SDimitry Andric   DumpFullpath(strm, &module.GetFileSpec(), 0);
16710b57cec5SDimitry Andric   strm.PutCString(":\n");
16720b57cec5SDimitry Andric 
16730b57cec5SDimitry Andric   TypeSP type_sp(type_list.GetTypeAtIndex(0));
16740b57cec5SDimitry Andric   if (type_sp) {
16750b57cec5SDimitry Andric     // Resolve the clang type so that any forward references to types that
16760b57cec5SDimitry Andric     // haven't yet been parsed will get parsed.
16770b57cec5SDimitry Andric     type_sp->GetFullCompilerType();
1678af732203SDimitry Andric     type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target);
1679af732203SDimitry Andric     // Print all typedef chains.
16800b57cec5SDimitry Andric     TypeSP typedef_type_sp(type_sp);
16810b57cec5SDimitry Andric     TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
16820b57cec5SDimitry Andric     while (typedefed_type_sp) {
16830b57cec5SDimitry Andric       strm.EOL();
16840b57cec5SDimitry Andric       strm.Printf("     typedef '%s': ",
16850b57cec5SDimitry Andric                   typedef_type_sp->GetName().GetCString());
16860b57cec5SDimitry Andric       typedefed_type_sp->GetFullCompilerType();
1687af732203SDimitry Andric       typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true,
1688af732203SDimitry Andric                                         target);
16890b57cec5SDimitry Andric       typedef_type_sp = typedefed_type_sp;
16900b57cec5SDimitry Andric       typedefed_type_sp = typedef_type_sp->GetTypedefType();
16910b57cec5SDimitry Andric     }
16920b57cec5SDimitry Andric   }
16930b57cec5SDimitry Andric   strm.EOL();
16949dba64beSDimitry Andric   return type_list.GetSize();
16950b57cec5SDimitry Andric }
16960b57cec5SDimitry Andric 
LookupFileAndLineInModule(CommandInterpreter & interpreter,Stream & strm,Module * module,const FileSpec & file_spec,uint32_t line,bool check_inlines,bool verbose)16970b57cec5SDimitry Andric static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter,
16980b57cec5SDimitry Andric                                           Stream &strm, Module *module,
16990b57cec5SDimitry Andric                                           const FileSpec &file_spec,
17000b57cec5SDimitry Andric                                           uint32_t line, bool check_inlines,
17010b57cec5SDimitry Andric                                           bool verbose) {
17020b57cec5SDimitry Andric   if (module && file_spec) {
17030b57cec5SDimitry Andric     SymbolContextList sc_list;
17040b57cec5SDimitry Andric     const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(
17050b57cec5SDimitry Andric         file_spec, line, check_inlines, eSymbolContextEverything, sc_list);
17060b57cec5SDimitry Andric     if (num_matches > 0) {
17070b57cec5SDimitry Andric       strm.Indent();
17080b57cec5SDimitry Andric       strm.Printf("%u match%s found in ", num_matches,
17090b57cec5SDimitry Andric                   num_matches > 1 ? "es" : "");
17100b57cec5SDimitry Andric       strm << file_spec;
17110b57cec5SDimitry Andric       if (line > 0)
17120b57cec5SDimitry Andric         strm.Printf(":%u", line);
17130b57cec5SDimitry Andric       strm << " in ";
17140b57cec5SDimitry Andric       DumpFullpath(strm, &module->GetFileSpec(), 0);
17150b57cec5SDimitry Andric       strm.PutCString(":\n");
17160b57cec5SDimitry Andric       DumpSymbolContextList(
17170b57cec5SDimitry Andric           interpreter.GetExecutionContext().GetBestExecutionContextScope(),
17180b57cec5SDimitry Andric           strm, sc_list, verbose);
17190b57cec5SDimitry Andric       return num_matches;
17200b57cec5SDimitry Andric     }
17210b57cec5SDimitry Andric   }
17220b57cec5SDimitry Andric   return 0;
17230b57cec5SDimitry Andric }
17240b57cec5SDimitry Andric 
FindModulesByName(Target * target,const char * module_name,ModuleList & module_list,bool check_global_list)17250b57cec5SDimitry Andric static size_t FindModulesByName(Target *target, const char *module_name,
17260b57cec5SDimitry Andric                                 ModuleList &module_list,
17270b57cec5SDimitry Andric                                 bool check_global_list) {
17280b57cec5SDimitry Andric   FileSpec module_file_spec(module_name);
17290b57cec5SDimitry Andric   ModuleSpec module_spec(module_file_spec);
17300b57cec5SDimitry Andric 
17310b57cec5SDimitry Andric   const size_t initial_size = module_list.GetSize();
17320b57cec5SDimitry Andric 
17330b57cec5SDimitry Andric   if (check_global_list) {
17340b57cec5SDimitry Andric     // Check the global list
17350b57cec5SDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
17360b57cec5SDimitry Andric         Module::GetAllocationModuleCollectionMutex());
17370b57cec5SDimitry Andric     const size_t num_modules = Module::GetNumberAllocatedModules();
17380b57cec5SDimitry Andric     ModuleSP module_sp;
17390b57cec5SDimitry Andric     for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
17400b57cec5SDimitry Andric       Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
17410b57cec5SDimitry Andric 
17420b57cec5SDimitry Andric       if (module) {
17430b57cec5SDimitry Andric         if (module->MatchesModuleSpec(module_spec)) {
17440b57cec5SDimitry Andric           module_sp = module->shared_from_this();
17450b57cec5SDimitry Andric           module_list.AppendIfNeeded(module_sp);
17460b57cec5SDimitry Andric         }
17470b57cec5SDimitry Andric       }
17480b57cec5SDimitry Andric     }
17490b57cec5SDimitry Andric   } else {
17500b57cec5SDimitry Andric     if (target) {
17510b57cec5SDimitry Andric       target->GetImages().FindModules(module_spec, module_list);
17529dba64beSDimitry Andric       const size_t num_matches = module_list.GetSize();
17530b57cec5SDimitry Andric 
17540b57cec5SDimitry Andric       // Not found in our module list for our target, check the main shared
17550b57cec5SDimitry Andric       // module list in case it is a extra file used somewhere else
17560b57cec5SDimitry Andric       if (num_matches == 0) {
17570b57cec5SDimitry Andric         module_spec.GetArchitecture() = target->GetArchitecture();
17580b57cec5SDimitry Andric         ModuleList::FindSharedModules(module_spec, module_list);
17590b57cec5SDimitry Andric       }
17600b57cec5SDimitry Andric     } else {
17610b57cec5SDimitry Andric       ModuleList::FindSharedModules(module_spec, module_list);
17620b57cec5SDimitry Andric     }
17630b57cec5SDimitry Andric   }
17640b57cec5SDimitry Andric 
17650b57cec5SDimitry Andric   return module_list.GetSize() - initial_size;
17660b57cec5SDimitry Andric }
17670b57cec5SDimitry Andric 
17680b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesModuleAutoComplete
17690b57cec5SDimitry Andric 
17700b57cec5SDimitry Andric // A base command object class that can auto complete with module file
17710b57cec5SDimitry Andric // paths
17720b57cec5SDimitry Andric 
17730b57cec5SDimitry Andric class CommandObjectTargetModulesModuleAutoComplete
17740b57cec5SDimitry Andric     : public CommandObjectParsed {
17750b57cec5SDimitry Andric public:
CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter & interpreter,const char * name,const char * help,const char * syntax,uint32_t flags=0)17760b57cec5SDimitry Andric   CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter &interpreter,
17770b57cec5SDimitry Andric                                                const char *name,
17780b57cec5SDimitry Andric                                                const char *help,
17799dba64beSDimitry Andric                                                const char *syntax,
17809dba64beSDimitry Andric                                                uint32_t flags = 0)
17819dba64beSDimitry Andric       : CommandObjectParsed(interpreter, name, help, syntax, flags) {
17820b57cec5SDimitry Andric     CommandArgumentEntry arg;
17830b57cec5SDimitry Andric     CommandArgumentData file_arg;
17840b57cec5SDimitry Andric 
17850b57cec5SDimitry Andric     // Define the first (and only) variant of this arg.
17860b57cec5SDimitry Andric     file_arg.arg_type = eArgTypeFilename;
17870b57cec5SDimitry Andric     file_arg.arg_repetition = eArgRepeatStar;
17880b57cec5SDimitry Andric 
17890b57cec5SDimitry Andric     // There is only one variant this argument could be; put it into the
17900b57cec5SDimitry Andric     // argument entry.
17910b57cec5SDimitry Andric     arg.push_back(file_arg);
17920b57cec5SDimitry Andric 
17930b57cec5SDimitry Andric     // Push the data for the first argument into the m_arguments vector.
17940b57cec5SDimitry Andric     m_arguments.push_back(arg);
17950b57cec5SDimitry Andric   }
17960b57cec5SDimitry Andric 
17970b57cec5SDimitry Andric   ~CommandObjectTargetModulesModuleAutoComplete() override = default;
17980b57cec5SDimitry Andric 
17999dba64beSDimitry Andric   void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)18009dba64beSDimitry Andric   HandleArgumentCompletion(CompletionRequest &request,
18010b57cec5SDimitry Andric                            OptionElementVector &opt_element_vector) override {
18020b57cec5SDimitry Andric     CommandCompletions::InvokeCommonCompletionCallbacks(
18030b57cec5SDimitry Andric         GetCommandInterpreter(), CommandCompletions::eModuleCompletion, request,
18040b57cec5SDimitry Andric         nullptr);
18050b57cec5SDimitry Andric   }
18060b57cec5SDimitry Andric };
18070b57cec5SDimitry Andric 
18080b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesSourceFileAutoComplete
18090b57cec5SDimitry Andric 
18100b57cec5SDimitry Andric // A base command object class that can auto complete with module source
18110b57cec5SDimitry Andric // file paths
18120b57cec5SDimitry Andric 
18130b57cec5SDimitry Andric class CommandObjectTargetModulesSourceFileAutoComplete
18140b57cec5SDimitry Andric     : public CommandObjectParsed {
18150b57cec5SDimitry Andric public:
CommandObjectTargetModulesSourceFileAutoComplete(CommandInterpreter & interpreter,const char * name,const char * help,const char * syntax,uint32_t flags)18160b57cec5SDimitry Andric   CommandObjectTargetModulesSourceFileAutoComplete(
18170b57cec5SDimitry Andric       CommandInterpreter &interpreter, const char *name, const char *help,
18180b57cec5SDimitry Andric       const char *syntax, uint32_t flags)
18190b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, name, help, syntax, flags) {
18200b57cec5SDimitry Andric     CommandArgumentEntry arg;
18210b57cec5SDimitry Andric     CommandArgumentData source_file_arg;
18220b57cec5SDimitry Andric 
18230b57cec5SDimitry Andric     // Define the first (and only) variant of this arg.
18240b57cec5SDimitry Andric     source_file_arg.arg_type = eArgTypeSourceFile;
18250b57cec5SDimitry Andric     source_file_arg.arg_repetition = eArgRepeatPlus;
18260b57cec5SDimitry Andric 
18270b57cec5SDimitry Andric     // There is only one variant this argument could be; put it into the
18280b57cec5SDimitry Andric     // argument entry.
18290b57cec5SDimitry Andric     arg.push_back(source_file_arg);
18300b57cec5SDimitry Andric 
18310b57cec5SDimitry Andric     // Push the data for the first argument into the m_arguments vector.
18320b57cec5SDimitry Andric     m_arguments.push_back(arg);
18330b57cec5SDimitry Andric   }
18340b57cec5SDimitry Andric 
18350b57cec5SDimitry Andric   ~CommandObjectTargetModulesSourceFileAutoComplete() override = default;
18360b57cec5SDimitry Andric 
18379dba64beSDimitry Andric   void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)18389dba64beSDimitry Andric   HandleArgumentCompletion(CompletionRequest &request,
18390b57cec5SDimitry Andric                            OptionElementVector &opt_element_vector) override {
18400b57cec5SDimitry Andric     CommandCompletions::InvokeCommonCompletionCallbacks(
18410b57cec5SDimitry Andric         GetCommandInterpreter(), CommandCompletions::eSourceFileCompletion,
18420b57cec5SDimitry Andric         request, nullptr);
18430b57cec5SDimitry Andric   }
18440b57cec5SDimitry Andric };
18450b57cec5SDimitry Andric 
18460b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesDumpObjfile
18470b57cec5SDimitry Andric 
18480b57cec5SDimitry Andric class CommandObjectTargetModulesDumpObjfile
18490b57cec5SDimitry Andric     : public CommandObjectTargetModulesModuleAutoComplete {
18500b57cec5SDimitry Andric public:
CommandObjectTargetModulesDumpObjfile(CommandInterpreter & interpreter)18510b57cec5SDimitry Andric   CommandObjectTargetModulesDumpObjfile(CommandInterpreter &interpreter)
18520b57cec5SDimitry Andric       : CommandObjectTargetModulesModuleAutoComplete(
18530b57cec5SDimitry Andric             interpreter, "target modules dump objfile",
18540b57cec5SDimitry Andric             "Dump the object file headers from one or more target modules.",
18559dba64beSDimitry Andric             nullptr, eCommandRequiresTarget) {}
18560b57cec5SDimitry Andric 
18570b57cec5SDimitry Andric   ~CommandObjectTargetModulesDumpObjfile() override = default;
18580b57cec5SDimitry Andric 
18590b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)18600b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
18619dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
18620b57cec5SDimitry Andric 
18630b57cec5SDimitry Andric     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
18640b57cec5SDimitry Andric     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
18650b57cec5SDimitry Andric     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
18660b57cec5SDimitry Andric 
18670b57cec5SDimitry Andric     size_t num_dumped = 0;
18680b57cec5SDimitry Andric     if (command.GetArgumentCount() == 0) {
18690b57cec5SDimitry Andric       // Dump all headers for all modules images
18700b57cec5SDimitry Andric       num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(),
18710b57cec5SDimitry Andric                                             target->GetImages());
18720b57cec5SDimitry Andric       if (num_dumped == 0) {
18730b57cec5SDimitry Andric         result.AppendError("the target has no associated executable images");
18740b57cec5SDimitry Andric       }
18750b57cec5SDimitry Andric     } else {
18760b57cec5SDimitry Andric       // Find the modules that match the basename or full path.
18770b57cec5SDimitry Andric       ModuleList module_list;
18780b57cec5SDimitry Andric       const char *arg_cstr;
18790b57cec5SDimitry Andric       for (int arg_idx = 0;
18800b57cec5SDimitry Andric            (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
18810b57cec5SDimitry Andric            ++arg_idx) {
18820b57cec5SDimitry Andric         size_t num_matched =
18830b57cec5SDimitry Andric             FindModulesByName(target, arg_cstr, module_list, true);
18840b57cec5SDimitry Andric         if (num_matched == 0) {
18850b57cec5SDimitry Andric           result.AppendWarningWithFormat(
18860b57cec5SDimitry Andric               "Unable to find an image that matches '%s'.\n", arg_cstr);
18870b57cec5SDimitry Andric         }
18880b57cec5SDimitry Andric       }
18890b57cec5SDimitry Andric       // Dump all the modules we found.
18900b57cec5SDimitry Andric       num_dumped =
18910b57cec5SDimitry Andric           DumpModuleObjfileHeaders(result.GetOutputStream(), module_list);
18920b57cec5SDimitry Andric     }
18930b57cec5SDimitry Andric 
18940b57cec5SDimitry Andric     if (num_dumped > 0) {
18950b57cec5SDimitry Andric       result.SetStatus(eReturnStatusSuccessFinishResult);
18960b57cec5SDimitry Andric     } else {
18970b57cec5SDimitry Andric       result.AppendError("no matching executable images found");
18980b57cec5SDimitry Andric     }
18990b57cec5SDimitry Andric     return result.Succeeded();
19000b57cec5SDimitry Andric   }
19010b57cec5SDimitry Andric };
19020b57cec5SDimitry Andric 
19030b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesDumpSymtab
19040b57cec5SDimitry Andric 
19050b57cec5SDimitry Andric static constexpr OptionEnumValueElement g_sort_option_enumeration[] = {
19069dba64beSDimitry Andric     {
19079dba64beSDimitry Andric         eSortOrderNone,
19089dba64beSDimitry Andric         "none",
19099dba64beSDimitry Andric         "No sorting, use the original symbol table order.",
19109dba64beSDimitry Andric     },
19119dba64beSDimitry Andric     {
19129dba64beSDimitry Andric         eSortOrderByAddress,
19139dba64beSDimitry Andric         "address",
19149dba64beSDimitry Andric         "Sort output by symbol address.",
19159dba64beSDimitry Andric     },
19169dba64beSDimitry Andric     {
19179dba64beSDimitry Andric         eSortOrderByName,
19189dba64beSDimitry Andric         "name",
19199dba64beSDimitry Andric         "Sort output by symbol name.",
19209dba64beSDimitry Andric     },
19219dba64beSDimitry Andric };
19220b57cec5SDimitry Andric 
19230b57cec5SDimitry Andric #define LLDB_OPTIONS_target_modules_dump_symtab
19240b57cec5SDimitry Andric #include "CommandOptions.inc"
19250b57cec5SDimitry Andric 
19260b57cec5SDimitry Andric class CommandObjectTargetModulesDumpSymtab
19270b57cec5SDimitry Andric     : public CommandObjectTargetModulesModuleAutoComplete {
19280b57cec5SDimitry Andric public:
CommandObjectTargetModulesDumpSymtab(CommandInterpreter & interpreter)19290b57cec5SDimitry Andric   CommandObjectTargetModulesDumpSymtab(CommandInterpreter &interpreter)
19300b57cec5SDimitry Andric       : CommandObjectTargetModulesModuleAutoComplete(
19310b57cec5SDimitry Andric             interpreter, "target modules dump symtab",
19329dba64beSDimitry Andric             "Dump the symbol table from one or more target modules.", nullptr,
19339dba64beSDimitry Andric             eCommandRequiresTarget),
19340b57cec5SDimitry Andric         m_options() {}
19350b57cec5SDimitry Andric 
19360b57cec5SDimitry Andric   ~CommandObjectTargetModulesDumpSymtab() override = default;
19370b57cec5SDimitry Andric 
GetOptions()19380b57cec5SDimitry Andric   Options *GetOptions() override { return &m_options; }
19390b57cec5SDimitry Andric 
19400b57cec5SDimitry Andric   class CommandOptions : public Options {
19410b57cec5SDimitry Andric   public:
CommandOptions()1942*5f7ddb14SDimitry Andric     CommandOptions() : Options() {}
19430b57cec5SDimitry Andric 
19440b57cec5SDimitry Andric     ~CommandOptions() override = default;
19450b57cec5SDimitry Andric 
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)19460b57cec5SDimitry Andric     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
19470b57cec5SDimitry Andric                           ExecutionContext *execution_context) override {
19480b57cec5SDimitry Andric       Status error;
19490b57cec5SDimitry Andric       const int short_option = m_getopt_table[option_idx].val;
19500b57cec5SDimitry Andric 
19510b57cec5SDimitry Andric       switch (short_option) {
1952480093f4SDimitry Andric       case 'm':
1953480093f4SDimitry Andric         m_prefer_mangled.SetCurrentValue(true);
1954480093f4SDimitry Andric         m_prefer_mangled.SetOptionWasSet();
1955480093f4SDimitry Andric         break;
1956480093f4SDimitry Andric 
19570b57cec5SDimitry Andric       case 's':
19580b57cec5SDimitry Andric         m_sort_order = (SortOrder)OptionArgParser::ToOptionEnum(
19590b57cec5SDimitry Andric             option_arg, GetDefinitions()[option_idx].enum_values,
19600b57cec5SDimitry Andric             eSortOrderNone, error);
19610b57cec5SDimitry Andric         break;
19620b57cec5SDimitry Andric 
19630b57cec5SDimitry Andric       default:
19649dba64beSDimitry Andric         llvm_unreachable("Unimplemented option");
19650b57cec5SDimitry Andric       }
19660b57cec5SDimitry Andric       return error;
19670b57cec5SDimitry Andric     }
19680b57cec5SDimitry Andric 
OptionParsingStarting(ExecutionContext * execution_context)19690b57cec5SDimitry Andric     void OptionParsingStarting(ExecutionContext *execution_context) override {
19700b57cec5SDimitry Andric       m_sort_order = eSortOrderNone;
1971480093f4SDimitry Andric       m_prefer_mangled.Clear();
19720b57cec5SDimitry Andric     }
19730b57cec5SDimitry Andric 
GetDefinitions()19740b57cec5SDimitry Andric     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
19750b57cec5SDimitry Andric       return llvm::makeArrayRef(g_target_modules_dump_symtab_options);
19760b57cec5SDimitry Andric     }
19770b57cec5SDimitry Andric 
1978*5f7ddb14SDimitry Andric     SortOrder m_sort_order = eSortOrderNone;
1979480093f4SDimitry Andric     OptionValueBoolean m_prefer_mangled = {false, false};
19800b57cec5SDimitry Andric   };
19810b57cec5SDimitry Andric 
19820b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)19830b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
19849dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
19850b57cec5SDimitry Andric     uint32_t num_dumped = 0;
1986480093f4SDimitry Andric     Mangled::NamePreference name_preference =
1987480093f4SDimitry Andric         (m_options.m_prefer_mangled ? Mangled::ePreferMangled
1988480093f4SDimitry Andric                                     : Mangled::ePreferDemangled);
19890b57cec5SDimitry Andric 
19900b57cec5SDimitry Andric     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
19910b57cec5SDimitry Andric     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
19920b57cec5SDimitry Andric     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
19930b57cec5SDimitry Andric 
19940b57cec5SDimitry Andric     if (command.GetArgumentCount() == 0) {
19950b57cec5SDimitry Andric       // Dump all sections for all modules images
1996af732203SDimitry Andric       const ModuleList &module_list = target->GetImages();
1997af732203SDimitry Andric       std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
1998af732203SDimitry Andric       const size_t num_modules = module_list.GetSize();
19990b57cec5SDimitry Andric       if (num_modules > 0) {
2000af732203SDimitry Andric         result.GetOutputStream().Format(
2001af732203SDimitry Andric             "Dumping symbol table for {0} modules.\n", num_modules);
2002af732203SDimitry Andric         for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
20030b57cec5SDimitry Andric           if (num_dumped > 0) {
20040b57cec5SDimitry Andric             result.GetOutputStream().EOL();
20050b57cec5SDimitry Andric             result.GetOutputStream().EOL();
20060b57cec5SDimitry Andric           }
20070b57cec5SDimitry Andric           if (m_interpreter.WasInterrupted())
20080b57cec5SDimitry Andric             break;
20090b57cec5SDimitry Andric           num_dumped++;
2010af732203SDimitry Andric           DumpModuleSymtab(m_interpreter, result.GetOutputStream(),
2011af732203SDimitry Andric                            module_sp.get(), m_options.m_sort_order,
2012af732203SDimitry Andric                            name_preference);
20130b57cec5SDimitry Andric         }
20140b57cec5SDimitry Andric       } else {
20150b57cec5SDimitry Andric         result.AppendError("the target has no associated executable images");
20160b57cec5SDimitry Andric         return false;
20170b57cec5SDimitry Andric       }
20180b57cec5SDimitry Andric     } else {
20190b57cec5SDimitry Andric       // Dump specified images (by basename or fullpath)
20200b57cec5SDimitry Andric       const char *arg_cstr;
20210b57cec5SDimitry Andric       for (int arg_idx = 0;
20220b57cec5SDimitry Andric            (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
20230b57cec5SDimitry Andric            ++arg_idx) {
20240b57cec5SDimitry Andric         ModuleList module_list;
20250b57cec5SDimitry Andric         const size_t num_matches =
20260b57cec5SDimitry Andric             FindModulesByName(target, arg_cstr, module_list, true);
20270b57cec5SDimitry Andric         if (num_matches > 0) {
2028af732203SDimitry Andric           for (ModuleSP module_sp : module_list.Modules()) {
2029af732203SDimitry Andric             if (module_sp) {
20300b57cec5SDimitry Andric               if (num_dumped > 0) {
20310b57cec5SDimitry Andric                 result.GetOutputStream().EOL();
20320b57cec5SDimitry Andric                 result.GetOutputStream().EOL();
20330b57cec5SDimitry Andric               }
20340b57cec5SDimitry Andric               if (m_interpreter.WasInterrupted())
20350b57cec5SDimitry Andric                 break;
20360b57cec5SDimitry Andric               num_dumped++;
2037af732203SDimitry Andric               DumpModuleSymtab(m_interpreter, result.GetOutputStream(),
2038af732203SDimitry Andric                                module_sp.get(), m_options.m_sort_order,
2039af732203SDimitry Andric                                name_preference);
20400b57cec5SDimitry Andric             }
20410b57cec5SDimitry Andric           }
20420b57cec5SDimitry Andric         } else
20430b57cec5SDimitry Andric           result.AppendWarningWithFormat(
20440b57cec5SDimitry Andric               "Unable to find an image that matches '%s'.\n", arg_cstr);
20450b57cec5SDimitry Andric       }
20460b57cec5SDimitry Andric     }
20470b57cec5SDimitry Andric 
20480b57cec5SDimitry Andric     if (num_dumped > 0)
20490b57cec5SDimitry Andric       result.SetStatus(eReturnStatusSuccessFinishResult);
20500b57cec5SDimitry Andric     else {
20510b57cec5SDimitry Andric       result.AppendError("no matching executable images found");
20520b57cec5SDimitry Andric     }
20530b57cec5SDimitry Andric     return result.Succeeded();
20540b57cec5SDimitry Andric   }
20550b57cec5SDimitry Andric 
20560b57cec5SDimitry Andric   CommandOptions m_options;
20570b57cec5SDimitry Andric };
20580b57cec5SDimitry Andric 
20590b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesDumpSections
20600b57cec5SDimitry Andric 
20610b57cec5SDimitry Andric // Image section dumping command
20620b57cec5SDimitry Andric 
20630b57cec5SDimitry Andric class CommandObjectTargetModulesDumpSections
20640b57cec5SDimitry Andric     : public CommandObjectTargetModulesModuleAutoComplete {
20650b57cec5SDimitry Andric public:
CommandObjectTargetModulesDumpSections(CommandInterpreter & interpreter)20660b57cec5SDimitry Andric   CommandObjectTargetModulesDumpSections(CommandInterpreter &interpreter)
20670b57cec5SDimitry Andric       : CommandObjectTargetModulesModuleAutoComplete(
20680b57cec5SDimitry Andric             interpreter, "target modules dump sections",
20690b57cec5SDimitry Andric             "Dump the sections from one or more target modules.",
20700b57cec5SDimitry Andric             //"target modules dump sections [<file1> ...]")
20719dba64beSDimitry Andric             nullptr, eCommandRequiresTarget) {}
20720b57cec5SDimitry Andric 
20730b57cec5SDimitry Andric   ~CommandObjectTargetModulesDumpSections() override = default;
20740b57cec5SDimitry Andric 
20750b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)20760b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
20779dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
20780b57cec5SDimitry Andric     uint32_t num_dumped = 0;
20790b57cec5SDimitry Andric 
20800b57cec5SDimitry Andric     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
20810b57cec5SDimitry Andric     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
20820b57cec5SDimitry Andric     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
20830b57cec5SDimitry Andric 
20840b57cec5SDimitry Andric     if (command.GetArgumentCount() == 0) {
20850b57cec5SDimitry Andric       // Dump all sections for all modules images
20860b57cec5SDimitry Andric       const size_t num_modules = target->GetImages().GetSize();
2087af732203SDimitry Andric       if (num_modules == 0) {
2088af732203SDimitry Andric         result.AppendError("the target has no associated executable images");
2089af732203SDimitry Andric         return false;
2090af732203SDimitry Andric       }
2091af732203SDimitry Andric 
2092af732203SDimitry Andric       result.GetOutputStream().Format("Dumping sections for {0} modules.\n",
2093af732203SDimitry Andric                                       num_modules);
20940b57cec5SDimitry Andric       for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
20950b57cec5SDimitry Andric         if (m_interpreter.WasInterrupted())
20960b57cec5SDimitry Andric           break;
20970b57cec5SDimitry Andric         num_dumped++;
20980b57cec5SDimitry Andric         DumpModuleSections(
20990b57cec5SDimitry Andric             m_interpreter, result.GetOutputStream(),
21000b57cec5SDimitry Andric             target->GetImages().GetModulePointerAtIndex(image_idx));
21010b57cec5SDimitry Andric       }
21020b57cec5SDimitry Andric     } else {
21030b57cec5SDimitry Andric       // Dump specified images (by basename or fullpath)
21040b57cec5SDimitry Andric       const char *arg_cstr;
21050b57cec5SDimitry Andric       for (int arg_idx = 0;
21060b57cec5SDimitry Andric            (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
21070b57cec5SDimitry Andric            ++arg_idx) {
21080b57cec5SDimitry Andric         ModuleList module_list;
21090b57cec5SDimitry Andric         const size_t num_matches =
21100b57cec5SDimitry Andric             FindModulesByName(target, arg_cstr, module_list, true);
21110b57cec5SDimitry Andric         if (num_matches > 0) {
21120b57cec5SDimitry Andric           for (size_t i = 0; i < num_matches; ++i) {
21130b57cec5SDimitry Andric             if (m_interpreter.WasInterrupted())
21140b57cec5SDimitry Andric               break;
21150b57cec5SDimitry Andric             Module *module = module_list.GetModulePointerAtIndex(i);
21160b57cec5SDimitry Andric             if (module) {
21170b57cec5SDimitry Andric               num_dumped++;
21180b57cec5SDimitry Andric               DumpModuleSections(m_interpreter, result.GetOutputStream(),
21190b57cec5SDimitry Andric                                  module);
21200b57cec5SDimitry Andric             }
21210b57cec5SDimitry Andric           }
21220b57cec5SDimitry Andric         } else {
21230b57cec5SDimitry Andric           // Check the global list
21240b57cec5SDimitry Andric           std::lock_guard<std::recursive_mutex> guard(
21250b57cec5SDimitry Andric               Module::GetAllocationModuleCollectionMutex());
21260b57cec5SDimitry Andric 
21270b57cec5SDimitry Andric           result.AppendWarningWithFormat(
21280b57cec5SDimitry Andric               "Unable to find an image that matches '%s'.\n", arg_cstr);
21290b57cec5SDimitry Andric         }
21300b57cec5SDimitry Andric       }
21310b57cec5SDimitry Andric     }
21320b57cec5SDimitry Andric 
21330b57cec5SDimitry Andric     if (num_dumped > 0)
21340b57cec5SDimitry Andric       result.SetStatus(eReturnStatusSuccessFinishResult);
21350b57cec5SDimitry Andric     else {
21360b57cec5SDimitry Andric       result.AppendError("no matching executable images found");
21370b57cec5SDimitry Andric     }
21380b57cec5SDimitry Andric     return result.Succeeded();
21390b57cec5SDimitry Andric   }
21400b57cec5SDimitry Andric };
21410b57cec5SDimitry Andric 
21425ffd83dbSDimitry Andric #pragma mark CommandObjectTargetModulesDumpClangAST
21430b57cec5SDimitry Andric 
21440b57cec5SDimitry Andric // Clang AST dumping command
21450b57cec5SDimitry Andric 
21460b57cec5SDimitry Andric class CommandObjectTargetModulesDumpClangAST
21470b57cec5SDimitry Andric     : public CommandObjectTargetModulesModuleAutoComplete {
21480b57cec5SDimitry Andric public:
CommandObjectTargetModulesDumpClangAST(CommandInterpreter & interpreter)21490b57cec5SDimitry Andric   CommandObjectTargetModulesDumpClangAST(CommandInterpreter &interpreter)
21500b57cec5SDimitry Andric       : CommandObjectTargetModulesModuleAutoComplete(
21510b57cec5SDimitry Andric             interpreter, "target modules dump ast",
21520b57cec5SDimitry Andric             "Dump the clang ast for a given module's symbol file.",
21530b57cec5SDimitry Andric             //"target modules dump ast [<file1> ...]")
21549dba64beSDimitry Andric             nullptr, eCommandRequiresTarget) {}
21550b57cec5SDimitry Andric 
21560b57cec5SDimitry Andric   ~CommandObjectTargetModulesDumpClangAST() override = default;
21570b57cec5SDimitry Andric 
21580b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)21590b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
21609dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
21610b57cec5SDimitry Andric 
2162af732203SDimitry Andric     const ModuleList &module_list = target->GetImages();
2163af732203SDimitry Andric     const size_t num_modules = module_list.GetSize();
21640b57cec5SDimitry Andric     if (num_modules == 0) {
21650b57cec5SDimitry Andric       result.AppendError("the target has no associated executable images");
21660b57cec5SDimitry Andric       return false;
21670b57cec5SDimitry Andric     }
21680b57cec5SDimitry Andric 
21690b57cec5SDimitry Andric     if (command.GetArgumentCount() == 0) {
21700b57cec5SDimitry Andric       // Dump all ASTs for all modules images
2171af732203SDimitry Andric       result.GetOutputStream().Format("Dumping clang ast for {0} modules.\n",
2172af732203SDimitry Andric                                       num_modules);
2173af732203SDimitry Andric       for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
21740b57cec5SDimitry Andric         if (m_interpreter.WasInterrupted())
21750b57cec5SDimitry Andric           break;
2176af732203SDimitry Andric         if (SymbolFile *sf = module_sp->GetSymbolFile())
21770b57cec5SDimitry Andric           sf->DumpClangAST(result.GetOutputStream());
21780b57cec5SDimitry Andric       }
21790b57cec5SDimitry Andric       result.SetStatus(eReturnStatusSuccessFinishResult);
21800b57cec5SDimitry Andric       return true;
21810b57cec5SDimitry Andric     }
21820b57cec5SDimitry Andric 
21830b57cec5SDimitry Andric     // Dump specified ASTs (by basename or fullpath)
21840b57cec5SDimitry Andric     for (const Args::ArgEntry &arg : command.entries()) {
21850b57cec5SDimitry Andric       ModuleList module_list;
21860b57cec5SDimitry Andric       const size_t num_matches =
21870b57cec5SDimitry Andric           FindModulesByName(target, arg.c_str(), module_list, true);
21880b57cec5SDimitry Andric       if (num_matches == 0) {
21890b57cec5SDimitry Andric         // Check the global list
21900b57cec5SDimitry Andric         std::lock_guard<std::recursive_mutex> guard(
21910b57cec5SDimitry Andric             Module::GetAllocationModuleCollectionMutex());
21920b57cec5SDimitry Andric 
21930b57cec5SDimitry Andric         result.AppendWarningWithFormat(
21940b57cec5SDimitry Andric             "Unable to find an image that matches '%s'.\n", arg.c_str());
21950b57cec5SDimitry Andric         continue;
21960b57cec5SDimitry Andric       }
21970b57cec5SDimitry Andric 
21980b57cec5SDimitry Andric       for (size_t i = 0; i < num_matches; ++i) {
21990b57cec5SDimitry Andric         if (m_interpreter.WasInterrupted())
22000b57cec5SDimitry Andric           break;
22010b57cec5SDimitry Andric         Module *m = module_list.GetModulePointerAtIndex(i);
22029dba64beSDimitry Andric         if (SymbolFile *sf = m->GetSymbolFile())
22030b57cec5SDimitry Andric           sf->DumpClangAST(result.GetOutputStream());
22040b57cec5SDimitry Andric       }
22050b57cec5SDimitry Andric     }
22060b57cec5SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishResult);
22070b57cec5SDimitry Andric     return true;
22080b57cec5SDimitry Andric   }
22090b57cec5SDimitry Andric };
22100b57cec5SDimitry Andric 
22110b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesDumpSymfile
22120b57cec5SDimitry Andric 
22130b57cec5SDimitry Andric // Image debug symbol dumping command
22140b57cec5SDimitry Andric 
22150b57cec5SDimitry Andric class CommandObjectTargetModulesDumpSymfile
22160b57cec5SDimitry Andric     : public CommandObjectTargetModulesModuleAutoComplete {
22170b57cec5SDimitry Andric public:
CommandObjectTargetModulesDumpSymfile(CommandInterpreter & interpreter)22180b57cec5SDimitry Andric   CommandObjectTargetModulesDumpSymfile(CommandInterpreter &interpreter)
22190b57cec5SDimitry Andric       : CommandObjectTargetModulesModuleAutoComplete(
22200b57cec5SDimitry Andric             interpreter, "target modules dump symfile",
22210b57cec5SDimitry Andric             "Dump the debug symbol file for one or more target modules.",
22220b57cec5SDimitry Andric             //"target modules dump symfile [<file1> ...]")
22239dba64beSDimitry Andric             nullptr, eCommandRequiresTarget) {}
22240b57cec5SDimitry Andric 
22250b57cec5SDimitry Andric   ~CommandObjectTargetModulesDumpSymfile() override = default;
22260b57cec5SDimitry Andric 
22270b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)22280b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
22299dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
22300b57cec5SDimitry Andric     uint32_t num_dumped = 0;
22310b57cec5SDimitry Andric 
22320b57cec5SDimitry Andric     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
22330b57cec5SDimitry Andric     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
22340b57cec5SDimitry Andric     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
22350b57cec5SDimitry Andric 
22360b57cec5SDimitry Andric     if (command.GetArgumentCount() == 0) {
22370b57cec5SDimitry Andric       // Dump all sections for all modules images
22380b57cec5SDimitry Andric       const ModuleList &target_modules = target->GetImages();
22390b57cec5SDimitry Andric       std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
22400b57cec5SDimitry Andric       const size_t num_modules = target_modules.GetSize();
2241af732203SDimitry Andric       if (num_modules == 0) {
22420b57cec5SDimitry Andric         result.AppendError("the target has no associated executable images");
22430b57cec5SDimitry Andric         return false;
22440b57cec5SDimitry Andric       }
2245af732203SDimitry Andric       result.GetOutputStream().Format(
2246af732203SDimitry Andric           "Dumping debug symbols for {0} modules.\n", num_modules);
2247af732203SDimitry Andric       for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
2248af732203SDimitry Andric         if (m_interpreter.WasInterrupted())
2249af732203SDimitry Andric           break;
2250af732203SDimitry Andric         if (DumpModuleSymbolFile(result.GetOutputStream(), module_sp.get()))
2251af732203SDimitry Andric           num_dumped++;
2252af732203SDimitry Andric       }
22530b57cec5SDimitry Andric     } else {
22540b57cec5SDimitry Andric       // Dump specified images (by basename or fullpath)
22550b57cec5SDimitry Andric       const char *arg_cstr;
22560b57cec5SDimitry Andric       for (int arg_idx = 0;
22570b57cec5SDimitry Andric            (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
22580b57cec5SDimitry Andric            ++arg_idx) {
22590b57cec5SDimitry Andric         ModuleList module_list;
22600b57cec5SDimitry Andric         const size_t num_matches =
22610b57cec5SDimitry Andric             FindModulesByName(target, arg_cstr, module_list, true);
22620b57cec5SDimitry Andric         if (num_matches > 0) {
22630b57cec5SDimitry Andric           for (size_t i = 0; i < num_matches; ++i) {
22640b57cec5SDimitry Andric             if (m_interpreter.WasInterrupted())
22650b57cec5SDimitry Andric               break;
22660b57cec5SDimitry Andric             Module *module = module_list.GetModulePointerAtIndex(i);
22670b57cec5SDimitry Andric             if (module) {
22689dba64beSDimitry Andric               if (DumpModuleSymbolFile(result.GetOutputStream(), module))
22690b57cec5SDimitry Andric                 num_dumped++;
22700b57cec5SDimitry Andric             }
22710b57cec5SDimitry Andric           }
22720b57cec5SDimitry Andric         } else
22730b57cec5SDimitry Andric           result.AppendWarningWithFormat(
22740b57cec5SDimitry Andric               "Unable to find an image that matches '%s'.\n", arg_cstr);
22750b57cec5SDimitry Andric       }
22760b57cec5SDimitry Andric     }
22770b57cec5SDimitry Andric 
22780b57cec5SDimitry Andric     if (num_dumped > 0)
22790b57cec5SDimitry Andric       result.SetStatus(eReturnStatusSuccessFinishResult);
22800b57cec5SDimitry Andric     else {
22810b57cec5SDimitry Andric       result.AppendError("no matching executable images found");
22820b57cec5SDimitry Andric     }
22830b57cec5SDimitry Andric     return result.Succeeded();
22840b57cec5SDimitry Andric   }
22850b57cec5SDimitry Andric };
22860b57cec5SDimitry Andric 
22870b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesDumpLineTable
22889dba64beSDimitry Andric #define LLDB_OPTIONS_target_modules_dump
22899dba64beSDimitry Andric #include "CommandOptions.inc"
22900b57cec5SDimitry Andric 
22910b57cec5SDimitry Andric // Image debug line table dumping command
22920b57cec5SDimitry Andric 
22930b57cec5SDimitry Andric class CommandObjectTargetModulesDumpLineTable
22940b57cec5SDimitry Andric     : public CommandObjectTargetModulesSourceFileAutoComplete {
22950b57cec5SDimitry Andric public:
CommandObjectTargetModulesDumpLineTable(CommandInterpreter & interpreter)22960b57cec5SDimitry Andric   CommandObjectTargetModulesDumpLineTable(CommandInterpreter &interpreter)
22970b57cec5SDimitry Andric       : CommandObjectTargetModulesSourceFileAutoComplete(
22980b57cec5SDimitry Andric             interpreter, "target modules dump line-table",
22990b57cec5SDimitry Andric             "Dump the line table for one or more compilation units.", nullptr,
23000b57cec5SDimitry Andric             eCommandRequiresTarget) {}
23010b57cec5SDimitry Andric 
23020b57cec5SDimitry Andric   ~CommandObjectTargetModulesDumpLineTable() override = default;
23030b57cec5SDimitry Andric 
GetOptions()23040b57cec5SDimitry Andric   Options *GetOptions() override { return &m_options; }
23050b57cec5SDimitry Andric 
23060b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)23070b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
23080b57cec5SDimitry Andric     Target *target = m_exe_ctx.GetTargetPtr();
23090b57cec5SDimitry Andric     uint32_t total_num_dumped = 0;
23100b57cec5SDimitry Andric 
23110b57cec5SDimitry Andric     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
23120b57cec5SDimitry Andric     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
23130b57cec5SDimitry Andric     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
23140b57cec5SDimitry Andric 
23150b57cec5SDimitry Andric     if (command.GetArgumentCount() == 0) {
23160b57cec5SDimitry Andric       result.AppendError("file option must be specified.");
23170b57cec5SDimitry Andric       return result.Succeeded();
23180b57cec5SDimitry Andric     } else {
23190b57cec5SDimitry Andric       // Dump specified images (by basename or fullpath)
23200b57cec5SDimitry Andric       const char *arg_cstr;
23210b57cec5SDimitry Andric       for (int arg_idx = 0;
23220b57cec5SDimitry Andric            (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
23230b57cec5SDimitry Andric            ++arg_idx) {
23240b57cec5SDimitry Andric         FileSpec file_spec(arg_cstr);
23250b57cec5SDimitry Andric 
23260b57cec5SDimitry Andric         const ModuleList &target_modules = target->GetImages();
23270b57cec5SDimitry Andric         std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2328af732203SDimitry Andric         if (target_modules.GetSize() > 0) {
23290b57cec5SDimitry Andric           uint32_t num_dumped = 0;
2330af732203SDimitry Andric           for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
23310b57cec5SDimitry Andric             if (m_interpreter.WasInterrupted())
23320b57cec5SDimitry Andric               break;
23330b57cec5SDimitry Andric             if (DumpCompileUnitLineTable(
2334af732203SDimitry Andric                     m_interpreter, result.GetOutputStream(), module_sp.get(),
23350b57cec5SDimitry Andric                     file_spec,
23360b57cec5SDimitry Andric                     m_options.m_verbose ? eDescriptionLevelFull
23370b57cec5SDimitry Andric                                         : eDescriptionLevelBrief))
23380b57cec5SDimitry Andric               num_dumped++;
23390b57cec5SDimitry Andric           }
23400b57cec5SDimitry Andric           if (num_dumped == 0)
23410b57cec5SDimitry Andric             result.AppendWarningWithFormat(
23420b57cec5SDimitry Andric                 "No source filenames matched '%s'.\n", arg_cstr);
23430b57cec5SDimitry Andric           else
23440b57cec5SDimitry Andric             total_num_dumped += num_dumped;
23450b57cec5SDimitry Andric         }
23460b57cec5SDimitry Andric       }
23470b57cec5SDimitry Andric     }
23480b57cec5SDimitry Andric 
23490b57cec5SDimitry Andric     if (total_num_dumped > 0)
23500b57cec5SDimitry Andric       result.SetStatus(eReturnStatusSuccessFinishResult);
23510b57cec5SDimitry Andric     else {
23520b57cec5SDimitry Andric       result.AppendError("no source filenames matched any command arguments");
23530b57cec5SDimitry Andric     }
23540b57cec5SDimitry Andric     return result.Succeeded();
23550b57cec5SDimitry Andric   }
23560b57cec5SDimitry Andric 
23570b57cec5SDimitry Andric   class CommandOptions : public Options {
23580b57cec5SDimitry Andric   public:
CommandOptions()23590b57cec5SDimitry Andric     CommandOptions() : Options() { OptionParsingStarting(nullptr); }
23600b57cec5SDimitry Andric 
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)23610b57cec5SDimitry Andric     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
23620b57cec5SDimitry Andric                           ExecutionContext *execution_context) override {
23630b57cec5SDimitry Andric       assert(option_idx == 0 && "We only have one option.");
23640b57cec5SDimitry Andric       m_verbose = true;
23650b57cec5SDimitry Andric 
23660b57cec5SDimitry Andric       return Status();
23670b57cec5SDimitry Andric     }
23680b57cec5SDimitry Andric 
OptionParsingStarting(ExecutionContext * execution_context)23690b57cec5SDimitry Andric     void OptionParsingStarting(ExecutionContext *execution_context) override {
23700b57cec5SDimitry Andric       m_verbose = false;
23710b57cec5SDimitry Andric     }
23720b57cec5SDimitry Andric 
GetDefinitions()23730b57cec5SDimitry Andric     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
23749dba64beSDimitry Andric       return llvm::makeArrayRef(g_target_modules_dump_options);
23750b57cec5SDimitry Andric     }
23760b57cec5SDimitry Andric 
23770b57cec5SDimitry Andric     bool m_verbose;
23780b57cec5SDimitry Andric   };
23790b57cec5SDimitry Andric 
23800b57cec5SDimitry Andric   CommandOptions m_options;
23810b57cec5SDimitry Andric };
23820b57cec5SDimitry Andric 
23830b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesDump
23840b57cec5SDimitry Andric 
23850b57cec5SDimitry Andric // Dump multi-word command for target modules
23860b57cec5SDimitry Andric 
23870b57cec5SDimitry Andric class CommandObjectTargetModulesDump : public CommandObjectMultiword {
23880b57cec5SDimitry Andric public:
23890b57cec5SDimitry Andric   // Constructors and Destructors
CommandObjectTargetModulesDump(CommandInterpreter & interpreter)23900b57cec5SDimitry Andric   CommandObjectTargetModulesDump(CommandInterpreter &interpreter)
23910b57cec5SDimitry Andric       : CommandObjectMultiword(
23920b57cec5SDimitry Andric             interpreter, "target modules dump",
23930b57cec5SDimitry Andric             "Commands for dumping information about one or "
23940b57cec5SDimitry Andric             "more target modules.",
23950b57cec5SDimitry Andric             "target modules dump "
23960b57cec5SDimitry Andric             "[headers|symtab|sections|ast|symfile|line-table] "
23970b57cec5SDimitry Andric             "[<file1> <file2> ...]") {
23980b57cec5SDimitry Andric     LoadSubCommand("objfile",
23990b57cec5SDimitry Andric                    CommandObjectSP(
24000b57cec5SDimitry Andric                        new CommandObjectTargetModulesDumpObjfile(interpreter)));
24010b57cec5SDimitry Andric     LoadSubCommand(
24020b57cec5SDimitry Andric         "symtab",
24030b57cec5SDimitry Andric         CommandObjectSP(new CommandObjectTargetModulesDumpSymtab(interpreter)));
24040b57cec5SDimitry Andric     LoadSubCommand("sections",
24050b57cec5SDimitry Andric                    CommandObjectSP(new CommandObjectTargetModulesDumpSections(
24060b57cec5SDimitry Andric                        interpreter)));
24070b57cec5SDimitry Andric     LoadSubCommand("symfile",
24080b57cec5SDimitry Andric                    CommandObjectSP(
24090b57cec5SDimitry Andric                        new CommandObjectTargetModulesDumpSymfile(interpreter)));
24100b57cec5SDimitry Andric     LoadSubCommand(
24110b57cec5SDimitry Andric         "ast", CommandObjectSP(
24120b57cec5SDimitry Andric                    new CommandObjectTargetModulesDumpClangAST(interpreter)));
24130b57cec5SDimitry Andric     LoadSubCommand("line-table",
24140b57cec5SDimitry Andric                    CommandObjectSP(new CommandObjectTargetModulesDumpLineTable(
24150b57cec5SDimitry Andric                        interpreter)));
24160b57cec5SDimitry Andric   }
24170b57cec5SDimitry Andric 
24180b57cec5SDimitry Andric   ~CommandObjectTargetModulesDump() override = default;
24190b57cec5SDimitry Andric };
24200b57cec5SDimitry Andric 
24210b57cec5SDimitry Andric class CommandObjectTargetModulesAdd : public CommandObjectParsed {
24220b57cec5SDimitry Andric public:
CommandObjectTargetModulesAdd(CommandInterpreter & interpreter)24230b57cec5SDimitry Andric   CommandObjectTargetModulesAdd(CommandInterpreter &interpreter)
24240b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "target modules add",
24250b57cec5SDimitry Andric                             "Add a new module to the current target's modules.",
24269dba64beSDimitry Andric                             "target modules add [<module>]",
24279dba64beSDimitry Andric                             eCommandRequiresTarget),
24289dba64beSDimitry Andric         m_option_group(), m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's',
24299dba64beSDimitry Andric                                         0, eArgTypeFilename,
24309dba64beSDimitry Andric                                         "Fullpath to a stand alone debug "
24310b57cec5SDimitry Andric                                         "symbols file for when debug symbols "
24320b57cec5SDimitry Andric                                         "are not in the executable.") {
24330b57cec5SDimitry Andric     m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
24340b57cec5SDimitry Andric                           LLDB_OPT_SET_1);
24350b57cec5SDimitry Andric     m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
24360b57cec5SDimitry Andric     m_option_group.Finalize();
24370b57cec5SDimitry Andric   }
24380b57cec5SDimitry Andric 
24390b57cec5SDimitry Andric   ~CommandObjectTargetModulesAdd() override = default;
24400b57cec5SDimitry Andric 
GetOptions()24410b57cec5SDimitry Andric   Options *GetOptions() override { return &m_option_group; }
24420b57cec5SDimitry Andric 
24439dba64beSDimitry Andric   void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)24449dba64beSDimitry Andric   HandleArgumentCompletion(CompletionRequest &request,
24450b57cec5SDimitry Andric                            OptionElementVector &opt_element_vector) override {
24460b57cec5SDimitry Andric     CommandCompletions::InvokeCommonCompletionCallbacks(
24470b57cec5SDimitry Andric         GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
24480b57cec5SDimitry Andric         request, nullptr);
24490b57cec5SDimitry Andric   }
24500b57cec5SDimitry Andric 
24510b57cec5SDimitry Andric protected:
24520b57cec5SDimitry Andric   OptionGroupOptions m_option_group;
24530b57cec5SDimitry Andric   OptionGroupUUID m_uuid_option_group;
24540b57cec5SDimitry Andric   OptionGroupFile m_symbol_file;
24550b57cec5SDimitry Andric 
DoExecute(Args & args,CommandReturnObject & result)24560b57cec5SDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
24579dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
24580b57cec5SDimitry Andric     bool flush = false;
24590b57cec5SDimitry Andric 
24600b57cec5SDimitry Andric     const size_t argc = args.GetArgumentCount();
24610b57cec5SDimitry Andric     if (argc == 0) {
24620b57cec5SDimitry Andric       if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
24630b57cec5SDimitry Andric         // We are given a UUID only, go locate the file
24640b57cec5SDimitry Andric         ModuleSpec module_spec;
24650b57cec5SDimitry Andric         module_spec.GetUUID() =
24660b57cec5SDimitry Andric             m_uuid_option_group.GetOptionValue().GetCurrentValue();
24670b57cec5SDimitry Andric         if (m_symbol_file.GetOptionValue().OptionWasSet())
24680b57cec5SDimitry Andric           module_spec.GetSymbolFileSpec() =
24690b57cec5SDimitry Andric               m_symbol_file.GetOptionValue().GetCurrentValue();
24700b57cec5SDimitry Andric         if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
24719dba64beSDimitry Andric           ModuleSP module_sp(
24729dba64beSDimitry Andric               target->GetOrCreateModule(module_spec, true /* notify */));
24730b57cec5SDimitry Andric           if (module_sp) {
24740b57cec5SDimitry Andric             result.SetStatus(eReturnStatusSuccessFinishResult);
24750b57cec5SDimitry Andric             return true;
24760b57cec5SDimitry Andric           } else {
24770b57cec5SDimitry Andric             StreamString strm;
24780b57cec5SDimitry Andric             module_spec.GetUUID().Dump(&strm);
24790b57cec5SDimitry Andric             if (module_spec.GetFileSpec()) {
24800b57cec5SDimitry Andric               if (module_spec.GetSymbolFileSpec()) {
24810b57cec5SDimitry Andric                 result.AppendErrorWithFormat(
24820b57cec5SDimitry Andric                     "Unable to create the executable or symbol file with "
24830b57cec5SDimitry Andric                     "UUID %s with path %s and symbol file %s",
24849dba64beSDimitry Andric                     strm.GetData(), module_spec.GetFileSpec().GetPath().c_str(),
24850b57cec5SDimitry Andric                     module_spec.GetSymbolFileSpec().GetPath().c_str());
24860b57cec5SDimitry Andric               } else {
24870b57cec5SDimitry Andric                 result.AppendErrorWithFormat(
24880b57cec5SDimitry Andric                     "Unable to create the executable or symbol file with "
24890b57cec5SDimitry Andric                     "UUID %s with path %s",
24900b57cec5SDimitry Andric                     strm.GetData(),
24910b57cec5SDimitry Andric                     module_spec.GetFileSpec().GetPath().c_str());
24920b57cec5SDimitry Andric               }
24930b57cec5SDimitry Andric             } else {
24940b57cec5SDimitry Andric               result.AppendErrorWithFormat("Unable to create the executable "
24950b57cec5SDimitry Andric                                            "or symbol file with UUID %s",
24960b57cec5SDimitry Andric                                            strm.GetData());
24970b57cec5SDimitry Andric             }
24980b57cec5SDimitry Andric             return false;
24990b57cec5SDimitry Andric           }
25000b57cec5SDimitry Andric         } else {
25010b57cec5SDimitry Andric           StreamString strm;
25020b57cec5SDimitry Andric           module_spec.GetUUID().Dump(&strm);
25030b57cec5SDimitry Andric           result.AppendErrorWithFormat(
25040b57cec5SDimitry Andric               "Unable to locate the executable or symbol file with UUID %s",
25050b57cec5SDimitry Andric               strm.GetData());
25060b57cec5SDimitry Andric           return false;
25070b57cec5SDimitry Andric         }
25080b57cec5SDimitry Andric       } else {
25090b57cec5SDimitry Andric         result.AppendError(
25100b57cec5SDimitry Andric             "one or more executable image paths must be specified");
25110b57cec5SDimitry Andric         return false;
25120b57cec5SDimitry Andric       }
25130b57cec5SDimitry Andric     } else {
25140b57cec5SDimitry Andric       for (auto &entry : args.entries()) {
25159dba64beSDimitry Andric         if (entry.ref().empty())
25160b57cec5SDimitry Andric           continue;
25170b57cec5SDimitry Andric 
25189dba64beSDimitry Andric         FileSpec file_spec(entry.ref());
25190b57cec5SDimitry Andric         if (FileSystem::Instance().Exists(file_spec)) {
25200b57cec5SDimitry Andric           ModuleSpec module_spec(file_spec);
25210b57cec5SDimitry Andric           if (m_uuid_option_group.GetOptionValue().OptionWasSet())
25220b57cec5SDimitry Andric             module_spec.GetUUID() =
25230b57cec5SDimitry Andric                 m_uuid_option_group.GetOptionValue().GetCurrentValue();
25240b57cec5SDimitry Andric           if (m_symbol_file.GetOptionValue().OptionWasSet())
25250b57cec5SDimitry Andric             module_spec.GetSymbolFileSpec() =
25260b57cec5SDimitry Andric                 m_symbol_file.GetOptionValue().GetCurrentValue();
25270b57cec5SDimitry Andric           if (!module_spec.GetArchitecture().IsValid())
25280b57cec5SDimitry Andric             module_spec.GetArchitecture() = target->GetArchitecture();
25290b57cec5SDimitry Andric           Status error;
25309dba64beSDimitry Andric           ModuleSP module_sp(target->GetOrCreateModule(
25319dba64beSDimitry Andric               module_spec, true /* notify */, &error));
25320b57cec5SDimitry Andric           if (!module_sp) {
25330b57cec5SDimitry Andric             const char *error_cstr = error.AsCString();
25340b57cec5SDimitry Andric             if (error_cstr)
25350b57cec5SDimitry Andric               result.AppendError(error_cstr);
25360b57cec5SDimitry Andric             else
25370b57cec5SDimitry Andric               result.AppendErrorWithFormat("unsupported module: %s",
25380b57cec5SDimitry Andric                                            entry.c_str());
25390b57cec5SDimitry Andric             return false;
25400b57cec5SDimitry Andric           } else {
25410b57cec5SDimitry Andric             flush = true;
25420b57cec5SDimitry Andric           }
25430b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishResult);
25440b57cec5SDimitry Andric         } else {
25450b57cec5SDimitry Andric           std::string resolved_path = file_spec.GetPath();
25469dba64beSDimitry Andric           if (resolved_path != entry.ref()) {
25470b57cec5SDimitry Andric             result.AppendErrorWithFormat(
25480b57cec5SDimitry Andric                 "invalid module path '%s' with resolved path '%s'\n",
25499dba64beSDimitry Andric                 entry.ref().str().c_str(), resolved_path.c_str());
25500b57cec5SDimitry Andric             break;
25510b57cec5SDimitry Andric           }
25520b57cec5SDimitry Andric           result.AppendErrorWithFormat("invalid module path '%s'\n",
25530b57cec5SDimitry Andric                                        entry.c_str());
25540b57cec5SDimitry Andric           break;
25550b57cec5SDimitry Andric         }
25560b57cec5SDimitry Andric       }
25570b57cec5SDimitry Andric     }
25580b57cec5SDimitry Andric 
25590b57cec5SDimitry Andric     if (flush) {
25600b57cec5SDimitry Andric       ProcessSP process = target->GetProcessSP();
25610b57cec5SDimitry Andric       if (process)
25620b57cec5SDimitry Andric         process->Flush();
25630b57cec5SDimitry Andric     }
25640b57cec5SDimitry Andric 
25650b57cec5SDimitry Andric     return result.Succeeded();
25660b57cec5SDimitry Andric   }
25670b57cec5SDimitry Andric };
25680b57cec5SDimitry Andric 
25690b57cec5SDimitry Andric class CommandObjectTargetModulesLoad
25700b57cec5SDimitry Andric     : public CommandObjectTargetModulesModuleAutoComplete {
25710b57cec5SDimitry Andric public:
CommandObjectTargetModulesLoad(CommandInterpreter & interpreter)25720b57cec5SDimitry Andric   CommandObjectTargetModulesLoad(CommandInterpreter &interpreter)
25730b57cec5SDimitry Andric       : CommandObjectTargetModulesModuleAutoComplete(
25749dba64beSDimitry Andric             interpreter, "target modules load",
25759dba64beSDimitry Andric             "Set the load addresses for one or more sections in a target "
25769dba64beSDimitry Andric             "module.",
25770b57cec5SDimitry Andric             "target modules load [--file <module> --uuid <uuid>] <sect-name> "
25789dba64beSDimitry Andric             "<address> [<sect-name> <address> ....]",
25799dba64beSDimitry Andric             eCommandRequiresTarget),
25800b57cec5SDimitry Andric         m_option_group(),
25810b57cec5SDimitry Andric         m_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName,
25820b57cec5SDimitry Andric                       "Fullpath or basename for module to load.", ""),
25830b57cec5SDimitry Andric         m_load_option(LLDB_OPT_SET_1, false, "load", 'l',
25840b57cec5SDimitry Andric                       "Write file contents to the memory.", false, true),
25850b57cec5SDimitry Andric         m_pc_option(LLDB_OPT_SET_1, false, "set-pc-to-entry", 'p',
25860b57cec5SDimitry Andric                     "Set PC to the entry point."
25870b57cec5SDimitry Andric                     " Only applicable with '--load' option.",
25880b57cec5SDimitry Andric                     false, true),
25890b57cec5SDimitry Andric         m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset,
25900b57cec5SDimitry Andric                        "Set the load address for all sections to be the "
25910b57cec5SDimitry Andric                        "virtual address in the file plus the offset.",
25920b57cec5SDimitry Andric                        0) {
25930b57cec5SDimitry Andric     m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
25940b57cec5SDimitry Andric                           LLDB_OPT_SET_1);
25950b57cec5SDimitry Andric     m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
25960b57cec5SDimitry Andric     m_option_group.Append(&m_load_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
25970b57cec5SDimitry Andric     m_option_group.Append(&m_pc_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
25980b57cec5SDimitry Andric     m_option_group.Append(&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
25990b57cec5SDimitry Andric     m_option_group.Finalize();
26000b57cec5SDimitry Andric   }
26010b57cec5SDimitry Andric 
26020b57cec5SDimitry Andric   ~CommandObjectTargetModulesLoad() override = default;
26030b57cec5SDimitry Andric 
GetOptions()26040b57cec5SDimitry Andric   Options *GetOptions() override { return &m_option_group; }
26050b57cec5SDimitry Andric 
26060b57cec5SDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)26070b57cec5SDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
26089dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
26090b57cec5SDimitry Andric     const bool load = m_load_option.GetOptionValue().GetCurrentValue();
26100b57cec5SDimitry Andric     const bool set_pc = m_pc_option.GetOptionValue().GetCurrentValue();
26119dba64beSDimitry Andric 
26120b57cec5SDimitry Andric     const size_t argc = args.GetArgumentCount();
26130b57cec5SDimitry Andric     ModuleSpec module_spec;
26140b57cec5SDimitry Andric     bool search_using_module_spec = false;
26150b57cec5SDimitry Andric 
26160b57cec5SDimitry Andric     // Allow "load" option to work without --file or --uuid option.
26170b57cec5SDimitry Andric     if (load) {
26180b57cec5SDimitry Andric       if (!m_file_option.GetOptionValue().OptionWasSet() &&
26190b57cec5SDimitry Andric           !m_uuid_option_group.GetOptionValue().OptionWasSet()) {
26200b57cec5SDimitry Andric         ModuleList &module_list = target->GetImages();
26210b57cec5SDimitry Andric         if (module_list.GetSize() == 1) {
26220b57cec5SDimitry Andric           search_using_module_spec = true;
26230b57cec5SDimitry Andric           module_spec.GetFileSpec() =
26240b57cec5SDimitry Andric               module_list.GetModuleAtIndex(0)->GetFileSpec();
26250b57cec5SDimitry Andric         }
26260b57cec5SDimitry Andric       }
26270b57cec5SDimitry Andric     }
26280b57cec5SDimitry Andric 
26290b57cec5SDimitry Andric     if (m_file_option.GetOptionValue().OptionWasSet()) {
26300b57cec5SDimitry Andric       search_using_module_spec = true;
26310b57cec5SDimitry Andric       const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
26320b57cec5SDimitry Andric       const bool use_global_module_list = true;
26330b57cec5SDimitry Andric       ModuleList module_list;
26340b57cec5SDimitry Andric       const size_t num_matches = FindModulesByName(
26350b57cec5SDimitry Andric           target, arg_cstr, module_list, use_global_module_list);
26360b57cec5SDimitry Andric       if (num_matches == 1) {
26370b57cec5SDimitry Andric         module_spec.GetFileSpec() =
26380b57cec5SDimitry Andric             module_list.GetModuleAtIndex(0)->GetFileSpec();
26390b57cec5SDimitry Andric       } else if (num_matches > 1) {
26400b57cec5SDimitry Andric         search_using_module_spec = false;
26410b57cec5SDimitry Andric         result.AppendErrorWithFormat(
26420b57cec5SDimitry Andric             "more than 1 module matched by name '%s'\n", arg_cstr);
26430b57cec5SDimitry Andric       } else {
26440b57cec5SDimitry Andric         search_using_module_spec = false;
26450b57cec5SDimitry Andric         result.AppendErrorWithFormat("no object file for module '%s'\n",
26460b57cec5SDimitry Andric                                      arg_cstr);
26470b57cec5SDimitry Andric       }
26480b57cec5SDimitry Andric     }
26490b57cec5SDimitry Andric 
26500b57cec5SDimitry Andric     if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
26510b57cec5SDimitry Andric       search_using_module_spec = true;
26520b57cec5SDimitry Andric       module_spec.GetUUID() =
26530b57cec5SDimitry Andric           m_uuid_option_group.GetOptionValue().GetCurrentValue();
26540b57cec5SDimitry Andric     }
26550b57cec5SDimitry Andric 
26560b57cec5SDimitry Andric     if (search_using_module_spec) {
26570b57cec5SDimitry Andric       ModuleList matching_modules;
26580b57cec5SDimitry Andric       target->GetImages().FindModules(module_spec, matching_modules);
26599dba64beSDimitry Andric       const size_t num_matches = matching_modules.GetSize();
26600b57cec5SDimitry Andric 
26610b57cec5SDimitry Andric       char path[PATH_MAX];
26620b57cec5SDimitry Andric       if (num_matches == 1) {
26630b57cec5SDimitry Andric         Module *module = matching_modules.GetModulePointerAtIndex(0);
26640b57cec5SDimitry Andric         if (module) {
26650b57cec5SDimitry Andric           ObjectFile *objfile = module->GetObjectFile();
26660b57cec5SDimitry Andric           if (objfile) {
26670b57cec5SDimitry Andric             SectionList *section_list = module->GetSectionList();
26680b57cec5SDimitry Andric             if (section_list) {
26690b57cec5SDimitry Andric               bool changed = false;
26700b57cec5SDimitry Andric               if (argc == 0) {
26710b57cec5SDimitry Andric                 if (m_slide_option.GetOptionValue().OptionWasSet()) {
26720b57cec5SDimitry Andric                   const addr_t slide =
26730b57cec5SDimitry Andric                       m_slide_option.GetOptionValue().GetCurrentValue();
26740b57cec5SDimitry Andric                   const bool slide_is_offset = true;
26750b57cec5SDimitry Andric                   module->SetLoadAddress(*target, slide, slide_is_offset,
26760b57cec5SDimitry Andric                                          changed);
26770b57cec5SDimitry Andric                 } else {
26780b57cec5SDimitry Andric                   result.AppendError("one or more section name + load "
26790b57cec5SDimitry Andric                                      "address pair must be specified");
26800b57cec5SDimitry Andric                   return false;
26810b57cec5SDimitry Andric                 }
26820b57cec5SDimitry Andric               } else {
26830b57cec5SDimitry Andric                 if (m_slide_option.GetOptionValue().OptionWasSet()) {
26840b57cec5SDimitry Andric                   result.AppendError("The \"--slide <offset>\" option can't "
26850b57cec5SDimitry Andric                                      "be used in conjunction with setting "
26860b57cec5SDimitry Andric                                      "section load addresses.\n");
26870b57cec5SDimitry Andric                   return false;
26880b57cec5SDimitry Andric                 }
26890b57cec5SDimitry Andric 
26900b57cec5SDimitry Andric                 for (size_t i = 0; i < argc; i += 2) {
26910b57cec5SDimitry Andric                   const char *sect_name = args.GetArgumentAtIndex(i);
26920b57cec5SDimitry Andric                   const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1);
26930b57cec5SDimitry Andric                   if (sect_name && load_addr_cstr) {
26940b57cec5SDimitry Andric                     ConstString const_sect_name(sect_name);
26955ffd83dbSDimitry Andric                     addr_t load_addr;
26965ffd83dbSDimitry Andric                     if (llvm::to_integer(load_addr_cstr, load_addr)) {
26970b57cec5SDimitry Andric                       SectionSP section_sp(
26980b57cec5SDimitry Andric                           section_list->FindSectionByName(const_sect_name));
26990b57cec5SDimitry Andric                       if (section_sp) {
27000b57cec5SDimitry Andric                         if (section_sp->IsThreadSpecific()) {
27010b57cec5SDimitry Andric                           result.AppendErrorWithFormat(
27020b57cec5SDimitry Andric                               "thread specific sections are not yet "
27030b57cec5SDimitry Andric                               "supported (section '%s')\n",
27040b57cec5SDimitry Andric                               sect_name);
27050b57cec5SDimitry Andric                           break;
27060b57cec5SDimitry Andric                         } else {
27070b57cec5SDimitry Andric                           if (target->GetSectionLoadList()
27089dba64beSDimitry Andric                                   .SetSectionLoadAddress(section_sp, load_addr))
27090b57cec5SDimitry Andric                             changed = true;
27100b57cec5SDimitry Andric                           result.AppendMessageWithFormat(
27110b57cec5SDimitry Andric                               "section '%s' loaded at 0x%" PRIx64 "\n",
27120b57cec5SDimitry Andric                               sect_name, load_addr);
27130b57cec5SDimitry Andric                         }
27140b57cec5SDimitry Andric                       } else {
27150b57cec5SDimitry Andric                         result.AppendErrorWithFormat("no section found that "
27160b57cec5SDimitry Andric                                                      "matches the section "
27170b57cec5SDimitry Andric                                                      "name '%s'\n",
27180b57cec5SDimitry Andric                                                      sect_name);
27190b57cec5SDimitry Andric                         break;
27200b57cec5SDimitry Andric                       }
27210b57cec5SDimitry Andric                     } else {
27220b57cec5SDimitry Andric                       result.AppendErrorWithFormat(
27239dba64beSDimitry Andric                           "invalid load address string '%s'\n", load_addr_cstr);
27240b57cec5SDimitry Andric                       break;
27250b57cec5SDimitry Andric                     }
27260b57cec5SDimitry Andric                   } else {
27270b57cec5SDimitry Andric                     if (sect_name)
27280b57cec5SDimitry Andric                       result.AppendError("section names must be followed by "
27290b57cec5SDimitry Andric                                          "a load address.\n");
27300b57cec5SDimitry Andric                     else
27310b57cec5SDimitry Andric                       result.AppendError("one or more section name + load "
27320b57cec5SDimitry Andric                                          "address pair must be specified.\n");
27330b57cec5SDimitry Andric                     break;
27340b57cec5SDimitry Andric                   }
27350b57cec5SDimitry Andric                 }
27360b57cec5SDimitry Andric               }
27370b57cec5SDimitry Andric 
27380b57cec5SDimitry Andric               if (changed) {
27390b57cec5SDimitry Andric                 target->ModulesDidLoad(matching_modules);
27400b57cec5SDimitry Andric                 Process *process = m_exe_ctx.GetProcessPtr();
27410b57cec5SDimitry Andric                 if (process)
27420b57cec5SDimitry Andric                   process->Flush();
27430b57cec5SDimitry Andric               }
27440b57cec5SDimitry Andric               if (load) {
27450b57cec5SDimitry Andric                 ProcessSP process = target->CalculateProcess();
27460b57cec5SDimitry Andric                 Address file_entry = objfile->GetEntryPointAddress();
27470b57cec5SDimitry Andric                 if (!process) {
27480b57cec5SDimitry Andric                   result.AppendError("No process");
27490b57cec5SDimitry Andric                   return false;
27500b57cec5SDimitry Andric                 }
27510b57cec5SDimitry Andric                 if (set_pc && !file_entry.IsValid()) {
27520b57cec5SDimitry Andric                   result.AppendError("No entry address in object file");
27530b57cec5SDimitry Andric                   return false;
27540b57cec5SDimitry Andric                 }
27550b57cec5SDimitry Andric                 std::vector<ObjectFile::LoadableData> loadables(
27560b57cec5SDimitry Andric                     objfile->GetLoadableData(*target));
27570b57cec5SDimitry Andric                 if (loadables.size() == 0) {
27580b57cec5SDimitry Andric                   result.AppendError("No loadable sections");
27590b57cec5SDimitry Andric                   return false;
27600b57cec5SDimitry Andric                 }
27610b57cec5SDimitry Andric                 Status error = process->WriteObjectFile(std::move(loadables));
27620b57cec5SDimitry Andric                 if (error.Fail()) {
27630b57cec5SDimitry Andric                   result.AppendError(error.AsCString());
27640b57cec5SDimitry Andric                   return false;
27650b57cec5SDimitry Andric                 }
27660b57cec5SDimitry Andric                 if (set_pc) {
27670b57cec5SDimitry Andric                   ThreadList &thread_list = process->GetThreadList();
27680b57cec5SDimitry Andric                   RegisterContextSP reg_context(
27690b57cec5SDimitry Andric                       thread_list.GetSelectedThread()->GetRegisterContext());
27700b57cec5SDimitry Andric                   addr_t file_entry_addr = file_entry.GetLoadAddress(target);
27710b57cec5SDimitry Andric                   if (!reg_context->SetPC(file_entry_addr)) {
27720b57cec5SDimitry Andric                     result.AppendErrorWithFormat("failed to set PC value to "
27730b57cec5SDimitry Andric                                                  "0x%" PRIx64 "\n",
27740b57cec5SDimitry Andric                                                  file_entry_addr);
27750b57cec5SDimitry Andric                   }
27760b57cec5SDimitry Andric                 }
27770b57cec5SDimitry Andric               }
27780b57cec5SDimitry Andric             } else {
27790b57cec5SDimitry Andric               module->GetFileSpec().GetPath(path, sizeof(path));
27809dba64beSDimitry Andric               result.AppendErrorWithFormat("no sections in object file '%s'\n",
27819dba64beSDimitry Andric                                            path);
27820b57cec5SDimitry Andric             }
27830b57cec5SDimitry Andric           } else {
27840b57cec5SDimitry Andric             module->GetFileSpec().GetPath(path, sizeof(path));
27850b57cec5SDimitry Andric             result.AppendErrorWithFormat("no object file for module '%s'\n",
27860b57cec5SDimitry Andric                                          path);
27870b57cec5SDimitry Andric           }
27880b57cec5SDimitry Andric         } else {
27890b57cec5SDimitry Andric           FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
27900b57cec5SDimitry Andric           if (module_spec_file) {
27910b57cec5SDimitry Andric             module_spec_file->GetPath(path, sizeof(path));
27920b57cec5SDimitry Andric             result.AppendErrorWithFormat("invalid module '%s'.\n", path);
27930b57cec5SDimitry Andric           } else
27940b57cec5SDimitry Andric             result.AppendError("no module spec");
27950b57cec5SDimitry Andric         }
27960b57cec5SDimitry Andric       } else {
27970b57cec5SDimitry Andric         std::string uuid_str;
27980b57cec5SDimitry Andric 
27990b57cec5SDimitry Andric         if (module_spec.GetFileSpec())
28000b57cec5SDimitry Andric           module_spec.GetFileSpec().GetPath(path, sizeof(path));
28010b57cec5SDimitry Andric         else
28020b57cec5SDimitry Andric           path[0] = '\0';
28030b57cec5SDimitry Andric 
28040b57cec5SDimitry Andric         if (module_spec.GetUUIDPtr())
28050b57cec5SDimitry Andric           uuid_str = module_spec.GetUUID().GetAsString();
28060b57cec5SDimitry Andric         if (num_matches > 1) {
28070b57cec5SDimitry Andric           result.AppendErrorWithFormat(
28080b57cec5SDimitry Andric               "multiple modules match%s%s%s%s:\n", path[0] ? " file=" : "",
28090b57cec5SDimitry Andric               path, !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
28100b57cec5SDimitry Andric           for (size_t i = 0; i < num_matches; ++i) {
28110b57cec5SDimitry Andric             if (matching_modules.GetModulePointerAtIndex(i)
28120b57cec5SDimitry Andric                     ->GetFileSpec()
28130b57cec5SDimitry Andric                     .GetPath(path, sizeof(path)))
28140b57cec5SDimitry Andric               result.AppendMessageWithFormat("%s\n", path);
28150b57cec5SDimitry Andric           }
28160b57cec5SDimitry Andric         } else {
28170b57cec5SDimitry Andric           result.AppendErrorWithFormat(
28180b57cec5SDimitry Andric               "no modules were found  that match%s%s%s%s.\n",
28199dba64beSDimitry Andric               path[0] ? " file=" : "", path, !uuid_str.empty() ? " uuid=" : "",
28209dba64beSDimitry Andric               uuid_str.c_str());
28210b57cec5SDimitry Andric         }
28220b57cec5SDimitry Andric       }
28230b57cec5SDimitry Andric     } else {
28240b57cec5SDimitry Andric       result.AppendError("either the \"--file <module>\" or the \"--uuid "
28250b57cec5SDimitry Andric                          "<uuid>\" option must be specified.\n");
28260b57cec5SDimitry Andric       return false;
28270b57cec5SDimitry Andric     }
28280b57cec5SDimitry Andric     return result.Succeeded();
28290b57cec5SDimitry Andric   }
28300b57cec5SDimitry Andric 
28310b57cec5SDimitry Andric   OptionGroupOptions m_option_group;
28320b57cec5SDimitry Andric   OptionGroupUUID m_uuid_option_group;
28330b57cec5SDimitry Andric   OptionGroupString m_file_option;
28340b57cec5SDimitry Andric   OptionGroupBoolean m_load_option;
28350b57cec5SDimitry Andric   OptionGroupBoolean m_pc_option;
28360b57cec5SDimitry Andric   OptionGroupUInt64 m_slide_option;
28370b57cec5SDimitry Andric };
28380b57cec5SDimitry Andric 
28390b57cec5SDimitry Andric // List images with associated information
28409dba64beSDimitry Andric #define LLDB_OPTIONS_target_modules_list
28419dba64beSDimitry Andric #include "CommandOptions.inc"
28420b57cec5SDimitry Andric 
28430b57cec5SDimitry Andric class CommandObjectTargetModulesList : public CommandObjectParsed {
28440b57cec5SDimitry Andric public:
28450b57cec5SDimitry Andric   class CommandOptions : public Options {
28460b57cec5SDimitry Andric   public:
CommandOptions()2847*5f7ddb14SDimitry Andric     CommandOptions() : Options(), m_format_array() {}
28480b57cec5SDimitry Andric 
28490b57cec5SDimitry Andric     ~CommandOptions() override = default;
28500b57cec5SDimitry Andric 
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)28510b57cec5SDimitry Andric     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
28520b57cec5SDimitry Andric                           ExecutionContext *execution_context) override {
28530b57cec5SDimitry Andric       Status error;
28540b57cec5SDimitry Andric 
28550b57cec5SDimitry Andric       const int short_option = m_getopt_table[option_idx].val;
28560b57cec5SDimitry Andric       if (short_option == 'g') {
28570b57cec5SDimitry Andric         m_use_global_module_list = true;
28580b57cec5SDimitry Andric       } else if (short_option == 'a') {
28590b57cec5SDimitry Andric         m_module_addr = OptionArgParser::ToAddress(
28600b57cec5SDimitry Andric             execution_context, option_arg, LLDB_INVALID_ADDRESS, &error);
28610b57cec5SDimitry Andric       } else {
28620b57cec5SDimitry Andric         unsigned long width = 0;
28630b57cec5SDimitry Andric         option_arg.getAsInteger(0, width);
28640b57cec5SDimitry Andric         m_format_array.push_back(std::make_pair(short_option, width));
28650b57cec5SDimitry Andric       }
28660b57cec5SDimitry Andric       return error;
28670b57cec5SDimitry Andric     }
28680b57cec5SDimitry Andric 
OptionParsingStarting(ExecutionContext * execution_context)28690b57cec5SDimitry Andric     void OptionParsingStarting(ExecutionContext *execution_context) override {
28700b57cec5SDimitry Andric       m_format_array.clear();
28710b57cec5SDimitry Andric       m_use_global_module_list = false;
28720b57cec5SDimitry Andric       m_module_addr = LLDB_INVALID_ADDRESS;
28730b57cec5SDimitry Andric     }
28740b57cec5SDimitry Andric 
GetDefinitions()28750b57cec5SDimitry Andric     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
28760b57cec5SDimitry Andric       return llvm::makeArrayRef(g_target_modules_list_options);
28770b57cec5SDimitry Andric     }
28780b57cec5SDimitry Andric 
28790b57cec5SDimitry Andric     // Instance variables to hold the values for command options.
28800b57cec5SDimitry Andric     typedef std::vector<std::pair<char, uint32_t>> FormatWidthCollection;
28810b57cec5SDimitry Andric     FormatWidthCollection m_format_array;
2882*5f7ddb14SDimitry Andric     bool m_use_global_module_list = false;
2883*5f7ddb14SDimitry Andric     lldb::addr_t m_module_addr = LLDB_INVALID_ADDRESS;
28840b57cec5SDimitry Andric   };
28850b57cec5SDimitry Andric 
CommandObjectTargetModulesList(CommandInterpreter & interpreter)28860b57cec5SDimitry Andric   CommandObjectTargetModulesList(CommandInterpreter &interpreter)
28870b57cec5SDimitry Andric       : CommandObjectParsed(
28880b57cec5SDimitry Andric             interpreter, "target modules list",
28890b57cec5SDimitry Andric             "List current executable and dependent shared library images.",
28900b57cec5SDimitry Andric             "target modules list [<cmd-options>]"),
28910b57cec5SDimitry Andric         m_options() {}
28920b57cec5SDimitry Andric 
28930b57cec5SDimitry Andric   ~CommandObjectTargetModulesList() override = default;
28940b57cec5SDimitry Andric 
GetOptions()28950b57cec5SDimitry Andric   Options *GetOptions() override { return &m_options; }
28960b57cec5SDimitry Andric 
28970b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)28980b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
28990b57cec5SDimitry Andric     Target *target = GetDebugger().GetSelectedTarget().get();
29000b57cec5SDimitry Andric     const bool use_global_module_list = m_options.m_use_global_module_list;
29010b57cec5SDimitry Andric     // Define a local module list here to ensure it lives longer than any
29020b57cec5SDimitry Andric     // "locker" object which might lock its contents below (through the
29030b57cec5SDimitry Andric     // "module_list_ptr" variable).
29040b57cec5SDimitry Andric     ModuleList module_list;
29050b57cec5SDimitry Andric     if (target == nullptr && !use_global_module_list) {
29060b57cec5SDimitry Andric       result.AppendError("invalid target, create a debug target using the "
29070b57cec5SDimitry Andric                          "'target create' command");
29080b57cec5SDimitry Andric       return false;
29090b57cec5SDimitry Andric     } else {
29100b57cec5SDimitry Andric       if (target) {
29110b57cec5SDimitry Andric         uint32_t addr_byte_size =
29120b57cec5SDimitry Andric             target->GetArchitecture().GetAddressByteSize();
29130b57cec5SDimitry Andric         result.GetOutputStream().SetAddressByteSize(addr_byte_size);
29140b57cec5SDimitry Andric         result.GetErrorStream().SetAddressByteSize(addr_byte_size);
29150b57cec5SDimitry Andric       }
29160b57cec5SDimitry Andric       // Dump all sections for all modules images
29170b57cec5SDimitry Andric       Stream &strm = result.GetOutputStream();
29180b57cec5SDimitry Andric 
29190b57cec5SDimitry Andric       if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) {
29200b57cec5SDimitry Andric         if (target) {
29210b57cec5SDimitry Andric           Address module_address;
29220b57cec5SDimitry Andric           if (module_address.SetLoadAddress(m_options.m_module_addr, target)) {
29230b57cec5SDimitry Andric             ModuleSP module_sp(module_address.GetModule());
29240b57cec5SDimitry Andric             if (module_sp) {
29250b57cec5SDimitry Andric               PrintModule(target, module_sp.get(), 0, strm);
29260b57cec5SDimitry Andric               result.SetStatus(eReturnStatusSuccessFinishResult);
29270b57cec5SDimitry Andric             } else {
29280b57cec5SDimitry Andric               result.AppendErrorWithFormat(
29290b57cec5SDimitry Andric                   "Couldn't find module matching address: 0x%" PRIx64 ".",
29300b57cec5SDimitry Andric                   m_options.m_module_addr);
29310b57cec5SDimitry Andric             }
29320b57cec5SDimitry Andric           } else {
29330b57cec5SDimitry Andric             result.AppendErrorWithFormat(
29340b57cec5SDimitry Andric                 "Couldn't find module containing address: 0x%" PRIx64 ".",
29350b57cec5SDimitry Andric                 m_options.m_module_addr);
29360b57cec5SDimitry Andric           }
29370b57cec5SDimitry Andric         } else {
29380b57cec5SDimitry Andric           result.AppendError(
29390b57cec5SDimitry Andric               "Can only look up modules by address with a valid target.");
29400b57cec5SDimitry Andric         }
29410b57cec5SDimitry Andric         return result.Succeeded();
29420b57cec5SDimitry Andric       }
29430b57cec5SDimitry Andric 
29440b57cec5SDimitry Andric       size_t num_modules = 0;
29450b57cec5SDimitry Andric 
29460b57cec5SDimitry Andric       // This locker will be locked on the mutex in module_list_ptr if it is
29470b57cec5SDimitry Andric       // non-nullptr. Otherwise it will lock the
29480b57cec5SDimitry Andric       // AllocationModuleCollectionMutex when accessing the global module list
29490b57cec5SDimitry Andric       // directly.
29500b57cec5SDimitry Andric       std::unique_lock<std::recursive_mutex> guard(
29510b57cec5SDimitry Andric           Module::GetAllocationModuleCollectionMutex(), std::defer_lock);
29520b57cec5SDimitry Andric 
29530b57cec5SDimitry Andric       const ModuleList *module_list_ptr = nullptr;
29540b57cec5SDimitry Andric       const size_t argc = command.GetArgumentCount();
29550b57cec5SDimitry Andric       if (argc == 0) {
29560b57cec5SDimitry Andric         if (use_global_module_list) {
29570b57cec5SDimitry Andric           guard.lock();
29580b57cec5SDimitry Andric           num_modules = Module::GetNumberAllocatedModules();
29590b57cec5SDimitry Andric         } else {
29600b57cec5SDimitry Andric           module_list_ptr = &target->GetImages();
29610b57cec5SDimitry Andric         }
29620b57cec5SDimitry Andric       } else {
29635ffd83dbSDimitry Andric         for (const Args::ArgEntry &arg : command) {
29640b57cec5SDimitry Andric           // Dump specified images (by basename or fullpath)
29650b57cec5SDimitry Andric           const size_t num_matches = FindModulesByName(
29665ffd83dbSDimitry Andric               target, arg.c_str(), module_list, use_global_module_list);
29670b57cec5SDimitry Andric           if (num_matches == 0) {
29680b57cec5SDimitry Andric             if (argc == 1) {
29690b57cec5SDimitry Andric               result.AppendErrorWithFormat("no modules found that match '%s'",
29705ffd83dbSDimitry Andric                                            arg.c_str());
29710b57cec5SDimitry Andric               return false;
29720b57cec5SDimitry Andric             }
29730b57cec5SDimitry Andric           }
29740b57cec5SDimitry Andric         }
29750b57cec5SDimitry Andric 
29760b57cec5SDimitry Andric         module_list_ptr = &module_list;
29770b57cec5SDimitry Andric       }
29780b57cec5SDimitry Andric 
29790b57cec5SDimitry Andric       std::unique_lock<std::recursive_mutex> lock;
29800b57cec5SDimitry Andric       if (module_list_ptr != nullptr) {
29810b57cec5SDimitry Andric         lock =
29820b57cec5SDimitry Andric             std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex());
29830b57cec5SDimitry Andric 
29840b57cec5SDimitry Andric         num_modules = module_list_ptr->GetSize();
29850b57cec5SDimitry Andric       }
29860b57cec5SDimitry Andric 
29870b57cec5SDimitry Andric       if (num_modules > 0) {
29880b57cec5SDimitry Andric         for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
29890b57cec5SDimitry Andric           ModuleSP module_sp;
29900b57cec5SDimitry Andric           Module *module;
29910b57cec5SDimitry Andric           if (module_list_ptr) {
29920b57cec5SDimitry Andric             module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
29930b57cec5SDimitry Andric             module = module_sp.get();
29940b57cec5SDimitry Andric           } else {
29950b57cec5SDimitry Andric             module = Module::GetAllocatedModuleAtIndex(image_idx);
29960b57cec5SDimitry Andric             module_sp = module->shared_from_this();
29970b57cec5SDimitry Andric           }
29980b57cec5SDimitry Andric 
29990b57cec5SDimitry Andric           const size_t indent = strm.Printf("[%3u] ", image_idx);
30000b57cec5SDimitry Andric           PrintModule(target, module, indent, strm);
30010b57cec5SDimitry Andric         }
30020b57cec5SDimitry Andric         result.SetStatus(eReturnStatusSuccessFinishResult);
30030b57cec5SDimitry Andric       } else {
30040b57cec5SDimitry Andric         if (argc) {
30050b57cec5SDimitry Andric           if (use_global_module_list)
30060b57cec5SDimitry Andric             result.AppendError(
30070b57cec5SDimitry Andric                 "the global module list has no matching modules");
30080b57cec5SDimitry Andric           else
30090b57cec5SDimitry Andric             result.AppendError("the target has no matching modules");
30100b57cec5SDimitry Andric         } else {
30110b57cec5SDimitry Andric           if (use_global_module_list)
30120b57cec5SDimitry Andric             result.AppendError("the global module list is empty");
30130b57cec5SDimitry Andric           else
30140b57cec5SDimitry Andric             result.AppendError(
30150b57cec5SDimitry Andric                 "the target has no associated executable images");
30160b57cec5SDimitry Andric         }
30170b57cec5SDimitry Andric         return false;
30180b57cec5SDimitry Andric       }
30190b57cec5SDimitry Andric     }
30200b57cec5SDimitry Andric     return result.Succeeded();
30210b57cec5SDimitry Andric   }
30220b57cec5SDimitry Andric 
PrintModule(Target * target,Module * module,int indent,Stream & strm)30230b57cec5SDimitry Andric   void PrintModule(Target *target, Module *module, int indent, Stream &strm) {
30240b57cec5SDimitry Andric     if (module == nullptr) {
30250b57cec5SDimitry Andric       strm.PutCString("Null module");
30260b57cec5SDimitry Andric       return;
30270b57cec5SDimitry Andric     }
30280b57cec5SDimitry Andric 
30290b57cec5SDimitry Andric     bool dump_object_name = false;
30300b57cec5SDimitry Andric     if (m_options.m_format_array.empty()) {
30310b57cec5SDimitry Andric       m_options.m_format_array.push_back(std::make_pair('u', 0));
30320b57cec5SDimitry Andric       m_options.m_format_array.push_back(std::make_pair('h', 0));
30330b57cec5SDimitry Andric       m_options.m_format_array.push_back(std::make_pair('f', 0));
30340b57cec5SDimitry Andric       m_options.m_format_array.push_back(std::make_pair('S', 0));
30350b57cec5SDimitry Andric     }
30360b57cec5SDimitry Andric     const size_t num_entries = m_options.m_format_array.size();
30370b57cec5SDimitry Andric     bool print_space = false;
30380b57cec5SDimitry Andric     for (size_t i = 0; i < num_entries; ++i) {
30390b57cec5SDimitry Andric       if (print_space)
30400b57cec5SDimitry Andric         strm.PutChar(' ');
30410b57cec5SDimitry Andric       print_space = true;
30420b57cec5SDimitry Andric       const char format_char = m_options.m_format_array[i].first;
30430b57cec5SDimitry Andric       uint32_t width = m_options.m_format_array[i].second;
30440b57cec5SDimitry Andric       switch (format_char) {
30450b57cec5SDimitry Andric       case 'A':
30460b57cec5SDimitry Andric         DumpModuleArchitecture(strm, module, false, width);
30470b57cec5SDimitry Andric         break;
30480b57cec5SDimitry Andric 
30490b57cec5SDimitry Andric       case 't':
30500b57cec5SDimitry Andric         DumpModuleArchitecture(strm, module, true, width);
30510b57cec5SDimitry Andric         break;
30520b57cec5SDimitry Andric 
30530b57cec5SDimitry Andric       case 'f':
30540b57cec5SDimitry Andric         DumpFullpath(strm, &module->GetFileSpec(), width);
30550b57cec5SDimitry Andric         dump_object_name = true;
30560b57cec5SDimitry Andric         break;
30570b57cec5SDimitry Andric 
30580b57cec5SDimitry Andric       case 'd':
30590b57cec5SDimitry Andric         DumpDirectory(strm, &module->GetFileSpec(), width);
30600b57cec5SDimitry Andric         break;
30610b57cec5SDimitry Andric 
30620b57cec5SDimitry Andric       case 'b':
30630b57cec5SDimitry Andric         DumpBasename(strm, &module->GetFileSpec(), width);
30640b57cec5SDimitry Andric         dump_object_name = true;
30650b57cec5SDimitry Andric         break;
30660b57cec5SDimitry Andric 
30670b57cec5SDimitry Andric       case 'h':
30680b57cec5SDimitry Andric       case 'o':
30690b57cec5SDimitry Andric         // Image header address
30700b57cec5SDimitry Andric         {
30710b57cec5SDimitry Andric           uint32_t addr_nibble_width =
30720b57cec5SDimitry Andric               target ? (target->GetArchitecture().GetAddressByteSize() * 2)
30730b57cec5SDimitry Andric                      : 16;
30740b57cec5SDimitry Andric 
30750b57cec5SDimitry Andric           ObjectFile *objfile = module->GetObjectFile();
30760b57cec5SDimitry Andric           if (objfile) {
30770b57cec5SDimitry Andric             Address base_addr(objfile->GetBaseAddress());
30780b57cec5SDimitry Andric             if (base_addr.IsValid()) {
30790b57cec5SDimitry Andric               if (target && !target->GetSectionLoadList().IsEmpty()) {
3080480093f4SDimitry Andric                 lldb::addr_t load_addr = base_addr.GetLoadAddress(target);
30810b57cec5SDimitry Andric                 if (load_addr == LLDB_INVALID_ADDRESS) {
30820b57cec5SDimitry Andric                   base_addr.Dump(&strm, target,
30830b57cec5SDimitry Andric                                  Address::DumpStyleModuleWithFileAddress,
30840b57cec5SDimitry Andric                                  Address::DumpStyleFileAddress);
30850b57cec5SDimitry Andric                 } else {
30860b57cec5SDimitry Andric                   if (format_char == 'o') {
30870b57cec5SDimitry Andric                     // Show the offset of slide for the image
3088480093f4SDimitry Andric                     strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3089480093f4SDimitry Andric                                 addr_nibble_width,
30900b57cec5SDimitry Andric                                 load_addr - base_addr.GetFileAddress());
30910b57cec5SDimitry Andric                   } else {
30920b57cec5SDimitry Andric                     // Show the load address of the image
30930b57cec5SDimitry Andric                     strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
30940b57cec5SDimitry Andric                                 addr_nibble_width, load_addr);
30950b57cec5SDimitry Andric                   }
30960b57cec5SDimitry Andric                 }
30970b57cec5SDimitry Andric                 break;
30980b57cec5SDimitry Andric               }
30990b57cec5SDimitry Andric               // The address was valid, but the image isn't loaded, output the
31000b57cec5SDimitry Andric               // address in an appropriate format
31010b57cec5SDimitry Andric               base_addr.Dump(&strm, target, Address::DumpStyleFileAddress);
31020b57cec5SDimitry Andric               break;
31030b57cec5SDimitry Andric             }
31040b57cec5SDimitry Andric           }
31050b57cec5SDimitry Andric           strm.Printf("%*s", addr_nibble_width + 2, "");
31060b57cec5SDimitry Andric         }
31070b57cec5SDimitry Andric         break;
31080b57cec5SDimitry Andric 
31090b57cec5SDimitry Andric       case 'r': {
31100b57cec5SDimitry Andric         size_t ref_count = 0;
31110b57cec5SDimitry Andric         ModuleSP module_sp(module->shared_from_this());
31120b57cec5SDimitry Andric         if (module_sp) {
31130b57cec5SDimitry Andric           // Take one away to make sure we don't count our local "module_sp"
31140b57cec5SDimitry Andric           ref_count = module_sp.use_count() - 1;
31150b57cec5SDimitry Andric         }
31160b57cec5SDimitry Andric         if (width)
31170b57cec5SDimitry Andric           strm.Printf("{%*" PRIu64 "}", width, (uint64_t)ref_count);
31180b57cec5SDimitry Andric         else
31190b57cec5SDimitry Andric           strm.Printf("{%" PRIu64 "}", (uint64_t)ref_count);
31200b57cec5SDimitry Andric       } break;
31210b57cec5SDimitry Andric 
31220b57cec5SDimitry Andric       case 's':
31230b57cec5SDimitry Andric       case 'S': {
31249dba64beSDimitry Andric         if (const SymbolFile *symbol_file = module->GetSymbolFile()) {
31259dba64beSDimitry Andric           const FileSpec symfile_spec =
31269dba64beSDimitry Andric               symbol_file->GetObjectFile()->GetFileSpec();
31270b57cec5SDimitry Andric           if (format_char == 'S') {
31280b57cec5SDimitry Andric             // Dump symbol file only if different from module file
31290b57cec5SDimitry Andric             if (!symfile_spec || symfile_spec == module->GetFileSpec()) {
31300b57cec5SDimitry Andric               print_space = false;
31310b57cec5SDimitry Andric               break;
31320b57cec5SDimitry Andric             }
31330b57cec5SDimitry Andric             // Add a newline and indent past the index
31340b57cec5SDimitry Andric             strm.Printf("\n%*s", indent, "");
31350b57cec5SDimitry Andric           }
31360b57cec5SDimitry Andric           DumpFullpath(strm, &symfile_spec, width);
31370b57cec5SDimitry Andric           dump_object_name = true;
31380b57cec5SDimitry Andric           break;
31390b57cec5SDimitry Andric         }
31400b57cec5SDimitry Andric         strm.Printf("%.*s", width, "<NONE>");
31410b57cec5SDimitry Andric       } break;
31420b57cec5SDimitry Andric 
31430b57cec5SDimitry Andric       case 'm':
31440b57cec5SDimitry Andric         strm.Format("{0:%c}", llvm::fmt_align(module->GetModificationTime(),
31450b57cec5SDimitry Andric                                               llvm::AlignStyle::Left, width));
31460b57cec5SDimitry Andric         break;
31470b57cec5SDimitry Andric 
31480b57cec5SDimitry Andric       case 'p':
31490b57cec5SDimitry Andric         strm.Printf("%p", static_cast<void *>(module));
31500b57cec5SDimitry Andric         break;
31510b57cec5SDimitry Andric 
31520b57cec5SDimitry Andric       case 'u':
31530b57cec5SDimitry Andric         DumpModuleUUID(strm, module);
31540b57cec5SDimitry Andric         break;
31550b57cec5SDimitry Andric 
31560b57cec5SDimitry Andric       default:
31570b57cec5SDimitry Andric         break;
31580b57cec5SDimitry Andric       }
31590b57cec5SDimitry Andric     }
31600b57cec5SDimitry Andric     if (dump_object_name) {
31610b57cec5SDimitry Andric       const char *object_name = module->GetObjectName().GetCString();
31620b57cec5SDimitry Andric       if (object_name)
31630b57cec5SDimitry Andric         strm.Printf("(%s)", object_name);
31640b57cec5SDimitry Andric     }
31650b57cec5SDimitry Andric     strm.EOL();
31660b57cec5SDimitry Andric   }
31670b57cec5SDimitry Andric 
31680b57cec5SDimitry Andric   CommandOptions m_options;
31690b57cec5SDimitry Andric };
31700b57cec5SDimitry Andric 
31710b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesShowUnwind
31720b57cec5SDimitry Andric 
31730b57cec5SDimitry Andric // Lookup unwind information in images
31749dba64beSDimitry Andric #define LLDB_OPTIONS_target_modules_show_unwind
31759dba64beSDimitry Andric #include "CommandOptions.inc"
31760b57cec5SDimitry Andric 
31770b57cec5SDimitry Andric class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {
31780b57cec5SDimitry Andric public:
31790b57cec5SDimitry Andric   enum {
31800b57cec5SDimitry Andric     eLookupTypeInvalid = -1,
31810b57cec5SDimitry Andric     eLookupTypeAddress = 0,
31820b57cec5SDimitry Andric     eLookupTypeSymbol,
31830b57cec5SDimitry Andric     eLookupTypeFunction,
31840b57cec5SDimitry Andric     eLookupTypeFunctionOrSymbol,
31850b57cec5SDimitry Andric     kNumLookupTypes
31860b57cec5SDimitry Andric   };
31870b57cec5SDimitry Andric 
31880b57cec5SDimitry Andric   class CommandOptions : public Options {
31890b57cec5SDimitry Andric   public:
CommandOptions()3190*5f7ddb14SDimitry Andric     CommandOptions() : Options(), m_str() {}
31910b57cec5SDimitry Andric 
31920b57cec5SDimitry Andric     ~CommandOptions() override = default;
31930b57cec5SDimitry Andric 
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)31940b57cec5SDimitry Andric     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
31950b57cec5SDimitry Andric                           ExecutionContext *execution_context) override {
31960b57cec5SDimitry Andric       Status error;
31970b57cec5SDimitry Andric 
31980b57cec5SDimitry Andric       const int short_option = m_getopt_table[option_idx].val;
31990b57cec5SDimitry Andric 
32000b57cec5SDimitry Andric       switch (short_option) {
32010b57cec5SDimitry Andric       case 'a': {
32025ffd83dbSDimitry Andric         m_str = std::string(option_arg);
32030b57cec5SDimitry Andric         m_type = eLookupTypeAddress;
32040b57cec5SDimitry Andric         m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
32050b57cec5SDimitry Andric                                             LLDB_INVALID_ADDRESS, &error);
32060b57cec5SDimitry Andric         if (m_addr == LLDB_INVALID_ADDRESS)
32070b57cec5SDimitry Andric           error.SetErrorStringWithFormat("invalid address string '%s'",
32080b57cec5SDimitry Andric                                          option_arg.str().c_str());
32090b57cec5SDimitry Andric         break;
32100b57cec5SDimitry Andric       }
32110b57cec5SDimitry Andric 
32120b57cec5SDimitry Andric       case 'n':
32135ffd83dbSDimitry Andric         m_str = std::string(option_arg);
32140b57cec5SDimitry Andric         m_type = eLookupTypeFunctionOrSymbol;
32150b57cec5SDimitry Andric         break;
32160b57cec5SDimitry Andric 
32170b57cec5SDimitry Andric       default:
32189dba64beSDimitry Andric         llvm_unreachable("Unimplemented option");
32190b57cec5SDimitry Andric       }
32200b57cec5SDimitry Andric 
32210b57cec5SDimitry Andric       return error;
32220b57cec5SDimitry Andric     }
32230b57cec5SDimitry Andric 
OptionParsingStarting(ExecutionContext * execution_context)32240b57cec5SDimitry Andric     void OptionParsingStarting(ExecutionContext *execution_context) override {
32250b57cec5SDimitry Andric       m_type = eLookupTypeInvalid;
32260b57cec5SDimitry Andric       m_str.clear();
32270b57cec5SDimitry Andric       m_addr = LLDB_INVALID_ADDRESS;
32280b57cec5SDimitry Andric     }
32290b57cec5SDimitry Andric 
GetDefinitions()32300b57cec5SDimitry Andric     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
32310b57cec5SDimitry Andric       return llvm::makeArrayRef(g_target_modules_show_unwind_options);
32320b57cec5SDimitry Andric     }
32330b57cec5SDimitry Andric 
32340b57cec5SDimitry Andric     // Instance variables to hold the values for command options.
32350b57cec5SDimitry Andric 
3236*5f7ddb14SDimitry Andric     int m_type = eLookupTypeInvalid; // Should be a eLookupTypeXXX enum after
3237*5f7ddb14SDimitry Andric                                      // parsing options
32380b57cec5SDimitry Andric     std::string m_str; // Holds name lookup
3239*5f7ddb14SDimitry Andric     lldb::addr_t m_addr = LLDB_INVALID_ADDRESS; // Holds the address to lookup
32400b57cec5SDimitry Andric   };
32410b57cec5SDimitry Andric 
CommandObjectTargetModulesShowUnwind(CommandInterpreter & interpreter)32420b57cec5SDimitry Andric   CommandObjectTargetModulesShowUnwind(CommandInterpreter &interpreter)
32430b57cec5SDimitry Andric       : CommandObjectParsed(
32440b57cec5SDimitry Andric             interpreter, "target modules show-unwind",
32450b57cec5SDimitry Andric             "Show synthesized unwind instructions for a function.", nullptr,
32460b57cec5SDimitry Andric             eCommandRequiresTarget | eCommandRequiresProcess |
32470b57cec5SDimitry Andric                 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
32480b57cec5SDimitry Andric         m_options() {}
32490b57cec5SDimitry Andric 
32500b57cec5SDimitry Andric   ~CommandObjectTargetModulesShowUnwind() override = default;
32510b57cec5SDimitry Andric 
GetOptions()32520b57cec5SDimitry Andric   Options *GetOptions() override { return &m_options; }
32530b57cec5SDimitry Andric 
32540b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)32550b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
32560b57cec5SDimitry Andric     Target *target = m_exe_ctx.GetTargetPtr();
32570b57cec5SDimitry Andric     Process *process = m_exe_ctx.GetProcessPtr();
32580b57cec5SDimitry Andric     ABI *abi = nullptr;
32590b57cec5SDimitry Andric     if (process)
32600b57cec5SDimitry Andric       abi = process->GetABI().get();
32610b57cec5SDimitry Andric 
32620b57cec5SDimitry Andric     if (process == nullptr) {
32630b57cec5SDimitry Andric       result.AppendError(
32640b57cec5SDimitry Andric           "You must have a process running to use this command.");
32650b57cec5SDimitry Andric       return false;
32660b57cec5SDimitry Andric     }
32670b57cec5SDimitry Andric 
32680b57cec5SDimitry Andric     ThreadList threads(process->GetThreadList());
32690b57cec5SDimitry Andric     if (threads.GetSize() == 0) {
32700b57cec5SDimitry Andric       result.AppendError("The process must be paused to use this command.");
32710b57cec5SDimitry Andric       return false;
32720b57cec5SDimitry Andric     }
32730b57cec5SDimitry Andric 
32740b57cec5SDimitry Andric     ThreadSP thread(threads.GetThreadAtIndex(0));
32750b57cec5SDimitry Andric     if (!thread) {
32760b57cec5SDimitry Andric       result.AppendError("The process must be paused to use this command.");
32770b57cec5SDimitry Andric       return false;
32780b57cec5SDimitry Andric     }
32790b57cec5SDimitry Andric 
32800b57cec5SDimitry Andric     SymbolContextList sc_list;
32810b57cec5SDimitry Andric 
32820b57cec5SDimitry Andric     if (m_options.m_type == eLookupTypeFunctionOrSymbol) {
32830b57cec5SDimitry Andric       ConstString function_name(m_options.m_str.c_str());
32840b57cec5SDimitry Andric       target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto,
32859dba64beSDimitry Andric                                         true, false, sc_list);
32860b57cec5SDimitry Andric     } else if (m_options.m_type == eLookupTypeAddress && target) {
32870b57cec5SDimitry Andric       Address addr;
32880b57cec5SDimitry Andric       if (target->GetSectionLoadList().ResolveLoadAddress(m_options.m_addr,
32890b57cec5SDimitry Andric                                                           addr)) {
32900b57cec5SDimitry Andric         SymbolContext sc;
32910b57cec5SDimitry Andric         ModuleSP module_sp(addr.GetModule());
32920b57cec5SDimitry Andric         module_sp->ResolveSymbolContextForAddress(addr,
32930b57cec5SDimitry Andric                                                   eSymbolContextEverything, sc);
32940b57cec5SDimitry Andric         if (sc.function || sc.symbol) {
32950b57cec5SDimitry Andric           sc_list.Append(sc);
32960b57cec5SDimitry Andric         }
32970b57cec5SDimitry Andric       }
32980b57cec5SDimitry Andric     } else {
32990b57cec5SDimitry Andric       result.AppendError(
33000b57cec5SDimitry Andric           "address-expression or function name option must be specified.");
33010b57cec5SDimitry Andric       return false;
33020b57cec5SDimitry Andric     }
33030b57cec5SDimitry Andric 
33040b57cec5SDimitry Andric     size_t num_matches = sc_list.GetSize();
33050b57cec5SDimitry Andric     if (num_matches == 0) {
33060b57cec5SDimitry Andric       result.AppendErrorWithFormat("no unwind data found that matches '%s'.",
33070b57cec5SDimitry Andric                                    m_options.m_str.c_str());
33080b57cec5SDimitry Andric       return false;
33090b57cec5SDimitry Andric     }
33100b57cec5SDimitry Andric 
33110b57cec5SDimitry Andric     for (uint32_t idx = 0; idx < num_matches; idx++) {
33120b57cec5SDimitry Andric       SymbolContext sc;
33130b57cec5SDimitry Andric       sc_list.GetContextAtIndex(idx, sc);
33140b57cec5SDimitry Andric       if (sc.symbol == nullptr && sc.function == nullptr)
33150b57cec5SDimitry Andric         continue;
33160b57cec5SDimitry Andric       if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr)
33170b57cec5SDimitry Andric         continue;
33180b57cec5SDimitry Andric       AddressRange range;
33190b57cec5SDimitry Andric       if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,
33200b57cec5SDimitry Andric                               false, range))
33210b57cec5SDimitry Andric         continue;
33220b57cec5SDimitry Andric       if (!range.GetBaseAddress().IsValid())
33230b57cec5SDimitry Andric         continue;
33240b57cec5SDimitry Andric       ConstString funcname(sc.GetFunctionName());
33250b57cec5SDimitry Andric       if (funcname.IsEmpty())
33260b57cec5SDimitry Andric         continue;
33270b57cec5SDimitry Andric       addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
33280b57cec5SDimitry Andric       if (abi)
33290b57cec5SDimitry Andric         start_addr = abi->FixCodeAddress(start_addr);
33300b57cec5SDimitry Andric 
33310b57cec5SDimitry Andric       FuncUnwindersSP func_unwinders_sp(
33320b57cec5SDimitry Andric           sc.module_sp->GetUnwindTable()
33330b57cec5SDimitry Andric               .GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
33340b57cec5SDimitry Andric       if (!func_unwinders_sp)
33350b57cec5SDimitry Andric         continue;
33360b57cec5SDimitry Andric 
33370b57cec5SDimitry Andric       result.GetOutputStream().Printf(
3338af732203SDimitry Andric           "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n",
33390b57cec5SDimitry Andric           sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(),
33400b57cec5SDimitry Andric           funcname.AsCString(), start_addr);
33410b57cec5SDimitry Andric 
3342af732203SDimitry Andric       Args args;
3343af732203SDimitry Andric       target->GetUserSpecifiedTrapHandlerNames(args);
3344af732203SDimitry Andric       size_t count = args.GetArgumentCount();
3345af732203SDimitry Andric       for (size_t i = 0; i < count; i++) {
3346af732203SDimitry Andric         const char *trap_func_name = args.GetArgumentAtIndex(i);
3347af732203SDimitry Andric         if (strcmp(funcname.GetCString(), trap_func_name) == 0)
3348af732203SDimitry Andric           result.GetOutputStream().Printf(
3349af732203SDimitry Andric               "This function is "
3350af732203SDimitry Andric               "treated as a trap handler function via user setting.\n");
3351af732203SDimitry Andric       }
3352af732203SDimitry Andric       PlatformSP platform_sp(target->GetPlatform());
3353af732203SDimitry Andric       if (platform_sp) {
3354af732203SDimitry Andric         const std::vector<ConstString> trap_handler_names(
3355af732203SDimitry Andric             platform_sp->GetTrapHandlerSymbolNames());
3356af732203SDimitry Andric         for (ConstString trap_name : trap_handler_names) {
3357af732203SDimitry Andric           if (trap_name == funcname) {
3358af732203SDimitry Andric             result.GetOutputStream().Printf(
3359af732203SDimitry Andric                 "This function's "
3360af732203SDimitry Andric                 "name is listed by the platform as a trap handler.\n");
3361af732203SDimitry Andric           }
3362af732203SDimitry Andric         }
3363af732203SDimitry Andric       }
3364af732203SDimitry Andric 
3365af732203SDimitry Andric       result.GetOutputStream().Printf("\n");
3366af732203SDimitry Andric 
33670b57cec5SDimitry Andric       UnwindPlanSP non_callsite_unwind_plan =
33680b57cec5SDimitry Andric           func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread);
33690b57cec5SDimitry Andric       if (non_callsite_unwind_plan) {
33700b57cec5SDimitry Andric         result.GetOutputStream().Printf(
33710b57cec5SDimitry Andric             "Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n",
33720b57cec5SDimitry Andric             non_callsite_unwind_plan->GetSourceName().AsCString());
33730b57cec5SDimitry Andric       }
33740b57cec5SDimitry Andric       UnwindPlanSP callsite_unwind_plan =
33750b57cec5SDimitry Andric           func_unwinders_sp->GetUnwindPlanAtCallSite(*target, *thread);
33760b57cec5SDimitry Andric       if (callsite_unwind_plan) {
33770b57cec5SDimitry Andric         result.GetOutputStream().Printf(
33780b57cec5SDimitry Andric             "Synchronous (restricted to call-sites) UnwindPlan is '%s'\n",
33790b57cec5SDimitry Andric             callsite_unwind_plan->GetSourceName().AsCString());
33800b57cec5SDimitry Andric       }
33810b57cec5SDimitry Andric       UnwindPlanSP fast_unwind_plan =
33820b57cec5SDimitry Andric           func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread);
33830b57cec5SDimitry Andric       if (fast_unwind_plan) {
33840b57cec5SDimitry Andric         result.GetOutputStream().Printf(
33850b57cec5SDimitry Andric             "Fast UnwindPlan is '%s'\n",
33860b57cec5SDimitry Andric             fast_unwind_plan->GetSourceName().AsCString());
33870b57cec5SDimitry Andric       }
33880b57cec5SDimitry Andric 
33890b57cec5SDimitry Andric       result.GetOutputStream().Printf("\n");
33900b57cec5SDimitry Andric 
33910b57cec5SDimitry Andric       UnwindPlanSP assembly_sp =
33920b57cec5SDimitry Andric           func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread);
33930b57cec5SDimitry Andric       if (assembly_sp) {
33940b57cec5SDimitry Andric         result.GetOutputStream().Printf(
33950b57cec5SDimitry Andric             "Assembly language inspection UnwindPlan:\n");
33960b57cec5SDimitry Andric         assembly_sp->Dump(result.GetOutputStream(), thread.get(),
33970b57cec5SDimitry Andric                           LLDB_INVALID_ADDRESS);
33980b57cec5SDimitry Andric         result.GetOutputStream().Printf("\n");
33990b57cec5SDimitry Andric       }
34000b57cec5SDimitry Andric 
34019dba64beSDimitry Andric       UnwindPlanSP of_unwind_sp =
34029dba64beSDimitry Andric           func_unwinders_sp->GetObjectFileUnwindPlan(*target);
34039dba64beSDimitry Andric       if (of_unwind_sp) {
34049dba64beSDimitry Andric         result.GetOutputStream().Printf("object file UnwindPlan:\n");
34059dba64beSDimitry Andric         of_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
34069dba64beSDimitry Andric                            LLDB_INVALID_ADDRESS);
34079dba64beSDimitry Andric         result.GetOutputStream().Printf("\n");
34089dba64beSDimitry Andric       }
34099dba64beSDimitry Andric 
34109dba64beSDimitry Andric       UnwindPlanSP of_unwind_augmented_sp =
3411480093f4SDimitry Andric           func_unwinders_sp->GetObjectFileAugmentedUnwindPlan(*target, *thread);
34129dba64beSDimitry Andric       if (of_unwind_augmented_sp) {
34139dba64beSDimitry Andric         result.GetOutputStream().Printf("object file augmented UnwindPlan:\n");
34149dba64beSDimitry Andric         of_unwind_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
34159dba64beSDimitry Andric                                      LLDB_INVALID_ADDRESS);
34169dba64beSDimitry Andric         result.GetOutputStream().Printf("\n");
34179dba64beSDimitry Andric       }
34189dba64beSDimitry Andric 
34190b57cec5SDimitry Andric       UnwindPlanSP ehframe_sp =
34200b57cec5SDimitry Andric           func_unwinders_sp->GetEHFrameUnwindPlan(*target);
34210b57cec5SDimitry Andric       if (ehframe_sp) {
34220b57cec5SDimitry Andric         result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
34230b57cec5SDimitry Andric         ehframe_sp->Dump(result.GetOutputStream(), thread.get(),
34240b57cec5SDimitry Andric                          LLDB_INVALID_ADDRESS);
34250b57cec5SDimitry Andric         result.GetOutputStream().Printf("\n");
34260b57cec5SDimitry Andric       }
34270b57cec5SDimitry Andric 
34280b57cec5SDimitry Andric       UnwindPlanSP ehframe_augmented_sp =
34290b57cec5SDimitry Andric           func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread);
34300b57cec5SDimitry Andric       if (ehframe_augmented_sp) {
34310b57cec5SDimitry Andric         result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
34320b57cec5SDimitry Andric         ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
34330b57cec5SDimitry Andric                                    LLDB_INVALID_ADDRESS);
34340b57cec5SDimitry Andric         result.GetOutputStream().Printf("\n");
34350b57cec5SDimitry Andric       }
34360b57cec5SDimitry Andric 
34370b57cec5SDimitry Andric       if (UnwindPlanSP plan_sp =
34380b57cec5SDimitry Andric               func_unwinders_sp->GetDebugFrameUnwindPlan(*target)) {
34390b57cec5SDimitry Andric         result.GetOutputStream().Printf("debug_frame UnwindPlan:\n");
34400b57cec5SDimitry Andric         plan_sp->Dump(result.GetOutputStream(), thread.get(),
34410b57cec5SDimitry Andric                       LLDB_INVALID_ADDRESS);
34420b57cec5SDimitry Andric         result.GetOutputStream().Printf("\n");
34430b57cec5SDimitry Andric       }
34440b57cec5SDimitry Andric 
34450b57cec5SDimitry Andric       if (UnwindPlanSP plan_sp =
34460b57cec5SDimitry Andric               func_unwinders_sp->GetDebugFrameAugmentedUnwindPlan(*target,
34470b57cec5SDimitry Andric                                                                   *thread)) {
34480b57cec5SDimitry Andric         result.GetOutputStream().Printf("debug_frame augmented UnwindPlan:\n");
34490b57cec5SDimitry Andric         plan_sp->Dump(result.GetOutputStream(), thread.get(),
34500b57cec5SDimitry Andric                       LLDB_INVALID_ADDRESS);
34510b57cec5SDimitry Andric         result.GetOutputStream().Printf("\n");
34520b57cec5SDimitry Andric       }
34530b57cec5SDimitry Andric 
34540b57cec5SDimitry Andric       UnwindPlanSP arm_unwind_sp =
34550b57cec5SDimitry Andric           func_unwinders_sp->GetArmUnwindUnwindPlan(*target);
34560b57cec5SDimitry Andric       if (arm_unwind_sp) {
34570b57cec5SDimitry Andric         result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
34580b57cec5SDimitry Andric         arm_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
34590b57cec5SDimitry Andric                             LLDB_INVALID_ADDRESS);
34600b57cec5SDimitry Andric         result.GetOutputStream().Printf("\n");
34610b57cec5SDimitry Andric       }
34620b57cec5SDimitry Andric 
34630b57cec5SDimitry Andric       if (UnwindPlanSP symfile_plan_sp =
34640b57cec5SDimitry Andric               func_unwinders_sp->GetSymbolFileUnwindPlan(*thread)) {
34650b57cec5SDimitry Andric         result.GetOutputStream().Printf("Symbol file UnwindPlan:\n");
34660b57cec5SDimitry Andric         symfile_plan_sp->Dump(result.GetOutputStream(), thread.get(),
34670b57cec5SDimitry Andric                               LLDB_INVALID_ADDRESS);
34680b57cec5SDimitry Andric         result.GetOutputStream().Printf("\n");
34690b57cec5SDimitry Andric       }
34700b57cec5SDimitry Andric 
34710b57cec5SDimitry Andric       UnwindPlanSP compact_unwind_sp =
34720b57cec5SDimitry Andric           func_unwinders_sp->GetCompactUnwindUnwindPlan(*target);
34730b57cec5SDimitry Andric       if (compact_unwind_sp) {
34740b57cec5SDimitry Andric         result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
34750b57cec5SDimitry Andric         compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
34760b57cec5SDimitry Andric                                 LLDB_INVALID_ADDRESS);
34770b57cec5SDimitry Andric         result.GetOutputStream().Printf("\n");
34780b57cec5SDimitry Andric       }
34790b57cec5SDimitry Andric 
34800b57cec5SDimitry Andric       if (fast_unwind_plan) {
34810b57cec5SDimitry Andric         result.GetOutputStream().Printf("Fast UnwindPlan:\n");
34820b57cec5SDimitry Andric         fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(),
34830b57cec5SDimitry Andric                                LLDB_INVALID_ADDRESS);
34840b57cec5SDimitry Andric         result.GetOutputStream().Printf("\n");
34850b57cec5SDimitry Andric       }
34860b57cec5SDimitry Andric 
34870b57cec5SDimitry Andric       ABISP abi_sp = process->GetABI();
34880b57cec5SDimitry Andric       if (abi_sp) {
34890b57cec5SDimitry Andric         UnwindPlan arch_default(lldb::eRegisterKindGeneric);
34900b57cec5SDimitry Andric         if (abi_sp->CreateDefaultUnwindPlan(arch_default)) {
34910b57cec5SDimitry Andric           result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
34920b57cec5SDimitry Andric           arch_default.Dump(result.GetOutputStream(), thread.get(),
34930b57cec5SDimitry Andric                             LLDB_INVALID_ADDRESS);
34940b57cec5SDimitry Andric           result.GetOutputStream().Printf("\n");
34950b57cec5SDimitry Andric         }
34960b57cec5SDimitry Andric 
34970b57cec5SDimitry Andric         UnwindPlan arch_entry(lldb::eRegisterKindGeneric);
34980b57cec5SDimitry Andric         if (abi_sp->CreateFunctionEntryUnwindPlan(arch_entry)) {
34990b57cec5SDimitry Andric           result.GetOutputStream().Printf(
35000b57cec5SDimitry Andric               "Arch default at entry point UnwindPlan:\n");
35010b57cec5SDimitry Andric           arch_entry.Dump(result.GetOutputStream(), thread.get(),
35020b57cec5SDimitry Andric                           LLDB_INVALID_ADDRESS);
35030b57cec5SDimitry Andric           result.GetOutputStream().Printf("\n");
35040b57cec5SDimitry Andric         }
35050b57cec5SDimitry Andric       }
35060b57cec5SDimitry Andric 
35070b57cec5SDimitry Andric       result.GetOutputStream().Printf("\n");
35080b57cec5SDimitry Andric     }
35090b57cec5SDimitry Andric     return result.Succeeded();
35100b57cec5SDimitry Andric   }
35110b57cec5SDimitry Andric 
35120b57cec5SDimitry Andric   CommandOptions m_options;
35130b57cec5SDimitry Andric };
35140b57cec5SDimitry Andric 
35150b57cec5SDimitry Andric // Lookup information in images
35169dba64beSDimitry Andric #define LLDB_OPTIONS_target_modules_lookup
35179dba64beSDimitry Andric #include "CommandOptions.inc"
35180b57cec5SDimitry Andric 
35190b57cec5SDimitry Andric class CommandObjectTargetModulesLookup : public CommandObjectParsed {
35200b57cec5SDimitry Andric public:
35210b57cec5SDimitry Andric   enum {
35220b57cec5SDimitry Andric     eLookupTypeInvalid = -1,
35230b57cec5SDimitry Andric     eLookupTypeAddress = 0,
35240b57cec5SDimitry Andric     eLookupTypeSymbol,
35250b57cec5SDimitry Andric     eLookupTypeFileLine, // Line is optional
35260b57cec5SDimitry Andric     eLookupTypeFunction,
35270b57cec5SDimitry Andric     eLookupTypeFunctionOrSymbol,
35280b57cec5SDimitry Andric     eLookupTypeType,
35290b57cec5SDimitry Andric     kNumLookupTypes
35300b57cec5SDimitry Andric   };
35310b57cec5SDimitry Andric 
35320b57cec5SDimitry Andric   class CommandOptions : public Options {
35330b57cec5SDimitry Andric   public:
CommandOptions()35340b57cec5SDimitry Andric     CommandOptions() : Options() { OptionParsingStarting(nullptr); }
35350b57cec5SDimitry Andric 
35360b57cec5SDimitry Andric     ~CommandOptions() override = default;
35370b57cec5SDimitry Andric 
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)35380b57cec5SDimitry Andric     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
35390b57cec5SDimitry Andric                           ExecutionContext *execution_context) override {
35400b57cec5SDimitry Andric       Status error;
35410b57cec5SDimitry Andric 
35420b57cec5SDimitry Andric       const int short_option = m_getopt_table[option_idx].val;
35430b57cec5SDimitry Andric 
35440b57cec5SDimitry Andric       switch (short_option) {
35450b57cec5SDimitry Andric       case 'a': {
35460b57cec5SDimitry Andric         m_type = eLookupTypeAddress;
35470b57cec5SDimitry Andric         m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
35480b57cec5SDimitry Andric                                             LLDB_INVALID_ADDRESS, &error);
35490b57cec5SDimitry Andric       } break;
35500b57cec5SDimitry Andric 
35510b57cec5SDimitry Andric       case 'o':
35520b57cec5SDimitry Andric         if (option_arg.getAsInteger(0, m_offset))
35530b57cec5SDimitry Andric           error.SetErrorStringWithFormat("invalid offset string '%s'",
35540b57cec5SDimitry Andric                                          option_arg.str().c_str());
35550b57cec5SDimitry Andric         break;
35560b57cec5SDimitry Andric 
35570b57cec5SDimitry Andric       case 's':
35585ffd83dbSDimitry Andric         m_str = std::string(option_arg);
35590b57cec5SDimitry Andric         m_type = eLookupTypeSymbol;
35600b57cec5SDimitry Andric         break;
35610b57cec5SDimitry Andric 
35620b57cec5SDimitry Andric       case 'f':
35630b57cec5SDimitry Andric         m_file.SetFile(option_arg, FileSpec::Style::native);
35640b57cec5SDimitry Andric         m_type = eLookupTypeFileLine;
35650b57cec5SDimitry Andric         break;
35660b57cec5SDimitry Andric 
35670b57cec5SDimitry Andric       case 'i':
35680b57cec5SDimitry Andric         m_include_inlines = false;
35690b57cec5SDimitry Andric         break;
35700b57cec5SDimitry Andric 
35710b57cec5SDimitry Andric       case 'l':
35720b57cec5SDimitry Andric         if (option_arg.getAsInteger(0, m_line_number))
35730b57cec5SDimitry Andric           error.SetErrorStringWithFormat("invalid line number string '%s'",
35740b57cec5SDimitry Andric                                          option_arg.str().c_str());
35750b57cec5SDimitry Andric         else if (m_line_number == 0)
35760b57cec5SDimitry Andric           error.SetErrorString("zero is an invalid line number");
35770b57cec5SDimitry Andric         m_type = eLookupTypeFileLine;
35780b57cec5SDimitry Andric         break;
35790b57cec5SDimitry Andric 
35800b57cec5SDimitry Andric       case 'F':
35815ffd83dbSDimitry Andric         m_str = std::string(option_arg);
35820b57cec5SDimitry Andric         m_type = eLookupTypeFunction;
35830b57cec5SDimitry Andric         break;
35840b57cec5SDimitry Andric 
35850b57cec5SDimitry Andric       case 'n':
35865ffd83dbSDimitry Andric         m_str = std::string(option_arg);
35870b57cec5SDimitry Andric         m_type = eLookupTypeFunctionOrSymbol;
35880b57cec5SDimitry Andric         break;
35890b57cec5SDimitry Andric 
35900b57cec5SDimitry Andric       case 't':
35915ffd83dbSDimitry Andric         m_str = std::string(option_arg);
35920b57cec5SDimitry Andric         m_type = eLookupTypeType;
35930b57cec5SDimitry Andric         break;
35940b57cec5SDimitry Andric 
35950b57cec5SDimitry Andric       case 'v':
35960b57cec5SDimitry Andric         m_verbose = true;
35970b57cec5SDimitry Andric         break;
35980b57cec5SDimitry Andric 
35990b57cec5SDimitry Andric       case 'A':
36000b57cec5SDimitry Andric         m_print_all = true;
36010b57cec5SDimitry Andric         break;
36020b57cec5SDimitry Andric 
36030b57cec5SDimitry Andric       case 'r':
36040b57cec5SDimitry Andric         m_use_regex = true;
36050b57cec5SDimitry Andric         break;
36069dba64beSDimitry Andric       default:
36079dba64beSDimitry Andric         llvm_unreachable("Unimplemented option");
36080b57cec5SDimitry Andric       }
36090b57cec5SDimitry Andric 
36100b57cec5SDimitry Andric       return error;
36110b57cec5SDimitry Andric     }
36120b57cec5SDimitry Andric 
OptionParsingStarting(ExecutionContext * execution_context)36130b57cec5SDimitry Andric     void OptionParsingStarting(ExecutionContext *execution_context) override {
36140b57cec5SDimitry Andric       m_type = eLookupTypeInvalid;
36150b57cec5SDimitry Andric       m_str.clear();
36160b57cec5SDimitry Andric       m_file.Clear();
36170b57cec5SDimitry Andric       m_addr = LLDB_INVALID_ADDRESS;
36180b57cec5SDimitry Andric       m_offset = 0;
36190b57cec5SDimitry Andric       m_line_number = 0;
36200b57cec5SDimitry Andric       m_use_regex = false;
36210b57cec5SDimitry Andric       m_include_inlines = true;
36220b57cec5SDimitry Andric       m_verbose = false;
36230b57cec5SDimitry Andric       m_print_all = false;
36240b57cec5SDimitry Andric     }
36250b57cec5SDimitry Andric 
GetDefinitions()36260b57cec5SDimitry Andric     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
36270b57cec5SDimitry Andric       return llvm::makeArrayRef(g_target_modules_lookup_options);
36280b57cec5SDimitry Andric     }
36290b57cec5SDimitry Andric 
36300b57cec5SDimitry Andric     int m_type;        // Should be a eLookupTypeXXX enum after parsing options
36310b57cec5SDimitry Andric     std::string m_str; // Holds name lookup
36320b57cec5SDimitry Andric     FileSpec m_file;   // Files for file lookups
36330b57cec5SDimitry Andric     lldb::addr_t m_addr; // Holds the address to lookup
36340b57cec5SDimitry Andric     lldb::addr_t
36350b57cec5SDimitry Andric         m_offset; // Subtract this offset from m_addr before doing lookups.
36360b57cec5SDimitry Andric     uint32_t m_line_number; // Line number for file+line lookups
36370b57cec5SDimitry Andric     bool m_use_regex;       // Name lookups in m_str are regular expressions.
36380b57cec5SDimitry Andric     bool m_include_inlines; // Check for inline entries when looking up by
36390b57cec5SDimitry Andric                             // file/line.
36400b57cec5SDimitry Andric     bool m_verbose;         // Enable verbose lookup info
36410b57cec5SDimitry Andric     bool m_print_all; // Print all matches, even in cases where there's a best
36420b57cec5SDimitry Andric                       // match.
36430b57cec5SDimitry Andric   };
36440b57cec5SDimitry Andric 
CommandObjectTargetModulesLookup(CommandInterpreter & interpreter)36450b57cec5SDimitry Andric   CommandObjectTargetModulesLookup(CommandInterpreter &interpreter)
36460b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "target modules lookup",
36470b57cec5SDimitry Andric                             "Look up information within executable and "
36480b57cec5SDimitry Andric                             "dependent shared library images.",
36490b57cec5SDimitry Andric                             nullptr, eCommandRequiresTarget),
36500b57cec5SDimitry Andric         m_options() {
36510b57cec5SDimitry Andric     CommandArgumentEntry arg;
36520b57cec5SDimitry Andric     CommandArgumentData file_arg;
36530b57cec5SDimitry Andric 
36540b57cec5SDimitry Andric     // Define the first (and only) variant of this arg.
36550b57cec5SDimitry Andric     file_arg.arg_type = eArgTypeFilename;
36560b57cec5SDimitry Andric     file_arg.arg_repetition = eArgRepeatStar;
36570b57cec5SDimitry Andric 
36580b57cec5SDimitry Andric     // There is only one variant this argument could be; put it into the
36590b57cec5SDimitry Andric     // argument entry.
36600b57cec5SDimitry Andric     arg.push_back(file_arg);
36610b57cec5SDimitry Andric 
36620b57cec5SDimitry Andric     // Push the data for the first argument into the m_arguments vector.
36630b57cec5SDimitry Andric     m_arguments.push_back(arg);
36640b57cec5SDimitry Andric   }
36650b57cec5SDimitry Andric 
36660b57cec5SDimitry Andric   ~CommandObjectTargetModulesLookup() override = default;
36670b57cec5SDimitry Andric 
GetOptions()36680b57cec5SDimitry Andric   Options *GetOptions() override { return &m_options; }
36690b57cec5SDimitry Andric 
LookupHere(CommandInterpreter & interpreter,CommandReturnObject & result,bool & syntax_error)36700b57cec5SDimitry Andric   bool LookupHere(CommandInterpreter &interpreter, CommandReturnObject &result,
36710b57cec5SDimitry Andric                   bool &syntax_error) {
36720b57cec5SDimitry Andric     switch (m_options.m_type) {
36730b57cec5SDimitry Andric     case eLookupTypeAddress:
36740b57cec5SDimitry Andric     case eLookupTypeFileLine:
36750b57cec5SDimitry Andric     case eLookupTypeFunction:
36760b57cec5SDimitry Andric     case eLookupTypeFunctionOrSymbol:
36770b57cec5SDimitry Andric     case eLookupTypeSymbol:
36780b57cec5SDimitry Andric     default:
36790b57cec5SDimitry Andric       return false;
36800b57cec5SDimitry Andric     case eLookupTypeType:
36810b57cec5SDimitry Andric       break;
36820b57cec5SDimitry Andric     }
36830b57cec5SDimitry Andric 
36840b57cec5SDimitry Andric     StackFrameSP frame = m_exe_ctx.GetFrameSP();
36850b57cec5SDimitry Andric 
36860b57cec5SDimitry Andric     if (!frame)
36870b57cec5SDimitry Andric       return false;
36880b57cec5SDimitry Andric 
36890b57cec5SDimitry Andric     const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
36900b57cec5SDimitry Andric 
36910b57cec5SDimitry Andric     if (!sym_ctx.module_sp)
36920b57cec5SDimitry Andric       return false;
36930b57cec5SDimitry Andric 
36940b57cec5SDimitry Andric     switch (m_options.m_type) {
36950b57cec5SDimitry Andric     default:
36960b57cec5SDimitry Andric       return false;
36970b57cec5SDimitry Andric     case eLookupTypeType:
36980b57cec5SDimitry Andric       if (!m_options.m_str.empty()) {
3699af732203SDimitry Andric         if (LookupTypeHere(&GetSelectedTarget(), m_interpreter,
3700af732203SDimitry Andric                            result.GetOutputStream(), *sym_ctx.module_sp,
3701af732203SDimitry Andric                            m_options.m_str.c_str(), m_options.m_use_regex)) {
37020b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishResult);
37030b57cec5SDimitry Andric           return true;
37040b57cec5SDimitry Andric         }
37050b57cec5SDimitry Andric       }
37060b57cec5SDimitry Andric       break;
37070b57cec5SDimitry Andric     }
37080b57cec5SDimitry Andric 
3709480093f4SDimitry Andric     return false;
37100b57cec5SDimitry Andric   }
37110b57cec5SDimitry Andric 
LookupInModule(CommandInterpreter & interpreter,Module * module,CommandReturnObject & result,bool & syntax_error)37120b57cec5SDimitry Andric   bool LookupInModule(CommandInterpreter &interpreter, Module *module,
37130b57cec5SDimitry Andric                       CommandReturnObject &result, bool &syntax_error) {
37140b57cec5SDimitry Andric     switch (m_options.m_type) {
37150b57cec5SDimitry Andric     case eLookupTypeAddress:
37160b57cec5SDimitry Andric       if (m_options.m_addr != LLDB_INVALID_ADDRESS) {
37170b57cec5SDimitry Andric         if (LookupAddressInModule(
37180b57cec5SDimitry Andric                 m_interpreter, result.GetOutputStream(), module,
37190b57cec5SDimitry Andric                 eSymbolContextEverything |
37200b57cec5SDimitry Andric                     (m_options.m_verbose
37210b57cec5SDimitry Andric                          ? static_cast<int>(eSymbolContextVariable)
37220b57cec5SDimitry Andric                          : 0),
37230b57cec5SDimitry Andric                 m_options.m_addr, m_options.m_offset, m_options.m_verbose)) {
37240b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishResult);
37250b57cec5SDimitry Andric           return true;
37260b57cec5SDimitry Andric         }
37270b57cec5SDimitry Andric       }
37280b57cec5SDimitry Andric       break;
37290b57cec5SDimitry Andric 
37300b57cec5SDimitry Andric     case eLookupTypeSymbol:
37310b57cec5SDimitry Andric       if (!m_options.m_str.empty()) {
37320b57cec5SDimitry Andric         if (LookupSymbolInModule(m_interpreter, result.GetOutputStream(),
37330b57cec5SDimitry Andric                                  module, m_options.m_str.c_str(),
37340b57cec5SDimitry Andric                                  m_options.m_use_regex, m_options.m_verbose)) {
37350b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishResult);
37360b57cec5SDimitry Andric           return true;
37370b57cec5SDimitry Andric         }
37380b57cec5SDimitry Andric       }
37390b57cec5SDimitry Andric       break;
37400b57cec5SDimitry Andric 
37410b57cec5SDimitry Andric     case eLookupTypeFileLine:
37420b57cec5SDimitry Andric       if (m_options.m_file) {
37430b57cec5SDimitry Andric         if (LookupFileAndLineInModule(
37440b57cec5SDimitry Andric                 m_interpreter, result.GetOutputStream(), module,
37450b57cec5SDimitry Andric                 m_options.m_file, m_options.m_line_number,
37460b57cec5SDimitry Andric                 m_options.m_include_inlines, m_options.m_verbose)) {
37470b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishResult);
37480b57cec5SDimitry Andric           return true;
37490b57cec5SDimitry Andric         }
37500b57cec5SDimitry Andric       }
37510b57cec5SDimitry Andric       break;
37520b57cec5SDimitry Andric 
37530b57cec5SDimitry Andric     case eLookupTypeFunctionOrSymbol:
37540b57cec5SDimitry Andric     case eLookupTypeFunction:
37550b57cec5SDimitry Andric       if (!m_options.m_str.empty()) {
37560b57cec5SDimitry Andric         if (LookupFunctionInModule(
37570b57cec5SDimitry Andric                 m_interpreter, result.GetOutputStream(), module,
37580b57cec5SDimitry Andric                 m_options.m_str.c_str(), m_options.m_use_regex,
37590b57cec5SDimitry Andric                 m_options.m_include_inlines,
37600b57cec5SDimitry Andric                 m_options.m_type ==
37610b57cec5SDimitry Andric                     eLookupTypeFunctionOrSymbol, // include symbols
37620b57cec5SDimitry Andric                 m_options.m_verbose)) {
37630b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishResult);
37640b57cec5SDimitry Andric           return true;
37650b57cec5SDimitry Andric         }
37660b57cec5SDimitry Andric       }
37670b57cec5SDimitry Andric       break;
37680b57cec5SDimitry Andric 
37690b57cec5SDimitry Andric     case eLookupTypeType:
37700b57cec5SDimitry Andric       if (!m_options.m_str.empty()) {
3771af732203SDimitry Andric         if (LookupTypeInModule(
3772af732203SDimitry Andric                 &GetSelectedTarget(), m_interpreter, result.GetOutputStream(),
3773af732203SDimitry Andric                 module, m_options.m_str.c_str(), m_options.m_use_regex)) {
37740b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishResult);
37750b57cec5SDimitry Andric           return true;
37760b57cec5SDimitry Andric         }
37770b57cec5SDimitry Andric       }
37780b57cec5SDimitry Andric       break;
37790b57cec5SDimitry Andric 
37800b57cec5SDimitry Andric     default:
37810b57cec5SDimitry Andric       m_options.GenerateOptionUsage(
37820b57cec5SDimitry Andric           result.GetErrorStream(), this,
37830b57cec5SDimitry Andric           GetCommandInterpreter().GetDebugger().GetTerminalWidth());
37840b57cec5SDimitry Andric       syntax_error = true;
37850b57cec5SDimitry Andric       break;
37860b57cec5SDimitry Andric     }
37870b57cec5SDimitry Andric 
37880b57cec5SDimitry Andric     result.SetStatus(eReturnStatusFailed);
37890b57cec5SDimitry Andric     return false;
37900b57cec5SDimitry Andric   }
37910b57cec5SDimitry Andric 
37920b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)37930b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
37949dba64beSDimitry Andric     Target *target = &GetSelectedTarget();
37950b57cec5SDimitry Andric     bool syntax_error = false;
37960b57cec5SDimitry Andric     uint32_t i;
37970b57cec5SDimitry Andric     uint32_t num_successful_lookups = 0;
37980b57cec5SDimitry Andric     uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
37990b57cec5SDimitry Andric     result.GetOutputStream().SetAddressByteSize(addr_byte_size);
38000b57cec5SDimitry Andric     result.GetErrorStream().SetAddressByteSize(addr_byte_size);
38010b57cec5SDimitry Andric     // Dump all sections for all modules images
38020b57cec5SDimitry Andric 
38030b57cec5SDimitry Andric     if (command.GetArgumentCount() == 0) {
38040b57cec5SDimitry Andric       ModuleSP current_module;
38050b57cec5SDimitry Andric 
38060b57cec5SDimitry Andric       // Where it is possible to look in the current symbol context first,
38070b57cec5SDimitry Andric       // try that.  If this search was successful and --all was not passed,
38080b57cec5SDimitry Andric       // don't print anything else.
38090b57cec5SDimitry Andric       if (LookupHere(m_interpreter, result, syntax_error)) {
38100b57cec5SDimitry Andric         result.GetOutputStream().EOL();
38110b57cec5SDimitry Andric         num_successful_lookups++;
38120b57cec5SDimitry Andric         if (!m_options.m_print_all) {
38130b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishResult);
38140b57cec5SDimitry Andric           return result.Succeeded();
38150b57cec5SDimitry Andric         }
38160b57cec5SDimitry Andric       }
38170b57cec5SDimitry Andric 
38180b57cec5SDimitry Andric       // Dump all sections for all other modules
38190b57cec5SDimitry Andric 
38200b57cec5SDimitry Andric       const ModuleList &target_modules = target->GetImages();
38210b57cec5SDimitry Andric       std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
3822af732203SDimitry Andric       if (target_modules.GetSize() == 0) {
38230b57cec5SDimitry Andric         result.AppendError("the target has no associated executable images");
38240b57cec5SDimitry Andric         return false;
38250b57cec5SDimitry Andric       }
3826af732203SDimitry Andric 
3827af732203SDimitry Andric       for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
3828af732203SDimitry Andric         if (module_sp != current_module &&
3829af732203SDimitry Andric             LookupInModule(m_interpreter, module_sp.get(), result,
3830af732203SDimitry Andric                            syntax_error)) {
3831af732203SDimitry Andric           result.GetOutputStream().EOL();
3832af732203SDimitry Andric           num_successful_lookups++;
3833af732203SDimitry Andric         }
3834af732203SDimitry Andric       }
38350b57cec5SDimitry Andric     } else {
38360b57cec5SDimitry Andric       // Dump specified images (by basename or fullpath)
38370b57cec5SDimitry Andric       const char *arg_cstr;
38380b57cec5SDimitry Andric       for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr &&
38390b57cec5SDimitry Andric                   !syntax_error;
38400b57cec5SDimitry Andric            ++i) {
38410b57cec5SDimitry Andric         ModuleList module_list;
38420b57cec5SDimitry Andric         const size_t num_matches =
38430b57cec5SDimitry Andric             FindModulesByName(target, arg_cstr, module_list, false);
38440b57cec5SDimitry Andric         if (num_matches > 0) {
38450b57cec5SDimitry Andric           for (size_t j = 0; j < num_matches; ++j) {
38460b57cec5SDimitry Andric             Module *module = module_list.GetModulePointerAtIndex(j);
38470b57cec5SDimitry Andric             if (module) {
38489dba64beSDimitry Andric               if (LookupInModule(m_interpreter, module, result, syntax_error)) {
38490b57cec5SDimitry Andric                 result.GetOutputStream().EOL();
38500b57cec5SDimitry Andric                 num_successful_lookups++;
38510b57cec5SDimitry Andric               }
38520b57cec5SDimitry Andric             }
38530b57cec5SDimitry Andric           }
38540b57cec5SDimitry Andric         } else
38550b57cec5SDimitry Andric           result.AppendWarningWithFormat(
38560b57cec5SDimitry Andric               "Unable to find an image that matches '%s'.\n", arg_cstr);
38570b57cec5SDimitry Andric       }
38580b57cec5SDimitry Andric     }
38590b57cec5SDimitry Andric 
38600b57cec5SDimitry Andric     if (num_successful_lookups > 0)
38610b57cec5SDimitry Andric       result.SetStatus(eReturnStatusSuccessFinishResult);
38620b57cec5SDimitry Andric     else
38630b57cec5SDimitry Andric       result.SetStatus(eReturnStatusFailed);
38640b57cec5SDimitry Andric     return result.Succeeded();
38650b57cec5SDimitry Andric   }
38660b57cec5SDimitry Andric 
38670b57cec5SDimitry Andric   CommandOptions m_options;
38680b57cec5SDimitry Andric };
38690b57cec5SDimitry Andric 
38700b57cec5SDimitry Andric #pragma mark CommandObjectMultiwordImageSearchPaths
38710b57cec5SDimitry Andric 
38720b57cec5SDimitry Andric // CommandObjectMultiwordImageSearchPaths
38730b57cec5SDimitry Andric 
38740b57cec5SDimitry Andric class CommandObjectTargetModulesImageSearchPaths
38750b57cec5SDimitry Andric     : public CommandObjectMultiword {
38760b57cec5SDimitry Andric public:
CommandObjectTargetModulesImageSearchPaths(CommandInterpreter & interpreter)38770b57cec5SDimitry Andric   CommandObjectTargetModulesImageSearchPaths(CommandInterpreter &interpreter)
38780b57cec5SDimitry Andric       : CommandObjectMultiword(
38790b57cec5SDimitry Andric             interpreter, "target modules search-paths",
38800b57cec5SDimitry Andric             "Commands for managing module search paths for a target.",
38810b57cec5SDimitry Andric             "target modules search-paths <subcommand> [<subcommand-options>]") {
38820b57cec5SDimitry Andric     LoadSubCommand(
38830b57cec5SDimitry Andric         "add", CommandObjectSP(
38840b57cec5SDimitry Andric                    new CommandObjectTargetModulesSearchPathsAdd(interpreter)));
38850b57cec5SDimitry Andric     LoadSubCommand(
38860b57cec5SDimitry Andric         "clear", CommandObjectSP(new CommandObjectTargetModulesSearchPathsClear(
38870b57cec5SDimitry Andric                      interpreter)));
38880b57cec5SDimitry Andric     LoadSubCommand(
38890b57cec5SDimitry Andric         "insert",
38900b57cec5SDimitry Andric         CommandObjectSP(
38910b57cec5SDimitry Andric             new CommandObjectTargetModulesSearchPathsInsert(interpreter)));
38920b57cec5SDimitry Andric     LoadSubCommand(
38930b57cec5SDimitry Andric         "list", CommandObjectSP(new CommandObjectTargetModulesSearchPathsList(
38940b57cec5SDimitry Andric                     interpreter)));
38950b57cec5SDimitry Andric     LoadSubCommand(
38960b57cec5SDimitry Andric         "query", CommandObjectSP(new CommandObjectTargetModulesSearchPathsQuery(
38970b57cec5SDimitry Andric                      interpreter)));
38980b57cec5SDimitry Andric   }
38990b57cec5SDimitry Andric 
39000b57cec5SDimitry Andric   ~CommandObjectTargetModulesImageSearchPaths() override = default;
39010b57cec5SDimitry Andric };
39020b57cec5SDimitry Andric 
39030b57cec5SDimitry Andric #pragma mark CommandObjectTargetModules
39040b57cec5SDimitry Andric 
39050b57cec5SDimitry Andric // CommandObjectTargetModules
39060b57cec5SDimitry Andric 
39070b57cec5SDimitry Andric class CommandObjectTargetModules : public CommandObjectMultiword {
39080b57cec5SDimitry Andric public:
39090b57cec5SDimitry Andric   // Constructors and Destructors
CommandObjectTargetModules(CommandInterpreter & interpreter)39100b57cec5SDimitry Andric   CommandObjectTargetModules(CommandInterpreter &interpreter)
39110b57cec5SDimitry Andric       : CommandObjectMultiword(interpreter, "target modules",
39120b57cec5SDimitry Andric                                "Commands for accessing information for one or "
39130b57cec5SDimitry Andric                                "more target modules.",
39140b57cec5SDimitry Andric                                "target modules <sub-command> ...") {
39150b57cec5SDimitry Andric     LoadSubCommand(
39160b57cec5SDimitry Andric         "add", CommandObjectSP(new CommandObjectTargetModulesAdd(interpreter)));
39170b57cec5SDimitry Andric     LoadSubCommand("load", CommandObjectSP(new CommandObjectTargetModulesLoad(
39180b57cec5SDimitry Andric                                interpreter)));
39190b57cec5SDimitry Andric     LoadSubCommand("dump", CommandObjectSP(new CommandObjectTargetModulesDump(
39200b57cec5SDimitry Andric                                interpreter)));
39210b57cec5SDimitry Andric     LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetModulesList(
39220b57cec5SDimitry Andric                                interpreter)));
39230b57cec5SDimitry Andric     LoadSubCommand(
39240b57cec5SDimitry Andric         "lookup",
39250b57cec5SDimitry Andric         CommandObjectSP(new CommandObjectTargetModulesLookup(interpreter)));
39260b57cec5SDimitry Andric     LoadSubCommand(
39270b57cec5SDimitry Andric         "search-paths",
39280b57cec5SDimitry Andric         CommandObjectSP(
39290b57cec5SDimitry Andric             new CommandObjectTargetModulesImageSearchPaths(interpreter)));
39300b57cec5SDimitry Andric     LoadSubCommand(
39310b57cec5SDimitry Andric         "show-unwind",
39320b57cec5SDimitry Andric         CommandObjectSP(new CommandObjectTargetModulesShowUnwind(interpreter)));
39330b57cec5SDimitry Andric   }
39340b57cec5SDimitry Andric 
39350b57cec5SDimitry Andric   ~CommandObjectTargetModules() override = default;
39360b57cec5SDimitry Andric 
39370b57cec5SDimitry Andric private:
39380b57cec5SDimitry Andric   // For CommandObjectTargetModules only
39395ffd83dbSDimitry Andric   CommandObjectTargetModules(const CommandObjectTargetModules &) = delete;
39405ffd83dbSDimitry Andric   const CommandObjectTargetModules &
39415ffd83dbSDimitry Andric   operator=(const CommandObjectTargetModules &) = delete;
39420b57cec5SDimitry Andric };
39430b57cec5SDimitry Andric 
39440b57cec5SDimitry Andric class CommandObjectTargetSymbolsAdd : public CommandObjectParsed {
39450b57cec5SDimitry Andric public:
CommandObjectTargetSymbolsAdd(CommandInterpreter & interpreter)39460b57cec5SDimitry Andric   CommandObjectTargetSymbolsAdd(CommandInterpreter &interpreter)
39470b57cec5SDimitry Andric       : CommandObjectParsed(
39480b57cec5SDimitry Andric             interpreter, "target symbols add",
39490b57cec5SDimitry Andric             "Add a debug symbol file to one of the target's current modules by "
39505ffd83dbSDimitry Andric             "specifying a path to a debug symbols file or by using the options "
39515ffd83dbSDimitry Andric             "to specify a module.",
39520b57cec5SDimitry Andric             "target symbols add <cmd-options> [<symfile>]",
39530b57cec5SDimitry Andric             eCommandRequiresTarget),
39540b57cec5SDimitry Andric         m_option_group(),
39550b57cec5SDimitry Andric         m_file_option(
39560b57cec5SDimitry Andric             LLDB_OPT_SET_1, false, "shlib", 's',
39570b57cec5SDimitry Andric             CommandCompletions::eModuleCompletion, eArgTypeShlibName,
39585ffd83dbSDimitry Andric             "Locate the debug symbols for the shared library specified by "
39595ffd83dbSDimitry Andric             "name."),
39600b57cec5SDimitry Andric         m_current_frame_option(
39610b57cec5SDimitry Andric             LLDB_OPT_SET_2, false, "frame", 'F',
39625ffd83dbSDimitry Andric             "Locate the debug symbols for the currently selected frame.",
39635ffd83dbSDimitry Andric             false, true)
39640b57cec5SDimitry Andric 
39650b57cec5SDimitry Andric   {
39660b57cec5SDimitry Andric     m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
39670b57cec5SDimitry Andric                           LLDB_OPT_SET_1);
39680b57cec5SDimitry Andric     m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
39690b57cec5SDimitry Andric     m_option_group.Append(&m_current_frame_option, LLDB_OPT_SET_2,
39700b57cec5SDimitry Andric                           LLDB_OPT_SET_2);
39710b57cec5SDimitry Andric     m_option_group.Finalize();
39720b57cec5SDimitry Andric   }
39730b57cec5SDimitry Andric 
39740b57cec5SDimitry Andric   ~CommandObjectTargetSymbolsAdd() override = default;
39750b57cec5SDimitry Andric 
39769dba64beSDimitry Andric   void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)39779dba64beSDimitry Andric   HandleArgumentCompletion(CompletionRequest &request,
39780b57cec5SDimitry Andric                            OptionElementVector &opt_element_vector) override {
39790b57cec5SDimitry Andric     CommandCompletions::InvokeCommonCompletionCallbacks(
39800b57cec5SDimitry Andric         GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
39810b57cec5SDimitry Andric         request, nullptr);
39820b57cec5SDimitry Andric   }
39830b57cec5SDimitry Andric 
GetOptions()39840b57cec5SDimitry Andric   Options *GetOptions() override { return &m_option_group; }
39850b57cec5SDimitry Andric 
39860b57cec5SDimitry Andric protected:
AddModuleSymbols(Target * target,ModuleSpec & module_spec,bool & flush,CommandReturnObject & result)39870b57cec5SDimitry Andric   bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush,
39880b57cec5SDimitry Andric                         CommandReturnObject &result) {
39890b57cec5SDimitry Andric     const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
3990480093f4SDimitry Andric     if (!symbol_fspec) {
3991480093f4SDimitry Andric       result.AppendError(
3992480093f4SDimitry Andric           "one or more executable image paths must be specified");
3993480093f4SDimitry Andric       return false;
3994480093f4SDimitry Andric     }
3995480093f4SDimitry Andric 
39960b57cec5SDimitry Andric     char symfile_path[PATH_MAX];
39970b57cec5SDimitry Andric     symbol_fspec.GetPath(symfile_path, sizeof(symfile_path));
39980b57cec5SDimitry Andric 
39990b57cec5SDimitry Andric     if (!module_spec.GetUUID().IsValid()) {
40000b57cec5SDimitry Andric       if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
40010b57cec5SDimitry Andric         module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename();
40020b57cec5SDimitry Andric     }
4003480093f4SDimitry Andric 
40045ffd83dbSDimitry Andric     // Now module_spec represents a symbol file for a module that might exist
40055ffd83dbSDimitry Andric     // in the current target.  Let's find possible matches.
40065ffd83dbSDimitry Andric     ModuleList matching_modules;
40070b57cec5SDimitry Andric 
40080b57cec5SDimitry Andric     // First extract all module specs from the symbol file
40090b57cec5SDimitry Andric     lldb_private::ModuleSpecList symfile_module_specs;
40100b57cec5SDimitry Andric     if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(),
40110b57cec5SDimitry Andric                                             0, 0, symfile_module_specs)) {
40120b57cec5SDimitry Andric       // Now extract the module spec that matches the target architecture
40130b57cec5SDimitry Andric       ModuleSpec target_arch_module_spec;
40140b57cec5SDimitry Andric       ModuleSpec symfile_module_spec;
40150b57cec5SDimitry Andric       target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
40160b57cec5SDimitry Andric       if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec,
40170b57cec5SDimitry Andric                                                       symfile_module_spec)) {
40180b57cec5SDimitry Andric         if (symfile_module_spec.GetUUID().IsValid()) {
40190b57cec5SDimitry Andric           // It has a UUID, look for this UUID in the target modules
40200b57cec5SDimitry Andric           ModuleSpec symfile_uuid_module_spec;
40210b57cec5SDimitry Andric           symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
40229dba64beSDimitry Andric           target->GetImages().FindModules(symfile_uuid_module_spec,
40235ffd83dbSDimitry Andric                                           matching_modules);
40240b57cec5SDimitry Andric         }
40250b57cec5SDimitry Andric       }
40260b57cec5SDimitry Andric 
40275ffd83dbSDimitry Andric       if (matching_modules.IsEmpty()) {
40285ffd83dbSDimitry Andric         // No matches yet.  Iterate through the module specs to find a UUID
40295ffd83dbSDimitry Andric         // value that we can match up to an image in our target.
40305ffd83dbSDimitry Andric         const size_t num_symfile_module_specs = symfile_module_specs.GetSize();
40315ffd83dbSDimitry Andric         for (size_t i = 0;
40325ffd83dbSDimitry Andric              i < num_symfile_module_specs && matching_modules.IsEmpty(); ++i) {
40330b57cec5SDimitry Andric           if (symfile_module_specs.GetModuleSpecAtIndex(
40340b57cec5SDimitry Andric                   i, symfile_module_spec)) {
40350b57cec5SDimitry Andric             if (symfile_module_spec.GetUUID().IsValid()) {
40365ffd83dbSDimitry Andric               // It has a UUID.  Look for this UUID in the target modules.
40370b57cec5SDimitry Andric               ModuleSpec symfile_uuid_module_spec;
40380b57cec5SDimitry Andric               symfile_uuid_module_spec.GetUUID() =
40390b57cec5SDimitry Andric                   symfile_module_spec.GetUUID();
40409dba64beSDimitry Andric               target->GetImages().FindModules(symfile_uuid_module_spec,
40415ffd83dbSDimitry Andric                                               matching_modules);
40420b57cec5SDimitry Andric             }
40430b57cec5SDimitry Andric           }
40440b57cec5SDimitry Andric         }
40450b57cec5SDimitry Andric       }
40460b57cec5SDimitry Andric     }
40470b57cec5SDimitry Andric 
40480b57cec5SDimitry Andric     // Just try to match up the file by basename if we have no matches at
40495ffd83dbSDimitry Andric     // this point.  For example, module foo might have symbols in foo.debug.
40505ffd83dbSDimitry Andric     if (matching_modules.IsEmpty())
40515ffd83dbSDimitry Andric       target->GetImages().FindModules(module_spec, matching_modules);
40520b57cec5SDimitry Andric 
40535ffd83dbSDimitry Andric     while (matching_modules.IsEmpty()) {
40540b57cec5SDimitry Andric       ConstString filename_no_extension(
40550b57cec5SDimitry Andric           module_spec.GetFileSpec().GetFileNameStrippingExtension());
4056480093f4SDimitry Andric       // Empty string returned, let's bail
40570b57cec5SDimitry Andric       if (!filename_no_extension)
40580b57cec5SDimitry Andric         break;
40590b57cec5SDimitry Andric 
4060480093f4SDimitry Andric       // Check if there was no extension to strip and the basename is the same
40610b57cec5SDimitry Andric       if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
40620b57cec5SDimitry Andric         break;
40630b57cec5SDimitry Andric 
4064480093f4SDimitry Andric       // Replace basename with one fewer extension
40650b57cec5SDimitry Andric       module_spec.GetFileSpec().GetFilename() = filename_no_extension;
40665ffd83dbSDimitry Andric       target->GetImages().FindModules(module_spec, matching_modules);
40670b57cec5SDimitry Andric     }
40680b57cec5SDimitry Andric 
40695ffd83dbSDimitry Andric     if (matching_modules.GetSize() > 1) {
40700b57cec5SDimitry Andric       result.AppendErrorWithFormat("multiple modules match symbol file '%s', "
40710b57cec5SDimitry Andric                                    "use the --uuid option to resolve the "
40720b57cec5SDimitry Andric                                    "ambiguity.\n",
40730b57cec5SDimitry Andric                                    symfile_path);
40745ffd83dbSDimitry Andric       return false;
40755ffd83dbSDimitry Andric     }
40765ffd83dbSDimitry Andric 
40775ffd83dbSDimitry Andric     if (matching_modules.GetSize() == 1) {
40785ffd83dbSDimitry Andric       ModuleSP module_sp(matching_modules.GetModuleAtIndex(0));
40790b57cec5SDimitry Andric 
40800b57cec5SDimitry Andric       // The module has not yet created its symbol vendor, we can just give
40810b57cec5SDimitry Andric       // the existing target module the symfile path to use for when it
40820b57cec5SDimitry Andric       // decides to create it!
40830b57cec5SDimitry Andric       module_sp->SetSymbolFileFileSpec(symbol_fspec);
40840b57cec5SDimitry Andric 
40859dba64beSDimitry Andric       SymbolFile *symbol_file =
40869dba64beSDimitry Andric           module_sp->GetSymbolFile(true, &result.GetErrorStream());
40870b57cec5SDimitry Andric       if (symbol_file) {
40880b57cec5SDimitry Andric         ObjectFile *object_file = symbol_file->GetObjectFile();
40890b57cec5SDimitry Andric         if (object_file && object_file->GetFileSpec() == symbol_fspec) {
40900b57cec5SDimitry Andric           // Provide feedback that the symfile has been successfully added.
40910b57cec5SDimitry Andric           const FileSpec &module_fs = module_sp->GetFileSpec();
40920b57cec5SDimitry Andric           result.AppendMessageWithFormat(
40930b57cec5SDimitry Andric               "symbol file '%s' has been added to '%s'\n", symfile_path,
40940b57cec5SDimitry Andric               module_fs.GetPath().c_str());
40950b57cec5SDimitry Andric 
40960b57cec5SDimitry Andric           // Let clients know something changed in the module if it is
40970b57cec5SDimitry Andric           // currently loaded
40980b57cec5SDimitry Andric           ModuleList module_list;
40990b57cec5SDimitry Andric           module_list.Append(module_sp);
41000b57cec5SDimitry Andric           target->SymbolsDidLoad(module_list);
41010b57cec5SDimitry Andric 
41020b57cec5SDimitry Andric           // Make sure we load any scripting resources that may be embedded
41030b57cec5SDimitry Andric           // in the debug info files in case the platform supports that.
41040b57cec5SDimitry Andric           Status error;
41050b57cec5SDimitry Andric           StreamString feedback_stream;
41060b57cec5SDimitry Andric           module_sp->LoadScriptingResourceInTarget(target, error,
41070b57cec5SDimitry Andric                                                    &feedback_stream);
41080b57cec5SDimitry Andric           if (error.Fail() && error.AsCString())
41090b57cec5SDimitry Andric             result.AppendWarningWithFormat(
41100b57cec5SDimitry Andric                 "unable to load scripting data for module %s - error "
41110b57cec5SDimitry Andric                 "reported was %s",
41120b57cec5SDimitry Andric                 module_sp->GetFileSpec()
41130b57cec5SDimitry Andric                     .GetFileNameStrippingExtension()
41140b57cec5SDimitry Andric                     .GetCString(),
41150b57cec5SDimitry Andric                 error.AsCString());
41160b57cec5SDimitry Andric           else if (feedback_stream.GetSize())
41175ffd83dbSDimitry Andric             result.AppendWarning(feedback_stream.GetData());
41180b57cec5SDimitry Andric 
41190b57cec5SDimitry Andric           flush = true;
41200b57cec5SDimitry Andric           result.SetStatus(eReturnStatusSuccessFinishResult);
41210b57cec5SDimitry Andric           return true;
41220b57cec5SDimitry Andric         }
41230b57cec5SDimitry Andric       }
41240b57cec5SDimitry Andric       // Clear the symbol file spec if anything went wrong
41250b57cec5SDimitry Andric       module_sp->SetSymbolFileFileSpec(FileSpec());
41260b57cec5SDimitry Andric     }
41270b57cec5SDimitry Andric 
41280b57cec5SDimitry Andric     StreamString ss_symfile_uuid;
4129480093f4SDimitry Andric     if (module_spec.GetUUID().IsValid()) {
4130480093f4SDimitry Andric       ss_symfile_uuid << " (";
41310b57cec5SDimitry Andric       module_spec.GetUUID().Dump(&ss_symfile_uuid);
4132480093f4SDimitry Andric       ss_symfile_uuid << ')';
4133480093f4SDimitry Andric     }
41340b57cec5SDimitry Andric     result.AppendErrorWithFormat(
4135480093f4SDimitry Andric         "symbol file '%s'%s does not match any existing module%s\n",
41360b57cec5SDimitry Andric         symfile_path, ss_symfile_uuid.GetData(),
41375ffd83dbSDimitry Andric         !llvm::sys::fs::is_regular_file(symbol_fspec.GetPath())
41380b57cec5SDimitry Andric             ? "\n       please specify the full path to the symbol file"
41390b57cec5SDimitry Andric             : "");
41400b57cec5SDimitry Andric     return false;
41410b57cec5SDimitry Andric   }
41420b57cec5SDimitry Andric 
DoExecute(Args & args,CommandReturnObject & result)41430b57cec5SDimitry Andric   bool DoExecute(Args &args, CommandReturnObject &result) override {
41440b57cec5SDimitry Andric     Target *target = m_exe_ctx.GetTargetPtr();
41450b57cec5SDimitry Andric     result.SetStatus(eReturnStatusFailed);
41460b57cec5SDimitry Andric     bool flush = false;
41470b57cec5SDimitry Andric     ModuleSpec module_spec;
41480b57cec5SDimitry Andric     const bool uuid_option_set =
41490b57cec5SDimitry Andric         m_uuid_option_group.GetOptionValue().OptionWasSet();
41500b57cec5SDimitry Andric     const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
41510b57cec5SDimitry Andric     const bool frame_option_set =
41520b57cec5SDimitry Andric         m_current_frame_option.GetOptionValue().OptionWasSet();
41530b57cec5SDimitry Andric     const size_t argc = args.GetArgumentCount();
41540b57cec5SDimitry Andric 
41550b57cec5SDimitry Andric     if (argc == 0) {
41560b57cec5SDimitry Andric       if (uuid_option_set || file_option_set || frame_option_set) {
41570b57cec5SDimitry Andric         bool success = false;
41580b57cec5SDimitry Andric         bool error_set = false;
41590b57cec5SDimitry Andric         if (frame_option_set) {
41600b57cec5SDimitry Andric           Process *process = m_exe_ctx.GetProcessPtr();
41610b57cec5SDimitry Andric           if (process) {
41620b57cec5SDimitry Andric             const StateType process_state = process->GetState();
41630b57cec5SDimitry Andric             if (StateIsStoppedState(process_state, true)) {
41640b57cec5SDimitry Andric               StackFrame *frame = m_exe_ctx.GetFramePtr();
41650b57cec5SDimitry Andric               if (frame) {
41660b57cec5SDimitry Andric                 ModuleSP frame_module_sp(
41670b57cec5SDimitry Andric                     frame->GetSymbolContext(eSymbolContextModule).module_sp);
41680b57cec5SDimitry Andric                 if (frame_module_sp) {
41690b57cec5SDimitry Andric                   if (FileSystem::Instance().Exists(
41700b57cec5SDimitry Andric                           frame_module_sp->GetPlatformFileSpec())) {
41710b57cec5SDimitry Andric                     module_spec.GetArchitecture() =
41720b57cec5SDimitry Andric                         frame_module_sp->GetArchitecture();
41730b57cec5SDimitry Andric                     module_spec.GetFileSpec() =
41740b57cec5SDimitry Andric                         frame_module_sp->GetPlatformFileSpec();
41750b57cec5SDimitry Andric                   }
41760b57cec5SDimitry Andric                   module_spec.GetUUID() = frame_module_sp->GetUUID();
41770b57cec5SDimitry Andric                   success = module_spec.GetUUID().IsValid() ||
41780b57cec5SDimitry Andric                             module_spec.GetFileSpec();
41790b57cec5SDimitry Andric                 } else {
41800b57cec5SDimitry Andric                   result.AppendError("frame has no module");
41810b57cec5SDimitry Andric                   error_set = true;
41820b57cec5SDimitry Andric                 }
41830b57cec5SDimitry Andric               } else {
41840b57cec5SDimitry Andric                 result.AppendError("invalid current frame");
41850b57cec5SDimitry Andric                 error_set = true;
41860b57cec5SDimitry Andric               }
41870b57cec5SDimitry Andric             } else {
41880b57cec5SDimitry Andric               result.AppendErrorWithFormat("process is not stopped: %s",
41890b57cec5SDimitry Andric                                            StateAsCString(process_state));
41900b57cec5SDimitry Andric               error_set = true;
41910b57cec5SDimitry Andric             }
41920b57cec5SDimitry Andric           } else {
41930b57cec5SDimitry Andric             result.AppendError(
41940b57cec5SDimitry Andric                 "a process must exist in order to use the --frame option");
41950b57cec5SDimitry Andric             error_set = true;
41960b57cec5SDimitry Andric           }
41970b57cec5SDimitry Andric         } else {
41980b57cec5SDimitry Andric           if (uuid_option_set) {
41990b57cec5SDimitry Andric             module_spec.GetUUID() =
42000b57cec5SDimitry Andric                 m_uuid_option_group.GetOptionValue().GetCurrentValue();
42010b57cec5SDimitry Andric             success |= module_spec.GetUUID().IsValid();
42020b57cec5SDimitry Andric           } else if (file_option_set) {
42030b57cec5SDimitry Andric             module_spec.GetFileSpec() =
42040b57cec5SDimitry Andric                 m_file_option.GetOptionValue().GetCurrentValue();
42050b57cec5SDimitry Andric             ModuleSP module_sp(
42060b57cec5SDimitry Andric                 target->GetImages().FindFirstModule(module_spec));
42070b57cec5SDimitry Andric             if (module_sp) {
42080b57cec5SDimitry Andric               module_spec.GetFileSpec() = module_sp->GetFileSpec();
42090b57cec5SDimitry Andric               module_spec.GetPlatformFileSpec() =
42100b57cec5SDimitry Andric                   module_sp->GetPlatformFileSpec();
42110b57cec5SDimitry Andric               module_spec.GetUUID() = module_sp->GetUUID();
42120b57cec5SDimitry Andric               module_spec.GetArchitecture() = module_sp->GetArchitecture();
42130b57cec5SDimitry Andric             } else {
42140b57cec5SDimitry Andric               module_spec.GetArchitecture() = target->GetArchitecture();
42150b57cec5SDimitry Andric             }
42160b57cec5SDimitry Andric             success |= module_spec.GetUUID().IsValid() ||
42170b57cec5SDimitry Andric                        FileSystem::Instance().Exists(module_spec.GetFileSpec());
42180b57cec5SDimitry Andric           }
42190b57cec5SDimitry Andric         }
42200b57cec5SDimitry Andric 
42210b57cec5SDimitry Andric         if (success) {
42220b57cec5SDimitry Andric           if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
42230b57cec5SDimitry Andric             if (module_spec.GetSymbolFileSpec())
42240b57cec5SDimitry Andric               success = AddModuleSymbols(target, module_spec, flush, result);
42250b57cec5SDimitry Andric           }
42260b57cec5SDimitry Andric         }
42270b57cec5SDimitry Andric 
42280b57cec5SDimitry Andric         if (!success && !error_set) {
42290b57cec5SDimitry Andric           StreamString error_strm;
42300b57cec5SDimitry Andric           if (uuid_option_set) {
42310b57cec5SDimitry Andric             error_strm.PutCString("unable to find debug symbols for UUID ");
42320b57cec5SDimitry Andric             module_spec.GetUUID().Dump(&error_strm);
42330b57cec5SDimitry Andric           } else if (file_option_set) {
42340b57cec5SDimitry Andric             error_strm.PutCString(
42350b57cec5SDimitry Andric                 "unable to find debug symbols for the executable file ");
42360b57cec5SDimitry Andric             error_strm << module_spec.GetFileSpec();
42370b57cec5SDimitry Andric           } else if (frame_option_set) {
42380b57cec5SDimitry Andric             error_strm.PutCString(
42390b57cec5SDimitry Andric                 "unable to find debug symbols for the current frame");
42400b57cec5SDimitry Andric           }
42410b57cec5SDimitry Andric           result.AppendError(error_strm.GetString());
42420b57cec5SDimitry Andric         }
42430b57cec5SDimitry Andric       } else {
42440b57cec5SDimitry Andric         result.AppendError("one or more symbol file paths must be specified, "
42450b57cec5SDimitry Andric                            "or options must be specified");
42460b57cec5SDimitry Andric       }
42470b57cec5SDimitry Andric     } else {
42480b57cec5SDimitry Andric       if (uuid_option_set) {
42490b57cec5SDimitry Andric         result.AppendError("specify either one or more paths to symbol files "
42500b57cec5SDimitry Andric                            "or use the --uuid option without arguments");
42510b57cec5SDimitry Andric       } else if (frame_option_set) {
42520b57cec5SDimitry Andric         result.AppendError("specify either one or more paths to symbol files "
42530b57cec5SDimitry Andric                            "or use the --frame option without arguments");
42540b57cec5SDimitry Andric       } else if (file_option_set && argc > 1) {
42550b57cec5SDimitry Andric         result.AppendError("specify at most one symbol file path when "
42560b57cec5SDimitry Andric                            "--shlib option is set");
42570b57cec5SDimitry Andric       } else {
42580b57cec5SDimitry Andric         PlatformSP platform_sp(target->GetPlatform());
42590b57cec5SDimitry Andric 
42600b57cec5SDimitry Andric         for (auto &entry : args.entries()) {
42619dba64beSDimitry Andric           if (!entry.ref().empty()) {
42620b57cec5SDimitry Andric             auto &symbol_file_spec = module_spec.GetSymbolFileSpec();
42639dba64beSDimitry Andric             symbol_file_spec.SetFile(entry.ref(), FileSpec::Style::native);
42640b57cec5SDimitry Andric             FileSystem::Instance().Resolve(symbol_file_spec);
42650b57cec5SDimitry Andric             if (file_option_set) {
42660b57cec5SDimitry Andric               module_spec.GetFileSpec() =
42670b57cec5SDimitry Andric                   m_file_option.GetOptionValue().GetCurrentValue();
42680b57cec5SDimitry Andric             }
42690b57cec5SDimitry Andric             if (platform_sp) {
42700b57cec5SDimitry Andric               FileSpec symfile_spec;
42710b57cec5SDimitry Andric               if (platform_sp
42720b57cec5SDimitry Andric                       ->ResolveSymbolFile(*target, module_spec, symfile_spec)
42730b57cec5SDimitry Andric                       .Success())
42740b57cec5SDimitry Andric                 module_spec.GetSymbolFileSpec() = symfile_spec;
42750b57cec5SDimitry Andric             }
42760b57cec5SDimitry Andric 
42770b57cec5SDimitry Andric             bool symfile_exists =
42780b57cec5SDimitry Andric                 FileSystem::Instance().Exists(module_spec.GetSymbolFileSpec());
42790b57cec5SDimitry Andric 
42800b57cec5SDimitry Andric             if (symfile_exists) {
42810b57cec5SDimitry Andric               if (!AddModuleSymbols(target, module_spec, flush, result))
42820b57cec5SDimitry Andric                 break;
42830b57cec5SDimitry Andric             } else {
42840b57cec5SDimitry Andric               std::string resolved_symfile_path =
42850b57cec5SDimitry Andric                   module_spec.GetSymbolFileSpec().GetPath();
42869dba64beSDimitry Andric               if (resolved_symfile_path != entry.ref()) {
42870b57cec5SDimitry Andric                 result.AppendErrorWithFormat(
42880b57cec5SDimitry Andric                     "invalid module path '%s' with resolved path '%s'\n",
42890b57cec5SDimitry Andric                     entry.c_str(), resolved_symfile_path.c_str());
42900b57cec5SDimitry Andric                 break;
42910b57cec5SDimitry Andric               }
42920b57cec5SDimitry Andric               result.AppendErrorWithFormat("invalid module path '%s'\n",
42930b57cec5SDimitry Andric                                            entry.c_str());
42940b57cec5SDimitry Andric               break;
42950b57cec5SDimitry Andric             }
42960b57cec5SDimitry Andric           }
42970b57cec5SDimitry Andric         }
42980b57cec5SDimitry Andric       }
42990b57cec5SDimitry Andric     }
43000b57cec5SDimitry Andric 
43010b57cec5SDimitry Andric     if (flush) {
43020b57cec5SDimitry Andric       Process *process = m_exe_ctx.GetProcessPtr();
43030b57cec5SDimitry Andric       if (process)
43040b57cec5SDimitry Andric         process->Flush();
43050b57cec5SDimitry Andric     }
43060b57cec5SDimitry Andric     return result.Succeeded();
43070b57cec5SDimitry Andric   }
43080b57cec5SDimitry Andric 
43090b57cec5SDimitry Andric   OptionGroupOptions m_option_group;
43100b57cec5SDimitry Andric   OptionGroupUUID m_uuid_option_group;
43110b57cec5SDimitry Andric   OptionGroupFile m_file_option;
43120b57cec5SDimitry Andric   OptionGroupBoolean m_current_frame_option;
43130b57cec5SDimitry Andric };
43140b57cec5SDimitry Andric 
43150b57cec5SDimitry Andric #pragma mark CommandObjectTargetSymbols
43160b57cec5SDimitry Andric 
43170b57cec5SDimitry Andric // CommandObjectTargetSymbols
43180b57cec5SDimitry Andric 
43190b57cec5SDimitry Andric class CommandObjectTargetSymbols : public CommandObjectMultiword {
43200b57cec5SDimitry Andric public:
43210b57cec5SDimitry Andric   // Constructors and Destructors
CommandObjectTargetSymbols(CommandInterpreter & interpreter)43220b57cec5SDimitry Andric   CommandObjectTargetSymbols(CommandInterpreter &interpreter)
43230b57cec5SDimitry Andric       : CommandObjectMultiword(
43240b57cec5SDimitry Andric             interpreter, "target symbols",
43250b57cec5SDimitry Andric             "Commands for adding and managing debug symbol files.",
43260b57cec5SDimitry Andric             "target symbols <sub-command> ...") {
43270b57cec5SDimitry Andric     LoadSubCommand(
43280b57cec5SDimitry Andric         "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter)));
43290b57cec5SDimitry Andric   }
43300b57cec5SDimitry Andric 
43310b57cec5SDimitry Andric   ~CommandObjectTargetSymbols() override = default;
43320b57cec5SDimitry Andric 
43330b57cec5SDimitry Andric private:
43340b57cec5SDimitry Andric   // For CommandObjectTargetModules only
43355ffd83dbSDimitry Andric   CommandObjectTargetSymbols(const CommandObjectTargetSymbols &) = delete;
43365ffd83dbSDimitry Andric   const CommandObjectTargetSymbols &
43375ffd83dbSDimitry Andric   operator=(const CommandObjectTargetSymbols &) = delete;
43380b57cec5SDimitry Andric };
43390b57cec5SDimitry Andric 
43400b57cec5SDimitry Andric #pragma mark CommandObjectTargetStopHookAdd
43410b57cec5SDimitry Andric 
43420b57cec5SDimitry Andric // CommandObjectTargetStopHookAdd
43439dba64beSDimitry Andric #define LLDB_OPTIONS_target_stop_hook_add
43449dba64beSDimitry Andric #include "CommandOptions.inc"
43450b57cec5SDimitry Andric 
43460b57cec5SDimitry Andric class CommandObjectTargetStopHookAdd : public CommandObjectParsed,
43470b57cec5SDimitry Andric                                        public IOHandlerDelegateMultiline {
43480b57cec5SDimitry Andric public:
4349af732203SDimitry Andric   class CommandOptions : public OptionGroup {
43500b57cec5SDimitry Andric   public:
CommandOptions()4351*5f7ddb14SDimitry Andric     CommandOptions() : OptionGroup(), m_line_end(UINT_MAX), m_one_liner() {}
43520b57cec5SDimitry Andric 
43530b57cec5SDimitry Andric     ~CommandOptions() override = default;
43540b57cec5SDimitry Andric 
GetDefinitions()43550b57cec5SDimitry Andric     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
43560b57cec5SDimitry Andric       return llvm::makeArrayRef(g_target_stop_hook_add_options);
43570b57cec5SDimitry Andric     }
43580b57cec5SDimitry Andric 
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)43590b57cec5SDimitry Andric     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
43600b57cec5SDimitry Andric                           ExecutionContext *execution_context) override {
43610b57cec5SDimitry Andric       Status error;
4362af732203SDimitry Andric       const int short_option =
4363af732203SDimitry Andric           g_target_stop_hook_add_options[option_idx].short_option;
43640b57cec5SDimitry Andric 
43650b57cec5SDimitry Andric       switch (short_option) {
43660b57cec5SDimitry Andric       case 'c':
43675ffd83dbSDimitry Andric         m_class_name = std::string(option_arg);
43680b57cec5SDimitry Andric         m_sym_ctx_specified = true;
43690b57cec5SDimitry Andric         break;
43700b57cec5SDimitry Andric 
43710b57cec5SDimitry Andric       case 'e':
43720b57cec5SDimitry Andric         if (option_arg.getAsInteger(0, m_line_end)) {
43730b57cec5SDimitry Andric           error.SetErrorStringWithFormat("invalid end line number: \"%s\"",
43740b57cec5SDimitry Andric                                          option_arg.str().c_str());
43750b57cec5SDimitry Andric           break;
43760b57cec5SDimitry Andric         }
43770b57cec5SDimitry Andric         m_sym_ctx_specified = true;
43780b57cec5SDimitry Andric         break;
43790b57cec5SDimitry Andric 
43800b57cec5SDimitry Andric       case 'G': {
43810b57cec5SDimitry Andric         bool value, success;
43820b57cec5SDimitry Andric         value = OptionArgParser::ToBoolean(option_arg, false, &success);
43830b57cec5SDimitry Andric         if (success) {
43840b57cec5SDimitry Andric           m_auto_continue = value;
43850b57cec5SDimitry Andric         } else
43860b57cec5SDimitry Andric           error.SetErrorStringWithFormat(
43870b57cec5SDimitry Andric               "invalid boolean value '%s' passed for -G option",
43880b57cec5SDimitry Andric               option_arg.str().c_str());
4389480093f4SDimitry Andric       } break;
43900b57cec5SDimitry Andric       case 'l':
43910b57cec5SDimitry Andric         if (option_arg.getAsInteger(0, m_line_start)) {
43920b57cec5SDimitry Andric           error.SetErrorStringWithFormat("invalid start line number: \"%s\"",
43930b57cec5SDimitry Andric                                          option_arg.str().c_str());
43940b57cec5SDimitry Andric           break;
43950b57cec5SDimitry Andric         }
43960b57cec5SDimitry Andric         m_sym_ctx_specified = true;
43970b57cec5SDimitry Andric         break;
43980b57cec5SDimitry Andric 
43990b57cec5SDimitry Andric       case 'i':
44000b57cec5SDimitry Andric         m_no_inlines = true;
44010b57cec5SDimitry Andric         break;
44020b57cec5SDimitry Andric 
44030b57cec5SDimitry Andric       case 'n':
44045ffd83dbSDimitry Andric         m_function_name = std::string(option_arg);
44050b57cec5SDimitry Andric         m_func_name_type_mask |= eFunctionNameTypeAuto;
44060b57cec5SDimitry Andric         m_sym_ctx_specified = true;
44070b57cec5SDimitry Andric         break;
44080b57cec5SDimitry Andric 
44090b57cec5SDimitry Andric       case 'f':
44105ffd83dbSDimitry Andric         m_file_name = std::string(option_arg);
44110b57cec5SDimitry Andric         m_sym_ctx_specified = true;
44120b57cec5SDimitry Andric         break;
44130b57cec5SDimitry Andric 
44140b57cec5SDimitry Andric       case 's':
44155ffd83dbSDimitry Andric         m_module_name = std::string(option_arg);
44160b57cec5SDimitry Andric         m_sym_ctx_specified = true;
44170b57cec5SDimitry Andric         break;
44180b57cec5SDimitry Andric 
44190b57cec5SDimitry Andric       case 't':
44200b57cec5SDimitry Andric         if (option_arg.getAsInteger(0, m_thread_id))
44210b57cec5SDimitry Andric           error.SetErrorStringWithFormat("invalid thread id string '%s'",
44220b57cec5SDimitry Andric                                          option_arg.str().c_str());
44230b57cec5SDimitry Andric         m_thread_specified = true;
44240b57cec5SDimitry Andric         break;
44250b57cec5SDimitry Andric 
44260b57cec5SDimitry Andric       case 'T':
44275ffd83dbSDimitry Andric         m_thread_name = std::string(option_arg);
44280b57cec5SDimitry Andric         m_thread_specified = true;
44290b57cec5SDimitry Andric         break;
44300b57cec5SDimitry Andric 
44310b57cec5SDimitry Andric       case 'q':
44325ffd83dbSDimitry Andric         m_queue_name = std::string(option_arg);
44330b57cec5SDimitry Andric         m_thread_specified = true;
44340b57cec5SDimitry Andric         break;
44350b57cec5SDimitry Andric 
44360b57cec5SDimitry Andric       case 'x':
44370b57cec5SDimitry Andric         if (option_arg.getAsInteger(0, m_thread_index))
44380b57cec5SDimitry Andric           error.SetErrorStringWithFormat("invalid thread index string '%s'",
44390b57cec5SDimitry Andric                                          option_arg.str().c_str());
44400b57cec5SDimitry Andric         m_thread_specified = true;
44410b57cec5SDimitry Andric         break;
44420b57cec5SDimitry Andric 
44430b57cec5SDimitry Andric       case 'o':
44440b57cec5SDimitry Andric         m_use_one_liner = true;
44455ffd83dbSDimitry Andric         m_one_liner.push_back(std::string(option_arg));
44460b57cec5SDimitry Andric         break;
44470b57cec5SDimitry Andric 
44480b57cec5SDimitry Andric       default:
44499dba64beSDimitry Andric         llvm_unreachable("Unimplemented option");
44500b57cec5SDimitry Andric       }
44510b57cec5SDimitry Andric       return error;
44520b57cec5SDimitry Andric     }
44530b57cec5SDimitry Andric 
OptionParsingStarting(ExecutionContext * execution_context)44540b57cec5SDimitry Andric     void OptionParsingStarting(ExecutionContext *execution_context) override {
44550b57cec5SDimitry Andric       m_class_name.clear();
44560b57cec5SDimitry Andric       m_function_name.clear();
44570b57cec5SDimitry Andric       m_line_start = 0;
44580b57cec5SDimitry Andric       m_line_end = UINT_MAX;
44590b57cec5SDimitry Andric       m_file_name.clear();
44600b57cec5SDimitry Andric       m_module_name.clear();
44610b57cec5SDimitry Andric       m_func_name_type_mask = eFunctionNameTypeAuto;
44620b57cec5SDimitry Andric       m_thread_id = LLDB_INVALID_THREAD_ID;
44630b57cec5SDimitry Andric       m_thread_index = UINT32_MAX;
44640b57cec5SDimitry Andric       m_thread_name.clear();
44650b57cec5SDimitry Andric       m_queue_name.clear();
44660b57cec5SDimitry Andric 
44670b57cec5SDimitry Andric       m_no_inlines = false;
44680b57cec5SDimitry Andric       m_sym_ctx_specified = false;
44690b57cec5SDimitry Andric       m_thread_specified = false;
44700b57cec5SDimitry Andric 
44710b57cec5SDimitry Andric       m_use_one_liner = false;
44720b57cec5SDimitry Andric       m_one_liner.clear();
44730b57cec5SDimitry Andric       m_auto_continue = false;
44740b57cec5SDimitry Andric     }
44750b57cec5SDimitry Andric 
44760b57cec5SDimitry Andric     std::string m_class_name;
44770b57cec5SDimitry Andric     std::string m_function_name;
4478*5f7ddb14SDimitry Andric     uint32_t m_line_start = 0;
44790b57cec5SDimitry Andric     uint32_t m_line_end;
44800b57cec5SDimitry Andric     std::string m_file_name;
44810b57cec5SDimitry Andric     std::string m_module_name;
4482*5f7ddb14SDimitry Andric     uint32_t m_func_name_type_mask =
4483*5f7ddb14SDimitry Andric         eFunctionNameTypeAuto; // A pick from lldb::FunctionNameType.
44840b57cec5SDimitry Andric     lldb::tid_t m_thread_id;
44850b57cec5SDimitry Andric     uint32_t m_thread_index;
44860b57cec5SDimitry Andric     std::string m_thread_name;
44870b57cec5SDimitry Andric     std::string m_queue_name;
4488*5f7ddb14SDimitry Andric     bool m_sym_ctx_specified = false;
44890b57cec5SDimitry Andric     bool m_no_inlines;
4490*5f7ddb14SDimitry Andric     bool m_thread_specified = false;
44910b57cec5SDimitry Andric     // Instance variables to hold the values for one_liner options.
4492*5f7ddb14SDimitry Andric     bool m_use_one_liner = false;
44930b57cec5SDimitry Andric     std::vector<std::string> m_one_liner;
4494af732203SDimitry Andric 
44950b57cec5SDimitry Andric     bool m_auto_continue;
44960b57cec5SDimitry Andric   };
44970b57cec5SDimitry Andric 
CommandObjectTargetStopHookAdd(CommandInterpreter & interpreter)44980b57cec5SDimitry Andric   CommandObjectTargetStopHookAdd(CommandInterpreter &interpreter)
44990b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "target stop-hook add",
4500af732203SDimitry Andric                             "Add a hook to be executed when the target stops."
4501af732203SDimitry Andric                             "The hook can either be a list of commands or an "
4502af732203SDimitry Andric                             "appropriately defined Python class.  You can also "
4503af732203SDimitry Andric                             "add filters so the hook only runs a certain stop "
4504af732203SDimitry Andric                             "points.",
45050b57cec5SDimitry Andric                             "target stop-hook add"),
45060b57cec5SDimitry Andric         IOHandlerDelegateMultiline("DONE",
45070b57cec5SDimitry Andric                                    IOHandlerDelegate::Completion::LLDBCommand),
4508af732203SDimitry Andric         m_options(), m_python_class_options("scripted stop-hook", true, 'P') {
4509af732203SDimitry Andric     SetHelpLong(
4510af732203SDimitry Andric         R"(
4511af732203SDimitry Andric Command Based stop-hooks:
4512af732203SDimitry Andric -------------------------
4513af732203SDimitry Andric   Stop hooks can run a list of lldb commands by providing one or more
4514af732203SDimitry Andric   --one-line-command options.  The commands will get run in the order they are
4515af732203SDimitry Andric   added.  Or you can provide no commands, in which case you will enter a
4516af732203SDimitry Andric   command editor where you can enter the commands to be run.
4517af732203SDimitry Andric 
4518af732203SDimitry Andric Python Based Stop Hooks:
4519af732203SDimitry Andric ------------------------
4520af732203SDimitry Andric   Stop hooks can be implemented with a suitably defined Python class, whose name
4521af732203SDimitry Andric   is passed in the --python-class option.
4522af732203SDimitry Andric 
4523af732203SDimitry Andric   When the stop hook is added, the class is initialized by calling:
4524af732203SDimitry Andric 
4525*5f7ddb14SDimitry Andric     def __init__(self, target, extra_args, internal_dict):
4526af732203SDimitry Andric 
4527af732203SDimitry Andric     target: The target that the stop hook is being added to.
4528af732203SDimitry Andric     extra_args: An SBStructuredData Dictionary filled with the -key -value
4529af732203SDimitry Andric                 option pairs passed to the command.
4530af732203SDimitry Andric     dict: An implementation detail provided by lldb.
4531af732203SDimitry Andric 
4532af732203SDimitry Andric   Then when the stop-hook triggers, lldb will run the 'handle_stop' method.
4533af732203SDimitry Andric   The method has the signature:
4534af732203SDimitry Andric 
4535af732203SDimitry Andric     def handle_stop(self, exe_ctx, stream):
4536af732203SDimitry Andric 
4537af732203SDimitry Andric     exe_ctx: An SBExecutionContext for the thread that has stopped.
4538af732203SDimitry Andric     stream: An SBStream, anything written to this stream will be printed in the
4539af732203SDimitry Andric             the stop message when the process stops.
4540af732203SDimitry Andric 
4541af732203SDimitry Andric     Return Value: The method returns "should_stop".  If should_stop is false
4542af732203SDimitry Andric                   from all the stop hook executions on threads that stopped
4543af732203SDimitry Andric                   with a reason, then the process will continue.  Note that this
4544af732203SDimitry Andric                   will happen only after all the stop hooks are run.
4545af732203SDimitry Andric 
4546af732203SDimitry Andric Filter Options:
4547af732203SDimitry Andric ---------------
4548af732203SDimitry Andric   Stop hooks can be set to always run, or to only run when the stopped thread
4549af732203SDimitry Andric   matches the filter options passed on the command line.  The available filter
4550af732203SDimitry Andric   options include a shared library or a thread or queue specification,
4551af732203SDimitry Andric   a line range in a source file, a function name or a class name.
4552af732203SDimitry Andric             )");
4553af732203SDimitry Andric     m_all_options.Append(&m_python_class_options,
4554af732203SDimitry Andric                          LLDB_OPT_SET_1 | LLDB_OPT_SET_2,
4555af732203SDimitry Andric                          LLDB_OPT_SET_FROM_TO(4, 6));
4556af732203SDimitry Andric     m_all_options.Append(&m_options);
4557af732203SDimitry Andric     m_all_options.Finalize();
4558af732203SDimitry Andric   }
45590b57cec5SDimitry Andric 
45600b57cec5SDimitry Andric   ~CommandObjectTargetStopHookAdd() override = default;
45610b57cec5SDimitry Andric 
GetOptions()4562af732203SDimitry Andric   Options *GetOptions() override { return &m_all_options; }
45630b57cec5SDimitry Andric 
45640b57cec5SDimitry Andric protected:
IOHandlerActivated(IOHandler & io_handler,bool interactive)45650b57cec5SDimitry Andric   void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
45669dba64beSDimitry Andric     StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
45670b57cec5SDimitry Andric     if (output_sp && interactive) {
45680b57cec5SDimitry Andric       output_sp->PutCString(
45690b57cec5SDimitry Andric           "Enter your stop hook command(s).  Type 'DONE' to end.\n");
45700b57cec5SDimitry Andric       output_sp->Flush();
45710b57cec5SDimitry Andric     }
45720b57cec5SDimitry Andric   }
45730b57cec5SDimitry Andric 
IOHandlerInputComplete(IOHandler & io_handler,std::string & line)45740b57cec5SDimitry Andric   void IOHandlerInputComplete(IOHandler &io_handler,
45750b57cec5SDimitry Andric                               std::string &line) override {
45760b57cec5SDimitry Andric     if (m_stop_hook_sp) {
45770b57cec5SDimitry Andric       if (line.empty()) {
45789dba64beSDimitry Andric         StreamFileSP error_sp(io_handler.GetErrorStreamFileSP());
45790b57cec5SDimitry Andric         if (error_sp) {
45800b57cec5SDimitry Andric           error_sp->Printf("error: stop hook #%" PRIu64
45810b57cec5SDimitry Andric                            " aborted, no commands.\n",
45820b57cec5SDimitry Andric                            m_stop_hook_sp->GetID());
45830b57cec5SDimitry Andric           error_sp->Flush();
45840b57cec5SDimitry Andric         }
45850b57cec5SDimitry Andric         Target *target = GetDebugger().GetSelectedTarget().get();
4586af732203SDimitry Andric         if (target) {
4587af732203SDimitry Andric           target->UndoCreateStopHook(m_stop_hook_sp->GetID());
4588af732203SDimitry Andric         }
45890b57cec5SDimitry Andric       } else {
4590af732203SDimitry Andric         // The IOHandler editor is only for command lines stop hooks:
4591af732203SDimitry Andric         Target::StopHookCommandLine *hook_ptr =
4592af732203SDimitry Andric             static_cast<Target::StopHookCommandLine *>(m_stop_hook_sp.get());
4593af732203SDimitry Andric 
4594af732203SDimitry Andric         hook_ptr->SetActionFromString(line);
45959dba64beSDimitry Andric         StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
45960b57cec5SDimitry Andric         if (output_sp) {
45970b57cec5SDimitry Andric           output_sp->Printf("Stop hook #%" PRIu64 " added.\n",
45980b57cec5SDimitry Andric                             m_stop_hook_sp->GetID());
45990b57cec5SDimitry Andric           output_sp->Flush();
46000b57cec5SDimitry Andric         }
46010b57cec5SDimitry Andric       }
46020b57cec5SDimitry Andric       m_stop_hook_sp.reset();
46030b57cec5SDimitry Andric     }
46040b57cec5SDimitry Andric     io_handler.SetIsDone(true);
46050b57cec5SDimitry Andric   }
46060b57cec5SDimitry Andric 
DoExecute(Args & command,CommandReturnObject & result)46070b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
46080b57cec5SDimitry Andric     m_stop_hook_sp.reset();
46090b57cec5SDimitry Andric 
46109dba64beSDimitry Andric     Target &target = GetSelectedOrDummyTarget();
4611af732203SDimitry Andric     Target::StopHookSP new_hook_sp =
4612af732203SDimitry Andric         target.CreateStopHook(m_python_class_options.GetName().empty() ?
4613af732203SDimitry Andric                                Target::StopHook::StopHookKind::CommandBased
4614af732203SDimitry Andric                                : Target::StopHook::StopHookKind::ScriptBased);
46150b57cec5SDimitry Andric 
46160b57cec5SDimitry Andric     //  First step, make the specifier.
46170b57cec5SDimitry Andric     std::unique_ptr<SymbolContextSpecifier> specifier_up;
46180b57cec5SDimitry Andric     if (m_options.m_sym_ctx_specified) {
46195ffd83dbSDimitry Andric       specifier_up = std::make_unique<SymbolContextSpecifier>(
46205ffd83dbSDimitry Andric           GetDebugger().GetSelectedTarget());
46210b57cec5SDimitry Andric 
46220b57cec5SDimitry Andric       if (!m_options.m_module_name.empty()) {
46230b57cec5SDimitry Andric         specifier_up->AddSpecification(
46240b57cec5SDimitry Andric             m_options.m_module_name.c_str(),
46250b57cec5SDimitry Andric             SymbolContextSpecifier::eModuleSpecified);
46260b57cec5SDimitry Andric       }
46270b57cec5SDimitry Andric 
46280b57cec5SDimitry Andric       if (!m_options.m_class_name.empty()) {
46290b57cec5SDimitry Andric         specifier_up->AddSpecification(
46300b57cec5SDimitry Andric             m_options.m_class_name.c_str(),
46310b57cec5SDimitry Andric             SymbolContextSpecifier::eClassOrNamespaceSpecified);
46320b57cec5SDimitry Andric       }
46330b57cec5SDimitry Andric 
46340b57cec5SDimitry Andric       if (!m_options.m_file_name.empty()) {
46359dba64beSDimitry Andric         specifier_up->AddSpecification(m_options.m_file_name.c_str(),
46360b57cec5SDimitry Andric                                        SymbolContextSpecifier::eFileSpecified);
46370b57cec5SDimitry Andric       }
46380b57cec5SDimitry Andric 
46390b57cec5SDimitry Andric       if (m_options.m_line_start != 0) {
46400b57cec5SDimitry Andric         specifier_up->AddLineSpecification(
46410b57cec5SDimitry Andric             m_options.m_line_start,
46420b57cec5SDimitry Andric             SymbolContextSpecifier::eLineStartSpecified);
46430b57cec5SDimitry Andric       }
46440b57cec5SDimitry Andric 
46450b57cec5SDimitry Andric       if (m_options.m_line_end != UINT_MAX) {
46460b57cec5SDimitry Andric         specifier_up->AddLineSpecification(
46470b57cec5SDimitry Andric             m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
46480b57cec5SDimitry Andric       }
46490b57cec5SDimitry Andric 
46500b57cec5SDimitry Andric       if (!m_options.m_function_name.empty()) {
46510b57cec5SDimitry Andric         specifier_up->AddSpecification(
46520b57cec5SDimitry Andric             m_options.m_function_name.c_str(),
46530b57cec5SDimitry Andric             SymbolContextSpecifier::eFunctionSpecified);
46540b57cec5SDimitry Andric       }
46550b57cec5SDimitry Andric     }
46560b57cec5SDimitry Andric 
46570b57cec5SDimitry Andric     if (specifier_up)
46580b57cec5SDimitry Andric       new_hook_sp->SetSpecifier(specifier_up.release());
46590b57cec5SDimitry Andric 
46600b57cec5SDimitry Andric     // Next see if any of the thread options have been entered:
46610b57cec5SDimitry Andric 
46620b57cec5SDimitry Andric     if (m_options.m_thread_specified) {
46630b57cec5SDimitry Andric       ThreadSpec *thread_spec = new ThreadSpec();
46640b57cec5SDimitry Andric 
46650b57cec5SDimitry Andric       if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) {
46660b57cec5SDimitry Andric         thread_spec->SetTID(m_options.m_thread_id);
46670b57cec5SDimitry Andric       }
46680b57cec5SDimitry Andric 
46690b57cec5SDimitry Andric       if (m_options.m_thread_index != UINT32_MAX)
46700b57cec5SDimitry Andric         thread_spec->SetIndex(m_options.m_thread_index);
46710b57cec5SDimitry Andric 
46720b57cec5SDimitry Andric       if (!m_options.m_thread_name.empty())
46730b57cec5SDimitry Andric         thread_spec->SetName(m_options.m_thread_name.c_str());
46740b57cec5SDimitry Andric 
46750b57cec5SDimitry Andric       if (!m_options.m_queue_name.empty())
46760b57cec5SDimitry Andric         thread_spec->SetQueueName(m_options.m_queue_name.c_str());
46770b57cec5SDimitry Andric 
46780b57cec5SDimitry Andric       new_hook_sp->SetThreadSpecifier(thread_spec);
46790b57cec5SDimitry Andric     }
46800b57cec5SDimitry Andric 
46810b57cec5SDimitry Andric     new_hook_sp->SetAutoContinue(m_options.m_auto_continue);
46820b57cec5SDimitry Andric     if (m_options.m_use_one_liner) {
4683af732203SDimitry Andric       // This is a command line stop hook:
4684af732203SDimitry Andric       Target::StopHookCommandLine *hook_ptr =
4685af732203SDimitry Andric           static_cast<Target::StopHookCommandLine *>(new_hook_sp.get());
4686af732203SDimitry Andric       hook_ptr->SetActionFromStrings(m_options.m_one_liner);
46870b57cec5SDimitry Andric       result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
46880b57cec5SDimitry Andric                                      new_hook_sp->GetID());
4689af732203SDimitry Andric     } else if (!m_python_class_options.GetName().empty()) {
4690af732203SDimitry Andric       // This is a scripted stop hook:
4691af732203SDimitry Andric       Target::StopHookScripted *hook_ptr =
4692af732203SDimitry Andric           static_cast<Target::StopHookScripted *>(new_hook_sp.get());
4693af732203SDimitry Andric       Status error = hook_ptr->SetScriptCallback(
4694af732203SDimitry Andric           m_python_class_options.GetName(),
4695af732203SDimitry Andric           m_python_class_options.GetStructuredData());
4696af732203SDimitry Andric       if (error.Success())
4697af732203SDimitry Andric         result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
4698af732203SDimitry Andric                                        new_hook_sp->GetID());
4699af732203SDimitry Andric       else {
4700af732203SDimitry Andric         // FIXME: Set the stop hook ID counter back.
4701af732203SDimitry Andric         result.AppendErrorWithFormat("Couldn't add stop hook: %s",
4702af732203SDimitry Andric                                      error.AsCString());
4703af732203SDimitry Andric         target.UndoCreateStopHook(new_hook_sp->GetID());
4704af732203SDimitry Andric         return false;
4705af732203SDimitry Andric       }
47060b57cec5SDimitry Andric     } else {
47070b57cec5SDimitry Andric       m_stop_hook_sp = new_hook_sp;
4708480093f4SDimitry Andric       m_interpreter.GetLLDBCommandsFromIOHandler("> ",   // Prompt
4709480093f4SDimitry Andric                                                  *this); // IOHandlerDelegate
47100b57cec5SDimitry Andric     }
47110b57cec5SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishNoResult);
47120b57cec5SDimitry Andric 
47130b57cec5SDimitry Andric     return result.Succeeded();
47140b57cec5SDimitry Andric   }
47150b57cec5SDimitry Andric 
47160b57cec5SDimitry Andric private:
47170b57cec5SDimitry Andric   CommandOptions m_options;
4718af732203SDimitry Andric   OptionGroupPythonClassWithDict m_python_class_options;
4719af732203SDimitry Andric   OptionGroupOptions m_all_options;
4720af732203SDimitry Andric 
47210b57cec5SDimitry Andric   Target::StopHookSP m_stop_hook_sp;
47220b57cec5SDimitry Andric };
47230b57cec5SDimitry Andric 
47240b57cec5SDimitry Andric #pragma mark CommandObjectTargetStopHookDelete
47250b57cec5SDimitry Andric 
47260b57cec5SDimitry Andric // CommandObjectTargetStopHookDelete
47270b57cec5SDimitry Andric 
47280b57cec5SDimitry Andric class CommandObjectTargetStopHookDelete : public CommandObjectParsed {
47290b57cec5SDimitry Andric public:
CommandObjectTargetStopHookDelete(CommandInterpreter & interpreter)47300b57cec5SDimitry Andric   CommandObjectTargetStopHookDelete(CommandInterpreter &interpreter)
47310b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "target stop-hook delete",
47320b57cec5SDimitry Andric                             "Delete a stop-hook.",
47330b57cec5SDimitry Andric                             "target stop-hook delete [<idx>]") {}
47340b57cec5SDimitry Andric 
47350b57cec5SDimitry Andric   ~CommandObjectTargetStopHookDelete() override = default;
47360b57cec5SDimitry Andric 
4737af732203SDimitry Andric   void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)4738af732203SDimitry Andric   HandleArgumentCompletion(CompletionRequest &request,
4739af732203SDimitry Andric                            OptionElementVector &opt_element_vector) override {
4740af732203SDimitry Andric     CommandCompletions::InvokeCommonCompletionCallbacks(
4741af732203SDimitry Andric         GetCommandInterpreter(), CommandCompletions::eStopHookIDCompletion,
4742af732203SDimitry Andric         request, nullptr);
4743af732203SDimitry Andric   }
4744af732203SDimitry Andric 
47450b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)47460b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
47479dba64beSDimitry Andric     Target &target = GetSelectedOrDummyTarget();
47480b57cec5SDimitry Andric     // FIXME: see if we can use the breakpoint id style parser?
47490b57cec5SDimitry Andric     size_t num_args = command.GetArgumentCount();
47500b57cec5SDimitry Andric     if (num_args == 0) {
47510b57cec5SDimitry Andric       if (!m_interpreter.Confirm("Delete all stop hooks?", true)) {
47520b57cec5SDimitry Andric         result.SetStatus(eReturnStatusFailed);
47530b57cec5SDimitry Andric         return false;
47540b57cec5SDimitry Andric       } else {
47559dba64beSDimitry Andric         target.RemoveAllStopHooks();
47560b57cec5SDimitry Andric       }
47570b57cec5SDimitry Andric     } else {
47580b57cec5SDimitry Andric       for (size_t i = 0; i < num_args; i++) {
47595ffd83dbSDimitry Andric         lldb::user_id_t user_id;
47605ffd83dbSDimitry Andric         if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
47610b57cec5SDimitry Andric           result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
47620b57cec5SDimitry Andric                                        command.GetArgumentAtIndex(i));
47630b57cec5SDimitry Andric           return false;
47640b57cec5SDimitry Andric         }
47655ffd83dbSDimitry Andric         if (!target.RemoveStopHookByID(user_id)) {
47660b57cec5SDimitry Andric           result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
47670b57cec5SDimitry Andric                                        command.GetArgumentAtIndex(i));
47680b57cec5SDimitry Andric           return false;
47690b57cec5SDimitry Andric         }
47700b57cec5SDimitry Andric       }
47710b57cec5SDimitry Andric     }
47720b57cec5SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishNoResult);
47730b57cec5SDimitry Andric     return result.Succeeded();
47740b57cec5SDimitry Andric   }
47750b57cec5SDimitry Andric };
47760b57cec5SDimitry Andric 
47770b57cec5SDimitry Andric #pragma mark CommandObjectTargetStopHookEnableDisable
47780b57cec5SDimitry Andric 
47790b57cec5SDimitry Andric // CommandObjectTargetStopHookEnableDisable
47800b57cec5SDimitry Andric 
47810b57cec5SDimitry Andric class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed {
47820b57cec5SDimitry Andric public:
CommandObjectTargetStopHookEnableDisable(CommandInterpreter & interpreter,bool enable,const char * name,const char * help,const char * syntax)47830b57cec5SDimitry Andric   CommandObjectTargetStopHookEnableDisable(CommandInterpreter &interpreter,
47840b57cec5SDimitry Andric                                            bool enable, const char *name,
47850b57cec5SDimitry Andric                                            const char *help, const char *syntax)
47860b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable) {
47870b57cec5SDimitry Andric   }
47880b57cec5SDimitry Andric 
47890b57cec5SDimitry Andric   ~CommandObjectTargetStopHookEnableDisable() override = default;
47900b57cec5SDimitry Andric 
4791af732203SDimitry Andric   void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)4792af732203SDimitry Andric   HandleArgumentCompletion(CompletionRequest &request,
4793af732203SDimitry Andric                            OptionElementVector &opt_element_vector) override {
4794af732203SDimitry Andric     if (request.GetCursorIndex())
4795af732203SDimitry Andric       return;
4796af732203SDimitry Andric     CommandCompletions::InvokeCommonCompletionCallbacks(
4797af732203SDimitry Andric         GetCommandInterpreter(), CommandCompletions::eStopHookIDCompletion,
4798af732203SDimitry Andric         request, nullptr);
4799af732203SDimitry Andric   }
4800af732203SDimitry Andric 
48010b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)48020b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
48039dba64beSDimitry Andric     Target &target = GetSelectedOrDummyTarget();
48040b57cec5SDimitry Andric     // FIXME: see if we can use the breakpoint id style parser?
48050b57cec5SDimitry Andric     size_t num_args = command.GetArgumentCount();
48060b57cec5SDimitry Andric     bool success;
48070b57cec5SDimitry Andric 
48080b57cec5SDimitry Andric     if (num_args == 0) {
48099dba64beSDimitry Andric       target.SetAllStopHooksActiveState(m_enable);
48100b57cec5SDimitry Andric     } else {
48110b57cec5SDimitry Andric       for (size_t i = 0; i < num_args; i++) {
48125ffd83dbSDimitry Andric         lldb::user_id_t user_id;
48135ffd83dbSDimitry Andric         if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
48140b57cec5SDimitry Andric           result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
48150b57cec5SDimitry Andric                                        command.GetArgumentAtIndex(i));
48160b57cec5SDimitry Andric           return false;
48170b57cec5SDimitry Andric         }
48189dba64beSDimitry Andric         success = target.SetStopHookActiveStateByID(user_id, m_enable);
48190b57cec5SDimitry Andric         if (!success) {
48200b57cec5SDimitry Andric           result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
48210b57cec5SDimitry Andric                                        command.GetArgumentAtIndex(i));
48220b57cec5SDimitry Andric           return false;
48230b57cec5SDimitry Andric         }
48240b57cec5SDimitry Andric       }
48250b57cec5SDimitry Andric     }
48260b57cec5SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishNoResult);
48270b57cec5SDimitry Andric     return result.Succeeded();
48280b57cec5SDimitry Andric   }
48290b57cec5SDimitry Andric 
48300b57cec5SDimitry Andric private:
48310b57cec5SDimitry Andric   bool m_enable;
48320b57cec5SDimitry Andric };
48330b57cec5SDimitry Andric 
48340b57cec5SDimitry Andric #pragma mark CommandObjectTargetStopHookList
48350b57cec5SDimitry Andric 
48360b57cec5SDimitry Andric // CommandObjectTargetStopHookList
48370b57cec5SDimitry Andric 
48380b57cec5SDimitry Andric class CommandObjectTargetStopHookList : public CommandObjectParsed {
48390b57cec5SDimitry Andric public:
CommandObjectTargetStopHookList(CommandInterpreter & interpreter)48400b57cec5SDimitry Andric   CommandObjectTargetStopHookList(CommandInterpreter &interpreter)
48410b57cec5SDimitry Andric       : CommandObjectParsed(interpreter, "target stop-hook list",
48420b57cec5SDimitry Andric                             "List all stop-hooks.",
48430b57cec5SDimitry Andric                             "target stop-hook list [<type>]") {}
48440b57cec5SDimitry Andric 
48450b57cec5SDimitry Andric   ~CommandObjectTargetStopHookList() override = default;
48460b57cec5SDimitry Andric 
48470b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)48480b57cec5SDimitry Andric   bool DoExecute(Args &command, CommandReturnObject &result) override {
48499dba64beSDimitry Andric     Target &target = GetSelectedOrDummyTarget();
48500b57cec5SDimitry Andric 
48519dba64beSDimitry Andric     size_t num_hooks = target.GetNumStopHooks();
48520b57cec5SDimitry Andric     if (num_hooks == 0) {
48530b57cec5SDimitry Andric       result.GetOutputStream().PutCString("No stop hooks.\n");
48540b57cec5SDimitry Andric     } else {
48550b57cec5SDimitry Andric       for (size_t i = 0; i < num_hooks; i++) {
48569dba64beSDimitry Andric         Target::StopHookSP this_hook = target.GetStopHookAtIndex(i);
48570b57cec5SDimitry Andric         if (i > 0)
48580b57cec5SDimitry Andric           result.GetOutputStream().PutCString("\n");
48590b57cec5SDimitry Andric         this_hook->GetDescription(&(result.GetOutputStream()),
48600b57cec5SDimitry Andric                                   eDescriptionLevelFull);
48610b57cec5SDimitry Andric       }
48620b57cec5SDimitry Andric     }
48630b57cec5SDimitry Andric     result.SetStatus(eReturnStatusSuccessFinishResult);
48640b57cec5SDimitry Andric     return result.Succeeded();
48650b57cec5SDimitry Andric   }
48660b57cec5SDimitry Andric };
48670b57cec5SDimitry Andric 
48680b57cec5SDimitry Andric #pragma mark CommandObjectMultiwordTargetStopHooks
48690b57cec5SDimitry Andric 
48700b57cec5SDimitry Andric // CommandObjectMultiwordTargetStopHooks
48710b57cec5SDimitry Andric 
48720b57cec5SDimitry Andric class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword {
48730b57cec5SDimitry Andric public:
CommandObjectMultiwordTargetStopHooks(CommandInterpreter & interpreter)48740b57cec5SDimitry Andric   CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter)
48750b57cec5SDimitry Andric       : CommandObjectMultiword(
48760b57cec5SDimitry Andric             interpreter, "target stop-hook",
48770b57cec5SDimitry Andric             "Commands for operating on debugger target stop-hooks.",
48780b57cec5SDimitry Andric             "target stop-hook <subcommand> [<subcommand-options>]") {
48790b57cec5SDimitry Andric     LoadSubCommand("add", CommandObjectSP(
48800b57cec5SDimitry Andric                               new CommandObjectTargetStopHookAdd(interpreter)));
48810b57cec5SDimitry Andric     LoadSubCommand(
48820b57cec5SDimitry Andric         "delete",
48830b57cec5SDimitry Andric         CommandObjectSP(new CommandObjectTargetStopHookDelete(interpreter)));
48840b57cec5SDimitry Andric     LoadSubCommand("disable",
48850b57cec5SDimitry Andric                    CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
48860b57cec5SDimitry Andric                        interpreter, false, "target stop-hook disable [<id>]",
48870b57cec5SDimitry Andric                        "Disable a stop-hook.", "target stop-hook disable")));
48880b57cec5SDimitry Andric     LoadSubCommand("enable",
48890b57cec5SDimitry Andric                    CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
48900b57cec5SDimitry Andric                        interpreter, true, "target stop-hook enable [<id>]",
48910b57cec5SDimitry Andric                        "Enable a stop-hook.", "target stop-hook enable")));
48920b57cec5SDimitry Andric     LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetStopHookList(
48930b57cec5SDimitry Andric                                interpreter)));
48940b57cec5SDimitry Andric   }
48950b57cec5SDimitry Andric 
48960b57cec5SDimitry Andric   ~CommandObjectMultiwordTargetStopHooks() override = default;
48970b57cec5SDimitry Andric };
48980b57cec5SDimitry Andric 
48990b57cec5SDimitry Andric #pragma mark CommandObjectMultiwordTarget
49000b57cec5SDimitry Andric 
49010b57cec5SDimitry Andric // CommandObjectMultiwordTarget
49020b57cec5SDimitry Andric 
CommandObjectMultiwordTarget(CommandInterpreter & interpreter)49030b57cec5SDimitry Andric CommandObjectMultiwordTarget::CommandObjectMultiwordTarget(
49040b57cec5SDimitry Andric     CommandInterpreter &interpreter)
49050b57cec5SDimitry Andric     : CommandObjectMultiword(interpreter, "target",
49060b57cec5SDimitry Andric                              "Commands for operating on debugger targets.",
49070b57cec5SDimitry Andric                              "target <subcommand> [<subcommand-options>]") {
49080b57cec5SDimitry Andric   LoadSubCommand("create",
49090b57cec5SDimitry Andric                  CommandObjectSP(new CommandObjectTargetCreate(interpreter)));
49100b57cec5SDimitry Andric   LoadSubCommand("delete",
49110b57cec5SDimitry Andric                  CommandObjectSP(new CommandObjectTargetDelete(interpreter)));
49120b57cec5SDimitry Andric   LoadSubCommand("list",
49130b57cec5SDimitry Andric                  CommandObjectSP(new CommandObjectTargetList(interpreter)));
49140b57cec5SDimitry Andric   LoadSubCommand("select",
49150b57cec5SDimitry Andric                  CommandObjectSP(new CommandObjectTargetSelect(interpreter)));
49165ffd83dbSDimitry Andric   LoadSubCommand("show-launch-environment",
49175ffd83dbSDimitry Andric                  CommandObjectSP(new CommandObjectTargetShowLaunchEnvironment(
49185ffd83dbSDimitry Andric                      interpreter)));
49190b57cec5SDimitry Andric   LoadSubCommand(
49200b57cec5SDimitry Andric       "stop-hook",
49210b57cec5SDimitry Andric       CommandObjectSP(new CommandObjectMultiwordTargetStopHooks(interpreter)));
49220b57cec5SDimitry Andric   LoadSubCommand("modules",
49230b57cec5SDimitry Andric                  CommandObjectSP(new CommandObjectTargetModules(interpreter)));
49240b57cec5SDimitry Andric   LoadSubCommand("symbols",
49250b57cec5SDimitry Andric                  CommandObjectSP(new CommandObjectTargetSymbols(interpreter)));
49260b57cec5SDimitry Andric   LoadSubCommand("variable",
49270b57cec5SDimitry Andric                  CommandObjectSP(new CommandObjectTargetVariable(interpreter)));
49280b57cec5SDimitry Andric }
49290b57cec5SDimitry Andric 
49300b57cec5SDimitry Andric CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget() = default;
4931