Repository navigation
[iOS] .NET 9.0.13 broke NativeAOT builds with classic linker when AesGcm is used #124609
Description
There's a Swift shim in libSystem.Security.Cryptography.Native.Apple.a. The build tools were likely upgraded between .NET 9.0.12 an .NET 9.0.13 which resulted in additional dependencies inside the Swift shim:
U __swift_FORCE_LOAD_$_swiftXPC
00000000000022d0 S __swift_FORCE_LOAD_$_swiftXPC_$_pal_swiftbindings
U __swift_FORCE_LOAD_$_swift_Builtin_float
00000000000022a8 S __swift_FORCE_LOAD_$_swift_Builtin_float_$_pal_swiftbindings
U __swift_FORCE_LOAD_$_swift_errno
0000000000002270 S __swift_FORCE_LOAD_$_swift_errno_$_pal_swiftbindings
U __swift_FORCE_LOAD_$_swift_math
00000000000022a0 S __swift_FORCE_LOAD_$_swift_math_$_pal_swiftbindings
U __swift_FORCE_LOAD_$_swift_signal
0000000000002278 S __swift_FORCE_LOAD_$_swift_signal_$_pal_swiftbindings
U __swift_FORCE_LOAD_$_swift_stdio
0000000000002298 S __swift_FORCE_LOAD_$_swift_stdio_$_pal_swiftbindings
U __swift_FORCE_LOAD_$_swift_time
0000000000002288 S __swift_FORCE_LOAD_$_swift_time_$_pal_swiftbindings
U __swift_FORCE_LOAD_$_swiftsys_time
0000000000002280 S __swift_FORCE_LOAD_$_swiftsys_time_$_pal_swiftbindings
U __swift_FORCE_LOAD_$_swiftunistd
0000000000002290 S __swift_FORCE_LOAD_$_swiftunistd_$_pal_swiftbindings
The new Apple linker has some logic to handle some backwards compatibility but that doesn't work with classic linker. The classic linker fails to compile the project now:
/usr/local/share/dotnet/packs/Microsoft.iOS.Sdk.net9.0_26.0/26.0.9785/targets/Xamarin.Shared.Sdk.targets(1835,3): error :
clang++ exited with code 1:
0 0x100d81788 __assert_rtn + 160
1 0x100d84570 ld::tool::SymbolTableAtom<x86_64>::classicOrdinalForProxy(ld::Atom const*) (.cold.3) + 0
2 0x100cbbdb0 ld::tool::SymbolTableAtom<x86_64>::classicOrdinalForProxy(ld::Atom const*) + 172
3 0x100cbcc24 ld::tool::SymbolTableAtom<arm64>::addImport(ld::Atom const*, ld::tool::StringPoolAtom*) + 140
4 0x100cbe508 ld::tool::SymbolTableAtom<arm64>::encode() + 396
5 0x100cb03b0 ___ZN2ld4tool10OutputFile20buildLINKEDITContentERNS_8InternalE_block_invoke.413 + 36
6 0x18814ca28 _dispatch_call_block_and_release + 32
7 0x1881664b0 _dispatch_client_callout + 16
8 0x188183d9c _dispatch_channel_invoke.cold.9 + 76
9 0x18815eadc _dispatch_root_queue_drain + 708
10 0x18815f120 _dispatch_worker_thread2 + 184
11 0x188303e84 _pthread_wqthread + 232
A linker snapshot was created at:
/tmp/AesGcmAppleNAOT-2026-02-19-191403.ld-snapshot
ld: Assertion failed: (it != _dylibToOrdinal.end()), function dylibToOrdinal, file OutputFile.cpp, line 5196.
We cannot use the new linker due to #119380.
Minimal repro:
AesGcmAppleNAOT.zip - Run dotnet publish
The repro simply uses the AesGcm class which depends on the Swift shim. For simplicity, any code like this is sufficient to reference the class and the related shims:
using (var aes = new AesGcm(new byte[32], 16))
aes.Encrypt([], [], [], [], []);The project includes global.json which pins the SDK version to 9.0.311. Downgrading to 9.0.310 (9.0.12 runtime) makes the error go away.
Minimal supported platform version is set with <SupportedOSPlatformVersion>15.0</SupportedOSPlatformVersion>. Raising it to 18.0 also makes the problem go away because the OS deployed Swift version is new enough.
Finally, <_UseClassicLinker>true</_UseClassicLinker> (dotnet/macios workload) switch is used to force the usage of the old linker.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsNo status
- StatusShow more project fieldsNo status
Activity
dotnet-policy-service commentedon Feb 19, 2026
Tagging subscribers to 'os-ios': @vitek-karas, @kotlarmilos, @steveisok, @akoeplinger
See info in area-owners.md if you want to be subscribed.
dotnet-policy-service commentedon Feb 19, 2026
Tagging subscribers to this area: @agocke, @dotnet/runtime-infrastructure
See info in area-owners.md if you want to be subscribed.
filipnavara commentedon Feb 19, 2026
Presumably we may need to tweak something like the
-runtime-compatibility-version noneoption if the build tools are updated between patch releases:runtime/src/native/libs/System.Security.Cryptography.Native.Apple/CMakeLists.txt
Line 92 in d9747b7
I tried using-runtime-compatibility-version 5.0 -disable-autolinking-runtime-compatibility -disable-autolinking-runtime-compatibility-concurrency -disable-autolinking-runtime-compatibility-dynamic-replacementswhich builds. However, I cannot quite reproduce the same build output as in the precompiled runtime artifacts in the first place so I cannot easily verify whether it did the right thing or not.(Managed to reproduce the broken build output with Xcode 16.4 and the suggestion above doesn't help)
dotnet-policy-service commentedon Feb 19, 2026
Tagging subscribers to this area: @agocke, @dotnet/ilc-contrib
See info in area-owners.md if you want to be subscribed.
akoeplinger commentedon Feb 20, 2026
Yes we noticed this in #120589 (comment), but we have no choice but to move forward on the macOS image we use.
Just to confirm, you're using a newer Xcode but just the old linker?
akoeplinger commentedon Feb 20, 2026
I tried a lot of similar things like you mentioned to workaround back then but I couldn't get the swift shims to stop being injected, it'd be awesome if you find something :)
filipnavara commentedon Feb 20, 2026
Yep, Xcode 26.2.
akoeplinger commentedon Feb 20, 2026
Hmm ok, that's another angle that wasn't apparent in #120589
that's not completely true, for 8.0/9.0 we could theoretically move back to the macos-14 image which is still available for a couple more months (assuming whatever Xcode is there doesn't inject the new shims). not sure how viable that is though
8 remaining items
dotnet-policy-service commentedon Apr 13, 2026
Tagging subscribers to this area: @dotnet/runtime-infrastructure
See info in area-owners.md if you want to be subscribed.
agocke commentedon Apr 18, 2026
So if we had Xcode 26 on our build machines, would that work?
filipnavara commentedon Apr 18, 2026
If it was used for the build then yes. (Xcode 26.something is available on the image)
I suppose the issue is partly to do some targeted small change vs. switching the whole build to use newer Xcode.
fix(maui): force ld_classic for iOS NAOT publish only #3856
fix(maui): force ld_classic for iOS NAOT publish only #3856
fix(maui): force ld_classic for iOS NAOT publish only #3856
JulieLeeMSFT commentedon Jul 10, 2026
@akoeplinger, assigning this issue to you. Please triage further if it needs to be pushed out.
akoeplinger commentedon Jul 14, 2026
Moving to 12.0