Modify unwinder to provide RtlVirtualUnwind.
authorBen Pye <ben@curlybracket.co.uk>
Tue, 14 Jul 2015 20:52:13 +0000 (21:52 +0100)
committerBen Pye <ben@curlybracket.co.uk>
Fri, 31 Jul 2015 14:44:36 +0000 (15:44 +0100)
Use PAL_VirtualUnwind on Linux ARM

Add assembler annotation for unwinding

src/jit/compiler.hpp
src/pal/inc/unixasmmacros.inc
src/pal/inc/unixasmmacrosamd64.inc
src/pal/inc/unixasmmacrosarm.inc
src/pal/src/exception/seh-unwind.cpp
src/unwinder/arm/unwinder_arm.cpp
src/vm/arm/asmhelpers.S
src/vm/arm/ehhelpers.S
src/vm/arm/stubs.cpp

index 501bfb2..99459dd 100644 (file)
@@ -764,11 +764,17 @@ inline
 
 inline
 float               getR4LittleEndian(const BYTE * ptr)
-{ return *(UNALIGNED float*)ptr; }
+{
+    __int32 val = getI4LittleEndian(ptr);
+    return *(float *)&val;
+}
 
 inline
 double              getR8LittleEndian(const BYTE * ptr)
-{ return *(UNALIGNED double*)ptr; }
+{
+    __int64 val = getI8LittleEndian(ptr);
+    return *(double *)&val;
+}
 
 
 /*****************************************************************************
index 45a2642..dc087cb 100644 (file)
         LEAF_END_MARKED \Name, \Section
 .endm
 
-.macro NESTED_ENTRY Name, Section, Handler
-        LEAF_ENTRY \Name, \Section
-        .ifnc \Handler, NoHandler
-#if defined(__APPLE__)
-        .cfi_personality 0x9b, C_FUNC(\Handler) // 0x9b == DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4
-#else
-        .cfi_personality 0, C_FUNC(\Handler) // 0 == DW_EH_PE_absptr
-#endif
-        .endif
-.endm
-
-.macro NESTED_END Name, Section
-        LEAF_END \Name, \Section
-#if defined(__APPLE__)
-        .section __LD,__compact_unwind,regular,debug
-        .quad C_FUNC(\Name)
-        .set C_FUNC(\Name\()_Size), C_FUNC(\Name\()_End) - C_FUNC(\Name)
-        .long C_FUNC(\Name\()_Size)
-        .long 0x04000000 # DWARF
-        .quad 0
-        .quad 0
-#endif
-.endm
-
 .macro END_PROLOGUE
 .endm
 
index 4689ad1..d1d760c 100644 (file)
@@ -3,6 +3,30 @@
 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
 //
 
+.macro NESTED_ENTRY Name, Section, Handler
+        LEAF_ENTRY \Name, \Section
+        .ifnc \Handler, NoHandler
+#if defined(__APPLE__)
+        .cfi_personality 0x9b, C_FUNC(\Handler) // 0x9b == DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4
+#else
+        .cfi_personality 0, C_FUNC(\Handler) // 0 == DW_EH_PE_absptr
+#endif
+        .endif
+.endm
+
+.macro NESTED_END Name, Section
+        LEAF_END \Name, \Section
+#if defined(__APPLE__)
+        .section __LD,__compact_unwind,regular,debug
+        .quad C_FUNC(\Name)
+        .set C_FUNC(\Name\()_Size), C_FUNC(\Name\()_End) - C_FUNC(\Name)
+        .long C_FUNC(\Name\()_Size)
+        .long 0x04000000 # DWARF
+        .quad 0
+        .quad 0
+#endif
+.endm
+
 .macro PATCH_LABEL Name
         .global C_FUNC(\Name)
 C_FUNC(\Name):
index 40daa7a..25f2ed7 100644 (file)
@@ -3,6 +3,17 @@
 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
 //
 
+.macro NESTED_ENTRY Name, Section, Handler
+        LEAF_ENTRY \Name, \Section
+        .ifnc \Handler, NoHandler
+        .personality C_FUNC(\Handler)
+        .endif
+.endm
+
+.macro NESTED_END Name, Section
+        LEAF_END \Name, \Section
+.endm
+
 .macro PATCH_LABEL Name
         .thumb_func
         .global C_FUNC(\Name)
@@ -14,7 +25,7 @@ C_FUNC(\Name):
         .global C_FUNC(\Name)
         .type \Name, %function
 C_FUNC(\Name):
-        .cfi_startproc
+        .fnstart
 .endm
 
 .macro LEAF_END_MARKED Name, Section
@@ -22,7 +33,7 @@ C_FUNC(\Name):
         .global C_FUNC(\Name\()_End)
 C_FUNC(\Name\()_End):
         .size \Name, .-\Name
-        .cfi_endproc
+        .fnend
 .endm
 
 .macro PREPARE_EXTERNAL_VAR Name, HelperReg
@@ -30,64 +41,43 @@ C_FUNC(\Name\()_End):
 .endm
 
 .macro push_nonvol_reg Register
-        push {\Register}
-        .cfi_adjust_cfa_offset 4
-        .cfi_rel_offset \Register, 0
+        push \Register
+        .save \Register
 .endm
 
 .macro pop_nonvol_reg Register
-        pop {\Register}
-        .cfi_adjust_cfa_offset -4
-        .cfi_restore \Register
-.endm
-
-.macro alloc_stack Size
-        sub sp, sp, \Size
-        .cfi_adjust_cfa_offset \Size
+        pop \Register
 .endm
 
-.macro free_stack Size
-        add sp, sp, \Size
-        .cfi_adjust_cfa_offset -\Size
+.macro vpush_nonvol_reg Register
+        vpush \Register
+        .vsave \Register
 .endm
 
-.macro set_cfa_register Reg, Offset
-        .cfi_def_cfa_register \Reg
-        .cfi_def_cfa_offset \Offset
+.macro vpop_nonvol_reg Register
+        vpop \Register
 .endm
 
-.macro save_reg_postsp Reg, Offset
-        str \Reg, [sp, #\Offset]
-        .cfi_rel_offset \Reg, __Offset
+.macro alloc_stack Size
+        sub sp, sp, \Size
+        .pad #\Size
 .endm
 
-.macro restore_reg Reg, Offset
-        ldr \Reg, [sp, #\Offset]
-        .cfi_restore \Reg
+.macro free_stack Size
+        add sp, sp, \Size
+        .pad #-\Size
 .endm
 
 .macro POP_CALLEE_SAVED_REGISTERS
-        pop {r4-r11, lr}
-        .cfi_adjust_cfa_offset -(4*9)
-        .cfi_restore r4
-        .cfi_restore r5
-        .cfi_restore r6
-        .cfi_restore r7
-        .cfi_restore r8
-        .cfi_restore r9
-        .cfi_restore r10
-        .cfi_restore r11
-        .cfi_restore lr
+        pop_nonvol_reg "{r4-r11, lr}"
 .endm
 
 .macro PUSH_CALLEE_SAVED_REGISTERS
-        push {r4-r11, lr}
-        .cfi_adjust_cfa_offset (4*9)
+        push_nonvol_reg "{r4-r11, lr}"
 .endm
 
 .macro push_register Reg
-        push            {\Reg}
-        .cfi_adjust_cfa_offset 4
+        push \Reg
 .endm
 
 .macro push_argument_register Reg
@@ -96,12 +86,10 @@ C_FUNC(\Name\()_End):
 
 .macro PUSH_ARGUMENT_REGISTERS
         push {r0-r3}
-        .cfi_adjust_cfa_offset (4*4)
 .endm
 
 .macro pop_register Reg
-        pop            {\Reg}
-        .cfi_adjust_cfa_offset -4
+        pop \Reg
 .endm
 
 .macro pop_argument_register Reg
@@ -110,7 +98,6 @@ C_FUNC(\Name\()_End):
 
 .macro POP_ARGUMENT_REGISTERS
         pop {r0-r3}
-        .cfi_adjust_cfa_offset -(4*4)
 .endm
 
 // Stack layout:
@@ -205,6 +192,31 @@ C_FUNC(\Name\()_End):
         .inst.w 0xde01
 .endm
 
+.macro PROLOG_PUSH RegList
+        push_nonvol_reg "\RegList"
+.endm
+
+.macro PROLOG_VPUSH RegList
+        vpush_nonvol_reg "\RegList"
+.endm
+
+.macro PROLOG_STACK_SAVE Register
+        .setfp \Register, sp
+        mov \Register, sp
+.endm
+
+.macro EPILOG_STACK_RESTORE Register
+        mov sp, \Register
+.endm
+
+.macro EPILOG_POP RegList
+        pop_nonvol_reg "\RegList"
+.endm
+
+.macro EPILOG_VPOP RegList
+        vpop_nonvol_reg "\RegList"
+.endm
+
 //-----------------------------------------------------------------------------
 // Macro used to check (in debug builds only) whether the stack is 64-bit aligned (a requirement before calling
 // out into C++/OS code). Invoke this directly after your prolog (if the stack frame size is fixed) or directly
index 9dd025c..70a1afd 100644 (file)
@@ -73,9 +73,9 @@ static void WinContextToUnwindCursor(CONTEXT *winContext, unw_cursor_t *cursor)
     unw_set_reg(cursor, UNW_X86_64_R14, winContext->R14);
     unw_set_reg(cursor, UNW_X86_64_R15, winContext->R15);
 #elif defined(_ARM_)
-    unw_set_reg(cursor, UNW_REG_IP, winContext->Pc);
-    unw_set_reg(cursor, UNW_REG_SP, winContext->Sp);
+    unw_set_reg(cursor, UNW_ARM_R13, winContext->Sp);
     unw_set_reg(cursor, UNW_ARM_R14, winContext->Lr);
+    unw_set_reg(cursor, UNW_ARM_R15, winContext->Pc);
     unw_set_reg(cursor, UNW_ARM_R4, winContext->R4);
     unw_set_reg(cursor, UNW_ARM_R5, winContext->R5);
     unw_set_reg(cursor, UNW_ARM_R6, winContext->R6);
@@ -100,9 +100,9 @@ static void UnwindContextToWinContext(unw_cursor_t *cursor, CONTEXT *winContext)
     unw_get_reg(cursor, UNW_X86_64_R14, (unw_word_t *) &winContext->R14);
     unw_get_reg(cursor, UNW_X86_64_R15, (unw_word_t *) &winContext->R15);
 #elif defined(_ARM_)
-    unw_get_reg(cursor, UNW_REG_IP, (unw_word_t *) &winContext->Pc);
-    unw_get_reg(cursor, UNW_REG_SP, (unw_word_t *) &winContext->Sp);
+    unw_get_reg(cursor, UNW_ARM_R13, (unw_word_t *) &winContext->Sp);
     unw_get_reg(cursor, UNW_ARM_R14, (unw_word_t *) &winContext->Lr);
+    unw_get_reg(cursor, UNW_ARM_R15, (unw_word_t *) &winContext->Pc);
     unw_get_reg(cursor, UNW_ARM_R4, (unw_word_t *) &winContext->R4);
     unw_get_reg(cursor, UNW_ARM_R5, (unw_word_t *) &winContext->R5);
     unw_get_reg(cursor, UNW_ARM_R6, (unw_word_t *) &winContext->R6);
index a07d9e7..8cf93f7 100644 (file)
 #define STATUS_UNWIND_UNSUPPORTED_VERSION   STATUS_UNSUCCESSFUL
 
 
-#define UPDATE_CONTEXT_POINTERS(Params, RegisterNumber, Address)
-#define UPDATE_FP_CONTEXT_POINTERS(Params, RegisterNumber, Address)
+#define UPDATE_CONTEXT_POINTERS(Params, RegisterNumber, Address)                \
+do {                                                                            \
+    PKNONVOLATILE_CONTEXT_POINTERS ContextPointers = (Params)->ContextPointers; \
+    if (ARGUMENT_PRESENT(ContextPointers)) {                                    \
+        if (RegisterNumber >=  4 && RegisterNumber <= 11) {                     \
+            (&ContextPointers->R4)[RegisterNumber - 4] = (PULONG)Address;       \
+        } else if (RegisterNumber == 14) {                                      \
+            ContextPointers->Lr = (PULONG)Address;                              \
+        }                                                                       \
+    }                                                                           \
+} while (0)
+
+#define UPDATE_FP_CONTEXT_POINTERS(Params, RegisterNumber, Address)             \
+do {                                                                            \
+    PKNONVOLATILE_CONTEXT_POINTERS ContextPointers = (Params)->ContextPointers; \
+    if (ARGUMENT_PRESENT(ContextPointers) &&                                    \
+        (RegisterNumber >=  8) &&                                               \
+        (RegisterNumber <= 15)) {                                               \
+                                                                                \
+        (&ContextPointers->D8)[RegisterNumber - 8] = (PULONGLONG)Address;       \
+    }                                                                           \
+} while (0)
+
 #define VALIDATE_STACK_ADDRESS(Params, Context, DataSize, Alignment, OutStatus)
 #define UNWIND_PARAMS_SET_TRAP_FRAME(Params, Address)
 
 
 #define CONTEXT_REGISTER(ctx, idx)    ((&(ctx)->R0)[idx])
 
+typedef struct _ARM_UNWIND_PARAMS
+{
+    PKNONVOLATILE_CONTEXT_POINTERS ContextPointers;
+} ARM_UNWIND_PARAMS, *PARM_UNWIND_PARAMS;
 
 //
 // The ConditionTable is used to look up the state of a condition
@@ -230,7 +255,7 @@ NTSTATUS
 RtlpUnwindCustom(
     __inout PT_CONTEXT ContextRecord,
     __in BYTE Opcode,
-    __in PVOID UnwindParams
+    __in PARM_UNWIND_PARAMS UnwindParams
     )
 
 /*++
@@ -358,7 +383,7 @@ RtlpPopVfpRegisterRange(
     __inout PT_CONTEXT ContextRecord,
     __in ULONG RegStart,
     __in ULONG RegStop,
-    __in PVOID UnwindParams
+    __in PARM_UNWIND_PARAMS UnwindParams
     )
 
 /*++
@@ -457,7 +482,7 @@ NTSTATUS
 RtlpPopRegisterMask(
     __inout PT_CONTEXT ContextRecord,
     __in WORD RegMask,
-    __in PVOID UnwindParams
+    __in PARM_UNWIND_PARAMS UnwindParams
     )
 /*++
 
@@ -624,7 +649,7 @@ RtlpUnwindFunctionCompact(
     __out PULONG EstablisherFrame,
     __deref_opt_out_opt PEXCEPTION_ROUTINE *HandlerRoutine,
     __out PVOID *HandlerData,
-    __in PVOID UnwindParams
+    __in PARM_UNWIND_PARAMS UnwindParams
     )
 {
     ULONG CBit;
@@ -894,7 +919,7 @@ RtlpUnwindFunctionFull(
     __out PULONG EstablisherFrame,
     __deref_opt_out_opt PEXCEPTION_ROUTINE *HandlerRoutine,
     __out PVOID *HandlerData,
-    __in PVOID UnwindParams
+    __in PARM_UNWIND_PARAMS UnwindParams
     )
 
 /*++
@@ -1480,8 +1505,41 @@ PEXCEPTION_ROUTINE RtlVirtualUnwind(
     __inout_opt PKNONVOLATILE_CONTEXT_POINTERS ContextPointers
     )
 {
-    PORTABILITY_ASSERT("Implement for PAL");
+    PEXCEPTION_ROUTINE handlerRoutine;
+    HRESULT res;
+    
+    IMAGE_ARM_RUNTIME_FUNCTION_ENTRY rfe;
+    rfe.BeginAddress = FunctionEntry->BeginAddress;
+    rfe.UnwindData = FunctionEntry->UnwindData;
+    
+    ARM_UNWIND_PARAMS unwindParams;
+    unwindParams.ContextPointers = ContextPointers;
+    
+    if ((FunctionEntry->UnwindData & 3) != 0) 
+    {
+        res = RtlpUnwindFunctionCompact(ControlPc - ImageBase,
+                                        &rfe,
+                                        ContextRecord,
+                                        EstablisherFrame,
+                                        &handlerRoutine,
+                                        HandlerData,
+                                        &unwindParams);
+
+    }
+    else
+    {
+        res = RtlpUnwindFunctionFull(ControlPc - ImageBase,
+                                    ImageBase,
+                                    &rfe,
+                                    ContextRecord,
+                                    EstablisherFrame,
+                                    &handlerRoutine,
+                                    HandlerData,
+                                    &unwindParams);
+    }
+
+    _ASSERTE(SUCCEEDED(res));
     
-    return NULL;
+    return handlerRoutine;
 }
 #endif
index 4e6e46b..d625f6b 100644 (file)
@@ -32,8 +32,8 @@
 //-----------------------------------------------------------------------------
 //void CallDescrWorkerInternal(CallDescrData * pCallDescrData)//
         NESTED_ENTRY CallDescrWorkerInternal,_TEXT,NoHandler
-        push    {r4,r5,r7,lr}
-        mov     r7, sp
+        PROLOG_PUSH         "{r4,r5,r7,lr}"
+        PROLOG_STACK_SAVE   r7
 
         mov     r5,r0 // save pCallDescrData in r5
 
@@ -130,8 +130,8 @@ LOCAL_LABEL(LReturnDone):
         vldm    sp, {d0-d3}
 #endif
 
-        mov     sp, r7
-        pop     {r4,r5,r7,pc}
+        EPILOG_STACK_RESTORE    r7
+        EPILOG_POP              "{r4,r5,r7,pc}"
 
         NESTED_END CallDescrWorkerInternal,_TEXT
 
@@ -173,9 +173,9 @@ LOCAL_LABEL(LReturnDone):
         //
         
         // Spill callee saved registers and return address.
-        push         {r4-r11,lr}
+        PROLOG_PUSH         "{r4-r11,lr}"
         
-        mov r7, sp
+        PROLOG_STACK_SAVE   r7
 
         //
         // This is the code that would have to run to setup this frame
@@ -242,8 +242,8 @@ LOCAL_LABEL(GoodGSCookie):
         // 
         // epilog
         //
-        mov sp, r7
-        pop {r4-r11,lr}
+        EPILOG_STACK_RESTORE    r7
+        EPILOG_POP              "{r4-r11,lr}"
         bx lr
         
     NESTED_END TailCallHelperStub, _TEXT
@@ -310,9 +310,9 @@ LOCAL_LABEL(LNullThis):
 // r12 = UMEntryThunk*
 //
         NESTED_ENTRY UMThunkStub,_TEXT,NoHandler
-        push {r4,r5,r7,r11,lr}
-        push {r0-r3,r12}
-        mov r7, sp
+        PROLOG_PUSH         "{r4,r5,r7,r11,lr}"
+        push                {r0-r3,r12}
+        PROLOG_STACK_SAVE   r7
 
         //GBLA UMThunkStub_HiddenArg // offset of saved UMEntryThunk *
         //GBLA UMThunkStub_StackArgs // offset of original stack args (total size of UMThunkStub frame)
@@ -375,9 +375,9 @@ LOCAL_LABEL(UMThunkStub_PostCall):
         mov                 r4, 0
         str                 r4, [r5, #Thread__m_fPreemptiveGCDisabled]
 
-        mov sp, r7
-        add sp, sp, #(4 * 5)
-        pop {r4,r5,r7,r11,pc}
+        EPILOG_STACK_RESTORE r7
+        free_stack           4 * 5
+        EPILOG_POP           "{r4,r5,r7,r11,pc}"
 
 LOCAL_LABEL(UMThunkStub_DoThreadSetup):
         sub                 sp, #SIZEOF__FloatArgumentRegisters
@@ -424,8 +424,8 @@ LOCAL_LABEL(UMThunkStub_WrongAppDomain):
 
         NESTED_ENTRY UM2MThunk_WrapperHelper, _TEXT, NoHandler
 
-        push {r4-r7,r11,lr}
-        mov r7, sp
+        PROLOG_PUSH         "{r4-r7,r11,lr}"
+        PROLOG_STACK_SAVE   r7
 
         CHECK_STACK_ALIGNMENT
 
@@ -481,8 +481,8 @@ LOCAL_LABEL(UM2MThunk_WrapperHelper_ArgumentsSetup):
         vldm                sp, {d0-d3}
 #endif
 
-        mov sp, r7
-        pop {r4-r7,r11,pc}
+        EPILOG_STACK_RESTORE r7
+        EPILOG_POP          "{r4-r7,r11,pc}"
 
         NESTED_END UM2MThunk_WrapperHelper, _TEXT
 
@@ -543,7 +543,7 @@ ThePreStubPatchLabel:
 
         // r12 = FixupPrecode *
 
-        push     {r0-r1}
+        PROLOG_PUSH     "{r0-r1}"
 
         // Inline computation done by FixupPrecode::GetMethodDesc()
         ldrb    r0, [r12, #3]           // m_PrecodeChunkIndex
@@ -554,7 +554,7 @@ ThePreStubPatchLabel:
         ldr     r0, [r0,#8]
         add     r12,r0,r1,lsl #2
 
-        pop {r0-r1}
+        EPILOG_POP      "{r0-r1}"
         b C_FUNC(ThePreStub)
 
         NESTED_END PrecodeFixupThunk, _TEXT
@@ -676,9 +676,9 @@ LOCAL_LABEL(Done):
 
         NESTED_ENTRY RedirectedHandledJITCaseFor\reason\()_Stub, _TEXT, NoHandler
 
-        push {r7,lr}     // return address
-        alloc_stack 4    // stack slot to save the CONTEXT *
-        mov r7, sp
+        PROLOG_PUSH "{r7,lr}"   // return address
+        alloc_stack 4           // stack slot to save the CONTEXT *
+        PROLOG_STACK_SAVE r7
 
         //REDIRECTSTUB_SP_OFFSET_CONTEXT is defined in asmconstants.h
         //If CONTEXT is not saved at 0 offset from SP it must be changed as well.
@@ -762,7 +762,7 @@ LOCAL_LABEL(checkStack_neg):
     NESTED_END checkStack, _TEXT
 
     NESTED_ENTRY stackProbe, _TEXT, NoHandler
-    push {r5,r6}
+    PROLOG_PUSH "{r5,r6}"
     mov         r6, r12
     bfc         r6, #0, #0xc  // align down (4K)
 LOCAL_LABEL(stackProbe_loop):
@@ -770,7 +770,7 @@ LOCAL_LABEL(stackProbe_loop):
     ldr         r5,[r4]       // try to read ... this should move the guard page
     cmp         r4,r6
     bne         LOCAL_LABEL(stackProbe_loop)
-    pop {r5,r6}
+    EPILOG_POP "{r5,r6}"
     sub r4,sp,r12
     bx lr
     NESTED_END stackProbe, _TEXT
@@ -907,15 +907,15 @@ LOCAL_LABEL(stackProbe_loop):
 //
     NESTED_ENTRY JIT_RareDisableHelper, _TEXT, NoHandler
 
-    push {r0-r1, r11, lr} // save integer return value
-    vpush {d0-d3}         // floating point return value
+    PROLOG_PUSH "{r0-r1, r11, lr}" // save integer return value
+    vpush {d0-d3}                  // floating point return value
 
     CHECK_STACK_ALIGNMENT
 
     bl          C_FUNC(JIT_RareDisableHelperWorker)
 
     vpop {d0-d3}
-    pop {r0-r1, r11, pc}
+    EPILOG_POP "{r0-r1, r11, pc}"
 
     NESTED_END JIT_RareDisableHelper, _TEXT
 
index aaa464e..a15f7cc 100644 (file)
@@ -39,7 +39,7 @@ OFFSET_OF_FRAME=(4 + SIZEOF__GSCookie)
         // IN: lr: original IP before redirect
         //
 
-        push         {r4,r7,lr}
+        PROLOG_PUSH  "{r4,r7,lr}"
         alloc_stack  OFFSET_OF_FRAME + SIZEOF__FaultingExceptionFrame
 
         // At this point, the stack maybe misaligned if the thread abort was asynchronously
@@ -47,7 +47,7 @@ OFFSET_OF_FRAME=(4 + SIZEOF__GSCookie)
         // align the stack before calling into the VM.
         //
         // Runtime check for 8-byte alignment. 
-        mov r7, sp
+        PROLOG_STACK_SAVE r7
         and r0, r7, #4
         sub sp, sp, r0
 
@@ -99,7 +99,7 @@ OFFSET_OF_FRAME=(4 + SIZEOF__GSCookie)
         // This helper enables us to call into a funclet after applying the non-volatiles
         NESTED_ENTRY CallEHFunclet, _TEXT, NoHandler
 
-        push         {r4-r11, lr}
+        PROLOG_PUSH  "{r4-r11, lr}"
         alloc_stack  4
 
         // On entry:
@@ -117,7 +117,7 @@ OFFSET_OF_FRAME=(4 + SIZEOF__GSCookie)
         blx r1
 
         free_stack   4
-        pop          {r4-r11, pc}
+        EPILOG_POP   "{r4-r11, pc}"
 
         NESTED_END CallEHFunclet, _TEXT
 
@@ -125,7 +125,7 @@ OFFSET_OF_FRAME=(4 + SIZEOF__GSCookie)
         // frame pointer for accessing the locals in the parent method.
         NESTED_ENTRY CallEHFilterFunclet, _TEXT, NoHandler
 
-        push         {lr}
+        PROLOG_PUSH  "{lr}"
         alloc_stack  4
 
         // On entry:
@@ -141,6 +141,6 @@ OFFSET_OF_FRAME=(4 + SIZEOF__GSCookie)
         blx r2
 
         free_stack   4
-        pop          {pc}
+        EPILOG_POP   "{pc}"
 
         NESTED_END CallEHFilterFunclet, _TEXT
index 91a3d70..368e6cf 100644 (file)
@@ -533,7 +533,12 @@ void LazyMachState::unwindLazyState(LazyMachState* baseState,
 
     do
     {
+#ifndef FEATURE_PAL
         pvControlPc = Thread::VirtualUnwindCallFrame(&ctx, &nonVolRegPtrs);
+#else // !FEATURE_PAL
+        PAL_VirtualUnwind(&ctx, &nonVolRegPtrs);
+        pvControlPc = GetIP(&ctx);
+#endif // !FEATURE_PAL
 
         if (funCallDepth > 0)
         {