Loading...
--- 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;