summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Kotas <jkotas@microsoft.com>2016-03-04 09:36:05 -0800
committerJan Kotas <jkotas@microsoft.com>2016-03-04 09:36:05 -0800
commit41d393fc361359b0143dc5ae62ae3a255e052d78 (patch)
treea6ba1e0ac5f7219ebf1bbf45128bd10efdc20633
parentf80c2fbb673dce9b049e4d02d0b8eadf998e9ea2 (diff)
parent35b5df6888f1574e6ef9313c6bc8522d1817573d (diff)
downloadcoreclr-41d393fc361359b0143dc5ae62ae3a255e052d78.tar.gz
coreclr-41d393fc361359b0143dc5ae62ae3a255e052d78.tar.bz2
coreclr-41d393fc361359b0143dc5ae62ae3a255e052d78.zip
Merge pull request #3502 from myungjoo/fix/3462_arm_linux_stack
ARM-Linux Fixes (Issue #3462)
-rw-r--r--src/coreclr/hosts/unixcoreruncommon/coreruncommon.cpp14
-rw-r--r--src/pal/src/config.h.in2
-rw-r--r--src/pal/src/configure.cmake24
-rw-r--r--src/pal/src/exception/seh-unwind.cpp39
4 files changed, 64 insertions, 15 deletions
diff --git a/src/coreclr/hosts/unixcoreruncommon/coreruncommon.cpp b/src/coreclr/hosts/unixcoreruncommon/coreruncommon.cpp
index 1125dfb819..8d32a7d390 100644
--- a/src/coreclr/hosts/unixcoreruncommon/coreruncommon.cpp
+++ b/src/coreclr/hosts/unixcoreruncommon/coreruncommon.cpp
@@ -268,6 +268,20 @@ int ExecuteManagedAssembly(
// Indicates failure
int exitCode = -1;
+#ifdef _ARM_
+ // LIBUNWIND-ARM has a bug of side effect with DWARF mode
+ // Ref: https://github.com/dotnet/coreclr/issues/3462
+ // This is why Fedora is disabling it by default as well.
+ // Assuming that we cannot enforce the user to set
+ // environmental variables for third party packages,
+ // we set the environmental variable of libunwind locally here.
+
+ // Without this, any exception handling will fail, so let's do this
+ // as early as possible.
+ // 0x1: DWARF / 0x2: FRAME / 0x4: EXIDX
+ putenv("UNW_ARM_UNWIND_METHOD=6");
+#endif // _ARM_
+
std::string coreClrDllPath(clrFilesAbsolutePath);
coreClrDllPath.append("/");
coreClrDllPath.append(coreClrDll);
diff --git a/src/pal/src/config.h.in b/src/pal/src/config.h.in
index 68cb81ba67..784383f8dd 100644
--- a/src/pal/src/config.h.in
+++ b/src/pal/src/config.h.in
@@ -53,6 +53,8 @@
#cmakedefine01 HAS_SYSV_SEMAPHORES
#cmakedefine01 HAS_PTHREAD_MUTEXES
#cmakedefine01 HAVE_TTRACE
+#cmakedefine HAVE_UNW_GET_SAVE_LOC
+#cmakedefine HAVE_UNW_GET_ACCESSORS
#cmakedefine01 HAVE_STAT_TIMESPEC
#cmakedefine01 HAVE_STAT_NSEC
diff --git a/src/pal/src/configure.cmake b/src/pal/src/configure.cmake
index be6114d48c..daa99622fe 100644
--- a/src/pal/src/configure.cmake
+++ b/src/pal/src/configure.cmake
@@ -73,8 +73,28 @@ check_function_exists(directio HAVE_DIRECTIO)
check_function_exists(semget HAS_SYSV_SEMAPHORES)
check_function_exists(pthread_mutex_init HAS_PTHREAD_MUTEXES)
check_function_exists(ttrace HAVE_TTRACE)
-check_function_exists(unw_get_save_loc HAVE_UNW_GET_SAVE_LOC)
-check_function_exists(unw_get_accessors HAVE_UNW_GET_ACCESSORS)
+set(CMAKE_REQUIRED_LIBRARIES unwind unwind-generic)
+check_cxx_source_compiles("
+#include <libunwind.h>
+
+int main(int argc, char **argv) {
+ unw_cursor_t cursor;
+ unw_save_loc_t saveLoc;
+ int reg = UNW_REG_IP;
+ unw_get_save_loc(&cursor, reg, &saveLoc);
+
+ return 0;
+}" HAVE_UNW_GET_SAVE_LOC)
+check_cxx_source_compiles("
+#include <libunwind.h>
+
+int main(int argc, char **argv) {
+ unw_addr_space_t as;
+ unw_get_accessors(as);
+
+ return 0;
+}" HAVE_UNW_GET_ACCESSORS)
+set(CMAKE_REQUIRED_LIBRARIES)
check_struct_has_member ("struct stat" st_atimespec "sys/types.h;sys/stat.h" HAVE_STAT_TIMESPEC)
check_struct_has_member ("struct stat" st_atimensec "sys/types.h;sys/stat.h" HAVE_STAT_NSEC)
diff --git a/src/pal/src/exception/seh-unwind.cpp b/src/pal/src/exception/seh-unwind.cpp
index 5d3b353494..333544379a 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,10 @@ 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);
+ winContext->Pc &= ~0x1;
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);