Coverage Report

Created: 2022-01-18 06:27

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