Loading...
launch-cache/dsc_extractor.cpp dyld-360.18 dyld-551.3
--- dyld/dyld-360.18/launch-cache/dsc_extractor.cpp
+++ dyld/dyld-551.3/launch-cache/dsc_extractor.cpp
@@ -98,7 +98,7 @@
 		if ( (entry.flags & EXPORT_SYMBOL_FLAGS_REEXPORT) == 0 )
 			return true;
 		// If the symbol comes from a dylib that is re-exported, this is not an individual symbol re-export
-		if ( _reexportDeps.count(entry.other) != 0 )
+		if ( _reexportDeps.count((int)entry.other) != 0 )
 			return true;
 		return false;
 	}
@@ -118,8 +118,11 @@
 	
 	// update load commands
 	uint64_t cumulativeFileSize = 0;
+	const unsigned origLoadCommandsSize = mh->sizeofcmds();
+	unsigned bytesRemaining = origLoadCommandsSize;
+	unsigned removedCount = 0;
 	const macho_load_command<P>* const cmds = (macho_load_command<P>*)((uint8_t*)mh + sizeof(macho_header<P>));
-	const uint32_t cmd_count = mh->ncmds();
+	const uint32_t cmdCount = mh->ncmds();
 	const macho_load_command<P>* cmd = cmds;
 	macho_segment_command<P>* linkEditSegCmd = NULL;
 	macho_symtab_command<P>* symtab = NULL;
@@ -130,7 +133,8 @@
 	uint32_t exportsTrieSize = 0;
 	std::set<int> reexportDeps;
 	int depIndex = 0;
-	for (uint32_t i = 0; i < cmd_count; ++i) {
+	for (uint32_t i = 0; i < cmdCount; ++i) {
+	    bool remove = false;
 		switch ( cmd->cmd() ) {
 		case macho_segment_command<P>::CMD:
 			{
@@ -188,10 +192,28 @@
 				reexportDeps.insert(depIndex);
 			}
 			break;
-		}
-		cmd = (const macho_load_command<P>*)(((uint8_t*)cmd)+cmd->cmdsize());
-	}
-	
+		case LC_SEGMENT_SPLIT_INFO:
+			// <rdar://problem/23212513> dylibs iOS 9 dyld caches have bogus LC_SEGMENT_SPLIT_INFO
+			remove = true;
+			break;
+		}
+		uint32_t cmdSize = cmd->cmdsize();
+		macho_load_command<P>* nextCmd = (macho_load_command<P>*)(((uint8_t*)cmd)+cmdSize);
+		if ( remove ) {
+			::memmove((void*)cmd, (void*)nextCmd, bytesRemaining);
+			++removedCount;
+		}
+		else {
+			bytesRemaining -= cmdSize;
+			cmd = nextCmd;
+		}
+	}
+	// zero out stuff removed
+	::bzero((void*)cmd, bytesRemaining);
+	// update header
+	mh->set_ncmds(cmdCount - removedCount);
+	mh->set_sizeofcmds(origLoadCommandsSize - bytesRemaining);
+
 	// rebuild symbol table
 	if ( linkEditSegCmd == NULL ) {
 		fprintf(stderr, "__LINKEDIT not found\n");
@@ -475,7 +497,7 @@
 	optimize_linkedit<A>(((macho_header<P>*)(base_ptr+offsetInFatFile)), textOffsetInCache, mapped_cache, &newSize);
 	
 	// update fat header with new file size
-    dylib_data.resize(offsetInFatFile+newSize);
+    dylib_data.resize((size_t)(offsetInFatFile+newSize));
     base_ptr                                    = &dylib_data.front();
 	FA->size                                    = OSSwapHostToBigInt32(newSize);
 #undef FH
@@ -499,7 +521,7 @@
 		return -1;
 	}
 	
-	void* mapped_cache = mmap(NULL, statbuf.st_size, PROT_READ, MAP_PRIVATE, cache_fd, 0);
+	void* mapped_cache = mmap(NULL, (size_t)statbuf.st_size, PROT_READ, MAP_PRIVATE, cache_fd, 0);
 	if (mapped_cache == MAP_FAILED) {
 		fprintf(stderr, "Error: mmap() for shared cache at %s failed, errno=%d\n", shared_cache_file_path, errno);
 		return -1;
@@ -525,9 +547,11 @@
 		dylib_create_func = dylib_maker<arm>;
 	else if ( strcmp((char*)mapped_cache, "dyld_v1   arm64") == 0 ) 
 		dylib_create_func = dylib_maker<arm64>;
+	else if ( strcmp((char*)mapped_cache, "dyld_v1  arm64e") == 0 )
+		dylib_create_func = dylib_maker<arm64>;
 	else {
 		fprintf(stderr, "Error: unrecognized dyld shared cache magic.\n");
-        munmap(mapped_cache, statbuf.st_size);
+        munmap(mapped_cache, (size_t)statbuf.st_size);
 		return -1;
 	}
 
@@ -539,7 +563,7 @@
 
     if(result != 0) {
 		fprintf(stderr, "Error: dyld_shared_cache_iterate_segments_with_slide failed.\n");
-        munmap(mapped_cache, statbuf.st_size);
+        munmap(mapped_cache, (size_t)statbuf.st_size);
 		return result;
     }
 
@@ -580,7 +604,7 @@
                 return;
             }
             
-            std::vector<uint8_t> *vec   = new std::vector<uint8_t>(statbuf.st_size);
+            std::vector<uint8_t> *vec   = new std::vector<uint8_t>((size_t)statbuf.st_size);
             if(pread(fd, &vec->front(), vec->size(), 0) != (long)vec->size()) {
                 fprintf(stderr, "can't read dylib file %s, errnor=%d\n", dylib_path, errno);
                 close(fd);
@@ -613,7 +637,7 @@
     dispatch_release(group);
     dispatch_release(writer_queue);
     
-    munmap(mapped_cache, statbuf.st_size);
+    munmap(mapped_cache, (size_t)statbuf.st_size);
 	return result;
 }