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