]> git.saurik.com Git - apple/system_cmds.git/blame_incremental - gcore.tproj/dyld_shared_cache.c
system_cmds-854.100.3.tar.gz
[apple/system_cmds.git] / gcore.tproj / dyld_shared_cache.c
... / ...
CommitLineData
1/*
2 * Copyright (c) 2016 Apple Inc. All rights reserved.
3 */
4
5#include "options.h"
6#include "dyld_shared_cache.h"
7#include "utils.h"
8
9#include <stdio.h>
10#include <string.h>
11#include <strings.h>
12#include <stdlib.h>
13#include <stdarg.h>
14#include <unistd.h>
15#include <errno.h>
16#include <fts.h>
17#include <fcntl.h>
18#include <assert.h>
19#include <sys/mman.h>
20#include <sys/stat.h>
21
22static const size_t dyld_cache_header_size = sizeof (struct copied_dyld_cache_header);
23
24/*
25 * The shared cache must both contain the magic ID and
26 * match the uuid we discovered via dyld's information.
27 * Assumes that the dyld_cache_header grows in a binary compatible fashion.
28 */
29bool
30get_uuid_from_shared_cache_mapping(const void *addr, size_t size, uuid_t out)
31{
32 const struct copied_dyld_cache_header *ch = addr;
33 if (size < sizeof (*ch))
34 return false;
35 static const char prefix[] = "dyld_v";
36 if (strncmp(ch->magic, prefix, strlen(prefix)) != 0)
37 return false;
38 uuid_copy(out, ch->uuid);
39 return true;
40}
41
42/*
43 * Look in the known places to see if we can find this one ..
44 */
45char *
46shared_cache_filename(const uuid_t uu)
47{
48 assert(!uuid_is_null(uu));
49 static char *sc_argv[] = {
50#if defined(__i386__) || defined(__x86_64__)
51 "/var/db/dyld",
52#elif defined(__arm__) || defined(__arm64__)
53 "/System/Library/Caches/com.apple.dyld",
54#else
55#error undefined
56#endif
57 NULL
58 };
59 char *nm = NULL;
60 FTS *fts = fts_open(sc_argv, FTS_NOCHDIR | FTS_LOGICAL | FTS_XDEV, NULL);
61 if (NULL != fts) {
62 FTSENT *fe;
63 while (NULL != (fe = fts_read(fts))) {
64 if ((fe->fts_info & FTS_F) == 0 ||
65 (fe->fts_info & FTS_ERR) != 0)
66 continue;
67
68 static const char prefix[] = "dyld_shared_cache_";
69 if (strncmp(fe->fts_name, prefix, strlen(prefix)) != 0)
70 continue;
71
72 if (fe->fts_statp->st_size < (off_t)dyld_cache_header_size)
73 continue;
74
75 int d = open(fe->fts_accpath, O_RDONLY);
76 if (-1 == d) {
77 if (OPTIONS_DEBUG(opt, 1))
78 printf("%s: cannot open - %s\n", fe->fts_accpath, strerror(errno));
79 continue;
80 }
81 void *addr = mmap(NULL, dyld_cache_header_size, PROT_READ, MAP_PRIVATE, d, 0);
82 close(d);
83 if ((void *)-1 == addr) {
84 if (OPTIONS_DEBUG(opt, 1))
85 printf("%s: cannot mmap - %s\n", fe->fts_accpath, strerror(errno));
86 continue;
87 }
88 uuid_t scuuid;
89 uuid_clear(scuuid);
90 if (get_uuid_from_shared_cache_mapping(addr, dyld_cache_header_size, scuuid)) {
91 if (uuid_compare(uu, scuuid) == 0)
92 nm = strdup(fe->fts_accpath);
93 else if (OPTIONS_DEBUG(opt, 3)) {
94 uuid_string_t scstr;
95 uuid_unparse_lower(scuuid, scstr);
96 printf("%s: shared cache mismatch (%s)\n", fe->fts_accpath, scstr);
97 }
98 }
99 munmap(addr, dyld_cache_header_size);
100 if (NULL != nm)
101 break;
102 }
103 }
104 if (fts)
105 fts_close(fts);
106 return nm;
107}