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.SetErrorStringWithFormatv( |
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.SetErrorStringWithFormatv(format: "platform '{0}' doesn't support '{1}'" , |
37 | args: platform_sp->GetPluginName(), |
38 | 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.SetErrorStringWithFormatv(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 | |