1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
3 * Copyright (c) 2009-2012 Apple Inc. All rights reserved.
5 * @APPLE_LICENSE_HEADER_START@
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
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.
22 * @APPLE_LICENSE_HEADER_END@
27 #include <Availability.h>
30 #include "dsc_iterator.h"
32 #include "DyldSharedCache.h"
33 #include "MachOAnalyzer.h"
36 static void forEachDylibInCache(const void* shared_cache_file
, void (^handler
)(const dyld_cache_image_info
* cachedDylibInfo
, bool isAlias
))
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 )
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
;
50 bool isAlias
= (dylibs
[i
].pathFileOffset
< firstImageOffset
);
51 handler(&dylibs
[i
], isAlias
);
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
;
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
;
69 dyld_shared_cache_dylib_info dylibInfo
;
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
;
78 dylibInfo
.uuid
= &uuid
;
79 ma
->forEachSegment(^(const dyld3::MachOAnalyzer::SegmentInfo
& info
, bool& stop
) {
80 if ( info
.fileSize
> info
.vmSize
) {
84 dyld_shared_cache_segment_info segInfo
;
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
);