]> git.saurik.com Git - apple/system_cmds.git/blob - gcore.tproj/dyld_shared_cache.c
system_cmds-735.20.1.tar.gz
[apple/system_cmds.git] / gcore.tproj / dyld_shared_cache.c
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
22 static 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 */
28 bool
29 get_uuid_from_shared_cache_mapping(const void *addr, size_t size, uuid_t out)
30 {
31 const struct copied_dyld_cache_header *ch = addr;
32 if (size < sizeof (*ch))
33 return false;
34 static const char prefix[] = "dyld_v1 ";
35 if (strncmp(ch->magic, prefix, strlen(prefix)) != 0)
36 return false;
37 uuid_copy(out, ch->uuid);
38 return true;
39 }
40
41 /*
42 * Look in the known places to see if we can find this one ..
43 */
44 char *
45 shared_cache_filename(const uuid_t uu)
46 {
47 assert(!uuid_is_null(uu));
48 static char *sc_argv[] = {
49 #if defined(__i386__) || defined(__x86_64__)
50 "/var/db/dyld",
51 #elif defined(__arm__) || defined(__arm64__)
52 "/System/Library/Caches/com.apple.dyld",
53 #else
54 #error undefined
55 #endif
56 NULL
57 };
58 char *nm = NULL;
59 FTS *fts = fts_open(sc_argv, FTS_NOCHDIR | FTS_LOGICAL | FTS_XDEV, NULL);
60 if (NULL != fts) {
61 FTSENT *fe;
62 while (NULL != (fe = fts_read(fts))) {
63 if ((fe->fts_info & FTS_F) == 0 ||
64 (fe->fts_info & FTS_ERR) != 0)
65 continue;
66
67 static const char prefix[] = "dyld_shared_cache_";
68 if (strncmp(fe->fts_name, prefix, strlen(prefix)) != 0)
69 continue;
70
71 if (fe->fts_statp->st_size < (off_t)dyld_cache_header_size)
72 continue;
73
74 int d = open(fe->fts_accpath, O_RDONLY);
75 if (-1 == d) {
76 if (opt->debug)
77 printf("%s: cannot open - %s\n", fe->fts_accpath, strerror(errno));
78 continue;
79 }
80 void *addr = mmap(NULL, dyld_cache_header_size, PROT_READ, MAP_PRIVATE, d, 0);
81 close(d);
82 if ((void *)-1 == addr) {
83 if (opt->debug)
84 printf("%s: cannot mmap - %s\n", fe->fts_accpath, strerror(errno));
85 continue;
86 }
87 uuid_t scuuid;
88 uuid_clear(scuuid);
89 if (get_uuid_from_shared_cache_mapping(addr, dyld_cache_header_size, scuuid)) {
90 if (uuid_compare(uu, scuuid) == 0)
91 nm = strdup(fe->fts_accpath);
92 else if (opt->debug) {
93 uuid_string_t scstr;
94 uuid_unparse_lower(scuuid, scstr);
95 printf("%s: shared cache mismatch (%s)\n", fe->fts_accpath, scstr);
96 }
97 }
98 munmap(addr, dyld_cache_header_size);
99 if (NULL != nm)
100 break;
101 }
102 }
103 if (fts)
104 fts_close(fts);
105 return nm;
106 }