1 //===-- PlatformRemoteDarwinDevice.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 "PlatformRemoteDarwinDevice.h"
10
11 #include "lldb/Breakpoint/BreakpointLocation.h"
12 #include "lldb/Core/Module.h"
13 #include "lldb/Core/ModuleList.h"
14 #include "lldb/Core/ModuleSpec.h"
15 #include "lldb/Core/PluginManager.h"
16 #include "lldb/Host/FileSystem.h"
17 #include "lldb/Host/Host.h"
18 #include "lldb/Host/HostInfo.h"
19 #include "lldb/Target/Process.h"
20 #include "lldb/Target/Target.h"
21 #include "lldb/Utility/FileSpec.h"
22 #include "lldb/Utility/Log.h"
23 #include "lldb/Utility/Status.h"
24 #include "lldb/Utility/StreamString.h"
25
26 using namespace lldb;
27 using namespace lldb_private;
28
SDKDirectoryInfo(const lldb_private::FileSpec & sdk_dir)29 PlatformRemoteDarwinDevice::SDKDirectoryInfo::SDKDirectoryInfo(
30 const lldb_private::FileSpec &sdk_dir)
31 : directory(sdk_dir), build(), user_cached(false) {
32 llvm::StringRef dirname_str = sdk_dir.GetFilename().GetStringRef();
33 llvm::StringRef build_str;
34 std::tie(version, build_str) = ParseVersionBuildDir(dirname_str);
35 build.SetString(build_str);
36 }
37
38 /// Default Constructor
PlatformRemoteDarwinDevice()39 PlatformRemoteDarwinDevice::PlatformRemoteDarwinDevice()
40 : PlatformDarwin(false), // This is a remote platform
41 m_sdk_directory_infos(), m_device_support_directory(),
42 m_device_support_directory_for_os_version(), m_build_update(),
43 m_last_module_sdk_idx(UINT32_MAX),
44 m_connected_module_sdk_idx(UINT32_MAX) {}
45
46 /// Destructor.
47 ///
48 /// The destructor is virtual since this class is designed to be
49 /// inherited from by the plug-in instance.
~PlatformRemoteDarwinDevice()50 PlatformRemoteDarwinDevice::~PlatformRemoteDarwinDevice() {}
51
GetStatus(Stream & strm)52 void PlatformRemoteDarwinDevice::GetStatus(Stream &strm) {
53 Platform::GetStatus(strm);
54 const char *sdk_directory = GetDeviceSupportDirectoryForOSVersion();
55 if (sdk_directory)
56 strm.Printf(" SDK Path: \"%s\"\n", sdk_directory);
57 else
58 strm.PutCString(" SDK Path: error: unable to locate SDK\n");
59
60 const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
61 for (uint32_t i = 0; i < num_sdk_infos; ++i) {
62 const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
63 strm.Printf(" SDK Roots: [%2u] \"%s\"\n", i,
64 sdk_dir_info.directory.GetPath().c_str());
65 }
66 }
67
ResolveExecutable(const ModuleSpec & ms,lldb::ModuleSP & exe_module_sp,const FileSpecList * module_search_paths_ptr)68 Status PlatformRemoteDarwinDevice::ResolveExecutable(
69 const ModuleSpec &ms, lldb::ModuleSP &exe_module_sp,
70 const FileSpecList *module_search_paths_ptr) {
71 Status error;
72 // Nothing special to do here, just use the actual file and architecture
73
74 ModuleSpec resolved_module_spec(ms);
75
76 // Resolve any executable within a bundle on MacOSX
77 // TODO: verify that this handles shallow bundles, if not then implement one
78 // ourselves
79 Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
80
81 if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) {
82 if (resolved_module_spec.GetArchitecture().IsValid() ||
83 resolved_module_spec.GetUUID().IsValid()) {
84 error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
85 nullptr, nullptr, nullptr);
86
87 if (exe_module_sp && exe_module_sp->GetObjectFile())
88 return error;
89 exe_module_sp.reset();
90 }
91 // No valid architecture was specified or the exact ARM slice wasn't found
92 // so ask the platform for the architectures that we should be using (in
93 // the correct order) and see if we can find a match that way
94 StreamString arch_names;
95 for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
96 idx, resolved_module_spec.GetArchitecture());
97 ++idx) {
98 error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
99 nullptr, nullptr, nullptr);
100 // Did we find an executable using one of the
101 if (error.Success()) {
102 if (exe_module_sp && exe_module_sp->GetObjectFile())
103 break;
104 else
105 error.SetErrorToGenericError();
106 }
107
108 if (idx > 0)
109 arch_names.PutCString(", ");
110 arch_names.PutCString(
111 resolved_module_spec.GetArchitecture().GetArchitectureName());
112 }
113
114 if (error.Fail() || !exe_module_sp) {
115 if (FileSystem::Instance().Readable(resolved_module_spec.GetFileSpec())) {
116 error.SetErrorStringWithFormat(
117 "'%s' doesn't contain any '%s' platform architectures: %s",
118 resolved_module_spec.GetFileSpec().GetPath().c_str(),
119 GetPluginName().GetCString(), arch_names.GetData());
120 } else {
121 error.SetErrorStringWithFormat(
122 "'%s' is not readable",
123 resolved_module_spec.GetFileSpec().GetPath().c_str());
124 }
125 }
126 } else {
127 error.SetErrorStringWithFormat(
128 "'%s' does not exist",
129 resolved_module_spec.GetFileSpec().GetPath().c_str());
130 }
131
132 return error;
133 }
134
135 FileSystem::EnumerateDirectoryResult
GetContainedFilesIntoVectorOfStringsCallback(void * baton,llvm::sys::fs::file_type ft,llvm::StringRef path)136 PlatformRemoteDarwinDevice::GetContainedFilesIntoVectorOfStringsCallback(
137 void *baton, llvm::sys::fs::file_type ft, llvm::StringRef path) {
138 ((PlatformRemoteDarwinDevice::SDKDirectoryInfoCollection *)baton)
139 ->push_back(PlatformRemoteDarwinDevice::SDKDirectoryInfo(FileSpec(path)));
140 return FileSystem::eEnumerateDirectoryResultNext;
141 }
142
UpdateSDKDirectoryInfosIfNeeded()143 bool PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded() {
144 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
145 std::lock_guard<std::mutex> guard(m_sdk_dir_mutex);
146 if (m_sdk_directory_infos.empty()) {
147 // A --sysroot option was supplied - add it to our list of SDKs to check
148 if (m_sdk_sysroot) {
149 FileSpec sdk_sysroot_fspec(m_sdk_sysroot.GetCString());
150 FileSystem::Instance().Resolve(sdk_sysroot_fspec);
151 const SDKDirectoryInfo sdk_sysroot_directory_info(sdk_sysroot_fspec);
152 m_sdk_directory_infos.push_back(sdk_sysroot_directory_info);
153 if (log) {
154 LLDB_LOGF(
155 log,
156 "PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded added "
157 "--sysroot SDK directory %s",
158 m_sdk_sysroot.GetCString());
159 }
160 return true;
161 }
162 const char *device_support_dir = GetDeviceSupportDirectory();
163 if (log) {
164 LLDB_LOGF(
165 log,
166 "PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded Got "
167 "DeviceSupport directory %s",
168 device_support_dir);
169 }
170 if (device_support_dir) {
171 const bool find_directories = true;
172 const bool find_files = false;
173 const bool find_other = false;
174
175 SDKDirectoryInfoCollection builtin_sdk_directory_infos;
176 FileSystem::Instance().EnumerateDirectory(
177 m_device_support_directory, find_directories, find_files, find_other,
178 GetContainedFilesIntoVectorOfStringsCallback,
179 &builtin_sdk_directory_infos);
180
181 // Only add SDK directories that have symbols in them, some SDKs only
182 // contain developer disk images and no symbols, so they aren't useful to
183 // us.
184 FileSpec sdk_symbols_symlink_fspec;
185 for (const auto &sdk_directory_info : builtin_sdk_directory_infos) {
186 sdk_symbols_symlink_fspec = sdk_directory_info.directory;
187 sdk_symbols_symlink_fspec.AppendPathComponent("Symbols");
188 if (FileSystem::Instance().Exists(sdk_symbols_symlink_fspec)) {
189 m_sdk_directory_infos.push_back(sdk_directory_info);
190 if (log) {
191 LLDB_LOGF(
192 log,
193 "PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded "
194 "added builtin SDK directory %s",
195 sdk_symbols_symlink_fspec.GetPath().c_str());
196 }
197 }
198 }
199
200 const uint32_t num_installed = m_sdk_directory_infos.size();
201 llvm::StringRef dirname = GetDeviceSupportDirectoryName();
202 std::string local_sdk_cache_str = "~/Library/Developer/Xcode/";
203 local_sdk_cache_str += std::string(dirname);
204 FileSpec local_sdk_cache(local_sdk_cache_str.c_str());
205 FileSystem::Instance().Resolve(local_sdk_cache);
206 if (FileSystem::Instance().Exists(local_sdk_cache)) {
207 if (log) {
208 LLDB_LOGF(
209 log,
210 "PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded "
211 "searching %s for additional SDKs",
212 local_sdk_cache.GetPath().c_str());
213 }
214 char path[PATH_MAX];
215 if (local_sdk_cache.GetPath(path, sizeof(path))) {
216 FileSystem::Instance().EnumerateDirectory(
217 path, find_directories, find_files, find_other,
218 GetContainedFilesIntoVectorOfStringsCallback,
219 &m_sdk_directory_infos);
220 const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
221 // First try for an exact match of major, minor and update
222 for (uint32_t i = num_installed; i < num_sdk_infos; ++i) {
223 m_sdk_directory_infos[i].user_cached = true;
224 if (log) {
225 LLDB_LOGF(log,
226 "PlatformRemoteDarwinDevice::"
227 "UpdateSDKDirectoryInfosIfNeeded "
228 "user SDK directory %s",
229 m_sdk_directory_infos[i].directory.GetPath().c_str());
230 }
231 }
232 }
233 }
234
235 const char *addtional_platform_dirs = getenv("PLATFORM_SDK_DIRECTORY");
236 if (addtional_platform_dirs) {
237 SDKDirectoryInfoCollection env_var_sdk_directory_infos;
238 FileSystem::Instance().EnumerateDirectory(
239 addtional_platform_dirs, find_directories, find_files, find_other,
240 GetContainedFilesIntoVectorOfStringsCallback,
241 &env_var_sdk_directory_infos);
242 FileSpec sdk_symbols_symlink_fspec;
243 for (const auto &sdk_directory_info : env_var_sdk_directory_infos) {
244 sdk_symbols_symlink_fspec = sdk_directory_info.directory;
245 sdk_symbols_symlink_fspec.AppendPathComponent("Symbols");
246 if (FileSystem::Instance().Exists(sdk_symbols_symlink_fspec)) {
247 m_sdk_directory_infos.push_back(sdk_directory_info);
248 if (log) {
249 LLDB_LOGF(
250 log,
251 "PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded "
252 "added env var SDK directory %s",
253 sdk_symbols_symlink_fspec.GetPath().c_str());
254 }
255 }
256 }
257 }
258
259 }
260 }
261 return !m_sdk_directory_infos.empty();
262 }
263
264 const PlatformRemoteDarwinDevice::SDKDirectoryInfo *
GetSDKDirectoryForCurrentOSVersion()265 PlatformRemoteDarwinDevice::GetSDKDirectoryForCurrentOSVersion() {
266 uint32_t i;
267 if (UpdateSDKDirectoryInfosIfNeeded()) {
268 const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
269
270 // Check to see if the user specified a build string. If they did, then be
271 // sure to match it.
272 std::vector<bool> check_sdk_info(num_sdk_infos, true);
273 ConstString build(m_sdk_build);
274 if (build) {
275 for (i = 0; i < num_sdk_infos; ++i)
276 check_sdk_info[i] = m_sdk_directory_infos[i].build == build;
277 }
278
279 // If we are connected we can find the version of the OS the platform us
280 // running on and select the right SDK
281 llvm::VersionTuple version = GetOSVersion();
282 if (!version.empty()) {
283 if (UpdateSDKDirectoryInfosIfNeeded()) {
284 // First try for an exact match of major, minor and update
285 for (i = 0; i < num_sdk_infos; ++i) {
286 if (check_sdk_info[i]) {
287 if (m_sdk_directory_infos[i].version == version)
288 return &m_sdk_directory_infos[i];
289 }
290 }
291 // First try for an exact match of major and minor
292 for (i = 0; i < num_sdk_infos; ++i) {
293 if (check_sdk_info[i]) {
294 if (m_sdk_directory_infos[i].version.getMajor() ==
295 version.getMajor() &&
296 m_sdk_directory_infos[i].version.getMinor() ==
297 version.getMinor()) {
298 return &m_sdk_directory_infos[i];
299 }
300 }
301 }
302 // Lastly try to match of major version only..
303 for (i = 0; i < num_sdk_infos; ++i) {
304 if (check_sdk_info[i]) {
305 if (m_sdk_directory_infos[i].version.getMajor() ==
306 version.getMajor()) {
307 return &m_sdk_directory_infos[i];
308 }
309 }
310 }
311 }
312 } else if (build) {
313 // No version, just a build number, search for the first one that matches
314 for (i = 0; i < num_sdk_infos; ++i)
315 if (check_sdk_info[i])
316 return &m_sdk_directory_infos[i];
317 }
318 }
319 return nullptr;
320 }
321
322 const PlatformRemoteDarwinDevice::SDKDirectoryInfo *
GetSDKDirectoryForLatestOSVersion()323 PlatformRemoteDarwinDevice::GetSDKDirectoryForLatestOSVersion() {
324 const PlatformRemoteDarwinDevice::SDKDirectoryInfo *result = nullptr;
325 if (UpdateSDKDirectoryInfosIfNeeded()) {
326 auto max = std::max_element(
327 m_sdk_directory_infos.begin(), m_sdk_directory_infos.end(),
328 [](const SDKDirectoryInfo &a, const SDKDirectoryInfo &b) {
329 return a.version < b.version;
330 });
331 if (max != m_sdk_directory_infos.end())
332 result = &*max;
333 }
334 return result;
335 }
336
GetDeviceSupportDirectory()337 const char *PlatformRemoteDarwinDevice::GetDeviceSupportDirectory() {
338 std::string platform_dir =
339 ("/Platforms/" + GetPlatformName() + "/DeviceSupport").str();
340 if (m_device_support_directory.empty()) {
341 if (FileSpec fspec = HostInfo::GetXcodeDeveloperDirectory()) {
342 m_device_support_directory = fspec.GetPath();
343 m_device_support_directory.append(platform_dir.c_str());
344 } else {
345 // Assign a single NULL character so we know we tried to find the device
346 // support directory and we don't keep trying to find it over and over.
347 m_device_support_directory.assign(1, '\0');
348 }
349 }
350 // We should have put a single NULL character into m_device_support_directory
351 // or it should have a valid path if the code gets here
352 assert(m_device_support_directory.empty() == false);
353 if (m_device_support_directory[0])
354 return m_device_support_directory.c_str();
355 return nullptr;
356 }
357
GetDeviceSupportDirectoryForOSVersion()358 const char *PlatformRemoteDarwinDevice::GetDeviceSupportDirectoryForOSVersion() {
359 if (m_sdk_sysroot)
360 return m_sdk_sysroot.GetCString();
361
362 if (m_device_support_directory_for_os_version.empty()) {
363 const PlatformRemoteDarwinDevice::SDKDirectoryInfo *sdk_dir_info =
364 GetSDKDirectoryForCurrentOSVersion();
365 if (sdk_dir_info == nullptr)
366 sdk_dir_info = GetSDKDirectoryForLatestOSVersion();
367 if (sdk_dir_info) {
368 char path[PATH_MAX];
369 if (sdk_dir_info->directory.GetPath(path, sizeof(path))) {
370 m_device_support_directory_for_os_version = path;
371 return m_device_support_directory_for_os_version.c_str();
372 }
373 } else {
374 // Assign a single NULL character so we know we tried to find the device
375 // support directory and we don't keep trying to find it over and over.
376 m_device_support_directory_for_os_version.assign(1, '\0');
377 }
378 }
379 // We should have put a single NULL character into
380 // m_device_support_directory_for_os_version or it should have a valid path
381 // if the code gets here
382 assert(m_device_support_directory_for_os_version.empty() == false);
383 if (m_device_support_directory_for_os_version[0])
384 return m_device_support_directory_for_os_version.c_str();
385 return nullptr;
386 }
387
FindFileInAllSDKs(const char * platform_file_path,FileSpecList & file_list)388 uint32_t PlatformRemoteDarwinDevice::FindFileInAllSDKs(const char *platform_file_path,
389 FileSpecList &file_list) {
390 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
391 if (platform_file_path && platform_file_path[0] &&
392 UpdateSDKDirectoryInfosIfNeeded()) {
393 const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
394 lldb_private::FileSpec local_file;
395 // First try for an exact match of major, minor and update
396 for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) {
397 LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file_path,
398 m_sdk_directory_infos[sdk_idx].directory);
399 if (GetFileInSDK(platform_file_path, sdk_idx, local_file)) {
400 file_list.Append(local_file);
401 }
402 }
403 }
404 return file_list.GetSize();
405 }
406
GetFileInSDK(const char * platform_file_path,uint32_t sdk_idx,lldb_private::FileSpec & local_file)407 bool PlatformRemoteDarwinDevice::GetFileInSDK(const char *platform_file_path,
408 uint32_t sdk_idx,
409 lldb_private::FileSpec &local_file) {
410 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
411 if (sdk_idx < m_sdk_directory_infos.size()) {
412 std::string sdkroot_path =
413 m_sdk_directory_infos[sdk_idx].directory.GetPath();
414 local_file.Clear();
415
416 if (!sdkroot_path.empty() && platform_file_path && platform_file_path[0]) {
417 // We may need to interpose "/Symbols/" or "/Symbols.Internal/" between
418 // the
419 // SDK root directory and the file path.
420
421 const char *paths_to_try[] = {"Symbols", "", "Symbols.Internal", nullptr};
422 for (size_t i = 0; paths_to_try[i] != nullptr; i++) {
423 local_file.SetFile(sdkroot_path, FileSpec::Style::native);
424 if (paths_to_try[i][0] != '\0')
425 local_file.AppendPathComponent(paths_to_try[i]);
426 local_file.AppendPathComponent(platform_file_path);
427 FileSystem::Instance().Resolve(local_file);
428 if (FileSystem::Instance().Exists(local_file)) {
429 LLDB_LOGF(log, "Found a copy of %s in the SDK dir %s/%s",
430 platform_file_path, sdkroot_path.c_str(), paths_to_try[i]);
431 return true;
432 }
433 local_file.Clear();
434 }
435 }
436 }
437 return false;
438 }
439
GetSymbolFile(const FileSpec & platform_file,const UUID * uuid_ptr,FileSpec & local_file)440 Status PlatformRemoteDarwinDevice::GetSymbolFile(const FileSpec &platform_file,
441 const UUID *uuid_ptr,
442 FileSpec &local_file) {
443 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
444 Status error;
445 char platform_file_path[PATH_MAX];
446 if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
447 const char *os_version_dir = GetDeviceSupportDirectoryForOSVersion();
448 if (os_version_dir) {
449 std::string resolved_path =
450 (llvm::Twine(os_version_dir) + "/" + platform_file_path).str();
451
452 local_file.SetFile(resolved_path, FileSpec::Style::native);
453 FileSystem::Instance().Resolve(local_file);
454 if (FileSystem::Instance().Exists(local_file)) {
455 if (log) {
456 LLDB_LOGF(log, "Found a copy of %s in the DeviceSupport dir %s",
457 platform_file_path, os_version_dir);
458 }
459 return error;
460 }
461
462 resolved_path = (llvm::Twine(os_version_dir) + "/Symbols.Internal/" +
463 platform_file_path)
464 .str();
465
466 local_file.SetFile(resolved_path, FileSpec::Style::native);
467 FileSystem::Instance().Resolve(local_file);
468 if (FileSystem::Instance().Exists(local_file)) {
469 LLDB_LOGF(
470 log,
471 "Found a copy of %s in the DeviceSupport dir %s/Symbols.Internal",
472 platform_file_path, os_version_dir);
473 return error;
474 }
475 resolved_path =
476 (llvm::Twine(os_version_dir) + "/Symbols/" + platform_file_path)
477 .str();
478
479 local_file.SetFile(resolved_path, FileSpec::Style::native);
480 FileSystem::Instance().Resolve(local_file);
481 if (FileSystem::Instance().Exists(local_file)) {
482 LLDB_LOGF(log, "Found a copy of %s in the DeviceSupport dir %s/Symbols",
483 platform_file_path, os_version_dir);
484 return error;
485 }
486 }
487 local_file = platform_file;
488 if (FileSystem::Instance().Exists(local_file))
489 return error;
490
491 error.SetErrorStringWithFormat(
492 "unable to locate a platform file for '%s' in platform '%s'",
493 platform_file_path, GetPluginName().GetCString());
494 } else {
495 error.SetErrorString("invalid platform file argument");
496 }
497 return error;
498 }
499
GetSharedModule(const ModuleSpec & module_spec,Process * process,ModuleSP & module_sp,const FileSpecList * module_search_paths_ptr,llvm::SmallVectorImpl<ModuleSP> * old_modules,bool * did_create_ptr)500 Status PlatformRemoteDarwinDevice::GetSharedModule(
501 const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
502 const FileSpecList *module_search_paths_ptr,
503 llvm::SmallVectorImpl<ModuleSP> *old_modules, bool *did_create_ptr) {
504 // For iOS, the SDK files are all cached locally on the host system. So first
505 // we ask for the file in the cached SDK, then we attempt to get a shared
506 // module for the right architecture with the right UUID.
507 const FileSpec &platform_file = module_spec.GetFileSpec();
508 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
509
510 Status error;
511 char platform_file_path[PATH_MAX];
512
513 if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
514 ModuleSpec platform_module_spec(module_spec);
515
516 UpdateSDKDirectoryInfosIfNeeded();
517
518 const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
519
520 // If we are connected we migth be able to correctly deduce the SDK
521 // directory using the OS build.
522 const uint32_t connected_sdk_idx = GetConnectedSDKIndex();
523 if (connected_sdk_idx < num_sdk_infos) {
524 LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
525 m_sdk_directory_infos[connected_sdk_idx].directory);
526 if (GetFileInSDK(platform_file_path, connected_sdk_idx,
527 platform_module_spec.GetFileSpec())) {
528 module_sp.reset();
529 error = ResolveExecutable(platform_module_spec, module_sp, nullptr);
530 if (module_sp) {
531 m_last_module_sdk_idx = connected_sdk_idx;
532 error.Clear();
533 return error;
534 }
535 }
536 }
537
538 // Try the last SDK index if it is set as most files from an SDK will tend
539 // to be valid in that same SDK.
540 if (m_last_module_sdk_idx < num_sdk_infos) {
541 LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
542 m_sdk_directory_infos[m_last_module_sdk_idx].directory);
543 if (GetFileInSDK(platform_file_path, m_last_module_sdk_idx,
544 platform_module_spec.GetFileSpec())) {
545 module_sp.reset();
546 error = ResolveExecutable(platform_module_spec, module_sp, nullptr);
547 if (module_sp) {
548 error.Clear();
549 return error;
550 }
551 }
552 }
553
554 // First try for an exact match of major, minor and update: If a particalar
555 // SDK version was specified via --version or --build, look for a match on
556 // disk.
557 const SDKDirectoryInfo *current_sdk_info =
558 GetSDKDirectoryForCurrentOSVersion();
559 const uint32_t current_sdk_idx =
560 GetSDKIndexBySDKDirectoryInfo(current_sdk_info);
561 if (current_sdk_idx < num_sdk_infos &&
562 current_sdk_idx != m_last_module_sdk_idx) {
563 LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
564 m_sdk_directory_infos[current_sdk_idx].directory);
565 if (GetFileInSDK(platform_file_path, current_sdk_idx,
566 platform_module_spec.GetFileSpec())) {
567 module_sp.reset();
568 error = ResolveExecutable(platform_module_spec, module_sp, nullptr);
569 if (module_sp) {
570 m_last_module_sdk_idx = current_sdk_idx;
571 error.Clear();
572 return error;
573 }
574 }
575 }
576
577 // Second try all SDKs that were found.
578 for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) {
579 if (m_last_module_sdk_idx == sdk_idx) {
580 // Skip the last module SDK index if we already searched it above
581 continue;
582 }
583 LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
584 m_sdk_directory_infos[sdk_idx].directory);
585 if (GetFileInSDK(platform_file_path, sdk_idx,
586 platform_module_spec.GetFileSpec())) {
587 // printf ("sdk[%u]: '%s'\n", sdk_idx, local_file.GetPath().c_str());
588
589 error = ResolveExecutable(platform_module_spec, module_sp, nullptr);
590 if (module_sp) {
591 // Remember the index of the last SDK that we found a file in in case
592 // the wrong SDK was selected.
593 m_last_module_sdk_idx = sdk_idx;
594 error.Clear();
595 return error;
596 }
597 }
598 }
599 }
600 // Not the module we are looking for... Nothing to see here...
601 module_sp.reset();
602
603 // This may not be an SDK-related module. Try whether we can bring in the
604 // thing to our local cache.
605 error = GetSharedModuleWithLocalCache(module_spec, module_sp,
606 module_search_paths_ptr, old_modules,
607 did_create_ptr);
608 if (error.Success())
609 return error;
610
611 // See if the file is present in any of the module_search_paths_ptr
612 // directories.
613 if (!module_sp)
614 error = PlatformDarwin::FindBundleBinaryInExecSearchPaths(
615 module_spec, process, module_sp, module_search_paths_ptr, old_modules,
616 did_create_ptr);
617
618 if (error.Success())
619 return error;
620
621 const bool always_create = false;
622 error = ModuleList::GetSharedModule(module_spec, module_sp,
623 module_search_paths_ptr, old_modules,
624 did_create_ptr, always_create);
625
626 if (module_sp)
627 module_sp->SetPlatformFileSpec(platform_file);
628
629 return error;
630 }
631
GetConnectedSDKIndex()632 uint32_t PlatformRemoteDarwinDevice::GetConnectedSDKIndex() {
633 if (IsConnected()) {
634 if (m_connected_module_sdk_idx == UINT32_MAX) {
635 std::string build;
636 if (GetRemoteOSBuildString(build)) {
637 const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
638 for (uint32_t i = 0; i < num_sdk_infos; ++i) {
639 const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
640 if (strstr(sdk_dir_info.directory.GetFilename().AsCString(""),
641 build.c_str())) {
642 m_connected_module_sdk_idx = i;
643 }
644 }
645 }
646 }
647 } else {
648 m_connected_module_sdk_idx = UINT32_MAX;
649 }
650 return m_connected_module_sdk_idx;
651 }
652
GetSDKIndexBySDKDirectoryInfo(const SDKDirectoryInfo * sdk_info)653 uint32_t PlatformRemoteDarwinDevice::GetSDKIndexBySDKDirectoryInfo(
654 const SDKDirectoryInfo *sdk_info) {
655 if (sdk_info == nullptr) {
656 return UINT32_MAX;
657 }
658
659 return sdk_info - &m_sdk_directory_infos[0];
660 }
661