diff options
| author | Mike Pall <mike> | 2010-09-28 17:50:33 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2010-09-28 17:50:33 +0200 |
| commit | a47136031e0717d61813024194840d9d351fe193 (patch) | |
| tree | 75085c2032a626d36354b8742d01af7f5f852842 /src | |
| parent | dc4fdecfb566fd3c3118f2d084fcfa00ccf6ff02 (diff) | |
| download | luajit-a47136031e0717d61813024194840d9d351fe193.tar.gz luajit-a47136031e0717d61813024194840d9d351fe193.tar.bz2 luajit-a47136031e0717d61813024194840d9d351fe193.zip | |
PPC: Add frame unwind info for assembler part.
Add define for target-specific exception handler return register.
Diffstat (limited to 'src')
| -rw-r--r-- | src/buildvm_ppc.dasc | 86 | ||||
| -rw-r--r-- | src/lj_arch.h | 3 | ||||
| -rw-r--r-- | src/lj_err.c | 22 |
3 files changed, 96 insertions, 15 deletions
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) | |||
| 2773 | /* Emit pseudo frame-info for all assembler functions. */ | 2773 | /* Emit pseudo frame-info for all assembler functions. */ |
| 2774 | static void emit_asm_debug(BuildCtx *ctx) | 2774 | static void emit_asm_debug(BuildCtx *ctx) |
| 2775 | { | 2775 | { |
| 2776 | /* NYI */ | 2776 | int i; |
| 2777 | UNUSED(ctx); | 2777 | switch (ctx->mode) { |
| 2778 | case BUILD_elfasm: | ||
| 2779 | fprintf(ctx->fp, "\t.section .debug_frame,\"\",@progbits\n"); | ||
| 2780 | fprintf(ctx->fp, | ||
| 2781 | ".Lframe0:\n" | ||
| 2782 | "\t.long .LECIE0-.LSCIE0\n" | ||
| 2783 | ".LSCIE0:\n" | ||
| 2784 | "\t.long 0xffffffff\n" | ||
| 2785 | "\t.byte 0x1\n" | ||
| 2786 | "\t.string \"\"\n" | ||
| 2787 | "\t.uleb128 0x1\n" | ||
| 2788 | "\t.sleb128 -4\n" | ||
| 2789 | "\t.byte 65\n" | ||
| 2790 | "\t.byte 0xc\n\t.uleb128 1\n\t.uleb128 0\n" | ||
| 2791 | "\t.align 2\n" | ||
| 2792 | ".LECIE0:\n\n"); | ||
| 2793 | fprintf(ctx->fp, | ||
| 2794 | ".LSFDE0:\n" | ||
| 2795 | "\t.long .LEFDE0-.LASFDE0\n" | ||
| 2796 | ".LASFDE0:\n" | ||
| 2797 | "\t.long .Lframe0\n" | ||
| 2798 | "\t.long .Lbegin\n" | ||
| 2799 | "\t.long %d\n" | ||
| 2800 | "\t.byte 0xe\n\t.uleb128 %d\n" | ||
| 2801 | "\t.byte 0x11\n\t.uleb128 65\n\t.sleb128 -1\n", | ||
| 2802 | (int)ctx->codesz, CFRAME_SIZE); | ||
| 2803 | for (i = 14; i <= 31; i++) | ||
| 2804 | #if LJ_TARGET_PPCSPE | ||
| 2805 | fprintf(ctx->fp, | ||
| 2806 | "\t.byte %d\n\t.uleb128 %d\n" | ||
| 2807 | "\t.byte 5\n\t.uleb128 %d\n\t.uleb128 %d\n", | ||
| 2808 | 0x80+i, 1+2*(31-i), 1200+i, 2+2*(31-i)); | ||
| 2809 | #else | ||
| 2810 | #error "missing frame info for saved registers" | ||
| 2811 | #endif | ||
| 2812 | fprintf(ctx->fp, | ||
| 2813 | "\t.align 2\n" | ||
| 2814 | ".LEFDE0:\n\n"); | ||
| 2815 | fprintf(ctx->fp, "\t.section .eh_frame,\"a\",@progbits\n"); | ||
| 2816 | fprintf(ctx->fp, | ||
| 2817 | ".Lframe1:\n" | ||
| 2818 | "\t.long .LECIE1-.LSCIE1\n" | ||
| 2819 | ".LSCIE1:\n" | ||
| 2820 | "\t.long 0\n" | ||
| 2821 | "\t.byte 0x1\n" | ||
| 2822 | "\t.string \"zPR\"\n" | ||
| 2823 | "\t.uleb128 0x1\n" | ||
| 2824 | "\t.sleb128 -4\n" | ||
| 2825 | "\t.byte 65\n" | ||
| 2826 | "\t.uleb128 6\n" /* augmentation length */ | ||
| 2827 | "\t.byte 0x1b\n" /* pcrel|sdata4 */ | ||
| 2828 | "\t.long lj_err_unwind_dwarf-.\n" | ||
| 2829 | "\t.byte 0x1b\n" /* pcrel|sdata4 */ | ||
| 2830 | "\t.byte 0xc\n\t.uleb128 1\n\t.uleb128 0\n" | ||
| 2831 | "\t.align 2\n" | ||
| 2832 | ".LECIE1:\n\n"); | ||
| 2833 | fprintf(ctx->fp, | ||
| 2834 | ".LSFDE1:\n" | ||
| 2835 | "\t.long .LEFDE1-.LASFDE1\n" | ||
| 2836 | ".LASFDE1:\n" | ||
| 2837 | "\t.long .LASFDE1-.Lframe1\n" | ||
| 2838 | "\t.long .Lbegin-.\n" | ||
| 2839 | "\t.long %d\n" | ||
| 2840 | "\t.uleb128 0\n" /* augmentation length */ | ||
| 2841 | "\t.byte 0xe\n\t.uleb128 %d\n" | ||
| 2842 | "\t.byte 0x11\n\t.uleb128 65\n\t.sleb128 -1\n", | ||
| 2843 | (int)ctx->codesz, CFRAME_SIZE); | ||
| 2844 | for (i = 14; i <= 31; i++) | ||
| 2845 | #if LJ_TARGET_PPCSPE | ||
| 2846 | fprintf(ctx->fp, | ||
| 2847 | "\t.byte %d\n\t.uleb128 %d\n" | ||
| 2848 | "\t.byte 5\n\t.uleb128 %d\n\t.uleb128 %d\n", | ||
| 2849 | 0x80+i, 1+2*(31-i), 1200+i, 2+2*(31-i)); | ||
| 2850 | #else | ||
| 2851 | #error "missing frame info for saved registers" | ||
| 2852 | #endif | ||
| 2853 | fprintf(ctx->fp, | ||
| 2854 | "\t.align 2\n" | ||
| 2855 | ".LEFDE1:\n\n"); | ||
| 2856 | break; | ||
| 2857 | default: | ||
| 2858 | break; | ||
| 2859 | } | ||
| 2778 | } | 2860 | } |
| 2779 | 2861 | ||
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 @@ | |||
| 52 | #define LJ_TARGET_X86 1 | 52 | #define LJ_TARGET_X86 1 |
| 53 | #define LJ_TARGET_X86ORX64 1 | 53 | #define LJ_TARGET_X86ORX64 1 |
| 54 | #define LJ_PAGESIZE 4096 | 54 | #define LJ_PAGESIZE 4096 |
| 55 | #define LJ_TARGET_EHRETREG 0 | ||
| 55 | #define LJ_TARGET_MASKSHIFT 1 | 56 | #define LJ_TARGET_MASKSHIFT 1 |
| 56 | #define LJ_TARGET_MASKROT 1 | 57 | #define LJ_TARGET_MASKROT 1 |
| 57 | 58 | ||
| @@ -63,6 +64,7 @@ | |||
| 63 | #define LJ_TARGET_X64 1 | 64 | #define LJ_TARGET_X64 1 |
| 64 | #define LJ_TARGET_X86ORX64 1 | 65 | #define LJ_TARGET_X86ORX64 1 |
| 65 | #define LJ_PAGESIZE 4096 | 66 | #define LJ_PAGESIZE 4096 |
| 67 | #define LJ_TARGET_EHRETREG 0 | ||
| 66 | #define LJ_TARGET_MASKSHIFT 1 | 68 | #define LJ_TARGET_MASKSHIFT 1 |
| 67 | #define LJ_TARGET_MASKROT 1 | 69 | #define LJ_TARGET_MASKROT 1 |
| 68 | 70 | ||
| @@ -78,6 +80,7 @@ | |||
| 78 | #define LJ_TARGET_PPC 1 | 80 | #define LJ_TARGET_PPC 1 |
| 79 | #define LJ_TARGET_PPCSPE 1 | 81 | #define LJ_TARGET_PPCSPE 1 |
| 80 | #define LJ_PAGESIZE 4096 | 82 | #define LJ_PAGESIZE 4096 |
| 83 | #define LJ_TARGET_EHRETREG 3 | ||
| 81 | #define LJ_TARGET_MASKSHIFT 0 | 84 | #define LJ_TARGET_MASKSHIFT 0 |
| 82 | #define LJ_TARGET_MASKROT 1 | 85 | #define LJ_TARGET_MASKROT 1 |
| 83 | #define LJ_ARCH_NOJIT 1 | 86 | #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 @@ | |||
| 32 | ** | 32 | ** |
| 33 | ** - EXT requires unwind tables for *all* functions on the C stack between | 33 | ** - EXT requires unwind tables for *all* functions on the C stack between |
| 34 | ** the pcall/catch and the error/throw. This is the default on x64, | 34 | ** the pcall/catch and the error/throw. This is the default on x64, |
| 35 | ** but needs to be manually enabled on x86 for non-C++ code. | 35 | ** but needs to be manually enabled on x86/PPC for non-C++ code. |
| 36 | ** | 36 | ** |
| 37 | ** - INT is faster when actually throwing errors (but this happens rarely). | 37 | ** - INT is faster when actually throwing errors (but this happens rarely). |
| 38 | ** Setting up error handlers is zero-cost in any case. | 38 | ** Setting up error handlers is zero-cost in any case. |
| @@ -48,9 +48,9 @@ | |||
| 48 | ** the wrapper function feature. Lua errors thrown through C++ frames | 48 | ** the wrapper function feature. Lua errors thrown through C++ frames |
| 49 | ** cannot be caught by C++ code and C++ destructors are not run. | 49 | ** cannot be caught by C++ code and C++ destructors are not run. |
| 50 | ** | 50 | ** |
| 51 | ** INT is the default on x86 systems, EXT is the default on x64 systems. | 51 | ** EXT is the default on x64 systems, INT is the default on all other systems. |
| 52 | ** | 52 | ** |
| 53 | ** EXT can only be manually enabled on POSIX/x86 systems using DWARF2 stack | 53 | ** EXT can be manually enabled on POSIX systems using GCC and DWARF2 stack |
| 54 | ** unwinding with -DLUAJIT_UNWIND_EXTERNAL. *All* C code must be compiled | 54 | ** unwinding with -DLUAJIT_UNWIND_EXTERNAL. *All* C code must be compiled |
| 55 | ** with -funwind-tables (or -fexceptions). This includes LuaJIT itself (set | 55 | ** with -funwind-tables (or -fexceptions). This includes LuaJIT itself (set |
| 56 | ** TARGET_CFLAGS), all of your C/Lua binding code, all loadable C modules | 56 | ** TARGET_CFLAGS), all of your C/Lua binding code, all loadable C modules |
| @@ -64,11 +64,7 @@ | |||
| 64 | */ | 64 | */ |
| 65 | 65 | ||
| 66 | #if defined(__GNUC__) | 66 | #if defined(__GNUC__) |
| 67 | #if LJ_TARGET_X86 | 67 | #if LJ_TARGET_X64 || defined(LUAJIT_UNWIND_EXTERNAL) |
| 68 | #ifdef LUAJIT_UNWIND_EXTERNAL | ||
| 69 | #define LJ_UNWIND_EXT 1 | ||
| 70 | #endif | ||
| 71 | #elif LJ_TARGET_X64 | ||
| 72 | #define LJ_UNWIND_EXT 1 | 68 | #define LJ_UNWIND_EXT 1 |
| 73 | #endif | 69 | #endif |
| 74 | #elif defined(LUA_USE_WIN) | 70 | #elif defined(LUA_USE_WIN) |
| @@ -579,15 +575,15 @@ LJ_FUNCA int lj_err_unwind_dwarf(int version, _Unwind_Action actions, | |||
| 579 | #if LJ_UNWIND_EXT | 575 | #if LJ_UNWIND_EXT |
| 580 | cf = err_unwind(L, cf, errcode); | 576 | cf = err_unwind(L, cf, errcode); |
| 581 | if (cf) { | 577 | if (cf) { |
| 582 | _Unwind_SetGR(ctx, 0, errcode); | 578 | _Unwind_SetGR(ctx, LJ_TARGET_EHRETREG, errcode); |
| 583 | _Unwind_SetIP(ctx, (_Unwind_Ptr)(cframe_unwind_ff(cf) ? | 579 | _Unwind_SetIP(ctx, (_Unwind_Ptr)(cframe_unwind_ff(cf) ? |
| 584 | lj_vm_unwind_ff_eh : | 580 | lj_vm_unwind_ff_eh : |
| 585 | lj_vm_unwind_c_eh)); | 581 | lj_vm_unwind_c_eh)); |
| 586 | return _URC_INSTALL_CONTEXT; | 582 | return _URC_INSTALL_CONTEXT; |
| 587 | } | 583 | } |
| 588 | #else | 584 | #else |
| 589 | /* This is not the proper way to escape from the unwinder. We get away | 585 | /* This is not the proper way to escape from the unwinder. We get away with |
| 590 | ** with it on x86 because the interpreter restores all callee-saved regs. | 586 | ** it on x86/PPC because the interpreter restores all callee-saved regs. |
| 591 | */ | 587 | */ |
| 592 | lj_err_throw(L, errcode); | 588 | lj_err_throw(L, errcode); |
| 593 | #endif | 589 | #endif |
| @@ -713,8 +709,8 @@ LJ_NOINLINE void LJ_FASTCALL lj_err_throw(lua_State *L, int errcode) | |||
| 713 | ** unwound. We have no choice but to call the panic function and exit. | 709 | ** unwound. We have no choice but to call the panic function and exit. |
| 714 | ** | 710 | ** |
| 715 | ** Usually this is caused by a C function without unwind information. | 711 | ** Usually this is caused by a C function without unwind information. |
| 716 | ** This should never happen on x64, but may happen on x86 if you've | 712 | ** This should never happen on x64, but may happen if you've manually |
| 717 | ** manually enabled LUAJIT_UNWIND_EXTERNAL and forgot to recompile *every* | 713 | ** enabled LUAJIT_UNWIND_EXTERNAL and forgot to recompile *every* |
| 718 | ** non-C++ file with -funwind-tables. | 714 | ** non-C++ file with -funwind-tables. |
| 719 | */ | 715 | */ |
| 720 | if (G(L)->panic) | 716 | if (G(L)->panic) |
