summaryrefslogtreecommitdiff
path: root/src/pal/src/exception/seh-unwind.cpp
diff options
context:
space:
mode:
authorGeoff Norton <grompf@gmail.com>2015-07-25 14:48:20 +0900
committerGeoff Norton <grompf@gmail.com>2015-07-27 21:12:04 -0700
commit16c43e35d1a9a858374757ccf0484a50afdb0b69 (patch)
tree1e8977500a18b28c00716d5378a1d5f0afa3b7a3 /src/pal/src/exception/seh-unwind.cpp
parent0a83c2fc30146b335a24c85de2a5ba33a72bdbdd (diff)
downloadcoreclr-16c43e35d1a9a858374757ccf0484a50afdb0b69.tar.gz
coreclr-16c43e35d1a9a858374757ccf0484a50afdb0b69.tar.bz2
coreclr-16c43e35d1a9a858374757ccf0484a50afdb0b69.zip
[aarch64] Initial aarch64/linux bring up
Diffstat (limited to 'src/pal/src/exception/seh-unwind.cpp')
-rw-r--r--src/pal/src/exception/seh-unwind.cpp78
1 files changed, 71 insertions, 7 deletions
diff --git a/src/pal/src/exception/seh-unwind.cpp b/src/pal/src/exception/seh-unwind.cpp
index 9dd025c51d..aee921dd06 100644
--- a/src/pal/src/exception/seh-unwind.cpp
+++ b/src/pal/src/exception/seh-unwind.cpp
@@ -50,6 +50,22 @@ Abstract:
ASSIGN_REG(R13) \
ASSIGN_REG(R14) \
ASSIGN_REG(R15)
+#elif defined(_ARM64_)
+#define ASSIGN_UNWIND_REGS \
+ ASSIGN_REG(Pc) \
+ ASSIGN_REG(Sp) \
+ ASSIGN_REG(Fp) \
+ ASSIGN_REG(Lr) \
+ ASSIGN_REG(X19) \
+ ASSIGN_REG(X20) \
+ ASSIGN_REG(X21) \
+ ASSIGN_REG(X22) \
+ ASSIGN_REG(X23) \
+ ASSIGN_REG(X24) \
+ ASSIGN_REG(X25) \
+ ASSIGN_REG(X26) \
+ ASSIGN_REG(X27) \
+ ASSIGN_REG(X28)
#else
#error unsupported architecture
#endif
@@ -111,6 +127,21 @@ static void UnwindContextToWinContext(unw_cursor_t *cursor, CONTEXT *winContext)
unw_get_reg(cursor, UNW_ARM_R9, (unw_word_t *) &winContext->R9);
unw_get_reg(cursor, UNW_ARM_R10, (unw_word_t *) &winContext->R10);
unw_get_reg(cursor, UNW_ARM_R11, (unw_word_t *) &winContext->R11);
+#elif defined(_ARM64_)
+ 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_AARCH64_X29, (unw_word_t *) &winContext->Fp);
+ unw_get_reg(cursor, UNW_AARCH64_X30, (unw_word_t *) &winContext->Lr);
+ unw_get_reg(cursor, UNW_AARCH64_X19, (unw_word_t *) &winContext->X19);
+ unw_get_reg(cursor, UNW_AARCH64_X20, (unw_word_t *) &winContext->X20);
+ unw_get_reg(cursor, UNW_AARCH64_X21, (unw_word_t *) &winContext->X21);
+ unw_get_reg(cursor, UNW_AARCH64_X22, (unw_word_t *) &winContext->X22);
+ unw_get_reg(cursor, UNW_AARCH64_X23, (unw_word_t *) &winContext->X23);
+ unw_get_reg(cursor, UNW_AARCH64_X24, (unw_word_t *) &winContext->X24);
+ unw_get_reg(cursor, UNW_AARCH64_X25, (unw_word_t *) &winContext->X25);
+ unw_get_reg(cursor, UNW_AARCH64_X26, (unw_word_t *) &winContext->X26);
+ unw_get_reg(cursor, UNW_AARCH64_X27, (unw_word_t *) &winContext->X27);
+ unw_get_reg(cursor, UNW_AARCH64_X28, (unw_word_t *) &winContext->X28);
#else
#error unsupported architecture
#endif
@@ -152,17 +183,50 @@ static void GetContextPointers(unw_cursor_t *cursor, unw_context_t *unwContext,
GetContextPointer(cursor, unwContext, UNW_ARM_R9, &contextPointers->R9);
GetContextPointer(cursor, unwContext, UNW_ARM_R10, &contextPointers->R10);
GetContextPointer(cursor, unwContext, UNW_ARM_R11, &contextPointers->R11);
+#elif defined(_ARM64_)
+ GetContextPointer(cursor, unwContext, UNW_AARCH64_X19, &contextPointers->X19);
+ GetContextPointer(cursor, unwContext, UNW_AARCH64_X20, &contextPointers->X20);
+ GetContextPointer(cursor, unwContext, UNW_AARCH64_X21, &contextPointers->X21);
+ GetContextPointer(cursor, unwContext, UNW_AARCH64_X22, &contextPointers->X22);
+ GetContextPointer(cursor, unwContext, UNW_AARCH64_X23, &contextPointers->X23);
+ GetContextPointer(cursor, unwContext, UNW_AARCH64_X24, &contextPointers->X24);
+ GetContextPointer(cursor, unwContext, UNW_AARCH64_X25, &contextPointers->X25);
+ GetContextPointer(cursor, unwContext, UNW_AARCH64_X26, &contextPointers->X26);
+ GetContextPointer(cursor, unwContext, UNW_AARCH64_X27, &contextPointers->X27);
+ GetContextPointer(cursor, unwContext, UNW_AARCH64_X28, &contextPointers->X28);
#else
#error unsupported architecture
#endif
}
+static DWORD64 GetPc(CONTEXT *context)
+{
+#if defined(_AMD64_)
+ return context->Rip;
+#elif defined(_ARM64_)
+ return context->Pc;
+#else
+#error don't know how to get the program counter for this architecture
+#endif
+}
+
+static void SetPc(CONTEXT *context, DWORD64 pc)
+{
+#if defined(_AMD64_)
+ context->Rip = pc;
+#elif defined(_ARM64_)
+ context->Pc = pc;
+#else
+#error don't know how to set the program counter for this architecture
+#endif
+}
+
BOOL PAL_VirtualUnwind(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *contextPointers)
{
int st;
unw_context_t unwContext;
unw_cursor_t cursor;
-#if defined(__APPLE__) || defined(__FreeBSD__)
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(_ARM64_)
DWORD64 curPc;
#endif
@@ -187,7 +251,7 @@ BOOL PAL_VirtualUnwind(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *contextP
WinContextToUnwindCursor(context, &cursor);
#endif
-#if defined(__APPLE__) || defined(__FreeBSD__)
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(_ARM64_)
// OSX and FreeBSD appear to do two different things when unwinding
// 1: If it reaches where it cannot unwind anymore, say a
// managed frame. It wil return 0, but also update the $pc
@@ -196,7 +260,7 @@ BOOL PAL_VirtualUnwind(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *contextP
// The behaviour of libunwind from nongnu.org is to null the PC
// So we bank the original PC here, so we can compare it after
// the step
- curPc = context->Rip;
+ curPc = GetPc(context);
#endif
st = unw_step(&cursor);
@@ -208,10 +272,10 @@ BOOL PAL_VirtualUnwind(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *contextP
// Update the passed in windows context to reflect the unwind
//
UnwindContextToWinContext(&cursor, context);
-#if defined(__APPLE__) || defined(__FreeBSD__)
- if (st == 0 && context->Rip == curPc)
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(_ARM64_)
+ if (st == 0 && GetPc(context) == curPc)
{
- context->Rip = 0;
+ SetPc(context, 0);
}
#endif
@@ -257,7 +321,7 @@ static void RtlpRaiseException(EXCEPTION_RECORD *ExceptionRecord)
ExceptionRecord->ExceptionAddress = (void *) ContextRecord.Eip;
#elif defined(_AMD64_)
ExceptionRecord->ExceptionAddress = (void *) ContextRecord.Rip;
-#elif defined(_ARM_)
+#elif defined(_ARM_) || defined(_ARM64_)
ExceptionRecord->ExceptionAddress = (void *) ContextRecord.Pc;
#else
#error unsupported architecture