This commit is contained in:
red-prig 2022-10-02 00:46:07 +03:00
parent 0482c59a4a
commit 57b2c9fa13
5 changed files with 514 additions and 63 deletions

View File

@ -34,7 +34,7 @@ int _sceKernelMapDirectMemory
adr = *virtualAddrDest; adr = *virtualAddrDest;
if ((((_direct_pool_id == 1) && ((APP_INFO[4] & 2) == 0)) && if ((((_direct_pool_id == 1) && ((APP_INFO[4] & 2) == 0)) &&
(((long)physicalAddr < 0x3000000000 || (0x301fffffff < physicalAddr)))) && (((long)physicalAddr < 0x3000000000 || (0x301fffffff < physicalAddr)))) &&
(((flags & 0x400U) == 0 && (0x24fffff < SDK_VERSION)))) { (((flags & SCE_KERNEL_MAP_DMEM_COMPAT) == 0 && (0x24fffff < SDK_VERSION)))) {
ret1 = sceKernelMapDirectMemory2 ret1 = sceKernelMapDirectMemory2
(virtualAddrDest,length,-1,protections,flags,physicalAddr,alignment); (virtualAddrDest,length,-1,protections,flags,physicalAddr,alignment);
return ret1; return ret1;
@ -330,3 +330,102 @@ int sceKernelReleaseFlexibleMemory(void *addr,size_t len)
return ret1; return ret1;
} }
int sceKernelQueryMemoryProtection(void *addr,void **start,void **end,int *prot)
{
int ret1;
int *perror;
void *_start;
void *_end;
uint _prot;
long __guard;
int err;
__guard = __stack_chk_guard._0_8_;
ret1 = sys_query_memory_protection(addr,&_start);
if (ret1 == 0) {
if (start != (void **)0x0) {
*start = _start;
}
if (end != (void **)0x0) {
*end = _end;
}
ret1 = 0;
if (prot != (int *)0x0) {
*prot = _prot & 0x37;
}
}
else {
perror = (int *)__error();
err = *perror;
ret1 = err + -0x7ffe0000;
if (err == 0) {
ret1 = err;
}
}
if (__stack_chk_guard._0_8_ != __guard) {
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
return ret1;
}
int sceKernelVirtualQuery(void *addr,int flags,void *info,qword infoSize)
{
int ret1;
int err;
int *perror;
ret1 = sys_virtual_query();
err = 0;
if (ret1 == -1) {
perror = (int *)__error();
ret1 = *perror;
err = ret1 + -0x7ffe0000;
if (ret1 == 0) {
err = ret1;
}
}
return err;
}
int sceKernelMtypeprotect(void *addr,qword len,int type,int prot)
{
int ret1;
int err;
int *perror;
ret1 = sys_mtypeprotect();
err = 0;
if (ret1 == -1) {
perror = (int *)__error();
ret1 = *perror;
err = ret1 + -0x7ffe0000;
if (ret1 == 0) {
err = ret1;
}
}
return err;
}
int sceKernelSetVirtualRangeName(void *addr,qword len,char *name)
{
int ret1;
int err;
int *perror;
ret1 = sys_mname();
err = 0;
if (ret1 == -1) {
perror = (int *)__error();
ret1 = *perror;
err = ret1 + -0x7ffe0000;
if (ret1 == 0) {
err = ret1;
}
}
return err;
}

View File

@ -154,7 +154,7 @@ type
Function check_fixed(Offset:Pointer;Size:QWORD;flags:Byte;fd:Integer):Integer; Function check_fixed(Offset:Pointer;Size:QWORD;flags:Byte;fd:Integer):Integer;
Function mmap(Offset:Pointer;Size,Align:QWORD;prot,flags:Byte;fd:Integer;addr:QWORD;var AdrOut:Pointer):Integer; Function mmap(Offset:Pointer;Size,Align:QWORD;prot,flags:Byte;fd:Integer;addr:QWORD;var AdrOut:Pointer):Integer;
Function CheckedAlloc(Offset:Pointer;Size:QWORD):Integer; procedure Protect(Offset:Pointer;Size:QWORD;prot:Integer);
Function Release(Offset:Pointer;Size:QWORD):Integer; Function Release(Offset:Pointer;Size:QWORD):Integer;
procedure Print; procedure Print;
@ -1113,40 +1113,98 @@ begin
end; end;
end; end;
///////// procedure TVirtualManager.Protect(Offset:Pointer;Size:QWORD;prot:Integer);
Function TVirtualManager.CheckedAlloc(Offset:Pointer;Size:QWORD):Integer;
var var
It:TAllcPoolNodeSet.Iterator;
key:TVirtualAdrNode; key:TVirtualAdrNode;
FEndO:Pointer; FEndN,FEndO:Pointer;
begin FSize:QWORD;
Result:=0;
if (Size=0) then Exit(EINVAL);
if (Offset<Flo) or (Offset>Fhi) then Exit(EINVAL);
FEndO:=Offset+Size; function _fetch:Boolean;
begin
Result:=False;
if _FetchNode_m(M_LE or C_FR or C_LE,Offset,key) then
begin
FEndN:=Offset+Size;
FEndO:=key.Offset+key.Size;
_Devide(Offset,Size,key);
Result:=True;
end else
if _FetchNode_m(M_BE or C_FR or C_BE,Offset,key) then
begin
FEndN:=Offset+Size;
FEndO:=key.Offset+key.Size;
_Devide(key.Offset,FEndN-key.Offset,key);
Result:=True;
end;
end;
function _map:Boolean;
begin
Result:=False;
//new save
if (key.block=nil) then
begin
key.F.prot:=prot;
end else
begin
key.block^.Protect(@key,prot);
end;
_Merge(key);
if (FEndO>=FEndN) then Exit(True);
FSize:=FEndO-Offset;
Offset:=Offset+FSize;
Size :=Size -FSize;
end;
function _skip:Boolean; inline;
begin
Result:=False;
FEndN:=Offset+Size;
FEndO:=key.Offset+key.Size;
if (FEndO>=FEndN) then Exit(True);
FSize:=FEndO-Offset;
Offset:=Offset+FSize;
Size :=Size -FSize;
end;
begin
repeat
key:=Default(TVirtualAdrNode); key:=Default(TVirtualAdrNode);
key.Offset:=Offset; key.Offset:=Offset;
It:=FAllcSet.find_le(key); if _fetch then
While (It.Item<>nil) do
begin begin
key:=It.Item^; if _map then Break;
end else
if (Offset>=key.Offset) then if _Find_m(M_LE,key) then
begin begin
if not key.IsFree then if _skip then Break;
end else
if _Find_m(M_BE,key) then
begin begin
Exit(ENOMEM); if _skip then Break;
end; end else
begin
Break;
end; end;
if (key.Offset>=FEndO) then Break; until false;
It.Next;
end;
end; end;
Function TVirtualManager.Release(Offset:Pointer;Size:QWORD):Integer; Function TVirtualManager.Release(Offset:Pointer;Size:QWORD):Integer;
@ -1291,11 +1349,34 @@ begin
until false; until false;
end; end;
function _alloc_str(IsFree:Boolean):RawByteString; function _alloc_str(var key:TVirtualAdrNode):RawByteString;
begin begin
Case IsFree of if (key.F.Free<>0) then
True :Result:='FREE'; begin
FAlse:Result:='ALLC'; Result:='FREE';
end else
if (key.F.reserv<>0) then
begin
Result:='RSRV';
end else
if (key.F.direct<>0) then
begin
Result:='DRCT';
end else
if (key.F.stack<>0) then
begin
Result:='STCK';
end else
if (key.F.polled<>0) then
begin
Result:='POOL';
end else
if (key.F.mapped<>0) then
begin
Result:='FMAP';
end else
begin
Result:='ALLC';
end; end;
end; end;
@ -1313,7 +1394,7 @@ begin
HexStr(QWORD(key.Offset+key.Size),10),':', HexStr(QWORD(key.Offset+key.Size),10),':',
HexStr(key.Size,10),'#', HexStr(key.Size,10),'#',
HexStr(qword(key.addr),10),'#', HexStr(qword(key.addr),10),'#',
_alloc_str(key.IsFree),'#'); _alloc_str(key),'#');
It.Next; It.Next;
end; end;

View File

@ -1616,7 +1616,7 @@ end;
//flag:MAP_ANON fd=-1 //flex //flag:MAP_ANON fd=-1 //flex
//flag:MAP_SHARED fd=/dev/dmem%d offset=physicalAddr //direct //flag:MAP_SHARED fd=/dev/dmem%d offset=physicalAddr //direct
function __mmap(addr:Pointer;len,align:size_t;prot,flags:Integer;fd:Integer;offset:size_t;var res:Pointer):Integer; function __mmap(addr:Pointer;len,align:size_t;prot,flags,fd:Integer;offset:size_t;var res:Pointer):Integer;
begin begin
Result:=EINVAL; Result:=EINVAL;
@ -1668,6 +1668,36 @@ begin
_sig_unlock; _sig_unlock;
end; end;
function __sys_mmap_dmem(
addr:Pointer;
length:QWORD;
alignment:QWORD;
mtype,prots,flags:Integer;
physicalAddr:QWORD;
var res:Pointer):Integer;
begin
Result:=0;
_sig_lock;
rwlock_wrlock(PageMM.FLock); //rw
Result:=DirectManager.CheckedMMap(physicalAddr,length);
if (Result=0) then
begin
flags:=flags or MAP_SHARED;
Result:=VirtualManager.mmap(addr,length,alignment,prots,flags,0,physicalAddr,res);
if (Result=0) then
begin
Result:=DirectManager.mmap_addr(physicalAddr,length,addr,mtype);
end;
end;
rwlock_unlock(PageMM.FLock);
_sig_unlock;
end;
function __munmap(addr:Pointer;len:size_t):Integer; function __munmap(addr:Pointer;len:size_t):Integer;
begin begin
Result:=VirtualManager.Release(addr,len); Result:=VirtualManager.Release(addr,len);
@ -1692,48 +1722,182 @@ end;
function _sceKernelMapFlexibleMemory( function _sceKernelMapFlexibleMemory(
virtualAddrDest:PPointer; virtualAddrDest:PPointer;
length:QWORD; length:QWORD;
prot,flags:Integer; prots,flags:Integer):Integer;
physicalAddr:QWORD;
alignment:QWORD):Integer; SysV_ABI_CDecl;
var var
addr:Pointer; addr:Pointer;
begin begin
Result:=SCE_KERNEL_ERROR_EINVAL; Result:=SCE_KERNEL_ERROR_EINVAL;
if ((($3fff < length) and ((length and $3fff)=0)) and if ((flags and $ffbfff6f)<>0) then Exit;
(((flags and $ffbfff6f) or (prot and $ffffffc8))=0)) then if ((prots and $ffffffc8)<>0) then Exit;
begin
if (length<LOGICAL_PAGE_SIZE) then Exit;
if not IsAlign(length,LOGICAL_PAGE_SIZE) then Exit;
addr:=virtualAddrDest^; addr:=virtualAddrDest^;
if not IsAlign(addr,LOGICAL_PAGE_SIZE) then Exit;
if (((flags and MAP_FIXED) <> 0) and (addr=nil)) then if (((flags and MAP_FIXED) <> 0) and (addr=nil)) then
begin begin
if ($16fffff < SDK_VERSION) then if (SDK_VERSION > $16fffff) then
begin begin
Exit(SCE_KERNEL_ERROR_EINVAL); Exit(SCE_KERNEL_ERROR_EINVAL);
end; end;
flags:=flags and $ffffffef; flags:=flags and $ffffffef;
Writeln('[WARNING] map(addr=0, flags=MAP_FIXED)'); Writeln('[WARNING] map(addr=0, flags=MAP_FIXED)');
end else
if (addr=nil) then
begin
addr:=Pointer($001000000000);
end; end;
Result:=__mmap(addr,length,0,prot,flags or MAP_ANON,-1,0,addr); if (addr=nil) then
_set_errno(Result);
if (Result<>0) then
begin begin
Result:=px2sce(Result); addr:=Pointer($880000000);
end else end;
Result:=__mmap(addr,length,0,prots,flags or MAP_ANON,-1,0,addr);
if (Result=0) then
begin begin
virtualAddrDest^:=addr; virtualAddrDest^:=addr;
Result:=0; Result:=0;
end; end;
end; end;
function _sceKernelReserveVirtualRange(
virtualAddrDest:PPointer;
length:QWORD;
flags:Integer;
alignment:QWORD):Integer;
var
addr:Pointer;
begin
Result:=SCE_KERNEL_ERROR_EINVAL;
if ((flags and $ffbfff6f)<>0) then Exit;
if (length<LOGICAL_PAGE_SIZE) then Exit;
if not IsAlign(length ,LOGICAL_PAGE_SIZE) then Exit;
if not IsAlign(alignment,LOGICAL_PAGE_SIZE) then Exit;
if not IsPowerOfTwo(alignment) then Exit;
if (alignment<LOGICAL_PAGE_SIZE) then alignment:=LOGICAL_PAGE_SIZE;
if (fastIntLog2(alignment)>31) then Exit;
addr:=virtualAddrDest^;
if not IsAlign(addr,LOGICAL_PAGE_SIZE) then Exit;
if (((flags and MAP_FIXED) <> 0) and (addr=nil)) then
begin
if (SDK_VERSION > $16fffff) then
begin
Exit(SCE_KERNEL_ERROR_EINVAL);
end; end;
flags:=flags and $ffffffef;
Writeln('[WARNING] map(addr=0, flags=MAP_FIXED)');
end;
Result:=__mmap(addr,length,alignment,0,flags or MAP_VOID or MAP_SHARED,-1,0,addr);
if (Result=0) then
begin
virtualAddrDest^:=addr;
Result:=0;
end;
end;
function _sceKernelMapDirectMemory2(
virtualAddrDest:PPointer;
length:QWORD;
mtype,prots,flags:Integer;
physicalAddr:QWORD;
alignment:QWORD):Integer;
var
addr:Pointer;
begin
Result:=SCE_KERNEL_ERROR_EINVAL;
if ((flags and $1f000000)<>0) then Exit;
if ((prots and $ffffffc8)<>0) then Exit;
if (length<LOGICAL_PAGE_SIZE) then Exit;
if not IsAlign(length ,LOGICAL_PAGE_SIZE) then Exit;
if not IsAlign(physicalAddr,LOGICAL_PAGE_SIZE) then Exit;
if not IsAlign(alignment ,LOGICAL_PAGE_SIZE) then Exit;
if not IsPowerOfTwo(alignment) then Exit;
if (alignment<LOGICAL_PAGE_SIZE) then alignment:=LOGICAL_PAGE_SIZE;
if (fastIntLog2(alignment)>31) then Exit;
addr:=virtualAddrDest^;
if not IsAlign(addr,LOGICAL_PAGE_SIZE) then Exit;
Result:=__sys_mmap_dmem(addr,length,alignment,mtype,prots,flags,physicalAddr,addr);
if (Result=0) then
begin
virtualAddrDest^:=addr;
Result:=0;
end;
end;
function _sceKernelMapDirectMemory(
virtualAddrDest:PPointer;
length:QWORD;
prots,flags:Integer;
physicalAddr:QWORD;
alignment:QWORD):Integer;
var
addr:Pointer;
_flags:Integer;
begin
Result:=SCE_KERNEL_ERROR_EINVAL;
if ((physicalAddr < $3000000000) or (physicalAddr > $301fffffff)) and
((flags and SCE_KERNEL_MAP_DMEM_COMPAT)=0) and (SDK_VERSION > $24fffff) then
begin
Result:=_sceKernelMapDirectMemory2(virtualAddrDest,length,-1,prots,flags,physicalAddr,alignment);
Exit;
end;
if ((flags and $1f000000)<>0) then Exit;
if ((prots and $ffffffc8)<>0) then Exit;
if (length<LOGICAL_PAGE_SIZE) then Exit;
if not IsAlign(length ,LOGICAL_PAGE_SIZE) then Exit;
if not IsAlign(physicalAddr,LOGICAL_PAGE_SIZE) then Exit;
if not IsAlign(alignment ,LOGICAL_PAGE_SIZE) then Exit;
if not IsPowerOfTwo(alignment) then Exit;
if (alignment<LOGICAL_PAGE_SIZE) then alignment:=LOGICAL_PAGE_SIZE;
if (fastIntLog2(alignment)>31) then Exit;
addr:=virtualAddrDest^;
if not IsAlign(addr,LOGICAL_PAGE_SIZE) then Exit;
_flags:=flags and $fffffbff;
if (((flags and MAP_FIXED) <> 0) and (addr=nil)) then
begin
if (SDK_VERSION > $16fffff) then
begin
Exit(SCE_KERNEL_ERROR_EINVAL);
end;
_flags:=flags and $fffffbef;
Writeln('[WARNING] map(addr=0, flags=MAP_FIXED)');
end;
if (addr=nil) then
begin
addr:=Pointer($880000000);
end;
Result:=__mmap(addr,length,alignment,prots,_flags or MAP_SHARED,0,physicalAddr,addr);
if (Result=0) then
begin
virtualAddrDest^:=addr;
Result:=0;
end;
end;
//// ////
//// ////

View File

@ -177,6 +177,8 @@ function GetSceProcParam:Pointer;
function GetSceUserMainThreadName:PChar; function GetSceUserMainThreadName:PChar;
function GetSceUserMainThreadPriority:PDWORD; function GetSceUserMainThreadPriority:PDWORD;
function GetSceUserMainThreadStackSize:PDWORD; function GetSceUserMainThreadStackSize:PDWORD;
function GetSceKernelMemParam:Pointer;
function GetSceKernelFlexibleMemorySize:PQWORD;
Function get_dev_progname:RawByteString; Function get_dev_progname:RawByteString;
@ -1558,6 +1560,34 @@ begin
end; end;
end; end;
function GetSceKernelMemParam:Pointer;
var
p:PSceProcParam;
begin
Result:=nil;
p:=GetSceProcParam;
if (p=nil) then Exit;
if (P^.Header.Size>=qword(@PSceProcParam(nil)^._sceKernelMemParam)+SizeOf(Pointer)) then
begin
Result:=p^._sceKernelMemParam;
end;
end;
function GetSceKernelFlexibleMemorySize:PQWORD;
var
p:PSceKernelMemParam;
begin
Result:=nil;
p:=GetSceKernelMemParam;
if (p=nil) then Exit;
if (P^.Size>=qword(@PSceKernelMemParam(nil)^.sceKernelFlexibleMemorySize)+SizeOf(Pointer)) then
begin
Result:=p^.sceKernelFlexibleMemorySize;
end;
end;
Function get_dev_progname:RawByteString; Function get_dev_progname:RawByteString;
begin begin
Result:=''; Result:='';

View File

@ -71,6 +71,7 @@ const
function _isgpu(prot:Integer):Boolean; inline; function _isgpu(prot:Integer):Boolean; inline;
function __map_prot_page(prot:Integer):DWORD; function __map_prot_page(prot:Integer):DWORD;
function __win_prot_page(prot:DWORD):Integer;
function __map_prot_file(prot:Integer):DWORD; function __map_prot_file(prot:Integer):DWORD;
function _VirtualAlloc (Addr:Pointer;dwSize:PTRUINT;prot:Integer):Integer; function _VirtualAlloc (Addr:Pointer;dwSize:PTRUINT;prot:Integer):Integer;
@ -81,6 +82,7 @@ function _VirtualFree (Addr:Pointer):Integer;
function _VirtualMmap (Addr:Pointer;len:size_t;prot,fd:Integer;offst:size_t):Integer; function _VirtualMmap (Addr:Pointer;len:size_t;prot,fd:Integer;offst:size_t):Integer;
function _VirtualUnmap (addr:Pointer):Integer; function _VirtualUnmap (addr:Pointer):Integer;
function _VirtualProtect (addr:Pointer;len:size_t;prot:Integer):Integer; function _VirtualProtect (addr:Pointer;len:size_t;prot:Integer):Integer;
function _VirtualQuery (addr:Pointer;paddr:PPointer;psize:Pptruint;pprots,pflags:PInteger):Integer;
implementation implementation
@ -120,6 +122,29 @@ begin
end; end;
end; end;
function __win_prot_page(prot:DWORD):Integer;
begin
Result:=0;
prot:=prot and (
PAGE_NOACCESS or
PAGE_READONLY or
PAGE_READWRITE or
PAGE_EXECUTE or
PAGE_EXECUTE_READ or
PAGE_EXECUTE_READWRITE);
Case prot of
PAGE_NOACCESS :Result:=0;
PAGE_READONLY :Result:=PROT_READ;
PAGE_READWRITE :Result:=PROT_READ or PROT_WRITE;
PAGE_EXECUTE :Result:=PROT_EXEC;
PAGE_EXECUTE_READ :Result:=PROT_EXEC or PROT_READ;
PAGE_EXECUTE_READWRITE:Result:=PROT_EXEC or PROT_READ or PROT_WRITE;
else;
end;
end;
function __map_prot_file(prot:Integer):DWORD; function __map_prot_file(prot:Integer):DWORD;
begin begin
Result:= 0; Result:= 0;
@ -256,6 +281,58 @@ begin
end; end;
end; end;
function _win_state(state:DWORD):Integer; inline;
begin
Case state of
MEM_COMMIT :Result:=MAP_FIXED;
MEM_RESERVE:Result:=MAP_VOID;
else Result:=0;
end;
end;
function _win_mtype(mtype:DWORD):Integer; inline;
begin
Case mtype of
MEM_PRIVATE:Result:=MAP_ANON;
else Result:=MAP_SHARED;
end;
end;
function _VirtualQuery(addr:Pointer;paddr:PPointer;psize:Pptruint;pprots,pflags:PInteger):Integer;
var
Info:TMemoryBasicInformation;
begin
Result:=0;
Info:=Default(TMemoryBasicInformation);
Result:=VirtualQuery(addr,Info,SizeOf(TMemoryBasicInformation));
if (Result=0) then
begin
Result:=GetLastError;
end else
begin
if (paddr<>nil) then
begin
paddr^:=Info.AllocationBase;
end;
if (psize<>nil) then
begin
psize^:=Info.RegionSize+(ptruint(Info.BaseAddress)-ptruint(Info.AllocationBase));
end;
if (pprots<>nil) then
begin
pprots^:=__win_prot_page(Info.Protect);
end;
if (pflags<>nil) then
begin
pflags^:=_win_state(Info.State) or _win_mtype(Info._Type)
end;
end;
end;
end. end.