+ return (-1);
+}
+
+#if TARGET_OS_WATCH
+uint32_t dyld_get_program_sdk_watch_os_version()
+{
+ if (gUseDyld3)
+ return dyld3::dyld_get_program_sdk_watch_os_version();
+
+ __block uint32_t retval = 0;
+ __block bool versionFound = false;
+ dyld3::dyld_get_image_versions((mach_header*)_NSGetMachExecuteHeader(), ^(dyld_platform_t platform, uint32_t sdk_version, uint32_t min_version) {
+ if (versionFound) return;
+
+ if (dyld_get_base_platform(platform) == PLATFORM_WATCHOS) {
+ versionFound = true;
+ retval = sdk_version;
+ }
+ });
+
+ return retval;
+}
+
+uint32_t dyld_get_program_min_watch_os_version()
+{
+ if (gUseDyld3)
+ return dyld3::dyld_get_program_min_watch_os_version();
+
+ __block uint32_t retval = 0;
+ __block bool versionFound = false;
+ dyld3::dyld_get_image_versions((mach_header*)_NSGetMachExecuteHeader(), ^(dyld_platform_t platform, uint32_t sdk_version, uint32_t min_version) {
+ if (versionFound) return;
+
+ if (dyld_get_base_platform(platform) == PLATFORM_WATCHOS) {
+ versionFound = true;
+ retval = min_version;
+ }
+ });
+
+ return retval;
+}
+#endif
+
+#if TARGET_OS_BRIDGE
+uint32_t dyld_get_program_sdk_bridge_os_version()
+{
+ if (gUseDyld3)
+ return dyld3::dyld_get_program_sdk_bridge_os_version();
+
+ __block uint32_t retval = 0;
+ __block bool versionFound = false;
+ dyld3::dyld_get_image_versions((mach_header*)_NSGetMachExecuteHeader(), ^(dyld_platform_t platform, uint32_t sdk_version, uint32_t min_version) {
+ if (versionFound) return;
+
+ if (dyld_get_base_platform(platform) == PLATFORM_BRIDGEOS) {
+ versionFound = true;
+ retval = sdk_version;
+ }
+ });
+
+ return retval;
+}
+
+uint32_t dyld_get_program_min_bridge_os_version()
+{
+ if (gUseDyld3)
+ return dyld3::dyld_get_program_min_bridge_os_version();
+
+ __block uint32_t retval = 0;
+ __block bool versionFound = false;
+ dyld3::dyld_get_image_versions((mach_header*)_NSGetMachExecuteHeader(), ^(dyld_platform_t platform, uint32_t sdk_version, uint32_t min_version) {
+ if (versionFound) return;
+
+ if (dyld_get_base_platform(platform) == PLATFORM_BRIDGEOS) {
+ versionFound = true;
+ retval = min_version;
+ }
+ });
+
+ return retval;
+}
+#endif
+
+/*
+ * Returns the sdk version (encode as nibble XXXX.YY.ZZ) the
+ * specified binary was built against.
+ *
+ * First looks for LC_VERSION_MIN_* in binary and if sdk field is
+ * not zero, return that value.
+ * Otherwise, looks for the libSystem.B.dylib the binary linked
+ * against and uses a table to convert that to an sdk version.
+ */
+uint32_t dyld_get_sdk_version(const mach_header* mh)
+{
+ return dyld3::dyld_get_sdk_version(mh);
+}
+
+uint32_t dyld_get_program_sdk_version()
+{
+ return dyld3::dyld_get_sdk_version((mach_header*)_NSGetMachExecuteHeader());
+}
+
+uint32_t dyld_get_min_os_version(const struct mach_header* mh)
+{
+ return dyld3::dyld_get_min_os_version(mh);
+}
+
+
+uint32_t dyld_get_program_min_os_version()
+{
+ return dyld3::dyld_get_min_os_version((mach_header*)_NSGetMachExecuteHeader());
+}
+
+
+bool _dyld_get_image_uuid(const struct mach_header* mh, uuid_t uuid)
+{
+ if ( gUseDyld3 )
+ return dyld3::_dyld_get_image_uuid(mh, uuid);
+
+ const load_command* startCmds = NULL;
+ if ( mh->magic == MH_MAGIC_64 )
+ startCmds = (load_command*)((char *)mh + sizeof(mach_header_64));
+ else if ( mh->magic == MH_MAGIC )
+ startCmds = (load_command*)((char *)mh + sizeof(mach_header));
+ else
+ return false; // not a mach-o file, or wrong endianness
+
+ const load_command* const cmdsEnd = (load_command*)((char*)startCmds + mh->sizeofcmds);
+ const load_command* cmd = startCmds;
+ for(uint32_t i = 0; i < mh->ncmds; ++i) {
+ const load_command* nextCmd = (load_command*)((char *)cmd + cmd->cmdsize);
+ if ( (cmd->cmdsize < 8) || (nextCmd > cmdsEnd) || (nextCmd < startCmds)) {
+ return false;
+ }
+ if ( cmd->cmd == LC_UUID ) {
+ const uuid_command* uuidCmd = (uuid_command*)cmd;
+ memcpy(uuid, uuidCmd->uuid, 16);
+ return true;
+ }
+ cmd = nextCmd;
+ }
+ bzero(uuid, 16);
+ return false;
+}
+
+dyld_platform_t dyld_get_active_platform(void) {
+ if (gUseDyld3)
+ return dyld3::dyld_get_active_platform();
+
+ // HACK
+ // Most of the new version SPIs have pure dyld3 implementations, but
+ // They cannot get to the main executable, so we implement this here
+ // and they can use this by calling ::dyld_get_active_platform() in the root namespace
+ static dyld_platform_t sActivePlatform = 0;
+ if (sActivePlatform) return sActivePlatform;
+
+ dyld3::dyld_get_image_versions((mach_header*)_NSGetMachExecuteHeader(), ^(dyld_platform_t platform, uint32_t sdk_version, uint32_t min_version) {
+ sActivePlatform = platform;
+ //FIXME assert there is only one?
+ });
+ return sActivePlatform;
+}
+
+dyld_platform_t dyld_get_base_platform(dyld_platform_t platform) {
+ return dyld3::dyld_get_base_platform(platform);
+}
+
+bool dyld_is_simulator_platform(dyld_platform_t platform) {
+ return dyld3::dyld_is_simulator_platform(platform);
+}
+
+bool dyld_sdk_at_least(const struct mach_header* mh, dyld_build_version_t version) {
+ return dyld3::dyld_sdk_at_least(mh, version);
+}
+
+bool dyld_minos_at_least(const struct mach_header* mh, dyld_build_version_t version) {
+ return dyld3::dyld_minos_at_least(mh, version);