From c8601a748f70c1e4e709f776f3eecb1e12efc4d6 Mon Sep 17 00:00:00 2001 From: SonicMastr Date: Wed, 1 Dec 2021 20:29:21 -0600 Subject: [PATCH 1/4] Initial Vita Port --- src/Makefile | 10 ++++++ src/host/buildvm_asm.c | 2 +- src/lib_io.c | 2 +- src/lib_os.c | 4 +-- src/lib_package.c | 2 +- src/lj_arch.h | 23 +++++++++---- src/lj_ccallback.c | 29 ++++++++++++++++ src/lj_clib.c | 4 +++ src/lj_def.h | 4 +++ src/lj_jit.h | 7 +++- src/lj_mcode.c | 78 ++++++++++++++++++++++++++++++++++++++++-- src/lj_prng.c | 8 +++++ 12 files changed, 158 insertions(+), 15 deletions(-) diff --git a/src/Makefile b/src/Makefile index 2538503f93..361b8ceffb 100644 --- a/src/Makefile +++ b/src/Makefile @@ -352,11 +352,17 @@ else ifeq (GNU/kFreeBSD,$(TARGET_SYS)) TARGET_XLIBS+= -ldl endif + ifeq (PSP2,$(TARGET_SYS)) + TARGET_XLIBS+= -ldl -lSceLibKernel_stub -ltaihen_stub -lSceSysmodule_stub + endif endif endif endif ifneq ($(HOST_SYS),$(TARGET_SYS)) + ifeq (PSP2,$(TARGET_SYS)) + HOST_XCFLAGS+= -DLUAJIT_OS=LUAJIT_OS_PSP2 -DLUAJIT_USE_SYSMALLOC + else ifeq (Windows,$(TARGET_SYS)) HOST_XCFLAGS+= -malign-double -DLUAJIT_OS=LUAJIT_OS_WINDOWS else @@ -374,6 +380,7 @@ ifneq ($(HOST_SYS),$(TARGET_SYS)) endif endif endif + endif endif ifneq (,$(CCDEBUG)) @@ -559,6 +566,9 @@ endif ifeq (PS3,$(TARGET_SYS)) BUILDMODE= static endif +ifeq (PSP2,$(TARGET_SYS)) + BUILDMODE= static +endif ifeq (Windows,$(HOST_SYS)) MINILUA_T= host/minilua.exe diff --git a/src/host/buildvm_asm.c b/src/host/buildvm_asm.c index 01a1ba0674..293b523946 100644 --- a/src/host/buildvm_asm.c +++ b/src/host/buildvm_asm.c @@ -324,7 +324,7 @@ void emit_asm(BuildCtx *ctx) fprintf(ctx->fp, "\n"); switch (ctx->mode) { case BUILD_elfasm: -#if !(LJ_TARGET_PS3 || LJ_TARGET_PSVITA) +#if !(LJ_TARGET_PS3 || LJ_TARGET_PSVITA || LJ_TARGET_PSP2) fprintf(ctx->fp, "\t.section .note.GNU-stack,\"\"," ELFASM_PX "progbits\n"); #endif #if LJ_TARGET_PPC && !LJ_TARGET_PS3 && !LJ_ABI_SOFTFP diff --git a/src/lib_io.c b/src/lib_io.c index b9d8cc7581..91b05d0514 100644 --- a/src/lib_io.c +++ b/src/lib_io.c @@ -439,7 +439,7 @@ LJLIB_CF(io_popen) LJLIB_CF(io_tmpfile) { IOFileUD *iof = io_file_new(L); -#if LJ_TARGET_PS3 || LJ_TARGET_PS4 || LJ_TARGET_PSVITA +#if LJ_TARGET_PS3 || LJ_TARGET_PS4 || LJ_TARGET_PSVITA || LJ_TARGET_PSP2 iof->fp = NULL; errno = ENOSYS; #else iof->fp = tmpfile(); diff --git a/src/lib_os.c b/src/lib_os.c index f19b831c75..a213b706d5 100644 --- a/src/lib_os.c +++ b/src/lib_os.c @@ -76,7 +76,7 @@ LJLIB_CF(os_rename) LJLIB_CF(os_tmpname) { -#if LJ_TARGET_PS3 || LJ_TARGET_PS4 || LJ_TARGET_PSVITA +#if LJ_TARGET_PS3 || LJ_TARGET_PS4 || LJ_TARGET_PSVITA || LJ_TARGET_PSP2 lj_err_caller(L, LJ_ERR_OSUNIQF); return 0; #else @@ -101,7 +101,7 @@ LJLIB_CF(os_tmpname) LJLIB_CF(os_getenv) { -#if LJ_TARGET_CONSOLE +#if LJ_TARGET_CONSOLE || LJ_TARGET_PSP2 lua_pushnil(L); #else lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */ diff --git a/src/lib_package.c b/src/lib_package.c index 2068a098b2..ea2c16947b 100644 --- a/src/lib_package.c +++ b/src/lib_package.c @@ -550,7 +550,7 @@ static int lj_cf_package_seeall(lua_State *L) static void setpath(lua_State *L, const char *fieldname, const char *envname, const char *def, int noenv) { -#if LJ_TARGET_CONSOLE +#if LJ_TARGET_CONSOLE || LJ_TARGET_PSP2 const char *path = NULL; UNUSED(envname); #else diff --git a/src/lj_arch.h b/src/lj_arch.h index ae99946763..25fbf4a9b7 100644 --- a/src/lj_arch.h +++ b/src/lj_arch.h @@ -34,11 +34,12 @@ /* Target OS. */ #define LUAJIT_OS_OTHER 0 -#define LUAJIT_OS_WINDOWS 1 -#define LUAJIT_OS_LINUX 2 -#define LUAJIT_OS_OSX 3 -#define LUAJIT_OS_BSD 4 -#define LUAJIT_OS_POSIX 5 +#define LUAJIT_OS_PSP2 1 +#define LUAJIT_OS_WINDOWS 2 +#define LUAJIT_OS_LINUX 3 +#define LUAJIT_OS_OSX 4 +#define LUAJIT_OS_BSD 5 +#define LUAJIT_OS_POSIX 6 /* Number mode. */ #define LJ_NUMMODE_SINGLE 0 /* Single-number mode only. */ @@ -74,7 +75,9 @@ /* Select native OS if no target OS defined. */ #ifndef LUAJIT_OS -#if defined(_WIN32) && !defined(_XBOX_VER) +#if defined(__vita__) +#define LUAJIT_OS LUAJIT_OS_PSP2 +#elif defined(_WIN32) && !defined(_XBOX_VER) #define LUAJIT_OS LUAJIT_OS_WINDOWS #elif defined(__linux__) #define LUAJIT_OS LUAJIT_OS_LINUX @@ -110,16 +113,20 @@ #define LJ_OS_NAME "BSD" #elif LUAJIT_OS == LUAJIT_OS_POSIX #define LJ_OS_NAME "POSIX" +#elif LUAJIT_OS == LUAJIT_OS_PSP2 +#define LJ_OS_NAME "PSP2" +#define LUAJIT_USE_SYSMALLOC 1 #else #define LJ_OS_NAME "Other" #endif +#define LJ_TARGET_PSP2 (LUAJIT_OS == LUAJIT_OS_PSP2) #define LJ_TARGET_WINDOWS (LUAJIT_OS == LUAJIT_OS_WINDOWS) #define LJ_TARGET_LINUX (LUAJIT_OS == LUAJIT_OS_LINUX) #define LJ_TARGET_OSX (LUAJIT_OS == LUAJIT_OS_OSX) #define LJ_TARGET_BSD (LUAJIT_OS == LUAJIT_OS_BSD) #define LJ_TARGET_POSIX (LUAJIT_OS > LUAJIT_OS_WINDOWS) -#define LJ_TARGET_DLOPEN LJ_TARGET_POSIX +#define LJ_TARGET_DLOPEN (LJ_TARGET_POSIX || LJ_TARGET_PSP2) #if TARGET_OS_IPHONE #define LJ_TARGET_IOS 1 @@ -558,6 +565,8 @@ #if defined(LUAJIT_DISABLE_PROFILE) #define LJ_HASPROFILE 0 +#elif LJ_TARGET_PSP2 +#define LJ_HASPROFILE 0 #elif LJ_TARGET_POSIX #define LJ_HASPROFILE 1 #define LJ_PROFILE_SIGPROF 1 diff --git a/src/lj_ccallback.c b/src/lj_ccallback.c index 80d738c66a..dc510265ce 100644 --- a/src/lj_ccallback.c +++ b/src/lj_ccallback.c @@ -250,6 +250,10 @@ static void *callback_mcode_init(global_State *g, uint32_t *page) #define WIN32_LEAN_AND_MEAN #include +#elif LJ_TARGET_PSP2 + +#include + #elif LJ_TARGET_POSIX #include @@ -275,6 +279,21 @@ static void callback_mcode_new(CTState *cts) p = LJ_WIN_VALLOC(NULL, sz, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); if (!p) lj_err_caller(cts->L, LJ_ERR_FFI_CBACKOV); +#elif LJ_TARGET_PSP2 + { + int fail; + SceUID block = sceKernelAllocMemBlockForVM("LuaJITCallbackCodeMemBlock", sz); + if (block < 0) + fail = 1; + else if (LJ_UNLIKELY(sceKernelGetMemBlockBase(block, &p) < 0)) + fail = 1; + else if (sceKernelOpenVMDomain() < 0) + fail = 1; + else + fail = 0; + if (fail) + lj_err_caller(cts->L, LJ_ERR_FFI_CBACKOV); + } #elif LJ_TARGET_POSIX p = mmap(NULL, sz, (PROT_READ|PROT_WRITE|CCPROT_CREATE), MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); @@ -295,6 +314,8 @@ static void callback_mcode_new(CTState *cts) DWORD oprot; LJ_WIN_VPROTECT(p, sz, PAGE_EXECUTE_READ, &oprot); } +#elif LJ_TARGET_PSP2 + sceKernelCloseVMDomain(); #elif LJ_TARGET_POSIX mprotect(p, sz, (PROT_READ|PROT_EXEC)); #endif @@ -309,6 +330,14 @@ void lj_ccallback_mcode_free(CTState *cts) #if LJ_TARGET_WINDOWS VirtualFree(p, 0, MEM_RELEASE); UNUSED(sz); +#elif LJ_TARGET_PSP2 + { + SceUID block; + void *base = (void *)((uintptr_t)p & ~(uintptr_t)0xFFFFF); + block = sceKernelFindMemBlockByAddr(base, 0); + sceKernelFreeMemBlock(block); + UNUSED(sz); + } #elif LJ_TARGET_POSIX munmap(p, sz); #else diff --git a/src/lj_clib.c b/src/lj_clib.c index d8636a48bc..3a5f4acad0 100644 --- a/src/lj_clib.c +++ b/src/lj_clib.c @@ -42,6 +42,8 @@ LJ_NORET LJ_NOINLINE static void clib_error_(lua_State *L) #if LJ_TARGET_CYGWIN #define CLIB_SOPREFIX "cyg" +#elif LJ_TARGET_PSP2 +#define CLIB_SOPREFIX "" #else #define CLIB_SOPREFIX "lib" #endif @@ -50,6 +52,8 @@ LJ_NORET LJ_NOINLINE static void clib_error_(lua_State *L) #define CLIB_SOEXT "%s.dylib" #elif LJ_TARGET_CYGWIN #define CLIB_SOEXT "%s.dll" +#elif LJ_TARGET_PSP2 +#define CLIB_SOEXT "%s" #else #define CLIB_SOEXT "%s.so" #endif diff --git a/src/lj_def.h b/src/lj_def.h index 3a28026c52..1d9721d6ad 100644 --- a/src/lj_def.h +++ b/src/lj_def.h @@ -71,7 +71,11 @@ typedef unsigned int uintptr_t; #define LJ_MAX_IDXCHAIN 100 /* __index/__newindex chain limit. */ #define LJ_STACK_EXTRA (5+2*LJ_FR2) /* Extra stack space (metamethods). */ +#if LJ_TARGET_PSP2 +#define LJ_NUM_CBPAGE 256 /* Number of FFI callback pages. */ +#else #define LJ_NUM_CBPAGE 1 /* Number of FFI callback pages. */ +#endif /* Minimum table/buffer sizes. */ #define LJ_MIN_GLOBAL 6 /* Min. global table size (hbits). */ diff --git a/src/lj_jit.h b/src/lj_jit.h index c9fe83191f..2fd90f7896 100644 --- a/src/lj_jit.h +++ b/src/lj_jit.h @@ -100,7 +100,11 @@ #define JIT_F_OPT_DEFAULT JIT_F_OPT_3 /* -- JIT engine parameters ----------------------------------------------- */ - +#if LJ_TARGET_PSP2 +#define JIT_P_sizemcode_DEFAULT 1024 +#define JIT_P_maxmcode_DEFAULT 8192 +#else +#define JIT_P_maxmcode_DEFAULT 512 #if LJ_TARGET_WINDOWS || LJ_64 /* See: http://blogs.msdn.com/oldnewthing/archive/2003/10/08/55239.aspx */ #define JIT_P_sizemcode_DEFAULT 64 @@ -108,6 +112,7 @@ /* Could go as low as 4K, but the mmap() overhead would be rather high. */ #define JIT_P_sizemcode_DEFAULT 32 #endif +#endif /* Optimization parameters and their defaults. Length is a char in octal! */ #define JIT_PARAMDEF(_) \ diff --git a/src/lj_mcode.c b/src/lj_mcode.c index b3efbc55d3..f9349aea91 100644 --- a/src/lj_mcode.c +++ b/src/lj_mcode.c @@ -33,13 +33,23 @@ void sys_icache_invalidate(void *start, size_t len); #endif +#if LJ_TARGET_PSP2 +#include +#endif + /* Synchronize data/instruction cache. */ void lj_mcode_sync(void *start, void *end) { #ifdef LUAJIT_USE_VALGRIND VALGRIND_DISCARD_TRANSLATIONS(start, (char *)end-(char *)start); #endif -#if LJ_TARGET_X86ORX64 +#if LJ_TARGET_PSP2 + SceUID block; + void *base = (void *)((uintptr_t)start & ~(uintptr_t)0xFFFFF); + block = sceKernelFindMemBlockByAddr(base, 0); + /* Removed Assertion */ + sceKernelSyncVMDomain(block, start, (char *)end-(char *)start); +#elif LJ_TARGET_X86ORX64 UNUSED(start); UNUSED(end); #elif LJ_TARGET_IOS sys_icache_invalidate(start, (char *)end-(char *)start); @@ -56,7 +66,58 @@ void lj_mcode_sync(void *start, void *end) #if LJ_HASJIT -#if LJ_TARGET_WINDOWS +#if LJ_TARGET_PSP2 + +#define LUAJIT_PSP2PROTECT_MCODE +#define MCPROT_RX 0 +#define MCPROT_RWX 1 + +/* +** NYI: proper fix of the potential race condition. +** Currently there's only a dirty hack on lj_mcode_patch. +*/ +static int mcode_setprot(void *p, size_t sz, int prot) +{ + UNUSED(p); UNUSED(sz); + if (MCPROT_RX == prot) + return sceKernelCloseVMDomain(); + else + return sceKernelOpenVMDomain(); +} + +static void *mcode_alloc_at(jit_State *J, uintptr_t hint, size_t sz, int prot) +{ + void *p; + int fail; + SceUID block = sceKernelAllocMemBlockForVM("LuaJITCodeMemBlock", sz); + if (block < 0) { + fail = 1; + } else if (LJ_UNLIKELY(sceKernelGetMemBlockBase(block, &p) < 0)) { + sceKernelFreeMemBlock(block); + fail = 1; + } else if (mcode_setprot(p, sz, prot)) { + sceKernelFreeMemBlock(block); + fail = 1; + } else { + fail = 0; + } + if (fail) { + if (!hint) lj_trace_err(J, LJ_TRERR_MCODEAL); + p = NULL; + } + return p; +} + +static void mcode_free(jit_State *J, void *p, size_t sz) +{ + SceUID block; + void *base = (void *)((uintptr_t)p & ~(uintptr_t)0xFFFFF); + block = sceKernelFindMemBlockByAddr(base, 0); + /* Removed Assertion */ + sceKernelFreeMemBlock(block); +} + +#elif LJ_TARGET_WINDOWS #define WIN32_LEAN_AND_MEAN #include @@ -154,6 +215,12 @@ static void mcode_protect(jit_State *J, int prot) UNUSED(J); UNUSED(prot); UNUSED(mcode_setprot); } +#else +#if defined(LUAJIT_PSP2PROTECT_MCODE) + +#define MCPROT_GEN MCPROT_RWX +#define MCPROT_RUN MCPROT_RX + #else /* This is the default behaviour and much safer: @@ -167,6 +234,8 @@ static void mcode_protect(jit_State *J, int prot) #define MCPROT_GEN MCPROT_RW #define MCPROT_RUN MCPROT_RX +#endif + /* Protection twiddling failed. Probably due to kernel security. */ static LJ_NOINLINE void mcode_protfail(jit_State *J) { @@ -326,7 +395,12 @@ MCode *lj_mcode_patch(jit_State *J, MCode *ptr, int finish) #if LUAJIT_SECURITY_MCODE if (J->mcarea == ptr) mcode_protect(J, MCPROT_RUN); +#ifdef LUAJIT_PSP2PROTECT_MCODE + /* Restore previous state of the current (top) MCode area */ + else if (LJ_UNLIKELY(mcode_setprot(NULL, 0, J->mcprot))) +#else else if (LJ_UNLIKELY(mcode_setprot(ptr, ((MCLink *)ptr)->size, MCPROT_RUN))) +#endif mcode_protfail(J); #endif return NULL; diff --git a/src/lj_prng.c b/src/lj_prng.c index bb32da8b0e..1bda8e117a 100644 --- a/src/lj_prng.c +++ b/src/lj_prng.c @@ -87,6 +87,10 @@ extern int sys_get_random_number(void *buf, uint64_t len); extern int sceRandomGetRandomNumber(void *buf, size_t len); +#elif LJ_TARGET_PSP2 + +extern int sceKernelGetRandomNumber(void *buf, size_t len); + #elif LJ_TARGET_WINDOWS || LJ_TARGET_XBOXONE #define WIN32_LEAN_AND_MEAN @@ -176,6 +180,10 @@ int LJ_FASTCALL lj_prng_seed_secure(PRNGState *rs) if (sceRandomGetRandomNumber(rs->u, sizeof(rs->u)) == 0) goto ok; +#elif LJ_TARGET_PSP2 + if (sceKernelGetRandomNumber(rs->u, sizeof(rs->u)) == 0) + goto ok; + #elif LJ_TARGET_UWP || LJ_TARGET_XBOXONE if (BCryptGenRandom(NULL, (PUCHAR)(rs->u), (ULONG)sizeof(rs->u), From 16adf524b3bda92da1a89e550dc2d2ff088b99f1 Mon Sep 17 00:00:00 2001 From: Jaylon Gowie Date: Fri, 19 Aug 2022 02:43:37 -0500 Subject: [PATCH 2/4] Update LuaJIT for new Vita libdl --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile b/src/Makefile index 132be7837c..a3826fd42f 100644 --- a/src/Makefile +++ b/src/Makefile @@ -353,7 +353,7 @@ else TARGET_XLIBS+= -ldl endif ifeq (PSP2,$(TARGET_SYS)) - TARGET_XLIBS+= -ldl -lSceLibKernel_stub -ltaihen_stub -lSceSysmodule_stub + TARGET_XLIBS+= -ldl -ltaihen_stub -lSceKernelModulemgr_stub -lSceSblSsMgr_stub -lSceLibKernel_stub -lSceSysmodule_stub endif endif endif From b94f5cb15223a58f741e8fdffcfddad303baa52b Mon Sep 17 00:00:00 2001 From: Jaylon Gowie Date: Fri, 19 Aug 2022 03:04:13 -0500 Subject: [PATCH 3/4] Fix VitaSDK build --- src/lj_prng.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/lj_prng.c b/src/lj_prng.c index 6ab326a394..55a41c146b 100644 --- a/src/lj_prng.c +++ b/src/lj_prng.c @@ -189,6 +189,11 @@ int LJ_FASTCALL lj_prng_seed_secure(PRNGState *rs) if (getentropy(rs->u, sizeof(rs->u)) == 0) goto ok; +#elif LJ_TARGET_PSP2 + + if (sceKernelGetRandomNumber(rs->u, sizeof(rs->u)) == 0) + goto ok; + #elif LJ_TARGET_UWP || LJ_TARGET_XBOXONE if (BCryptGenRandom(NULL, (PUCHAR)(rs->u), (ULONG)sizeof(rs->u), From c329ddd10691c1875f26087ba23c2ae278515e24 Mon Sep 17 00:00:00 2001 From: Jaylon Gowie Date: Fri, 19 Aug 2022 03:20:46 -0500 Subject: [PATCH 4/4] Vita: Fix libdl support --- src/lj_clib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lj_clib.c b/src/lj_clib.c index 2a8eb2bf7b..715491e29e 100644 --- a/src/lj_clib.c +++ b/src/lj_clib.c @@ -53,7 +53,7 @@ LJ_NORET LJ_NOINLINE static void clib_error_(lua_State *L) #elif LJ_TARGET_CYGWIN #define CLIB_SOEXT "%s.dll" #elif LJ_TARGET_PSP2 -#define CLIB_SOEXT "%s" +#define CLIB_SOEXT "%s.suprx" #else #define CLIB_SOEXT "%s.so" #endif