if (ctx->mode != BUILD_machasm)
fprintf(ctx->fp, ".Lbegin:\n");
+#if LJ_TARGET_ARM && defined(__GNUC__)
+ /* This should really be moved into buildvm_arm.dasc. */
+ fprintf(ctx->fp,
+ ".fnstart\n"
+ ".save {r4, r5, r6, r7, r8, r9, r10, r11, lr}\n"
+ ".pad #28\n");
+#endif
+
for (i = rel = 0; i < ctx->nsym; i++) {
int32_t ofs = ctx->sym[i].ofs;
int32_t next = ctx->sym[i+1].ofs;
#endif
}
+#if LJ_TARGET_ARM && defined(__GNUC__)
+ fprintf(ctx->fp,
+ ".globl lj_err_unwind_arm\n"
+ ".personality lj_err_unwind_arm\n"
+ ".fnend\n");
+#endif
+
fprintf(ctx->fp, "\n");
switch (ctx->mode) {
case BUILD_elfasm:
/* -- External frame unwinding -------------------------------------------- */
-#if defined(__GNUC__) && !LJ_TARGET_ARM
+#if defined(__GNUC__)
#ifdef __clang__
/* http://llvm.org/bugs/show_bug.cgi?id=8703 */
#define LJ_UEXCLASS_CHECK(cl) (((cl) ^ LJ_UEXCLASS) <= 0xff)
#define LJ_UEXCLASS_ERRCODE(cl) ((int)((cl) & 0xff))
+#if !LJ_TARGET_ARM
+
/* DWARF2 personality handler referenced from interpreter .eh_frame. */
LJ_FUNCA int lj_err_unwind_dwarf(int version, _Unwind_Action actions,
_Unwind_Exception_Class uexclass, struct _Unwind_Exception *uex,
}
#endif
+#else
+
+/* ARM unwinder personality handler referenced from interpreter .ARM.extab. */
+LJ_FUNCA _Unwind_Reason_Code lj_err_unwind_arm(_Unwind_State state,
+ _Unwind_Control_Block *ucb,
+ _Unwind_Context *ctx)
+{
+ void *cf = (void *)_Unwind_GetGR(ctx, 13);
+ lua_State *L = cframe_L(cf);
+ if ((state & _US_ACTION_MASK) == _US_VIRTUAL_UNWIND_FRAME) {
+ setstrV(L, L->top++, lj_err_str(L, LJ_ERR_ERRCPP));
+ return _URC_HANDLER_FOUND;
+ }
+ if ((state & _US_ACTION_MASK) == _US_UNWIND_FRAME_STARTING) {
+ _Unwind_DeleteException(ucb);
+ _Unwind_SetGR(ctx, 15, (_Unwind_Word)(void *)lj_err_throw);
+ _Unwind_SetGR(ctx, 0, (_Unwind_Word)L);
+ _Unwind_SetGR(ctx, 1, (_Unwind_Word)LUA_ERRRUN);
+ return _URC_INSTALL_CONTEXT;
+ }
+ if (__gnu_unwind_frame(ucb, ctx) != _URC_OK)
+ return _URC_FAILURE;
+ return _URC_CONTINUE_UNWIND;
+}
+
+#endif
+
#elif LJ_TARGET_X64 && LJ_TARGET_WINDOWS
/*