Loading...
other-tools/dsc_iterator.cpp /dev/null dyld-940
--- /dev/null
+++ dyld/dyld-940/other-tools/dsc_iterator.cpp
@@ -0,0 +1,102 @@
+/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 
+ *
+ * Copyright (c) 2009-2012 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <Availability.h>
+
+
+#include "dsc_iterator.h"
+#define NO_ULEB
+#include "DyldSharedCache.h"
+#include "MachOAnalyzer.h"
+
+
+static void forEachDylibInCache(const void* shared_cache_file, void (^handler)(const dyld_cache_image_info* cachedDylibInfo, bool isAlias))
+{
+    const dyld_cache_header*        header      = (dyld_cache_header*)shared_cache_file;
+    const dyld_cache_mapping_info*  mappings    = (dyld_cache_mapping_info*)((char*)shared_cache_file + header->mappingOffset);
+    dyld_cache_image_info*          images      = (dyld_cache_image_info*)((char*)shared_cache_file + header->imagesOffsetOld);
+    uint32_t                        imagesCount = header->imagesCountOld;
+    if ( header->mappingOffset >= __offsetof(dyld_cache_header, imagesCount) ) {
+        images = (dyld_cache_image_info*)((char*)shared_cache_file + header->imagesOffset);
+        imagesCount = header->imagesCount;
+    }
+
+    if ( mappings[0].fileOffset != 0 )
+        return;
+    uint64_t firstImageOffset = 0;
+    uint64_t firstRegionAddress = mappings[0].address;
+    for (uint32_t i=0; i < imagesCount; ++i) {
+        uint64_t offset = images[i].address - firstRegionAddress;
+        if ( firstImageOffset == 0 )
+            firstImageOffset = offset;
+        // skip over aliases.  This is no longer valid in newer caches
+        //bool isAlias = false;//(dylibs[i].pathFileOffset < firstImageOffset);
+        handler(&images[i], false);
+    }
+}
+
+
+extern int dyld_shared_cache_iterate(const void* shared_cache_file, uint32_t shared_cache_size,
+                                         void (^callback)(const dyld_shared_cache_dylib_info* dylibInfo, const dyld_shared_cache_segment_info* segInfo)) {
+    const dyld_cache_header*       header             = (dyld_cache_header*)shared_cache_file;
+    const dyld_cache_mapping_info* mappings           = (dyld_cache_mapping_info*)((char*)shared_cache_file + header->mappingOffset);
+    const uint64_t                 unslideLoadAddress = mappings[0].address;
+
+    __block uint32_t index = 0;
+    __block int      result = 0;
+    forEachDylibInCache(shared_cache_file, ^(const dyld_cache_image_info* cachedDylibInfo, bool isAlias) {
+        uint64_t                    imageCacheOffset = cachedDylibInfo->address - unslideLoadAddress;
+        const dyld3::MachOAnalyzer* ma               = (dyld3::MachOAnalyzer*)((uint8_t*)shared_cache_file + imageCacheOffset);
+        const char*                 dylibPath        = (char*)shared_cache_file + cachedDylibInfo->pathFileOffset;
+
+        dyld_shared_cache_dylib_info dylibInfo;
+        uuid_t                       uuid;
+        dylibInfo.version    = 2;
+        dylibInfo.machHeader = ma;
+        dylibInfo.path       = dylibPath;
+        dylibInfo.modTime    = cachedDylibInfo->modTime;
+        dylibInfo.inode      = cachedDylibInfo->inode;
+        dylibInfo.isAlias    = isAlias;
+        ma->getUuid(uuid);
+        dylibInfo.uuid       = &uuid;
+        ma->forEachSegment(^(const dyld3::MachOAnalyzer::SegmentInfo& info, bool& stop) {
+            if ( info.fileSize > info.vmSize ) {
+                stop = true;
+                return;
+            }
+            dyld_shared_cache_segment_info segInfo;
+            segInfo.version       = 2;
+            segInfo.name          = info.segName;
+            segInfo.fileOffset    = info.fileOffset;
+            segInfo.fileSize      = info.vmSize;
+            segInfo.address       = info.vmAddr;
+            segInfo.addressOffset = info.vmAddr - unslideLoadAddress;
+            callback(&dylibInfo, &segInfo);
+        });
+        index++;
+    });
+    return result;
+}