1 //===-- OptionGroupPlatform.cpp ---------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/Interpreter/OptionGroupPlatform.h"
11 
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/Interpreter/CommandInterpreter.h"
17 #include "lldb/Target/Platform.h"
18 #include "lldb/Utility/Utils.h"
19 
20 using namespace lldb;
21 using namespace lldb_private;
22 
23 PlatformSP
24 OptionGroupPlatform::CreatePlatformWithOptions (CommandInterpreter &interpreter,
25                                                 const ArchSpec &arch,
26                                                 bool make_selected,
27                                                 Error& error,
28                                                 ArchSpec &platform_arch) const
29 {
30     PlatformSP platform_sp;
31 
32     if (!m_platform_name.empty())
33     {
34         platform_sp = Platform::Create (ConstString(m_platform_name.c_str()), error);
35         if (platform_sp)
36         {
37             if (platform_arch.IsValid() && !platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch))
38             {
39                 error.SetErrorStringWithFormat ("platform '%s' doesn't support '%s'",
40                                                 platform_sp->GetName().GetCString(),
41                                                 arch.GetTriple().getTriple().c_str());
42                 platform_sp.reset();
43                 return platform_sp;
44             }
45         }
46     }
47     else if (arch.IsValid())
48     {
49         platform_sp = Platform::Create (arch, &platform_arch, error);
50     }
51 
52     if (platform_sp)
53     {
54         interpreter.GetDebugger().GetPlatformList().Append (platform_sp, make_selected);
55         if (m_os_version_major != UINT32_MAX)
56         {
57             platform_sp->SetOSVersion (m_os_version_major,
58                                        m_os_version_minor,
59                                        m_os_version_update);
60         }
61 
62         if (m_sdk_sysroot)
63             platform_sp->SetSDKRootDirectory (m_sdk_sysroot);
64 
65         if (m_sdk_build)
66             platform_sp->SetSDKBuild (m_sdk_build);
67     }
68 
69     return platform_sp;
70 }
71 
72 void
73 OptionGroupPlatform::OptionParsingStarting (CommandInterpreter &interpreter)
74 {
75     m_platform_name.clear();
76     m_sdk_sysroot.Clear();
77     m_sdk_build.Clear();
78     m_os_version_major = UINT32_MAX;
79     m_os_version_minor = UINT32_MAX;
80     m_os_version_update = UINT32_MAX;
81 }
82 
83 static OptionDefinition
84 g_option_table[] =
85 {
86     { LLDB_OPT_SET_ALL, false, "platform", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePlatform, "Specify name of the platform to use for this target, creating the platform if necessary."},
87     { LLDB_OPT_SET_ALL, false, "version" , 'v', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "Specify the initial SDK version to use prior to connecting." },
88     { LLDB_OPT_SET_ALL, false, "build"   , 'b', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "Specify the initial SDK build number." },
89     { LLDB_OPT_SET_ALL, false, "sysroot" , 'S', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFilename, "Specify the SDK root directory that contains a root of all remote system files." }
90 };
91 
92 const OptionDefinition*
93 OptionGroupPlatform::GetDefinitions ()
94 {
95     if (m_include_platform_option)
96         return g_option_table;
97     return g_option_table + 1;
98 }
99 
100 uint32_t
101 OptionGroupPlatform::GetNumDefinitions ()
102 {
103     if (m_include_platform_option)
104         return llvm::array_lengthof(g_option_table);
105     return llvm::array_lengthof(g_option_table) - 1;
106 }
107 
108 
109 Error
110 OptionGroupPlatform::SetOptionValue (CommandInterpreter &interpreter,
111                                      uint32_t option_idx,
112                                      const char *option_arg)
113 {
114     Error error;
115     if (!m_include_platform_option)
116         ++option_idx;
117 
118     const int short_option = g_option_table[option_idx].short_option;
119 
120     switch (short_option)
121     {
122         case 'p':
123             m_platform_name.assign (option_arg);
124             break;
125 
126         case 'v':
127             if (Args::StringToVersion (option_arg,
128                                        m_os_version_major,
129                                        m_os_version_minor,
130                                        m_os_version_update) == option_arg)
131                 error.SetErrorStringWithFormat ("invalid version string '%s'", option_arg);
132             break;
133 
134         case 'b':
135             m_sdk_build.SetCString (option_arg);
136             break;
137 
138         case 'S':
139             m_sdk_sysroot.SetCString (option_arg);
140             break;
141 
142         default:
143             error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
144             break;
145     }
146     return error;
147 }
148 
149 bool
150 OptionGroupPlatform::PlatformMatches(const lldb::PlatformSP &platform_sp) const
151 {
152     if (platform_sp)
153     {
154         if (!m_platform_name.empty())
155         {
156             if (platform_sp->GetName() != ConstString(m_platform_name.c_str()))
157                 return false;
158         }
159 
160         if (m_sdk_build && m_sdk_build != platform_sp->GetSDKBuild())
161             return false;
162 
163         if (m_sdk_sysroot && m_sdk_sysroot != platform_sp->GetSDKRootDirectory())
164             return false;
165 
166         if (m_os_version_major != UINT32_MAX)
167         {
168             uint32_t major, minor, update;
169             if (platform_sp->GetOSVersion (major, minor, update))
170             {
171                 if (m_os_version_major != major)
172                     return false;
173                 if (m_os_version_minor != minor)
174                     return false;
175                 if (m_os_version_update != update)
176                     return false;
177             }
178         }
179         return true;
180     }
181     return false;
182 }
183