Coverage Report

Created: 2022-01-15 10:30

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
Line
Count
Source (jump to first uncovered line)
1
//===-- HostInfoMacOSX.mm ---------------------------------------*- C++ -*-===//
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/Host/FileSystem.h"
10
#include "lldb/Host/Host.h"
11
#include "lldb/Host/HostInfo.h"
12
#include "lldb/Host/macosx/HostInfoMacOSX.h"
13
#include "lldb/Utility/Args.h"
14
#include "lldb/Utility/Log.h"
15
#include "lldb/Utility/Timer.h"
16
#include "Utility/UuidCompatibility.h"
17
18
#include "llvm/ADT/SmallString.h"
19
#include "llvm/ADT/StringMap.h"
20
#include "llvm/Support/FileSystem.h"
21
#include "llvm/Support/Path.h"
22
#include "llvm/Support/raw_ostream.h"
23
24
// C++ Includes
25
#include <string>
26
27
// C inclues
28
#include <cstdlib>
29
#include <sys/sysctl.h>
30
#include <sys/syslimits.h>
31
#include <sys/types.h>
32
33
// Objective-C/C++ includes
34
#include <CoreFoundation/CoreFoundation.h>
35
#include <Foundation/Foundation.h>
36
#include <mach-o/dyld.h>
37
#include <objc/objc-auto.h>
38
39
// These are needed when compiling on systems
40
// that do not yet have these definitions
41
#include <AvailabilityMacros.h>
42
#ifndef CPU_SUBTYPE_X86_64_H
43
#define CPU_SUBTYPE_X86_64_H ((cpu_subtype_t)8)
44
#endif
45
#ifndef CPU_TYPE_ARM64
46
#define CPU_TYPE_ARM64 (CPU_TYPE_ARM | CPU_ARCH_ABI64)
47
#endif
48
49
#ifndef CPU_TYPE_ARM64_32
50
#define CPU_ARCH_ABI64_32 0x02000000
51
#define CPU_TYPE_ARM64_32 (CPU_TYPE_ARM | CPU_ARCH_ABI64_32)
52
#endif
53
54
#include <TargetConditionals.h> // for TARGET_OS_TV, TARGET_OS_WATCH
55
56
using namespace lldb_private;
57
58
56
llvm::Optional<std::string> HostInfoMacOSX::GetOSBuildString() {
59
56
  int mib[2] = {CTL_KERN, KERN_OSVERSION};
60
56
  char cstr[PATH_MAX];
61
56
  size_t cstr_len = sizeof(cstr);
62
56
  if (::sysctl(mib, 2, cstr, &cstr_len, NULL, 0) == 0)
63
56
    return std::string(cstr, cstr_len - 1);
64
65
0
  return llvm::None;
66
56
}
67
68
791
static void ParseOSVersion(llvm::VersionTuple &version, NSString *Key) {
69
791
  @autoreleasepool {
70
791
    NSDictionary *version_info =
71
791
      [NSDictionary dictionaryWithContentsOfFile:
72
791
       @"/System/Library/CoreServices/SystemVersion.plist"];
73
791
    NSString *version_value = [version_info objectForKey: Key];
74
791
    const char *version_str = [version_value UTF8String];
75
791
    version.tryParse(version_str);
76
791
  }
77
791
}
78
79
2.66k
llvm::VersionTuple HostInfoMacOSX::GetOSVersion() {
80
2.66k
  static llvm::VersionTuple g_version;
81
2.66k
  if (g_version.empty())
82
791
    ParseOSVersion(g_version, @"ProductVersion");
83
2.66k
  return g_version;
84
2.66k
}
85
86
0
llvm::VersionTuple HostInfoMacOSX::GetMacCatalystVersion() {
87
0
  static llvm::VersionTuple g_version;
88
0
  if (g_version.empty())
89
0
    ParseOSVersion(g_version, @"iOSSupportVersion");
90
0
  return g_version;
91
0
}
92
93
94
11
FileSpec HostInfoMacOSX::GetProgramFileSpec() {
95
11
  static FileSpec g_program_filespec;
96
11
  if (!g_program_filespec) {
97
11
    char program_fullpath[PATH_MAX];
98
    // If DST is NULL, then return the number of bytes needed.
99
11
    uint32_t len = sizeof(program_fullpath);
100
11
    int err = _NSGetExecutablePath(program_fullpath, &len);
101
11
    if (err == 0)
102
11
      g_program_filespec.SetFile(program_fullpath, FileSpec::Style::native);
103
0
    else if (err == -1) {
104
0
      char *large_program_fullpath = (char *)::malloc(len + 1);
105
106
0
      err = _NSGetExecutablePath(large_program_fullpath, &len);
107
0
      if (err == 0)
108
0
        g_program_filespec.SetFile(large_program_fullpath,
109
0
                                   FileSpec::Style::native);
110
111
0
      ::free(large_program_fullpath);
112
0
    }
113
11
  }
114
11
  return g_program_filespec;
115
11
}
116
117
744
bool HostInfoMacOSX::ComputeSupportExeDirectory(FileSpec &file_spec) {
118
744
  FileSpec lldb_file_spec = GetShlibDir();
119
744
  if (!lldb_file_spec)
120
0
    return false;
121
122
744
  std::string raw_path = lldb_file_spec.GetPath();
123
124
744
  size_t framework_pos = raw_path.find("LLDB.framework");
125
744
  if (framework_pos != std::string::npos) {
126
0
    framework_pos += strlen("LLDB.framework");
127
#if TARGET_OS_IPHONE
128
    // Shallow bundle
129
    raw_path.resize(framework_pos);
130
#else
131
    // Normal bundle
132
0
    raw_path.resize(framework_pos);
133
0
    raw_path.append("/Resources");
134
0
#endif
135
744
  } else {
136
    // Find the bin path relative to the lib path where the cmake-based
137
    // OS X .dylib lives.  This is not going to work if the bin and lib
138
    // dir are not both in the same dir.
139
    //
140
    // It is not going to work to do it by the executable path either,
141
    // as in the case of a python script, the executable is python, not
142
    // the lldb driver.
143
744
    raw_path.append("/../bin");
144
744
    FileSpec support_dir_spec(raw_path);
145
744
    FileSystem::Instance().Resolve(support_dir_spec);
146
744
    if (!FileSystem::Instance().IsDirectory(support_dir_spec)) {
147
0
      Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
148
0
      LLDB_LOGF(log, "HostInfoMacOSX::%s(): failed to find support directory",
149
0
                __FUNCTION__);
150
0
      return false;
151
0
    }
152
153
    // Get normalization from support_dir_spec.  Note the FileSpec resolve
154
    // does not remove '..' in the path.
155
744
    char *const dir_realpath =
156
744
        realpath(support_dir_spec.GetPath().c_str(), NULL);
157
744
    if (dir_realpath) {
158
744
      raw_path = dir_realpath;
159
744
      free(dir_realpath);
160
744
    } else {
161
0
      raw_path = support_dir_spec.GetPath();
162
0
    }
163
744
  }
164
165
744
  file_spec.GetDirectory().SetString(
166
744
      llvm::StringRef(raw_path.c_str(), raw_path.size()));
167
744
  return (bool)file_spec.GetDirectory();
168
744
}
169
170
1
bool HostInfoMacOSX::ComputeHeaderDirectory(FileSpec &file_spec) {
171
1
  FileSpec lldb_file_spec = GetShlibDir();
172
1
  if (!lldb_file_spec)
173
0
    return false;
174
175
1
  std::string raw_path = lldb_file_spec.GetPath();
176
177
1
  size_t framework_pos = raw_path.find("LLDB.framework");
178
1
  if (framework_pos != std::string::npos) {
179
0
    framework_pos += strlen("LLDB.framework");
180
0
    raw_path.resize(framework_pos);
181
0
    raw_path.append("/Headers");
182
0
  }
183
1
  file_spec.GetDirectory().SetString(
184
1
      llvm::StringRef(raw_path.c_str(), raw_path.size()));
185
1
  return true;
186
1
}
187
188
3.44k
bool HostInfoMacOSX::ComputeSystemPluginsDirectory(FileSpec &file_spec) {
189
3.44k
  FileSpec lldb_file_spec = GetShlibDir();
190
3.44k
  if (!lldb_file_spec)
191
0
    return false;
192
193
3.44k
  std::string raw_path = lldb_file_spec.GetPath();
194
195
3.44k
  size_t framework_pos = raw_path.find("LLDB.framework");
196
3.44k
  if (framework_pos == std::string::npos)
197
3.44k
    return false;
198
199
0
  framework_pos += strlen("LLDB.framework");
200
0
  raw_path.resize(framework_pos);
201
0
  raw_path.append("/Resources/PlugIns");
202
0
  file_spec.GetDirectory().SetString(
203
0
      llvm::StringRef(raw_path.c_str(), raw_path.size()));
204
0
  return true;
205
3.44k
}
206
207
3.44k
bool HostInfoMacOSX::ComputeUserPluginsDirectory(FileSpec &file_spec) {
208
3.44k
  FileSpec temp_file("~/Library/Application Support/LLDB/PlugIns");
209
3.44k
  FileSystem::Instance().Resolve(temp_file);
210
3.44k
  file_spec.GetDirectory().SetCString(temp_file.GetPath().c_str());
211
3.44k
  return true;
212
3.44k
}
213
214
void HostInfoMacOSX::ComputeHostArchitectureSupport(ArchSpec &arch_32,
215
3.49k
                                                    ArchSpec &arch_64) {
216
  // All apple systems support 32 bit execution.
217
3.49k
  uint32_t cputype, cpusubtype;
218
3.49k
  uint32_t is_64_bit_capable = false;
219
3.49k
  size_t len = sizeof(cputype);
220
3.49k
  ArchSpec host_arch;
221
  // These will tell us about the kernel architecture, which even on a 64
222
  // bit machine can be 32 bit...
223
3.49k
  if (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0) {
224
3.49k
    len = sizeof(cpusubtype);
225
3.49k
    if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) != 0)
226
0
      cpusubtype = CPU_TYPE_ANY;
227
228
3.49k
    len = sizeof(is_64_bit_capable);
229
3.49k
    ::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0);
230
231
3.49k
    if (cputype == CPU_TYPE_ARM64 && 
cpusubtype == CPU_SUBTYPE_ARM64E0
) {
232
      // The arm64e architecture is a preview. Pretend the host architecture
233
      // is arm64.
234
0
      cpusubtype = CPU_SUBTYPE_ARM64_ALL;
235
0
    }
236
237
3.49k
    if (is_64_bit_capable) {
238
3.49k
      if (cputype & CPU_ARCH_ABI64) {
239
        // We have a 64 bit kernel on a 64 bit system
240
0
        arch_64.SetArchitecture(eArchTypeMachO, cputype, cpusubtype);
241
3.49k
      } else {
242
        // We have a 64 bit kernel that is returning a 32 bit cputype, the
243
        // cpusubtype will be correct as if it were for a 64 bit architecture
244
3.49k
        arch_64.SetArchitecture(eArchTypeMachO, cputype | CPU_ARCH_ABI64,
245
3.49k
                                cpusubtype);
246
3.49k
      }
247
248
      // Now we need modify the cpusubtype for the 32 bit slices.
249
3.49k
      uint32_t cpusubtype32 = cpusubtype;
250
3.49k
#if defined(__i386__) || defined(__x86_64__)
251
3.49k
      if (cpusubtype == CPU_SUBTYPE_486 || 
cpusubtype == CPU_SUBTYPE_X86_64_H0
)
252
3.49k
        cpusubtype32 = CPU_SUBTYPE_I386_ALL;
253
#elif defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
254
      if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64)
255
        cpusubtype32 = CPU_SUBTYPE_ARM_V7S;
256
#endif
257
3.49k
      arch_32.SetArchitecture(eArchTypeMachO, cputype & ~(CPU_ARCH_MASK),
258
3.49k
                              cpusubtype32);
259
260
3.49k
      if (cputype == CPU_TYPE_ARM || 
261
3.49k
          cputype == CPU_TYPE_ARM64 || 
262
3.49k
          cputype == CPU_TYPE_ARM64_32) {
263
// When running on a watch or tv, report the host os correctly
264
#if defined(TARGET_OS_TV) && TARGET_OS_TV == 1
265
        arch_32.GetTriple().setOS(llvm::Triple::TvOS);
266
        arch_64.GetTriple().setOS(llvm::Triple::TvOS);
267
#elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1
268
        arch_32.GetTriple().setOS(llvm::Triple::BridgeOS);
269
        arch_64.GetTriple().setOS(llvm::Triple::BridgeOS);
270
#elif defined(TARGET_OS_WATCHOS) && TARGET_OS_WATCHOS == 1
271
        arch_32.GetTriple().setOS(llvm::Triple::WatchOS);
272
        arch_64.GetTriple().setOS(llvm::Triple::WatchOS);
273
#elif defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1
274
0
        arch_32.GetTriple().setOS(llvm::Triple::MacOSX);
275
0
        arch_64.GetTriple().setOS(llvm::Triple::MacOSX);
276
#else
277
        arch_32.GetTriple().setOS(llvm::Triple::IOS);
278
        arch_64.GetTriple().setOS(llvm::Triple::IOS);
279
#endif
280
3.49k
      } else {
281
3.49k
        arch_32.GetTriple().setOS(llvm::Triple::MacOSX);
282
3.49k
        arch_64.GetTriple().setOS(llvm::Triple::MacOSX);
283
3.49k
      }
284
3.49k
    } else {
285
      // We have a 32 bit kernel on a 32 bit system
286
0
      arch_32.SetArchitecture(eArchTypeMachO, cputype, cpusubtype);
287
#if defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
288
      arch_32.GetTriple().setOS(llvm::Triple::WatchOS);
289
#else
290
0
      arch_32.GetTriple().setOS(llvm::Triple::IOS);
291
0
#endif
292
0
      arch_64.Clear();
293
0
    }
294
3.49k
  }
295
3.49k
}
296
297
/// Return and cache $DEVELOPER_DIR if it is set and exists.
298
953
static std::string GetEnvDeveloperDir() {
299
953
  static std::string g_env_developer_dir;
300
953
  static std::once_flag g_once_flag;
301
953
  std::call_once(g_once_flag, [&]() {
302
462
    if (const char *developer_dir_env_var = getenv("DEVELOPER_DIR")) {
303
0
      FileSpec fspec(developer_dir_env_var);
304
0
      if (FileSystem::Instance().Exists(fspec))
305
0
        g_env_developer_dir = fspec.GetPath();
306
0
    }});
307
953
  return g_env_developer_dir;
308
953
}
309
310
1.42k
FileSpec HostInfoMacOSX::GetXcodeContentsDirectory() {
311
1.42k
  static FileSpec g_xcode_contents_path;
312
1.42k
  static std::once_flag g_once_flag;
313
1.42k
  std::call_once(g_once_flag, [&]() {
314
    // Try the shlib dir first.
315
453
    if (FileSpec fspec = HostInfo::GetShlibDir()) {
316
453
      if (FileSystem::Instance().Exists(fspec)) {
317
453
        std::string xcode_contents_dir =
318
453
            XcodeSDK::FindXcodeContentsDirectoryInPath(fspec.GetPath());
319
453
        if (!xcode_contents_dir.empty()) {
320
0
          g_xcode_contents_path = FileSpec(xcode_contents_dir);
321
0
          return;
322
0
        }
323
453
      }
324
453
    }
325
326
453
    llvm::SmallString<128> env_developer_dir(GetEnvDeveloperDir());
327
453
    if (!env_developer_dir.empty()) {
328
0
      llvm::sys::path::append(env_developer_dir, "Contents");
329
0
      std::string xcode_contents_dir =
330
0
          XcodeSDK::FindXcodeContentsDirectoryInPath(env_developer_dir);
331
0
      if (!xcode_contents_dir.empty()) {
332
0
        g_xcode_contents_path = FileSpec(xcode_contents_dir);
333
0
        return;
334
0
      }
335
0
    }
336
337
453
    FileSpec fspec(HostInfo::GetXcodeSDKPath(XcodeSDK::GetAnyMacOS()));
338
453
    if (fspec) {
339
453
      if (FileSystem::Instance().Exists(fspec)) {
340
453
        std::string xcode_contents_dir =
341
453
            XcodeSDK::FindXcodeContentsDirectoryInPath(fspec.GetPath());
342
453
        if (!xcode_contents_dir.empty()) {
343
453
          g_xcode_contents_path = FileSpec(xcode_contents_dir);
344
453
          return;
345
453
        }
346
453
      }
347
453
    }
348
453
  });
349
1.42k
  return g_xcode_contents_path;
350
1.42k
}
351
352
4
lldb_private::FileSpec HostInfoMacOSX::GetXcodeDeveloperDirectory() {
353
4
  static lldb_private::FileSpec g_developer_directory;
354
4
  static llvm::once_flag g_once_flag;
355
4
  llvm::call_once(g_once_flag, []() {
356
3
    if (FileSpec fspec = GetXcodeContentsDirectory()) {
357
3
      fspec.AppendPathComponent("Developer");
358
3
      if (FileSystem::Instance().Exists(fspec))
359
3
        g_developer_directory = fspec;
360
3
    }
361
3
  });
362
4
  return g_developer_directory;
363
4
}
364
365
499
static std::string GetXcodeSDK(XcodeSDK sdk) {
366
499
  XcodeSDK::Info info = sdk.Parse();
367
499
  std::string sdk_name = XcodeSDK::GetCanonicalName(info);
368
369
499
  auto xcrun = [](const std::string &sdk,
370
500
                  llvm::StringRef developer_dir = "") -> std::string {
371
500
    Args args;
372
500
    if (!developer_dir.empty()) {
373
0
      args.AppendArgument("/usr/bin/env");
374
0
      args.AppendArgument("DEVELOPER_DIR=" + developer_dir.str());
375
0
    }
376
500
    args.AppendArgument("/usr/bin/xcrun");
377
500
    args.AppendArgument("--show-sdk-path");
378
500
    args.AppendArgument("--sdk");
379
500
    args.AppendArgument(sdk);
380
381
500
    int status = 0;
382
500
    int signo = 0;
383
500
    std::string output_str;
384
500
    lldb_private::Status error =
385
500
        Host::RunShellCommand(args, FileSpec(), &status, &signo, &output_str,
386
500
                              std::chrono::seconds(15));
387
388
    // Check that xcrun return something useful.
389
500
    if (status != 0 || 
output_str.empty()477
)
390
23
      return {};
391
392
    // Convert to a StringRef so we can manipulate the string without modifying
393
    // the underlying data.
394
477
    llvm::StringRef output(output_str);
395
396
    // Remove any trailing newline characters.
397
477
    output = output.rtrim();
398
399
    // Strip any leading newline characters and everything before them.
400
477
    const size_t last_newline = output.rfind('\n');
401
477
    if (last_newline != llvm::StringRef::npos)
402
0
      output = output.substr(last_newline + 1);
403
404
477
    return output.str();
405
500
  };
406
407
500
  auto find_sdk = [&xcrun](const std::string &sdk_name) -> std::string {
408
    // Invoke xcrun with the developer dir specified in the environment.
409
500
    std::string developer_dir = GetEnvDeveloperDir();
410
500
    if (!developer_dir.empty()) {
411
      // Don't fallback if DEVELOPER_DIR was set.
412
0
      return xcrun(sdk_name, developer_dir);
413
0
    }
414
415
    // Invoke xcrun with the shlib dir.
416
500
    if (FileSpec fspec = HostInfo::GetShlibDir()) {
417
500
      if (FileSystem::Instance().Exists(fspec)) {
418
500
        std::string contents_dir =
419
500
            XcodeSDK::FindXcodeContentsDirectoryInPath(fspec.GetPath());
420
500
        llvm::StringRef shlib_developer_dir =
421
500
            llvm::sys::path::parent_path(contents_dir);
422
500
        if (!shlib_developer_dir.empty()) {
423
0
          std::string sdk = xcrun(sdk_name, std::move(shlib_developer_dir));
424
0
          if (!sdk.empty())
425
0
            return sdk;
426
0
        }
427
500
      }
428
500
    }
429
430
    // Invoke xcrun without a developer dir as a last resort.
431
500
    return xcrun(sdk_name);
432
500
  };
433
434
499
  std::string path = find_sdk(sdk_name);
435
499
  while (path.empty()) {
436
    // Try an alternate spelling of the name ("macosx10.9internal").
437
23
    if (info.type == XcodeSDK::Type::MacOSX && 
!info.version.empty()1
&&
438
23
        
info.internal1
) {
439
0
      llvm::StringRef fixed(sdk_name);
440
0
      if (fixed.consume_back(".internal"))
441
0
        sdk_name = fixed.str() + "internal";
442
0
      path = find_sdk(sdk_name);
443
0
      if (!path.empty())
444
0
        break;
445
0
    }
446
23
    Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
447
23
    LLDB_LOGF(log, "Couldn't find SDK %s on host", sdk_name.c_str());
448
449
    // Try without the version.
450
23
    if (!info.version.empty()) {
451
1
      info.version = {};
452
1
      sdk_name = XcodeSDK::GetCanonicalName(info);
453
1
      path = find_sdk(sdk_name);
454
1
      if (!path.empty())
455
1
        break;
456
1
    }
457
458
22
    LLDB_LOGF(log, "Couldn't find any matching SDK on host");
459
22
    return {};
460
23
  }
461
462
  // Whatever is left in output should be a valid path.
463
477
  if (!FileSystem::Instance().Exists(path))
464
0
    return {};
465
477
  return path;
466
477
}
467
468
655
llvm::StringRef HostInfoMacOSX::GetXcodeSDKPath(XcodeSDK sdk) {
469
655
  static llvm::StringMap<std::string> g_sdk_path;
470
655
  static std::mutex g_sdk_path_mutex;
471
472
655
  std::lock_guard<std::mutex> guard(g_sdk_path_mutex);
473
655
  LLDB_SCOPED_TIMER();
474
475
655
  auto it = g_sdk_path.find(sdk.GetString());
476
655
  if (it != g_sdk_path.end())
477
156
    return it->second;
478
499
  auto it_new = g_sdk_path.insert({sdk.GetString(), GetXcodeSDK(sdk)});
479
499
  return it_new.first->second;
480
655
}
481
482
namespace {
483
struct dyld_shared_cache_dylib_text_info {
484
  uint64_t version; // current version 1
485
  // following fields all exist in version 1
486
  uint64_t loadAddressUnslid;
487
  uint64_t textSegmentSize;
488
  uuid_t dylibUuid;
489
  const char *path; // pointer invalid at end of iterations
490
  // following fields all exist in version 2
491
  uint64_t textSegmentOffset; // offset from start of cache
492
};
493
typedef struct dyld_shared_cache_dylib_text_info
494
    dyld_shared_cache_dylib_text_info;
495
}
496
497
extern "C" int dyld_shared_cache_iterate_text(
498
    const uuid_t cacheUuid,
499
    void (^callback)(const dyld_shared_cache_dylib_text_info *info));
500
extern "C" uint8_t *_dyld_get_shared_cache_range(size_t *length);
501
extern "C" bool _dyld_get_shared_cache_uuid(uuid_t uuid);
502
503
namespace {
504
class SharedCacheInfo {
505
public:
506
0
  const UUID &GetUUID() const { return m_uuid; }
507
269k
  const llvm::StringMap<SharedCacheImageInfo> &GetImages() const {
508
269k
    return m_images;
509
269k
  }
510
511
  SharedCacheInfo();
512
513
private:
514
  llvm::StringMap<SharedCacheImageInfo> m_images;
515
  UUID m_uuid;
516
};
517
}
518
519
815
SharedCacheInfo::SharedCacheInfo() {
520
815
  size_t shared_cache_size;
521
815
  uint8_t *shared_cache_start =
522
815
      _dyld_get_shared_cache_range(&shared_cache_size);
523
815
  uuid_t dsc_uuid;
524
815
  _dyld_get_shared_cache_uuid(dsc_uuid);
525
815
  m_uuid = UUID::fromData(dsc_uuid);
526
527
815
  dyld_shared_cache_iterate_text(
528
1.47M
      dsc_uuid, ^(const dyld_shared_cache_dylib_text_info *info) {
529
1.47M
        m_images[info->path] = SharedCacheImageInfo{
530
1.47M
            UUID::fromData(info->dylibUuid, 16),
531
1.47M
            std::make_shared<DataBufferUnowned>(
532
1.47M
                shared_cache_start + info->textSegmentOffset,
533
1.47M
                shared_cache_size - info->textSegmentOffset)};
534
1.47M
      });
535
815
}
536
537
SharedCacheImageInfo
538
269k
HostInfoMacOSX::GetSharedCacheImageInfo(llvm::StringRef image_name) {
539
269k
  static SharedCacheInfo g_shared_cache_info;
540
269k
  return g_shared_cache_info.GetImages().lookup(image_name);
541
269k
}