PPC: Add frame unwind info for assembler part.

Add define for target-specific exception handler return register.
master
Mike Pall 2010-09-28 17:50:33 +02:00
parent dc4fdecfb5
commit a47136031e
3 changed files with 96 additions and 15 deletions

View File

@ -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;
}
}

View File

@ -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

View File

@ -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)