From f7dc94a7abb2eca53246e7f5b749ca01899c8636 Mon Sep 17 00:00:00 2001 From: Luke Gorrie Date: Thu, 16 Mar 2017 17:07:41 +0000 Subject: [PATCH] Define NO_UNWIND I hope that I understand this feature correctly... it's for allowing C++ exceptions to propagate through LuaJIT? (e.g. C++ calls LuaJIT calls C++ throws exception?) Removing with this rationale: - Complex hairy code. - Limited value. - Looks straightforward to re-introduce if needed. --- src/ifdef-defile | 3 +- src/lj_arch.h | 11 --- src/lj_err.c | 196 ----------------------------------------------- src/lj_frame.h | 4 - src/vm_x64.dasc | 196 ----------------------------------------------- 5 files changed, 2 insertions(+), 408 deletions(-) diff --git a/src/ifdef-defile b/src/ifdef-defile index c1e8faf734..e2c4862417 100644 --- a/src/ifdef-defile +++ b/src/ifdef-defile @@ -3,11 +3,13 @@ #define LJ_GC64 1 #define LJ_HASFFI 1 #define LJ_HASJIT 1 +#define LJ_NOUNWIND 1 #define LUAJIT_DISABLE_PROFILE 1 #define LUAJIT_DISABLE_VMEVENT 1 #define LUAJIT_ENABLE_GC64 1 #define LUAJIT_ENABLE_JIT 1 #undef LJ_HASPROFILE +#undef LJ_UNWIND_EXT #undef LUAJIT_DISABLE_FFI #undef LUAJIT_DISABLE_JIT #undef LUAJIT_NOFFI @@ -61,7 +63,6 @@ #undef LJ_ARCH_NOFFI #undef LJ_ARCH_PPC #undef LJ_BE -#undef LJ_NOUNWIND #undef LJ_OS_NOJIT #undef LJ_SOFTFP #undef LJ_TARGET_ARM diff --git a/src/lj_arch.h b/src/lj_arch.h index c9f0e79830..d15892a059 100644 --- a/src/lj_arch.h +++ b/src/lj_arch.h @@ -152,17 +152,6 @@ #define LJ_TARGET_UNALIGNED 0 #endif -/* Various workarounds for embedded operating systems or weak C runtimes. */ - -#if !defined(LUAJIT_NO_UNWIND) && __GNU_COMPACT_EH__ -/* NYI: no support for compact unwind specification, yet. */ -#define LUAJIT_NO_UNWIND 1 -#endif - -#if defined(LUAJIT_NO_UNWIND) || defined(__symbian__) || LJ_TARGET_IOS || LJ_TARGET_PS3 || LJ_TARGET_PS4 -#define LJ_NO_UNWIND 1 -#endif - /* Compatibility with Lua 5.1 vs. 5.2. */ #ifdef LUAJIT_ENABLE_LUA52COMPAT #define LJ_52 1 diff --git a/src/lj_err.c b/src/lj_err.c index c233780b64..2a63cd910e 100644 --- a/src/lj_err.c +++ b/src/lj_err.c @@ -18,53 +18,6 @@ #include "lj_vm.h" #include "lj_strfmt.h" -/* -** LuaJIT can either use internal or external frame unwinding: -** -** - Internal frame unwinding (INT) is free-standing and doesn't require -** any OS or library support. -** -** - External frame unwinding (EXT) uses the system-provided unwind handler. -** -** Pros and Cons: -** -** - 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/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. -** -** - EXT provides full interoperability with C++ exceptions. You can throw -** Lua errors or C++ exceptions through a mix of Lua frames and C++ frames. -** C++ destructors are called as needed. C++ exceptions caught by pcall -** are converted to the string "C++ exception". Lua errors can be caught -** with catch (...) in C++. -** -** - INT has only limited support for automatically catching C++ exceptions -** on POSIX systems using DWARF2 stack unwinding. Other systems may use -** the wrapper function feature. Lua errors thrown through C++ frames -** cannot be caught by C++ code and C++ destructors are not run. -** -** EXT is the default on x64 systems and on Windows, INT is the default on all -** other systems. -** -** 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 -** and all C libraries that have callbacks which may be used to call back -** into Lua. C++ code must *not* be compiled with -fno-exceptions. -** -** EXT is mandatory on WIN64 since the calling convention has an abundance -** of callee-saved registers (rbx, rbp, rsi, rdi, r12-r15, xmm6-xmm15). -** The POSIX/x64 interpreter only saves r12/r13 for INT (e.g. PS4). -*/ - -#if defined(__GNUC__) && (LJ_TARGET_X64 || defined(LUAJIT_UNWIND_EXTERNAL)) && !LJ_NO_UNWIND -#define LJ_UNWIND_EXT 1 -#endif - /* -- Error messages ------------------------------------------------------ */ /* Error message strings. */ @@ -113,23 +66,10 @@ static void *err_unwind(lua_State *L, void *stopcf, int errcode) break; case FRAME_C: /* C frame. */ unwind_c: -#if LJ_UNWIND_EXT - if (errcode) { - L->base = frame_prevd(frame) + 1; - L->cframe = cframe_prev(cf); - unwindstack(L, frame - LJ_FR2); - } else if (cf != stopcf) { - cf = cframe_prev(cf); - frame = frame_prevd(frame); - break; - } - return NULL; /* Continue unwinding. */ -#else UNUSED(stopcf); cf = cframe_prev(cf); frame = frame_prevd(frame); break; -#endif case FRAME_CP: /* Protected C frame. */ if (cframe_canyield(cf)) { /* Resume? */ if (errcode) { @@ -179,127 +119,6 @@ static void *err_unwind(lua_State *L, void *stopcf, int errcode) return L; /* Anything non-NULL will do. */ } -/* -- External frame unwinding -------------------------------------------- */ - -#if defined(__GNUC__) && !LJ_NO_UNWIND && !LJ_ABI_WIN - -/* -** We have to use our own definitions instead of the mandatory (!) unwind.h, -** since various OS, distros and compilers mess up the header installation. -*/ - -typedef struct _Unwind_Context _Unwind_Context; - -#define _URC_OK 0 -#define _URC_FATAL_PHASE1_ERROR 3 -#define _URC_HANDLER_FOUND 6 -#define _URC_INSTALL_CONTEXT 7 -#define _URC_CONTINUE_UNWIND 8 -#define _URC_FAILURE 9 - -#define LJ_UEXCLASS 0x4c55414a49543200ULL /* LUAJIT2\0 */ -#define LJ_UEXCLASS_MAKE(c) (LJ_UEXCLASS | (uint64_t)(c)) -#define LJ_UEXCLASS_CHECK(cl) (((cl) ^ LJ_UEXCLASS) <= 0xff) -#define LJ_UEXCLASS_ERRCODE(cl) ((int)((cl) & 0xff)) - - -typedef struct _Unwind_Exception -{ - uint64_t exclass; - void (*excleanup)(int, struct _Unwind_Exception *); - uintptr_t p1, p2; -} __attribute__((__aligned__)) _Unwind_Exception; - -extern uintptr_t _Unwind_GetCFA(_Unwind_Context *); -extern void _Unwind_SetGR(_Unwind_Context *, int, uintptr_t); -extern void _Unwind_SetIP(_Unwind_Context *, uintptr_t); -extern void _Unwind_DeleteException(_Unwind_Exception *); -extern int _Unwind_RaiseException(_Unwind_Exception *); - -#define _UA_SEARCH_PHASE 1 -#define _UA_CLEANUP_PHASE 2 -#define _UA_HANDLER_FRAME 4 -#define _UA_FORCE_UNWIND 8 - -/* DWARF2 personality handler referenced from interpreter .eh_frame. */ -LJ_FUNCA int lj_err_unwind_dwarf(int version, int actions, - uint64_t uexclass, _Unwind_Exception *uex, _Unwind_Context *ctx) -{ - void *cf; - lua_State *L; - if (version != 1) - return _URC_FATAL_PHASE1_ERROR; - UNUSED(uexclass); - cf = (void *)_Unwind_GetCFA(ctx); - L = cframe_L(cf); - if ((actions & _UA_SEARCH_PHASE)) { -#if LJ_UNWIND_EXT - if (err_unwind(L, cf, 0) == NULL) - return _URC_CONTINUE_UNWIND; -#endif - if (!LJ_UEXCLASS_CHECK(uexclass)) { - setstrV(L, L->top++, lj_err_str(L, LJ_ERR_ERRCPP)); - } - return _URC_HANDLER_FOUND; - } - if ((actions & _UA_CLEANUP_PHASE)) { - int errcode; - if (LJ_UEXCLASS_CHECK(uexclass)) { - errcode = LJ_UEXCLASS_ERRCODE(uexclass); - } else { - if ((actions & _UA_HANDLER_FRAME)) - _Unwind_DeleteException(uex); - errcode = LUA_ERRRUN; - } -#if LJ_UNWIND_EXT - cf = err_unwind(L, cf, errcode); - if ((actions & _UA_FORCE_UNWIND)) { - return _URC_CONTINUE_UNWIND; - } else if (cf) { - _Unwind_SetGR(ctx, LJ_TARGET_EHRETREG, errcode); - _Unwind_SetIP(ctx, (uintptr_t)(cframe_unwind_ff(cf) ? - lj_vm_unwind_ff_eh : - lj_vm_unwind_c_eh)); - return _URC_INSTALL_CONTEXT; - } - else if ((actions & _UA_HANDLER_FRAME)) { - /* Workaround for ancient libgcc bug. Still present in RHEL 5.5. :-/ - ** Real fix: http://gcc.gnu.org/viewcvs/trunk/gcc/unwind-dw2.c?r1=121165&r2=124837&pathrev=153877&diff_format=h - */ - _Unwind_SetGR(ctx, LJ_TARGET_EHRETREG, errcode); - _Unwind_SetIP(ctx, (uintptr_t)lj_vm_unwind_rethrow); - return _URC_INSTALL_CONTEXT; - } -#else - /* This is not the proper way to escape from the unwinder. We get away with - ** it on non-x64 because the interpreter restores all callee-saved regs. - */ - lj_err_throw(L, errcode); -#endif - } - return _URC_CONTINUE_UNWIND; -} - -#if LJ_UNWIND_EXT -#if LJ_TARGET_OSX || defined(__OpenBSD__) -/* Sorry, no thread safety for OSX. Complain to Apple, not me. */ -static _Unwind_Exception static_uex; -#else -static __thread _Unwind_Exception static_uex; -#endif - -/* Raise DWARF2 exception. */ -static void err_raise_ext(int errcode) -{ - static_uex.exclass = LJ_UEXCLASS_MAKE(errcode); - static_uex.excleanup = NULL; - _Unwind_RaiseException(&static_uex); -} -#endif - - -#endif - /* -- Error handling ------------------------------------------------------ */ /* Throw error. Find catch frame, unwind stack and continue. */ @@ -309,20 +128,6 @@ LJ_NOINLINE void lj_err_throw(lua_State *L, int errcode) lj_trace_abort(g); setmref(g->jit_base, NULL); L->status = 0; -#if LJ_UNWIND_EXT - err_raise_ext(errcode); - /* - ** A return from this function signals a corrupt C stack that cannot be - ** 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 if you've manually - ** enabled LUAJIT_UNWIND_EXTERNAL and forgot to recompile *every* - ** non-C++ file with -funwind-tables. - */ - if (G(L)->panic) - G(L)->panic(L); -#else { void *cf = err_unwind(L, NULL, errcode); if (cframe_unwind_ff(cf)) @@ -330,7 +135,6 @@ LJ_NOINLINE void lj_err_throw(lua_State *L, int errcode) else lj_vm_unwind_c(cframe_raw(cf), errcode); } -#endif exit(EXIT_FAILURE); } diff --git a/src/lj_frame.h b/src/lj_frame.h index 04350576e1..0526614073 100644 --- a/src/lj_frame.h +++ b/src/lj_frame.h @@ -85,11 +85,7 @@ enum { LJ_CONT_TAILCALL, LJ_CONT_FFI_CALLBACK }; /* Special continuations. */ #define CFRAME_OFS_ERRF (3*4) #define CFRAME_OFS_NRES (2*4) #define CFRAME_OFS_MULTRES (0*4) -#if LJ_NO_UNWIND #define CFRAME_SIZE (12*8) -#else -#define CFRAME_SIZE (10*8) -#endif #define CFRAME_SIZE_JIT (CFRAME_SIZE + 16) #define CFRAME_SHIFT_MULTRES 0 diff --git a/src/vm_x64.dasc b/src/vm_x64.dasc index 5ffadef3db..9776f33c93 100644 --- a/src/vm_x64.dasc +++ b/src/vm_x64.dasc @@ -143,9 +143,7 @@ |.define CFRAME_SPACE, aword*5 // Delta for rsp (see <--). |.macro saveregs_ | push rbx; push r15; push r14 -|.if NO_UNWIND | push r13; push r12 -|.endif | sub rsp, CFRAME_SPACE |.endmacro |.macro saveregs @@ -153,14 +151,11 @@ |.endmacro |.macro restoreregs | add rsp, CFRAME_SPACE -|.if NO_UNWIND | pop r12; pop r13 -|.endif | pop r14; pop r15; pop rbx; pop rbp |.endmacro | |//----- 16 byte aligned, -|.if NO_UNWIND |.define SAVE_RET, aword [rsp+aword*11] //<-- rsp entering interpreter. |.define SAVE_R4, aword [rsp+aword*10] |.define SAVE_R3, aword [rsp+aword*9] @@ -168,13 +163,6 @@ |.define SAVE_R1, aword [rsp+aword*7] |.define SAVE_RU2, aword [rsp+aword*6] |.define SAVE_RU1, aword [rsp+aword*5] //<-- rsp after register saves. -|.else -|.define SAVE_RET, aword [rsp+aword*9] //<-- rsp entering interpreter. -|.define SAVE_R4, aword [rsp+aword*8] -|.define SAVE_R3, aword [rsp+aword*7] -|.define SAVE_R2, aword [rsp+aword*6] -|.define SAVE_R1, aword [rsp+aword*5] //<-- rsp after register saves. -|.endif |.define SAVE_CFRAME, aword [rsp+aword*4] |.define SAVE_PC, aword [rsp+aword*3] |.define SAVE_L, aword [rsp+aword*2] @@ -4282,9 +4270,6 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) case BC_JFORI: case BC_JFORL: -#if !LJ_HASJIT - break; -#endif case BC_FORI: case BC_IFORL: vk = (op == BC_IFORL || op == BC_JFORL); @@ -4432,9 +4417,6 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) break; case BC_JITERL: -#if !LJ_HASJIT - break; -#endif case BC_IITERL: | ins_AJ // RA = base, RD = target | lea RA, [BASE+RA*8] @@ -4526,9 +4508,6 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) break; case BC_JFUNCF: -#if !LJ_HASJIT - break; -#endif case BC_IFUNCF: | ins_AD // BASE = new base, RA = framesize, RD = nargs+1 | mov KBASE, [PC-4+PC2PROTO(k)] @@ -4556,9 +4535,6 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) break; case BC_JFUNCV: -#if !LJ_HASJIT - break; -#endif | int3 // NYI: compiled vararg functions break; /* NYI: compiled vararg functions. */ @@ -4696,13 +4672,10 @@ static void emit_asm_debug(BuildCtx *ctx) "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset rbx */ "\t.byte 0x8f\n\t.uleb128 0x4\n" /* offset r15 */ "\t.byte 0x8e\n\t.uleb128 0x5\n" /* offset r14 */ -#if LJ_NO_UNWIND "\t.byte 0x8d\n\t.uleb128 0x6\n" /* offset r13 */ "\t.byte 0x8c\n\t.uleb128 0x7\n" /* offset r12 */ -#endif "\t.align 8\n" ".LEFDE0:\n\n", fcofs, CFRAME_SIZE); -#if LJ_HASFFI fprintf(ctx->fp, ".LSFDE1:\n" "\t.long .LEFDE1-.LASFDE1\n" @@ -4716,176 +4689,7 @@ static void emit_asm_debug(BuildCtx *ctx) "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset rbx */ "\t.align 8\n" ".LEFDE1:\n\n", (int)ctx->codesz - fcofs); -#endif -#if !LJ_NO_UNWIND -#if (defined(__sun__) && defined(__svr4__)) - fprintf(ctx->fp, "\t.section .eh_frame,\"a\",@unwind\n"); -#else - fprintf(ctx->fp, "\t.section .eh_frame,\"a\",@progbits\n"); -#endif - 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 -8\n" - "\t.byte 0x10\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 0x7\n\t.uleb128 8\n" - "\t.byte 0x80+0x10\n\t.uleb128 0x1\n" - "\t.align 8\n" - ".LECIE1:\n\n"); - fprintf(ctx->fp, - ".LSFDE2:\n" - "\t.long .LEFDE2-.LASFDE2\n" - ".LASFDE2:\n" - "\t.long .LASFDE2-.Lframe1\n" - "\t.long .Lbegin-.\n" - "\t.long %d\n" - "\t.uleb128 0\n" /* augmentation length */ - "\t.byte 0xe\n\t.uleb128 %d\n" /* def_cfa_offset */ - "\t.byte 0x86\n\t.uleb128 0x2\n" /* offset rbp */ - "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset rbx */ - "\t.byte 0x8f\n\t.uleb128 0x4\n" /* offset r15 */ - "\t.byte 0x8e\n\t.uleb128 0x5\n" /* offset r14 */ - "\t.align 8\n" - ".LEFDE2:\n\n", fcofs, CFRAME_SIZE); -#if LJ_HASFFI - fprintf(ctx->fp, - ".Lframe2:\n" - "\t.long .LECIE2-.LSCIE2\n" - ".LSCIE2:\n" - "\t.long 0\n" - "\t.byte 0x1\n" - "\t.string \"zR\"\n" - "\t.uleb128 0x1\n" - "\t.sleb128 -8\n" - "\t.byte 0x10\n" - "\t.uleb128 1\n" /* augmentation length */ - "\t.byte 0x1b\n" /* pcrel|sdata4 */ - "\t.byte 0xc\n\t.uleb128 0x7\n\t.uleb128 8\n" - "\t.byte 0x80+0x10\n\t.uleb128 0x1\n" - "\t.align 8\n" - ".LECIE2:\n\n"); - fprintf(ctx->fp, - ".LSFDE3:\n" - "\t.long .LEFDE3-.LASFDE3\n" - ".LASFDE3:\n" - "\t.long .LASFDE3-.Lframe2\n" - "\t.long lj_vm_ffi_call-.\n" - "\t.long %d\n" - "\t.uleb128 0\n" /* augmentation length */ - "\t.byte 0xe\n\t.uleb128 16\n" /* def_cfa_offset */ - "\t.byte 0x86\n\t.uleb128 0x2\n" /* offset rbp */ - "\t.byte 0xd\n\t.uleb128 0x6\n" /* def_cfa_register rbp */ - "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset rbx */ - "\t.align 8\n" - ".LEFDE3:\n\n", (int)ctx->codesz - fcofs); -#endif -#endif - break; -#if !LJ_NO_UNWIND - /* Mental note: never let Apple design an assembler. - ** Or a linker. Or a plastic case. But I digress. - */ - case BUILD_machasm: { -#if LJ_HASFFI - int fcsize = 0; -#endif - int i; - fprintf(ctx->fp, "\t.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support\n"); - fprintf(ctx->fp, - "EH_frame1:\n" - "\t.set L$set$x,LECIEX-LSCIEX\n" - "\t.long L$set$x\n" - "LSCIEX:\n" - "\t.long 0\n" - "\t.byte 0x1\n" - "\t.ascii \"zPR\\0\"\n" - "\t.byte 0x1\n" - "\t.byte 128-8\n" - "\t.byte 0x10\n" - "\t.byte 6\n" /* augmentation length */ - "\t.byte 0x9b\n" /* indirect|pcrel|sdata4 */ - "\t.long _lj_err_unwind_dwarf+4@GOTPCREL\n" - "\t.byte 0x1b\n" /* pcrel|sdata4 */ - "\t.byte 0xc\n\t.byte 0x7\n\t.byte 8\n" - "\t.byte 0x80+0x10\n\t.byte 0x1\n" - "\t.align 3\n" - "LECIEX:\n\n"); - for (i = 0; i < ctx->nsym; i++) { - const char *name = ctx->sym[i].name; - int32_t size = ctx->sym[i+1].ofs - ctx->sym[i].ofs; - if (size == 0) continue; -#if LJ_HASFFI - if (!strcmp(name, "_lj_vm_ffi_call")) { fcsize = size; continue; } -#endif - fprintf(ctx->fp, - "%s.eh:\n" - "LSFDE%d:\n" - "\t.set L$set$%d,LEFDE%d-LASFDE%d\n" - "\t.long L$set$%d\n" - "LASFDE%d:\n" - "\t.long LASFDE%d-EH_frame1\n" - "\t.long %s-.\n" - "\t.long %d\n" - "\t.byte 0\n" /* augmentation length */ - "\t.byte 0xe\n\t.byte %d\n" /* def_cfa_offset */ - "\t.byte 0x86\n\t.byte 0x2\n" /* offset rbp */ - "\t.byte 0x83\n\t.byte 0x3\n" /* offset rbx */ - "\t.byte 0x8f\n\t.byte 0x4\n" /* offset r15 */ - "\t.byte 0x8e\n\t.byte 0x5\n" /* offset r14 */ - "\t.align 3\n" - "LEFDE%d:\n\n", - name, i, i, i, i, i, i, i, name, size, CFRAME_SIZE, i); - } -#if LJ_HASFFI - if (fcsize) { - fprintf(ctx->fp, - "EH_frame2:\n" - "\t.set L$set$y,LECIEY-LSCIEY\n" - "\t.long L$set$y\n" - "LSCIEY:\n" - "\t.long 0\n" - "\t.byte 0x1\n" - "\t.ascii \"zR\\0\"\n" - "\t.byte 0x1\n" - "\t.byte 128-8\n" - "\t.byte 0x10\n" - "\t.byte 1\n" /* augmentation length */ - "\t.byte 0x1b\n" /* pcrel|sdata4 */ - "\t.byte 0xc\n\t.byte 0x7\n\t.byte 8\n" - "\t.byte 0x80+0x10\n\t.byte 0x1\n" - "\t.align 3\n" - "LECIEY:\n\n"); - fprintf(ctx->fp, - "_lj_vm_ffi_call.eh:\n" - "LSFDEY:\n" - "\t.set L$set$yy,LEFDEY-LASFDEY\n" - "\t.long L$set$yy\n" - "LASFDEY:\n" - "\t.long LASFDEY-EH_frame2\n" - "\t.long _lj_vm_ffi_call-.\n" - "\t.long %d\n" - "\t.byte 0\n" /* augmentation length */ - "\t.byte 0xe\n\t.byte 16\n" /* def_cfa_offset */ - "\t.byte 0x86\n\t.byte 0x2\n" /* offset rbp */ - "\t.byte 0xd\n\t.byte 0x6\n" /* def_cfa_register rbp */ - "\t.byte 0x83\n\t.byte 0x3\n" /* offset rbx */ - "\t.align 3\n" - "LEFDEY:\n\n", fcsize); - } -#endif - fprintf(ctx->fp, ".subsections_via_symbols\n"); - } break; -#endif default: /* Difficult for other modes. */ break; }