Inline-Lua
view release on metacpan or search on metacpan
ffi/target/release/build/mlua-sys-6a99a2ae50f12319/out/luajit-build/build/src/lj_mcode.c view on Meta::CPAN
** but NONE of them is writable.
**
** The current memory area is marked read-write (but NOT executable) only
** during the short time window while the assembler generates machine code.
*/
#define MCPROT_GEN MCPROT_RW
#define MCPROT_RUN MCPROT_RX
/* Protection twiddling failed. Probably due to kernel security. */
static LJ_NORET LJ_NOINLINE void mcode_protfail(jit_State *J)
{
lua_CFunction panic = J2G(J)->panic;
if (panic) {
lua_State *L = J->L;
setstrV(L, L->top++, lj_err_str(L, LJ_ERR_JITPROT));
panic(L);
}
exit(EXIT_FAILURE);
}
/* 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;
}
}
#endif
/* -- MCode area allocation ----------------------------------------------- */
#if LJ_64
#define mcode_validptr(p) (p)
#else
#define mcode_validptr(p) ((p) && (uintptr_t)(p) < 0xffff0000)
#endif
#ifdef LJ_TARGET_JUMPRANGE
/* Get memory within relative jump distance of our code in 64 bit mode. */
static void *mcode_alloc(jit_State *J, size_t sz)
{
/* Target an address in the static assembler code (64K aligned).
** Try addresses within a distance of target-range/2+1MB..target+range/2-1MB.
** Use half the jump range so every address in the range can reach any other.
*/
#if LJ_TARGET_MIPS
/* Use the middle of the 256MB-aligned region. */
uintptr_t target = ((uintptr_t)(void *)lj_vm_exit_handler &
~(uintptr_t)0x0fffffffu) + 0x08000000u;
#else
uintptr_t target = (uintptr_t)(void *)lj_vm_exit_handler & ~(uintptr_t)0xffff;
#endif
const uintptr_t range = (1u << (LJ_TARGET_JUMPRANGE-1)) - (1u << 21);
/* First try a contiguous area below the last one. */
uintptr_t hint = J->mcarea ? (uintptr_t)J->mcarea - sz : 0;
int i;
/* Limit probing iterations, depending on the available pool size. */
for (i = 0; i < LJ_TARGET_JUMPRANGE; i++) {
if (mcode_validptr(hint)) {
void *p = mcode_alloc_at(J, hint, sz, MCPROT_GEN);
if (mcode_validptr(p) &&
((uintptr_t)p + sz - target < range || target - (uintptr_t)p < range))
return p;
if (p) mcode_free(J, p, sz); /* Free badly placed area. */
}
/* Next try probing 64K-aligned pseudo-random addresses. */
do {
hint = lj_prng_u64(&J2G(J)->prng) & ((1u<<LJ_TARGET_JUMPRANGE)-0x10000);
} while (!(hint + sz < range+range));
hint = target + hint - range;
}
lj_trace_err(J, LJ_TRERR_MCODEAL); /* Give up. OS probably ignores hints? */
return NULL;
}
#else
/* All memory addresses are reachable by relative jumps. */
static void *mcode_alloc(jit_State *J, size_t sz)
{
#if defined(__OpenBSD__) || defined(__NetBSD__) || LJ_TARGET_UWP
/* 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
}
#endif
/* -- MCode area management ----------------------------------------------- */
/* Allocate a new MCode area. */
static void mcode_allocarea(jit_State *J)
{
MCode *oldarea = J->mcarea;
size_t sz = (size_t)J->param[JIT_P_sizemcode] << 10;
sz = (sz + LJ_PAGESIZE-1) & ~(size_t)(LJ_PAGESIZE - 1);
J->mcarea = (MCode *)mcode_alloc(J, sz);
J->szmcarea = sz;
J->mcprot = MCPROT_GEN;
J->mctop = (MCode *)((char *)J->mcarea + J->szmcarea);
J->mcbot = (MCode *)((char *)J->mcarea + sizeof(MCLink));
((MCLink *)J->mcarea)->next = oldarea;
((MCLink *)J->mcarea)->size = sz;
J->szallmcarea += sz;
J->mcbot = (MCode *)lj_err_register_mcode(J->mcarea, sz, (uint8_t *)J->mcbot);
}
/* Free all MCode areas. */
void lj_mcode_free(jit_State *J)
( run in 0.901 second using v1.01-cache-2.11-cpan-71847e10f99 )