Skip to content

Commit

Permalink
Fix unwinding in some of the ARM64 helpers (#99103)
Browse files Browse the repository at this point in the history
Fixes #98738.

For the following assembly:

```
unwindtest`RhpNewObject:
    0x55555ab478 <+0>:   stp    x29, x30, [sp, #-0x80]!
->  0x55555ab47c <+4>:   mov    x29, sp
    0x55555ab480 <+8>:   stp    x19, x20, [sp, #0x20]
    0x55555ab484 <+12>:  stp    x21, x22, [sp, #0x30]
    0x55555ab488 <+16>:  stp    x23, x24, [sp, #0x40]
    0x55555ab48c <+20>:  stp    x25, x26, [sp, #0x50]
    0x55555ab490 <+24>:  stp    x27, x28, [sp, #0x60]
    0x55555ab494 <+28>:  add    x3, sp, #0x80
    0x55555ab498 <+32>:  str    x3, [sp, #0x70]
    0x55555ab49c <+36>:  mov    x3, #0x7ff
    0x55555ab4a0 <+40>:  str    x3, [sp, #0x18]
    0x55555ab4a4 <+44>:  mov    x3, sp
    0x55555ab4a8 <+48>:  mov    x19, x0
    0x55555ab4ac <+52>:  mov    w2, #0x0
    0x55555ab4b0 <+56>:  bl     0x55555583a8              ; ::RhpGcAlloc(MethodTable *, uint32_t, uintptr_t, PInvokeTransitionFrame *) at GCHelpers.cpp:540
    0x55555ab4b4 <+60>:  cbz    x0, 0x55555ab4d4          ; <+92>
    0x55555ab4b8 <+64>:  ldp    x19, x20, [sp, #0x20]
    0x55555ab4bc <+68>:  ldp    x21, x22, [sp, #0x30]
    0x55555ab4c0 <+72>:  ldp    x23, x24, [sp, #0x40]
    0x55555ab4c4 <+76>:  ldp    x25, x26, [sp, #0x50]
    0x55555ab4c8 <+80>:  ldp    x27, x28, [sp, #0x60]
    0x55555ab4cc <+84>:  ldp    x29, x30, [sp], #0x80
    0x55555ab4d0 <+88>:  ret
    0x55555ab4d4 <+92>:  mov    x0, x19
    0x55555ab4d8 <+96>:  mov    x1, #0x0
    0x55555ab4dc <+100>: ldp    x19, x20, [sp, #0x20]
    0x55555ab4e0 <+104>: ldp    x21, x22, [sp, #0x30]
    0x55555ab4e4 <+108>: ldp    x23, x24, [sp, #0x40]
    0x55555ab4e8 <+112>: ldp    x25, x26, [sp, #0x50]
    0x55555ab4ec <+116>: ldp    x27, x28, [sp, #0x60]
    0x55555ab4f0 <+120>: ldp    x29, x30, [sp], #0x80
    0x55555ab4f4 <+124>: b      0x55555eaa90              ; System.Runtime.EH__FailedAllocation at ExceptionHandling.cs:399
```

LLDB had the following unwind plan according to disassembly:

```
row[0]:    0: CFA=sp +0 =>
row[1]:    4: CFA=sp+128 => fp=[CFA-128] lr=[CFA-120]
row[2]:    8: CFA=fp+128 => fp=[CFA-128] lr=[CFA-120]
row[3]:   12: CFA=fp+128 => x19=[CFA-96] x20=[CFA-88] fp=[CFA-128] lr=[CFA-120]
row[4]:   16: CFA=fp+128 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] fp=[CFA-128] lr=[CFA-120]
row[5]:   20: CFA=fp+128 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] fp=[CFA-128] lr=[CFA-120]
row[6]:   24: CFA=fp+128 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] fp=[CFA-128] lr=[CFA-120]
row[7]:   28: CFA=fp+128 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[8]:   36: CFA=fp+128 => x3=[CFA-16] x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[9]:   68: CFA=fp+128 => x3=[CFA-16] x19= <same> x20= <same> x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[10]:   72: CFA=fp+128 => x3=[CFA-16] x19= <same> x20= <same> x21= <same> x22= <same> x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[11]:   76: CFA=fp+128 => x3=[CFA-16] x19= <same> x20= <same> x21= <same> x22= <same> x23= <same> x24= <same> x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[12]:   80: CFA=fp+128 => x3=[CFA-16] x19= <same> x20= <same> x21= <same> x22= <same> x23= <same> x24= <same> x25= <same> x26= <same> x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[13]:   84: CFA=fp+128 => x3=[CFA-16] x19= <same> x20= <same> x21= <same> x22= <same> x23= <same> x24= <same> x25= <same> x26= <same> x27= <same> x28= <same> fp=[CFA-128] lr=[CFA-120]
row[14]:   88: CFA=fp+128 => x3=[CFA-16] x19= <same> x20= <same> x21= <same> x22= <same> x23= <same> x24= <same> x25= <same> x26= <same> x27= <same> x28= <same> fp= <same> lr= <same>
row[15]:   92: CFA=fp+128 => x3=[CFA-16] x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[16]:  104: CFA=fp+128 => x3=[CFA-16] x19= <same> x20= <same> x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[17]:  108: CFA=fp+128 => x3=[CFA-16] x19= <same> x20= <same> x21= <same> x22= <same> x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[18]:  112: CFA=fp+128 => x3=[CFA-16] x19= <same> x20= <same> x21= <same> x22= <same> x23= <same> x24= <same> x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[19]:  116: CFA=fp+128 => x3=[CFA-16] x19= <same> x20= <same> x21= <same> x22= <same> x23= <same> x24= <same> x25= <same> x26= <same> x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[20]:  120: CFA=fp+128 => x3=[CFA-16] x19= <same> x20= <same> x21= <same> x22= <same> x23= <same> x24= <same> x25= <same> x26= <same> x27= <same> x28= <same> fp=[CFA-128] lr=[CFA-120]
row[21]:  124: CFA=fp+128 => x3=[CFA-16] x19= <same> x20= <same> x21= <same> x22= <same> x23= <same> x24= <same> x25= <same> x26= <same> x27= <same> x28= <same> fp= <same> lr= <same>
```

Our eh_frame info was:

```
row[0]:    0: CFA=sp +0 =>
row[1]:    4: CFA=sp+128 => fp=[CFA-128] lr=[CFA-120]
row[2]:    8: CFA=fp+128 => fp=[CFA-128] lr=[CFA-120]
row[3]:   12: CFA=fp+128 => x19=[CFA-96] x20=[CFA-88] fp=[CFA-128] lr=[CFA-120]
row[4]:   16: CFA=fp+128 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] fp=[CFA-128] lr=[CFA-120]
row[5]:   20: CFA=fp+128 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] fp=[CFA-128] lr=[CFA-120]
row[6]:   24: CFA=fp+128 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] fp=[CFA-128] lr=[CFA-120]
row[7]:   28: CFA=fp+128 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[8]:   68: CFA=fp+128 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[9]:   72: CFA=fp+128 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[10]:   76: CFA=fp+128 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[11]:   80: CFA=fp+128 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[12]:   84: CFA=fp+128 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[13]:   88: CFA=fp +0 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[14]:  104: CFA=fp +0 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[15]:  108: CFA=fp +0 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[16]:  112: CFA=fp +0 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[17]:  116: CFA=fp +0 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[18]:  120: CFA=fp +0 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[19]:  124: CFA=fp-128 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
```

Notice the CFA at offset 88 started to be bad.

With this fix, the unwind plan is now:

```
row[0]:    0: CFA=sp +0 =>
row[1]:    4: CFA=sp+128 => fp=[CFA-128] lr=[CFA-120]
row[2]:    8: CFA=fp+128 => fp=[CFA-128] lr=[CFA-120]
row[3]:   12: CFA=fp+128 => x19=[CFA-96] x20=[CFA-88] fp=[CFA-128] lr=[CFA-120]
row[4]:   16: CFA=fp+128 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] fp=[CFA-128] lr=[CFA-120]
row[5]:   20: CFA=fp+128 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] fp=[CFA-128] lr=[CFA-120]
row[6]:   24: CFA=fp+128 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] fp=[CFA-128] lr=[CFA-120]
row[7]:   28: CFA=fp+128 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[8]:   64: CFA=fp+128 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[9]:   68: CFA=fp+128 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[10]:   72: CFA=fp+128 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[11]:   76: CFA=fp+128 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[12]:   80: CFA=fp+128 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[13]:   84: CFA=fp+128 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[14]:   88: CFA=fp +0 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[15]:   92: CFA=fp+128 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[16]:  104: CFA=fp+128 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[17]:  108: CFA=fp+128 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[18]:  112: CFA=fp+128 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[19]:  116: CFA=fp+128 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[20]:  120: CFA=fp+128 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
row[21]:  124: CFA=fp-128 => x19=[CFA-96] x20=[CFA-88] x21=[CFA-80] x22=[CFA-72] x23=[CFA-64] x24=[CFA-56] x25=[CFA-48] x26=[CFA-40] x27=[CFA-32] x28=[CFA-24] fp=[CFA-128] lr=[CFA-120]
```

For some reason, CFA at 88 is still FP+0, and at 124 it's FP-128, but we don't care about offset 124. I can't figure out what is going on at 88 that offset 92 magically fixes.
  • Loading branch information
MichalStrehovsky authored Feb 29, 2024
1 parent 1afd4bc commit 96a2d01
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/coreclr/nativeaot/Runtime/arm64/AllocFast.S
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,11 @@ LOCAL_LABEL(RhpNewFast_RarePath):
// Set the new objects MethodTable pointer on success.
cbz x0, LOCAL_LABEL(NewOutOfMemory)

.cfi_remember_state
POP_COOP_PINVOKE_FRAME
EPILOG_RETURN

.cfi_restore_state
LOCAL_LABEL(NewOutOfMemory):
// This is the OOM failure path. We are going to tail-call to a managed helper that will throw
// an out of memory exception that the caller of this allocator understands.
Expand Down Expand Up @@ -262,9 +264,11 @@ LOCAL_LABEL(RhpNewArray_Rare):
// Set the new objects MethodTable pointer and length on success.
cbz x0, LOCAL_LABEL(ArrayOutOfMemory)

.cfi_remember_state
POP_COOP_PINVOKE_FRAME
EPILOG_RETURN

.cfi_restore_state
LOCAL_LABEL(ArrayOutOfMemory):
// This is the OOM failure path. We are going to tail-call to a managed helper that will throw
// an out of memory exception that the caller of this allocator understands.
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/nativeaot/Runtime/arm64/GcProbe.S
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,11 @@ NESTED_ENTRY RhpWaitForGC, _TEXT, NoHandler
ldr x2, [sp, #OFFSETOF__PInvokeTransitionFrame__m_Flags]
tbnz x2, #PTFF_THREAD_ABORT_BIT, LOCAL_LABEL(ThrowThreadAbort)

.cfi_remember_state
POP_PROBE_FRAME
EPILOG_RETURN

.cfi_restore_state
LOCAL_LABEL(ThrowThreadAbort):
POP_PROBE_FRAME
mov w0, #STATUS_REDHAWK_THREAD_ABORT
Expand Down

0 comments on commit 96a2d01

Please sign in to comment.