/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- PlatformMacOSX.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 "PlatformMacOSX.h" |
10 | | #include "PlatformRemoteMacOSX.h" |
11 | | #include "PlatformRemoteiOS.h" |
12 | | #if defined(__APPLE__) |
13 | | #include "PlatformAppleSimulator.h" |
14 | | #include "PlatformDarwinKernel.h" |
15 | | #include "PlatformRemoteAppleBridge.h" |
16 | | #include "PlatformRemoteAppleTV.h" |
17 | | #include "PlatformRemoteAppleWatch.h" |
18 | | #endif |
19 | | #include "lldb/Breakpoint/BreakpointLocation.h" |
20 | | #include "lldb/Core/Debugger.h" |
21 | | #include "lldb/Core/Module.h" |
22 | | #include "lldb/Core/ModuleList.h" |
23 | | #include "lldb/Core/ModuleSpec.h" |
24 | | #include "lldb/Core/PluginManager.h" |
25 | | #include "lldb/Host/Config.h" |
26 | | #include "lldb/Host/Host.h" |
27 | | #include "lldb/Host/HostInfo.h" |
28 | | #include "lldb/Symbol/ObjectFile.h" |
29 | | #include "lldb/Target/Process.h" |
30 | | #include "lldb/Target/Target.h" |
31 | | #include "lldb/Utility/DataBufferHeap.h" |
32 | | #include "lldb/Utility/FileSpec.h" |
33 | | #include "lldb/Utility/Log.h" |
34 | | #include "lldb/Utility/Status.h" |
35 | | #include "lldb/Utility/StreamString.h" |
36 | | |
37 | | #include <sstream> |
38 | | |
39 | | using namespace lldb; |
40 | | using namespace lldb_private; |
41 | | |
42 | | LLDB_PLUGIN_DEFINE(PlatformMacOSX) |
43 | | |
44 | | static uint32_t g_initialize_count = 0; |
45 | | |
46 | 3.94k | void PlatformMacOSX::Initialize() { |
47 | 3.94k | PlatformDarwin::Initialize(); |
48 | 3.94k | PlatformRemoteiOS::Initialize(); |
49 | 3.94k | PlatformRemoteMacOSX::Initialize(); |
50 | 3.94k | #if defined(__APPLE__) |
51 | 3.94k | PlatformAppleSimulator::Initialize(); |
52 | 3.94k | PlatformDarwinKernel::Initialize(); |
53 | 3.94k | PlatformRemoteAppleTV::Initialize(); |
54 | 3.94k | PlatformRemoteAppleWatch::Initialize(); |
55 | 3.94k | PlatformRemoteAppleBridge::Initialize(); |
56 | 3.94k | #endif |
57 | | |
58 | 3.94k | if (g_initialize_count++ == 0) { |
59 | 3.94k | #if defined(__APPLE__) |
60 | 3.94k | PlatformSP default_platform_sp(new PlatformMacOSX()); |
61 | 3.94k | default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture()); |
62 | 3.94k | Platform::SetHostPlatform(default_platform_sp); |
63 | 3.94k | #endif |
64 | 3.94k | PluginManager::RegisterPlugin(PlatformMacOSX::GetPluginNameStatic(), |
65 | 3.94k | PlatformMacOSX::GetDescriptionStatic(), |
66 | 3.94k | PlatformMacOSX::CreateInstance); |
67 | 3.94k | } |
68 | 3.94k | } |
69 | | |
70 | 3.93k | void PlatformMacOSX::Terminate() { |
71 | 3.93k | if (g_initialize_count > 0) { |
72 | 3.93k | if (--g_initialize_count == 0) { |
73 | 3.93k | PluginManager::UnregisterPlugin(PlatformMacOSX::CreateInstance); |
74 | 3.93k | } |
75 | 3.93k | } |
76 | | |
77 | 3.93k | #if defined(__APPLE__) |
78 | 3.93k | PlatformRemoteAppleBridge::Terminate(); |
79 | 3.93k | PlatformRemoteAppleWatch::Terminate(); |
80 | 3.93k | PlatformRemoteAppleTV::Terminate(); |
81 | 3.93k | PlatformDarwinKernel::Terminate(); |
82 | 3.93k | PlatformAppleSimulator::Terminate(); |
83 | 3.93k | #endif |
84 | 3.93k | PlatformRemoteMacOSX::Initialize(); |
85 | 3.93k | PlatformRemoteiOS::Terminate(); |
86 | 3.93k | PlatformDarwin::Terminate(); |
87 | 3.93k | } |
88 | | |
89 | 3.95k | llvm::StringRef PlatformMacOSX::GetDescriptionStatic() { |
90 | 3.95k | return "Local Mac OS X user platform plug-in."; |
91 | 3.95k | } |
92 | | |
93 | 206 | PlatformSP PlatformMacOSX::CreateInstance(bool force, const ArchSpec *arch) { |
94 | | // The only time we create an instance is when we are creating a remote |
95 | | // macosx platform which is handled by PlatformRemoteMacOSX. |
96 | 206 | return PlatformSP(); |
97 | 206 | } |
98 | | |
99 | | /// Default Constructor |
100 | 3.94k | PlatformMacOSX::PlatformMacOSX() : PlatformDarwinDevice(true) {} |
101 | | |
102 | 0 | ConstString PlatformMacOSX::GetSDKDirectory(lldb_private::Target &target) { |
103 | 0 | ModuleSP exe_module_sp(target.GetExecutableModule()); |
104 | 0 | if (!exe_module_sp) |
105 | 0 | return {}; |
106 | | |
107 | 0 | ObjectFile *objfile = exe_module_sp->GetObjectFile(); |
108 | 0 | if (!objfile) |
109 | 0 | return {}; |
110 | | |
111 | 0 | llvm::VersionTuple version = objfile->GetSDKVersion(); |
112 | 0 | if (version.empty()) |
113 | 0 | return {}; |
114 | | |
115 | | // First try to find an SDK that matches the given SDK version. |
116 | 0 | if (FileSpec fspec = HostInfo::GetXcodeContentsDirectory()) { |
117 | 0 | StreamString sdk_path; |
118 | 0 | sdk_path.Printf("%s/Developer/Platforms/MacOSX.platform/Developer/" |
119 | 0 | "SDKs/MacOSX%u.%u.sdk", |
120 | 0 | fspec.GetPath().c_str(), version.getMajor(), |
121 | 0 | *version.getMinor()); |
122 | 0 | if (FileSystem::Instance().Exists(fspec)) |
123 | 0 | return ConstString(sdk_path.GetString()); |
124 | 0 | } |
125 | | |
126 | | // Use the default SDK as a fallback. |
127 | 0 | auto sdk_path_or_err = |
128 | 0 | HostInfo::GetSDKRoot(HostInfo::SDKOptions{XcodeSDK::GetAnyMacOS()}); |
129 | 0 | if (!sdk_path_or_err) { |
130 | 0 | Debugger::ReportError("Error while searching for Xcode SDK: " + |
131 | 0 | toString(sdk_path_or_err.takeError())); |
132 | 0 | return {}; |
133 | 0 | } |
134 | | |
135 | 0 | FileSpec fspec(*sdk_path_or_err); |
136 | 0 | if (fspec) { |
137 | 0 | if (FileSystem::Instance().Exists(fspec)) |
138 | 0 | return ConstString(fspec.GetPath()); |
139 | 0 | } |
140 | | |
141 | 0 | return {}; |
142 | 0 | } |
143 | | |
144 | | std::vector<ArchSpec> |
145 | 7.70k | PlatformMacOSX::GetSupportedArchitectures(const ArchSpec &process_host_arch) { |
146 | 7.70k | std::vector<ArchSpec> result; |
147 | | #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) |
148 | | // When cmdline lldb is run on iOS, watchOS, etc, it is still |
149 | | // using "PlatformMacOSX". |
150 | | llvm::Triple::OSType host_os = GetHostOSType(); |
151 | | ARMGetSupportedArchitectures(result, host_os); |
152 | | |
153 | | if (host_os == llvm::Triple::MacOSX) { |
154 | | // We can't use x86GetSupportedArchitectures() because it uses |
155 | | // the system architecture for some of its return values and also |
156 | | // has a 32bits variant. |
157 | | result.push_back(ArchSpec("x86_64-apple-macosx")); |
158 | | result.push_back(ArchSpec("x86_64-apple-ios-macabi")); |
159 | | result.push_back(ArchSpec("arm64-apple-ios-macabi")); |
160 | | result.push_back(ArchSpec("arm64e-apple-ios-macabi")); |
161 | | |
162 | | // On Apple Silicon, the host platform is compatible with iOS triples to |
163 | | // support unmodified "iPhone and iPad Apps on Apple Silicon Macs". Because |
164 | | // the binaries are identical, we must rely on the host architecture to |
165 | | // tell them apart and mark the host platform as compatible or not. |
166 | | if (!process_host_arch || |
167 | | process_host_arch.GetTriple().getOS() == llvm::Triple::MacOSX) { |
168 | | result.push_back(ArchSpec("arm64-apple-ios")); |
169 | | result.push_back(ArchSpec("arm64e-apple-ios")); |
170 | | } |
171 | | } |
172 | | #else |
173 | 7.70k | x86GetSupportedArchitectures(result); |
174 | 7.70k | result.push_back(ArchSpec("x86_64-apple-ios-macabi")); |
175 | 7.70k | #endif |
176 | 7.70k | return result; |
177 | 7.70k | } |
178 | | |
179 | | lldb_private::Status PlatformMacOSX::GetSharedModule( |
180 | | const lldb_private::ModuleSpec &module_spec, Process *process, |
181 | | lldb::ModuleSP &module_sp, |
182 | | const lldb_private::FileSpecList *module_search_paths_ptr, |
183 | 115k | llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules, bool *did_create_ptr) { |
184 | 115k | Status error = GetSharedModuleWithLocalCache(module_spec, module_sp, |
185 | 115k | module_search_paths_ptr, |
186 | 115k | old_modules, did_create_ptr); |
187 | | |
188 | 115k | if (module_sp) { |
189 | 114k | if (module_spec.GetArchitecture().GetCore() == |
190 | 114k | ArchSpec::eCore_x86_64_x86_64h) { |
191 | 0 | ObjectFile *objfile = module_sp->GetObjectFile(); |
192 | 0 | if (objfile == nullptr) { |
193 | | // We didn't find an x86_64h slice, fall back to a x86_64 slice |
194 | 0 | ModuleSpec module_spec_x86_64(module_spec); |
195 | 0 | module_spec_x86_64.GetArchitecture() = ArchSpec("x86_64-apple-macosx"); |
196 | 0 | lldb::ModuleSP x86_64_module_sp; |
197 | 0 | llvm::SmallVector<lldb::ModuleSP, 1> old_x86_64_modules; |
198 | 0 | bool did_create = false; |
199 | 0 | Status x86_64_error = GetSharedModuleWithLocalCache( |
200 | 0 | module_spec_x86_64, x86_64_module_sp, module_search_paths_ptr, |
201 | 0 | &old_x86_64_modules, &did_create); |
202 | 0 | if (x86_64_module_sp && x86_64_module_sp->GetObjectFile()) { |
203 | 0 | module_sp = x86_64_module_sp; |
204 | 0 | if (old_modules) |
205 | 0 | old_modules->append(old_x86_64_modules.begin(), |
206 | 0 | old_x86_64_modules.end()); |
207 | 0 | if (did_create_ptr) |
208 | 0 | *did_create_ptr = did_create; |
209 | 0 | return x86_64_error; |
210 | 0 | } |
211 | 0 | } |
212 | 0 | } |
213 | 114k | } |
214 | | |
215 | 115k | if (!module_sp) { |
216 | 355 | error = FindBundleBinaryInExecSearchPaths(module_spec, process, module_sp, |
217 | 355 | module_search_paths_ptr, |
218 | 355 | old_modules, did_create_ptr); |
219 | 355 | } |
220 | 115k | return error; |
221 | 115k | } |
222 | | |
223 | 1.79k | llvm::StringRef PlatformMacOSX::GetDeviceSupportDirectoryName() { |
224 | 1.79k | return "macOS DeviceSupport"; |
225 | 1.79k | } |
226 | | |
227 | 1.79k | llvm::StringRef PlatformMacOSX::GetPlatformName() { return "MacOSX.platform"; } |