Loading...
src/ImageLoaderMachO.cpp dyld-421.2 dyld-519.2.2
--- dyld/dyld-421.2/src/ImageLoaderMachO.cpp
+++ dyld/dyld-519.2.2/src/ImageLoaderMachO.cpp
@@ -52,6 +52,7 @@
 #include "ImageLoaderMachOClassic.h"
 #endif
 #include "mach-o/dyld_images.h"
+#include "Tracing.h"
 #include "dyld.h"
 
 // <rdar://problem/8718137> use stack guard random value to add padding between dylibs
@@ -68,6 +69,43 @@
 #ifndef LC_VERSION_MIN_WATCHOS
 	#define LC_VERSION_MIN_WATCHOS 0x30
 #endif
+
+#ifndef LC_BUILD_VERSION
+	#define LC_BUILD_VERSION 0x32 /* build for platform min OS version */
+
+	/*
+	 * The build_version_command contains the min OS version on which this 
+	 * binary was built to run for its platform.  The list of known platforms and
+	 * tool values following it.
+	 */
+	struct build_version_command {
+		uint32_t	cmd;		/* LC_BUILD_VERSION */
+		uint32_t	cmdsize;	/* sizeof(struct build_version_command) plus */
+								/* ntools * sizeof(struct build_tool_version) */
+		uint32_t	platform;	/* platform */
+		uint32_t	minos;		/* X.Y.Z is encoded in nibbles xxxx.yy.zz */
+		uint32_t	sdk;		/* X.Y.Z is encoded in nibbles xxxx.yy.zz */
+		uint32_t	ntools;		/* number of tool entries following this */
+	};
+
+	struct build_tool_version {
+		uint32_t	tool;		/* enum for the tool */
+		uint32_t	version;	/* version number of the tool */
+	};
+
+	/* Known values for the platform field above. */
+	#define PLATFORM_MACOS		1
+	#define PLATFORM_IOS		2
+	#define PLATFORM_TVOS		3
+	#define PLATFORM_WATCHOS	4
+	#define PLATFORM_BRIDGEOS	5
+
+	/* Known values for the tool field above. */
+	#define TOOL_CLANG	1
+	#define TOOL_SWIFT	2
+	#define TOOL_LD		3
+#endif
+
 
 
 #if TARGET_IPHONE_SIMULATOR
@@ -224,7 +262,7 @@
 					if ( (segCmd->initprot != 0) && ((segCmd->initprot & VM_PROT_READ) == 0) )
 						dyld::throwf("malformed mach-o image: %s segment is not mapped readable", segCmd->segname);
 				}
-				if ( (segCmd->fileoff == 0) && (segCmd->filesize != 0) ) {
+                if ( (segCmd->fileoff == 0) && (segCmd->filesize != 0) ) {
 					if ( (segCmd->initprot & VM_PROT_READ) == 0 )
 						dyld::throwf("malformed mach-o image: %s segment maps start of file but is not readable", segCmd->segname);
 					if ( (segCmd->initprot & VM_PROT_WRITE) == VM_PROT_WRITE ) {
@@ -356,7 +394,7 @@
 		throw "load commands not in a segment";
 	if ( linkeditSegCmd == NULL )
 		throw "malformed mach-o image: missing __LINKEDIT segment";
-	if ( startOfFileSegCmd == NULL )
+	if ( !inCache && (startOfFileSegCmd == NULL) )
 		throw "malformed mach-o image: missing __TEXT segment that maps start of file";
 	// <rdar://problem/13145644> verify every segment does not overlap another segment
 	if ( context.strictMachORequired ) {
@@ -1258,6 +1296,7 @@
 	const struct load_command* const cmds = (struct load_command*)(((char*)mh) + sizeof(macho_header));
 	const struct load_command* cmd = cmds;
 	const struct version_min_command* versCmd;
+	const struct build_version_command* buildVersCmd;
 	for (uint32_t i = 0; i < cmd_count; ++i) {
 		switch ( cmd->cmd ) {
 			case LC_VERSION_MIN_MACOSX:
@@ -1266,6 +1305,9 @@
 			case LC_VERSION_MIN_WATCHOS:
 				versCmd = (version_min_command*)cmd;
 				return versCmd->sdk;
+			case LC_BUILD_VERSION:
+				buildVersCmd = (build_version_command*)cmd;
+				return buildVersCmd->sdk;
 		}
 		cmd = (const struct load_command*)(((char*)cmd)+cmd->cmdsize);
 	}
@@ -1283,6 +1325,7 @@
 	const struct load_command* const cmds = (struct load_command*)(((char*)mh) + sizeof(macho_header));
 	const struct load_command* cmd = cmds;
 	const struct version_min_command* versCmd;
+	const struct build_version_command* buildVersCmd;
 	for (uint32_t i = 0; i < cmd_count; ++i) {
 		switch ( cmd->cmd ) {
 			case LC_VERSION_MIN_MACOSX:
@@ -1291,6 +1334,9 @@
 			case LC_VERSION_MIN_WATCHOS:
 				versCmd = (version_min_command*)cmd;
 				return versCmd->version;
+			case LC_BUILD_VERSION:
+				buildVersCmd = (build_version_command*)cmd;
+				return buildVersCmd->minos;
 		}
 		cmd = (const struct load_command*)(((char*)cmd)+cmd->cmdsize);
 	}
@@ -1794,7 +1840,7 @@
 	for (uint32_t i = 0; i < cmd_count; ++i) {
 		if ( cmd->cmd == LC_SEGMENT_COMMAND ) {
 			const macho_segment_command* seg = (macho_segment_command*)cmd;
-			if ( (seg->fileoff == 0) && (seg->filesize != 0) )
+			if ( strcmp(seg->segname, "__TEXT") == 0 )
 				return (char*)mh - (char*)(seg->vmaddr);
 		}
 		cmd = (const load_command*)(((char*)cmd)+cmd->cmdsize);
@@ -2004,7 +2050,7 @@
 
 // These are defined in dyldStartup.s
 extern "C" void stub_binding_helper();
-
+extern "C" int _dyld_func_lookup(const char* name, void** address);
 
 void ImageLoaderMachO::setupLazyPointerHandler(const LinkContext& context)
 {
@@ -2160,7 +2206,9 @@
 					}
 					if ( context.verboseInit )
 						dyld::log("dyld: calling -init function %p in %s\n", func, this->getPath());
-					func(context.argc, context.argv, context.envp, context.apple, &context.programVars);
+                    dyld3::kdebug_trace_dyld_duration(DBG_DYLD_TIMING_STATIC_INITIALIZER, (uint64_t)func, 0, ^{
+                        func(context.argc, context.argv, context.envp, context.apple, &context.programVars);
+                    });
 					break;
 			}
 			cmd = (const struct load_command*)(((char*)cmd)+cmd->cmdsize);
@@ -2202,7 +2250,9 @@
 							if ( context.verboseInit )
 								dyld::log("dyld: calling initializer function %p in %s\n", func, this->getPath());
 							bool haveLibSystemHelpersBefore = (dyld::gLibSystemHelpers != NULL);
-							func(context.argc, context.argv, context.envp, context.apple, &context.programVars);
+                            dyld3::kdebug_trace_dyld_duration(DBG_DYLD_TIMING_STATIC_INITIALIZER, (uint64_t)func, 0, ^{
+                                func(context.argc, context.argv, context.envp, context.apple, &context.programVars);
+                            });
 							bool haveLibSystemHelpersAfter = (dyld::gLibSystemHelpers != NULL);
 							if ( !haveLibSystemHelpersBefore && haveLibSystemHelpersAfter ) {
 								// now safe to use malloc() and other calls in libSystem.dylib
@@ -2422,7 +2472,7 @@
 	}
 	// map in all segments
 	for(unsigned int i=0, e=segmentCount(); i < e; ++i) {
-		vm_offset_t fileOffset = segFileOffset(i) + offsetInFat;
+		vm_offset_t fileOffset = (vm_offset_t)(segFileOffset(i) + offsetInFat);
 		vm_size_t size = segFileSize(i);
 		uintptr_t requestedLoadAddress = segPreferredLoadAddress(i) + slide;
 		int protection = 0;
@@ -2569,8 +2619,9 @@
 					unslidLinkEditBase = (uint8_t*)(seg->vmaddr - seg->fileoff);
 					linkEditBaseFound = true;
 				}
-				else if ( (seg->fileoff == 0) && (seg->filesize != 0) )
+				else if ( strcmp(seg->segname, "__TEXT") == 0 ) {
 					slide = (uintptr_t)mh - seg->vmaddr;
+                }
 				break;
 			case LC_SYMTAB:
 				symtab = (symtab_command*)cmd;