summaryrefslogtreecommitdiff
path: root/src/pal/src/exception/seh-unwind.cpp
diff options
context:
space:
mode:
authorMyungJoo Ham <myungjoo.ham@samsung.com>2016-02-29 17:07:31 +0900
committerMyungJoo Ham <myungjoo.ham@samsung.com>2016-03-04 00:28:11 +0900
commit5c0095268e19e5a5fcf035c4c591ed03e552f072 (patch)
tree7f50c9c3de8081e9bbf45bc05daecad003e9d085 /src/pal/src/exception/seh-unwind.cpp
parentfdc40a40581f6a601ba508e33ad641640a956f91 (diff)
downloadcoreclr-5c0095268e19e5a5fcf035c4c591ed03e552f072.tar.gz
coreclr-5c0095268e19e5a5fcf035c4c591ed03e552f072.tar.bz2
coreclr-5c0095268e19e5a5fcf035c4c591ed03e552f072.zip
Fix Stack Unwind for ARM/Linux
Make context information compatible with libunwind-arm. In Linux/ARM, seh-unwind.cpp has been updating unw_cursor_t to point another stack by updating the cursor's register entries. However, that does not work in libunwind-arm in Linux, which breaks PAL_VirtualUnwind() functions. Getting the stack information from the cursor had a compatibility issue as well. This patch make both "context->cursor" and "cursor->context" methods compatible with ARM/Linux. Fix #3312 Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
Diffstat (limited to 'src/pal/src/exception/seh-unwind.cpp')
-rw-r--r--src/pal/src/exception/seh-unwind.cpp38
1 files changed, 25 insertions, 13 deletions
diff --git a/src/pal/src/exception/seh-unwind.cpp b/src/pal/src/exception/seh-unwind.cpp
index 5d3b353494..ea17cce29e 100644
--- a/src/pal/src/exception/seh-unwind.cpp
+++ b/src/pal/src/exception/seh-unwind.cpp
@@ -97,17 +97,29 @@ 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_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);
- unw_set_reg(cursor, UNW_ARM_R7, winContext->R7);
- unw_set_reg(cursor, UNW_ARM_R8, winContext->R8);
- unw_set_reg(cursor, UNW_ARM_R9, winContext->R9);
- unw_set_reg(cursor, UNW_ARM_R10, winContext->R10);
- unw_set_reg(cursor, UNW_ARM_R11, winContext->R11);
+ // 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
@@ -124,9 +136,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_ARM_R13, (unw_word_t *) &winContext->Sp);
+ unw_get_reg(cursor, UNW_REG_SP, (unw_word_t *) &winContext->Sp);
+ unw_get_reg(cursor, UNW_REG_IP, (unw_word_t *) &winContext->Pc);
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);