diff --git a/kernel/mm.txt b/kernel/mm.txt deleted file mode 100644 index e926f6e..0000000 --- a/kernel/mm.txt +++ /dev/null @@ -1,431 +0,0 @@ - -int sceKernelMapDirectMemory - (void **virtualAddrDest,qword length,int protections,int flags,qword physicalAddr, - qword alignment) - -{ - int iVar1; - ulong in_stack_00000000; - - pthread_once((pthread_once_t *)&_mem_init_ctl,_mem_init); - iVar1 = _sceKernelMapDirectMemory - (_direct_pool_id,virtualAddrDest,length,protections,flags,physicalAddr,alignment - ,in_stack_00000000); - return iVar1; -} - -int _sceKernelMapDirectMemory - (uint pool_id,void **virtualAddrDest,qword length,int protections,int flags, - qword physicalAddr,qword alignment,ulong param_8) - -{ - int last; - int *perror; - uint _flags; - dword *poffset; - void *adr; - qword align; - int ret1; - uint _len; - - pthread_once((pthread_once_t *)&_mem_init_ctl,_mem_init); - ret1 = SCE_KERNEL_ERROR_EINVAL; - if (pool_id < 3) { - adr = *virtualAddrDest; - if ((((_direct_pool_id == 1) && ((APP_INFO[4] & 2) == 0)) && - (((long)physicalAddr < 0x3000000000 || (0x301fffffff < physicalAddr)))) && - (((flags & SCE_KERNEL_MAP_DMEM_COMPAT) == 0 && (0x24fffff < SDK_VERSION)))) { - ret1 = sceKernelMapDirectMemory2 - (virtualAddrDest,length,-1,protections,flags,physicalAddr,alignment); - return ret1; - } - if (((((flags & 0xff9ffb6fU) == 0) && ((protections & 0xffffffc8U) == 0)) && - (_len = (uint)length, - (((uint)adr | (uint)alignment | (uint)physicalAddr | _len) & 0x3fff) == 0)) && - ((~-alignment & alignment) == 0)) { - _flags = flags & 0xfffffbff; - if (((flags & MAP_FIXED) != 0) && (adr == (void *)0x0)) { - if (0x16fffff < SDK_VERSION) { - return SCE_KERNEL_ERROR_EINVAL; - } - _flags = flags & 0xfffffbef; - puts("[WARNING] map(addr=0, flags=MAP_FIXED)"); - } - if (adr == (void *)0x0) { - if (param_8 >> 0x1e == 0x20) { - adr = (void *)0x880000000; - } - else { - adr = (void *)((ulong)((APP_INFO[4] & 2) == 0) << 0x21); - } - } - align = 0x4000; - if (0x4000 < alignment) { - align = alignment; - } - last = flsl(align); - if (last + -1 < 31) { - poffset = &DAT_01059578; - if (0x301fffffff < physicalAddr) { - poffset = DWORD_ARRAY_01059570 + (int)pool_id; - } - if ((long)physicalAddr < 0x3000000000) { - poffset = DWORD_ARRAY_01059570 + (int)pool_id; - } - adr = mmap(adr,length,protections,_flags | (last + -1) * 0x1000000 | MAP_SHARED,*poffset,physicalAddr); - if (adr == MAP_FAILED) { - perror = (int *)__error(); - last = *perror; - ret1 = last + -0x7ffe0000; - if (last == 0) { - ret1 = last; - } - } - else { - *virtualAddrDest = adr; - ret1 = 0; - } - } - } - } - return ret1; -} - -int sceKernelMapDirectMemory2 - (void **virtualAddrDest,qword length,int memoryType,int protections,int flags, - qword physicalAddr,qword alignment) - -{ - int last; - void *adr; - int *perror; - int ret1; - qword align; - - pthread_once((pthread_once_t *)&_mem_init_ctl,_mem_init); - ret1 = SCE_KERNEL_ERROR_EOPNOTSUPP; - if ((((_direct_pool_id == 1) && ((APP_INFO[4] & 2) == 0)) && - (ret1 = SCE_KERNEL_ERROR_EINVAL, (flags & 0x1f000000U) == 0)) && - (((alignment & 0x3fff) == 0 && ((~-alignment & alignment) == 0)))) { - align = 0x4000; - if (0x4000 < alignment) { - align = alignment; - } - last = flsl(align); - if (last + -1 < 31) { - adr = (void *)sys_mmap_dmem(*virtualAddrDest,length,memoryType,protections, - (last + -1) * 0x1000000 | flags,physicalAddr); - if (adr == MAP_FAILED) { - perror = (int *)__error(); - last = *perror; - ret1 = last + -0x7ffe0000; - if (last == 0) { - ret1 = last; - } - } - else { - *virtualAddrDest = adr; - ret1 = 0; - } - } - } - return ret1; -} - -int sceKernelMapFlexibleMemory(void **virtualAddrDest,qword length,int protections,int flags) - -{ - int iVar1; - undefined in_stack_00000000; - undefined7 in_stack_00000001; - - iVar1 = _sceKernelMapFlexibleMemory - (virtualAddrDest,length,protections,flags, - CONCAT71(in_stack_00000001,in_stack_00000000)); - return iVar1; -} - -int _sceKernelMapFlexibleMemory - (void **virtualAddrDest,qword length,int protections,int flags,ulong param) - -{ - int *perror; - int ret1; - void *adr; - int err; - - ret1 = SCE_KERNEL_ERROR_EINVAL; - if (((0x3fff < length) && ((length & 0x3fff) == 0)) && - ((flags & 0xffbfff6fU | protections & 0xffffffc8U) == 0)) { - adr = *virtualAddrDest; - if (((flags & MAP_FIXED) != 0) && (adr == (void *)0x0)) { - if (0x16fffff < SDK_VERSION) { - return SCE_KERNEL_ERROR_EINVAL; - } - flags = flags & 0xffffffef; - puts("[WARNING] map(addr=0, flags=MAP_FIXED)"); - } - if (adr == (void *)0x0) { - if (param >> 0x1e == 0x20) { - adr = (void *)0x880000000; - } - else { - adr = (void *)((ulong)((APP_INFO[4] & 2) == 0) << 0x21); - } - } - adr = (void *)mmap(adr,length,protections,flags | MAP_ANON,-1,0); - if (adr == MAP_FAILED) { - perror = (int *)__error(); - err = *perror; - ret1 = err + -0x7ffe0000; - if (err == 0) { - ret1 = err; - } - } - else { - *virtualAddrDest = adr; - ret1 = 0; - } - } - return ret1; -} - -int sceKernelReserveVirtualRange(void **addr,size_t len,int flags,size_t alignment) - -{ - int last; - int *perror; - size_t align; - int ret1; - void *adr; - - ret1 = SCE_KERNEL_ERROR_EINVAL; - if ((((flags & 0xffbfff6fU) == 0) && - (adr = *addr, (((uint)adr | (uint)alignment | (uint)len) & 0x3fff) == 0)) && - ((~-alignment & alignment) == 0)) { - align = 0x4000; - if (0x4000 < alignment) { - align = alignment; - } - last = flsl(align); - if (last + -1 < 0x1f) { - if (((flags & MAP_FIXED) != 0) && (adr == (void *)0x0)) { - if (0x16fffff < SDK_VERSION) { - return SCE_KERNEL_ERROR_EINVAL; - } - flags = flags & 0xffffffef; - puts("[WARNING] map(addr=0, flags=MAP_FIXED)"); - } - adr = (void *)mmap(adr,len,0,(last + -1) * 0x1000000 | flags | MAP_VOID | MAP_SHARED,-1,0); - if (adr == MAP_FAILED) { - perror = (int *)__error(); - last = *perror; - ret1 = last + -0x7ffe0000; - if (last == 0) { - ret1 = last; - } - } - else { - *addr = adr; - ret1 = 0; - } - } - } - return ret1; -} - -int sceKernelMprotect(void *addr,size_t len,int prot) - -{ - int ret1; - int *perror; - int err; - - ret1 = mprotect(addr,len,prot); - if (ret1 < 0) { - perror = (int *)__error(); - err = *perror; - ret1 = err + -0x7ffe0000; - if (err == 0) { - ret1 = err; - } - } - return ret1; -} - -int sceKernelMsync(void *addr,size_t len,int flags) - -{ - int ret1; - int *perror; - int err; - - ret1 = msync(addr,len,flags); - if (ret1 < 0) { - perror = (int *)__error(); - err = *perror; - ret1 = err + -0x7ffe0000; - if (err == 0) { - ret1 = err; - } - } - return ret1; -} - -int sceKernelMmap(void *addr,size_t len,int prot,int flags,int fd,size_t offset,void **res) - -{ - int iVar1; - int err; - void *adr; - int *perror; - - adr = mmap(addr,len,prot,flags,fd,offset); - if (adr != MAP_FAILED) { - *res = adr; - return 0; - } - perror = (int *)__error(); - iVar1 = *perror; - err = iVar1 + -0x7ffe0000; - if (iVar1 == 0) { - err = iVar1; - } - return err; -} - -int sceKernelMunmap(void *addr,size_t len) - -{ - int ret1; - int *perror; - int err; - - ret1 = munmap(addr,len); - if (ret1 < 0) { - perror = (int *)__error(); - err = *perror; - ret1 = err + -0x7ffe0000; - if (err == 0) { - ret1 = err; - } - } - return ret1; -} - -int sceKernelReleaseFlexibleMemory(void *addr,size_t len) - -{ - int ret2; - int ret1; - - ret1 = SCE_KERNEL_ERROR_EINVAL; - if ((((uint)addr | (uint)len) & 0x3fff) == 0) { - ret2 = madvise(addr,len,MADV_FREE); - ret1 = SCE_KERNEL_ERROR_EINVAL; - if (ret2 != -1) { - ret1 = 0; - } - } - 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; -} diff --git a/kernel/ps4_libkernel.pas b/kernel/ps4_libkernel.pas index bde4eee..312802a 100644 --- a/kernel/ps4_libkernel.pas +++ b/kernel/ps4_libkernel.pas @@ -940,6 +940,7 @@ begin lib^.set_proc($0C6306DC9B21AD95,@ps4_sceKernelSetVirtualRangeName); lib^.set_proc($21620105D4C78ADE,@ps4_sceKernelMapFlexibleMemory); lib^.set_proc($98BF0D0C7F3A8902,@ps4_sceKernelMapNamedFlexibleMemory); + lib^.set_proc($91CF8B1042186A47,@ps4_sceKernelMapNamedSystemFlexibleMemory); lib^.set_proc($EE8C6FDCF3C2BA6A,@ps4_sceKernelReserveVirtualRange); lib^.set_proc($0504278A8963F6D4,@ps4_sceKernelMapDirectMemory2); lib^.set_proc($2FF4372C48C86E00,@ps4_sceKernelMapDirectMemory); diff --git a/kernel/ps4_map_mm.pas b/kernel/ps4_map_mm.pas index 5a37f71..1da5bf1 100644 --- a/kernel/ps4_map_mm.pas +++ b/kernel/ps4_map_mm.pas @@ -172,6 +172,12 @@ function ps4_sceKernelMapNamedFlexibleMemory( prots,flags:Integer; name:PChar):Integer; SysV_ABI_CDecl; +function ps4_sceKernelMapNamedSystemFlexibleMemory( + virtualAddrDest:PPointer; + length:QWORD; + prots,flags:Integer; + name:PChar):Integer; SysV_ABI_CDecl; + function ps4_sceKernelReserveVirtualRange( virtualAddrDest:PPointer; length:QWORD; @@ -1066,6 +1072,54 @@ begin end; end; +function _sceKernelMapNamedSystemFlexibleMemory( + virtualAddrDest:PPointer; + length:QWORD; + prots,flags:Integer; + name:PChar):Integer; +var + addr:Pointer; +begin + Result:=SCE_KERNEL_ERROR_EINVAL; + + if ((flags and $ffbfff6f)<>0) then Exit; + if ((prots and $ffffffc8)<>0) then Exit; + + if (length 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; + + if (((flags and MAP_FIXED)=0) and (addr=nil)) then + begin + addr:=Pointer($880000000); + end; + + Result:=__mmap(addr,length,0,prots,flags or MAP_ANON or MAP_SYSTEM,-1,0,addr); + _set_errno(Result); + + if (Result<>0) then + begin + Result:=px2sce(Result); + end else + begin + _sys_mname(addr,length,name); + virtualAddrDest^:=addr; + Result:=0; + end; +end; + function _sceKernelReserveVirtualRange( virtualAddrDest:PPointer; length:QWORD; @@ -1439,6 +1493,20 @@ begin end; end; +function ps4_sceKernelMapNamedSystemFlexibleMemory( + virtualAddrDest:PPointer; + length:QWORD; + prots,flags:Integer; + name:PChar):Integer; SysV_ABI_CDecl; +begin + Result:=_sceKernelMapNamedSystemFlexibleMemory(virtualAddrDest,length,prots,flags,name); + + if (Result<>0) then + begin + Writeln(StdErr,'[WARN]:sceKernelMapNamedSystemFlexibleMemory:',Result); + end; +end; + function ps4_sceKernelReserveVirtualRange( virtualAddrDest:PPointer; length:QWORD; diff --git a/kernel/ps4_mspace.pas b/kernel/ps4_mspace.pas index a878ab5..40c112e 100644 --- a/kernel/ps4_mspace.pas +++ b/kernel/ps4_mspace.pas @@ -5,6 +5,8 @@ unit ps4_mspace; interface uses + ps4_elf, + ps4_program, ps4_mutex, ps4_map_mm; @@ -64,8 +66,8 @@ type pSceLibcMallocManagedSize=^SceLibcMallocManagedSize; SceLibcMallocManagedSize=packed record - size :word; - version :word; + size :word; //1 + version :word; //40 reserved1 :dword; maxSystemSize :QWORD; currentSystemSize:QWORD; @@ -101,8 +103,8 @@ type HighAddressAlloc :QWORD; heap_bits :DWORD; f_988:Integer; - f_992:QWORD; - cbs :Pointer; //callbak actions + g_cbs :Pointer; //global callback actions + cbs :Pointer; //callback actions msp_array_flags :DWORD; //save to array used msp_array_id :DWORD; //array pos + 1 SystemSize :QWORD; @@ -135,6 +137,35 @@ uses sys_kernel, sys_signal; +type + TAddressRangeCallback=procedure(base:Pointer;size:ptruint); SysV_ABI_CDecl; + +var + SceLibcIHeap:SceLibcMspace; + p_SceLibcIHeap:pSceLibcMspace=nil; + + g_addr_cbs:TAddressRangeCallback=nil; + + g_SceKernelIntMemPthread:pSceLibcMspace; + g_SceKernelIntMemTLS:pSceLibcMspace; + g_SceKernelIntMemThrSpec:pSceLibcMspace; + + g_SystemSize:ptruint=0; + + g_SceKernelIntMemTLS_base:Pointer; + + g_heap_param:packed record + custom_heap_size:Integer; + HeapDelayedAlloc:Integer; + SystemData:Pointer; + f_16:Integer; + custom_heap_init_size:Integer; + HeapInitialSize:Integer; + HeapMemoryLock:Integer; + ptype_is_1:Integer; + f_36:Integer; + end; + //libc use nedmalloc modification Const @@ -490,12 +521,17 @@ begin Result:=(s>m^.trim_check); end; +function _INITIAL_LOCK(m:mstate):Integer; inline; +begin + Result:=ps4_scePthreadMutexInit(@m^.mutex,nil,@m^.name); +end; + function INITIAL_LOCK(m:mstate):Integer; inline; begin Result:=0; if use_lock(m) then begin - Result:=ps4_scePthreadMutexInit(@m^.mutex,nil,@m^.name); + Result:=_INITIAL_LOCK(m); end; end; @@ -1202,11 +1238,19 @@ begin begin m^.least_addr:=mm; end; + m^.footprint:=m^.footprint+mmsize; if (m^.footprint > m^.max_footprint) then begin m^.max_footprint:=m^.footprint; end; + + m^.currentInuseSize:=m^.currentInuseSize+128; + if (m^.currentInuseSize > m^.maxInuseSize) then + begin + m^.maxInuseSize:=m^.currentInuseSize; + end; + assert(is_aligned(chunk2mem(p))); //check_mmapped_chunk(m, p); debug Result:=chunk2mem(p); @@ -1255,11 +1299,21 @@ begin begin m^.least_addr:=cp; end; - m^.footprint:=m^.footprint+(newmmsize-oldmmsize); + + psize:=ptruint(newmmsize-oldmmsize); + + m^.footprint:=m^.footprint+psize; if (m^.footprint > m^.max_footprint) then begin m^.max_footprint:=m^.footprint; end; + + m^.currentInuseSize:=m^.currentInuseSize+psize; + if (m^.currentInuseSize > m^.maxInuseSize) then + begin + m^.maxInuseSize:=m^.currentInuseSize; + end; + //check_mmapped_chunk(m, newp); debug Result:=newp; end; @@ -1487,6 +1541,12 @@ begin m^.max_footprint:=m^.footprint; end; + m^.currentInuseSize:=m^.currentInuseSize+128; + if (m^.currentInuseSize > m^.maxInuseSize) then + begin + m^.maxInuseSize:=m^.currentInuseSize; + end; + if (not is_initialized(m)) then begin if (m^.least_addr=nil) or (tbase < m^.least_addr) then @@ -1612,7 +1672,9 @@ begin if (CALL_MUNMAP(base, size)=0) then begin released:=released+size; + m^.footprint:=m^.footprint-size; + m^.currentInuseSize:=m^.currentInuseSize-128; sp:=pred; sp^.next:=next; @@ -1672,7 +1734,10 @@ begin if (released <> 0) then begin sp^.size:=sp^.size-released; + m^.footprint:= m^.footprint-released; + m^.currentInuseSize:=m^.currentInuseSize-128; + init_top(m, m^.top, m^.topsize - released); //check_top_chunk(m, m^.top); debug end; @@ -1884,6 +1949,7 @@ begin MALLOC_FAILURE_ACTION; Exit(nil); end; + if (PREACTION(m)=0) then begin oldp:=mem2chunk(oldmem); @@ -1929,6 +1995,7 @@ begin POSTACTION(m); Exit(nil); end; + //#if DEBUG // if (newp != 0) begin // check_inuse_chunk(m, newp); @@ -1990,10 +2057,12 @@ begin begin Exit(internal_malloc(m, bytes)); end; + if (alignment 0) then begin a:=MALLOC_ALIGNMENT shl 1; @@ -2067,14 +2136,23 @@ begin assert((ptruint(chunk2mem(p)) and alignment) = 0); //check_inuse_chunk(m, p); debug POSTACTION(m); + if (leader <> nil) then begin internal_free(m, leader); end; + if (trailer <> nil) then begin internal_free(m, trailer); end; + + m^.currentInuseSize:=m^.currentInuseSize+chunksize(p); + if (m^.currentInuseSize > m^.maxInuseSize) then + begin + m^.maxInuseSize:=m^.currentInuseSize; + end; + Exit(chunk2mem(p)); end; end; @@ -2289,6 +2367,13 @@ begin mem:=sys_alloc(ms,nb); _postaction: + + ms^.currentInuseSize:=ms^.currentInuseSize+chunksize(mem2chunk(mem)); + if (ms^.currentInuseSize > ms^.maxInuseSize) then + begin + ms^.maxInuseSize:=ms^.currentInuseSize; + end; + POSTACTION(ms); Exit(mem); end; @@ -2361,6 +2446,7 @@ begin if (PREACTION(fm)=0) then begin //check_inuse_chunk(fm, p); debug + psize:=0; if ok_address(fm, p) and ok_inuse(p) then begin psize:=chunksize(p); @@ -2375,6 +2461,7 @@ begin if (CALL_MUNMAP(mm, psize)=0) then begin fm^.footprint:=fm^.footprint-psize; + fm^.currentInuseSize:=fm^.currentInuseSize-128; end; goto _postaction; end else @@ -2465,6 +2552,7 @@ begin USAGE_ERROR_ACTION(fm, p); Result:=3; _postaction: + fm^.currentInuseSize:=fm^.currentInuseSize-psize; POSTACTION(fm); end; end; @@ -2534,7 +2622,7 @@ begin end; end; -function mspace_memalign(ms:mstate;alignment,bytes:ptruint):Pointer; +function mspace_memalign(ms:mstate;alignment,bytes:ptruint):Pointer; inline; begin if (not ok_magic(ms)) then begin @@ -2544,7 +2632,7 @@ begin Result:=internal_memalign(ms,alignment,bytes); end; -function mspace_trim(ms:mstate;pad:ptruint):Integer; +function mspace_trim(ms:mstate;pad:ptruint):Integer; inline; begin Result:=0; if (not ok_magic(ms)) then @@ -2559,7 +2647,7 @@ begin end; end; -function mspace_usable_size(mem:Pointer):ptruint; +function mspace_usable_size(mem:Pointer):ptruint; inline; var p:mchunkptr; begin @@ -2836,6 +2924,481 @@ begin CALLBACK_ACTION(msp,6,@data); end; +function _sceLibcMspaceMallocUsableSize(ptr:Pointer):ptruint; +begin + Result:=mspace_usable_size(ptr); +end; + +function _sceLibcMspaceMallocStatsFast(msp:pSceLibcMspace;mmsize:pSceLibcMallocManagedSize):Integer; +begin + Result:=1; + if (msp<>nil) then + if (mmsize<>nil) then + if ok_magic(msp) then + if (mmsize^.version=1) and (mmsize^.size=40) then + if (PREACTION(msp)=0) then + begin + mmsize^.maxSystemSize :=msp^.max_footprint; + mmsize^.currentSystemSize:=msp^.footprint; + mmsize^.maxInuseSize :=msp^.maxInuseSize; + mmsize^.currentInuseSize :=msp^.currentInuseSize; + POSTACTION(msp); + Result:=0; + end; +end; + +function _sceLibcMspaceIsHeapEmpty(msp:pSceLibcMspace):Integer; +var + InuseSize:ptruint; +begin + Result:=1; + if (msp<>nil) then + if ok_magic(msp) then + if (PREACTION(msp)=0) then + begin + InuseSize:=msp^.currentInuseSize; + POSTACTION(msp); + Result:=Integer((InuseSize and ptruint($ffffffffffffff7f))=0); + if (p_SceLibcIHeap<>msp) then + begin + Result:=Integer(InuseSize=1440); + end; + end; +end; + +procedure _sceLibcMspaceSetMallocCallback(msp:pSceLibcMspace;cbs:Pointer); +begin + if (cbs<>nil) then + if (PREACTION(msp)=0) then + begin + msp^.cbs:=cbs; + POSTACTION(msp); + end; +end; + +///// + +function _sceLibcHeapSetAddressRangeCallback(cbs:Pointer):Integer; +begin + Result:=-1; + if (cbs<>nil) then + begin + Result:=0; + g_addr_cbs:=TAddressRangeCallback(cbs); + end; +end; + +function _sceLibcMspaceGetAddressRanges(msp:pSceLibcMspace):Integer; +var + sp:msegmentptr; +begin + Result:=-1; + if (msp<>nil) then + if (g_addr_cbs<>nil) then + if ok_magic(msp) then + begin + sp:=@msp^.seg; + While (sp<>nil) do + begin + g_addr_cbs(sp^.base,sp^.size); + sp:=sp^.next; + end; + Result:=0; + end; +end; + +function _QZ9YgTk_yrE:Integer; //QZ9YgTk+yrE +begin + Result:=-1; + if (g_addr_cbs<>nil) then + begin + g_addr_cbs(p_SceLibcIHeap,1280); + Result:=0; + end; +end; + +function _sceLibcHeapGetAddressRanges:Integer; +begin + Result:=_sceLibcMspaceGetAddressRanges(p_SceLibcIHeap); +end; + +function wUqJ0psUjDo(msp:pSceLibcMspace):Integer; //wUqJ0psUjDo +begin + Result:=-1; + if (msp<>nil) then + if ok_magic(msp) then + begin + p_SceLibcIHeap^.MutexPoolForMono:=msp; + Result:=0; + end; +end; + +//procedure sceLibcHeapSetTraceMarker; +//procedure sceLibcHeapUnsetTraceMarker; + +///// + +procedure mem_init(m:mstate;nb:ptruint); +var + tbase:Pointer; + tsize:ptruint; + mmap_flag:flag_t; + rsize:ptruint; + mp:Pointer; + mn:mchunkptr; +begin + tbase:=nil; + tsize:=0; + mmap_flag:=0; + + rsize:=granularity_align(nb + SYS_ALLOC_PADDING); + if (rsize > nb) then + begin + mp:=CALL_MMAP(m,rsize); + if (mp<>nil) then + begin + tbase:=mp; + tsize:=rsize; + mmap_flag:=USE_MMAP_BIT; + end; + end; + + if (tbase<>nil) then + begin + + m^.footprint:=m^.footprint+tsize; + if (m^.footprint > m^.max_footprint) then + begin + m^.max_footprint:=m^.footprint; + end; + + m^.currentInuseSize:=m^.currentInuseSize+128; + if (m^.currentInuseSize > m^.maxInuseSize) then + begin + m^.maxInuseSize:=m^.currentInuseSize; + end; + + if (not is_initialized(m)) then + begin + if (m^.least_addr=nil) or (tbase < m^.least_addr) then + begin + m^.least_addr:=tbase; + end; + m^.seg.base :=tbase; + m^.seg.size :=tsize; + m^.seg.sflags:=mmap_flag; + m^.magic :=DEFAULT_MAGIC; + init_bins(m); + begin + mn:=next_chunk(mem2chunk(m)); + init_top(m, mn, ((tbase + tsize) - Pointer(mn)) -TOP_FOOT_SIZE); + end; + end; + + Exit; + end; + + MALLOC_FAILURE_ACTION; +end; + +function _mmap_system(size:ptruint;_out:PPointer;name:Pchar):Integer; +var + ret:Integer; + res:Pointer; + addr:Pointer; +begin + addr:=nil; + res:=g_heap_param.SystemData; + if (res=nil) then + begin + if (g_heap_param.ptype_is_1=0) then + begin + ret:=ps4_sceKernelMapNamedSystemFlexibleMemory(@addr,size,3,0,name); + end else + begin + ret:=ps4_sceKernelMapNamedFlexibleMemory(@addr,size,3,0,name); + end; + if (ret=0) then + begin + res:=addr; + if (g_heap_param.HeapMemoryLock=0) then + begin + ret:=0; + //ret:=sceKernelMlock(addr,size); TODO + if (ret=0) then + begin + _out^:=res; + Exit(0); + end; + end; + Assert(p_SceLibcIHeap^.top<>nil); + end else + begin + Assert(p_SceLibcIHeap^.top<>nil); + end; + ret:=-1; + end else + begin + _out^:=res; + Exit(0); + end; + Result:=ret; +end; + +function _malloc_init_lv2(msp:pSceLibcMspace):Integer; +label + _mmap_resize, + _break; +var + tmp:pSceLibcMspace; + + SceLibcParam:PSceLibcParam; + SceLibcInternalHeap:DWORD; + sceLibcHeapDebugFlags:DWORD; + sceLibcHeapSize:QWORD; + sceLibcHeapDelayedAlloc:DWORD; + sceLibcHeapExtendedAlloc:DWORD; + sceLibcHeapInitialSize:DWORD; + sceLibcHeapMemoryLock:DWORD; + sceLibcMaxSystemSize:QWORD; + + len:QWORD; + + _SystemData:Pointer; + _SystemSize:ptruint; + +begin + if (p_SceLibcIHeap=nil) then + begin + p_SceLibcIHeap:=msp; + end; + + tmp:=p_SceLibcIHeap; + + tmp^.name:='SceLibcIHeap'; + + if _INITIAL_LOCK(@tmp)<>0 then Exit(1); + + tmp^.magic :=DEFAULT_MAGIC; + tmp^.mflags :=USE_MMAP_BIT or USE_LOCK_BIT or 4; + tmp^.page_size :=16384; + tmp^.granularity:=65536; + + // + + g_SystemSize:=$40000; + g_heap_param.custom_heap_size:=1; + g_heap_param.ptype_is_1:=integer(1{sceKernelGetProcessType(-1)}=1); //app_type mean???? + + SceLibcInternalHeap:=0; + sceLibcHeapDebugFlags:=0; + sceLibcHeapSize:=0; + sceLibcHeapDelayedAlloc:=0; + sceLibcHeapExtendedAlloc:=0; + sceLibcHeapInitialSize:=0; + sceLibcMaxSystemSize:=0; + + SceLibcParam:=GetSceLibcParam; + if (SceLibcParam<>nil) then + begin + + if (SceLibcParam^.Size>=qword(@PSceLibcParam(nil)^.SceLibcInternalHeap)+SizeOf(Pointer)) then + begin + SceLibcInternalHeap:=SceLibcParam^.SceLibcInternalHeap; + end; + + if (SceLibcParam^.Size>=qword(@PSceLibcParam(nil)^.sceLibcHeapDebugFlags)+SizeOf(Pointer)) then + if (SceLibcParam^.sceLibcHeapDebugFlags<>nil) then + begin + sceLibcHeapDebugFlags:=SceLibcParam^.sceLibcHeapDebugFlags^; + end; + + if (SceLibcParam^.Size>=qword(@PSceLibcParam(nil)^.sceLibcHeapSize)+SizeOf(Pointer)) then + if (SceLibcParam^.sceLibcHeapSize<>nil) then + begin + sceLibcHeapSize:=SceLibcParam^.sceLibcHeapSize^; + end; + + if (SceLibcParam^.Size>=qword(@PSceLibcParam(nil)^.sceLibcHeapDelayedAlloc)+SizeOf(Pointer)) then + if (SceLibcParam^.sceLibcHeapDelayedAlloc<>nil) then + begin + sceLibcHeapDelayedAlloc:=SceLibcParam^.sceLibcHeapDelayedAlloc^; + end; + + if (SceLibcParam^.Size>=qword(@PSceLibcParam(nil)^.sceLibcHeapExtendedAlloc)+SizeOf(Pointer)) then + if (SceLibcParam^.sceLibcHeapExtendedAlloc<>nil) then + begin + sceLibcHeapExtendedAlloc:=SceLibcParam^.sceLibcHeapExtendedAlloc^; + end; + + if (SceLibcParam^.Size>=qword(@PSceLibcParam(nil)^.sceLibcHeapInitialSize)+SizeOf(Pointer)) then + if (SceLibcParam^.sceLibcHeapInitialSize<>nil) then + begin + sceLibcHeapInitialSize:=SceLibcParam^.sceLibcHeapInitialSize^; + end; + + if (SceLibcParam^.Size>=qword(@PSceLibcParam(nil)^.sceLibcHeapMemoryLock)+SizeOf(Pointer)) then + if (SceLibcParam^.sceLibcHeapMemoryLock<>nil) then + begin + sceLibcHeapMemoryLock:=SceLibcParam^.sceLibcHeapMemoryLock^; + end; + + if (SceLibcParam^.Size>=qword(@PSceLibcParam(nil)^.sceLibcMaxSystemSize)+SizeOf(Pointer)) then + if (SceLibcParam^.sceLibcMaxSystemSize<>nil) then + begin + sceLibcMaxSystemSize:=SceLibcParam^.sceLibcMaxSystemSize^; + end; + + end; + + // + + if (sceLibcHeapDebugFlags and SCE_LIBC_MSPACE_DEBUG_SHORTAGE)<>0 then + begin + tmp^.debug_flags:=tmp^.debug_flags or 4; + end; + + if (sceLibcHeapDebugFlags and SCE_LIBC_MSPACE_IN_ARRAY)<>0 then + begin + tmp^.msp_array_flags:=tmp^.msp_array_flags or 1; + end; + + tmp^.ptr_self:=tmp; + + if (SceLibcInternalHeap=0) then + begin + + tmp:=p_SceLibcIHeap; + tmp^.name:='SceLibcInternalHeap'; + + if (sceLibcHeapSize<>0) then + begin + g_heap_param.custom_heap_size:=1; + g_SystemSize:=ptruint($ffffffffffffffff); + if (sceLibcHeapSize < ptruint($ffffffffffff0001)) then + begin + g_SystemSize:=(sceLibcHeapSize+$ffff) and ptruint($ffffffffffff0000); + end; + end; + + if (sceLibcHeapSize<>0) then + begin + g_heap_param.HeapDelayedAlloc:=1; + end; + + if (sceLibcHeapExtendedAlloc<>0) then + begin + g_heap_param.custom_heap_size:=0; + end; + + if (sceLibcHeapInitialSize<>0) then + begin + g_heap_param.custom_heap_init_size:=1; + g_heap_param.HeapInitialSize:=(sceLibcHeapInitialSize + $ffff) and $ffff0000; + end; + + //sceLibcHeapHighAddressAlloc + + if (sceLibcHeapMemoryLock<>0) then + begin + g_heap_param.HeapMemoryLock:=1; + end; + +_mmap_resize: + if ((g_heap_param.custom_heap_size = 0) or (g_heap_param.HeapDelayedAlloc <> 0)) then + begin + if ((g_heap_param.custom_heap_size = 0) and (g_heap_param.custom_heap_init_size <> 0)) then + begin + if (g_SystemSize < g_heap_param.HeapInitialSize) then Exit(1); + if (g_heap_param.HeapDelayedAlloc = 0) then + begin + len:=g_heap_param.HeapInitialSize-96; + mem_init(p_SceLibcIHeap,len); + end; + end; + end else + if (g_SystemSize<>0) then + begin + _mmap_system(g_SystemSize,@g_heap_param.SystemData,p_SceLibcIHeap^.name); + end; + p_SceLibcIHeap^.g_cbs:=nil; + + end else //SceLibcInternalHeap + begin + if ((SceLibcInternalHeap<>1) or (sceLibcParam^.entry_count<6)) then //sceKernelInternalMemorySize ??? + begin + g_SystemSize:=ptruint($ffffffffffffffff); + g_heap_param.custom_heap_size:=0; + goto _mmap_resize; + end; + + p_SceLibcIHeap^.name:='SceKernelInternalMemory'; + + g_SystemSize:=$1000000; + + if (g_heap_param.ptype_is_1<>0) and (sceLibcMaxSystemSize<>0) then + begin + g_SystemSize:=sceLibcMaxSystemSize; + if (g_SystemSize<$1000000) then + begin + g_SystemSize:=$1000000; + end else + if (g_SystemSize > ptruint($ffffffffffff0000)) then goto _break; + + g_SystemSize:=(g_SystemSize+$ffff) and ptruint($ffffffffffff0000); + end; + +_break: + + g_heap_param.custom_heap_size:=1; + + _mmap_system(g_SystemSize,@g_heap_param.SystemData,p_SceLibcIHeap^.name); + + _SystemData:=g_heap_param.SystemData; + _SystemSize:=g_SystemSize; + + tmp:=_sceLibcMspaceCreate('SceKernelIntMemPthread', + _SystemData+(_SystemSize-$b4000), //base + $b4000, //size + SCE_LIBC_MSPACE_THREAD_UNSAFE or SCE_LIBC_MSPACE_IN_ARRAY); + + if (tmp=nil) then Exit(-1); + g_SceKernelIntMemPthread:=tmp; + tmp^.mutex:=p_SceLibcIHeap^.mutex; + + g_SceKernelIntMemTLS_base:=_SystemData+(_SystemSize-$29c000); + + tmp:=_sceLibcMspaceCreate('SceKernelIntMemTLS', + g_SceKernelIntMemTLS_base+$48000, //base + $1a0000, //size + SCE_LIBC_MSPACE_THREAD_UNSAFE or SCE_LIBC_MSPACE_IN_ARRAY); + + if (tmp=nil) then Exit(-1); + g_SceKernelIntMemTLS:=tmp; + tmp^.mutex:=p_SceLibcIHeap^.mutex; + + tmp:=_sceLibcMspaceCreate('SceKernelIntMemPthread', + _SystemData+(_SystemSize-$294000), //base + $40000, //size + SCE_LIBC_MSPACE_THREAD_UNSAFE or SCE_LIBC_MSPACE_IN_ARRAY); + + if (tmp=nil) then Exit(-1); + g_SceKernelIntMemThrSpec:=tmp; + tmp^.mutex:=p_SceLibcIHeap^.mutex; + + //g_internal_alloc = 1; + + g_SystemSize:=g_SystemSize-$29c000; + end; + + p_SceLibcIHeap^.SystemSize:=g_SystemSize; + Result:=0; +end; + +function _malloc_init:Integer; +begin + Result:=_malloc_init_lv2(@SceLibcIHeap); +end; end. diff --git a/ps4_elf.pas b/ps4_elf.pas index c4fb58c..c6e48d2 100644 --- a/ps4_elf.pas +++ b/ps4_elf.pas @@ -112,7 +112,7 @@ type sceKernelInternalMemorySize :PQWORD; _sceLibcMallocReplaceForTls :PsceLibcMallocReplaceForTls; //The maximum amount of the memory areas for the mspace. min:0x1000000 - sceLibcMaxSystemSize :PQWORD; + sceLibcMaxSystemSize :PQWORD; //(entry_count > 7) sceLibcHeapDebugFlags :PQWORD; //(entry_count > 8) sceLibcStdThreadStackSize :PDWORD; Unknown3:QWORD;