forked from OSchip/llvm-project
[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__)
|
||||
# define _LIBUNWIND_TARGET_AARCH64 1
|
||||
# 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
|
||||
# elif defined(__arm__)
|
||||
# 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];
|
||||
#elif defined(__arm__)
|
||||
disp->ContextRecord->R1 = ms_exc->ExceptionInformation[3];
|
||||
#elif defined(__aarch64__)
|
||||
disp->ContextRecord->X1 = ms_exc->ExceptionInformation[3];
|
||||
#endif
|
||||
}
|
||||
// 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;
|
||||
unw_get_reg(&cursor, UNW_ARM_R0, &retval);
|
||||
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
|
||||
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__)
|
||||
#elif defined(__arm__) || defined(__aarch64__)
|
||||
ms_exc->ExceptionInformation[2] = disp->TargetPc;
|
||||
#endif
|
||||
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);
|
||||
co->setInfoBasedOnIPRegister();
|
||||
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
|
||||
return UNW_EINVAL;
|
||||
#endif
|
||||
|
@ -458,6 +470,8 @@ _unw_seh_get_disp_ctx(unw_cursor_t *cursor) {
|
|||
return reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_x86_64> *>(cursor)->getDispatcherContext();
|
||||
#elif defined(_LIBUNWIND_TARGET_ARM)
|
||||
return reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm> *>(cursor)->getDispatcherContext();
|
||||
#elif defined(_LIBUNWIND_TARGET_AARCH64)
|
||||
return reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm64> *>(cursor)->getDispatcherContext();
|
||||
#else
|
||||
return nullptr;
|
||||
#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);
|
||||
#elif defined(_LIBUNWIND_TARGET_ARM)
|
||||
reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm> *>(cursor)->setDispatcherContext(disp);
|
||||
#elif defined(_LIBUNWIND_TARGET_AARCH64)
|
||||
reinterpret_cast<UnwindCursor<LocalAddressSpace, Registers_arm64> *>(cursor)->setDispatcherContext(disp);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -615,6 +615,13 @@ UnwindCursor<A, R>::UnwindCursor(unw_context_t *context, A &as)
|
|||
d.d = r.getFloatRegister(i);
|
||||
_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
|
||||
}
|
||||
|
||||
|
@ -638,6 +645,8 @@ bool UnwindCursor<A, R>::validReg(int regNum) {
|
|||
if (regNum >= UNW_X86_64_RAX && regNum <= UNW_X86_64_R15) return true;
|
||||
#elif defined(_LIBUNWIND_TARGET_ARM)
|
||||
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
|
||||
return false;
|
||||
}
|
||||
|
@ -683,6 +692,10 @@ unw_word_t UnwindCursor<A, R>::getReg(int regNum) {
|
|||
case UNW_ARM_LR: return _msContext.Lr;
|
||||
case UNW_REG_IP:
|
||||
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
|
||||
}
|
||||
_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_REG_IP:
|
||||
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
|
||||
default:
|
||||
_LIBUNWIND_ABORT("unsupported register");
|
||||
|
@ -740,6 +787,8 @@ bool UnwindCursor<A, R>::validFloatReg(int regNum) {
|
|||
#if defined(_LIBUNWIND_TARGET_ARM)
|
||||
if (regNum >= UNW_ARM_S0 && regNum <= UNW_ARM_S31) 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
|
||||
return false;
|
||||
}
|
||||
|
@ -764,6 +813,8 @@ unw_fpreg_t UnwindCursor<A, R>::getFloatReg(int regNum) {
|
|||
return d.d;
|
||||
}
|
||||
_LIBUNWIND_ABORT("unsupported float register");
|
||||
#elif defined(_LIBUNWIND_TARGET_AARCH64)
|
||||
return _msContext.V[regNum - UNW_ARM64_D0].D[0];
|
||||
#else
|
||||
_LIBUNWIND_ABORT("float registers unimplemented");
|
||||
#endif
|
||||
|
@ -789,6 +840,8 @@ void UnwindCursor<A, R>::setFloatReg(int regNum, unw_fpreg_t value) {
|
|||
_msContext.D[regNum - UNW_ARM_D0] = d.w;
|
||||
}
|
||||
_LIBUNWIND_ABORT("unsupported float register");
|
||||
#elif defined(_LIBUNWIND_TARGET_AARCH64)
|
||||
_msContext.V[regNum - UNW_ARM64_D0].D[0] = value;
|
||||
#else
|
||||
_LIBUNWIND_ABORT("float registers unimplemented");
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue