Fix existing code for SEH on ARM to compile correctly
authorMartin Storsjo <martin@martin.st>
Fri, 31 Aug 2018 14:56:55 +0000 (14:56 +0000)
committerMartin Storsjo <martin@martin.st>
Fri, 31 Aug 2018 14:56:55 +0000 (14:56 +0000)
Even though SEH for ARM is incomplete, make what code already exists
at least compile correctly.

The _LIBUNWIND_CURSOR_SIZE wasn't correct.

ARM (and AArch64) have a DISPATCHER_CONTEXT field named TargetPc
instead of TargetIp.

For the libunwind.h UNW_* constants, there is no UNW_ARM_PC, only
UNW_ARM_IP.

Don't use 'r' as loop variable when 'r' already is a Registers_arm
member.

Differential Revision: https://reviews.llvm.org/D51530

llvm-svn: 341217

libunwind/include/__libunwind_config.h
libunwind/src/Unwind-seh.cpp
libunwind/src/UnwindCursor.hpp

index 0704946..a1e2f6d 100644 (file)
@@ -63,7 +63,7 @@
 #  define _LIBUNWIND_TARGET_ARM 1
 #  if defined(__SEH__)
 #    define _LIBUNWIND_CONTEXT_SIZE 42
-#    define _LIBUNWIND_CURSOR_SIZE 85
+#    define _LIBUNWIND_CURSOR_SIZE 80
 #  elif defined(__ARM_WMMX)
 #    define _LIBUNWIND_CONTEXT_SIZE 61
 #    define _LIBUNWIND_CURSOR_SIZE 68
index aaf2e98..73616a8 100644 (file)
@@ -164,17 +164,22 @@ _GCC_specific_handler(PEXCEPTION_RECORD ms_exc, PVOID frame, PCONTEXT ms_ctx,
     // This should never happen in phase 1.
     if (!IS_UNWINDING(ms_exc->ExceptionFlags))
       _LIBUNWIND_ABORT("Personality installed context during phase 1!");
-    exc->private_[2] = disp->TargetIp;
 #ifdef __x86_64__
+    exc->private_[2] = disp->TargetIp;
     unw_get_reg(&cursor, UNW_X86_64_RAX, &retval);
     unw_get_reg(&cursor, UNW_X86_64_RDX, &exc->private_[3]);
 #elif defined(__arm__)
+    exc->private_[2] = disp->TargetPc;
     unw_get_reg(&cursor, UNW_ARM_R0, &retval);
     unw_get_reg(&cursor, UNW_ARM_R1, &exc->private_[3]);
 #endif
     unw_get_reg(&cursor, UNW_REG_IP, &target);
     ms_exc->ExceptionCode = STATUS_GCC_UNWIND;
+#ifdef __x86_64__
     ms_exc->ExceptionInformation[2] = disp->TargetIp;
+#elif defined(__arm__)
+    ms_exc->ExceptionInformation[2] = disp->TargetPc;
+#endif
     ms_exc->ExceptionInformation[3] = exc->private_[3];
     // Give NTRTL some scratch space to keep track of the collided unwind.
     // Don't use the one that was passed in; we don't want to overwrite the
index 7c1506a..7ea75cc 100644 (file)
@@ -606,14 +606,14 @@ UnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as)
   _msContext.R12 = r.getRegister(UNW_ARM_R12);
   _msContext.Sp = r.getRegister(UNW_ARM_SP);
   _msContext.Lr = r.getRegister(UNW_ARM_LR);
-  _msContext.Pc = r.getRegister(UNW_ARM_PC);
-  for (int r = UNW_ARM_D0; r <= UNW_ARM_D31; ++r) {
+  _msContext.Pc = r.getRegister(UNW_ARM_IP);
+  for (int i = UNW_ARM_D0; i <= UNW_ARM_D31; ++i) {
     union {
       uint64_t w;
       double d;
     } d;
-    d.d = r.getFloatRegister(r);
-    _msContext.D[r - UNW_ARM_D0] = d.w;
+    d.d = r.getFloatRegister(i);
+    _msContext.D[i - UNW_ARM_D0] = d.w;
   }
 #endif
 }
@@ -682,7 +682,7 @@ unw_word_t UnwindCursor<A, R>::getReg(int regNum) {
   case UNW_ARM_SP: return _msContext.Sp;
   case UNW_ARM_LR: return _msContext.Lr;
   case UNW_REG_IP:
-  case UNW_ARM_PC: return _msContext.Pc;
+  case UNW_ARM_IP: return _msContext.Pc;
 #endif
   }
   _LIBUNWIND_ABORT("unsupported register");
@@ -728,7 +728,7 @@ void UnwindCursor<A, R>::setReg(int regNum, unw_word_t value) {
   case UNW_ARM_SP: _msContext.Sp = value; break;
   case UNW_ARM_LR: _msContext.Lr = value; break;
   case UNW_REG_IP:
-  case UNW_ARM_PC: _msContext.Pc = value; break;
+  case UNW_ARM_IP: _msContext.Pc = value; break;
 #endif
   default:
     _LIBUNWIND_ABORT("unsupported register");
@@ -842,7 +842,7 @@ const char *UnwindCursor<A, R>::getRegisterName(int regNum) {
   case UNW_ARM_SP: return "sp";
   case UNW_ARM_LR: return "lr";
   case UNW_REG_IP:
-  case UNW_ARM_PC: return "pc";
+  case UNW_ARM_IP: return "pc";
   case UNW_ARM_S0: return "s0";
   case UNW_ARM_S1: return "s1";
   case UNW_ARM_S2: return "s2";