Explorar el Código

PPC: Add frame unwind info for assembler part.

Add define for target-specific exception handler return register.
Mike Pall hace 15 años
padre
commit
a47136031e
Se han modificado 3 ficheros con 96 adiciones y 15 borrados
  1. 84 2
      src/buildvm_ppc.dasc
  2. 3 0
      src/lj_arch.h
  3. 9 13
      src/lj_err.c

+ 84 - 2
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;
+  }
 }
 

+ 3 - 0
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

+ 9 - 13
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)