]> git.saurik.com Git - apple/system_cmds.git/blame - gcore.tproj/dyld_shared_cache.c
system_cmds-880.40.5.tar.gz
[apple/system_cmds.git] / gcore.tproj / dyld_shared_cache.c
CommitLineData
cf37c299
A
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>
c0bbac3a 21#include <TargetConditionals.h>
cf37c299
A
22
23static 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.
530d02b6 28 * Assumes that the dyld_cache_header grows in a binary compatible fashion.
cf37c299
A
29 */
30bool
31get_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;
530d02b6 36 static const char prefix[] = "dyld_v";
cf37c299
A
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 */
46char *
47shared_cache_filename(const uuid_t uu)
48{
49 assert(!uuid_is_null(uu));
50 static char *sc_argv[] = {
c0bbac3a
A
51#if TARGET_OS_OSX
52 "/System/Library/dyld",
53#elif TARGET_OS_IPHONE
cf37c299
A
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) {
887d5eed 78 if (OPTIONS_DEBUG(opt, 1))
cf37c299
A
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) {
887d5eed 85 if (OPTIONS_DEBUG(opt, 1))
cf37c299
A
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);
887d5eed 94 else if (OPTIONS_DEBUG(opt, 3)) {
cf37c299
A
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}