dyld-832.7.1.tar.gz
[apple/dyld.git] / dyld3 / shared-cache / dsc_iterator.cpp
1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
2 *
3 * Copyright (c) 2009-2012 Apple Inc. All rights reserved.
4 *
5 * @APPLE_LICENSE_HEADER_START@
6 *
7 * This file contains Original Code and/or Modifications of Original Code
8 * as defined in and that are subject to the Apple Public Source License
9 * Version 2.0 (the 'License'). You may not use this file except in
10 * compliance with the License. Please obtain a copy of the License at
11 * http://www.opensource.apple.com/apsl/ and read it before using this
12 * file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
19 * Please see the License for the specific language governing rights and
20 * limitations under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <Availability.h>
28
29
30 #include "dsc_iterator.h"
31 #define NO_ULEB
32 #include "DyldSharedCache.h"
33 #include "MachOAnalyzer.h"
34
35
36 static void forEachDylibInCache(const void* shared_cache_file, void (^handler)(const dyld_cache_image_info* cachedDylibInfo, bool isAlias))
37 {
38 const dyld_cache_header* header = (dyld_cache_header*)shared_cache_file;
39 const dyld_cache_image_info* dylibs = (dyld_cache_image_info*)((char*)shared_cache_file + header->imagesOffset);
40 const dyld_cache_mapping_info* mappings = (dyld_cache_mapping_info*)((char*)shared_cache_file + header->mappingOffset);
41 if ( mappings[0].fileOffset != 0 )
42 return;
43 uint64_t firstImageOffset = 0;
44 uint64_t firstRegionAddress = mappings[0].address;
45 for (uint32_t i=0; i < header->imagesCount; ++i) {
46 uint64_t offset = dylibs[i].address - firstRegionAddress;
47 if ( firstImageOffset == 0 )
48 firstImageOffset = offset;
49 // skip over aliases
50 bool isAlias = (dylibs[i].pathFileOffset < firstImageOffset);
51 handler(&dylibs[i], isAlias);
52 }
53 }
54
55
56 extern int dyld_shared_cache_iterate(const void* shared_cache_file, uint32_t shared_cache_size,
57 void (^callback)(const dyld_shared_cache_dylib_info* dylibInfo, const dyld_shared_cache_segment_info* segInfo)) {
58 const dyld_cache_header* header = (dyld_cache_header*)shared_cache_file;
59 const dyld_cache_mapping_info* mappings = (dyld_cache_mapping_info*)((char*)shared_cache_file + header->mappingOffset);
60 const uint64_t unslideLoadAddress = mappings[0].address;
61
62 __block uint32_t index = 0;
63 __block int result = 0;
64 forEachDylibInCache(shared_cache_file, ^(const dyld_cache_image_info* cachedDylibInfo, bool isAlias) {
65 uint64_t imageCacheOffset = cachedDylibInfo->address - unslideLoadAddress;
66 const dyld3::MachOAnalyzer* ma = (dyld3::MachOAnalyzer*)((uint8_t*)shared_cache_file + imageCacheOffset);
67 const char* dylibPath = (char*)shared_cache_file + cachedDylibInfo->pathFileOffset;
68
69 dyld_shared_cache_dylib_info dylibInfo;
70 uuid_t uuid;
71 dylibInfo.version = 2;
72 dylibInfo.machHeader = ma;
73 dylibInfo.path = dylibPath;
74 dylibInfo.modTime = cachedDylibInfo->modTime;
75 dylibInfo.inode = cachedDylibInfo->inode;
76 dylibInfo.isAlias = isAlias;
77 ma->getUuid(uuid);
78 dylibInfo.uuid = &uuid;
79 ma->forEachSegment(^(const dyld3::MachOAnalyzer::SegmentInfo& info, bool& stop) {
80 if ( info.fileSize > info.vmSize ) {
81 stop = true;
82 return;
83 }
84 dyld_shared_cache_segment_info segInfo;
85 segInfo.version = 2;
86 segInfo.name = info.segName;
87 segInfo.fileOffset = info.fileOffset;
88 segInfo.fileSize = info.vmSize;
89 segInfo.address = info.vmAddr;
90 segInfo.addressOffset = info.vmAddr - unslideLoadAddress;
91 callback(&dylibInfo, &segInfo);
92 });
93 index++;
94 });
95 return result;
96 }