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