| 1 | //===-- OptionGroupPlatform.cpp -------------------------------------------===// |
| 2 | // |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | |
| 9 | #include "lldb/Interpreter/OptionGroupPlatform.h" |
| 10 | |
| 11 | #include "lldb/Host/OptionParser.h" |
| 12 | #include "lldb/Interpreter/CommandInterpreter.h" |
| 13 | #include "lldb/Target/Platform.h" |
| 14 | |
| 15 | using namespace lldb; |
| 16 | using namespace lldb_private; |
| 17 | |
| 18 | PlatformSP OptionGroupPlatform::CreatePlatformWithOptions( |
| 19 | CommandInterpreter &interpreter, const ArchSpec &arch, bool make_selected, |
| 20 | Status &error, ArchSpec &platform_arch) const { |
| 21 | PlatformList &platforms = interpreter.GetDebugger().GetPlatformList(); |
| 22 | |
| 23 | PlatformSP platform_sp; |
| 24 | |
| 25 | if (!m_platform_name.empty()) { |
| 26 | platform_sp = platforms.Create(name: m_platform_name); |
| 27 | if (!platform_sp) { |
| 28 | error = Status::FromErrorStringWithFormatv( |
| 29 | format: "unable to find a plug-in for the platform named \"{0}\"" , |
| 30 | args: m_platform_name); |
| 31 | } |
| 32 | if (platform_sp) { |
| 33 | if (platform_arch.IsValid() && |
| 34 | !platform_sp->IsCompatibleArchitecture( |
| 35 | arch, process_host_arch: {}, match: ArchSpec::CompatibleMatch, compatible_arch_ptr: &platform_arch)) { |
| 36 | error = Status::FromErrorStringWithFormatv( |
| 37 | format: "platform '{0}' doesn't support '{1}'" , |
| 38 | args: platform_sp->GetPluginName(), args: arch.GetTriple().getTriple()); |
| 39 | platform_sp.reset(); |
| 40 | return platform_sp; |
| 41 | } |
| 42 | } |
| 43 | } else if (arch.IsValid()) { |
| 44 | platform_sp = platforms.GetOrCreate(arch, process_host_arch: {}, platform_arch_ptr: &platform_arch, error); |
| 45 | } |
| 46 | |
| 47 | if (platform_sp) { |
| 48 | if (make_selected) |
| 49 | platforms.SetSelectedPlatform(platform_sp); |
| 50 | if (!m_os_version.empty()) |
| 51 | platform_sp->SetOSVersion(m_os_version); |
| 52 | |
| 53 | if (!m_sdk_sysroot.empty()) |
| 54 | platform_sp->SetSDKRootDirectory(m_sdk_sysroot); |
| 55 | |
| 56 | if (!m_sdk_build.empty()) |
| 57 | platform_sp->SetSDKBuild(m_sdk_build); |
| 58 | } |
| 59 | |
| 60 | return platform_sp; |
| 61 | } |
| 62 | |
| 63 | void OptionGroupPlatform::OptionParsingStarting( |
| 64 | ExecutionContext *execution_context) { |
| 65 | m_platform_name.clear(); |
| 66 | m_sdk_sysroot.clear(); |
| 67 | m_sdk_build.clear(); |
| 68 | m_os_version = llvm::VersionTuple(); |
| 69 | } |
| 70 | |
| 71 | static constexpr OptionDefinition g_option_table[] = { |
| 72 | {LLDB_OPT_SET_ALL, .required: false, .long_option: "platform" , .short_option: 'p', .option_has_arg: OptionParser::eRequiredArgument, |
| 73 | .validator: nullptr, .enum_values: {}, .completion_type: 0, .argument_type: eArgTypePlatform, .usage_text: "Specify name of the platform to " |
| 74 | "use for this target, creating the " |
| 75 | "platform if necessary." }, |
| 76 | {LLDB_OPT_SET_ALL, .required: false, .long_option: "version" , .short_option: 'v', .option_has_arg: OptionParser::eRequiredArgument, |
| 77 | .validator: nullptr, .enum_values: {}, .completion_type: 0, .argument_type: eArgTypeNone, |
| 78 | .usage_text: "Specify the initial SDK version to use prior to connecting." }, |
| 79 | {LLDB_OPT_SET_ALL, .required: false, .long_option: "build" , .short_option: 'b', .option_has_arg: OptionParser::eRequiredArgument, |
| 80 | .validator: nullptr, .enum_values: {}, .completion_type: 0, .argument_type: eArgTypeNone, |
| 81 | .usage_text: "Specify the initial SDK build number." }, |
| 82 | {LLDB_OPT_SET_ALL, .required: false, .long_option: "sysroot" , .short_option: 'S', .option_has_arg: OptionParser::eRequiredArgument, |
| 83 | .validator: nullptr, .enum_values: {}, .completion_type: 0, .argument_type: eArgTypeFilename, .usage_text: "Specify the SDK root directory " |
| 84 | "that contains a root of all " |
| 85 | "remote system files." }}; |
| 86 | |
| 87 | llvm::ArrayRef<OptionDefinition> OptionGroupPlatform::GetDefinitions() { |
| 88 | llvm::ArrayRef<OptionDefinition> result(g_option_table); |
| 89 | if (m_include_platform_option) |
| 90 | return result; |
| 91 | return result.drop_front(); |
| 92 | } |
| 93 | |
| 94 | Status |
| 95 | OptionGroupPlatform::SetOptionValue(uint32_t option_idx, |
| 96 | llvm::StringRef option_arg, |
| 97 | ExecutionContext *execution_context) { |
| 98 | Status error; |
| 99 | if (!m_include_platform_option) |
| 100 | ++option_idx; |
| 101 | |
| 102 | const int short_option = g_option_table[option_idx].short_option; |
| 103 | |
| 104 | switch (short_option) { |
| 105 | case 'p': |
| 106 | m_platform_name.assign(str: option_arg.str()); |
| 107 | break; |
| 108 | |
| 109 | case 'v': |
| 110 | if (m_os_version.tryParse(string: option_arg)) |
| 111 | error = Status::FromErrorStringWithFormatv(format: "invalid version string '{0}'" , |
| 112 | args&: option_arg); |
| 113 | break; |
| 114 | |
| 115 | case 'b': |
| 116 | m_sdk_build.assign(str: option_arg.str()); |
| 117 | break; |
| 118 | |
| 119 | case 'S': |
| 120 | m_sdk_sysroot.assign(str: option_arg.str()); |
| 121 | break; |
| 122 | |
| 123 | default: |
| 124 | llvm_unreachable("Unimplemented option" ); |
| 125 | } |
| 126 | return error; |
| 127 | } |
| 128 | |
| 129 | bool OptionGroupPlatform::PlatformMatches( |
| 130 | const lldb::PlatformSP &platform_sp) const { |
| 131 | if (!platform_sp) |
| 132 | return false; |
| 133 | |
| 134 | if (!m_platform_name.empty() && platform_sp->GetName() != m_platform_name) |
| 135 | return false; |
| 136 | |
| 137 | if (!m_sdk_build.empty() && platform_sp->GetSDKBuild() != m_sdk_build) |
| 138 | return false; |
| 139 | |
| 140 | if (!m_sdk_sysroot.empty() && |
| 141 | platform_sp->GetSDKRootDirectory() != m_sdk_sysroot) |
| 142 | return false; |
| 143 | |
| 144 | if (!m_os_version.empty() && platform_sp->GetOSVersion() != m_os_version) |
| 145 | return false; |
| 146 | |
| 147 | return true; |
| 148 | } |
| 149 | |