Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
e3c70a7
macOS: Fix support for Apple hardened runtime.
Mar 9, 2025
4f2bb19
macOS: Fix Apple hardened runtime support and put behind build option.
Mar 10, 2025
84cb21f
REVERT: Change handling of nil value markers in template tables.
Mar 10, 2025
538a821
Change handling of nil value markers in template tables.
Mar 11, 2025
e9e4b6d
Initialize unused value when specializing to cdata metatable.
Apr 7, 2025
e76bb50
Fix error generation in load*.
Apr 7, 2025
e0a7ea8
Merge branch 'master' into v2.1
Apr 7, 2025
c262976
ARM64: Fix pass-by-value struct calling conventions.
Apr 10, 2025
51d4c26
ARM: Fix soft-float math.min()/math.max().
Apr 10, 2025
eec7a80
Prevent Clang UB 'optimization' which breaks integerness checks.
Apr 10, 2025
9c8eb7c
FFI: Fix dangling CType references.
May 28, 2025
852c3a0
Merge branch 'master' into v2.1
May 28, 2025
cd4af8a
Avoid out-of-range PC for stack overflow error from snapshot restore.
May 28, 2025
0a8cd58
Merge branch 'master' into v2.1
May 28, 2025
048972d
Fix JIT slot overflow during up-recursion.
May 28, 2025
f9140a6
Merge branch 'master' into v2.1
May 28, 2025
c64020f
FFI: Fix dangling CType references (again).
Jul 24, 2025
e3fa3c4
Avoid out-of-range PC for stack overflow error from snapshot restore.
Jul 24, 2025
c92d0cb
x86/x64: Don't use undefined MUL/IMUL zero flag.
Jul 24, 2025
eed22e9
Merge branch 'master' into v2.1
Jul 24, 2025
871db2c
Windows: Add lua52compat option to msvcbuild.bat.
Jul 24, 2025
54a1626
Fix reporting of an error during error handling.
Oct 16, 2025
a69aef4
Fix io.write() of newly created buffer.
Oct 16, 2025
a21ba1c
Add GNU/Hurd build support.
Oct 16, 2025
5c3254d
Gracefully handle broken custom allocator.
Oct 16, 2025
25a61a1
x64: Add support for CET IBT.
Oct 16, 2025
e34a78a
x64: Various fixes for CET IBT.
Oct 27, 2025
8651ef6
ARM64: Add support for ARM BTI.
Oct 28, 2025
864e78d
Windows: Fix lua52compat option for msvcbuild.bat.
Oct 28, 2025
5b20d6e
ARM64: Fix ARM BTI.
Oct 29, 2025
8518c0b
x64: Fix CET IBT.
Oct 29, 2025
3c7b158
ARM64: Fix disassembly of >2GB branch targets.
Nov 5, 2025
68354f4
Allow mcode allocations outside of the jump range to the support code.
Nov 5, 2025
578c41c
ARM64: Enable unaligned accesses if indicated by the toolchain.
Nov 8, 2025
fdf2379
macOS: Change Mach-O object file layout required by XCode 15.0.
Nov 8, 2025
5c64775
Run VM events and finalizers in separate state.
Nov 10, 2025
c94312d
FFI: Avoid dangling cts->L.
Nov 10, 2025
eba91fc
Merge branch 'master' into v2.1
Nov 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions doc/running.html
Original file line number Diff line number Diff line change
Expand Up @@ -299,9 +299,9 @@ <h3 id="opt_O"><tt>-O[level]</tt><br>
<tr class="even">
<td class="param_name">recunroll</td><td class="param_default">2</td><td class="param_desc">Min. unroll factor for true recursion</td></tr>
<tr class="odd separate">
<td class="param_name">sizemcode</td><td class="param_default">32</td><td class="param_desc">Size of each machine code area in KBytes (Windows: 64K)</td></tr>
<td class="param_name">sizemcode</td><td class="param_default">64</td><td class="param_desc">Size of each machine code area in KBytes</td></tr>
<tr class="even">
<td class="param_name">maxmcode</td><td class="param_default">512</td><td class="param_desc">Max. total size of all machine code areas in KBytes</td></tr>
<td class="param_name">maxmcode</td><td class="param_default">2048</td><td class="param_desc">Max. total size of all machine code areas in KBytes</td></tr>
</table>
<br class="flush">
</div>
Expand Down
22 changes: 22 additions & 0 deletions dynasm/dasm_arm64.lua
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,10 @@ local map_cond = {
hs = 2, lo = 3,
}

local map_bti = {
c = 0x40, j = 0x80, jc = 0xc0,
}

------------------------------------------------------------------------------

local parse_reg_type
Expand Down Expand Up @@ -475,6 +479,12 @@ local function parse_cond(expr, inv)
return shl(bit.bxor(c, inv), 12)
end

local function parse_map(expr, map)
local x = map[expr]
if not x then werror("bad operand") end
return x
end

local function parse_load(params, nparams, n, op)
if params[n+2] then werror("too many operands") end
local scale = shr(op, 30)
Expand Down Expand Up @@ -823,11 +833,21 @@ map_op = {
tbz_3 = "36000000DTBw|36000000DTBx",
tbnz_3 = "37000000DTBw|37000000DTBx",

-- Branch Target Identification.
bti_1 = "d503241ft",

-- ARM64e: Pointer authentication codes (PAC).
blraaz_1 = "d63f081fNx",
blrabz_1 = "d63f0c1fNx",
braa_2 = "d71f0800NDx",
brab_2 = "d71f0c00NDx",
braaz_1 = "d61f081fNx",
brabz_1 = "d61f0c1fNx",
paciasp_0 = "d503233f",
pacibsp_0 = "d503237f",
autiasp_0 = "d50323bf",
autibsp_0 = "d50323ff",
retaa_0 = "d65f0bff",
retab_0 = "d65f0fff",

-- Miscellaneous instructions.
Expand Down Expand Up @@ -996,6 +1016,8 @@ local function parse_template(params, template, nparams, pos)
op = op + parse_cond(q, 0); n = n + 1
elseif p == "c" then
op = op + parse_cond(q, 1); n = n + 1
elseif p == "t" then
op = op + parse_map(q, map_bti); n = n + 1

else
assert(false)
Expand Down
14 changes: 14 additions & 0 deletions src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,9 @@ endif
ifneq (,$(INSTALL_LJLIBD))
TARGET_XCFLAGS+= -DLUA_LJDIR=\"$(INSTALL_LJLIBD)\"
endif
ifeq (,$(shell $(TARGET_CC) -o /dev/null -c -x c /dev/null -fno-strict-float-cast-overflow 2>/dev/null || echo 1))
TARGET_XCFLAGS+= -fno-strict-float-cast-overflow
endif

##############################################################################
# Target system detection.
Expand Down Expand Up @@ -354,6 +357,9 @@ else
ifeq (GNU/kFreeBSD,$(TARGET_SYS))
TARGET_XLIBS+= -ldl
endif
ifeq (GNU,$(TARGET_SYS))
TARGET_XLIBS+= -ldl
endif
endif
endif
endif
Expand Down Expand Up @@ -440,6 +446,14 @@ ifneq (,$(findstring LJ_ABI_PAUTH 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D PAUTH
TARGET_ARCH+= -DLJ_ABI_PAUTH=1
endif
ifneq (,$(findstring LJ_ABI_BRANCH_TRACK 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D BRANCH_TRACK
TARGET_ARCH+= -DLJ_ABI_BRANCH_TRACK=1
endif
ifneq (,$(findstring LJ_ABI_SHADOW_STACK 1,$(TARGET_TESTARCH)))
DASM_AFLAGS+= -D SHADOW_STACK
TARGET_ARCH+= -DLJ_ABI_SHADOW_STACK=1
endif
DASM_AFLAGS+= -D VER=$(subst LJ_ARCH_VERSION_,,$(filter LJ_ARCH_VERSION_%,$(subst LJ_ARCH_VERSION ,LJ_ARCH_VERSION_,$(TARGET_TESTARCH))))
ifeq (Windows,$(TARGET_SYS))
DASM_AFLAGS+= -D WIN
Expand Down
30 changes: 18 additions & 12 deletions src/jit/bcsave.lua
Original file line number Diff line number Diff line change
Expand Up @@ -465,9 +465,11 @@ typedef struct {
mach_segment_command_64 seg;
mach_section_64 sec;
mach_symtab_command sym;
} mach_obj_64;
typedef struct {
mach_nlist_64 sym_entry;
uint8_t space[4096];
} mach_obj_64;
} mach_obj_64_tail;
]]
local symname = '_'..LJBC_PREFIX..ctx.modname
local cputype, cpusubtype = 0x01000007, 3
Expand All @@ -479,7 +481,10 @@ typedef struct {

-- Create Mach-O object and fill in header.
local o = ffi.new("mach_obj_64")
local mach_size = aligned(ffi.offsetof(o, "space")+#symname+2, 8)
local t = ffi.new("mach_obj_64_tail")
local ofs_bc = ffi.sizeof(o)
local sz_bc = aligned(#s, 8)
local ofs_sym = ofs_bc + sz_bc

-- Fill in sections and symbols.
o.hdr.magic = 0xfeedfacf
Expand All @@ -491,30 +496,31 @@ typedef struct {
o.seg.cmd = 0x19
o.seg.cmdsize = ffi.sizeof(o.seg)+ffi.sizeof(o.sec)
o.seg.vmsize = #s
o.seg.fileoff = mach_size
o.seg.fileoff = ofs_bc
o.seg.filesize = #s
o.seg.maxprot = 1
o.seg.initprot = 1
o.seg.nsects = 1
ffi.copy(o.sec.sectname, "__data")
ffi.copy(o.sec.segname, "__DATA")
o.sec.size = #s
o.sec.offset = mach_size
o.sec.offset = ofs_bc
o.sym.cmd = 2
o.sym.cmdsize = ffi.sizeof(o.sym)
o.sym.symoff = ffi.offsetof(o, "sym_entry")
o.sym.symoff = ofs_sym
o.sym.nsyms = 1
o.sym.stroff = ffi.offsetof(o, "sym_entry")+ffi.sizeof(o.sym_entry)
o.sym.stroff = ofs_sym + ffi.offsetof(t, "space")
o.sym.strsize = aligned(#symname+2, 8)
o.sym_entry.type = 0xf
o.sym_entry.sect = 1
o.sym_entry.strx = 1
ffi.copy(o.space+1, symname)
t.sym_entry.type = 0xf
t.sym_entry.sect = 1
t.sym_entry.strx = 1
ffi.copy(t.space+1, symname)

-- Write Mach-O object file.
local fp = savefile(output, "wb")
fp:write(ffi.string(o, mach_size))
bcsave_tail(fp, output, s)
fp:write(ffi.string(o, ofs_bc))
fp:write(s, ("\0"):rep(sz_bc - #s))
bcsave_tail(fp, output, ffi.string(t, ffi.offsetof(t, "space") + o.sym.strsize))
end

local function bcsave_obj(ctx, output, s)
Expand Down
10 changes: 8 additions & 2 deletions src/jit/dis_arm64.lua
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,10 @@ local map_br = { -- Branches, exception generating and system instructions.
},
{ -- System instructions.
shift = 0, mask = 0x3fffff,
[0x03201f] = "nop"
[0x03201f] = "nop",
[0x03245f] = "bti c",
[0x03249f] = "bti j",
[0x0324df] = "bti jc",
},
{ -- Unconditional branch, register.
shift = 0, mask = 0xfffc1f,
Expand Down Expand Up @@ -920,7 +923,7 @@ local function disass_ins(ctx)
elseif p == "B" then
local addr = ctx.addr + pos + parse_immpc(op, name)
ctx.rel = addr
x = "0x"..tohex(addr)
x = format("0x%08x", addr)
elseif p == "T" then
x = bor(band(rshift(op, 26), 32), band(rshift(op, 19), 31))
elseif p == "V" then
Expand Down Expand Up @@ -1171,6 +1174,9 @@ local function disass_ins(ctx)
end
end
second0 = true
elseif p == " " then
operands[#operands+1] = pat:match(" (.*)")
break
else
assert(false)
end
Expand Down
20 changes: 19 additions & 1 deletion src/jit/dis_x86.lua
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ local map_opc2 = {
"movlhpsXrm$movhpsXrm|movshdupXrm|movhpdXrm",
"movhpsXmr||movhpdXmr",
"$prefetcht!Bm","hintnopVm","hintnopVm","hintnopVm",
"hintnopVm","hintnopVm","hintnopVm","hintnopVm",
"hintnopVm","hintnopVm","endbr*hintnopVm","hintnopVm",
--2x
"movUmx$","movUmy$","movUxm$","movUym$","movUmz$",nil,"movUzm$",nil,
"movapsXrm||movapdXrm",
Expand Down Expand Up @@ -804,6 +804,24 @@ map_act = {
return dispatch(ctx, map_opcvm[ctx.mrm])
end,

-- Special NOP for endbr64/endbr32.
endbr = function(ctx, name, pat)
if ctx.rep then
local pos = ctx.pos
local b = byte(ctx.code, pos)
local text
if b == 0xfa then text = "endbr64"
elseif b == 0xfb then text = "endbr64"
end
if text then
ctx.pos = pos + 1
ctx.rep = nil
return putop(ctx, text)
end
end
return dispatch(ctx, pat)
end,

-- Floating point opcode dispatch.
fp = function(ctx, name, pat)
local mrm = getmrm(ctx); if not mrm then return incomplete(ctx) end
Expand Down
24 changes: 21 additions & 3 deletions src/lib_jit.c
Original file line number Diff line number Diff line change
Expand Up @@ -479,12 +479,21 @@ static int jitopt_param(jit_State *J, const char *str)
size_t len = *(const uint8_t *)lst;
lj_assertJ(len != 0, "bad JIT_P_STRING");
if (strncmp(str, lst+1, len) == 0 && str[len] == '=') {
int32_t n = 0;
uint32_t n = 0;
const char *p = &str[len+1];
while (*p >= '0' && *p <= '9')
n = n*10 + (*p++ - '0');
if (*p) return 0; /* Malformed number. */
J->param[i] = n;
if (*p || (int32_t)n < 0) return 0; /* Malformed number. */
if (i == JIT_P_sizemcode) { /* Adjust to required range here. */
#if LJ_TARGET_JUMPRANGE
uint32_t maxkb = ((1 << (LJ_TARGET_JUMPRANGE - 10)) - 64);
#else
uint32_t maxkb = ((1 << (31 - 10)) - 64);
#endif
n = (n + (LJ_PAGESIZE >> 10) - 1) & ~((LJ_PAGESIZE >> 10) - 1);
if (n > maxkb) n = maxkb;
}
J->param[i] = (int32_t)n;
if (i == JIT_P_hotloop)
lj_dispatch_init_hotcount(J2G(J));
return 1; /* Ok. */
Expand Down Expand Up @@ -714,7 +723,16 @@ static void jit_init(lua_State *L)
jit_State *J = L2J(L);
J->flags = jit_cpudetect() | JIT_F_ON | JIT_F_OPT_DEFAULT;
memcpy(J->param, jit_param_default, sizeof(J->param));
#if LJ_TARGET_UNALIGNED
G(L)->tmptv.u64 = U64x(0000504d,4d500000);
#endif
lj_dispatch_update(G(L));
#if LJ_TARGET_UNALIGNED
/* If you get a crash below then your toolchain indicates unaligned
** accesses are OK, but your kernel disagrees. I.e. fix your toolchain.
*/
if (*(uint32_t *)((char *)&G(L)->tmptv + 2) != 0x504d4d50u) L->top = NULL;
#endif
}
#endif

Expand Down
38 changes: 37 additions & 1 deletion src/lj_arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@
#elif defined(__QNX__)
#define LJ_TARGET_QNX 1
#define LUAJIT_OS LUAJIT_OS_POSIX
#elif defined(__GNU__)
#define LJ_TARGET_HURD 1
#define LUAJIT_OS LUAJIT_OS_POSIX
#else
#define LUAJIT_OS LUAJIT_OS_OTHER
#endif
Expand Down Expand Up @@ -216,6 +219,29 @@
#error "macOS requires GC64 -- don't disable it"
#endif

#if !defined(LJ_ABI_BRANCH_TRACK) && (__CET__ & 1) && \
LJ_TARGET_GC64 && defined(LUAJIT_ENABLE_CET_BR)
/*
** Control-Flow Enforcement Technique (CET) indirect branch tracking (IBT).
** This is not enabled by default because it causes a notable slowdown of
** the interpreter on all x64 CPUs, whether they have CET enabled or not.
** If your toolchain enables -fcf-protection=branch by default, you need
** to build with: make amalg XCFLAGS=-DLUAJIT_ENABLE_CET_BR
*/
#define LJ_ABI_BRANCH_TRACK 1
#endif

#if !defined(LJ_ABI_SHADOW_STACK) && (__CET__ & 2)
/*
** Control-Flow Enforcement Technique (CET) shadow stack (CET-SS).
** It has no code overhead and doesn't cause any slowdowns when unused.
** It can also be unconditionally enabled since all code already follows
** a strict CALL to RET correspondence for performance reasons (all modern
** CPUs use a (non-enforcing) shadow stack for return branch prediction).
*/
#define LJ_ABI_SHADOW_STACK 1
#endif

#elif LUAJIT_TARGET == LUAJIT_ARCH_ARM

#define LJ_ARCH_NAME "arm"
Expand Down Expand Up @@ -262,6 +288,11 @@
#if !defined(LJ_ABI_PAUTH) && defined(__arm64e__)
#define LJ_ABI_PAUTH 1
#endif
#if !defined(LJ_ABI_BRANCH_TRACK) && (__ARM_FEATURE_BTI_DEFAULT & 1) && \
defined(LUAJIT_ENABLE_CET_BR)
/* See comments about LUAJIT_ENABLE_CET_BR above. */
#define LJ_ABI_BRANCH_TRACK 1
#endif
#define LJ_TARGET_ARM64 1
#define LJ_TARGET_EHRETREG 0
#define LJ_TARGET_EHRAREG 30
Expand All @@ -270,8 +301,13 @@
#define LJ_TARGET_MASKROT 1
#define LJ_TARGET_UNIFYROT 2 /* Want only IR_BROR. */
#define LJ_TARGET_GC64 1
#define LJ_PAGESIZE 16384
#define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL

#if __ARM_FEATURE_UNALIGNED
#define LJ_TARGET_UNALIGNED 1
#endif

#define LJ_ARCH_VERSION 80

#elif LUAJIT_TARGET == LUAJIT_ARCH_PPC
Expand Down Expand Up @@ -425,7 +461,7 @@
#define LJ_TARGET_MIPS 1
#define LJ_TARGET_EHRETREG 4
#define LJ_TARGET_EHRAREG 31
#define LJ_TARGET_JUMPRANGE 27 /* 2*2^27 = 256MB-aligned region */
#define LJ_TARGET_JUMPRANGE 28 /* 2^28 = 256MB-aligned region */
#define LJ_TARGET_MASKSHIFT 1
#define LJ_TARGET_MASKROT 1
#define LJ_TARGET_UNIFYROT 2 /* Want only IR_BROR. */
Expand Down
9 changes: 8 additions & 1 deletion src/lj_asm.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ typedef struct ASMState {
MCode *invmcp; /* Points to invertible loop branch (or NULL). */
MCode *flagmcp; /* Pending opportunity to merge flag setting ins. */
MCode *realign; /* Realign loop if not NULL. */
MCode *mctail; /* Tail of trace before stack adjust + jmp. */
#if LJ_TARGET_PPC || LJ_TARGET_ARM64
MCode *mcexit; /* Pointer to exit stubs. */
#endif

#ifdef LUAJIT_RANDOM_RA
/* Randomize register allocation. OK for fuzz testing, not for production. */
Expand Down Expand Up @@ -2541,7 +2545,7 @@ void lj_asm_trace(jit_State *J, GCtrace *T)
RA_DBGX((as, "===== STOP ====="));

/* General trace setup. Emit tail of trace. */
asm_tail_prep(as);
asm_tail_prep(as, T->link);
as->mcloop = NULL;
as->flagmcp = NULL;
as->topslot = 0;
Expand Down Expand Up @@ -2586,6 +2590,9 @@ void lj_asm_trace(jit_State *J, GCtrace *T)
asm_head_side(as);
else
asm_head_root(as);
#if LJ_ABI_BRANCH_TRACK
emit_branch_track(as);
#endif
asm_phi_fixup(as);

if (J->curfinal->nins >= T->nins) { /* IR didn't grow? */
Expand Down
Loading