diff --git a/src/buildvm_ppc.dasc b/src/buildvm_ppc.dasc index 2b4e1da6..c6bf24b7 100644 --- a/src/buildvm_ppc.dasc +++ b/src/buildvm_ppc.dasc @@ -2773,7 +2773,89 @@ static int build_backend(BuildCtx *ctx) /* Emit pseudo frame-info for all assembler functions. */ static void emit_asm_debug(BuildCtx *ctx) { - /* NYI */ - UNUSED(ctx); + int i; + switch (ctx->mode) { + case BUILD_elfasm: + fprintf(ctx->fp, "\t.section .debug_frame,\"\",@progbits\n"); + fprintf(ctx->fp, + ".Lframe0:\n" + "\t.long .LECIE0-.LSCIE0\n" + ".LSCIE0:\n" + "\t.long 0xffffffff\n" + "\t.byte 0x1\n" + "\t.string \"\"\n" + "\t.uleb128 0x1\n" + "\t.sleb128 -4\n" + "\t.byte 65\n" + "\t.byte 0xc\n\t.uleb128 1\n\t.uleb128 0\n" + "\t.align 2\n" + ".LECIE0:\n\n"); + fprintf(ctx->fp, + ".LSFDE0:\n" + "\t.long .LEFDE0-.LASFDE0\n" + ".LASFDE0:\n" + "\t.long .Lframe0\n" + "\t.long .Lbegin\n" + "\t.long %d\n" + "\t.byte 0xe\n\t.uleb128 %d\n" + "\t.byte 0x11\n\t.uleb128 65\n\t.sleb128 -1\n", + (int)ctx->codesz, CFRAME_SIZE); + for (i = 14; i <= 31; i++) +#if LJ_TARGET_PPCSPE + fprintf(ctx->fp, + "\t.byte %d\n\t.uleb128 %d\n" + "\t.byte 5\n\t.uleb128 %d\n\t.uleb128 %d\n", + 0x80+i, 1+2*(31-i), 1200+i, 2+2*(31-i)); +#else +#error "missing frame info for saved registers" +#endif + fprintf(ctx->fp, + "\t.align 2\n" + ".LEFDE0:\n\n"); + fprintf(ctx->fp, "\t.section .eh_frame,\"a\",@progbits\n"); + fprintf(ctx->fp, + ".Lframe1:\n" + "\t.long .LECIE1-.LSCIE1\n" + ".LSCIE1:\n" + "\t.long 0\n" + "\t.byte 0x1\n" + "\t.string \"zPR\"\n" + "\t.uleb128 0x1\n" + "\t.sleb128 -4\n" + "\t.byte 65\n" + "\t.uleb128 6\n" /* augmentation length */ + "\t.byte 0x1b\n" /* pcrel|sdata4 */ + "\t.long lj_err_unwind_dwarf-.\n" + "\t.byte 0x1b\n" /* pcrel|sdata4 */ + "\t.byte 0xc\n\t.uleb128 1\n\t.uleb128 0\n" + "\t.align 2\n" + ".LECIE1:\n\n"); + fprintf(ctx->fp, + ".LSFDE1:\n" + "\t.long .LEFDE1-.LASFDE1\n" + ".LASFDE1:\n" + "\t.long .LASFDE1-.Lframe1\n" + "\t.long .Lbegin-.\n" + "\t.long %d\n" + "\t.uleb128 0\n" /* augmentation length */ + "\t.byte 0xe\n\t.uleb128 %d\n" + "\t.byte 0x11\n\t.uleb128 65\n\t.sleb128 -1\n", + (int)ctx->codesz, CFRAME_SIZE); + for (i = 14; i <= 31; i++) +#if LJ_TARGET_PPCSPE + fprintf(ctx->fp, + "\t.byte %d\n\t.uleb128 %d\n" + "\t.byte 5\n\t.uleb128 %d\n\t.uleb128 %d\n", + 0x80+i, 1+2*(31-i), 1200+i, 2+2*(31-i)); +#else +#error "missing frame info for saved registers" +#endif + fprintf(ctx->fp, + "\t.align 2\n" + ".LEFDE1:\n\n"); + break; + default: + break; + } } diff --git a/src/lj_arch.h b/src/lj_arch.h index a0f08a22..7f1fe93c 100644 --- a/src/lj_arch.h +++ b/src/lj_arch.h @@ -52,6 +52,7 @@ #define LJ_TARGET_X86 1 #define LJ_TARGET_X86ORX64 1 #define LJ_PAGESIZE 4096 +#define LJ_TARGET_EHRETREG 0 #define LJ_TARGET_MASKSHIFT 1 #define LJ_TARGET_MASKROT 1 @@ -63,6 +64,7 @@ #define LJ_TARGET_X64 1 #define LJ_TARGET_X86ORX64 1 #define LJ_PAGESIZE 4096 +#define LJ_TARGET_EHRETREG 0 #define LJ_TARGET_MASKSHIFT 1 #define LJ_TARGET_MASKROT 1 @@ -78,6 +80,7 @@ #define LJ_TARGET_PPC 1 #define LJ_TARGET_PPCSPE 1 #define LJ_PAGESIZE 4096 +#define LJ_TARGET_EHRETREG 3 #define LJ_TARGET_MASKSHIFT 0 #define LJ_TARGET_MASKROT 1 #define LJ_ARCH_NOJIT 1 diff --git a/src/lj_err.c b/src/lj_err.c index 9c6de3aa..5a6aac83 100644 --- a/src/lj_err.c +++ b/src/lj_err.c @@ -32,7 +32,7 @@ ** ** - EXT requires unwind tables for *all* functions on the C stack between ** the pcall/catch and the error/throw. This is the default on x64, -** but needs to be manually enabled on x86 for non-C++ code. +** but needs to be manually enabled on x86/PPC for non-C++ code. ** ** - INT is faster when actually throwing errors (but this happens rarely). ** Setting up error handlers is zero-cost in any case. @@ -48,9 +48,9 @@ ** the wrapper function feature. Lua errors thrown through C++ frames ** cannot be caught by C++ code and C++ destructors are not run. ** -** INT is the default on x86 systems, EXT is the default on x64 systems. +** EXT is the default on x64 systems, INT is the default on all other systems. ** -** EXT can only be manually enabled on POSIX/x86 systems using DWARF2 stack +** EXT can be manually enabled on POSIX systems using GCC and DWARF2 stack ** unwinding with -DLUAJIT_UNWIND_EXTERNAL. *All* C code must be compiled ** with -funwind-tables (or -fexceptions). This includes LuaJIT itself (set ** TARGET_CFLAGS), all of your C/Lua binding code, all loadable C modules @@ -64,11 +64,7 @@ */ #if defined(__GNUC__) -#if LJ_TARGET_X86 -#ifdef LUAJIT_UNWIND_EXTERNAL -#define LJ_UNWIND_EXT 1 -#endif -#elif LJ_TARGET_X64 +#if LJ_TARGET_X64 || defined(LUAJIT_UNWIND_EXTERNAL) #define LJ_UNWIND_EXT 1 #endif #elif defined(LUA_USE_WIN) @@ -579,15 +575,15 @@ LJ_FUNCA int lj_err_unwind_dwarf(int version, _Unwind_Action actions, #if LJ_UNWIND_EXT cf = err_unwind(L, cf, errcode); if (cf) { - _Unwind_SetGR(ctx, 0, errcode); + _Unwind_SetGR(ctx, LJ_TARGET_EHRETREG, errcode); _Unwind_SetIP(ctx, (_Unwind_Ptr)(cframe_unwind_ff(cf) ? lj_vm_unwind_ff_eh : lj_vm_unwind_c_eh)); return _URC_INSTALL_CONTEXT; } #else - /* This is not the proper way to escape from the unwinder. We get away - ** with it on x86 because the interpreter restores all callee-saved regs. + /* This is not the proper way to escape from the unwinder. We get away with + ** it on x86/PPC because the interpreter restores all callee-saved regs. */ lj_err_throw(L, errcode); #endif @@ -713,8 +709,8 @@ LJ_NOINLINE void LJ_FASTCALL lj_err_throw(lua_State *L, int errcode) ** unwound. We have no choice but to call the panic function and exit. ** ** Usually this is caused by a C function without unwind information. - ** This should never happen on x64, but may happen on x86 if you've - ** manually enabled LUAJIT_UNWIND_EXTERNAL and forgot to recompile *every* + ** This should never happen on x64, but may happen if you've manually + ** enabled LUAJIT_UNWIND_EXTERNAL and forgot to recompile *every* ** non-C++ file with -funwind-tables. */ if (G(L)->panic)