/* Set/reset protection to allow patching of MCode areas. */ MCode *lj_mcode_patch(jit_State *J, MCode *ptr, int finish) { #ifdef LUAJIT_UNPROTECT_MCODE UNUSED(J); UNUSED(ptr); UNUSED(finish); return NULL; #else if (finish) { if (J->mcarea == ptr) mcode_protect(J, MCPROT_RUN); else if (LJ_UNLIKELY(mcode_setprot(ptr, ((MCLink *)ptr)->size, MCPROT_RUN))) mcode_protfail(J); return NULL; } else { MCode *mc = J->mcarea; /* Try current area first to use the protection cache. */ if (ptr >= mc && ptr < (MCode *)((char *)mc + J->szmcarea)) { mcode_protect(J, MCPROT_GEN); return mc; } /* Otherwise search through the list of MCode areas. */ for (;;) { mc = ((MCLink *)mc)->next; lua_assert(mc != NULL); if (ptr >= mc && ptr < (MCode *)((char *)mc + ((MCLink *)mc)->size)) { if (LJ_UNLIKELY(mcode_setprot(mc, ((MCLink *)mc)->size, MCPROT_GEN))) mcode_protfail(J); return mc; } } } #endif }
/* Change protection of MCode area. */ static void mcode_protect(jit_State *J, int prot) { if (J->mcprot != prot) { if (LJ_UNLIKELY(mcode_setprot(J->mcarea, J->szmcarea, prot))) mcode_protfail(J); J->mcprot = prot; } }
/* Change protection of MCode area. */ static void mcode_protect(jit_State *J, int prot) { #ifdef LUAJIT_UNPROTECT_MCODE UNUSED(J); UNUSED(prot); #else if (J->mcprot != prot) { mcode_setprot(J->mcarea, J->szmcarea, prot); J->mcprot = prot; } #endif }
/* All memory addresses are reachable by relative jumps. */ static void *mcode_alloc(jit_State *J, size_t sz) { #ifdef __OpenBSD__ /* Allow better executable memory allocation for OpenBSD W^X mode. */ void *p = mcode_alloc_at(J, 0, sz, MCPROT_RUN); if (p && mcode_setprot(p, sz, MCPROT_GEN)) { mcode_free(J, p, sz); return NULL; } return p; #else return mcode_alloc_at(J, 0, sz, MCPROT_GEN); #endif }