diff --git a/libretro-common/include/libretro.h b/libretro-common/include/libretro.h index 5c95c508f9..6aaefc88be 100644 --- a/libretro-common/include/libretro.h +++ b/libretro-common/include/libretro.h @@ -1793,6 +1793,12 @@ enum retro_mod * this environment call to query support. */ +#define RETRO_ENVIRONMENT_GET_JIT_CAPABLE 74 + /* bool * -- + * Result is set to true if the frontend has already verified JIT can be + * used, mainly for use iOS/tvOS. On other platforms the result is true. + */ + /* VFS functionality */ diff --git a/pkg/apple/JITSupport.h b/pkg/apple/JITSupport.h index 50641d1645..8d81691202 100644 --- a/pkg/apple/JITSupport.h +++ b/pkg/apple/JITSupport.h @@ -11,7 +11,8 @@ #include -static bool jb_has_debugger_attached(void); +bool jb_has_debugger_attached(void); bool jb_enable_ptrace_hack(void); +void jb_start_altkit(void); #endif /* JITSupport_h */ diff --git a/pkg/apple/JITSupport.m b/pkg/apple/JITSupport.m index aaa1fbc2e6..fd8058e35a 100644 --- a/pkg/apple/JITSupport.m +++ b/pkg/apple/JITSupport.m @@ -16,6 +16,12 @@ #include #include +#if defined(HAVE_ALTKIT) +@import AltKit; +#endif + +#include "../../verbosity.h" + extern int csops(pid_t pid, unsigned int ops, void * useraddr, size_t usersize); extern boolean_t exc_server(mach_msg_header_t *, mach_msg_header_t *); extern int ptrace(int request, pid_t pid, caddr_t addr, int data); @@ -32,7 +38,7 @@ static void *exception_handler(void *argument) { return NULL; } -static bool jb_has_debugger_attached(void) { +bool jb_has_debugger_attached(void) { int flags; return !csops(getpid(), CS_OPS_STATUS, &flags, sizeof(flags)) && flags & CS_DEBUGGED; } @@ -70,7 +76,33 @@ bool jb_enable_ptrace_hack(void) { task_set_exception_ports(mach_task_self(), EXC_MASK_SOFTWARE, port, EXCEPTION_DEFAULT, THREAD_STATE_NONE); pthread_t thread; pthread_create(&thread, NULL, exception_handler, (void *)&port); + } else { + // JIT code frequently causes an EXC_BAD_ACCESS exception that lldb + // cannot be convinced to ignore. Instead we can set up a nul handler + // that effectively causes it to be ignored. Note that this sometimes + // also hides actual crashes from the debugger. + task_set_exception_ports(mach_task_self(), EXC_MASK_BAD_ACCESS, MACH_PORT_NULL, EXCEPTION_DEFAULT, THREAD_STATE_NONE); } return true; } + +void jb_start_altkit(void) { +#if HAVE_ALTKIT + [[ALTServerManager sharedManager] autoconnectWithCompletionHandler:^(ALTServerConnection *connection, NSError *error) { + if (error) + return; + + [connection enableUnsignedCodeExecutionWithCompletionHandler:^(BOOL success, NSError *error) { + if (success) + [[ALTServerManager sharedManager] stopDiscovering]; + else + RARCH_WARN("AltServer failed: %s\n", [error.description UTF8String]); + + [connection disconnect]; + }]; + }]; + + [[ALTServerManager sharedManager] startDiscovering]; +#endif +} diff --git a/pkg/apple/LLDBInitFile b/pkg/apple/LLDBInitFile new file mode 100644 index 0000000000..7f55672ee6 --- /dev/null +++ b/pkg/apple/LLDBInitFile @@ -0,0 +1 @@ +breakpoint set --func-regex "^(NS|UI)ApplicationMain$" --command "process handle --pass true --stop false SIGBUS" --auto-continue true diff --git a/pkg/apple/RetroArch_iOS13.xcodeproj/project.pbxproj b/pkg/apple/RetroArch_iOS13.xcodeproj/project.pbxproj index 31d4a40994..0e771bb8b4 100644 --- a/pkg/apple/RetroArch_iOS13.xcodeproj/project.pbxproj +++ b/pkg/apple/RetroArch_iOS13.xcodeproj/project.pbxproj @@ -10,6 +10,7 @@ 0714E7142983A5AC00E6B45B /* libMoltenVK.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 0714E7132983A5AC00E6B45B /* libMoltenVK.dylib */; }; 0714E7152983A5E500E6B45B /* libMoltenVK.dylib in Embed Libraries */ = {isa = PBXBuildFile; fileRef = 0714E7132983A5AC00E6B45B /* libMoltenVK.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 07B7872D29E8FE8F0088B74F /* filters in Resources */ = {isa = PBXBuildFile; fileRef = 07B7872C29E8FE8F0088B74F /* filters */; }; + 07EB0FA429F761B800D87936 /* AltKit in Frameworks */ = {isa = PBXBuildFile; productRef = 07EB0FA329F761B800D87936 /* AltKit */; }; 9204BE0D1D319EF300BD49DB /* griffin_objc.m in Sources */ = {isa = PBXBuildFile; fileRef = 50521A431AA23BF500185CC9 /* griffin_objc.m */; }; 9204BE101D319EF300BD49DB /* griffin.c in Sources */ = {isa = PBXBuildFile; fileRef = 501232C9192E5FC40063A359 /* griffin.c */; }; 9204BE121D319EF300BD49DB /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 5040F04F1AE47ED4006F6972 /* libz.dylib */; }; @@ -466,6 +467,7 @@ 9204BE1B1D319EF300BD49DB /* CoreAudio.framework in Frameworks */, 9204BE1C1D319EF300BD49DB /* UIKit.framework in Frameworks */, 9204BE1D1D319EF300BD49DB /* Foundation.framework in Frameworks */, + 07EB0FA429F761B800D87936 /* AltKit in Frameworks */, 9204BE1E1D319EF300BD49DB /* CoreGraphics.framework in Frameworks */, 9204BE1F1D319EF300BD49DB /* GLKit.framework in Frameworks */, 9204BE201D319EF300BD49DB /* OpenGLES.framework in Frameworks */, @@ -1251,6 +1253,9 @@ 9292D6F028F549D200E47A75 /* PBXTargetDependency */, ); name = RetroArchiOS; + packageProductDependencies = ( + 07EB0FA329F761B800D87936 /* AltKit */, + ); productName = RetroArch; productReference = 9204BE2B1D319EF300BD49DB /* RetroArch.app */; productType = "com.apple.product-type.application"; @@ -1328,6 +1333,9 @@ Base, ); mainGroup = 96AFAE1A16C1D4EA009DE44C; + packageReferences = ( + 07EB0FA229F761B800D87936 /* XCRemoteSwiftPackageReference "AltKit" */, + ); productRefGroup = 96AFAE2616C1D4EA009DE44C /* Products */; projectDirPath = ""; projectRoot = ""; @@ -1565,6 +1573,7 @@ "-DGLES_SILENCE_DEPRECATION", "-DGLSLANG_OSINCLUDE_UNIX", "-DHAVE_7ZIP", + "-DHAVE_ALTKIT", "-DHAVE_AUDIOMIXER", "-DHAVE_BTSTACK", "-DHAVE_BUILTINGLSLANG", @@ -1706,6 +1715,7 @@ "-DGLES_SILENCE_DEPRECATION", "-DGLSLANG_OSINCLUDE_UNIX", "-DHAVE_7ZIP", + "-DHAVE_ALTKIT", "-DHAVE_AUDIOMIXER", "-DHAVE_BTSTACK", "-DHAVE_BUILTINGLSLANG", @@ -2471,6 +2481,25 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + 07EB0FA229F761B800D87936 /* XCRemoteSwiftPackageReference "AltKit" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/rileytestut/AltKit.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 0.0.1; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 07EB0FA329F761B800D87936 /* AltKit */ = { + isa = XCSwiftPackageProductDependency; + package = 07EB0FA229F761B800D87936 /* XCRemoteSwiftPackageReference "AltKit" */; + productName = AltKit; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = 96AFAE1C16C1D4EA009DE44C /* Project object */; } diff --git a/pkg/apple/RetroArch_iOS13.xcodeproj/xcshareddata/xcschemes/RetroArch iOS Debug.xcscheme b/pkg/apple/RetroArch_iOS13.xcodeproj/xcshareddata/xcschemes/RetroArch iOS Debug.xcscheme index 6698f4f6b5..c854fe168d 100644 --- a/pkg/apple/RetroArch_iOS13.xcodeproj/xcshareddata/xcschemes/RetroArch iOS Debug.xcscheme +++ b/pkg/apple/RetroArch_iOS13.xcodeproj/xcshareddata/xcschemes/RetroArch iOS Debug.xcscheme @@ -43,6 +43,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + customLLDBInitFile = "$(SRCROOT)/LLDBInitFile" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" diff --git a/pkg/apple/RetroArch_iOS13.xcodeproj/xcshareddata/xcschemes/RetroArch iOS Release.xcscheme b/pkg/apple/RetroArch_iOS13.xcodeproj/xcshareddata/xcschemes/RetroArch iOS Release.xcscheme index d4a8b001ae..1dfc45bbda 100644 --- a/pkg/apple/RetroArch_iOS13.xcodeproj/xcshareddata/xcschemes/RetroArch iOS Release.xcscheme +++ b/pkg/apple/RetroArch_iOS13.xcodeproj/xcshareddata/xcschemes/RetroArch iOS Release.xcscheme @@ -43,6 +43,7 @@ buildConfiguration = "Release" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + customLLDBInitFile = "$(SRCROOT)/LLDBInitFile" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" diff --git a/pkg/apple/iOS/Info.plist b/pkg/apple/iOS/Info.plist index d95c9b1230..83ae62ffbf 100644 --- a/pkg/apple/iOS/Info.plist +++ b/pkg/apple/iOS/Info.plist @@ -44,6 +44,14 @@ LSSupportsOpeningDocumentsInPlace + NSBonjourServices + + _altserver._tcp + + NSLocalNetworkUsageDescription + RetroArch uses the local network to find and communicate with AltServer to enable JIT. + ALTDeviceID + NSCameraUsageDescription YES UIApplicationExitsOnSuspend diff --git a/runloop.c b/runloop.c index 846fbabcd3..10fb8c2d14 100644 --- a/runloop.c +++ b/runloop.c @@ -241,6 +241,10 @@ #include "lakka.h" #endif +#if defined(HAVE_COCOATOUCH) && TARGET_OS_IOS +#include "JITSupport.h" +#endif + #define SHADER_FILE_WATCH_DELAY_MSEC 500 #define QUIT_DELAY_USEC 3 * 1000000 /* 3 seconds */ @@ -3378,6 +3382,16 @@ bool runloop_environment_cb(unsigned cmd, void *data) } break; + case RETRO_ENVIRONMENT_GET_JIT_CAPABLE: + { +#if defined(HAVE_COCOATOUCH) && TARGET_OS_IOS + *(bool*)data = jb_has_debugger_attached(); +#else + *(bool*)data = true; +#endif + } + break; + default: RARCH_LOG("[Environ]: UNSUPPORTED (#%u).\n", cmd); return false; diff --git a/ui/drivers/ui_cocoatouch.m b/ui/drivers/ui_cocoatouch.m index f9df985e1f..ff2aa3380b 100644 --- a/ui/drivers/ui_cocoatouch.m +++ b/ui/drivers/ui_cocoatouch.m @@ -436,6 +436,10 @@ enum [self refreshSystemConfig]; [self showGameView]; +#if TARGET_OS_IOS + jb_start_altkit(); +#endif + rarch_main(argc, argv, NULL); rarch_start_draw_observer();