-
Notifications
You must be signed in to change notification settings - Fork 59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Current State of JIT #44
Comments
I wish I had your skills but that's awesome. |
Haha thanks man. I learned most of this in the past year, and I'm really just learning it as I go. Working on projects like this teaches you a ton really quickly |
Looking at the source, the relevant sections are in |
Thanks @milch I think those write the push and pops at the beginning and end of the JIT block though and seem working okay. For anyone trying to debug the JIT generated code you can change EMU_setCpuMode in emulatorViewController.mm from 1 to 2 to turn on JIT and set a breakpoint at the end of armExecuteLJIT(). Then view the memory at opfun by right clicking opfun and click view memory and that's the generated JIT code. |
It works!!! I've been working on JIT all day and finally got it working on 32 bit devices. The bad news is the way I fixed it was to run it very slowly. For some reason slowing it down to around 100 instructions per second fixed the random register clears. This is way too slow to play any games but it's huge progress. If I fix whatever is messing with the registers when the program is not slowed down, JIT will work 100% meaning full speed for all devices. It will even work on non-jailbroken iPhones |
Just got 60 fps on my iPad mini on a simple homebrew game (up from 16 fps). There's still problems but I'm going to talk to a professor tomorrow and hopefully he can help me sort it out. |
JIT is finished for 32bit devices. I hope it works on non-jailbroken phones. I'm going to work on getting it for 64bit arm devices next |
Yay !!! |
Wow, this is awesome. Your work here is incredible, and if I read that right you're saying that it might work even for non-jailbreakon phones? Simply amazing, keep it up! |
I hope so I really need someone to test it for me. If anyone has a stock 32bit phone (before the iPhone 6) and is able to side load the app and run it with JIT on, please let me know |
It'd have to be a iPhone 5 or below, the iPhone 5s is 64 bit Luke Rooney/ Director of Productions Trinity Corporation On Apr 28, 2016, 9:02 AM -0700, Will Cobbnotifications@github.com, wrote:
|
I have an old stock iPad mini. Can I use it to help you? |
Yea! Try building it from XCode and set the emulator engine to JIT in the settings. If it runs that means JIT will work on non-jailbroken devices |
ReportVersion: iNDS 1.5.1 (Debug)
All games are working in Running with Xcode
Game doesn't crash now, but hangs on a black screen with ? FPS. Also there's a blue (lldb) waiting for my input (in the Xcode output). ArmLJit.cppTEMPLATE static u32 cpuExecuteLJIT()
{
...
return opfun(); //Thread 9: EXC_BAD_ACCESS (code=2, address=0x40000000)
} Edit: Formating |
I really wish I had your skills @WilliamLCobb |
Thanks for posting that. Sadly it looks like KPP in iOS 9 is preventing JIT and it's unlikely I'll find a way around it. JIT will work on jailbroken 32bit iOS 9 devices and all 32bit iOS 8 devices but thats it. Maybe someone or I will find a way around this but for now JIT is very limited. |
@WilliamLCobb unsure if it will work on iOS 9, but on OS X 10.11 it's possible to create executable pages ad-hoc by calling mmap with the flags MAP_ANON, MAP_PRIVATE and MAP_JIT, could be used to implement JIT on 64 bit devices? On OS X this doesn't require any entitlements either but I have a feeling it will need some sort of entitlement on iOS (if it even works). This method also seems to have far less restrictions than the usual if this is what the JIT core already does then just ignore my message haha, I haven't yet looked at the source tested some shellcode at runtime on an iPhone 6+ on iOS 9.0.2 |
Thanks! I'm not using those flags right now but I'll definitely give them a shot in a minute and I'll let you know if it works |
Wow! Thats jailed ios9? |
i'm jailbroken, but if it works on stock OS X i guess it should work on jailed iOS 9 |
Oddly if you add MAP_JIT on iOS 8 is makes mapp fail. But great work. I'll push out an update soon and start working on arm64 I was wrong, JIT does not work on jailed iOS 9 devices |
Well it just crashed but I'm hopeful this will help me get it to work. |
@WilliamLCobb glad to hear it, but I have a feeling that this is a shortcoming on apple's part for not checking signing on the pages rather than a planned feature 😞 wouldn't be surprised if they patch it in later iOS versions |
Awesome! @WilliamLCobb and @Razzile, do you mind sharing your experience with the PPSSPP team (#8122)? Plus now that you're working on the amd64 JIT, I have an jailbroken iPhone 6 8.4 (pre-KPP) if you need my help. |
I was wrong when I said it ran on jailed devices. I've been testing some more and I can't get it to work again. It might have defaulted to the interpreter without me knowing but I didn't save the output to check. I'm going to try to look for an exploit to break outside of the sandbox in order to protect memory pages for execution. I don't have a ton of experience in security but I have enough to get started. Anyway the speedup from JIT is kind of disappointing. I haven't optimized anything yet but it's only like 10% on my iPad mini and I thought it would be much higher. I'll definitely work on it this summer but until we find a way to get JIT running on jailed devices, working on the JIT implementation is pretty pointless. |
@WilliamLCobb I am now unjailbroken (funny what a day can do). I'll investigate JIT on jailed devices too and post any results |
my initial test i posted yesterday throws Invalid argument on jailed iOS 9.3.1 :/ still looking into it EDIT: with a little tweaking i managed to get my above example to work on iOS 9.3.1 char shell[] = {0x10, 0x20, 0x70, 0x47}; // return 16;
- (void)viewDidLoad {
void *page = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
if (page == (void*)-1) {
perror(NULL);
return;
}
memcpy(page, shell, sizeof(shell));
typedef int (*shell_execute)();
shell_execute exe = (shell_execute)((int)page+1);
mprotect(page, 4096, PROT_READ | PROT_EXEC);
NSString *string = [NSString stringWithFormat:@"%d", exe()];
self.label.text = string;
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
} i had to map the page as RW and then after copying the code map it as RX. I used shellcode rather than dynamically generated JIT code but the effect should be the same. Still not sure why MAP_JIT is "invalid" on 9.3.1 this makes me think that the crashes you had may be due to incorrectly generated JIT code rather than code signing issues. |
Woah really? I was getting a bad access with an error code of 2 meaning the privileges were off. What device is this on? |
I'm about to update my iPad and I'll check it out |
iphone 6+ 9.3.1 |
I did research on the iPhone 5C and the iPhone 5. Both of them use the same CPU, same GPU, and same memory type and speed. Other than the colors, there really isn't a difference in terms of performance. |
I'm still working on iNDS 2.0.0, and every bug that was fixed in the master branch after May 3 still isn't fixed in the 2.0 branch. I made a pull request about that. |
I'm going to test the ArmThreadedInterpreter, ArmCJit and ArmLJit on DeSmuME 0.9.11. How do people even manage to build those? |
What is void*4? |
@DarknesGaming what context? a check like |
Thank you for the valuable information @razzle. That explains why JIT still isn't available for 64-bit devices, and it shows how much of a noob I am with C++ and Objective-C code. |
I just looked into the GNU Lightning 1.2 source code, and compared it to the new 2.1 code. That explains how @WilliamLCobb managed to port GNU Lightning in the first place, but doesn't explain how the ArmLJit.cpp file was created. |
Hey @WilliamLCobb, I know we need a better Renderer but have you looked at the (newly implemented) IR Interpreter (Intermediate Representation) from the PPSSPP team [#8725]?
|
@Anuskuss not to sound like a critic or anything, but do you think that would work with DeSmuME? DeSmuME already has a JIT compiler, but to enable that is by getting into the terminal of Apple devices to use --cpu-mode=1. |
@DarknesGaming We can't use the JIT compiler on iOS9 so this was a suggestion to look at an alternative. |
Based on what he wrote. It should work fine on jailbroken devices. Jailed however requires it to be signed with a dev certificate. And I believe that the other projects mentioned above can use this as well. |
Wow that's awesome! I'll add that in a second and see how it goes. The last thing we need is information on upgrading GNU lightning to 2.1. The syntax isn't that different from 1.2 but I've found no documentation for 2.x other than a few examples. No change log in the source or anything for upgrading from 1.2. |
The other alternative if to keep using 1.2 and add a custom arm64 support. I'd be surprised if someone hasn't already done this but I haven't been able to find it. Also I know 64bit processors are able to execute 32bit instructions but I don't know if it's possible to switch mid execution on iOS. If we could enable this somehow, very little work would be needed for JIT on all devices. |
I've been trying to get GNU Lightning 2.1 to function, but all the guides and manuals haven't been updated in over 10 years. |
Just so I can it out quick before I forget (this probably isn't the place to put this) but the 1.5.3 update started pumping any sound from the volume bumper from the top of my iPhone instead from the speakers. I don't have volume bumpers turned on or microphone and I have no idea how to fix it! Luke Rooney/ Director of Productions Trinity Corporation On May 20, 2016, 10:41 AM -0700, DarknesGamingnotifications@github.com, wrote:
|
All the code is in the screenshot. #include <sys/mman.h> for mmap(). shell is the byte code representation of syscall(SYS_write, stdout, arg1, arg2) [or equivalent] to write to stdout
|
It works! I wish we could get the JIT flag somehow because the memory has to be protected twice every time a block is compiled (Only JIT marked pages can be write and exec). One weird thing is after adding the syscall my iPad is completely unusable until I restart it after I close iNDS. Buttons stop working and it stops responding to events. If I tap a button or icon the animation happens but nothing else. It also refuses to unlock after I lock it telling me my passcode is incorrect. Very odd, I'll upload the change and see if anyone else has similar problems |
@WilliamLCobb the JIT flag requires the entitlement <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>dynamic-codesigning</key>
<true/>
<key>get-task-allow</key>
<true/>
</dict>
</plist> (not sure if get-task-allow is needed but included for good measure) |
also @WilliamLCobb that device freezing happened to me too but only once out of the 5 or so times i was testing JIT. it's very odd indeed. you could try calling ptrace(-1, 0, 0, 0) which is an invalid flag, hopefully ptrace would just error but the system would still disable codesigning first. wouldn't change anything though if it was the mapped pages causing problems and not ptrace |
I would try this, but after @WilliamLCobb's device going nuts I don't think that would be a good idea. I'm assuming his iPad is 32-bit because it's still not available for 64-bit devices yet. |
@DarknesGaming Lol you dont have to worry about the 9.3.2 update. Apple pulled it. Second time they have pulled an update and that last one was recent too. Regarding your comment about it not being on 64 bit device, I don't know what you mean since @Razzile has mentioned above that hes been doing his testing on an iPhone 6+ 9.3.1 Summary of JIT status on iOS 9 So as of right now thanks to Razzile we are now a step closer to getting it working. Just need to work out bugs with it. If I am wrong about my understanding of the situation then someone can correct me on it :p |
We could add an arm64 backend to GNU Lightning, but that means using the 2.0-2.1 source code and editing the ArmLJit.cpp file. Plus, the GNU Lightning source code refers "arm64" as "aarch64" instead. |
For your information Apple recently announced changes in the way JSCore & its JIT are managed in iOS 10
|
That doesn't look like good news 😔 fortunately the JIT method mentioned above isn't used by safari but by debugserver instead. Hopefully it remains unchanged |
Talk to the devs of ppsspp I am currently using iOS 9.3.3 and they got hit working on ppsspp. |
iPhone 6 Plus by the way |
I'm not sure the current state of JIT. I've been away from iNDS for a while, but I have been messing around with mmap again on iOS 9.3.3. if your app has the not sure if this is useful for iNDS or if the current system (interpreted or anything else) is okay as it is |
here I am, bringing up dead issues again hehe I noticed in coolstar's latest iOS 11 jailbreak code this commit seems to be make code run like it's being debugged, I talked about loong ago. If that's the case then I see no reason why JIT wouldn't work with this jailbreak. I haven't tested yet though |
@Razzile iNDS displays a black screen wih the controller overlay and any subsequent launches results in the same black screen and the app is unusable. My fix is to do a hard reset (restart my iPhone). My guess is that iNDS has 32bit instructions that is not supported on iOS 11 (please do correct me). |
In order to keep this organized, I'll update this comment with any progress on JIT.
So far JIT code is successfully compiled and running on iOS 8.3 on a 32bit processor. I'm sure iOS 9 on a 32 bit processor would also work fine, I just don't want to upgrade my iPad to test it. Inside armInnerLoop(), JIT code will run anywhere from 1 to 100 time before it crashes. The function where JIT execution is compiled and then run is cpuExecuteLJIT() inside ArmLJit.cpp.
The main problem we're facing is the code in the JIT block branches to many other functions inside ArmLJit.cpp. These functions then push the callee registers r4-r8. Oddly, these callee saved registers are not pushed back onto the stack before returning to the JIT block as they should be. This causes bad access errors and the crashing we currently see.
Interestingly, the current implementation runs the same without root privileges and will probably run on non jailbroken phones.
The text was updated successfully, but these errors were encountered: