[SEH] Add initial support for AArch64
This doesn't yet implement inspecting the .pdata/.xdata to find the LSDA pointer (in UnwindCursor::getInfoFromSEH), but normal C++ exception handling seems to run just fine without it. (The only place I can see where it's even referenced is in unwind_phase2_forced, and I can't find a codepath where libcxxabi would end up calling that.) Differential Revision: https://reviews.llvm.org/D55674 llvm-svn: 349532
This commit is contained in:
parent
18a9d545e1
commit
09cf6374c1
|
@ -57,7 +57,11 @@
|
||||||
# elif defined(__aarch64__)
|
# elif defined(__aarch64__)
|
||||||
# define _LIBUNWIND_TARGET_AARCH64 1
|
# define _LIBUNWIND_TARGET_AARCH64 1
|
||||||
# define _LIBUNWIND_CONTEXT_SIZE 66
|
# define _LIBUNWIND_CONTEXT_SIZE 66
|
||||||
# define _LIBUNWIND_CURSOR_SIZE 78
|
# if defined(__SEH__)
|
||||||
|
# define _LIBUNWIND_CURSOR_SIZE 164
|
||||||
|
# else
|
||||||
|
# define _LIBUNWIND_CURSOR_SIZE 78
|
||||||
|
# endif
|
||||||
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64
|
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64
|
||||||
# elif defined(__arm__)
|
# elif defined(__arm__)
|
||||||
# define _LIBUNWIND_TARGET_ARM 1
|
# define _LIBUNWIND_TARGET_ARM 1
|
||||||
|
|
|
@ -87,6 +87,8 @@ _GCC_specific_handler(PEXCEPTION_RECORD ms_exc, PVOID frame, PCONTEXT ms_ctx,
|
||||||
disp->ContextRecord->Rdx = ms_exc->ExceptionInformation[3];
|
disp->ContextRecord->Rdx = ms_exc->ExceptionInformation[3];
|
||||||
#elif defined(__arm__)
|
#elif defined(__arm__)
|
||||||
disp->ContextRecord->R1 = ms_exc->ExceptionInformation[3];
|
disp->ContextRecord->R1 = ms_exc->ExceptionInformation[3];
|
||||||
|
#elif defined(__aarch64__)
|
||||||
|
disp->ContextRecord->X1 = ms_exc->ExceptionInformation[3];
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
// This is the collided unwind to the landing pad. Nothing to do.
|
// This is the collided unwind to the landing pad. Nothing to do.
|
||||||
|
@ -172,12 +174,16 @@ _GCC_specific_handler(PEXCEPTION_RECORD ms_exc, PVOID frame, PCONTEXT ms_ctx,
|
||||||
exc->private_[2] = disp->TargetPc;
|
exc->private_[2] = disp->TargetPc;
|
||||||
unw_get_reg(&cursor, UNW_ARM_R0, &retval);
|
unw_get_reg(&cursor, UNW_ARM_R0, &retval);
|
||||||
unw_get_reg(&cursor, UNW_ARM_R1, &exc->private_[3]);
|
unw_get_reg(&cursor, UNW_ARM_R1, &exc->private_[3]);
|
||||||
|
#elif defined(__aarch64__)
|
||||||
|
exc->private_[2] = disp->TargetPc;
|
||||||
|
unw_get_reg(&cursor, UNW_ARM64_X0, &retval);
|
||||||
|
unw_get_reg(&cursor, UNW_ARM64_X1, &exc->private_[3]);
|
||||||
#endif
|
#endif
|
||||||
unw_get_reg(&cursor, UNW_REG_IP, &target);
|
unw_get_reg(&cursor, UNW_REG_IP, &target);
|
||||||
ms_exc->ExceptionCode = STATUS_GCC_UNWIND;
|
ms_exc->ExceptionCode = STATUS_GCC_UNWIND;
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
ms_exc->ExceptionInformation[2] = disp->TargetIp;
|
ms_exc->ExceptionInformation[2] = disp->TargetIp;
|
||||||
#elif defined(__arm__)
|
#elif defined(__arm__) || defined(__aarch64__)
|
||||||
ms_exc->ExceptionInformation[2] = disp->TargetPc;
|
ms_exc->ExceptionInformation[2] = disp->TargetPc;
|
||||||
#endif
|
#endif
|
||||||
ms_exc->ExceptionInformation[3] = exc->private_[3];
|
ms_exc->ExceptionInformation[3] = exc->private_[3];
|
||||||
|
@ -447,6 +453,12 @@ _unw_init_seh(unw_cursor_t *cursor, CONTEXT *context) {
|
||||||
auto *co = reinterpret_cast<AbstractUnwindCursor *>(cursor);
|
auto *co = reinterpret_cast<AbstractUnwindCursor *>(cursor);
|
||||||
co->setInfoBasedOnIPRegister();
|
co->setInfoBasedOnIPRegister();
|
||||||
return UNW_ESUCCESS;
|
return UNW_ESUCCESS;
|
||||||
|
#elif defined(_LIBUNWIND_TARGET_AARCH64)
|
||||||
|
new ((void *)cursor) UnwindCursor<LocalAddressSpace, Registers_arm64>(
|
||||||
|
context, LocalAddressSpace::sThisAddressSpace);
|
||||||
|
auto *co = reinterpret_cast<AbstractUnwindCursor *>(cursor);
|
||||||
|
co->setInfoBasedOnIPRegister();
|
||||||
|
return UNW_ESUCCESS;
|
||||||
#else
|
#else
|
||||||
return UNW_EINVAL;
|
return UNW_EINVAL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -458,6 +470,8 @@ _unw_seh_get_disp_ctx(unw_cursor_t *cursor) {
|
||||||
return reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_x86_64> *>(cursor)->getDispatcherContext();
|
return reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_x86_64> *>(cursor)->getDispatcherContext();
|
||||||
#elif defined(_LIBUNWIND_TARGET_ARM)
|
#elif defined(_LIBUNWIND_TARGET_ARM)
|
||||||
return reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm> *>(cursor)->getDispatcherContext();
|
return reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm> *>(cursor)->getDispatcherContext();
|
||||||
|
#elif defined(_LIBUNWIND_TARGET_AARCH64)
|
||||||
|
return reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm64> *>(cursor)->getDispatcherContext();
|
||||||
#else
|
#else
|
||||||
return nullptr;
|
return nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
@ -469,6 +483,8 @@ _unw_seh_set_disp_ctx(unw_cursor_t *cursor, DISPATCHER_CONTEXT *disp) {
|
||||||
reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_x86_64> *>(cursor)->setDispatcherContext(disp);
|
reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_x86_64> *>(cursor)->setDispatcherContext(disp);
|
||||||
#elif defined(_LIBUNWIND_TARGET_ARM)
|
#elif defined(_LIBUNWIND_TARGET_ARM)
|
||||||
reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm> *>(cursor)->setDispatcherContext(disp);
|
reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm> *>(cursor)->setDispatcherContext(disp);
|
||||||
|
#elif defined(_LIBUNWIND_TARGET_AARCH64)
|
||||||
|
reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm64> *>(cursor)->setDispatcherContext(disp);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -615,6 +615,13 @@ UnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as)
|
||||||
d.d = r.getFloatRegister(i);
|
d.d = r.getFloatRegister(i);
|
||||||
_msContext.D[i - UNW_ARM_D0] = d.w;
|
_msContext.D[i - UNW_ARM_D0] = d.w;
|
||||||
}
|
}
|
||||||
|
#elif defined(_LIBUNWIND_TARGET_AARCH64)
|
||||||
|
for (int i = UNW_ARM64_X0; i <= UNW_ARM64_X30; ++i)
|
||||||
|
_msContext.X[i - UNW_ARM64_X0] = r.getRegister(i);
|
||||||
|
_msContext.Sp = r.getRegister(UNW_REG_SP);
|
||||||
|
_msContext.Pc = r.getRegister(UNW_REG_IP);
|
||||||
|
for (int i = UNW_ARM64_D0; i <= UNW_ARM64_D31; ++i)
|
||||||
|
_msContext.V[i - UNW_ARM64_D0].D[0] = r.getFloatRegister(i);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -638,6 +645,8 @@ bool UnwindCursor<A, R>::validReg(int regNum) {
|
||||||
if (regNum >= UNW_X86_64_RAX && regNum <= UNW_X86_64_R15) return true;
|
if (regNum >= UNW_X86_64_RAX && regNum <= UNW_X86_64_R15) return true;
|
||||||
#elif defined(_LIBUNWIND_TARGET_ARM)
|
#elif defined(_LIBUNWIND_TARGET_ARM)
|
||||||
if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15) return true;
|
if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15) return true;
|
||||||
|
#elif defined(_LIBUNWIND_TARGET_AARCH64)
|
||||||
|
if (regNum >= UNW_ARM64_X0 && regNum <= UNW_ARM64_X30) return true;
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -683,6 +692,10 @@ unw_word_t UnwindCursor<A, R>::getReg(int regNum) {
|
||||||
case UNW_ARM_LR: return _msContext.Lr;
|
case UNW_ARM_LR: return _msContext.Lr;
|
||||||
case UNW_REG_IP:
|
case UNW_REG_IP:
|
||||||
case UNW_ARM_IP: return _msContext.Pc;
|
case UNW_ARM_IP: return _msContext.Pc;
|
||||||
|
#elif defined(_LIBUNWIND_TARGET_AARCH64)
|
||||||
|
case UNW_REG_SP: return _msContext.Sp;
|
||||||
|
case UNW_REG_IP: return _msContext.Pc;
|
||||||
|
default: return _msContext.X[regNum - UNW_ARM64_X0];
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
_LIBUNWIND_ABORT("unsupported register");
|
_LIBUNWIND_ABORT("unsupported register");
|
||||||
|
@ -729,6 +742,40 @@ void UnwindCursor<A, R>::setReg(int regNum, unw_word_t value) {
|
||||||
case UNW_ARM_LR: _msContext.Lr = value; break;
|
case UNW_ARM_LR: _msContext.Lr = value; break;
|
||||||
case UNW_REG_IP:
|
case UNW_REG_IP:
|
||||||
case UNW_ARM_IP: _msContext.Pc = value; break;
|
case UNW_ARM_IP: _msContext.Pc = value; break;
|
||||||
|
#elif defined(_LIBUNWIND_TARGET_AARCH64)
|
||||||
|
case UNW_REG_SP: _msContext.Sp = value; break;
|
||||||
|
case UNW_REG_IP: _msContext.Pc = value; break;
|
||||||
|
case UNW_ARM64_X0:
|
||||||
|
case UNW_ARM64_X1:
|
||||||
|
case UNW_ARM64_X2:
|
||||||
|
case UNW_ARM64_X3:
|
||||||
|
case UNW_ARM64_X4:
|
||||||
|
case UNW_ARM64_X5:
|
||||||
|
case UNW_ARM64_X6:
|
||||||
|
case UNW_ARM64_X7:
|
||||||
|
case UNW_ARM64_X8:
|
||||||
|
case UNW_ARM64_X9:
|
||||||
|
case UNW_ARM64_X10:
|
||||||
|
case UNW_ARM64_X11:
|
||||||
|
case UNW_ARM64_X12:
|
||||||
|
case UNW_ARM64_X13:
|
||||||
|
case UNW_ARM64_X14:
|
||||||
|
case UNW_ARM64_X15:
|
||||||
|
case UNW_ARM64_X16:
|
||||||
|
case UNW_ARM64_X17:
|
||||||
|
case UNW_ARM64_X18:
|
||||||
|
case UNW_ARM64_X19:
|
||||||
|
case UNW_ARM64_X20:
|
||||||
|
case UNW_ARM64_X21:
|
||||||
|
case UNW_ARM64_X22:
|
||||||
|
case UNW_ARM64_X23:
|
||||||
|
case UNW_ARM64_X24:
|
||||||
|
case UNW_ARM64_X25:
|
||||||
|
case UNW_ARM64_X26:
|
||||||
|
case UNW_ARM64_X27:
|
||||||
|
case UNW_ARM64_X28:
|
||||||
|
case UNW_ARM64_FP:
|
||||||
|
case UNW_ARM64_LR: _msContext.X[regNum - UNW_ARM64_X0] = value; break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
_LIBUNWIND_ABORT("unsupported register");
|
_LIBUNWIND_ABORT("unsupported register");
|
||||||
|
@ -740,6 +787,8 @@ bool UnwindCursor<A, R>::validFloatReg(int regNum) {
|
||||||
#if defined(_LIBUNWIND_TARGET_ARM)
|
#if defined(_LIBUNWIND_TARGET_ARM)
|
||||||
if (regNum >= UNW_ARM_S0 && regNum <= UNW_ARM_S31) return true;
|
if (regNum >= UNW_ARM_S0 && regNum <= UNW_ARM_S31) return true;
|
||||||
if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D31) return true;
|
if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D31) return true;
|
||||||
|
#elif defined(_LIBUNWIND_TARGET_AARCH64)
|
||||||
|
if (regNum >= UNW_ARM64_D0 && regNum <= UNW_ARM64_D31) return true;
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -764,6 +813,8 @@ unw_fpreg_t UnwindCursor<A, R>::getFloatReg(int regNum) {
|
||||||
return d.d;
|
return d.d;
|
||||||
}
|
}
|
||||||
_LIBUNWIND_ABORT("unsupported float register");
|
_LIBUNWIND_ABORT("unsupported float register");
|
||||||
|
#elif defined(_LIBUNWIND_TARGET_AARCH64)
|
||||||
|
return _msContext.V[regNum - UNW_ARM64_D0].D[0];
|
||||||
#else
|
#else
|
||||||
_LIBUNWIND_ABORT("float registers unimplemented");
|
_LIBUNWIND_ABORT("float registers unimplemented");
|
||||||
#endif
|
#endif
|
||||||
|
@ -789,6 +840,8 @@ void UnwindCursor<A, R>::setFloatReg(int regNum, unw_fpreg_t value) {
|
||||||
_msContext.D[regNum - UNW_ARM_D0] = d.w;
|
_msContext.D[regNum - UNW_ARM_D0] = d.w;
|
||||||
}
|
}
|
||||||
_LIBUNWIND_ABORT("unsupported float register");
|
_LIBUNWIND_ABORT("unsupported float register");
|
||||||
|
#elif defined(_LIBUNWIND_TARGET_AARCH64)
|
||||||
|
_msContext.V[regNum - UNW_ARM64_D0].D[0] = value;
|
||||||
#else
|
#else
|
||||||
_LIBUNWIND_ABORT("float registers unimplemented");
|
_LIBUNWIND_ABORT("float registers unimplemented");
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue