This commit is contained in:
Pavel 2025-01-23 17:56:51 +03:00
parent 245db5d640
commit 6bcc9a26c1
5 changed files with 364 additions and 87 deletions

View File

@ -595,17 +595,27 @@ begin
end;
end;
{
type
pSceKernelEventFlag=PPointer;
pSceKernelEventFlagOptParam=Pointer;
var
ps4_sceKernelCreateEventFlag:function(ef:pSceKernelEventFlag;
pName:PChar;
attr:DWORD;
initPattern:QWORD;
pOptParam:pSceKernelEventFlagOptParam
):Integer;
function ps4_sceNpCreateEventFlag(ef:pSceKernelEventFlag;
pName:PChar;
attr:DWORD;
initPattern:QWORD
):Integer;
):Integer;
begin
Result:=ps4_sceKernelCreateEventFlag(ef,pName,attr,initPattern,nil);
Result:=(Result shr $1F) and Result; // Looks like bool, but True when Result<0
end;
}
function ExecuteGuest_mallocFunc(addr:Pointer;size:size_t;userdata:Pointer):Pointer; external name 'ExecuteGuest';
@ -615,12 +625,88 @@ var
npObj:PSceNpObject;
begin
npObj:=ExecuteGuest_mallocFunc(mem^.mallocFunc,size+$10,mem^.userdata);
if npObj<>nil then
if (npObj<>nil) then
begin
npObj^.mem:=mem;
Result:=@npObj^.entry;
end else
begin
Result:=nil;
end;
end;
//
type
p_obj_cbs=^t_obj_cbs;
t_obj_cbs=packed record
clear:Pointer;
free :Pointer;
end;
p_EventFlag=^t_EventFlag;
t_EventFlag=packed record
cbs :p_obj_cbs;
evf :Pointer;
evtype:Integer;
end;
p_Mutex=^t_Mutex;
t_Mutex=packed record
cbs :p_obj_cbs;
mutex :Pointer;
init :Byte;
end;
var
global_evf_cbs :p_obj_cbs;
global_mutex_cbs:p_obj_cbs;
//sce::np::EventFlag::EventFlag(EventFlag *this)
procedure ps4__ZN3sce2np9EventFlagC1Ev(this:p_EventFlag);
begin
this^.cbs :=global_evf_cbs;
this^.evf :=nil;
this^.evtype:=0;
end;
//sce::np::EventFlag::Create(EventFlag *this,char *name,uint attr)
function ps4__ZN3sce2np9EventFlag6CreateEPKcj(this:p_EventFlag;name:PChar;attr:DWORD):Integer;
begin
Result:=Integer($80559e03);
if (this^.evtype=0) then
begin
Result:=ps4_sceNpCreateEventFlag(@this^.evf,name,attr,0);
if (Result > -1) then
begin
this^.evtype:=1;
end;
end;
end;
//
//sce::np::Mutex::Mutex(Mutex *this)
procedure ps4__ZN3sce2np5MutexC1Ev(this:p_Mutex);
begin
this^.cbs :=global_mutex_cbs;
this^.mutex:=nil;
this^.init :=0;
end;
//sce::np::Mutex::Init(Mutex *this,char *name,uint flags)
function ps4__ZN3sce2np5Mutex4InitEPKcj(this:p_Mutex;name:PChar;flags:DWORD):Integer;
begin
Result:=Integer($80559e03);
if (this^.init=0) then
begin
Result:=ps4_sceNpMutexInit(@this^.mutex,name,(flags and 1)<>0);
if (Result > -1) then
begin
Result:=0;
this^.init:=1;
end;
end;
end;
function Load_libSceNpCommon(name:pchar):p_lib_info;
@ -652,15 +738,27 @@ begin
lib.set_proc($DA3747A0FA52F96D,@ps4_sceNpHeapGetStat);
lib.set_proc($C15767EFC1CA737D,@ps4_sceNpHeapDestroy);
//
//lib.set_proc($EA3156A407EA01C7,@ps4_sceNpCreateEventFlag);
lib.set_proc($EA3156A407EA01C7,@ps4_sceNpCreateEventFlag);
//
lib.set_proc($D2CC8D921240355C,@ps4__ZN3sce2np6ObjectnwEmR14SceNpAllocator);
//
lib.set_proc($70C3A0904D8CD9EF,@ps4__ZN3sce2np9EventFlagC1Ev);
lib.set_proc($6A6162FC0BF5F615,@ps4__ZN3sce2np9EventFlag6CreateEPKcj);
//
lib.set_proc($3B502F950537DE92,@ps4__ZN3sce2np5MutexC1Ev);
lib.set_proc($69334E97D101E15E,@ps4__ZN3sce2np5Mutex4InitEPKcj);
//
lib.add_data(@global_evf_cbs ,SizeOf(t_obj_cbs));
lib.add_data(@global_mutex_cbs,SizeOf(t_obj_cbs));
//
//import
module:=Result^.add_mod('libkernel',1);
lib:=module.add_lib('libkernel');
lib.set_proc($0691686E8509A195,@ps4_sceKernelCreateEventFlag);
lib.set_proc($98BF0D0C7F3A8902,@ps4_sceKernelMapNamedFlexibleMemory);
lib.set_proc($17C6D41F0006DBCE,@ps4_scePthreadMutexattrInit);

View File

@ -1283,6 +1283,16 @@ begin
end;
end;
procedure ExecuteStop; SysV_ABI_CDecl; assembler; nostackframe; public;
asm
//restore rbp,rsp
//load r14,r15,r13
movq jit_frame.tf_r14(%r13),%r14
movq jit_frame.tf_r15(%r13),%r15
movq jit_frame.tf_r13(%r13),%r13
end;
//rdi -> addr
//rsi -> rdi
//rdx -> rsi
@ -1290,6 +1300,9 @@ end;
//r8 -> rcx
//r9 -> r8
// EXECUTE_MAGIC_ADDR $FFFFFFFFFCAFEDAD
// $0xFCAFEDAD = -55579219
procedure ExecuteGuest; SysV_ABI_CDecl; assembler; nostackframe; public;
asm
//save r13
@ -1323,14 +1336,14 @@ asm
xorq %r15,%r15
call jit_jmp_dispatch //in:r14(addr) r15(plt) out:r14(addr)
call %r14
movq jit_frame.tf_rsp(%r13), %r15 //mov r15,rsp
leaq -8(%r15), %r15 //lea r15,[r15-8]
//restore rbp,rsp
movq $-55579219,(%r15) //mov [r15],magic (sign extend)
//load r14,r15,r13
movq jit_frame.tf_r14(%r13),%r14
movq jit_frame.tf_r15(%r13),%r15
movq jit_frame.tf_r13(%r13),%r13
movq %r15, jit_frame.tf_rsp(%r13) //mov rsp,r15
jmp %r14
end;
function is_push_op(Opcode:TOpcode):Boolean; inline;

View File

@ -655,6 +655,11 @@ begin
Result:=Byte(QWORD(addr) shr 4) xor Byte(QWORD(addr) shr 12);
end;
procedure ExecuteStop; external;
const
EXECUTE_MAGIC_ADDR:QWORD=QWORD($FFFFFFFFFCAFEDAD);
function jmp_dispatcher(addr:Pointer;plt:p_jit_plt;from:Pointer):Pointer; public;
label
_start;
@ -674,6 +679,10 @@ begin
begin
//switch to internal
if (QWORD(addr)=EXECUTE_MAGIC_ADDR) then
begin
Exit(@ExecuteStop);
end else
if ((QWORD(addr) and UNRESOLVE_MAGIC_MASK)=UNRESOLVE_MAGIC_ADDR) then
begin
if exist_jit_host(from,@td^.td_frame.tf_rip) then

View File

@ -659,6 +659,7 @@ begin
str:=obj_get_str(refobj,ref^.st_name);
ST_BIND:=ELF64_ST_BIND(ref^.st_info);
if (ST_BIND=STB_LOCAL) then
begin
def :=ref;

View File

@ -19,10 +19,12 @@ type
TLIBRARY=packed object
libptr:Pointer; //p_Lib_Entry
mod_id:Word;
function set_symb (nid:QWORD;info:Byte;value:Pointer):Boolean;
function set_proc (nid:QWORD;value:Pointer):Boolean;
function set_data (nid:QWORD;value:Pointer):Boolean;
function set_symb (nid:QWORD;info:Byte;value:Pointer;size:QWORD):Boolean;
function set_proc (nid:QWORD;value:Pointer):Boolean; //publish procedure export:[JIT->HLE] or import:[JIT->value^]
function set_data (nid:QWORD;value:Pointer;size:QWORD):Boolean; //publish data export:[JIT->HLE]
function set_weak (nid:QWORD;value:Pointer):Boolean;
function add_data (value:PPointer;size:QWORD):Boolean; //alloc local data [guest->value^]
function add_func (value:PPointer;code:Pointer):Boolean; //alloc JIT addr [guest->value^]
function get_value(nid:QWORD):Pointer;
end;
@ -554,7 +556,7 @@ begin
Result.mod_id:=mod_id;
end;
function TLIBRARY.set_symb(nid:QWORD;info:Byte;value:Pointer):Boolean;
function TLIBRARY.set_symb(nid:QWORD;info:Byte;value:Pointer;size:QWORD):Boolean;
var
lib_entry:p_Lib_Entry;
h_entry:p_sym_hash_entry;
@ -570,6 +572,7 @@ begin
//
h_entry^.sym.st_info :=info;
h_entry^.sym.st_value:=0; //jit build
h_entry^.sym.st_size :=size;
//
h_entry^.native:=value;
@ -599,17 +602,67 @@ end;
function TLIBRARY.set_proc(nid:QWORD;value:Pointer):Boolean;
begin
Result:=set_symb(nid,(STB_GLOBAL shl 4) or STT_FUN,value);
Result:=set_symb(nid,(STB_GLOBAL shl 4) or STT_FUN,value,0);
end;
function TLIBRARY.set_data(nid:QWORD;value:Pointer):Boolean;
function TLIBRARY.set_data(nid:QWORD;value:Pointer;size:QWORD):Boolean;
begin
Result:=set_symb(nid,(STB_GLOBAL shl 4) or STT_OBJECT,value);
Result:=set_symb(nid,(STB_GLOBAL shl 4) or STT_OBJECT,value,size);
end;
function TLIBRARY.set_weak(nid:QWORD;value:Pointer):Boolean;
begin
Result:=set_symb(nid,(STB_WEAK shl 4) or STT_FUN,value);
Result:=set_symb(nid,(STB_WEAK shl 4) or STT_FUN,value,0);
end;
function TLIBRARY.add_data(value:PPointer;size:QWORD):Boolean;
var
lib_entry:p_Lib_Entry;
h_entry:p_sym_hash_entry;
data:PPointer;
begin
lib_entry:=libptr;
//
h_entry:=AllocMem(SizeOf(t_sym_hash_entry));
//
h_entry^.nid :=0;
h_entry^.mod_id:=mod_id; //export -> mod_id=0
h_entry^.lib_id:=lib_entry^.dval.id;
//
h_entry^.sym.st_info :=(STB_LOCAL shl 4) or STT_OBJECT;
h_entry^.sym.st_value:=0; //preload build
h_entry^.sym.st_size :=size;
//
h_entry^.native:=value;
TAILQ_INSERT_TAIL(@Lib_Entry^.syms,h_entry,@h_entry^.link);
Inc(Lib_Entry^.count);
Result:=True;
end;
function TLIBRARY.add_func(value:PPointer;code:Pointer):Boolean;
var
lib_entry:p_Lib_Entry;
h_entry:p_sym_hash_entry;
data:PPointer;
begin
lib_entry:=libptr;
//
h_entry:=AllocMem(SizeOf(t_sym_hash_entry));
//
h_entry^.nid :=0;
h_entry^.mod_id:=mod_id; //export -> mod_id=0
h_entry^.lib_id:=lib_entry^.dval.id;
//
h_entry^.sym.st_info :=(STB_LOCAL shl 4) or STT_FUN;
h_entry^.sym.st_value:=PtrUint(code);
h_entry^.sym.st_size :=0;
//
h_entry^.native:=value;
TAILQ_INSERT_TAIL(@Lib_Entry^.syms,h_entry,@h_entry^.link);
Inc(Lib_Entry^.count);
Result:=True;
end;
function TLIBRARY.get_value(nid:QWORD):Pointer;
@ -2890,40 +2943,84 @@ end;
function map_prx_internal(name:pchar;obj:p_lib_info):Integer;
var
Lib_Entry:p_Lib_Entry;
h_entry:p_sym_hash_entry;
h_entry :p_sym_hash_entry;
hle_import_table:p_hle_import_entry;
hle_import_base :PPointer;
hle_local_data :Pointer;
map:vm_map_t;
vaddr_lo:QWORD;
vaddr_hi:QWORD;
data :Pointer;
vaddr_lo :QWORD;
vaddr_hi :QWORD;
data :Pointer;
export_count:Integer;
import_count:Integer;
local_size :QWORD;
s :QWORD;
i,error:Integer;
begin
Result:=0;
export_count:=0;
import_count:=0;
local_size :=0;
//get sym count
Lib_Entry:=TAILQ_FIRST(@obj^.lib_table);
while (Lib_Entry<>nil) do
begin
if (Lib_Entry^.import=0) then //export
//
h_entry:=TAILQ_FIRST(@Lib_Entry^.syms);
while (h_entry<>nil) do
begin
export_count:=export_count+Lib_Entry^.count;
end else
begin
import_count:=import_count+Lib_Entry^.count;
//
if (ELF64_ST_BIND(h_entry^.sym.st_info)=STB_LOCAL) then
begin
//local
Case ELF64_ST_TYPE(h_entry^.sym.st_info) of
STT_NOTYPE,
STT_FUN,
STT_SCE:
begin
export_count:=export_count+1;
end;
STT_OBJECT:
begin
local_size:=local_size+h_entry^.sym.st_size;
end;
else;
end; //case
//local
end else
if (ELF64_ST_BIND(h_entry^.sym.st_info)=STB_GLOBAL) then
begin
//global
Case ELF64_ST_TYPE(h_entry^.sym.st_info) of
STT_NOTYPE,
STT_FUN,
STT_SCE:
begin
if (Lib_Entry^.import=0) then //export
begin
export_count:=export_count+1;
end else
begin
import_count:=import_count+1;
end;
end;
else;
end; //case
//global
end;
//
h_entry:=TAILQ_NEXT(h_entry,@h_entry^.link)
end;
//
Lib_Entry:=TAILQ_NEXT(Lib_Entry,@Lib_Entry^.link)
end;
//jit export space = (export_count*8) + (import_count*2*8)
obj^.text_size:=AlignUp((export_count*8) + (import_count*2*8),PAGE_SIZE);
//jit import space = sceModuleParam + import_count*8
obj^.data_size:=AlignUp(Sizeof(TsceModuleParam)+import_count*8,PAGE_SIZE);
//jit import space = sceModuleParam + local_size + import_count*8
obj^.data_size:=AlignUp(Sizeof(TsceModuleParam)+local_size+import_count*8,PAGE_SIZE);
//sum
obj^.map_size :=obj^.text_size+obj^.data_size;
@ -2966,37 +3063,80 @@ begin
pSceModuleParam(data)^:=obj^.module_param^;
obj^.module_param:=data;
hle_import_base:=data+sizeOf(TsceModuleParam); //HLE
//per lib global data
hle_local_data :=data+sizeOf(TsceModuleParam); //HLE
//per lib import table
hle_import_base:=hle_local_data+local_size; //HLE
obj^.hle_import_count:=import_count;
//alloc hle import table
if (import_count<>0) then
//alloc hle import table / per lib global data
if (import_count<>0) or (local_size<>0) then
begin
hle_import_table:=AllocMem(import_count*SizeOf(t_hle_import_entry));
obj^.hle_import_table:=hle_import_table;
if (import_count<>0) then
begin
hle_import_table:=AllocMem(import_count*SizeOf(t_hle_import_entry));
obj^.hle_import_table:=hle_import_table;
end;
i:=0;
s:=0;
Lib_Entry:=TAILQ_FIRST(@obj^.lib_table);
while (Lib_Entry<>nil) do
begin
if (Lib_Entry^.import<>0) then //import
//
h_entry:=TAILQ_FIRST(@Lib_Entry^.syms);
while (h_entry<>nil) do
begin
h_entry:=TAILQ_FIRST(@Lib_Entry^.syms);
while (h_entry<>nil) do
//
if (ELF64_ST_BIND(h_entry^.sym.st_info)=STB_LOCAL) then
begin
hle_import_table[i].h_entry :=h_entry;
hle_import_table[i].jit_guest_addr :=nil; //jit build
hle_import_table[i].jit_host_addr :=nil; //jit dynamic cache
hle_import_table[i].import_place_addr:=@hle_import_base[i];
Inc(i);
//
h_entry:=TAILQ_NEXT(h_entry,@h_entry^.link)
//local
Case ELF64_ST_TYPE(h_entry^.sym.st_info) of
STT_OBJECT:
begin
PPointer(h_entry^.native)^:=(hle_local_data+s);
s:=s+h_entry^.sym.st_size;
end;
else;
end; //case
//local
end else
if (ELF64_ST_BIND(h_entry^.sym.st_info)=STB_GLOBAL) then
begin
//global
Case ELF64_ST_TYPE(h_entry^.sym.st_info) of
STT_NOTYPE,
STT_FUN,
STT_SCE:
begin
if (Lib_Entry^.import=0) then //export
begin
//
end else
begin
//
hle_import_table[i].h_entry :=h_entry;
hle_import_table[i].jit_guest_addr :=nil; //jit build
hle_import_table[i].jit_host_addr :=nil; //jit dynamic cache
hle_import_table[i].import_place_addr:=@hle_import_base[i];
Inc(i);
//
end;
end;
else;
end; //case
//global
end;
//
h_entry:=TAILQ_NEXT(h_entry,@h_entry^.link)
end;
//
Lib_Entry:=TAILQ_NEXT(Lib_Entry,@Lib_Entry^.link)
end;
end;
end; //(import_count<>0)
//protect text,data
vm_map_lock(map);
@ -3118,7 +3258,7 @@ var
Lib_Entry:p_Lib_Entry;
h_entry:p_sym_hash_entry;
i,hle_count,ST_TYPE:Integer;
i,hle_count:Integer;
hle_import_table:p_hle_import_entry;
@ -3142,17 +3282,35 @@ begin
h_entry:=TAILQ_FIRST(@Lib_Entry^.syms);
while (h_entry<>nil) do
begin
ST_TYPE:=ELF64_ST_TYPE(h_entry^.sym.st_info);
Case ST_TYPE of
STT_NOTYPE,
STT_FUN,
STT_SCE:
begin
ctx.add_export_point(h_entry^.native,@h_entry^.sym.st_value);
end;
else;
end; //case
if (ELF64_ST_BIND(h_entry^.sym.st_info)=STB_LOCAL) then
begin
//local
Case ELF64_ST_TYPE(h_entry^.sym.st_info) of
STT_NOTYPE,
STT_FUN,
STT_SCE:
begin
ctx.add_export_point(Pointer(h_entry^.sym.st_value),h_entry^.native);
end;
else;
end; //case
//local
end else
if (ELF64_ST_BIND(h_entry^.sym.st_info)=STB_GLOBAL) then
begin
//global
Case ELF64_ST_TYPE(h_entry^.sym.st_info) of
STT_NOTYPE,
STT_FUN,
STT_SCE:
begin
ctx.add_export_point(h_entry^.native,@h_entry^.sym.st_value);
end;
else;
end; //case
//global
end;
h_entry:=TAILQ_NEXT(h_entry,@h_entry^.link)
end;
@ -3171,17 +3329,16 @@ begin
begin
h_entry:=hle_import_table[i].h_entry;
ST_TYPE:=ELF64_ST_TYPE(h_entry^.sym.st_info);
Case ST_TYPE of
STT_NOTYPE,
STT_FUN,
STT_SCE:
begin
ctx.add_import_point(hle_import_table[i].import_place_addr,@hle_import_table[i].jit_guest_addr);
end;
else;
end; //case
if (ELF64_ST_BIND(h_entry^.sym.st_info)=STB_GLOBAL) then
Case ELF64_ST_TYPE(h_entry^.sym.st_info) of
STT_NOTYPE,
STT_FUN,
STT_SCE:
begin
ctx.add_import_point(hle_import_table[i].import_place_addr,@hle_import_table[i].jit_guest_addr);
end;
else;
end; //case
end;
end;
@ -3196,26 +3353,25 @@ begin
begin
h_entry:=hle_import_table[i].h_entry;
ST_TYPE:=ELF64_ST_TYPE(h_entry^.sym.st_info);
if (ELF64_ST_BIND(h_entry^.sym.st_info)=STB_GLOBAL) then
Case ELF64_ST_TYPE(h_entry^.sym.st_info) of
STT_NOTYPE,
STT_FUN,
STT_SCE:
begin
//
Assert(hle_import_table[i].jit_guest_addr<>nil,'jit_guest_addr');
Case ST_TYPE of
STT_NOTYPE,
STT_FUN,
STT_SCE:
begin
//
Assert(hle_import_table[i].jit_guest_addr<>nil,'jit_guest_addr');
node:=fetch_entry(hle_import_table[i].jit_guest_addr);
Assert(node<>nil,'fetch_entry');
//
hle_import_table[i].jit_host_addr:=node^.dst;
//
node^.dec_ref('fetch_entry');
//
end;
else;
end; //case
node:=fetch_entry(hle_import_table[i].jit_guest_addr);
Assert(node<>nil,'fetch_entry');
//
hle_import_table[i].jit_host_addr:=node^.dst;
//
node^.dec_ref('fetch_entry');
//
end;
else;
end; //case
end;
end;