Loading...
launch-cache/dsc_iterator.cpp dyld-421.1 dyld-195.5
--- dyld/dyld-421.1/launch-cache/dsc_iterator.cpp
+++ dyld/dyld-195.5/launch-cache/dsc_iterator.cpp
@@ -1,6 +1,6 @@
 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 
  *
- * Copyright (c) 2009-2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2009-2010 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -35,23 +35,19 @@
 #include "CacheFileAbstraction.hpp"
 
 
+
 namespace dyld {
 
 
 	// convert an address in the shared region where the cache would normally be mapped, into an address where the cache is currently mapped
 	template <typename E>
-	const uint8_t* mappedAddress(const uint8_t* cache, const uint8_t* cacheEnd, uint64_t addr)
+	const uint8_t* mappedAddress(const uint8_t* cache, uint64_t addr)
 	{
 		const dyldCacheHeader<E>* header = (dyldCacheHeader<E>*)cache;
 		const dyldCacheFileMapping<E>* mappings = (dyldCacheFileMapping<E>*)&cache[header->mappingOffset()];
 		for (uint32_t i=0; i < header->mappingCount(); ++i) {
 			if ( (mappings[i].address() <= addr) &&  (addr < (mappings[i].address() + mappings[i].size())) ) {
-				uint64_t cacheOffset = mappings[i].file_offset() + addr - mappings[i].address();
-				const uint8_t* result =  &cache[cacheOffset];
-				if ( result < cacheEnd )
-					return result;
-				else 
-					return NULL;
+				return &cache[mappings[i].file_offset() + addr - mappings[i].address()];
 			}
 		}
 		return NULL;
@@ -59,37 +55,14 @@
 
 	// call the callback block on each segment in this image						  	  
 	template <typename A>
-	int walkSegments(const uint8_t* cache, const uint8_t* cacheEnd, const uint8_t* firstSeg, const char* dylibPath, uint64_t inode,uint64_t modTime, const uint8_t* machHeader, 
-											void (^callback)(const dyld_shared_cache_dylib_info* dylibInfo, const dyld_shared_cache_segment_info* segInfo)) 
+	void walkSegments(const uint8_t* cache, const char* dylibPath, const uint8_t* machHeader, uint64_t slide, dyld_shared_cache_iterator_slide_t callback) 
 	{
 		typedef typename A::P		P;	
 		typedef typename A::P::E	E;	
-		dyld_shared_cache_dylib_info	dylibInfo;
-		dyld_shared_cache_segment_info	segInfo;
-		dylibInfo.version = 2;
-		dylibInfo.isAlias = (dylibPath < (char*)firstSeg); // paths for aliases are store between cache header and first segment
-		dylibInfo.machHeader = machHeader;
-		dylibInfo.path = dylibPath;
-		dylibInfo.inode = inode;
-		dylibInfo.modTime = modTime;
 		const macho_header<P>* mh = (const macho_header<P>*)machHeader;
 		const macho_load_command<P>* const cmds = (macho_load_command<P>*)(machHeader + sizeof(macho_header<P>));
-		if ( (machHeader+ mh->sizeofcmds()) > cacheEnd )
-			return -1;
 		const uint32_t cmd_count = mh->ncmds();
 		const macho_load_command<P>* cmd = cmds;
-		// scan for LC_UUID
-		dylibInfo.uuid = NULL;
-		for (uint32_t i = 0; i < cmd_count; ++i) {
-			if ( cmd->cmd() == LC_UUID ) {
-				const uuid_command* uc = (const uuid_command*)cmd;
-				dylibInfo.uuid = &uc->uuid;
-				break;
-			}
-			cmd = (const macho_load_command<P>*)(((uint8_t*)cmd)+cmd->cmdsize());
-		}
-		// callback for each LC_SEGMENT
-		cmd = cmds;
 		for (uint32_t i = 0; i < cmd_count; ++i) {
 			if ( cmd->cmd() == macho_segment_command<P>::CMD ) {
 				macho_segment_command<P>* segCmd = (macho_segment_command<P>*)cmd;
@@ -101,76 +74,39 @@
 				uint64_t sizem = segCmd->vmsize();
 				if ( strcmp(segCmd->segname(), "__LINKEDIT") == 0 ) {
 					// clip LINKEDIT size if bigger than cache file
-					if ( (fileOffset+sizem) > (uint64_t)(cacheEnd-cache) )
-						sizem = (cacheEnd-cache)-fileOffset;
+					const dyldCacheHeader<E>* header = (dyldCacheHeader<E>*)cache;
+					const dyldCacheFileMapping<E>* mappings = (dyldCacheFileMapping<E>*)&cache[header->mappingOffset()];
+					if ( mappings[2].file_offset() <= fileOffset ) {
+						if ( sizem > mappings[2].size() )
+							sizem = mappings[2].file_offset() + mappings[2].size() - fileOffset;
+					}
 				}
-				segInfo.version = 1;
-				segInfo.name = segCmd->segname();
-				segInfo.fileOffset = fileOffset;
-				segInfo.fileSize = sizem;
-				if ( segCmd->filesize() > segCmd->vmsize() )
-					return -1;
-				segInfo.address = segCmd->vmaddr();
-				callback(&dylibInfo, &segInfo);
+				callback(dylibPath, segCmd->segname(), fileOffset, sizem, segCmd->vmaddr()+slide, slide);
 			}
 			cmd = (const macho_load_command<P>*)(((uint8_t*)cmd)+cmd->cmdsize());
 		}
-		return 0;
 	}
 			
 							  
 	// call walkSegments on each image in the cache							  	  
 	template <typename A>
-	int walkImages(const uint8_t* cache, uint32_t size,	void (^callback)(const dyld_shared_cache_dylib_info* dylibInfo, const dyld_shared_cache_segment_info* segInfo)) 
+	int walkImages(const uint8_t* cache, dyld_shared_cache_iterator_slide_t callback) 
 	{
-		// Sanity check there is at least a header
-		if ( (size > 0) && (size < 0x7000) )
-			return -1;
 		typedef typename A::P::E			E;	
 		typedef typename A::P				P;	
-		const dyldCacheHeader<E>*      header   = (dyldCacheHeader<E>*)cache;
-		const dyldCacheImageInfo<E>*   dylibs   = (dyldCacheImageInfo<E>*)&cache[header->imagesOffset()];
-		const dyldCacheFileMapping<E>* mappings = (dyldCacheFileMapping<E>*)&cache[header->mappingOffset()];
-		uint64_t greatestMappingOffset = 0;
-		for (uint32_t i=0; i < header->mappingCount(); ++i) {
-			if ( (size != 0) && (mappings[i].file_offset() > size) )
-				return -1;
-			uint64_t endOffset = mappings[i].file_offset()+mappings[i].size();
-			if ( (size != 0) && (endOffset > size) )
-				return -1;
-			if ( endOffset > greatestMappingOffset ) 
-				greatestMappingOffset = endOffset;
-		}
-		const uint8_t* cacheEnd = &cache[size];
-		if ( size == 0 ) {
-			// Zero size means old API is being used, assume all mapped
-			cacheEnd = &cache[greatestMappingOffset];
-		}
-		else {
-			// verifiy mappings are not bigger than size
-			if ( size < greatestMappingOffset ) 
-				return -1;
-		}
-		// verify all image infos are mapped
-		if ( (const uint8_t*)&dylibs[header->imagesCount()] > cacheEnd )
-			return -1;
-		const uint8_t* firstSeg = NULL;
+		typedef typename A::P::uint_t		pint_t;
+		const dyldCacheHeader<E>* header = (dyldCacheHeader<E>*)cache;
+		uint64_t slide = 0;
+		if ( header->mappingOffset() >= 0x48 ) {
+			const dyldCacheFileMapping<E>* mappings = (dyldCacheFileMapping<E>*)&cache[header->mappingOffset()];
+			uint64_t storedPointerToHeader = P::getP(*((pint_t*)&cache[mappings[1].file_offset()]));
+			slide = storedPointerToHeader - mappings[0].address();
+		}	
+		const dyldCacheImageInfo<E>* dylibs = (dyldCacheImageInfo<E>*)&cache[header->imagesOffset()];
 		for (uint32_t i=0; i < header->imagesCount(); ++i) {
 			const char* dylibPath  = (char*)cache + dylibs[i].pathFileOffset();
-			uint64_t inode = dylibs[i].inode();
-			uint64_t modTime = dylibs[i].modTime();
-			if ( (const uint8_t*)dylibPath > cacheEnd )
-				return -1;
-			const uint8_t* machHeader = mappedAddress<E>(cache, cacheEnd, dylibs[i].address());
-			if ( machHeader == NULL )
-				return -1;
-			if ( machHeader > cacheEnd )
-				return -1;
-			if ( firstSeg == NULL )
-				firstSeg = machHeader;
-			int result = walkSegments<A>(cache, cacheEnd, firstSeg, dylibPath, inode, modTime, machHeader, callback);
-			if ( result != 0 )
-				return result;
+			const uint8_t* machHeader = mappedAddress<E>(cache, dylibs[i].address());
+			walkSegments<A>(cache, dylibPath, machHeader, slide, callback);
 		}
 		return 0;
 	}
@@ -182,36 +118,23 @@
 // this routine will call the callback block once for each segment
 // in each dylib in the shared cache file.  
 // Returns -1 if there was an error, otherwise 0.
-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)) {
+int dyld_shared_cache_iterate_segments_with_slide(const void* shared_cache_file, dyld_shared_cache_iterator_slide_t callback)
+{
 	const uint8_t* cache = (uint8_t*)shared_cache_file;
 		 if ( strcmp((char*)cache, "dyld_v1    i386") == 0 ) 
-			return dyld::walkImages<x86>(cache, shared_cache_size, callback);
+			return dyld::walkImages<x86>(cache, callback);
 	else if ( strcmp((char*)cache, "dyld_v1  x86_64") == 0 ) 
-			return dyld::walkImages<x86_64>(cache, shared_cache_size, callback);
-	else if ( strcmp((char*)cache, "dyld_v1 x86_64h") == 0 ) 
-			return dyld::walkImages<x86_64>(cache, shared_cache_size, callback);
+			return dyld::walkImages<x86_64>(cache, callback);
+	else if ( strcmp((char*)cache, "dyld_v1     ppc") == 0 ) 
+			return dyld::walkImages<ppc>(cache, callback);
 	else if ( strcmp((char*)cache, "dyld_v1   armv5") == 0 ) 
-			return dyld::walkImages<arm>(cache, shared_cache_size, callback);
+			return dyld::walkImages<arm>(cache, callback);
 	else if ( strcmp((char*)cache, "dyld_v1   armv6") == 0 ) 
-			return dyld::walkImages<arm>(cache, shared_cache_size, callback);
+			return dyld::walkImages<arm>(cache, callback);
 	else if ( strcmp((char*)cache, "dyld_v1   armv7") == 0 ) 
-			return dyld::walkImages<arm>(cache, shared_cache_size, callback);
-	else if ( strncmp((char*)cache, "dyld_v1  armv7", 14) == 0 ) 
-			return dyld::walkImages<arm>(cache, shared_cache_size, callback);
-	else if ( strcmp((char*)cache, "dyld_v1   arm64") == 0 ) 
-			return dyld::walkImages<arm64>(cache, shared_cache_size, callback);
+			return dyld::walkImages<arm>(cache, callback);
 	else
 		return -1;
-}
-
-
-// implement old version by calling new version
-int dyld_shared_cache_iterate_segments_with_slide(const void* shared_cache_file, dyld_shared_cache_iterator_slide_t callback)
-{
-	return dyld_shared_cache_iterate(shared_cache_file, 0, ^(const dyld_shared_cache_dylib_info* dylibInfo, const dyld_shared_cache_segment_info* segInfo) {
-														callback(dylibInfo->path, segInfo->name, segInfo->fileOffset, segInfo->fileSize, segInfo->address, 0);
-	});
 }
 
 // implement non-block version by calling block version