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
Xcode 12 toolchain generated binary for arm64e is not compatible lower than iOS 14. #563
Comments
This is a known issue; as you surmised, iOS 13 and 14 have different arm64e ABIs which is perfectly valid since the ABI is currently unstable -- and so it might change in the future as well. One potential solution that I've been thinking about is to allow users to specify multiple toolchains which can be used to build different slices of the MachO. It should be possible to |
thanks for your response.
okey, this is not theos resolvable issue... correct? |
iirc someone figured out that it might depend on the order in which you supply the slices so try reversing the order to see if that works. This issue should remain open since we'll need to add dual toolchain support to Theos in order to work around it. |
Do "order" means
|
Yeah that's what I meant. Try using Xcode 11's lipo? |
Unfortunately, same error.
|
I just found this thread; Matt's research seems promising. |
Hmm, patched version of lipo is required to create multiple same arch slice having fat binary...? |
the lipo'd dylib with two arm64e slices seems to work on 13.5 at least, we still need to test whether it works on 14 EDIT: seems to work on 14 too |
great news! if that solution is perfect, probably we should create drop-in replacement for patched lipo like dm.pl in the future. |
not only that, but to be honest it would be nice if theos could automate the entire process because a lot of developers (effectively anyone that develops something that's not only hooking appstore apps) will have problems with this once a 14 jailbreak that supports arm64e devices drops. you would of course need to have both xcode 11 and 12 toolchains installed. |
@opa334 that's the plan; it would ideally be possible to select different toolchains for different architectures. |
I confirmed too. fat binary that created by patched
NOTE: |
Newly Substitute v2 saying As a result, it only contains single arm64e slice, and caps 0x00 ABI version.
|
I figured out a potential way to do this via iOSOpenDev, and might be useful for you all to know how I approached the problem. That said, this is not tested on a real device but follows on from the work I did in the linked thread above. Consider it as "probably works with maybe minor adjustments"! Pre-requisites:
Steps:
Pay very close attention to the value of
That now is Xcode 12 ready to build with the older toolchain for arm64e.
The following is iOSOpenDev specific, but you'll get the idea.
This script will re-run compilation for the current target for After this, the output should then be a fat archive containing both the new and old arm64e formats, all handled automatically inside Xcode. I'll be bundling this all up into an easy to use setup on my branch of iOSOpenDev, but I'm aware nobody except me uses that...! EDIT: During testing, I have found the following modifications are required for a successful build to occur (usually applied when patching Xcode via iOSOpenDev's install script). In
|
Nice works with toolchain system! Is it possible to replace toolchain that swift.org distributed one? (It is small download size than full Xcode and can be support Linux(Ubuntu)) |
@r-plus i think so? As long as the clang version they ship predates the change to the arm64e ABI, then it should all work in a similar way. |
Last I checked, the toolchains on swift.org don't support arm64e compilation at all. It is possible to build a non-macOS toolchain with arm64e support though: Procursus does it here, although the Swift open source repo seems to not have support for the new (iOS 14) ABI yet. |
uh, that's too bad. I remembered some developers still supporting armv6 using custom theos to support multiple toolchain. |
Inspired by @opa334 's script, I implemented an experimental second toolchain support in my theos fork. Xcode 11 toolchain and The only difference is to I have checked the generated binary(Tweak with preferences bundle) using Hope it can be helpful and there will be an official support. :D |
i think new variable to support multiple toolchain should receive array (colon separated string like TARGET) of additional toolchain path to support more future ABI changes. for example
If Apple change the ABI again in the future, developers simply add @kabiroberai do you have any plan? |
@r-plus I've been considering something similar to your suggestion – except it'd probably be easier for Theos to deal with if we did it along the lines of This'll definitely require at least some degree of re-architecting (potentially adding another level of Make recursion which sucks because that means more overhead) but it's a necessary evil. |
0x80 ABI version of arm64e slice is not required to work in my tested tweaks (and preferencebundle too) and environement (iPhone 12 mini + iOS 14.1 + unc0ver) hmm, unc0ver doing something specially for this? |
second slice is only needed for binaries, not for dylibs (and binaries don't need an arm64e slice at all, arm64 works fine) no, unc0ver is not doing anything special |
Thanks for confirming @opa334. So in that case we need to:
|
To clarify, my intent isn't to automatically download the appropriate toolchain but to present a warning that recommends switching to the right one. More specifically, I've been doing some experimentation and it turns out the OSS Swift 5.3 toolchains from https://swift.org/download contain clang/swiftc binaries which are capable of building for the iOS 13 arm64e ABI while being compatible with the iOS 14 SDK. I still need to do some more research but this may be our best bet for now. The only other officially supported alternative (and the only official solution atm) on macOS is to download Xcode 11 alongside Xcode 12 and specify the former to Theos via xcode-select/DEVELOPER_DIR. I do not recommend ad-hoc solutions involving downloading a standalone copy of Xcode 11's XcodeDefault.xctoolchain because that toolchain is not designed to be used outside of Xcode 11. |
I used the lipo on https://www.dropbox.com/s/6h85hlc4sm14zeg/lipo?dl=0. tested on macOS Monterey 12.0.1, Xcode 13.1, Xcode 11.5. When compiling the tweak, it failed: |
using lipo is unnecessary, the arm64e slice compiled with Xcode 11 works on both <= 13 and >= 14 |
somebody suggested this on the Discord group a while ago, so I thought I would drop it here as a possible solution for any passerbys who don’t mind using python: |
FYI: If you see this error message when use Xcode 11.7 on newly macOS (in my case, clean installed M1 mac Monterey 12.3.1)
disabling SIP (System Integrity Protection) is the way to resolve. |
Here's the POC change in Theos you may use for building compatible arm64e slice, with the latest version of Xcode. # makefiles/targets/_common/darwin_tail.mk
_THEOS_TARGET_CFLAGS := -isysroot "$(ISYSROOT)" $(VERSIONFLAGS) $(_THEOS_TARGET_CC_CFLAGS)
+ ifeq ($(THEOS_CURRENT_ARCH),arm64e)
+ _THEOS_TARGET_CFLAGS += -fno-ptrauth-abi-version
+ endif
_THEOS_TARGET_CCFLAGS := $(_TARGET_LIBCPP_CCFLAGS)
_THEOS_TARGET_LDFLAGS := -isysroot "$(SYSROOT)" $(VERSIONFLAGS) $(LEGACYFLAGS) -multiply_defined suppress $(_TARGET_LIBCPP_LDFLAGS) $(_TARGET_LIBSWIFT_LDFLAGS)
+ ifeq ($(THEOS_CURRENT_ARCH),arm64e)
+ _THEOS_TARGET_LDFLAGS += -Xlinker -ios_version_min -Xlinker 6.0 # anything between 5.0 (inclusive) to 14.0 (exclusive)
+ endif https://github.com/PoomSmart/theos/pull/1/files When linking, you may see a warning like this which can be ignored: |
^ For future reference, it appears that using the flags above does NOT actually work: https://discord.com/channels/811490080278839327/811494949849661490/1162546530654355546 It was re-tested today:
Nonetheless if someone ever wants to test out the above flags with Xcode 15+ (and without modifying Theos itself), I'd suggest this way in Makefile ( ifeq ($(THEOS_PACKAGE_SCHEME),rootless)
ARCHS = arm64 arm64e
TARGET = iphone:clang:latest:15.0
else
ARCHS = armv7 armv7s arm64 arm64e
TARGET = iphone:clang:latest:7.0
arm64e_CFLAGS = -fno-ptrauth-abi-version
arm64e_LDFLAGS = -ld_classic
endif |
It seems the issue is not fixable, right? All to the different ABIs. |
Yeah, but it's somewhat strange that Apple would completely break compiling for the old ABI in newer compiler. I'm not sure how much the switch
and that using But either way, I can't seem to find any code for this option in public sources, so I suppose it's not open sourced yet, and so we won't really know what it actually does until it is...? |
What are the steps to reproduce this issue?
otool -l
In this result, caps means ABI version 0x80 (128) and
LC_BUILD_VERSION
cmd withminos 14.0
is appear instead ofLC_VERSION_MIN_IPHONEOS
.Below is result build by Xcode 11.7
Additionally this is error log in linker phase when I build by Xcode 11 with static library built by Xcode 12.
What happens?
Could not load binary built by Xcode 12 in A12 and A13 devices.
I tested in
I'm not sure about ABI version 0x00 binary (built by Xcode 11) will be executable in A12-13(also A14+) + iOS 14 environment (not yet jailbreakable).
If not executable, maybe we should separate package for iOS 14+ and lower than iOS 14 ...? (yes, this is not theos issue)
What were you expecting to happen?
We should make configurable option for build ABI version 0x00 binary or 0x80 binary with Xcode 12.lipo
. (e.g. armv7/arm64/arm64e (0x00)/arm64e (0x80))lipo
as theos project likedm.pl
... or hosting/maintaining patched version oflipo
as theos project. This tool must support x86_64 and arm64 or written by on the fly scripting language like perl. Either way, theos should be configurable for using lipo tool (e.g._THEOS_TARGET_LIPO
)Any logs, error output, etc?
nothing error when build.
Any other comments?
nothing.
What versions of software are you using?
Operating System: …
macOS 10.15.4
Toolchain Version: …
Xcode 12.1 and 11.7
SDK Version: …
9.2 copied from Xcode 7.2
The text was updated successfully, but these errors were encountered: