_Unwind_VRS_Result _Unwind_VRS_Pop( _Unwind_Context *context, _Unwind_VRS_RegClass regclass, uint32_t discriminator, _Unwind_VRS_DataRepresentation representation) { if (regclass != _UVRSC_CORE || representation != _UVRSD_UINT32) { // TODO(piman): VFP, ... _LIBUNWIND_ABORT("during phase1 personality function said it would " "stop here, but now if phase2 it did not stop here"); return _UVRSR_NOT_IMPLEMENTED; } bool do13 = false; uint32_t reg13Value = 0; uint32_t* sp; if (_Unwind_VRS_Get(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, &sp) != _UVRSR_OK) { return _UVRSR_FAILED; } for (int i = 0; i < 16; ++i) { if (!(discriminator & (1<<i))) continue; uint32_t value = *sp++; if (i == 13) { reg13Value = value; do13 = true; } else { if (_Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_R0 + i, _UVRSD_UINT32, &value) != _UVRSR_OK) { return _UVRSR_FAILED; } } } if (do13) { return _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, ®13Value); } else { return _Unwind_VRS_Set(context, _UVRSC_CORE, UNW_ARM_SP, _UVRSD_UINT32, &sp); } }
// Older versions of Clang don't provide a definition of _Unwind_GetIP(), so // we include an appropriate version of our own. Once we have updated to // Clang 3.4, this code can be removed. static __inline__ uintptr_t _Unwind_GetIP(struct _Unwind_Context *__context) { uintptr_t __ip = 0; _Unwind_VRS_Get(__context, _UVRSC_CORE, 15, _UVRSD_UINT32, &__ip); return __ip & ~0x1; }
static inline uint32_t _Unwind_GetGR(_Unwind_Context *ctx, int r) { uint32_t v; _Unwind_VRS_Get(ctx, 0, r, 0, &v); return v; }
uint64_t WRAP(_Unwind_GetGR)(struct _Unwind_Context* ctx, int index) { uint32_t val; _Unwind_VRS_Get(ctx, _UVRSC_CORE, index, _UVRSD_UINT32, &val); return (uint64_t)val; }