aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/host/buildvm_asm.c9
-rw-r--r--src/lj_err.c92
-rw-r--r--src/vm_arm.dasc11
3 files changed, 84 insertions, 28 deletions
diff --git a/src/host/buildvm_asm.c b/src/host/buildvm_asm.c
index 9b7ae53a..9b119425 100644
--- a/src/host/buildvm_asm.c
+++ b/src/host/buildvm_asm.c
@@ -261,11 +261,20 @@ void emit_asm(BuildCtx *ctx)
261 261
262#if LJ_TARGET_ARM && defined(__GNUC__) && !LJ_NO_UNWIND 262#if LJ_TARGET_ARM && defined(__GNUC__) && !LJ_NO_UNWIND
263 /* This should really be moved into buildvm_arm.dasc. */ 263 /* This should really be moved into buildvm_arm.dasc. */
264#if LJ_ARCH_HASFPU
265 fprintf(ctx->fp,
266 ".fnstart\n"
267 ".save {r5, r6, r7, r8, r9, r10, r11, lr}\n"
268 ".vsave {d8-d15}\n"
269 ".save {r4}\n"
270 ".pad #28\n");
271#else
264 fprintf(ctx->fp, 272 fprintf(ctx->fp,
265 ".fnstart\n" 273 ".fnstart\n"
266 ".save {r4, r5, r6, r7, r8, r9, r10, r11, lr}\n" 274 ".save {r4, r5, r6, r7, r8, r9, r10, r11, lr}\n"
267 ".pad #28\n"); 275 ".pad #28\n");
268#endif 276#endif
277#endif
269#if LJ_TARGET_MIPS 278#if LJ_TARGET_MIPS
270 fprintf(ctx->fp, ".set nomips16\n.abicalls\n.set noreorder\n.set nomacro\n"); 279 fprintf(ctx->fp, ".set nomips16\n.abicalls\n.set noreorder\n.set nomacro\n");
271#endif 280#endif
diff --git a/src/lj_err.c b/src/lj_err.c
index 9ac0c988..d641735e 100644
--- a/src/lj_err.c
+++ b/src/lj_err.c
@@ -190,13 +190,6 @@ static void *err_unwind(lua_State *L, void *stopcf, int errcode)
190** since various OS, distros and compilers mess up the header installation. 190** since various OS, distros and compilers mess up the header installation.
191*/ 191*/
192 192
193typedef struct _Unwind_Exception
194{
195 uint64_t exclass;
196 void (*excleanup)(int, struct _Unwind_Exception *);
197 uintptr_t p1, p2;
198} __attribute__((__aligned__)) _Unwind_Exception;
199
200typedef struct _Unwind_Context _Unwind_Context; 193typedef struct _Unwind_Context _Unwind_Context;
201 194
202#define _URC_OK 0 195#define _URC_OK 0
@@ -206,8 +199,20 @@ typedef struct _Unwind_Context _Unwind_Context;
206#define _URC_CONTINUE_UNWIND 8 199#define _URC_CONTINUE_UNWIND 8
207#define _URC_FAILURE 9 200#define _URC_FAILURE 9
208 201
202#define LJ_UEXCLASS 0x4c55414a49543200ULL /* LUAJIT2\0 */
203#define LJ_UEXCLASS_MAKE(c) (LJ_UEXCLASS | (uint64_t)(c))
204#define LJ_UEXCLASS_CHECK(cl) (((cl) ^ LJ_UEXCLASS) <= 0xff)
205#define LJ_UEXCLASS_ERRCODE(cl) ((int)((cl) & 0xff))
206
209#if !LJ_TARGET_ARM 207#if !LJ_TARGET_ARM
210 208
209typedef struct _Unwind_Exception
210{
211 uint64_t exclass;
212 void (*excleanup)(int, struct _Unwind_Exception *);
213 uintptr_t p1, p2;
214} __attribute__((__aligned__)) _Unwind_Exception;
215
211extern uintptr_t _Unwind_GetCFA(_Unwind_Context *); 216extern uintptr_t _Unwind_GetCFA(_Unwind_Context *);
212extern void _Unwind_SetGR(_Unwind_Context *, int, uintptr_t); 217extern void _Unwind_SetGR(_Unwind_Context *, int, uintptr_t);
213extern void _Unwind_SetIP(_Unwind_Context *, uintptr_t); 218extern void _Unwind_SetIP(_Unwind_Context *, uintptr_t);
@@ -219,11 +224,6 @@ extern int _Unwind_RaiseException(_Unwind_Exception *);
219#define _UA_HANDLER_FRAME 4 224#define _UA_HANDLER_FRAME 4
220#define _UA_FORCE_UNWIND 8 225#define _UA_FORCE_UNWIND 8
221 226
222#define LJ_UEXCLASS 0x4c55414a49543200ULL /* LUAJIT2\0 */
223#define LJ_UEXCLASS_MAKE(c) (LJ_UEXCLASS | (uint64_t)(c))
224#define LJ_UEXCLASS_CHECK(cl) (((cl) ^ LJ_UEXCLASS) <= 0xff)
225#define LJ_UEXCLASS_ERRCODE(cl) ((int)((cl) & 0xff))
226
227/* DWARF2 personality handler referenced from interpreter .eh_frame. */ 227/* DWARF2 personality handler referenced from interpreter .eh_frame. */
228LJ_FUNCA int lj_err_unwind_dwarf(int version, int actions, 228LJ_FUNCA int lj_err_unwind_dwarf(int version, int actions,
229 uint64_t uexclass, _Unwind_Exception *uex, _Unwind_Context *ctx) 229 uint64_t uexclass, _Unwind_Exception *uex, _Unwind_Context *ctx)
@@ -302,10 +302,23 @@ static void err_raise_ext(int errcode)
302} 302}
303#endif 303#endif
304 304
305#else 305#else /* LJ_TARGET_ARM */
306
307#define _US_VIRTUAL_UNWIND_FRAME 0
308#define _US_UNWIND_FRAME_STARTING 1
309#define _US_ACTION_MASK 3
310#define _US_FORCE_UNWIND 8
311
312typedef struct _Unwind_Control_Block _Unwind_Control_Block;
313typedef struct _Unwind_Context _Unwind_Context;
314
315struct _Unwind_Control_Block {
316 uint64_t exclass;
317 uint32_t misc[20];
318};
306 319
307extern void _Unwind_DeleteException(void *); 320extern int _Unwind_RaiseException(_Unwind_Control_Block *);
308extern int __gnu_unwind_frame (void *, _Unwind_Context *); 321extern int __gnu_unwind_frame(_Unwind_Control_Block *, _Unwind_Context *);
309extern int _Unwind_VRS_Set(_Unwind_Context *, int, uint32_t, int, void *); 322extern int _Unwind_VRS_Set(_Unwind_Context *, int, uint32_t, int, void *);
310extern int _Unwind_VRS_Get(_Unwind_Context *, int, uint32_t, int, void *); 323extern int _Unwind_VRS_Get(_Unwind_Context *, int, uint32_t, int, void *);
311 324
@@ -321,34 +334,57 @@ static inline void _Unwind_SetGR(_Unwind_Context *ctx, int r, uint32_t v)
321 _Unwind_VRS_Set(ctx, 0, r, 0, &v); 334 _Unwind_VRS_Set(ctx, 0, r, 0, &v);
322} 335}
323 336
324#define _US_VIRTUAL_UNWIND_FRAME 0 337extern void lj_vm_unwind_ext(void);
325#define _US_UNWIND_FRAME_STARTING 1
326#define _US_ACTION_MASK 3
327#define _US_FORCE_UNWIND 8
328 338
329/* ARM unwinder personality handler referenced from interpreter .ARM.extab. */ 339/* ARM unwinder personality handler referenced from interpreter .ARM.extab. */
330LJ_FUNCA int lj_err_unwind_arm(int state, void *ucb, _Unwind_Context *ctx) 340LJ_FUNCA int lj_err_unwind_arm(int state, _Unwind_Control_Block *ucb,
341 _Unwind_Context *ctx)
331{ 342{
332 void *cf = (void *)_Unwind_GetGR(ctx, 13); 343 void *cf = (void *)_Unwind_GetGR(ctx, 13);
333 lua_State *L = cframe_L(cf); 344 lua_State *L = cframe_L(cf);
334 if ((state & _US_ACTION_MASK) == _US_VIRTUAL_UNWIND_FRAME) { 345 int errcode;
335 setstrV(L, L->top++, lj_err_str(L, LJ_ERR_ERRCPP)); 346
347 switch ((state & _US_ACTION_MASK)) {
348 case _US_VIRTUAL_UNWIND_FRAME:
349 if ((state & _US_FORCE_UNWIND)) break;
336 return _URC_HANDLER_FOUND; 350 return _URC_HANDLER_FOUND;
337 } 351 case _US_UNWIND_FRAME_STARTING:
338 if ((state&(_US_ACTION_MASK|_US_FORCE_UNWIND)) == _US_UNWIND_FRAME_STARTING) { 352 if (LJ_UEXCLASS_CHECK(ucb->exclass)) {
339 _Unwind_DeleteException(ucb); 353 errcode = LJ_UEXCLASS_ERRCODE(ucb->exclass);
340 _Unwind_SetGR(ctx, 15, (uint32_t)(void *)lj_err_throw); 354 } else {
341 _Unwind_SetGR(ctx, 0, (uint32_t)L); 355 errcode = LUA_ERRRUN;
342 _Unwind_SetGR(ctx, 1, (uint32_t)LUA_ERRRUN); 356 setstrV(L, L->top++, lj_err_str(L, LJ_ERR_ERRCPP));
357 }
358 cf = err_unwind(L, cf, errcode);
359 if ((state & _US_FORCE_UNWIND) || cf == NULL) break;
360 _Unwind_SetGR(ctx, 15, (uint32_t)lj_vm_unwind_ext);
361 _Unwind_SetGR(ctx, 0, (uint32_t)ucb);
362 _Unwind_SetGR(ctx, 1, (uint32_t)errcode);
363 _Unwind_SetGR(ctx, 2, cframe_unwind_ff(cf) ?
364 (uint32_t)lj_vm_unwind_ff_eh :
365 (uint32_t)lj_vm_unwind_c_eh);
343 return _URC_INSTALL_CONTEXT; 366 return _URC_INSTALL_CONTEXT;
367 default:
368 return _URC_FAILURE;
344 } 369 }
345 if (__gnu_unwind_frame(ucb, ctx) != _URC_OK) 370 if (__gnu_unwind_frame(ucb, ctx) != _URC_OK)
346 return _URC_FAILURE; 371 return _URC_FAILURE;
347 return _URC_CONTINUE_UNWIND; 372 return _URC_CONTINUE_UNWIND;
348} 373}
349 374
375#if LJ_UNWIND_EXT
376static __thread _Unwind_Control_Block static_uex;
377
378static void err_raise_ext(int errcode)
379{
380 memset(&static_uex, 0, sizeof(static_uex));
381 static_uex.exclass = LJ_UEXCLASS_MAKE(errcode);
382 _Unwind_RaiseException(&static_uex);
383}
350#endif 384#endif
351 385
386#endif /* LJ_TARGET_ARM */
387
352#elif LJ_TARGET_X64 && LJ_ABI_WIN 388#elif LJ_TARGET_X64 && LJ_ABI_WIN
353 389
354/* 390/*
diff --git a/src/vm_arm.dasc b/src/vm_arm.dasc
index af722f9e..acc0853b 100644
--- a/src/vm_arm.dasc
+++ b/src/vm_arm.dasc
@@ -373,6 +373,17 @@ static void build_subroutines(BuildCtx *ctx)
373 | st_vmstate CARG2 373 | st_vmstate CARG2
374 | b ->vm_returnc 374 | b ->vm_returnc
375 | 375 |
376 |->vm_unwind_ext: // Complete external unwind.
377#if !LJ_NO_UNWIND
378 | push {r0, r1, r2, lr}
379 | bl extern _Unwind_Complete
380 | ldr r0, [sp]
381 | bl extern _Unwind_DeleteException
382 | pop {r0, r1, r2, lr}
383 | mov r0, r1
384 | bx r2
385#endif
386 |
376 |//----------------------------------------------------------------------- 387 |//-----------------------------------------------------------------------
377 |//-- Grow stack for calls ----------------------------------------------- 388 |//-- Grow stack for calls -----------------------------------------------
378 |//----------------------------------------------------------------------- 389 |//-----------------------------------------------------------------------