diff --git a/sys/dev/dev_gc.pas b/sys/dev/dev_gc.pas new file mode 100644 index 00000000..027055b3 --- /dev/null +++ b/sys/dev/dev_gc.pas @@ -0,0 +1,88 @@ +unit dev_gc; + +{$mode ObjFPC}{$H+} +{$CALLING SysV_ABI_CDecl} + +interface + +uses + kern_conf; + +procedure gc_initialize(); + +implementation + +uses + errno, + vm, + kern_thr, + trap; + +Function gc_ioctl(dev:p_cdev;cmd:QWORD;data:Pointer;fflag:Integer):Integer; +begin + Result:=0; + + Writeln('gc_ioctl(0x',HexStr(cmd,8),')'); + + case cmd of + 0:; + else + begin + print_backtrace(stderr,Pointer(curkthread^.td_frame.tf_rip),Pointer(curkthread^.td_frame.tf_rbp),0); + Assert(False); + Result:=EINVAL; + end; + end; + +end; + +Function gc_mmap(dev:p_cdev;offset:vm_ooffset_t;paddr:p_vm_paddr_t;nprot:Integer;memattr:p_vm_memattr_t):Integer; +begin + print_backtrace(stderr,Pointer(curkthread^.td_frame.tf_rip),Pointer(curkthread^.td_frame.tf_rbp),0); + Assert(False); + Result:=0; +end; + +{ + int ret2; + int ret1; + GS_OFFSET *in_GS_OFFSET; + + ret2 = sceSblACMgrHasUseHp3dPipeCapability(in_GS_OFFSET->td->td_ucred); + ret1 = 1; + if ((ret2 == 0) && (ret1 = 0x16, offset < 0x4000)) { + ret1 = 0; + *paddr = offset + *(long *)(*(long *)(dev + 0xa8) + 0x216c8); + *memattr = 0; + } + return ret1; +} + +const + gc_cdevsw:t_cdevsw=( + d_version :D_VERSION; + d_flags :0; + d_name :'gc'; + d_open :nil; + d_fdopen :nil; + d_close :nil; + d_read :nil; + d_write :nil; + d_ioctl :@gc_ioctl; + d_poll :nil; + d_mmap :@gc_mmap; + d_strategy :nil; + d_dump :nil; + d_kqfilter :nil; + d_purge :nil; + d_mmap_single:nil; + ); + +procedure gc_initialize(); +begin + make_dev(@gc_cdevsw,0,0,0,&666,'gc',[]); +end; + + +end. + diff --git a/sys/kern/kern_authinfo.pas b/sys/kern/kern_authinfo.pas index bd50a90c..35e27ebd 100644 --- a/sys/kern/kern_authinfo.pas +++ b/sys/kern/kern_authinfo.pas @@ -5,12 +5,118 @@ unit kern_authinfo; interface -uses - kern_rtld; +type + p_proc_type_info=^t_proc_type_info; + t_proc_type_info=packed record + size :QWORD; + bptype:DWORD; + pflags:DWORD; + end; + {$IF sizeof(t_proc_type_info)<>16}{$STOP sizeof(t_proc_type_info)<>16}{$ENDIF} + + p_authinfo=^t_authinfo; + t_authinfo=packed record + app_type :QWORD; + app_flags :QWORD; //62 bit IsSystemProcess;61 bit IsGameProcess1;60 bit IsGameProcess2; + app_cap :QWORD; + unknow1 :array[0..1] of QWORD; + s_prog_attr:QWORD; + unknow2 :array[0..10] of QWORD; + end; + {$IF sizeof(t_authinfo)<>136}{$STOP sizeof(t_authinfo)<>136}{$ENDIF} + +const + //eLoadOptions + LOAD_OPTIONS_DEFAULT =$0000; + LOAD_OPTIONS_LOAD_SUSPENDED =$0001; + LOAD_OPTIONS_USE_SYSTEM_LIBRARY_VERIFICATION =$0002; + LOAD_OPTIONS_SLV_MODE_WARN =$0004; + LOAD_OPTIONS_ARG_STACK_SIZE =$0008; + LOAD_OPTIONS_FULL_DEBUG_REQUIRED =$0010; + + //mmap_flags + //bit 1 -> is_big_app + //bit 2 -> first find addr is (1 shl 33) -> + // _sceKernelMapFlexibleMemory + // _sceKernelMapDirectMemory + // sceKernelMapDirectMemory2 + + //excp_flags + //bit 1 -> use in [libkernel_exception] -> + // -> sceKernelInstallExceptionHandler + // -> sceKernelRemoveExceptionHandler + // -> sceKernelAddGpuExceptionEvent + // -> sceKernelDeleteGpuExceptionEvent + // -> sceKernelBacktraceSelf + //bit 2 -> sys_mdbg_service + +type + TCUSANAME=array[0..9] of AnsiChar; + + //[preload_lib] -> sceSysmodulePreloadModuleForLibkernel + //0x0000000004 libSceNet + //0x0000000008 libSceIpmi + //0x0000000010 libSceMbus + //0x0000000020 libSceRegMgr + //0x0000000040 libSceRtc + //0x0000000080 libSceAvSetting + //0x0000000100 libSceVideoOut + //0x0000000200 libSceGnmDriver + //0x0000000400 libSceAudioOut + //0x0000000800 libSceAudioIn + //0x0000001000 libSceAjm + //0x0000002000 libScePad + //0x0000004000 libSceCamera + //0x0000008000 libSceDbg + //0x0000010000 libSceNetCtl + //0x0000020000 libScettp + //0x0000040000 libSceSsl + //0x0000080000 libSceNpCommon + //0x0000100000 libSceNpManager + //0x0000200000 libSceNpWebApi + //0x0000400000 libSceSaveData + //0x0000800000 libSceSystemService + //0x0001000000 libSceUserService + //0x0002000000 libSceCommonDialog + //0x0004000000 libSceSysUtil + //0x0008000000 libScePerf + //0x0010000000 libSceWebKit2ForVideoService + //0x0020000000 libSceOrbisCompatForVideoService + //0x0040000000 libSceFios2,libc + //0x0080000000 libSceRazorCpu + //0x0100000000 libSceRazorCpu_debug + //0x1000000000 libSceHttp2 + //0x2000000000 libSceNpGameIntent + //0x4000000000 libSceNpWebApi2 + + p_appinfo=^t_appinfo; + t_appinfo=packed record + AppId :Integer; //4 + mmap_flags :Integer; //4 + excp_flags :Integer; //4 + AppType :Integer; //4 5? + CUSANAME :TCUSANAME; //10 + debug_level:Byte; //1 + slv_flags :Byte; //1 eLoadOptions + f_1c :Byte; + f_1d :Byte; + f_1e :Byte; + f_1f :Byte; + preload_lib:QWORD; + f_28 :Integer; + f_2c :Integer; + f_30 :Integer; + f_34 :Integer; + f_38 :QWORD; + f_40 :QWORD; + end; + {$IF sizeof(t_appinfo)<>72}{$STOP sizeof(t_appinfo)<>72}{$ENDIF} var g_authinfo:t_authinfo; + g_appinfo :t_appinfo; +function sys_get_proc_type_info(dst:Pointer):Integer; function sys_get_authinfo(pid:Integer;info:Pointer):Integer; implementation @@ -18,7 +124,79 @@ implementation uses errno, systm, - md_proc; + md_proc, + kern_rtld; + +function sceSblACMgrIsVideoplayerProcess(info:p_authinfo):Boolean; +begin + Result:=(info^.app_type + QWORD($c7ffffffefffffff)) < 2; +end; + +function sceSblACMgrHasUseVideoServiceCapability(info:p_authinfo):Boolean; +begin + Result:=((info^.app_cap shr $39) and 1)<>0; +end; + +function sceSblACMgrHasSceProgramAttribute(info:p_authinfo):Boolean; +var + sce_prog_attr:QWORD; +begin + sce_prog_attr:=info^.s_prog_attr; + if ((sce_prog_attr and $1000000)=0) then + begin + if ((sce_prog_attr and $2000000)<>0) then + begin + Exit(true); + end; + //sceSblRcMgrIsAllowULDebugger + if (((sce_prog_attr shr (3*8)) and 1)=0) then + begin + Exit(false); + end; + end; + //sceSblRcMgrIsSoftwagnerQafForAcmgr + Exit(false); +end; + +function sys_get_proc_type_info(dst:Pointer):Integer; +var + info:t_proc_type_info; +begin + info:=Default(t_proc_type_info); + + Result:=copyin(dst,@info.size,SizeOf(QWORD)); + if (Result<>0) then Exit; + + if (info.size<>SizeOf(t_proc_type_info)) then Exit(EINVAL); + + info.bptype:=budget_ptype_caller; + + if sceSblACMgrIsVideoplayerProcess(@g_authinfo) then + begin + info.pflags:=info.pflags or $04; + end; + + if sceSblACMgrHasUseVideoServiceCapability(@g_authinfo) then + begin + info.pflags:=info.pflags or $10; + end; + + if sceSblACMgrHasSceProgramAttribute(@g_authinfo) then + begin + info.pflags:=info.pflags or $80; + end; + + //sceSblACMgrIsJitCompilerProcess() -> | 0x01 + //sceSblACMgrIsJitApplicationProcess() -> | 0x02 + //sceSblACMgrIsVideoplayerProcess() -> | 0x04 + //sceSblACMgrIsDiskplayeruiProcess() -> | 0x08 + //sceSblACMgrHasUseVideoServiceCapability() -> | 0x10 + //sceSblACMgrIsWebcoreProcess() -> | 0x20 + //is_libkernel_sys() -> | 0x40 + //sceSblACMgrHasSceProgramAttribute() -> | 0x80 + + Result:=copyout(@info,dst,SizeOf(t_proc_type_info)); +end; function sys_get_authinfo(pid:Integer;info:Pointer):Integer; var @@ -40,12 +218,12 @@ begin // data:=g_authinfo; //end else begin - x:=g_authinfo.app_type_id; + x:=g_authinfo.app_type; y:=x+QWORD($c7ffffffeffffffc); if (y < $f) and (((QWORD($6001) shr (y and $3f)) and 1)<>0) then begin - data.app_type_id:=x; + data.app_type:=x; end; data.app_flags:=g_authinfo.app_flags and QWORD($7000000000000000); diff --git a/sys/kern/kern_budget.pas b/sys/kern/kern_budget.pas index d6066ec4..9a74a403 100644 --- a/sys/kern/kern_budget.pas +++ b/sys/kern/kern_budget.pas @@ -13,16 +13,12 @@ function sys_budget_get_ptype(pid:Integer):Integer; function sys_budget_get_ptype_of_budget(key:Integer):Integer; function sys_budget_getid():Integer; -function sys_get_proc_type_info(dst:Pointer):Integer; - implementation uses errno, - systm, kern_thr, - md_proc, - kern_rtld; + md_proc; function sys_budget_create(name:pchar;ptype:DWORD;unk_ptr1:Pointer;unk_count:DWORD;unk_ptr2:Pointer):Integer; begin @@ -76,41 +72,6 @@ begin Exit(ENOSYS); //sceSblACMgrIsSystemUcred end; -type - p_proc_type_info=^t_proc_type_info; - t_proc_type_info=packed record - size :QWORD; - bptype:DWORD; - pflags:DWORD; - end; - {$IF sizeof(t_proc_type_info)<>16}{$STOP sizeof(t_proc_type_info)<>16}{$ENDIF} - -function sys_get_proc_type_info(dst:Pointer):Integer; -var - info:t_proc_type_info; -begin - info:=Default(t_proc_type_info); - - Result:=copyin(dst,@info.size,SizeOf(QWORD)); - if (Result<>0) then Exit; - - if (Result<>SizeOf(t_proc_type_info)) then Exit(EINVAL); - - info.bptype:=budget_ptype_caller; - info.pflags:=0; - - //sceSblACMgrIsJitCompilerProcess() -> | 0x01 - //sceSblACMgrIsJitApplicationProcess() -> | 0x02 - //sceSblACMgrIsVideoplayerProcess() -> | 0x04 - //sceSblACMgrIsDiskplayeruiProcess() -> | 0x08 - //sceSblACMgrHasUseVideoServiceCapability() -> | 0x10 - //sceSblACMgrIsWebcoreProcess() -> | 0x20 - //is_libkernel_sys() -> | 0x40 - //sceSblACMgrHasSceProgramAttribute() -> | 0x80 - - Result:=copyout(@info,dst,SizeOf(t_proc_type_info)); -end; - end. diff --git a/sys/kern/kern_dlsym.pas b/sys/kern/kern_dlsym.pas index a060823a..75af1e84 100644 --- a/sys/kern/kern_dlsym.pas +++ b/sys/kern/kern_dlsym.pas @@ -533,7 +533,8 @@ begin def :=@dynlibs_info.sym_zero; defobj:=dynlibs_info.libprogram; end else - if (where<>nil) then + if (where<>nil) and + (ELF64_ST_TYPE(ref^.st_info)<>STT_OBJECT) then begin stub:=vm_get_patch_link(refobj^.rel_data^.obj,where); diff --git a/sys/kern/kern_exec.pas b/sys/kern/kern_exec.pas index 51151363..e9e65adb 100644 --- a/sys/kern/kern_exec.pas +++ b/sys/kern/kern_exec.pas @@ -38,8 +38,9 @@ uses vmparam, vm_map, vm_mmap, - vnamei, vm_object, + vm_pager, + vnamei, vfs_lookup, vmount, vfile, @@ -1096,7 +1097,11 @@ begin if (Result<>0) then Exit; - imgp^.obj:=vm_object_allocate(OBJT_DEFAULT,OFF_TO_IDX(imgp^.max_addr-imgp^.min_addr)); + imgp^.obj:=vm_pager_allocate(OBJT_SELF, + imgp^.vp, + imgp^.max_addr-imgp^.min_addr, + 1, + 0); Result:=scan_load_sections(imgp,phdr,hdr^.e_phnum); if (Result<>0) then @@ -1433,6 +1438,15 @@ begin //copy authinfo g_authinfo:=imgp^.authinfo; + //copy appinfo + g_appinfo.mmap_flags:=g_appinfo.mmap_flags or 1; //is_big_app ??? + if (p_proc.p_sce_replay_exec<>0) then + begin + g_appinfo.mmap_flags:=g_appinfo.mmap_flags or 2; //is_system ??? + end; + + //TODO load CUSANAME + //init std tty init_tty; diff --git a/sys/kern/kern_rtld.pas b/sys/kern/kern_rtld.pas index bbb4ba90..042c4f6a 100644 --- a/sys/kern/kern_rtld.pas +++ b/sys/kern/kern_rtld.pas @@ -12,7 +12,8 @@ uses vnode, vm_object, vuio, - elf64; + elf64, + kern_authinfo; const AT_NULL = 0; // Terminates the vector. @@ -84,17 +85,6 @@ type entry :QWORD; end; - p_authinfo=^t_authinfo; - t_authinfo=packed record - app_type_id:QWORD; - app_flags :QWORD; //62 bit IsSystemProcess;61 bit IsGameProcess1;60 bit IsGameProcess2; - app_cap :QWORD; - unknow1 :array[0..1] of QWORD; - s_prog_attr:QWORD; - unknow2 :array[0..10] of QWORD; - end; - {$IF sizeof(t_authinfo)<>136}{$STOP sizeof(t_authinfo)<>136}{$ENDIF} - p_image_params=^t_image_params; t_image_params=packed record vp :p_vnode; @@ -481,10 +471,10 @@ begin (imgp^.image_self =nil) then begin case ExtractFileExt(imgp^.execpath) of - '.sprx','.prx' :imgp^.authinfo.app_type_id:=QWORD($3900000000000002); - '.sdll','.sexe':imgp^.authinfo.app_type_id:=QWORD($3901000000000001); + '.sprx','.prx' :imgp^.authinfo.app_type:=QWORD($3900000000000002); + '.sdll','.sexe':imgp^.authinfo.app_type:=QWORD($3901000000000001); else - imgp^.authinfo.app_type_id:=QWORD($3100000000000001); + imgp^.authinfo.app_type:=QWORD($3100000000000001); end; Exit; end; @@ -498,7 +488,7 @@ begin authinfo:=Pointer(Pointer(imgp^.image_self)+s); - imgp^.authinfo.app_type_id:=authinfo^.AuthorityID; + imgp^.authinfo.app_type:=authinfo^.AuthorityID; end; function is_used_mode_2mb(phdr:p_elf64_phdr;is_dynlib,budget_ptype_caller:Integer):Boolean; diff --git a/sys/kern/kern_stub.pas b/sys/kern/kern_stub.pas index a9d42c78..7998da47 100644 --- a/sys/kern/kern_stub.pas +++ b/sys/kern/kern_stub.pas @@ -15,8 +15,6 @@ const m_first_chunk=2; m_last__chunk=4; - segment_size =64*1024; - type p_stub_chunk=^stub_chunk; stub_chunk=packed record @@ -40,6 +38,7 @@ uses hamt, kern_rwlock, vm, + vmparam, vm_map, vm_mmap, vm_object; @@ -50,32 +49,51 @@ var chunk_lock :Pointer=nil; -function alloc_segment(start:Pointer):p_stub_chunk; +function AlignUp(addr:PtrUInt;alignment:PtrUInt):PtrUInt; inline; +var + tmp:PtrUInt; +begin + if (alignment=0) then Exit(addr); + tmp:=addr+PtrUInt(alignment-1); + Result:=tmp-(tmp mod alignment) +end; + +function alloc_segment(start,size:QWORD):p_stub_chunk; var map:vm_map_t; err:Integer; begin Result:=nil; + + size:=AlignUp(size+SizeOf(stub_chunk),PAGE_SIZE); + map:=@g_vmspace.vm_map; + if (start=0) then + begin + start:=SCE_REPLAY_EXEC_START; + end; + err:=vm_mmap2(map, @start, - segment_size, + size, VM_PROT_RWX, VM_PROT_RWX, - MAP_ANON or MAP_PRIVATE or (16 shl MAP_ALIGNMENT_BIT), + MAP_ANON or MAP_PRIVATE, OBJT_DEFAULT, nil, 0); if (err<>0) then Exit; - Result:=start; + vm_map_set_name(map,start,size,'#patch'); + + Result:=Pointer(start); Result^.head :=m_header; Result^.flags :=m_free__chunk or m_first_chunk or m_last__chunk; Result^.prev_size :=0; - Result^.curr_size :=segment_size; + Result^.curr_size :=size; Result^.refs :=0; Result^.link.tqe_next:=nil; Result^.link.tqe_prev:=nil; @@ -88,25 +106,15 @@ begin map:=@g_vmspace.vm_map; vm_map_lock (map); - vm_map_delete(map, qword(chunk), qword(chunk) + segment_size); + vm_map_delete(map, qword(chunk), qword(chunk) + chunk^.curr_size); vm_map_unlock(map); end; -function AlignUp(addr:PtrUInt;alignment:PtrUInt):PtrUInt; inline; -var - tmp:PtrUInt; -begin - if (alignment=0) then Exit(addr); - tmp:=addr+PtrUInt(alignment-1); - Result:=tmp-(tmp mod alignment) -end; - procedure fix_next_size(chunk:p_stub_chunk); var next:p_stub_chunk; begin - if (chunk^.curr_size0) then @@ -230,15 +237,13 @@ function p_alloc(vaddr:Pointer;size:Integer):p_stub_chunk; var chunk:p_stub_chunk; begin - Assert(size<=(segment_size-SizeOf(stub_chunk)),'p_alloc to big'); - rw_wlock(chunk_lock); chunk:=find_free_chunk(vaddr,size); if (chunk=nil) then begin - chunk:=alloc_segment(vaddr); + chunk:=alloc_segment(QWORD(vaddr),size); Assert(chunk<>nil,'p_alloc NOMEM'); end; @@ -271,8 +276,7 @@ begin merge_chunk(chunk); - if (chunk^.curr_size>=segment_size) and - ((chunk^.flags and (m_first_chunk or m_last__chunk))=(m_first_chunk or m_last__chunk)) then + if ((chunk^.flags and (m_first_chunk or m_last__chunk))=(m_first_chunk or m_last__chunk)) then begin free_segment(chunk); end else diff --git a/sys/kern/kern_sysctl.pas b/sys/kern/kern_sysctl.pas index a1308e92..52e30083 100644 --- a/sys/kern/kern_sysctl.pas +++ b/sys/kern/kern_sysctl.pas @@ -161,6 +161,7 @@ uses kern_thr, kern_sx, time, + kern_authinfo, md_arc4random, md_proc; @@ -349,65 +350,11 @@ begin Result:=SYSCTL_OUT(req,@data,len); end; -const - //eLoadOptions - LOAD_OPTIONS_DEFAULT =$0000; - LOAD_OPTIONS_LOAD_SUSPENDED =$0001; - LOAD_OPTIONS_USE_SYSTEM_LIBRARY_VERIFICATION =$0002; - LOAD_OPTIONS_SLV_MODE_WARN =$0004; - LOAD_OPTIONS_ARG_STACK_SIZE =$0008; - LOAD_OPTIONS_FULL_DEBUG_REQUIRED =$0010; - - //mmap_flags - //bit 1 -> is_big_app - //bit 2 -> first find addr is (1 shl 33) -> - // _sceKernelMapFlexibleMemory - // _sceKernelMapDirectMemory - // sceKernelMapDirectMemory2 - - //excp_flags - //bit 1 -> use in [libkernel_exception] -> - // -> sceKernelInstallExceptionHandler - // -> sceKernelRemoveExceptionHandler - // -> sceKernelAddGpuExceptionEvent - // -> sceKernelDeleteGpuExceptionEvent - // -> sceKernelBacktraceSelf - //bit 2 -> sys_mdbg_service - -type - TCUSANAME=array[0..9] of AnsiChar; - - PSCE_APP_ENV=^TSCE_APP_ENV; - TSCE_APP_ENV=packed record - AppId :Integer; //4 - mmap_flags :Integer; //4 - excp_flags :Integer; //4 - AppType :Integer; //4 5? - CUSANAME :TCUSANAME; //10 - debug_level:Byte; //1 - slv_flags :Byte; //1 eLoadOptions - f_1c :Byte; - f_1d :Byte; - f_1e :Byte; - f_1f :Byte; - f_20 :QWORD; - f_28 :Integer; - f_2c :Integer; - f_30 :Integer; - f_34 :Integer; - f_38 :QWORD; - f_40 :QWORD; - end; - {$IF sizeof(TSCE_APP_ENV)<>72}{$STOP sizeof(TSCE_APP_ENV)<>72}{$ENDIF} - -var - G_APPINFO:TSCE_APP_ENV; - function sysctl_kern_proc_appinfo(oidp:p_sysctl_oid;arg1:Pointer;arg2:ptrint;req:p_sysctl_req):Integer; var pid:Integer; - - APPINFO:TSCE_APP_ENV; + flags:Integer; + appinfo:t_appinfo; begin if (req^.oldlen > 72) then Exit(EINVAL); @@ -415,27 +362,19 @@ begin if (pid<>g_pid) then Exit(EINVAL); - //G_APPINFO.mmap_flags:=G_APPINFO.mmap_flags or 1; - if (p_proc.p_sce_replay_exec<>0) then - begin - G_APPINFO.mmap_flags:=G_APPINFO.mmap_flags or 2; - end; - //sceSblACMgrIsSystemUcred()!=0 -> any proc //sceSblACMgrIsSystemUcred()==0 -> cur proc - Result:=SYSCTL_OUT(req,@G_APPINFO,SizeOf(TSCE_APP_ENV)); + Result:=SYSCTL_OUT(req,@g_appinfo,SizeOf(t_appinfo)); - if (Result=0) and (req^.newlen=SizeOf(TSCE_APP_ENV)) then + if (Result=0) and (req^.newlen=SizeOf(t_appinfo)) then begin - Result:=SYSCTL_IN(req,@APPINFO,SizeOf(TSCE_APP_ENV)); + Result:=SYSCTL_IN(req,@appinfo,SizeOf(t_appinfo)); if (Result=0) then begin - G_APPINFO:=APPINFO; - if (p_proc.p_sce_replay_exec<>0) then - begin - G_APPINFO.mmap_flags:=G_APPINFO.mmap_flags or 2; - end; + flags:=g_appinfo.mmap_flags; + g_appinfo:=appinfo; + g_appinfo.mmap_flags:=g_appinfo.mmap_flags or (flags and 2) end; end; diff --git a/sys/kern/subr_dynlib.pas b/sys/kern/subr_dynlib.pas index 5e7613d2..a0cdc5c2 100644 --- a/sys/kern/subr_dynlib.pas +++ b/sys/kern/subr_dynlib.pas @@ -357,6 +357,7 @@ uses vm_map, vm_mmap, vm_object, + vm_pager, vuio, vstat, vfcntl, @@ -2045,7 +2046,11 @@ begin new^.tls_init_addr :=new^.tls_init_addr +delta; new^.eh_frame_hdr_addr:=new^.eh_frame_hdr_addr+delta; - imgp^.obj:=vm_object_allocate(OBJT_SELF,OFF_TO_IDX(imgp^.max_addr-imgp^.min_addr)); + imgp^.obj:=vm_pager_allocate(OBJT_SELF, + imgp^.vp, + imgp^.max_addr-imgp^.min_addr, + 1, + 0); error:=dynlib_load_sections(imgp,new,phdr,hdr^.e_phnum,delta); if (error<>0) then @@ -2675,6 +2680,8 @@ begin Result^.internal:=1; Result^.loaded:=1; + Writeln(' preload_prx_internal:',path); + // Exit; end; diff --git a/sys/sys_sysinit.pas b/sys/sys_sysinit.pas index 575fc343..ce4ed2e6 100644 --- a/sys/sys_sysinit.pas +++ b/sys/sys_sysinit.pas @@ -44,7 +44,8 @@ uses dev_tty, dev_dmem, dev_dipsw, - dev_rng; + dev_rng, + dev_gc; var daemon_thr:p_kthread; @@ -81,6 +82,7 @@ begin dmemdev_init(); dipsw_init(); rng_init(); + gc_initialize(); end; //Manual order of lazy initialization diff --git a/sys/syscalls.pas b/sys/syscalls.pas index d99cb298..adeec438 100644 --- a/sys/syscalls.pas +++ b/sys/syscalls.pas @@ -229,7 +229,7 @@ function budget_get_ptype(pid:Integer):Integer; function __sys_get_proc_type_info(dst:Pointer):Integer; function thr_get_name(id:DWORD;pname:PChar):Integer; function set_gpo(uiBits:DWORD):Integer; -function ipmimgr_call(op,arg:Integer;res:PInteger;params:Pointer;paramsSize:QWORD):Integer; +function ipmimgr_call(op,kid:Integer;res:PInteger;params:Pointer;paramsSize:QWORD):Integer; function get_gpo(pbits:PByte):Integer; function thr_suspend_ucontext(tid:Integer):Integer; function thr_resume_ucontext(tid:Integer):Integer; @@ -1807,7 +1807,7 @@ asm jmp cerror end; -function ipmimgr_call(op,arg:Integer;res:PInteger;params:Pointer;paramsSize:QWORD):Integer; assembler; nostackframe; +function ipmimgr_call(op,kid:Integer;res:PInteger;params:Pointer;paramsSize:QWORD):Integer; assembler; nostackframe; asm movq $622,%rax call fast_syscall diff --git a/sys/test/project1.lpi b/sys/test/project1.lpi index e0693f5f..9e0138f8 100644 --- a/sys/test/project1.lpi +++ b/sys/test/project1.lpi @@ -670,6 +670,14 @@ + + + + + + + + diff --git a/sys/test/project1.lpr b/sys/test/project1.lpr index 75cb41cf..f4b76f2c 100644 --- a/sys/test/project1.lpr +++ b/sys/test/project1.lpr @@ -99,10 +99,10 @@ uses kern_dmem, kern_bnet, uipc_syscalls, - kern_ipmimgr{, + kern_ipmimgr, ps4_libSceSystemService, ps4_libSceIpmi, - ps4_libSceDialogs}; + ps4_libSceDialogs; const PAGE_MAP_COUNT=(qword(VM_MAXUSER_ADDRESS) shr PAGE_SHIFT); @@ -366,6 +366,8 @@ begin //readln; argv0:='/app0/basic-sample_debug.elf'; + argv0:='/app0/simple.elf'; + //argv0:='/app0/videoout_basic.elf'; err:=_execve(argv0,@argv0,nil); end; diff --git a/sys/test/ps4_libscesystemservice.pas b/sys/test/ps4_libscesystemservice.pas index 8e290ad1..de307709 100644 --- a/sys/test/ps4_libscesystemservice.pas +++ b/sys/test/ps4_libscesystemservice.pas @@ -129,8 +129,7 @@ uses errno, time, md_time, - trap, - kern_dlsym; + trap; type pSceSystemServiceDisplaySafeAreaInfo=^SceSystemServiceDisplaySafeAreaInfo; @@ -419,23 +418,6 @@ begin Result:=0; end; -type - t_sceSysmoduleLoadModuleInternal=function(id:DWORD):DWORD; - -procedure init(); -var - ptr:t_sceSysmoduleLoadModuleInternal; -begin - ptr:=nil; - name_dlsym('libSceSysmodule','sceSysmoduleLoadModuleInternal',@ptr); - if (ptr<>nil) then - begin - ptr($80000052); - end; - - Writeln('init'); -end; - // function Load_libSceSystemService(name:pchar):p_lib_info; @@ -444,8 +426,6 @@ var begin Result:=obj_new_int('libSceSystemService'); - Result^.init_proc_addr:=@init; - lib:=Result^.add_lib('libSceSystemService'); lib.set_proc($7D9A38F2E9FB2CAE,@ps4_sceSystemServiceParamGetInt); lib.set_proc($4AC0BF9BF4BD2530,@ps4_sceSystemServiceParamGetString); diff --git a/sys/vm/vm_mmap.pas b/sys/vm/vm_mmap.pas index 669f6e56..8285a380 100644 --- a/sys/vm/vm_mmap.pas +++ b/sys/vm/vm_mmap.pas @@ -63,7 +63,92 @@ uses vfcntl, vnode, vfs_subr, - vnode_if; + vnode_if, + kern_conf, + vm_pager; + +function vm_mmap_cdev(objsize :vm_size_t; + prot :vm_prot_t; + maxprotp :p_vm_prot_t; + flagsp :PInteger; + cdev :p_cdev; + foff :p_vm_ooffset_t; + objp :p_vm_object_t):Integer; +var + obj:vm_object_t; + dsw:p_cdevsw; + error,flags,ref:Integer; +begin + flags:=flagsp^; + + dsw:=dev_refthread(cdev, @ref); + if (dsw=nil) then + begin + Exit(ENXIO); + end; + + if ((dsw^.d_flags and D_MMAP_ANON)<>0) then + begin + dev_relthread(cdev, ref); + maxprotp^:=VM_PROT_ALL; + flagsp^:=flagsp^ or MAP_ANON; + Exit(0); + end; + { + * cdevs do not provide private mappings of any kind. + } + if ((maxprotp^ and VM_PROT_WRITE)=0) and + ((prot and VM_PROT_WRITE)<>0) then + begin + dev_relthread(cdev, ref); + Exit(EACCES); + end; + + if ((flags and (MAP_PRIVATE{ or MAP_COPY}))<>0) then + begin + dev_relthread(cdev, ref); + Exit(EINVAL); + end; + { + * Force device mappings to be shared. + } + flags:=flags or MAP_SHARED; + + { + * First, try d_mmap_single(). If that is not implemented + * (returns ENODEV), fall back to using the device pager. + * Note that d_mmap_single() must return a reference to the + * object (it needs to bump the reference count of the object + * it returns somehow). + * + * XXX assumes VM_PROT_*=PROT_* + } + if (dsw^.d_mmap_single=nil) then + begin + error:=ENODEV; + end else + begin + error:=dsw^.d_mmap_single(cdev, foff, objsize, objp, prot); + end; + + dev_relthread(cdev, ref); + + if (error<>ENODEV) then + begin + Exit(error); + end; + + obj:=vm_pager_allocate(OBJT_DEVICE, cdev, objsize, prot, foff^); + + if (obj=nil) then + begin + Exit(EINVAL); + end; + + objp^:=obj; + flagsp^:=flags; + Exit(0); +end; function vm_mmap_vnode(objsize :vm_size_t; prot :vm_prot_t; @@ -74,6 +159,7 @@ function vm_mmap_vnode(objsize :vm_size_t; objp :p_vm_object_t; writecounted:PBoolean):Integer; label + mark_atime, done; var va:t_vattr; @@ -100,44 +186,58 @@ begin flags:=flagsp^; obj:=nil; obj:=vp^.v_object; - if (vp^.v_type=VREG) then - begin - { - * Get the proper underlying object - } - if (obj=nil) then - begin - error:=EINVAL; - goto done; - end; - if (obj^.handle<>vp) then - begin - vput(vp); - vp:=obj^.handle; - { - * Bypass filesystems obey the mpsafety of the - * underlying fs. - } - error:=vget(vp, locktype); - if (error<>0) then - begin - VFS_UNLOCK_GIANT(vfslocked); - Exit(error); - end; - end; - if (locktype=LK_EXCLUSIVE) then - begin - writecounted^:=TRUE; - //vnode_pager_update_writecount(obj, 0, objsize); - end; - end else - begin - error:=EINVAL; - goto done; + + case vp^.v_type of + VREG: + begin + { + * Get the proper underlying object + } + if (obj=nil) then + begin + error:=EINVAL; + goto done; + end; + if (obj^.handle<>vp) then + begin + vput(vp); + vp:=obj^.handle; + { + * Bypass filesystems obey the mpsafety of the + * underlying fs. + } + error:=vget(vp, locktype); + if (error<>0) then + begin + VFS_UNLOCK_GIANT(vfslocked); + Exit(error); + end; + end; + if (locktype=LK_EXCLUSIVE) then + begin + writecounted^:=TRUE; + //vnode_pager_update_writecount(obj, 0, objsize); + end; + end; + VCHR: + begin + error:=vm_mmap_cdev(objsize, prot, maxprotp, flagsp, vp^.v_rdev, foffp, objp); + if (error=0) then goto mark_atime; + goto done; + end + + else + begin + error:=EINVAL; + goto done; + end; end; + error:=VOP_GETATTR(vp, @va); if (error<>0) then + begin goto done; + end; if ((flags and MAP_SHARED)<>0) then begin @@ -161,7 +261,7 @@ begin begin flags:=flags or MAP_NOSYNC; end; - //obj:=vm_pager_allocate(OBJT_VNODE, vp, objsize, prot, foff, cred); + obj:=vm_pager_allocate(OBJT_VNODE, vp, objsize, prot, foff); if (obj=nil) then begin error:=ENOMEM; @@ -170,6 +270,7 @@ begin objp^:=obj; flagsp^:=flags; +mark_atime: vfs_mark_atime(vp); done: @@ -183,6 +284,29 @@ done: Result:=(error); end; +function vm_mmap_shm(objsize :vm_size_t; + prot :vm_prot_t; + maxprotp :p_vm_prot_t; + flagsp :PInteger; + shmfd :Pointer; //shmfd + foff :p_vm_ooffset_t; + objp :p_vm_object_t):Integer; +var + error:Integer; +begin + if ((flagsp^ and MAP_SHARED)<>0) and + ((maxprotp^ and VM_PROT_WRITE)=0) and + ((prot and VM_PROT_WRITE)<>0) then + begin + Exit(EACCES); + end; + + //error:=shm_mmap(shmfd, objsize, foff, objp); + error:=EOPNOTSUPP; + + Exit(error); +end; + function vm_mmap_to_errno(rv:Integer):Integer; inline; begin Case rv of @@ -224,7 +348,7 @@ begin size:=round_page(size); - if (g_vmspace.vm_map.size + size) > lim_cur(RLIMIT_VMEM) then + if (map^.size + size) > lim_cur(RLIMIT_VMEM) then begin Exit(ENOMEM); end; @@ -246,9 +370,17 @@ begin writecounted:=False; Case handle_type of + OBJT_DEVICE: + begin + error:=vm_mmap_cdev(size,prot,@maxprot,@flags,handle,@foff,@vm_obj); + end; OBJT_VNODE: begin - error:=vm_mmap_vnode(size,prot,@maxprot,@flags, handle,@foff,@vm_obj,@writecounted); + error:=vm_mmap_vnode(size,prot,@maxprot,@flags,handle,@foff,@vm_obj,@writecounted); + end; + OBJT_SWAP: + begin + error:=vm_mmap_shm(size,prot,@maxprot,@flags,handle,@foff,@vm_obj); end; OBJT_DEFAULT: begin @@ -260,11 +392,11 @@ begin error:=EINVAL; end; end; - else - error:=EINVAL; - end; + else + error:=EINVAL; + end; - if (error<>0) then Exit(error); + if (error<>0) then Exit(error); if ((flags and MAP_ANON)<>0) then begin @@ -478,10 +610,11 @@ begin Result:=fget_mmap(_fd,rights,@cap_maxprot,@fp); if (Result<>0) then goto _done; + if (fp^.f_type=DTYPE_SHM) then begin handle:=fp^.f_data; - //handle_type:=OBJT_SWAP; + handle_type:=OBJT_SWAP; maxprot:=VM_PROT_NONE; // FREAD should always be set. @@ -601,10 +734,8 @@ begin Exit(EINVAL); end; - vm_map_lock(@g_vmspace.vm_map); - + vm_map_lock (@g_vmspace.vm_map); vm_map_delete(@g_vmspace.vm_map, qword(addr), qword(addr) + size); - vm_map_unlock(@g_vmspace.vm_map); // vm_map_delete returns nothing but KERN_SUCCESS anyway diff --git a/sys/vm/vm_object.pas b/sys/vm/vm_object.pas index 1e1679d0..f4251cfd 100644 --- a/sys/vm/vm_object.pas +++ b/sys/vm/vm_object.pas @@ -117,6 +117,7 @@ uses vmparam, vnode, vfs_subr, + vm_pager, vm_patch_link; function IDX_TO_OFF(x:DWORD):QWORD; inline; @@ -193,9 +194,6 @@ end; procedure vm_object_destroy(obj:vm_object_t); begin - Case obj^.otype of - OBJT_DEFAULT:; - end; mtx_destroy(obj^.mtx); FreeMem(obj); end; @@ -255,6 +253,7 @@ begin Assert(obj^.ref_count=0,'vm_object_terminate: obj with references'); + vm_pager_deallocate(obj); VM_OBJECT_UNLOCK(obj); vm_object_destroy(obj); diff --git a/sys/vm/vm_pager.pas b/sys/vm/vm_pager.pas new file mode 100644 index 00000000..fbb646ae --- /dev/null +++ b/sys/vm/vm_pager.pas @@ -0,0 +1,77 @@ +unit vm_pager; + +{$mode ObjFPC}{$H+} +{$CALLING SysV_ABI_CDecl} + +interface + +uses + vm, + vm_object; + +function vm_pager_allocate(otype:objtype_t; + handle:Pointer; + size:vm_ooffset_t; + prot:vm_prot_t; + off:vm_ooffset_t):vm_object_t; + +procedure vm_pager_deallocate(obj:vm_object_t); + +implementation + +uses + vmparam; + +function OFF_TO_IDX(x:QWORD):DWORD; inline; +begin + Result:=QWORD(x) shr PAGE_SHIFT; +end; + +function vm_pager_allocate(otype:objtype_t; + handle:Pointer; + size:vm_ooffset_t; + prot:vm_prot_t; + off:vm_ooffset_t):vm_object_t; +begin + case otype of + OBJT_DEFAULT :Result:=vm_object_allocate(otype,OFF_TO_IDX(size)); + //OBJT_SWAP :; + //OBJT_VNODE :; + //OBJT_DEVICE :; + //OBJT_PHYS :; + //OBJT_DEAD :; + //OBJT_SG :; + //OBJT_JITSHM :; + OBJT_SELF :Result:=vm_object_allocate(otype,OFF_TO_IDX(size)); + //OBJT_TRCMEM :; + //OBJT_PHYSHM :; + //OBJT_BLOCKPOOL:; + else + Assert(False); + end; +end; + +procedure vm_pager_deallocate(obj:vm_object_t); +begin + if (obj=nil) then Exit; + + case obj^.otype of + OBJT_DEFAULT :; + OBJT_SWAP :; + OBJT_VNODE :; + OBJT_DEVICE :; + OBJT_PHYS :; + OBJT_DEAD :; + OBJT_SG :; + OBJT_JITSHM :; + OBJT_SELF :; + OBJT_TRCMEM :; + OBJT_PHYSHM :; + OBJT_BLOCKPOOL:; + else; + end; +end; + + +end. +