mirror of https://github.com/red-prig/fpPS4.git
This commit is contained in:
parent
0482c59a4a
commit
57b2c9fa13
101
kernel/mm.txt
101
kernel/mm.txt
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,49 +1722,183 @@ 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
|
|
||||||
addr:=virtualAddrDest^;
|
|
||||||
|
|
||||||
if (((flags and MAP_FIXED)<>0) and (addr=nil)) then
|
if (length<LOGICAL_PAGE_SIZE) then Exit;
|
||||||
|
if not IsAlign(length,LOGICAL_PAGE_SIZE) then Exit;
|
||||||
|
|
||||||
|
addr:=virtualAddrDest^;
|
||||||
|
if not IsAlign(addr,LOGICAL_PAGE_SIZE) then Exit;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
flags:=flags and $ffffffef;
|
||||||
|
Writeln('[WARNING] map(addr=0, flags=MAP_FIXED)');
|
||||||
end;
|
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;
|
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;
|
||||||
|
|
||||||
|
|
||||||
////
|
////
|
||||||
////
|
////
|
||||||
|
|
||||||
|
|
|
@ -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:='';
|
||||||
|
|
77
rtl/mmap.pas
77
rtl/mmap.pas
|
@ -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.
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue