Closed am11 closed 2 years ago
Ah, so those messages are still generated by the object writer in ILC.
For example here: https://github.com/dotnet/llvm-project/blob/f1120a92d05f1c57e75af7d16504012570ef3409/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp#L102-L103.
Looks like we need to decide what kind of relocation to generate when we're generating it.
@MichalStrehovsky, thanks for the pointers. The managed part of objwriter API currently does not support VariantKind
, so I updated objwriter: https://github.com/dotnet/llvm-project/pull/185. With the current state of that PR (+ https://github.com/dotnet/runtime/compare/main...am11:feature/nativeaot/osx-arm64), these two ilc errors are vanished:
error: fixup value out of range
error: ADR/ADRP relocations must be GOT relative
but this one remains:
error: unknown AArch64 fixup kind!
it is false
return from https://github.com/dotnet/llvm-project/blob/f1120a92d05f1c57e75af7d16504012570ef3409/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp#L59. I noticed that in objwriter, we do not explicitly create a MCFixup
for mach, looks like those are classified by AArch64AsmBackend
. 💭
Really nice progress!
What is the reloc it's complaining about? Is it FK_PCRel_4
by any chance? We add special handling to it in our LLVM patch: https://github.com/dotnet/llvm-project/commit/67f5503adc0fe9d886a33df58f49a4b3e2b8c21e. Maybe having it take the same path as FK_Data_4
would work?
You'll know if the reloc got messed up if it ends up pointing at garbage after linking.
Those were indeed all FK_PCRel_4
. 😄
Pushed a commit to treat it as FK_Data_4
. With that ilc
msbuild task completes without producing any diagnostics.
clang task, however, continues to fail (still complaining about __LD,__compact_unwind section, bad length file
). Interestingly, now the __LD,__compact_unwind
section has disappeared when I run with objdump -d
(as it was showing previously), but it shows up with objdump --full-contents -d
.
Running ld
command with -v
shows nothing useful:
% "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld" \
-demangle -lto_library /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/libLTO.dylib \
-dynamic -arch arm64 -platform_version macos 12.0.0 12.1 \
-syslibroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk \
-o bin/release/net7.0/osx-arm64/native/naot1 \
-L/usr/local/lib obj/release/net7.0/osx-arm64/native/naot1.o \
/Users/am11/.nuget/packages/runtime.osx-arm64.microsoft.dotnet.ilcompiler/7.0.0-dev/sdk/libbootstrapper.a \
/Users/am11/.nuget/packages/runtime.osx-arm64.microsoft.dotnet.ilcompiler/7.0.0-dev/sdk/libRuntime.WorkstationGC.a \
/Users/am11/.nuget/packages/runtime.osx-arm64.microsoft.dotnet.ilcompiler/7.0.0-dev/framework/libSystem.Native.a \
/Users/am11/.nuget/packages/runtime.osx-arm64.microsoft.dotnet.ilcompiler/7.0.0-dev/framework/libSystem.Globalization.Native.a \
/Users/am11/.nuget/packages/runtime.osx-arm64.microsoft.dotnet.ilcompiler/7.0.0-dev/framework/libSystem.IO.Compression.Native.a \
/Users/am11/.nuget/packages/runtime.osx-arm64.microsoft.dotnet.ilcompiler/7.0.0-dev/framework/libSystem.Net.Security.Native.a \
/Users/am11/.nuget/packages/runtime.osx-arm64.microsoft.dotnet.ilcompiler/7.0.0-dev/framework/libSystem.Security.Cryptography.Native.Apple.a \
-rpath @executable_path -lc++ -ldl -lm -lz -licucore \
-framework CoreFoundation -framework Foundation -framework Security -framework GSS \
-lSystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/13.0.0/lib/darwin/libclang_rt.osx.a \
-v
@(#)PROGRAM:ld PROJECT:ld64-711
BUILD 21:57:24 Nov 17 2021
configured to support archs: armv6 armv7 armv7s arm64 arm64e arm64_32 i386 x86_64 x86_64h armv6m armv7k armv7m armv7em
Library search paths:
/usr/local/lib
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib
Framework search paths:
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/
ld: malformed __LD,__compact_unwind section, bad length file 'obj/release/net7.0/osx-arm64/native/naot1.o'
Digging in Apple's source code, the error seems to be:
the size of __compact_unwind section is not divisible by the size of the unwind entry. That's odd because we don't generate the Apple weird thing, we generate DWARF CFI.
However, looking at LLVM source code, I think this is kicking in:
And LLVM does generate something on our behalf. Probably broken from the sound of it.
I would dig around that - can we still make do without a __compact_unwind section? If it's not present in the executable, maybe ld would still do the right thing and convert it from CFI to the compact unwind scheme for us.
Maybe the right thing would be to start generating compact unwinding because Apple tends to unceremoniously cut off things they don't like anymore after a couple years of supporting both the thing they stopped liking and the new shiny thing. Unwinding codes are currently generated in RyuJIT.
Thanks, and nice detective work finding those links! (I was only searching across org:dotnet 😅)
Disabling compact unwind (https://github.com/dotnet/llvm-project/pull/185/commits/090a4651fd8f1ccc27bf5c87f8ec00a9861daf09) revealed some missing symbols errors. Those error messages were generous enough to point me to the missing C_FUNC()
: https://github.com/am11/runtime/commit/3bcd7b6c (I previously fixed couple of those in https://github.com/am11/runtime/commit/b8cc922c79653098a1ad9d3eb64bec7c1d8db58e which were failing the runtime build, but the new ones only show up when consuming Microsoft.DotNet.ILCompiler
package 🤷)
Looks like we are getting there. Next error is:
ld: in section __DATA,.corert_eh_table reloc 0: unknown relocation type 15 file 'obj/release/net7.0/osx-arm64/native/naot1.o'
Apparently, reloc 15 is assigned to PPC_RELOC_LOCAL_SECTDIFF
(suggesting something is off the kilter.. 👀).
.corert_eh_table
uses the 32-bit relative relocs that would be translated to FK_PCRel_4
I think - so something might be going wrong around that.
Can you try updating this:
and make it so that it returns false
for ARM64 macOS? (use Architecture
and OperatingSystem
that is conveniently available on the class).
This will make the compiler avoid generating 32bit relative relocations in favor of full pointers. It will make the executables a bit bigger. We would want to try find a way to do 32bit relative relocs eventually, but let's first find out if that's really the problem.
Having SupportsRelativePointers to return false had no effect, getting the ditto ld error. :(
Ah, there's an extra code path that is not active for Wasm or CppCodegen (for which SupportsRelativePointers
was introduced) - replace IMAGE_REL_BASED_RELPTR32
with IMAGE_REL_BASED_DIR64
in src\coreclr\tools\aot\ILCompiler.Compiler\Compiler\DependencyAnalysis\ObjectWriter.cs. This is nothing but a hack (it's going to crash if we take a GC or exception at runtime), but it might help narrowing down the problem/make further progress.
Thanks, this workaround worked for .corert_eh_table
section. Now I am getting it from another section:
ld: in section __TEXT,__const reloc 0: unknown relocation type 15 file 'obj/release/net7.0/osx-arm64/native/naot1.o'
I'll try to find out what is causing type 15 failure (to avoid workarounds).
I'll try to find out what is causing type 15 failure (to avoid workarounds).
Yeah, that sounds like a better plan. This workaround is starting to get out of hand (I think now it's relocs generated by RyuJIT).
I was able to make quick progress on issues like this in the past by reducing the problem into a ZeroSharp no-runtime size (https://github.com/MichalStrehovsky/zerosharp) repro case. The object files generated out of that are just a couple kilobytes in size and it's easier to trace through the problematic code within the compiler with that. But it's not mandatory to go in that direction, just a possible avenue if too many things are happening in a full Hello World.
Pushed a commit to objwriter (https://github.com/dotnet/llvm-project/pull/185/commits/7280b550bb8ac3cce72a1ee288dc744b1ab9b1b6) which fixes type 15 error. After that dotnet publish
produced the binary successfully but it does not print Hello World!
yet. :)
% lldb bin/release/net7.0/osx-arm64/publish/naot1
Added Microsoft public symbol server
Added symbol directory path: /usr/local/share/dotnet/shared/Microsoft.NETCore.App/6.0.2
Added symbol directory path: /usr/local/share/dotnet/packs/Microsoft.NETCore.App.Host.osx-arm64/6.0.2/runtimes/osx-arm64/native
(lldb) target create "../naot1/bin/release/net7.0/osx-arm64/publish/naot1"
Current executable set to '/Users/am11/projects/naot1/bin/release/net7.0/osx-arm64/publish/naot1' (arm64).
(lldb) r
Process 38291 launched: '/Users/am11/projects/naot1/bin/release/net7.0/osx-arm64/publish/naot1' (arm64)
Process 38291 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2, address=0x100460988)
frame #0: 0x0000000100460988 naot1`tls_CurrentThread
naot1`tls_CurrentThread:
-> 0x100460988 <+0>: ldp x16, x17, [x9, #-0xd0]
0x10046098c <+4>: udf #0x1
0x100460990 <+8>: udf #0x102
0x100460994 <+12>: udf #0x0
Target 0: (naot1) stopped.
(lldb) bt all
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2, address=0x100460988)
* frame #0: 0x0000000100460988 naot1`tls_CurrentThread
frame #1: 0x00000001001a6db0 naot1`InitializeModules + 80
frame #2: 0x0000000100006438 naot1`main [inlined] InitializeRuntime() at main.cpp:169:5 [opt]
frame #3: 0x00000001000063ac naot1`main(argc=1, argv=0x000000016fdff798) at main.cpp:201:19 [opt]
frame #4: 0x0000000100c350f4 dyld`start + 520
thread #2
frame #0: 0x00000001a96f1eac libsystem_kernel.dylib`mach_absolute_time + 108
frame #1: 0x00000001a96f3838 libsystem_kernel.dylib`__commpage_gettimeofday_internal + 44
frame #2: 0x00000001a95f9534 libsystem_c.dylib`gettimeofday + 52
frame #3: 0x000000010004fcb4 naot1`::QueryPerformanceCounter(lpPerformanceCount=0x000000016fe86f68) at PalRedhawkUnix.cpp:1090:9 [opt]
frame #4: 0x0000000100012090 naot1`EnsureYieldProcessorNormalizedInitialized() [inlined] PalQueryPerformanceCounter(arg1=0x000000016fe86f68) at PalRedhawkFunctions.h:131:12 [opt]
frame #5: 0x0000000100012088 naot1`EnsureYieldProcessorNormalizedInitialized() at yieldprocessornormalized.cpp:76:9 [opt]
frame #6: 0x0000000100012024 naot1`EnsureYieldProcessorNormalizedInitialized() at yieldprocessornormalized.cpp:118:9 [opt]
frame #7: 0x000000010000801c naot1`FinalizerStart(pContext=0x0000600003000090) at FinalizerHelpers.cpp:54:5 [opt]
frame #8: 0x00000001a972d240 libsystem_pthread.dylib`_pthread_start + 148
Great progress!
If I'm looking at the right thing, tls_currentThread
is data, not code, so I guess we shouldn't be running it. But seeing a problem around it is not completely surprising since TLS access is likely going to be different on macOS than it is on Linux. The fix will probably be around the INLINE_GET_TLS_VAR
macro in src\coreclr\nativeaot\Runtime. It should expand to however threadlocal statics are accessed on ARM64. There already is an if APPLE
on the x64 version of the macro.
Yup, that was it: https://github.com/am11/runtime/commit/5106fc986382dae29aeaf93402f0f3dea408bc7d (based on ELF sequence vs. MachO)
It has moved the needle a bit; next up is RhpNewArray
:
(lldb) r
Process 89591 launched: '/Users/am11/projects/naot1/bin/release/net7.0/osx-arm64/publish/naot1' (arm64)
This version of LLDB has no plugin for the mipsassem language. Inspection of frame variables will be limited.
Process 89591 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2, address=0x1a9734530)
frame #0: 0x000000010005c750 naot1`RhpNewArray at AllocFast.S:213
210 ldr x12, [x3, #OFFSETOF__Thread__m_alloc_context__alloc_ptr]
211
212 // Update the alloc pointer to account for the allocation.
-> 213 str x2, [x3, #OFFSETOF__Thread__m_alloc_context__alloc_ptr]
214
215 // Set the new objects MethodTable pointer and element count.
216 str x0, [x12, #OFFSETOF__Object__m_pEEType]
Target 0: (naot1) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2, address=0x1a9734530)
* frame #0: 0x000000010005c750 naot1`RhpNewArray at AllocFast.S:213
frame #1: 0x00000001001a7114 naot1`S_P_CoreLib_Internal_Runtime_CompilerHelpers_StartupCodeHelpers__CreateTypeManagers + 100
frame #2: 0x00000001001a6db0 naot1`InitializeModules + 80
frame #3: 0x0000000100006458 naot1`main [inlined] InitializeRuntime() at main.cpp:169:5 [opt]
frame #4: 0x00000001000063cc naot1`main(argc=1, argv=0x000000016fdff7a0) at main.cpp:201:19 [opt]
frame #5: 0x0000000100c350f4 dyld`start + 520
(lldb) register read
General Purpose Registers:
x0 = 0x0000000100f04290
x1 = 0x0000000000000001
x2 = 0xd53bd071f9400430
x3 = 0x00000001a9734530 libdyld.dylib`tlv_get_addr
x4 = 0x000000000000000a
x5 = 0x0000000000000000
x6 = 0x0000000000000002
x7 = 0x0000000000000000
x8 = 0x00000000ffffffff
x9 = 0x0000000000000000
x10 = 0x0000000000000070
x11 = 0x0000000000000001
x12 = 0xd53bd071f9400410
x13 = 0x0000000001dfb800
x14 = 0x0000000001c00000
x15 = 0x0000000000000044
x16 = 0x0000000000000000
x17 = 0x0000000100f04290
x18 = 0x0000000000000000
x19 = 0x0000000000000001
x20 = 0x0000000100460968 naot1`__Module
x21 = 0x0000000100000000 naot1`_mh_execute_header
x22 = 0x00000001003773a0 naot1`c_classlibFunctions
x23 = 0x000000000000000a
x24 = 0x0000000000000000
x25 = 0x0000000000000000
x26 = 0x0000000000000000
x27 = 0x0000000000000000
x28 = 0x0000000000000000
fp = 0x000000016fdff570
lr = 0x000000010005c738 naot1`RhpNewArray + 56
sp = 0x000000016fdff560
pc = 0x000000010005c750 naot1`RhpNewArray + 80
cpsr = 0x80001000
# a weird "error: warning: warning:" from printer
(lldb) p OFFSETOF__Thread__m_alloc_context__alloc_ptr
error: warning: warning: got name from symbols: OFFSETOF__Thread__m_alloc_context__alloc_ptr
error: <user expression 8>:1:1: reference to 'OFFSETOF__Thread__m_alloc_context__alloc_ptr' is ambiguous
OFFSETOF__Thread__m_alloc_context__alloc_ptr
^
note: candidate found by name lookup is 'OFFSETOF__Thread__m_alloc_context__alloc_ptr'
note: candidate found by name lookup is 'OFFSETOF__Thread__m_alloc_context__alloc_ptr'
# but this suggests offset is zero
(lldb) image lookup -n OFFSETOF__Thread__m_alloc_context__alloc_ptr
1 match found in /Users/am11/projects/naot1/bin/release/net7.0/osx-arm64/publish/naot1:
Address: 0x0000000000000000 (0x0000000000000000)
Summary: 0x0000000000000000
That looks related to the TLS access. We're here:
My suspicion is that INLINE_GETTHREAD
loaded a bogus address into x3. It's supposed to load the tls_CurrentThread
thread-local static.
I would put a breakpoint here:
and see what value the variable has (and how the compiler got to it in assembly). Then compare with what INLINE_GETTHREAD came up with. (Make sure you're looking at the same thread, we already have the finalizer thread running at this point in startup).
Ah, right, had to move x0 to the target register and also pop stack before endm for APPLE
branch: https://github.com/am11/runtime/commit/750fc8349ce41a66998cd5a847d2e22c979c285e. Thanks for the debugging pointers, I just printed its address with p (Thread *) &tls_CurrentThread
and then compared what's the effect on x3 before and after Alloc.S:196.
Now we are in the managed main and getting to the code emitted via objwriter:
(lldb) target create "../naot1/bin/release/net7.0/osx-arm64/native/naot1"
Current executable set to '/Users/am11/projects/naot1/bin/release/net7.0/osx-arm64/native/naot1' (arm64).
(lldb) r
Process 86586 launched: '/Users/am11/projects/naot1/bin/release/net7.0/osx-arm64/native/naot1' (arm64)
Process 86586 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
frame #0: 0x00000001001fa8a4 naot1`S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>__Create + 52
naot1`S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>__Create:
-> 0x1001fa8a4 <+52>: ldr x1, [x0]
0x1001fa8a8 <+56>: ldr x1, [x1, #0x1e8]
0x1001fa8ac <+60>: blr x1
0x1001fa8b0 <+64>: bl 0x1001a3b10 ; S_P_CoreLib_Internal_IntrinsicSupport_EqualityComparerHelpers__GetComparer
Target 0: (naot1) stopped.
(lldb) bt all
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
* frame #0: 0x00000001001fa8a4 naot1`S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>__Create + 52
frame #1: 0x0000000100190dd4 naot1`S_P_CoreLib_System_Collections_Generic_NonRandomizedStringEqualityComparer___cctor + 36
frame #2: 0x000000010019722c naot1`S_P_CoreLib_System_Runtime_CompilerServices_ClassConstructorRunner__EnsureClassConstructorRun + 204
frame #3: 0x00000001001970e4 naot1`S_P_CoreLib_System_Runtime_CompilerServices_ClassConstructorRunner__CheckStaticClassConstructionReturnGCStaticBase + 20
frame #4: 0x0000000100190d48 naot1`S_P_CoreLib_System_Collections_Generic_NonRandomizedStringEqualityComparer__GetStringComparer + 24
frame #5: 0x000000010020cc80 naot1`S_P_CoreLib_System_Collections_Generic_Dictionary_2<System___Canon__System___Canon>___ctor_2 + 128
frame #6: 0x00000001000e2a04 naot1`S_P_CoreLib_System_AppContext__SetData + 84
frame #7: 0x00000001002125a0 naot1`Internal_CompilerGenerated__Module___SetAppContextSwitches + 32
frame #8: 0x0000000100212734 naot1`__managed__Main + 228
frame #9: 0x0000000100006454 naot1`main(argc=1, argv=0x000000016fdff798) at main.cpp:205:18 [opt]
frame #10: 0x0000000100c350f4 dyld`start + 520
thread #2
frame #0: 0x00000001a96f1eac libsystem_kernel.dylib`mach_absolute_time + 108
frame #1: 0x00000001a96f3838 libsystem_kernel.dylib`__commpage_gettimeofday_internal + 44
frame #2: 0x00000001a95f9534 libsystem_c.dylib`gettimeofday + 52
frame #3: 0x000000010004fcc4 naot1`::QueryPerformanceCounter(lpPerformanceCount=0x000000016fe86f68) at PalRedhawkUnix.cpp:1090:9 [opt]
frame #4: 0x00000001000120a0 naot1`EnsureYieldProcessorNormalizedInitialized() [inlined] PalQueryPerformanceCounter(arg1=0x000000016fe86f68) at PalRedhawkFunctions.h:131:12 [opt]
frame #5: 0x0000000100012098 naot1`EnsureYieldProcessorNormalizedInitialized() at yieldprocessornormalized.cpp:76:9 [opt]
frame #6: 0x0000000100012034 naot1`EnsureYieldProcessorNormalizedInitialized() at yieldprocessornormalized.cpp:118:9 [opt]
frame #7: 0x000000010000802c naot1`FinalizerStart(pContext=0x0000600003000090) at FinalizerHelpers.cpp:54:5 [opt]
frame #8: 0x00000001a972d240 libsystem_pthread.dylib`_pthread_start + 148
(lldb) register read
General Purpose Registers:
x0 = 0x0000000000000000
x1 = 0x0000000100373628 (void *)0x0000000100469238: __writableDataString
x2 = 0x00000001003eeaf0 __TypeThreadStaticIndexS_P_CoreLib_System_Threading_ManagedThreadId
x3 = 0x0000000000000018
x4 = 0x0000000000000000
x5 = 0x0000000101800000
x6 = 0x0000000000000007
x7 = 0x0000000000000000
x8 = 0x0000000100ec11f0
x9 = 0x0000600000004090
x10 = 0x00000001a9734530 libdyld.dylib`tlv_get_addr
x11 = 0x0000000000000001
x12 = 0x000000010045f1e8 g_ephemeral_high
x13 = 0x0000000101807fd0
x14 = 0x0000000101806608
x15 = 0x0000000101806620
x16 = 0x0000000000000000
x17 = 0x0000000100f04290
x18 = 0x0000000000000000
x19 = 0x000000010041bf70 vtable for S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<String>
x20 = 0x00000001198061d8
x21 = 0x00000001198061e0
x22 = 0x0000000101806440
x23 = 0x0000000119804820
x24 = 0x0000000000000000
x25 = 0x0000000000000000
x26 = 0x0000000000000000
x27 = 0x0000000000000000
x28 = 0x0000000000000000
fp = 0x000000016fdff420
lr = 0x00000001001fa8a4 naot1`S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>__Create + 52
sp = 0x000000016fdff420
pc = 0x00000001001fa8a4 naot1`S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>__Create + 52
cpsr = 0x60001000
This doesn't ring any bell - can you paste the full disassembly of the faulting method? It's not clear where we are. I'm guessing that this is an attempt to do a virtual call to access the TypeHandle
property here:
...but the System.Type
we got out of the typeof
is bogus. Right before that you should see a call to this method:
Validate that the parameter to the method is correct (it should be a MethodTable*
and should have an associated textual symbol) and then try to step through what it's doing.
Might be easier to debug through this with optimizations off (drop the -O
parameter from the ilc command line or dotnet publish
as Debug
).
With debug, here is the full disassembly at IP/PC (0x1002f0bb8
in the middle of disassembly):
(lldb) r
Process 88778 launched: '/Users/am11/projects/naot1/bin/Debug/net7.0/osx-arm64/publish/naot1' (arm64)
Process 88778 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
frame #0: 0x00000001002f0bb8 naot1`S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>__Create + 168
naot1`S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>__Create:
-> 0x1002f0bb8 <+168>: ldr wzr, [x0]
0x1002f0bbc <+172>: blr x1
0x1002f0bc0 <+176>: str x0, [x29, #0x48]
0x1002f0bc4 <+180>: ldr x0, [x29, #0x48]
Target 0: (naot1) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
* frame #0: 0x00000001002f0bb8 naot1`S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>__Create + 168
frame #1: 0x00000001002f0c74 naot1`S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>__get_Default + 68
frame #2: 0x000000010023dec4 naot1`S_P_CoreLib_System_Collections_Generic_NonRandomizedStringEqualityComparer___cctor + 36
frame #3: 0x0000000100247ba0 naot1`S_P_CoreLib_System_Runtime_CompilerServices_ClassConstructorRunner__EnsureClassConstructorRun + 384
frame #4: 0x0000000100247988 naot1`S_P_CoreLib_System_Runtime_CompilerServices_ClassConstructorRunner__CheckStaticClassConstructionReturnGCStaticBase + 24
frame #5: 0x000000010023de28 naot1`S_P_CoreLib_System_Collections_Generic_NonRandomizedStringEqualityComparer__GetStringComparer + 40
frame #6: 0x000000010030e32c naot1`S_P_CoreLib_System_Collections_Generic_Dictionary_2<System___Canon__System___Canon>___ctor_2 + 268
frame #7: 0x000000010030e1dc naot1`S_P_CoreLib_System_Collections_Generic_Dictionary_2<System___Canon__System___Canon>___ctor + 28
frame #8: 0x0000000100123414 naot1`S_P_CoreLib_System_AppContext__SetData + 116
frame #9: 0x0000000100317a9c naot1`Internal_CompilerGenerated__Module___SetAppContextSwitches + 28
frame #10: 0x0000000100317bbc naot1`__managed__Main + 60
frame #11: 0x000000010000df64 naot1`main(argc=1, argv=0x000000016fdff7a0) at main.cpp:205:18 [opt]
frame #12: 0x0000000100f190f4 dyld`start + 520
(lldb) disassemble -a 0x1002f0bb8
naot1`S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>__Create:
0x1002f0b10 <+0>: stp x29, x30, [sp, #-0x90]!
0x1002f0b14 <+4>: mov x29, sp
0x1002f0b18 <+8>: add x9, x29, #0x28 ; =0x28
0x1002f0b1c <+12>: movi.16b v16, #0x0
0x1002f0b20 <+16>: stp q16, q16, [x9]
0x1002f0b24 <+20>: stp q16, q16, [x9, #0x20]
0x1002f0b28 <+24>: stp xzr, xzr, [x9, #0x40]
0x1002f0b2c <+28>: str xzr, [x9, #0x50]
0x1002f0b30 <+32>: str x0, [x29, #0x88]
0x1002f0b34 <+36>: str x0, [x29, #0x80]
0x1002f0b38 <+40>: ldr x0, [x29, #0x80]
0x1002f0b3c <+44>: bl 0x10000b380 ; __GenericLookupFromType_S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>_GCStaticBase_S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<T_System___Canon>
0x1002f0b40 <+48>: add x0, x0, #0x8 ; =0x8
0x1002f0b44 <+52>: str x0, [x29, #0x78]
0x1002f0b48 <+56>: ldr x0, [x29, #0x80]
0x1002f0b4c <+60>: bl 0x10000bd54 ; __GenericLookupFromType_S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>_TypeHandle_S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<T_System___Canon>
0x1002f0b50 <+64>: bl 0x1002f0af0 ; S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>__get_SupportsGenericIEquatableInterfaces
0x1002f0b54 <+68>: str w0, [x29, #0x74]
0x1002f0b58 <+72>: ldr x0, [x29, #0x78]
0x1002f0b5c <+76>: str x0, [x29, #0x68]
0x1002f0b60 <+80>: ldr w0, [x29, #0x74]
0x1002f0b64 <+84>: cbnz w0, 0x1002f0b88 ; <+120>
0x1002f0b68 <+88>: nop
0x1002f0b6c <+92>: nop
0x1002f0b70 <+96>: nop
0x1002f0b74 <+100>: nop
0x1002f0b78 <+104>: nop
0x1002f0b7c <+108>: ldr x0, [x29, #0x68]
0x1002f0b80 <+112>: str x0, [x29, #0x28]
0x1002f0b84 <+116>: b 0x1002f0b84 ; <+116>
0x1002f0b88 <+120>: ldr x0, [x29, #0x80]
0x1002f0b8c <+124>: bl 0x10000bd60 ; __GenericLookupFromType_S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>_TypeHandle_T_System___Canon
0x1002f0b90 <+128>: bl 0x100261960 ; S_P_CoreLib_Internal_Runtime_CompilerHelpers_LdTokenHelpers__GetRuntimeTypeHandle
0x1002f0b94 <+132>: str x0, [x29, #0x60]
0x1002f0b98 <+136>: ldr x0, [x29, #0x60]
0x1002f0b9c <+140>: bl 0x100140890 ; S_P_CoreLib_System_Type__GetTypeFromHandle
0x1002f0ba0 <+144>: str x0, [x29, #0x58]
0x1002f0ba4 <+148>: adrp x0, -747
0x1002f0ba8 <+152>: add x0, x0, #0x4a8 ; =0x4a8
0x1002f0bac <+156>: str x0, [x29, #0x50]
0x1002f0bb0 <+160>: ldr x0, [x29, #0x58]
0x1002f0bb4 <+164>: ldr x1, [x29, #0x50]
-> 0x1002f0bb8 <+168>: ldr wzr, [x0]
0x1002f0bbc <+172>: blr x1
0x1002f0bc0 <+176>: str x0, [x29, #0x48]
0x1002f0bc4 <+180>: ldr x0, [x29, #0x48]
0x1002f0bc8 <+184>: bl 0x1002596d0 ; S_P_CoreLib_Internal_IntrinsicSupport_EqualityComparerHelpers__GetComparer
0x1002f0bcc <+188>: str x0, [x29, #0x40]
0x1002f0bd0 <+192>: ldr x0, [x29, #0x80]
0x1002f0bd4 <+196>: bl 0x10000c954 ; __GenericLookupFromType_S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>_MethodDictionary_S_P_CoreLib_System_Runtime_CompilerServices_Unsafe__As<S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<T_System___Canon>>
0x1002f0bd8 <+200>: str x0, [x29, #0x20]
0x1002f0bdc <+204>: ldr x0, [x29, #0x20]
0x1002f0be0 <+208>: ldr x1, [x29, #0x40]
0x1002f0be4 <+212>: bl 0x100370490 ; S_P_CoreLib_System_Runtime_CompilerServices_Unsafe__As<System___Canon>
0x1002f0be8 <+216>: str x0, [x29, #0x38]
0x1002f0bec <+220>: ldr x0, [x29, #0x80]
0x1002f0bf0 <+224>: bl 0x10000c948 ; __GenericLookupFromType_S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>_MethodDictionary_S_P_CoreLib_System_Threading_Interlocked__CompareExchange_3<S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<T_System___Canon>>
0x1002f0bf4 <+228>: str x0, [x29, #0x18]
0x1002f0bf8 <+232>: ldr x0, [x29, #0x18]
0x1002f0bfc <+236>: ldr x1, [x29, #0x68]
0x1002f0c00 <+240>: ldr x2, [x29, #0x38]
0x1002f0c04 <+244>: mov x3, xzr
0x1002f0c08 <+248>: bl 0x10036f770 ; S_P_CoreLib_System_Threading_Interlocked__CompareExchange_3<System___Canon>
0x1002f0c0c <+252>: str x0, [x29, #0x30]
0x1002f0c10 <+256>: nop
0x1002f0c14 <+260>: ldr x0, [x29, #0x80]
0x1002f0c18 <+264>: bl 0x10000b380 ; __GenericLookupFromType_S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>_GCStaticBase_S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<T_System___Canon>
0x1002f0c1c <+268>: ldr x0, [x0, #0x8]
0x1002f0c20 <+272>: ldp x29, x30, [sp], #0x90
0x1002f0c24 <+276>: ret
0x1002f0c28 <+280>: udf #0x0
0x1002f0c2c <+284>: udf #0x0
(lldb) register read
General Purpose Registers:
x0 = 0x0000000000000000
x1 = 0x00000001000054a8 naot1`__VirtualCall_S_P_CoreLib_System_Type__get_TypeHandle
x2 = 0x000000000000000a
x3 = 0x0000000102006668
x4 = 0x0000000000000020
x5 = 0x0000000000000003
x6 = 0x0000000000000007
x7 = 0x0000000000000000
x8 = 0x00000001011a11f0
x9 = 0x000000016fdff218
x10 = 0x00000001a9734530 libdyld.dylib`tlv_get_addr
x11 = 0x0000000000000001
x12 = 0x00000001005fe7a8 g_ephemeral_high
x13 = 0x0000000102007fd0
x14 = 0x0000000102006638
x15 = 0x0000000102006650
x16 = 0x0000000000000000
x17 = 0x0000000101204290
x18 = 0x0000000000000000
x19 = 0x000000016fdff7a0
x20 = 0x0000000000000001
x21 = 0x0000000100000000 naot1`_mh_execute_header
x22 = 0x0000000000000000
x23 = 0x0000000000000000
x24 = 0x0000000000000000
x25 = 0x0000000000000000
x26 = 0x0000000000000000
x27 = 0x0000000000000000
x28 = 0x0000000000000000
fp = 0x000000016fdff290
lr = 0x00000001002f0ba0 naot1`S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>__Create + 144
sp = 0x000000016fdff290
pc = 0x00000001002f0bb8 naot1`S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>__Create + 168
cpsr = 0x20001000
x0
is null.
BTW, runtime's build.sh also produced ~/projects/runtime/artifacts/packages/Release/Shipping/Microsoft.DotNet.ILCompiler.7.0.0-dev.symbols.nupkg
, but I am not sure if dotnet-sos, dotnet-symbol and friends recognize it OOTB (there were few exports which were required for singlefilehost to work with SOS: https://github.com/dotnet/runtime/commit/b0621e79cc2fe988875dd97a46f131439bdce636 and https://github.com/dotnet/runtime/commit/8c6e3e995af2714bc4c35086afce0cdbf449df1d. That would make things super easy to debug.
I'm still looking at the disassembly, but while I'm doing that - the compiler produces DWARF debug information so you should be getting line numbers and local variables. It's supposed to debug like C++. Make sure ILC is invoked with the -g
option (it should be unless opted out).
Yup, ./obj/Debug/net7.0/osx-arm64/native/naot1.ilc.rsp
has -g
. So the output in lldb is complete/expected. 👍
Can you dump what's in x0 at the spot where we call S_P_CoreLib_System_Type__GetTypeFromHandle
? It should be an address that has a symbol associated with it (image lookup -va the_address_in_x0
should show a symbol for it). If there's no symbol, it's suspicious - it should be pointing to a MethodTable so you can cast it to MethodTable* and dump the contents to see if it looks legit. If it has a symbol, it's legit for sure.
If x0 is already bogus at that point, check x0 before the call to __GenericLookupFromType_S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>_TypeHandle_S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<T_System___Canon>
. That one should also be a MethodTable with a symbol associated.
Yup, ./obj/Debug/net7.0/osx-arm64/native/naot1.ilc.rsp has -g. So the output in lldb is complete/expected. 👍
Just to double check - do you get line debugging and local variables as well?
vtable for String
is the name:
(lldb) r
Process 89722 launched: '/Users/am11/projects/naot1/bin/Debug/net7.0/osx-arm64/publish/naot1' (arm64)
Process 89722 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
frame #0: 0x00000001002f0bb8 naot1`S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>__Create + 168
naot1`S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>__Create:
-> 0x1002f0bb8 <+168>: ldr wzr, [x0]
0x1002f0bbc <+172>: blr x1
0x1002f0bc0 <+176>: str x0, [x29, #0x48]
0x1002f0bc4 <+180>: ldr x0, [x29, #0x48]
Target 0: (naot1) stopped.
(lldb) disassemble -a 0x1002f0bb8
naot1`S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>__Create:
0x1002f0b10 <+0>: stp x29, x30, [sp, #-0x90]!
0x1002f0b14 <+4>: mov x29, sp
0x1002f0b18 <+8>: add x9, x29, #0x28 ; =0x28
0x1002f0b1c <+12>: movi.16b v16, #0x0
0x1002f0b20 <+16>: stp q16, q16, [x9]
0x1002f0b24 <+20>: stp q16, q16, [x9, #0x20]
0x1002f0b28 <+24>: stp xzr, xzr, [x9, #0x40]
0x1002f0b2c <+28>: str xzr, [x9, #0x50]
0x1002f0b30 <+32>: str x0, [x29, #0x88]
0x1002f0b34 <+36>: str x0, [x29, #0x80]
0x1002f0b38 <+40>: ldr x0, [x29, #0x80]
0x1002f0b3c <+44>: bl 0x10000b380 ; __GenericLookupFromType_S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>_GCStaticBase_S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<T_System___Canon>
0x1002f0b40 <+48>: add x0, x0, #0x8 ; =0x8
0x1002f0b44 <+52>: str x0, [x29, #0x78]
0x1002f0b48 <+56>: ldr x0, [x29, #0x80]
0x1002f0b4c <+60>: bl 0x10000bd54 ; __GenericLookupFromType_S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>_TypeHandle_S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<T_System___Canon>
0x1002f0b50 <+64>: bl 0x1002f0af0 ; S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>__get_SupportsGenericIEquatableInterfaces
0x1002f0b54 <+68>: str w0, [x29, #0x74]
0x1002f0b58 <+72>: ldr x0, [x29, #0x78]
0x1002f0b5c <+76>: str x0, [x29, #0x68]
0x1002f0b60 <+80>: ldr w0, [x29, #0x74]
0x1002f0b64 <+84>: cbnz w0, 0x1002f0b88 ; <+120>
0x1002f0b68 <+88>: nop
0x1002f0b6c <+92>: nop
0x1002f0b70 <+96>: nop
0x1002f0b74 <+100>: nop
0x1002f0b78 <+104>: nop
0x1002f0b7c <+108>: ldr x0, [x29, #0x68]
0x1002f0b80 <+112>: str x0, [x29, #0x28]
0x1002f0b84 <+116>: b 0x1002f0b84 ; <+116>
0x1002f0b88 <+120>: ldr x0, [x29, #0x80]
0x1002f0b8c <+124>: bl 0x10000bd60 ; __GenericLookupFromType_S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>_TypeHandle_T_System___Canon
0x1002f0b90 <+128>: bl 0x100261960 ; S_P_CoreLib_Internal_Runtime_CompilerHelpers_LdTokenHelpers__GetRuntimeTypeHandle
0x1002f0b94 <+132>: str x0, [x29, #0x60]
0x1002f0b98 <+136>: ldr x0, [x29, #0x60]
0x1002f0b9c <+140>: bl 0x100140890 ; S_P_CoreLib_System_Type__GetTypeFromHandle
0x1002f0ba0 <+144>: str x0, [x29, #0x58]
0x1002f0ba4 <+148>: adrp x0, -747
0x1002f0ba8 <+152>: add x0, x0, #0x4a8 ; =0x4a8
0x1002f0bac <+156>: str x0, [x29, #0x50]
0x1002f0bb0 <+160>: ldr x0, [x29, #0x58]
0x1002f0bb4 <+164>: ldr x1, [x29, #0x50]
-> 0x1002f0bb8 <+168>: ldr wzr, [x0]
0x1002f0bbc <+172>: blr x1
0x1002f0bc0 <+176>: str x0, [x29, #0x48]
0x1002f0bc4 <+180>: ldr x0, [x29, #0x48]
0x1002f0bc8 <+184>: bl 0x1002596d0 ; S_P_CoreLib_Internal_IntrinsicSupport_EqualityComparerHelpers__GetComparer
0x1002f0bcc <+188>: str x0, [x29, #0x40]
0x1002f0bd0 <+192>: ldr x0, [x29, #0x80]
0x1002f0bd4 <+196>: bl 0x10000c954 ; __GenericLookupFromType_S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>_MethodDictionary_S_P_CoreLib_System_Runtime_CompilerServices_Unsafe__As<S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<T_System___Canon>>
0x1002f0bd8 <+200>: str x0, [x29, #0x20]
0x1002f0bdc <+204>: ldr x0, [x29, #0x20]
0x1002f0be0 <+208>: ldr x1, [x29, #0x40]
0x1002f0be4 <+212>: bl 0x100370490 ; S_P_CoreLib_System_Runtime_CompilerServices_Unsafe__As<System___Canon>
0x1002f0be8 <+216>: str x0, [x29, #0x38]
0x1002f0bec <+220>: ldr x0, [x29, #0x80]
0x1002f0bf0 <+224>: bl 0x10000c948 ; __GenericLookupFromType_S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>_MethodDictionary_S_P_CoreLib_System_Threading_Interlocked__CompareExchange_3<S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<T_System___Canon>>
0x1002f0bf4 <+228>: str x0, [x29, #0x18]
0x1002f0bf8 <+232>: ldr x0, [x29, #0x18]
0x1002f0bfc <+236>: ldr x1, [x29, #0x68]
0x1002f0c00 <+240>: ldr x2, [x29, #0x38]
0x1002f0c04 <+244>: mov x3, xzr
0x1002f0c08 <+248>: bl 0x10036f770 ; S_P_CoreLib_System_Threading_Interlocked__CompareExchange_3<System___Canon>
0x1002f0c0c <+252>: str x0, [x29, #0x30]
0x1002f0c10 <+256>: nop
0x1002f0c14 <+260>: ldr x0, [x29, #0x80]
0x1002f0c18 <+264>: bl 0x10000b380 ; __GenericLookupFromType_S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>_GCStaticBase_S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<T_System___Canon>
0x1002f0c1c <+268>: ldr x0, [x0, #0x8]
0x1002f0c20 <+272>: ldp x29, x30, [sp], #0x90
0x1002f0c24 <+276>: ret
0x1002f0c28 <+280>: udf #0x0
0x1002f0c2c <+284>: udf #0x0
(lldb) b -a 0x1002f0b9c
Breakpoint 1: where = naot1`S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>__Create + 140, address = 0x00000001002f0b9c
(lldb) r
There is a running process, kill it and restart?: [Y/n] Y
Process 89722 exited with status = 9 (0x00000009)
Process 89732 launched: '/Users/am11/projects/naot1/bin/Debug/net7.0/osx-arm64/publish/naot1' (arm64)
Process 89732 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x00000001002f0b9c naot1`S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>__Create + 140
naot1`S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>__Create:
-> 0x1002f0b9c <+140>: bl 0x100140890 ; S_P_CoreLib_System_Type__GetTypeFromHandle
0x1002f0ba0 <+144>: str x0, [x29, #0x58]
0x1002f0ba4 <+148>: adrp x0, -747
0x1002f0ba8 <+152>: add x0, x0, #0x4a8 ; =0x4a8
Target 0: (naot1) stopped.
(lldb) register read x0
x0 = 0x00000001005a0620 vtable for String
(lldb) image lookup -va 0x00000001005a0620
Address: naot1[0x00000001005a0620] (naot1.__DATA.__data + 297760)
Summary: vtable for String
Module: file = "/Users/am11/projects/naot1/bin/Debug/net7.0/osx-arm64/publish/naot1", arch = "arm64"
Symbol: id = {0x00008410}, range = [0x00000001005a0620-0x00000001005a0698), name="vtable for String", mangled="_ZTV6String"
Just to double check - do you get line debugging and local variables as well?
Yup, previously I set breakpoint in Alloc.S
(in the published app with release configuration): b Alloc.S:196
Alloc.S and friends seem to have embedded source with actual code comments.. which is probably too much for release configuration. 😅
Vtable for string is expected. Can step through the process of converting that to a System.Type instance? It should be pretty short. The MethodTable has a pointer to a writable chunk of memory (might be a problem with that reloc?). The writable chunk of memory has a GCHandle to the System.Type instance. It will likely be uninitialized at this point. We should return a valid object instance.
The intrinsic function GetTypeFromEETypePtr was inlined, stepping into visited this method: https://github.com/dotnet/runtime/blob/07e87bc4cb0358f57e7116e047f7d2017b049cf9/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Type.CoreRT.cs#L23 and it jumped back to the caller after failing that null check. It indeed looks related to the virtual call (or perhaps the interlock exchange in GetTypeFromEETypePtrSlow
?):
0x1002f0b9c <+140>: bl 0x100140890 ; S_P_CoreLib_System_Type__GetTypeFromHandle
x0 = 0x00000001005a0620 vtable for String
0x1002f0ba0 <+144>: str x0, [x29, #0x58]
x0 = 0x0000000000000000
0x1002f0ba4 <+148>: adrp x0, -747
x0 = 0x0000000000000000
0x1002f0ba8 <+152>: add x0, x0, #0x4a8 ; =0x4a8
x0 = 0x0000000100005000 naot1`__VirtualCall_S_P_Reflection_Core_System_Reflection_Runtime_MethodInfos_RuntimeConstructorInfo__get_RuntimeParameters + 8
0x1002f0bac <+156>: str x0, [x29, #0x50]
x0 = 0x00000001000054a8 naot1`__VirtualCall_S_P_CoreLib_System_Type__get_TypeHandle
0x1002f0bb0 <+160>: ldr x0, [x29, #0x58]
x0 = 0x00000001000054a8 naot1`__VirtualCall_S_P_CoreLib_System_Type__get_TypeHandle
0x1002f0bb4 <+164>: ldr x1, [x29, #0x50]
x0 = 0x0000000000000000
0x1002f0bb8 <+168>: ldr wzr, [x0] <---- EXC_BAD_ACCESS
x0 = 0x0000000000000000
I think the problem is somewhere in GetTypeFromEETypePtr
. The ldr wzr, [x0]
line is doing a null check because the call that follows it cannot handle null anymore - it's checking that this
for the virtual call is accessible (x0 is supposed to be the this
and it was returned by the GetTypeFromEETypePtr
call).
I expect us to take the SupportsWritableData
branch, followed by the !IsAllocated
branch, into GetTypeFromEETypePtrSlow
.
That one should return a valid object instance (it should be non-null, and if you cast that value to void**
and dereference it once, there should be a symbol associated with it (the first field of an object instance is a pointer to its MethodTable (aka vtable). Something is going wrong around there.
It reaches Unsafe.As<T>
call on line 35, which seems to be returning null (in X0, assuming it is following standard aarch64 calling convention).
(lldb) c
Process 97360 resuming
Process 97360 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 3.1
frame #0: 0x000000010014095c naot1`S_P_CoreLib_System_Type__GetTypeFromEETypePtr + 108
naot1`S_P_CoreLib_System_Type__GetTypeFromEETypePtr:
-> 0x10014095c <+108>: bl 0x100370490 ; S_P_CoreLib_System_Runtime_CompilerServices_Unsafe__As<System___Canon>
0x100140960 <+112>: str x0, [x29, #0x18]
0x100140964 <+116>: ldr x0, [x29, #0x18]
0x100140968 <+120>: ldp x29, x30, [sp], #0x60
Target 0: (naot1) stopped.
(lldb) register read
General Purpose Registers:
x0 = 0x00000001005833f8 __GenericDict_S_P_CoreLib_System_Runtime_CompilerServices_Unsafe__As<S_P_CoreLib_System_Type>
x1 = 0x0000000000000000
x2 = 0x000000000000000a
x3 = 0x0000000102806668
x4 = 0x0000000000000020
x5 = 0x0000000000000003
x6 = 0x0000000000000001
x7 = 0x0000000000000000
x8 = 0x00000001011a11f0
x9 = 0x000000016fdff218
x10 = 0x00000001a9734530 libdyld.dylib`tlv_get_addr
x11 = 0x0000000000000001
x12 = 0x00000001005fe7a8 g_ephemeral_high
x13 = 0x0000000102807fd0
x14 = 0x0000000102806638
x15 = 0x0000000102806650
x16 = 0x0000000000000000
x17 = 0x0000000101304810
x18 = 0x0000000000000000
x19 = 0x000000016fdff7a0
x20 = 0x0000000000000001
x21 = 0x0000000100000000 naot1`_mh_execute_header
x22 = 0x0000000000000000
x23 = 0x0000000000000000
x24 = 0x0000000000000000
x25 = 0x0000000000000000
x26 = 0x0000000000000000
x27 = 0x0000000000000000
x28 = 0x0000000000000000
fp = 0x000000016fdff200
lr = 0x000000010014094c naot1`S_P_CoreLib_System_Type__GetTypeFromEETypePtr + 92
sp = 0x000000016fdff200
pc = 0x000000010014095c naot1`S_P_CoreLib_System_Type__GetTypeFromEETypePtr + 108
cpsr = 0x20001000
(lldb) n
Process 97360 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = instruction step over
frame #0: 0x0000000100140960 naot1`S_P_CoreLib_System_Type__GetTypeFromEETypePtr + 112
naot1`S_P_CoreLib_System_Type__GetTypeFromEETypePtr:
-> 0x100140960 <+112>: str x0, [x29, #0x18]
0x100140964 <+116>: ldr x0, [x29, #0x18]
0x100140968 <+120>: ldp x29, x30, [sp], #0x60
0x10014096c <+124>: ret
Target 0: (naot1) stopped.
(lldb) register read
General Purpose Registers:
x0 = 0x0000000000000000
x1 = 0x0000000000000000
x2 = 0x000000000000000a
x3 = 0x0000000102806668
x4 = 0x0000000000000020
x5 = 0x0000000000000003
x6 = 0x0000000000000001
x7 = 0x0000000000000000
x8 = 0x00000001011a11f0
x9 = 0x000000016fdff218
x10 = 0x00000001a9734530 libdyld.dylib`tlv_get_addr
x11 = 0x0000000000000001
x12 = 0x00000001005fe7a8 g_ephemeral_high
x13 = 0x0000000102807fd0
x14 = 0x0000000102806638
x15 = 0x0000000102806650
x16 = 0x0000000000000000
x17 = 0x0000000101304810
x18 = 0x0000000000000000
x19 = 0x000000016fdff7a0
x20 = 0x0000000000000001
x21 = 0x0000000100000000 naot1`_mh_execute_header
x22 = 0x0000000000000000
x23 = 0x0000000000000000
x24 = 0x0000000000000000
x25 = 0x0000000000000000
x26 = 0x0000000000000000
x27 = 0x0000000000000000
x28 = 0x0000000000000000
fp = 0x000000016fdff200
lr = 0x0000000100140960 naot1`S_P_CoreLib_System_Type__GetTypeFromEETypePtr + 112
sp = 0x000000016fdff200
pc = 0x0000000100140960 naot1`S_P_CoreLib_System_Type__GetTypeFromEETypePtr + 112
cpsr = 0x20001000
Didn't knew that in lldb, gui
command opens up a TUI 🤩
(bit unfortunately that we don't have variables in the upper frames)
Can you try flipping SupportsRelativePointers to false again? I think something is wrong with the reloc from read-only section to read write section.
I tried it before but it wasn't passing withdotnet publish -c Release
. ld was failing like:
...
ld: warning: pointer not aligned at address 0x1003C0482 (___external_NativeReferences_references_End + 56 from obj/release/net7.0/osx-arm64/native/naot1.o)
ld: warning: pointer not aligned at address 0x1003C047A (___external_NativeReferences_references_End + 48 from obj/release/net7.0/osx-arm64/native/naot1.o)
ld: warning: pointer not aligned at address 0x1003C0472 (___external_NativeReferences_references_End + 40 from obj/release/net7.0/osx-arm64/native/naot1.o)
ld: warning: pointer not aligned at address 0x1003C046A (___external_NativeReferences_references_End + 32 from obj/release/net7.0/osx-arm64/native/naot1.o)
ld: warning: pointer not aligned at address 0x1003C0462 (___external_NativeReferences_references_End + 24 from obj/release/net7.0/osx-arm64/native/naot1.o)
ld: warning: pointer not aligned at address 0x1003C045A (___external_NativeReferences_references_End + 16 from obj/release/net7.0/osx-arm64/native/naot1.o)
ld: warning: pointer not aligned at address 0x1003C0452 (___external_NativeReferences_references_End + 8 from obj/release/net7.0/osx-arm64/native/naot1.o)
ld: warning: pointer not aligned at address 0x1003C044A (___external_NativeReferences_references_End + 0 from obj/release/net7.0/osx-arm64/native/naot1.o)
ld: unaligned pointer(s) for architecture arm64
... tons of these
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Now I have tried with Debug, and it builds. Unfortuately lldb does not hit the breakpoints anymore.
This is what I have (note that it still fails in GetTypeFromEETypePtr call):
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
frame #0: 0x00000001a96f99b8 libsystem_kernel.dylib`__pthread_kill + 8
libsystem_kernel.dylib`__pthread_kill:
-> 0x1a96f99b8 <+8>: b.lo 0x1a96f99d8 ; <+40>
0x1a96f99bc <+12>: pacibsp
0x1a96f99c0 <+16>: stp x29, x30, [sp, #-0x10]!
0x1a96f99c4 <+20>: mov x29, sp
Target 0: (naot1) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
* frame #0: 0x00000001a96f99b8 libsystem_kernel.dylib`__pthread_kill + 8
frame #1: 0x00000001a972ceb0 libsystem_pthread.dylib`pthread_kill + 288
frame #2: 0x00000001a966a314 libsystem_c.dylib`abort + 164
frame #3: 0x0000000100065ea4 naot1`SystemNative_Abort at pal_threading.c:286:5 [opt]
frame #4: 0x000000010025eed8 naot1`S_P_CoreLib_Interop_Sys__Abort + 40
frame #5: 0x000000010013c85c naot1`S_P_CoreLib_System_RuntimeExceptionHelpers__FailFast_1 + 268
frame #6: 0x000000010013c514 naot1`S_P_CoreLib_System_RuntimeExceptionHelpers__FailFast + 36
frame #7: 0x00000001001294f4 naot1`S_P_CoreLib_System_Environment__FailFast + 20
frame #8: 0x00000001000a9cc4 naot1`S_P_TypeLoader_Internal_Runtime_TypeLoader_NativeFormatModuleInfoEnumerator___ctor + 196
frame #9: 0x00000001000a9bd8 naot1`S_P_TypeLoader_Internal_Runtime_TypeLoader_NativeFormatModuleInfoEnumerable__GetEnumerator + 56
frame #10: 0x00000001000ce288 naot1`S_P_TypeLoader_Internal_Runtime_TypeLoader_TypeLoaderEnvironment_NamedTypeRuntimeTypeHandleToMetadataHashtable__CreateValueFromKey + 136
frame #11: 0x000000010029f5c4 naot1`S_P_CoreLib_Internal_TypeSystem_LockFreeReaderHashtable_2<S_P_CoreLib_System_RuntimeTypeHandle__System___Canon>__CreateValueAndEnsureValueIsInTable + 68
frame #12: 0x000000010029f63c naot1`S_P_CoreLib_Internal_TypeSystem_LockFreeReaderHashtable_2<S_P_CoreLib_System_RuntimeTypeHandle__System___Canon>__GetOrCreateValue + 76
frame #13: 0x00000001000bef04 naot1`S_P_TypeLoader_Internal_Runtime_TypeLoader_TypeLoaderEnvironment__TryGetMetadataForNamedType + 52
frame #14: 0x00000001000e52d4 naot1`S_P_Reflection_Execution_Internal_Reflection_Execution_ExecutionEnvironmentImplementation__TryGetMetadataForNamedType + 52
frame #15: 0x00000001000f02ac naot1`S_P_Reflection_Core_Internal_Reflection_Core_Execution_ExecutionDomain__GetNamedTypeForHandle + 92
frame #16: 0x00000001000e8bd4 naot1`S_P_Reflection_Execution_Internal_Reflection_Execution_ReflectionExecutionDomainCallbacksImplementation__GetNamedTypeForHandle + 52
frame #17: 0x0000000100255960 naot1`S_P_CoreLib_Internal_Reflection_Core_NonPortable_RuntimeTypeUnifier__GetRuntimeTypeBypassCache + 288
frame #18: 0x000000010027fd6c naot1`S_P_CoreLib_Internal_Reflection_Core_NonPortable_RuntimeTypeUnifier_RuntimeTypeHandleToTypeCache__Factory + 60
frame #19: 0x00000001002c1e4c naot1`S_P_CoreLib_System_Collections_Concurrent_ConcurrentUnifierW_2<IntPtr__System___Canon>__GetOrAdd + 156
frame #20: 0x000000010025582c naot1`S_P_CoreLib_Internal_Reflection_Core_NonPortable_RuntimeTypeUnifier__GetRuntimeTypeForEEType + 60
frame #21: 0x000000010013d8d4 naot1`S_P_CoreLib_System_Type__GetTypeFromEETypePtr + 164
frame #22: 0x000000010013d808 naot1`S_P_CoreLib_System_Type__GetTypeFromHandle + 56
frame #23: 0x00000001002d6c48 naot1`S_P_CoreLib_System_Runtime_Intrinsics_Scalar_1<UIntPtr>__get_AllBitsSet + 72
frame #24: 0x00000001002d629c naot1`S_P_CoreLib_System_Numerics_Vector_1<UIntPtr>__get_AllBitsSet + 12
frame #25: 0x000000010034f004 naot1`S_P_CoreLib_System_Numerics_Vector__LessThanOrEqualAll<UInt16> + 36
frame #26: 0x00000001001e0bbc naot1`S_P_CoreLib_System_Text_ASCIIUtility__GetIndexOfFirstNonAsciiChar_Default + 172
frame #27: 0x00000001001e0ad8 naot1`S_P_CoreLib_System_Text_ASCIIUtility__GetIndexOfFirstNonAsciiChar + 40
frame #28: 0x00000001001fdf98 naot1`S_P_CoreLib_System_Text_Unicode_Utf16Utility__GetPointerToFirstInvalidChar + 72
frame #29: 0x00000001001fa448 naot1`S_P_CoreLib_System_Text_UTF8Encoding__GetByteCountFast + 72
frame #30: 0x00000001001fa394 naot1`S_P_CoreLib_System_Text_UTF8Encoding__GetByteCountCommon + 84
frame #31: 0x00000001001fa2c0 naot1`S_P_CoreLib_System_Text_UTF8Encoding__GetByteCount_0 + 160
frame #32: 0x00000001001e9fb0 naot1`S_P_CoreLib_System_Text_Encoding__GetBytes_2 + 80
frame #33: 0x0000000100278bc0 naot1`S_P_CoreLib_System_Text_UTF8Encoding_UTF8EncodingSealed__GetBytes + 96
frame #34: 0x000000010027f424 naot1`S_P_CoreLib_Internal_Console_Error__Write + 68
frame #35: 0x000000010013c848 naot1`S_P_CoreLib_System_RuntimeExceptionHelpers__FailFast_1 + 248
frame #36: 0x000000010013c514 naot1`S_P_CoreLib_System_RuntimeExceptionHelpers__FailFast + 36
frame #37: 0x00000001001294f4 naot1`S_P_CoreLib_System_Environment__FailFast + 20
frame #38: 0x00000001000a9cc4 naot1`S_P_TypeLoader_Internal_Runtime_TypeLoader_NativeFormatModuleInfoEnumerator___ctor + 196
frame #39: 0x00000001000a9bd8 naot1`S_P_TypeLoader_Internal_Runtime_TypeLoader_NativeFormatModuleInfoEnumerable__GetEnumerator + 56
frame #40: 0x00000001000ce288 naot1`S_P_TypeLoader_Internal_Runtime_TypeLoader_TypeLoaderEnvironment_NamedTypeRuntimeTypeHandleToMetadataHashtable__CreateValueFromKey + 136
frame #41: 0x000000010029f5c4 naot1`S_P_CoreLib_Internal_TypeSystem_LockFreeReaderHashtable_2<S_P_CoreLib_System_RuntimeTypeHandle__System___Canon>__CreateValueAndEnsureValueIsInTable + 68
frame #42: 0x000000010029f63c naot1`S_P_CoreLib_Internal_TypeSystem_LockFreeReaderHashtable_2<S_P_CoreLib_System_RuntimeTypeHandle__System___Canon>__GetOrCreateValue + 76
frame #43: 0x00000001000bef04 naot1`S_P_TypeLoader_Internal_Runtime_TypeLoader_TypeLoaderEnvironment__TryGetMetadataForNamedType + 52
frame #44: 0x00000001000e52d4 naot1`S_P_Reflection_Execution_Internal_Reflection_Execution_ExecutionEnvironmentImplementation__TryGetMetadataForNamedType + 52
frame #45: 0x00000001000f02ac naot1`S_P_Reflection_Core_Internal_Reflection_Core_Execution_ExecutionDomain__GetNamedTypeForHandle + 92
frame #46: 0x00000001000e8bd4 naot1`S_P_Reflection_Execution_Internal_Reflection_Execution_ReflectionExecutionDomainCallbacksImplementation__GetNamedTypeForHandle + 52
frame #47: 0x0000000100255960 naot1`S_P_CoreLib_Internal_Reflection_Core_NonPortable_RuntimeTypeUnifier__GetRuntimeTypeBypassCache + 288
frame #48: 0x000000010027fd6c naot1`S_P_CoreLib_Internal_Reflection_Core_NonPortable_RuntimeTypeUnifier_RuntimeTypeHandleToTypeCache__Factory + 60
frame #49: 0x00000001002c1e4c naot1`S_P_CoreLib_System_Collections_Concurrent_ConcurrentUnifierW_2<IntPtr__System___Canon>__GetOrAdd + 156
frame #50: 0x000000010025582c naot1`S_P_CoreLib_Internal_Reflection_Core_NonPortable_RuntimeTypeUnifier__GetRuntimeTypeForEEType + 60
frame #51: 0x000000010013d8d4 naot1`S_P_CoreLib_System_Type__GetTypeFromEETypePtr + 164
frame #52: 0x000000010013d808 naot1`S_P_CoreLib_System_Type__GetTypeFromHandle + 56
frame #53: 0x000000010030b228 naot1`S_P_CoreLib_System_Collections_Generic_Dictionary_2<System___Canon__System___Canon>___ctor_2 + 200
frame #54: 0x000000010030b11c naot1`S_P_CoreLib_System_Collections_Generic_Dictionary_2<System___Canon__System___Canon>___ctor + 28
frame #55: 0x0000000100120354 naot1`S_P_CoreLib_System_AppContext__SetData + 116
frame #56: 0x00000001003149dc naot1`Internal_CompilerGenerated__Module___SetAppContextSwitches + 28
frame #57: 0x0000000100314afc naot1`__managed__Main + 60
frame #58: 0x000000010000aea4 naot1`main(argc=1, argv=0x000000016fdff7a0) at main.cpp:205:18 [opt]
frame #59: 0x0000000100e1d0f4 dyld`start + 520
breakpoints not working with SupportsRelativePointers:false makes it a useless option for me. 😞
I have a feeling that we would need to revisit encodings in methods like EmitLDR() etc. in ARM64Emitter.cs to see if we need to handle values differently for macho (https://github.com/below/HelloSilicon#chapter-4-controlling-programm-flow). Do you have any suggestions about the best was to find out if it is in fact some instruction encoding issue? I was thinking about something like objdump'ing another program like dotnet
or corerun
and comparing those encodings with what we are emitting in ARM64Emitter.
Seems like this comment: https://github.com/dotnet/runtime/blob/041933fd086f69f839cf38733dd56a1ea9f09866/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/CallingConventions.cs#L6 is outdated ever since this commit was merged https://github.com/dotnet/runtime/commit/648437b1b4db6536ae33763b6c9178287c0a52bd. It added osx-arm64 support in the VM, and at the same time refactored the "slot" -based units to bytes/offsets for all architectures. I'll try to update it without unit conversions.
aside - line 26 of CallingConventions.cs seems to have a bug, UNIXAMD64
is not a defined constant in that project (or anywhere else in the repo)?
ld: warning: pointer not aligned at address 0x1003C0482 (___external_NativeReferences_references_End + 56 from obj/release/net7.0/osx-arm64/native/naot1.o)
Should be fixed by #67516.
breakpoints not working with SupportsRelativePointers:false makes it a useless option for me. 😞
That is very odd. SupportsRelativePointers
affects very few things in the compiler. I would not expect it to affect debugging.
aside - line 26 of CallingConventions.cs seems to have a bug, UNIXAMD64 is not a defined constant in that project (or anywhere else in the repo)?
CallingConventions.cs is only used in extremely rare circumstances (maybe only when reflection invoking a method with more than 256 parameters). It was written for .NET Native that is Windows only (where it was used more often). You can ignore it.
Going back to the original failure with SupportsRelativePointers=true, can you drill into why GCHandle.IsAllocated returns true? I would expect this to initially be false - the data we're reading from (where the GCHandle is placed) is in the .bss
section (that's the special thing about it) and should be zero-initialized. It should not point to an object.
can you drill into why GCHandle.IsAllocated returns true?
bss section is showing up in the app's main module (third-last):
(lldb) image dump sections naot1
Sections for '/Users/am11/projects/naot1/bin/Debug/net7.0/osx-arm64/publish/naot1' (arm64):
SectID Type Load Address Perm File Off. File Size Flags Section Name
---------- ---------------- --------------------------------------- ---- ---------- ---------- ---------- ----------------------------
0x00000100 container [0x0000000000000000-0x0000000100000000)* --- 0x00000000 0x00000000 0x00000000 naot1.__PAGEZERO
0x00000200 container [0x0000000100000000-0x000000010048c000) r-x 0x00000000 0x0048c000 0x00000000 naot1.__TEXT
0x00000001 code [0x0000000100004904-0x000000010007b3e8) r-x 0x00004904 0x00076ae4 0x80000400 naot1.__TEXT.__text
0x00000002 code [0x000000010007b3e8-0x000000010007bd24) r-x 0x0007b3e8 0x0000093c 0x80000408 naot1.__TEXT.__stubs
0x00000003 regular [0x000000010007bd24-0x000000010007bd30) r-x 0x0007bd24 0x0000000c 0x00000016 naot1.__TEXT.__init_offsets
0x00000004 regular [0x000000010007bd30-0x00000001003841e8) r-x 0x0007bd30 0x003084b8 0x00000000 naot1.__TEXT.__managedcode
0x00000005 regular [0x00000001003841f0-0x0000000100486632) r-x 0x003841f0 0x00102442 0x00000000 naot1.__TEXT.__const
0x00000006 regular [0x0000000100486634-0x00000001004884dc) r-x 0x00486634 0x00001ea8 0x00000000 naot1.__TEXT.__unbox
0x00000007 data-cstr [0x00000001004884dc-0x000000010048b753) r-x 0x004884dc 0x00003277 0x00000002 naot1.__TEXT.__cstring
0x00000008 compact-unwind [0x000000010048b754-0x000000010048bb34) r-x 0x0048b754 0x000003e0 0x00000000 naot1.__TEXT.__unwind_info
0x00000009 eh-frame [0x000000010048bb38-0x000000010048bff8) r-x 0x0048bb38 0x000004c0 0x00000000 naot1.__TEXT.__eh_frame
0x00000300 container [0x000000010048c000-0x00000001004cc000) rw- 0x0048c000 0x00040000 0x00000010 naot1.__DATA_CONST
0x0000000a data-ptrs [0x000000010048c000-0x00000001004c76a8) rw- 0x0048c000 0x0003b6a8 0x00000006 naot1.__DATA_CONST.__got
0x0000000b regular [0x00000001004c76a8-0x00000001004c8410) rw- 0x004c76a8 0x00000d68 0x00000000 naot1.__DATA_CONST.__const
0x00000400 container [0x00000001004cc000-0x0000000100614000) rw- 0x004cc000 0x00138000 0x00000000 naot1.__DATA
0x0000000c regular [0x00000001004cc000-0x0000000100557a9a) rw- 0x004cc000 0x0008ba9a 0x00000000 naot1.__DATA..corert_eh_table
0x0000000d data [0x0000000100557b00-0x00000001005fff68) rw- 0x00557b00 0x000a8468 0x00000000 naot1.__DATA.__data
0x0000000e regular [0x00000001005fff68-0x00000001005fff70) rw- 0x005fff68 0x00000008 0x00000000 naot1.__DATA.__modules
0x0000000f regular [0x00000001005fff70-0x0000000100600018) rw- 0x005fff70 0x000000a8 0x00000013 naot1.__DATA.__thread_vars
0x00000010 regular [0x0000000100600018-0x0000000100600100) rw- 0x00600018 0x000000e8 0x00000011 naot1.__DATA.__thread_data
0x00000011 regular [0x0000000100600100-0x0000000100600129) rw- 0x00000000 0x00000000 0x00000012 naot1.__DATA.__thread_bss
0x00000012 zero-fill [0x0000000100600130-0x0000000100609cf8) rw- 0x00000000 0x00000000 0x00000001 naot1.__DATA.__bss
0x00000013 zero-fill [0x0000000100609cf8-0x0000000100610450) rw- 0x00000000 0x00000000 0x00000001 naot1.__DATA.__common
0x00000500 container [0x0000000100614000-0x0000000100f14000) r-- 0x00604000 0x008fca12 0x00000000 naot1.__LINKEDIT
When IsAllocated is visited from GetTypeFromEETypePtr
, the state of registers look like this:
(lldb) disas
naot1`S_P_CoreLib_System_Runtime_InteropServices_GCHandle__get_IsAllocated:
-> 0x100239720 <+0>: stp x29, x30, [sp, #-0x20]!
0x100239724 <+4>: mov x29, sp
0x100239728 <+8>: str x0, [x29, #0x18]
0x10023972c <+12>: ldr x0, [x29, #0x18]
0x100239730 <+16>: ldr x0, [x0]
0x100239734 <+20>: mov w1, wzr
0x100239738 <+24>: sxtw x1, w1
0x10023973c <+28>: cmp x0, x1
0x100239740 <+32>: cset x0, hi
0x100239744 <+36>: ldp x29, x30, [sp], #0x20
0x100239748 <+40>: ret
0x10023974c <+44>: udf #0x0
(lldb) register read
General Purpose Registers:
x0 = 0x00000001004c3618 (void *)0x0000000100608660: __writableDataString
x1 = 0x00000001004c3618 (void *)0x0000000100608660: __writableDataString
x2 = 0x000000000000000a
x3 = 0x0000000102806668
x4 = 0x0000000000000020
x5 = 0x0000000000000003
x6 = 0x0000000000000001
x7 = 0x0000000000000000
x8 = 0x00000001011a11f0
x9 = 0x000000016fdff218
x10 = 0x00000001a9734530 libdyld.dylib`tlv_get_addr
x11 = 0x0000000000000001
x12 = 0x00000001005fe7a8 g_ephemeral_high
x13 = 0x0000000102807fd0
x14 = 0x0000000102806638
x15 = 0x0000000102806650
x16 = 0x0000000000000000
x17 = 0x0000000101304810
x18 = 0x0000000000000000
x19 = 0x000000016fdff7a0
x20 = 0x0000000000000001
x21 = 0x0000000100000000 naot1`_mh_execute_header
x22 = 0x0000000000000000
x23 = 0x0000000000000000
x24 = 0x0000000000000000
x25 = 0x0000000000000000
x26 = 0x0000000000000000
x27 = 0x0000000000000000
x28 = 0x0000000000000000
fp = 0x000000016fdff200
lr = 0x0000000100130108 naot1`S_P_CoreLib_System_Type__GetTypeFromEETypePtr + 72
sp = 0x000000016fdff200
pc = 0x0000000100239720 naot1`S_P_CoreLib_System_Runtime_InteropServices_GCHandle__get_IsAllocated
cpsr = 0x60001000
when the cursor reaches 0x100239734 <+20>: 0x2a1f03e1 mov w1, wzr
, it looks like:
(lldb) n
Process 38694 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = instruction step over
frame #0: 0x0000000100239734 naot1`S_P_CoreLib_System_Runtime_InteropServices_GCHandle__get_IsAllocated + 20
naot1`S_P_CoreLib_System_Runtime_InteropServices_GCHandle__get_IsAllocated:
-> 0x100239734 <+20>: mov w1, wzr
0x100239738 <+24>: sxtw x1, w1
0x10023973c <+28>: cmp x0, x1
0x100239740 <+32>: cset x0, hi
Target 0: (naot1) stopped.
(lldb) register read
General Purpose Registers:
x0 = 0x0000000100608660 naot1`__writableDataString
x1 = 0x00000001004c3618 (void *)0x0000000100608660: __writableDataString
x2 = 0x000000000000000a
x3 = 0x0000000102806668
x4 = 0x0000000000000020
x5 = 0x0000000000000003
x6 = 0x0000000000000001
x7 = 0x0000000000000000
x8 = 0x00000001011a11f0
x9 = 0x000000016fdff218
x10 = 0x00000001a9734530 libdyld.dylib`tlv_get_addr
x11 = 0x0000000000000001
x12 = 0x00000001005fe7a8 g_ephemeral_high
x13 = 0x0000000102807fd0
x14 = 0x0000000102806638
x15 = 0x0000000102806650
x16 = 0x0000000000000000
x17 = 0x0000000101304810
x18 = 0x0000000000000000
x19 = 0x000000016fdff7a0
x20 = 0x0000000000000001
x21 = 0x0000000100000000 naot1`_mh_execute_header
x22 = 0x0000000000000000
x23 = 0x0000000000000000
x24 = 0x0000000000000000
x25 = 0x0000000000000000
x26 = 0x0000000000000000
x27 = 0x0000000000000000
x28 = 0x0000000000000000
fp = 0x000000016fdff1e0
lr = 0x0000000100130108 naot1`S_P_CoreLib_System_Type__GetTypeFromEETypePtr + 72
sp = 0x000000016fdff1e0
pc = 0x0000000100239734 naot1`S_P_CoreLib_System_Runtime_InteropServices_GCHandle__get_IsAllocated + 20
cpsr = 0x60001000
then x1 becomes zero and the subsequent comparison fails returning true
.
Ok, looks like we have a case of a wrong relocation. When we're in GCHandle__get_IsAllocated
, this
in x0
is 0x00000001004c3618
, but from the memory map you posted above, that address is part of naot1.__DATA_CONST.__got
. So we're in global offset table, but the code doesn't expect having to dereference the pointer (GOT table is a table of indirections).
So object writer generated a GOT relocation for something that should just store the address of the destination directly. GOT requires an extra dereference to access what the reloc points to.
This might be responsible for the problem: https://github.com/dotnet/llvm-project/pull/185/files#diff-3dd92a728cef8bf36a3e8104cbfcf2b9b901abff46340d48f5cf0a02d3274a2aR455-R456
Trying to figure out how does the RelocationInfoType
map to section? e.g. changing ARM64_RELOC_POINTER_TO_GOT
to ARM64_RELOC_PAGE21
puts x0 into __DATA.__data
. Not sure what makes it place in bss. 🤔
bss is a property of the symbol definition (the symbol that the reloc points to is defined in the bss section), not a property of the reloc to the symbol.
__data might be fine too; I don't know what the linker is doing with this. The important bit is that will be all zeros, the GCHandle will be unallocated and we can write a valid GC handle in that location.
AFAIK ARM64_RELOC_PAGE21 is one of the weirdo relocation types that are to satisfy oddities in ARM instruction encoding. We wouldn't be using them for the data structures.
I'm a bit at loss for where to look next. Normally I would write a piece of C++ that uses the reloc type I'm after and just massage things to emit it, but I don't know if C++ uses 32bit relative pointers for anything, so I can't point you to that. It may well be that the solution will be to do SupportsRelativePointers:false and get that one going instead.
FWIW, the previous iteration (where we ended up with the GOT reloc), looked fine, except for the GOT bit. It was 32 bit, it looked like everything else was pointing to the right thing, but it shouldn't have instructed ld to create GOT entry for it.
bss is a property of the symbol definition (the symbol that the reloc points to is defined in the bss section), not a property of the reloc to the symbol.
Ah, this is correct. I am not sure how/why it is classified as IMAGE_REL_BASED_RELPTR32
to begin with? Is that expected? Note that in addition to these: https://github.com/dotnet/llvm-project/blob/495e374f8fb370a0bf45304fbc835dbf78f2949d/llvm/tools/objwriter/objwriter.cpp#L248-L258, SectionKind.h
also has:
static SectionKind getBSS() { return get(BSS); }
static SectionKind getBSSLocal() { return get(BSSLocal); }
static SectionKind getBSSExtern() { return get(BSSExtern); }
if that's something we want to wire up via enum CustomSectionAttributes
(in objwriter.h
), it is possible.
I have made two changes:
main
after a weekwith that, although it still fails at the same spot, we get x0 in __DATA.__data
section; with ARM64_RELOC_POINTER_TO_GOT
:
(lldb) image dump sections naot1
Sections for '/Users/am11/projects/naot1/bin/Debug/net7.0/osx-arm64/publish/naot1' (arm64):
SectID Type Load Address Perm File Off. File Size Flags Section Name
---------- ---------------- --------------------------------------- ---- ---------- ---------- ---------- ----------------------------
0x00000100 container [0x0000000000000000-0x0000000100000000)* --- 0x00000000 0x00000000 0x00000000 naot1.__PAGEZERO
0x00000200 container [0x0000000100000000-0x0000000100488000) r-x 0x00000000 0x00488000 0x00000000 naot1.__TEXT
0x00000001 code [0x0000000100001274-0x0000000100077c78) r-x 0x00001274 0x00076a04 0x80000400 naot1.__TEXT.__text
0x00000002 code [0x0000000100077c78-0x00000001000785b4) r-x 0x00077c78 0x0000093c 0x80000408 naot1.__TEXT.__stubs
0x00000003 regular [0x00000001000785b4-0x00000001000785c0) r-x 0x000785b4 0x0000000c 0x00000016 naot1.__TEXT.__init_offsets
0x00000004 regular [0x00000001000785c0-0x0000000100380a88) r-x 0x000785c0 0x003084c8 0x00000000 naot1.__TEXT.__managedcode
0x00000005 regular [0x0000000100380a90-0x0000000100482642) r-x 0x00380a90 0x00101bb2 0x00000000 naot1.__TEXT.__const
0x00000006 regular [0x0000000100482644-0x00000001004844e4) r-x 0x00482644 0x00001ea0 0x00000000 naot1.__TEXT.__unbox
0x00000007 data-cstr [0x00000001004844e4-0x000000010048775b) r-x 0x004844e4 0x00003277 0x00000002 naot1.__TEXT.__cstring
0x00000008 compact-unwind [0x000000010048775c-0x0000000100487b3c) r-x 0x0048775c 0x000003e0 0x00000000 naot1.__TEXT.__unwind_info
0x00000009 eh-frame [0x0000000100487b40-0x0000000100488000) r-x 0x00487b40 0x000004c0 0x00000000 naot1.__TEXT.__eh_frame
0x00000300 container [0x0000000100488000-0x00000001004c0000) rw- 0x00488000 0x00038000 0x00000010 naot1.__DATA_CONST
0x0000000a data-ptrs [0x0000000100488000-0x00000001004bcc30) rw- 0x00488000 0x00034c30 0x00000006 naot1.__DATA_CONST.__got
0x0000000b regular [0x00000001004bcc30-0x00000001004bd998) rw- 0x004bcc30 0x00000d68 0x00000000 naot1.__DATA_CONST.__const
0x00000400 container [0x00000001004c0000-0x0000000100608000) rw- 0x004c0000 0x00138000 0x00000000 naot1.__DATA
0x0000000c regular [0x00000001004c0000-0x000000010054bb23) rw- 0x004c0000 0x0008bb23 0x00000000 naot1.__DATA..corert_eh_table
0x0000000d data [0x000000010054bc00-0x00000001005f4068) rw- 0x0054bc00 0x000a8468 0x00000000 naot1.__DATA.__data
0x0000000e regular [0x00000001005f4068-0x00000001005f4070) rw- 0x005f4068 0x00000008 0x00000000 naot1.__DATA.__modules
0x0000000f regular [0x00000001005f4070-0x00000001005f4118) rw- 0x005f4070 0x000000a8 0x00000013 naot1.__DATA.__thread_vars
0x00000010 regular [0x00000001005f4118-0x00000001005f4200) rw- 0x005f4118 0x000000e8 0x00000011 naot1.__DATA.__thread_data
0x00000011 regular [0x00000001005f4200-0x00000001005f4229) rw- 0x00000000 0x00000000 0x00000012 naot1.__DATA.__thread_bss
0x00000012 zero-fill [0x00000001005f4230-0x00000001005fddf8) rw- 0x00000000 0x00000000 0x00000001 naot1.__DATA.__bss
0x00000013 zero-fill [0x00000001005fddf8-0x0000000100604550) rw- 0x00000000 0x00000000 0x00000001 naot1.__DATA.__common
0x00000500 container [0x0000000100608000-0x0000000100f04000) r-- 0x005f8000 0x008f8e72 0x00000000 naot1.__LINKEDIT
(lldb) si
Process 46176 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = instruction step into
frame #0: 0x000000010036c060 naot1`S_P_CoreLib_System_Runtime_CompilerServices_Unsafe__As<System___Canon>
naot1`S_P_CoreLib_System_Runtime_CompilerServices_Unsafe__As<System___Canon>:
-> 0x10036c060 <+0>: stp x29, x30, [sp, #-0x20]!
0x10036c064 <+4>: mov x29, sp
0x10036c068 <+8>: str x0, [x29, #0x18]
0x10036c06c <+12>: str x1, [x29, #0x10]
Target 0: (naot1) stopped.
(lldb) register read
General Purpose Registers:
x0 = 0x0000000100577088 __GenericDict_S_P_CoreLib_System_Runtime_CompilerServices_Unsafe__As<S_P_CoreLib_System_Type>
x1 = 0x0000000000000000
x2 = 0x000000000000000a
x3 = 0x0000000102806650
x4 = 0x0000000000000020
x5 = 0x0000000000000003
x6 = 0x0000000000000001
x7 = 0x0000000000000000
x8 = 0x00000001011911f0
x9 = 0x000000016fdff218
x10 = 0x00000001a9734530 libdyld.dylib`tlv_get_addr
x11 = 0x0000000000000001
x12 = 0x00000001005f28a8 g_ephemeral_high
x13 = 0x0000000102807fd0
x14 = 0x0000000102806620
x15 = 0x0000000102806638
x16 = 0x0000000000000000
x17 = 0x0000000101304630
x18 = 0x0000000000000000
x19 = 0x000000016fdff7a0
x20 = 0x0000000000000001
x21 = 0x0000000100000000 naot1`_mh_execute_header
x22 = 0x0000000000000000
x23 = 0x0000000000000000
x24 = 0x0000000000000000
x25 = 0x0000000000000000
x26 = 0x0000000000000000
x27 = 0x0000000000000000
x28 = 0x0000000000000000
fp = 0x000000016fdff200
lr = 0x00000001000ad580 naot1`S_P_CoreLib_System_Type__GetTypeFromEETypePtr + 112
sp = 0x000000016fdff200
pc = 0x000000010036c060 naot1`S_P_CoreLib_System_Runtime_CompilerServices_Unsafe__As<System___Canon>
cpsr = 0x20001000
(lldb) disas
naot1`S_P_CoreLib_System_Runtime_CompilerServices_Unsafe__As<System___Canon>:
-> 0x10036c060 <+0>: stp x29, x30, [sp, #-0x20]!
0x10036c064 <+4>: mov x29, sp
0x10036c068 <+8>: str x0, [x29, #0x18]
0x10036c06c <+12>: str x1, [x29, #0x10]
0x10036c070 <+16>: ldr x0, [x29, #0x10]
0x10036c074 <+20>: ldp x29, x30, [sp], #0x20
0x10036c078 <+24>: ret
0x10036c07c <+28>: udf #0x0
(lldb) c
Process 46176 resuming
Process 46176 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
frame #0: 0x00000001002e8bf8 naot1`S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>__Create + 168
naot1`S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>__Create:
-> 0x1002e8bf8 <+168>: ldr wzr, [x0]
0x1002e8bfc <+172>: blr x1
0x1002e8c00 <+176>: str x0, [x29, #0x48]
0x1002e8c04 <+180>: ldr x0, [x29, #0x48]
Target 0: (naot1) stopped.
(lldb) disas
naot1`S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>__Create:
0x1002e8b50 <+0>: stp x29, x30, [sp, #-0x90]!
0x1002e8b54 <+4>: mov x29, sp
0x1002e8b58 <+8>: add x9, x29, #0x28 ; =0x28
0x1002e8b5c <+12>: movi.16b v16, #0x0
0x1002e8b60 <+16>: stp q16, q16, [x9]
0x1002e8b64 <+20>: stp q16, q16, [x9, #0x20]
0x1002e8b68 <+24>: stp xzr, xzr, [x9, #0x40]
0x1002e8b6c <+28>: str xzr, [x9, #0x50]
0x1002e8b70 <+32>: str x0, [x29, #0x88]
0x1002e8b74 <+36>: str x0, [x29, #0x80]
0x1002e8b78 <+40>: ldr x0, [x29, #0x80]
0x1002e8b7c <+44>: bl 0x100007b74 ; __GenericLookupFromType_S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>_GCStaticBase_S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<T_System___Canon>
0x1002e8b80 <+48>: add x0, x0, #0x8 ; =0x8
0x1002e8b84 <+52>: str x0, [x29, #0x78]
0x1002e8b88 <+56>: ldr x0, [x29, #0x80]
0x1002e8b8c <+60>: bl 0x100008594 ; __GenericLookupFromType_S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>_TypeHandle_S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<T_System___Canon>
0x1002e8b90 <+64>: bl 0x1002e8b30 ; S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>__get_SupportsGenericIEquatableInterfaces
0x1002e8b94 <+68>: str w0, [x29, #0x74]
0x1002e8b98 <+72>: ldr x0, [x29, #0x78]
0x1002e8b9c <+76>: str x0, [x29, #0x68]
0x1002e8ba0 <+80>: ldr w0, [x29, #0x74]
0x1002e8ba4 <+84>: cbnz w0, 0x1002e8bc8 ; <+120>
0x1002e8ba8 <+88>: nop
0x1002e8bac <+92>: nop
0x1002e8bb0 <+96>: nop
0x1002e8bb4 <+100>: nop
0x1002e8bb8 <+104>: nop
0x1002e8bbc <+108>: ldr x0, [x29, #0x68]
0x1002e8bc0 <+112>: str x0, [x29, #0x28]
0x1002e8bc4 <+116>: b 0x1002e8bc4 ; <+116>
0x1002e8bc8 <+120>: ldr x0, [x29, #0x80]
0x1002e8bcc <+124>: bl 0x1000085a0 ; __GenericLookupFromType_S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>_TypeHandle_T_System___Canon
0x1002e8bd0 <+128>: bl 0x1001ce590 ; S_P_CoreLib_Internal_Runtime_CompilerHelpers_LdTokenHelpers__GetRuntimeTypeHandle
0x1002e8bd4 <+132>: str x0, [x29, #0x60]
0x1002e8bd8 <+136>: ldr x0, [x29, #0x60]
0x1002e8bdc <+140>: bl 0x1000ad4b0 ; S_P_CoreLib_System_Type__GetTypeFromHandle
0x1002e8be0 <+144>: str x0, [x29, #0x58]
0x1002e8be4 <+148>: adrp x0, -743
0x1002e8be8 <+152>: add x0, x0, #0x538 ; =0x538
0x1002e8bec <+156>: str x0, [x29, #0x50]
0x1002e8bf0 <+160>: ldr x0, [x29, #0x58]
0x1002e8bf4 <+164>: ldr x1, [x29, #0x50]
-> 0x1002e8bf8 <+168>: ldr wzr, [x0]
0x1002e8bfc <+172>: blr x1
0x1002e8c00 <+176>: str x0, [x29, #0x48]
0x1002e8c04 <+180>: ldr x0, [x29, #0x48]
0x1002e8c08 <+184>: bl 0x1001c6300 ; S_P_CoreLib_Internal_IntrinsicSupport_EqualityComparerHelpers__GetComparer
0x1002e8c0c <+188>: str x0, [x29, #0x40]
0x1002e8c10 <+192>: ldr x0, [x29, #0x80]
0x1002e8c14 <+196>: bl 0x10000926c ; __GenericLookupFromType_S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>_MethodDictionary_S_P_CoreLib_System_Runtime_CompilerServices_Unsafe__As<S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<T_System___Canon>>
0x1002e8c18 <+200>: str x0, [x29, #0x20]
0x1002e8c1c <+204>: ldr x0, [x29, #0x20]
0x1002e8c20 <+208>: ldr x1, [x29, #0x40]
0x1002e8c24 <+212>: bl 0x10036c060 ; S_P_CoreLib_System_Runtime_CompilerServices_Unsafe__As<System___Canon>
0x1002e8c28 <+216>: str x0, [x29, #0x38]
0x1002e8c2c <+220>: ldr x0, [x29, #0x80]
0x1002e8c30 <+224>: bl 0x100009260 ; __GenericLookupFromType_S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>_MethodDictionary_S_P_CoreLib_System_Threading_Interlocked__CompareExchange_3<S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<T_System___Canon>>
0x1002e8c34 <+228>: str x0, [x29, #0x18]
0x1002e8c38 <+232>: ldr x0, [x29, #0x18]
0x1002e8c3c <+236>: ldr x1, [x29, #0x68]
0x1002e8c40 <+240>: ldr x2, [x29, #0x38]
0x1002e8c44 <+244>: mov x3, xzr
0x1002e8c48 <+248>: bl 0x10036b340 ; S_P_CoreLib_System_Threading_Interlocked__CompareExchange_3<System___Canon>
0x1002e8c4c <+252>: str x0, [x29, #0x30]
0x1002e8c50 <+256>: nop
0x1002e8c54 <+260>: ldr x0, [x29, #0x80]
0x1002e8c58 <+264>: bl 0x100007b74 ; __GenericLookupFromType_S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<System___Canon>_GCStaticBase_S_P_CoreLib_System_Collections_Generic_EqualityComparer_1<T_System___Canon>
0x1002e8c5c <+268>: ldr x0, [x0, #0x8]
0x1002e8c60 <+272>: ldp x29, x30, [sp], #0x90
0x1002e8c64 <+276>: ret
0x1002e8c68 <+280>: udf #0x0
0x1002e8c6c <+284>: udf #0x0
These changes in main might have something to do with this slight improvement: https://github.com/dotnet/runtime/commit/4019e83878a81465f6e42e8502b53bc5d1752f81 and https://github.com/dotnet/runtime/commit/64096424f2c61453819522450945388734825bea.
Ah, this is correct. I am not sure how/why it is classified as
IMAGE_REL_BASED_RELPTR32
to begin with? Is that expected?
The problematic reloc around the GCHandle code is generated as such here: https://github.com/dotnet/runtime/blob/34f2b587f3512d3974d73b316e565194df34eea3/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs#L925-L938
We use IMAGE_REL_BASED_RELPTR32
because the target of the reloc is within the same image and we don't want to waste a full pointer on it. It's not the only place that uses IMAGE_REL_BASED_RELPTR32
for this reason. SupportsRelativePointers
guards the use of these relocs in data structures because there's targets like WASM that cannot express such relocation.
You could rule out whether the problem is related to BSS by changing the section here to data: https://github.com/dotnet/runtime/blob/938f2e3105ce9a851fedac96a210ffabaccb7dc3/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs#L241. It will emit explicit zeros into the image instead of relying on BSS.
These changes in main might have something to do with this slight improvement: https://github.com/dotnet/runtime/commit/4019e83878a81465f6e42e8502b53bc5d1752f81 and https://github.com/dotnet/runtime/commit/64096424f2c61453819522450945388734825bea.
None of the files in those commits compile as part of NativeAOT so its unlikely.
The null dereference you're seeing is still caused by the code around the GCHandle thinking that there's a GC handle with some null object.
The GCHandle in question is 8 bytes of what's supposed to be the BSS section.
Changing Bss to Data in that BlobNode ctor gives:
(lldb) register read
General Purpose Registers:
x0 = 0x000000010056f088 __GenericDict_S_P_CoreLib_System_Runtime_CompilerServices_Unsafe__As<S_P_CoreLib_System_Type>
x1 = 0x00000001020075e8
x2 = 0x000000000000000a
x3 = 0x0000000101404080
x4 = 0x0000000000000061
x5 = 0x000000016fdfee58
x6 = 0x0000000000000000
x7 = 0x0000000000000000
x8 = 0x00000001012911f0
x9 = 0x000000016fdff218
x10 = 0x00000001a9734530 libdyld.dylib`tlv_get_addr
x11 = 0x0000000000000001
x12 = 0x00000001005f5e60 naot1`g_highest_address
x13 = 0x0000000102007fd0
x14 = 0x000000016fdff320
x15 = 0x0000000102006460
x16 = 0x0000000000000000
x17 = 0x0000000101404080
x18 = 0x0000000000000000
x19 = 0x000000016fdff7a0
x20 = 0x0000000000000001
x21 = 0x0000000100000000 naot1`_mh_execute_header
x22 = 0x0000000000000000
x23 = 0x0000000000000000
x24 = 0x0000000000000000
x25 = 0x0000000000000000
x26 = 0x0000000000000000
x27 = 0x0000000000000000
x28 = 0x0000000000000000
fp = 0x000000016fdff200
lr = 0x00000001000ad580 naot1`S_P_CoreLib_System_Type__GetTypeFromEETypePtr + 112
sp = 0x000000016fdff200
pc = 0x000000010036c060 naot1`S_P_CoreLib_System_Runtime_CompilerServices_Unsafe__As<System___Canon>
cpsr = 0x20001000
it is __data section:
0x0000000d data [0x0000000100543c00-0x00000001005f4f68) rw- 0x00543c00 0x000b1368 0x00000000 naot1.__DATA.__data
and the As<T>
call in S_P_CoreLib_System_Type__GetTypeFromEETypePtr
does not fail (it later gives EXC_BAD_ACCESS from S_P_CoreLib_Internal_Runtime_IatAwarePointer_1<S_P_CoreLib_Internal_Runtime_MethodTable>__get_Value
).
Note that while x0 still has the same value (__GenericDict_S_P_CoreLib_System_Runtime_CompilerServices_Unsafe__As<S_P_CoreLib_System_Type>
), the difference between previously failing call to As<T>
and this successful execution is address of x1; before it was null, now it has the address 0x00000001020075e8
, which is outside of the entire module address ranges (0x0000000000000000 - 0x0000000100ef8000
).
Yeah, the reloc looks still wrong then.
In your objwriter change, what is forcing the RelocType = unsigned(MachO::ARM64_RELOC_POINTER_TO_GOT);
part around FK_PCRel_4
? Is anything asserting/crashing if that line is not there? A thing with GOT in the name doesn't sound right.
Removing RelocType = unsigned(MachO::ARM64_RELOC_POINTER_TO_GOT);
line from AArch64MachObjectWriter.cpp
takes us back to the error from the very top post:
...
naot1 -> /Users/am11/projects/naot1/bin/Debug/net7.0/osx-arm64/naot1.dll
Generating compatible native code. To optimize for size or speed, visit https://aka.ms/OptimizeCoreRT
<unknown>:0: error: ADR/ADRP relocations must be GOT relative
<unknown>:0: error: unknown AArch64 fixup kind!
<unknown>:0: error: unknown AArch64 fixup kind!
<unknown>:0: error: fixup value out of range
<unknown>:0: error: ADR/ADRP relocations must be GOT relative
<unknown>:0: error: unknown AArch64 fixup kind!
<unknown>:0: error: unknown AArch64 fixup kind!
<unknown>:0: error: fixup value out of range
<unknown>:0: error: ADR/ADRP relocations must be GOT relative
<unknown>:0: error: unknown AArch64 fixup kind!
<unknown>:0: error: unknown AArch64 fixup kind!
<unknown>:0: error: fixup value out of range
<unknown>:0: error: ADR/ADRP relocations must be GOT relative
<unknown>:0: error: unknown AArch64 fixup kind!
<unknown>:0: error: unknown AArch64 fixup kind!
<unknown>:0: error: fixup value out of range
<unknown>:0: error: ADR/ADRP relocations must be GOT relative
<unknown>:0: error: unknown AArch64 fixup kind!
<unknown>:0: error: unknown AArch64 fixup kind!
<unknown>:0: error: fixup value out of range
<unknown>:0: error: ADR/ADRP relocations must be GOT relative
<unknown>:0: error: unknown AArch64 fixup kind!
<unknown>:0: error: unknown AArch64 fixup kind!
<unknown>:0: error: fixup value out of range
<unknown>:0: error: ADR/ADRP relocations must be GOT relative
<unknown>:0: error: unknown AArch64 fixup kind!
<unknown>:0: error: unknown AArch64 fixup kind!
<unknown>:0: error: fixup value out of range
<unknown>:0: error: ADR/ADRP relocations must be GOT relative
<unknown>:0: error: unknown AArch64 fixup kind!
<unknown>:0: error: unknown AArch64 fixup kind!
<unknown>:0: error: ADR/ADRP relocations must be GOT relative
<unknown>:0: error: unknown AArch64 fixup kind!
<unknown>:0: error: unknown AArch64 fixup kind!
<unknown>:0: error: fixup value out of range
<unknown>:0: error: ADR/ADRP relocations must be GOT relative
...
<unknown>:0: error: unknown AArch64 fixup kind!
<unknown>:0: error: unknown AArch64 fixup kind!
<unknown>:0: error: unknown AArch64 fixup kind!
<unknown>:0: error: unknown AArch64 fixup kind!
<unknown>:0: error: unknown AArch64 fixup kind!
<unknown>:0: error: unknown AArch64 fixup kind!
<unknown>:0: error: unknown AArch64 fixup kind!
<unknown>:0: error: unknown AArch64 fixup kind!
<unknown>:0: error: unknown AArch64 fixup kind!
<unknown>:0: error: unknown AArch64 fixup kind!
<unknown>:0: error: unknown AArch64 fixup kind!
<unknown>:0: error: unknown AArch64 fixup kind!
ld: malformed __LD,__compact_unwind section, bad length file 'obj/Debug/net7.0/osx-arm64/native/naot1.o'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
(although useCompactUnwind still returns false per the change we made earlier)
I don't understand how deleting the RelocType = unsigned(MachO::ARM64_RELOC_POINTER_TO_GOT);
line gets us to the ADR/ADRP relocations must be GOT relative
message - the message comes from a different switch block in the same method - how does deleting the single line gets us to a different switch block?
I haven't stepped through that code, but it could be recordRelocation is called again for same symbol with immediate flag set? I don't have any other local changes.
Are you 100% sure you're using the objwriter you built? I crosscompiled from windows, but I don't see those errors printed even if I remove the line in question (just the one line, not the entire case
).
Indeed case of bad caching. 😞 I tried again from clean state (takes 13-15 minutes to clean the nuget caches and build both repos on M1 pro). The error is there, but it is different:
Generating compatible native code. To optimize for size or speed, visit https://aka.ms/OptimizeCoreRT
ld: in section __DATA,.corert_eh_table reloc 0: pcrel and ARM64_RELOC_UNSIGNED not supported file 'obj/Debug/net7.0/osx-arm64/native/naot1.o'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Uncommenting that (one) RelocType
line fixes this error and publishes the app which I was debugging.
Generating compatible native code. To optimize for size or speed, visit https://aka.ms/OptimizeCoreRT
ld: warning: can't parse dwarf compilation unit info in obj/Debug/net7.0/osx-arm64/native/naot1.o
naot1 -> /Users/am11/projects/naot1/bin/Debug/net7.0/osx-arm64/publish
Note that earlier we were getting type 15
error from corert_eh_table
(https://github.com/dotnet/runtime/issues/67232#issuecomment-1083078234). Looks like case FK_PCRel_4
needs a rework.
Looking at the relocations that seem to be actually supported around the error message in https://github.com/zzjconcent/ollvm/blob/d28107a3d30dfadde47ae0118d62d8d7951491f9/src/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h doesn't give us many options. It might be possible to represent this as ARM64_RELOC_SUBTRACTOR (make a temp symbol for current address and do a difference to destination). That's what PC relative is about anyway.
Or the other option is to take the !SupportsRelativePointers path because that's clearly where Apple wants us to go after they gimped their platform again and removed a reloc kind that exists everywhere else.
With SupportRelativePointers=false
, now backtraces are also working. We reach: https://github.com/dotnet/runtime/blob/6de7147b9266d7730b0d73ba67632b0c198cb11e/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/ModuleList.cs#L367 and it returns false followed by the FailFast from next line which results in SIGABRT. This Find
method is returning null (so it doesn't enter if
block): https://github.com/dotnet/runtime/blob/6de7147b9266d7730b0d73ba67632b0c198cb11e/src/coreclr/nativeaot/Common/src/System/Collections/Generic/LowLevelDictionary.cs#L79-L80
same callstack as https://github.com/dotnet/runtime/issues/67232#issuecomment-1086634886.
According to x/64s $x0
, the message is:
Invalid module requested in enumeration: 69446c657665c77
This is a huge address out of all module ranges. 🤔
@am11 - thanks for your help with this so far! I haven't forgotten about this, but my son was born and other things are now taking priority. I don't expect things to be normal for the next few weeks.
I am trying to enable NativeAOT on OSX arm64. With this patch https://github.com/dotnet/runtime/compare/main...am11:feature/nativeaot/osx-arm64 (tested with both
@GOTPAGE
and@PAGE
assembler directives), it builds the nupkg. Consuming that package results in the following errors during theilc
step:somewhere after the objwriter has succeeded: https://github.com/dotnet/runtime/blob/071e772d9d3bd8b50a5380bce6214277a1e61c98/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ObjectWriter.cs#L1183 and before the
clang
command is executed. While the ilc task does not fail, MSBuild fails on the clang step:With objdump, that
__LD,__compact_unwind
section looks like: