-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Add support to iOS / Mac ARM64 #9699
Conversation
as you may be interested: @shindere |
EduardoRFS (2020/06/21 17:18 -0700):
as you may be interested: @shindere
Yes yes, I'm following. Just that I have too little time to deal with it
at the moment, but it's on my lists.
|
Also backported to 4.10, same state as the trunk |
I haven't fully reviewed yet, and hope to do it soon, but this looks very good, and extremely timely! Thank you @EduardoRFS . It would be very nice to add references to the iOS ABI (and the soon-to-be-revealed macOS one too!) in file asmcomp/arm64/NOTES.md. Is this the reference document you worked from? https://developer.apple.com/library/archive/documentation/Xcode/Conceptual/iPhoneOSABIReference/Articles/ARM64FunctionCallingConventions.html |
Added that, but it's not the full story, like x8 and x9 being safe across calls, it's in the linker code, as you can see the stub mentioning it. Couldn't found any reference for that as most details of that. Maybe mentioning that in the code? |
Three remarks to this pull request:
Edit: attached log files of testsuite: log.txt |
@m-schmidt: thanks a lot for the early testing, the results are extremely encouraging! tests/unwind is a macos-specific thing for Spacetime profiling; possibly Spacetime needs to be turned off on macOS/ARM64. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commit fdcfe0d must be removed before merging because it breaks the bootstrap. I understand why it is useful in a cross-compilation setting, but cross-compilation will have to be handled differently and in separate future work.
Makefile
Outdated
@@ -1014,7 +1014,7 @@ toplevel/opttoploop.cmx: otherlibs/dynlink/dynlink.cmxa | |||
make_opcodes := tools/make_opcodes$(EXE) | |||
|
|||
bytecomp/opcodes.ml: runtime/caml/instruct.h $(make_opcodes) | |||
runtime/ocamlrun$(EXE) $(make_opcodes) -opcodes < $< > $@ | |||
$(CAMLRUN) $(make_opcodes) -opcodes < $< > $@ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make_opcodes
is generated by boot/ocamlc -use-prims runtime/primitives
, so it must be run with runtime/camlrun$(EXE)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will address it, thanks and also open a cross compilation PR.
If anyone is interested on why I made that, I got a native cross compiler to work(ocamlopt.opt), and this was a requirement.
https://github.com/EduardoRFS/reason-mobile/blob/master/patches/ocaml/files/make.cross.sh
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(I'm trying to review commit-by-commit and Github doesn't make this easy.)
Commit 2c84349: I agree the use of x18 was wrong. The original ARM64/Linux port did not use x18 at all.
ARG_DOMAIN_STATE_PTR could be any register used for parameter passing beyond r0...r3, which are used to pass up to 4 arguments to the OCaml code being called from C.
The proposed change is OK as long as we don't need a second temporary register in addition to x16. If we ever need a second temp, we'll go back to using r17 and could use r4, say, as ARG_DOMAIN_STATE_PTR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commit 02dd612 is fine. Well spotted!
However the commit message should be made more informative:
"Avoid implicit conversion from integer to FP
This is flagged (rightly so) by clang -Wimplicit-int-float-conversion
."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commit 7db8f62 looks good to me.
Commit 51769c0 is OK, but it's a real pain that the macOS assembler doesn't support multiline C preprocessor macros like the GNU and LLVM assemblers.
Commit 7f6681b is misguided in my opinion. The compiled code should never use x18 for any purpose. But I'm pretty sure you can use x8 for the "ARG" register, see below why.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The last commit 2f1c175, looks good to me. A small suggestion below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the style comment I promised.
asmcomp/arm64/emit.mlp
Outdated
let is_macosx = | ||
Config.system = "macosx" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could move this definition to asmcomp/arm64/arch.ml
, so that you don't have to repeat it in selection.ml.
Also, the house style would omit is_
and call this variable macosx
. For example in asmcomp/amd64/arch.ml
, we have a win64
Boolean, not is_win64
.
Also, the new brand name is macOS, so macOS
or macos
would work too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm trying to keep it coherently with every other mention where it is macosx
, if we want to rename, it should be in a future PR. But fully agreed on removing the is_
and moving to arch.ml
@xavierleroy thanks for the review, it's funny I had even implemented x8 instead of x18 for every platform, but I was thinking "it will slightly increase the spill rate, but if you agree on that, this is nice. Also it will makes a lot more easier to check the overall code because we will not have any branching except by the calling convention. Thx for the review, will address the points maded in the following days and fix the buggy tests. |
@m-schmidt seriously, thanks, are you sure about the triplet? Like is that what Also if you can or know someone who can lend me an ssh I have time to address it, I'm doing this fulltime. And would love to address esy(and opam if needed). |
I get the following output:
But the configure script of OCaml prints:
|
@m-schmidt thx, is exactly what I was expecting, the configure script doesn't know Simple to fix, thanks for your help |
Configuration triplets are guessed by the |
Naïve question: how do you test on iOS?
Do you have to use a jailbroken hardware, or have you found another way?
Thanks!
|
Xavier Leroy (2020/06/30 00:12 -0700):
Configuration triplets are guessed by the `config.guess` script, which
is straight from the FSF. Please try with the newest scripts first
(https://savannah.gnu.org/projects/config), before modifying our
configure.ac.
Agreed, if the newer `config.guess` fixes the problem, we can replace
our bundled one by this one.
Thanks a lot for pointing that out, @xavierleroy
|
@shindere actually both, I use a jailbroken iPhone, quite simple to setup. But also I have an iOS emulator working (xnu-qemu-arm64), currently it doesn't support KVM so full software emulation, but I'm working on that. |
Interesting, thanks!
do you have to stick to a precise iOS version, or are you able to
jailbreak again after even the most recent upgrades?
I'd be interested in the emulator solution, too!
|
@shindere I can update my iPhone, every iPhone up to the iPhone X, has a permanent security problem into the ROM part of the bootloader and that leads to jailbreak. Look for checkra1n. So while iPhone X is supported that should still be valuable. The emulator, you should be able to setup iOS 12 which is the same from a binary perspective as iOS 13. If you're using macOS following the tutorial on this README.md should work, for Linux you need some patches that I didn't publish to get the network to work. After having everything setup, it's just like any VM, with working SSH. BTW I'm waiting the mac ARM, as it should be able to run almost exactly the same binaries as a normal iPhone when using the simulator. Except by some really low level features(SECURE_KERNEL). |
Right, I'm not worried at all about extra spilling here. For |
I'm seeing lots of alignment warnings from ocamlopt generated code:
Reading the manual page for ranlib reveals the worrying detail that the libtool(1) command (not to be confused with the GNU libtool) replaces ranlib now:
There's already a bit of a morass of workarounds for macOS-specific behaviour with ranlib/ar (especially around empty archives) in trunk, so I stopped looking there for the evening :-) |
I'm seeing the glass half-full: maybe |
I confirm everything works and builds without warnings if "ar" is configured to be a shell script that calls "libtool -shared" underneath. Nonetheless, it would be nice if a registered Apple developer could report the issue with "ar", as it is affecting other programs as well. |
I filed radar bug FB8190988 on Apple's system with the ranlib/ar warning logs and repro instructions from this PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I reviewed again. Looks good to me. I see no reason to delay merging, since the remaining macOS problems ("ar" warnings and "tests/unwind" failure) are probably not our fault and can be worked around later.
Am I correct that the INSTALL file has not been updated and that we don't |
@shindere you would be correct, but is the same as any compiler after the fix on config.guess, if you're using jailbreak. And is the the same as any cross compiler otherwise. Just configure and make |
OK ok, and I guess since deploying includes jailbreak we can not realy
document the procedure, that's too bad.
|
Mine is FB8207693 (which makes 16k filed bugs in under 2 days). I made a shorter example to reproduce with just plain C files. Let's hope for the best. |
Good news! With Beta 4 the alignment warnings of ar/ranlib are gone. |
Add support for iOS and macOS on ARM64
Add support for iOS and macOS on ARM64
Add support for iOS and macOS on ARM64
Add support for iOS and macOS on ARM64
Add support for iOS and macOS on ARM64
Add support for iOS and macOS on ARM64
Add support for iOS and macOS on ARM64
Add support for iOS and macOS on ARM64
Requirements
Apple / Darwin ARM64 assembler:
_
L
Runtime requirements:
x18
as the kernel sets it to 0 at anytimeAbout this PR
This PR was based on the #1084 but it diverges on some details and it also addresses some problems, namely, shared libraries on iOS and
./configure
support.I tried to keep the ABI as close as possible to Linux ARM64, they're identical if we keep x15 as the ADDITIONAL_ARG and when the OCaml code is in the main binary.After some changes, now both ARM64 platforms uses x8 as ADDITIONAL_ARG, so the only remaining difference in the ABI is #9752 and that we do only x0-x7 for ARGS.
But for iOS if the OCaml code is in a shared library it mess with every register except x0-x9 when making function calls, even to symbols in the same shared library. The ABI is x0-x7 for ARGS, x8 seems to be used for syscalls so it is also saved and x9 is saved in the same package as x8.
And to support iOS in a shared library this ABI needs to be followed, so x0-x7 was used for ARGS and x8 was used as the additional ARG.
Changes to Linux ARM64
It is a requirement to not use x18, by moving some registers it was possible to stop using it without any visible(to me) performance impact as the data dependency and the instructions was kept 1:1.
But as x18 is still safe to use, and x15 is also used as a temporary register, it seems like a good idea to use x18 as the ADDITIONAL ARG instead of x15.
That can easily be reverted if it isn't desired.
Current state + Tests
Currently I can compile it using a cross compiler and inside an iPhone with jailbreak is also possible to run the testsuite if you patch the iPhoneOS.sdk to support
system()
. Currently the best way to run the tests is exactly like that, an iPhone up to iPhone X with jailbreak on an ssh, but maybe Apple will release a Mac ARM.The test suite is almost entirely green, I'm looking on how to solve all of them, but overall the support is great
https://gist.githubusercontent.com/EduardoRFS/d067cff0aebec4df0fe55539669fff05/raw/10e071ba62a094c37e2f140835ed33a2cacc3211/test-result-ocaml+ios.txt
Known causes:
statmemprof/internal.ml
fails because iOS supports only 1008 on the stack size, so it doesn't fit in the stack