diff options
-rw-r--r-- | src/pal/src/exception/seh-unwind.cpp | 56 |
1 files changed, 32 insertions, 24 deletions
diff --git a/src/pal/src/exception/seh-unwind.cpp b/src/pal/src/exception/seh-unwind.cpp index f708ce57e8..25a8789a0c 100644 --- a/src/pal/src/exception/seh-unwind.cpp +++ b/src/pal/src/exception/seh-unwind.cpp @@ -85,6 +85,33 @@ static void WinContextToUnwindContext(CONTEXT *winContext, unw_context_t *unwCon #undef ASSIGN_REG } #else +static void UpdateUnwindContextWithWinContext(CONTEXT *winContext, unw_context_t *unwContext) +{ +#if defined(_ARM_) + // Assuming that unw_set_reg() on cursor will point the cursor to the + // supposed stack frame is dangerous for libunwind-arm in Linux. + // It is because libunwind's unw_cursor_t has other data structure + // initialized by unw_init_local(), which are not updated by + // unw_set_reg(). + unwContext->regs[0] = 0; + unwContext->regs[1] = 0; + unwContext->regs[2] = 0; + unwContext->regs[3] = 0; + unwContext->regs[4] = winContext->R4; + unwContext->regs[5] = winContext->R5; + unwContext->regs[6] = winContext->R6; + unwContext->regs[7] = winContext->R7; + unwContext->regs[8] = winContext->R8; + unwContext->regs[9] = winContext->R9; + unwContext->regs[10] = winContext->R10; + unwContext->regs[11] = winContext->R11; + unwContext->regs[12] = 0; + unwContext->regs[13] = winContext->Sp; + unwContext->regs[14] = winContext->Lr; + unwContext->regs[15] = winContext->Pc; +#endif +} + static void WinContextToUnwindCursor(CONTEXT *winContext, unw_cursor_t *cursor) { #if defined(_AMD64_) @@ -96,30 +123,6 @@ static void WinContextToUnwindCursor(CONTEXT *winContext, unw_cursor_t *cursor) unw_set_reg(cursor, UNW_X86_64_R13, winContext->R13); unw_set_reg(cursor, UNW_X86_64_R14, winContext->R14); unw_set_reg(cursor, UNW_X86_64_R15, winContext->R15); -#elif defined(_ARM_) - // Assuming that unw_set_reg() on cursor will point the cursor to the - // supposed stack frame is dangerous for libunwind-arm in Linux. - // It is because libunwind's unw_cursor_t has other data structure - // initialized by unw_init_local(), which are not updated by - // unw_set_reg(). - unw_context_t context; - context.regs[0] = 0; - context.regs[1] = 0; - context.regs[2] = 0; - context.regs[3] = 0; - context.regs[4] = winContext->R4; - context.regs[5] = winContext->R5; - context.regs[6] = winContext->R6; - context.regs[7] = winContext->R7; - context.regs[8] = winContext->R8; - context.regs[9] = winContext->R9; - context.regs[10] = winContext->R10; - context.regs[11] = winContext->R11; - context.regs[12] = 0; - context.regs[13] = winContext->Sp; - context.regs[14] = winContext->Lr; - context.regs[15] = winContext->Pc; - unw_init_local(cursor, &context); #endif } #endif @@ -251,6 +254,11 @@ BOOL PAL_VirtualUnwind(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *contextP return FALSE; } #endif + +#if !UNWIND_CONTEXT_IS_UCONTEXT_T + UpdateUnwindContextWithWinContext(context, &unwContext); +#endif + st = unw_init_local(&cursor, &unwContext); if (st < 0) { |