diff --git a/sys/dev/dev_gc.pas b/sys/dev/dev_gc.pas index 19769f99..801de0f7 100644 --- a/sys/dev/dev_gc.pas +++ b/sys/dev/dev_gc.pas @@ -82,14 +82,14 @@ begin if (paddr=0) and ((g_appinfo.mmap_flags and 2)<>0) then begin - paddr:=QWORD($fc0000000); + paddr:=SCE_REPLAY_EXEC_START; end; Result:=vm_mmap2(map, @paddr,psize, prot,prot, MAP_ANON or MAP_SYSTEM or MAP_SHARED,OBJT_DEFAULT, - nil,0); + nil,0,nil); if (Result=0) then begin diff --git a/sys/kern/kern_dmem.pas b/sys/kern/kern_dmem.pas index ed1d54b9..a0cd4894 100644 --- a/sys/kern/kern_dmem.pas +++ b/sys/kern/kern_dmem.pas @@ -102,6 +102,7 @@ implementation uses errno, + md_systm, systm, vm, vmparam, @@ -207,15 +208,16 @@ begin rmem_map_unlock(@rmap); end; -function kern_mmap_dmem(map :vm_map_t; - addr :p_vm_offset_t; - phaddr:QWORD; - vaddr :QWORD; - length:QWORD; - mtype :DWORD; - prot :DWORD; - align :QWORD; - flags :DWORD):Integer; +function kern_mmap_dmem(map :vm_map_t; + addr :p_vm_offset_t; + phaddr :QWORD; + vaddr :QWORD; + length :QWORD; + mtype :DWORD; + prot :DWORD; + align :QWORD; + flags :DWORD; + stack_addr:Pointer):Integer; label _fixed, _rmap_insert; @@ -282,6 +284,12 @@ begin if (err=0) then begin + + if ((flags and MAP_NO_OVERWRITE)=0) then + begin + vm_map_delete(map, vaddr, v_end, True); + end; + vm_object_reference(dmap.vobj); err:=vm_map_insert(map, dmap.vobj, phaddr, vaddr, v_end, prot, VM_PROT_ALL, cow, ((p_proc.p_dmem_aliasing and 3)<>0)); @@ -368,6 +376,10 @@ var map:vm_map_t; addr:vm_offset_t; align:QWORD; + + rbp:PPointer; + rip:Pointer; + stack_addr:Pointer; begin td:=curkthread; if (td=nil) then Exit(Pointer(-1)); @@ -420,23 +432,48 @@ begin //Sanitizer end; + //backtrace + rbp:=Pointer(td^.td_frame.tf_rbp); + stack_addr:=nil; + + while (QWORD(rbp) < QWORD($800000000000)) do + begin + rip:=md_fuword(rbp[1]); + rbp:=md_fuword(rbp[0]); + + if (QWORD(rip)=QWORD(-1)) or + (QWORD(rbp)=QWORD(-1)) then + begin + Break; + end; + + if (p_proc.p_libkernel_start_addr > rip) or + (p_proc.p_libkernel___end_addr <= rip) then + begin + stack_addr:=rip; + Break; + end; + + end; + //backtrace + map:=p_proc.p_vmspace; if ((flags and MAP_FIXED)=0) then begin if (addr=0) then begin - if (p_proc.p_sce_replay_exec=0) then + if ( (QWORD(stack_addr) - QWORD($7f0000000)) < QWORD($800000000)) then begin - addr:=SCE_USR_HEAP_START; + addr:=SCE_SYS_HEAP_START; end else begin - addr:=SCE_REPLAY_EXEC_START; + addr:=SCE_USR_HEAP_START; end; end else - if (p_proc.p_sce_replay_exec<>0) and - (addrQWORD($7efffffff)) then + if ( (QWORD(stack_addr) - QWORD($7f0000000)) > QWORD($7ffffffff)) and + (addr < QWORD($ff0000001)) and + ( (length + addr) > QWORD($7efffffff)) then begin addr:=$ff0000000; end; @@ -469,9 +506,19 @@ begin mtype, prot or ((prot shr 1) and 1), align, - flags)); + flags, + stack_addr)); td^.td_retval[0]:=addr; + + Writeln('sys_mmap_dmem(','0x',HexStr(QWORD(vaddr),10), + ',0x',HexStr(length,10), + ',0x',HexStr(mtype,1), + ',0x',HexStr(prot,1), + ',0x',HexStr(flags,6), + ',0x',HexStr(phaddr,10), + '):',Integer(Result), + ':0x',HexStr(addr,10),'..0x',HexStr(addr+length,10)); end; function IN_CUSALIST_1:Boolean; @@ -700,6 +747,7 @@ begin Exit(EINVAL); end; + //backtrace rbp:=Pointer(td^.td_frame.tf_rbp); repeat @@ -710,8 +758,8 @@ begin Break; end; - rip:=fuword(rbp[1]); - rbp:=fuword(rbp[0]); + rip:=md_fuword(rbp[1]); + rbp:=md_fuword(rbp[0]); if (QWORD(rip)=QWORD(-1)) or (QWORD(rbp)=QWORD(-1)) then @@ -737,6 +785,7 @@ begin end; until false; + //backtrace vm_map_lock(map); diff --git a/sys/kern/kern_exec.pas b/sys/kern/kern_exec.pas index 90f6a90e..1e7dd729 100644 --- a/sys/kern/kern_exec.pas +++ b/sys/kern/kern_exec.pas @@ -1269,7 +1269,7 @@ begin ET_SCE_REPLAY_EXEC: begin - p_proc.p_sce_replay_exec:=1; + g_appinfo.mmap_flags:=g_appinfo.mmap_flags or 2; //is_system ??? end; ET_SCE_DYNEXEC: @@ -1688,10 +1688,6 @@ begin g_appinfo.AppId:=$60000100; 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; if (p_proc.p_budget_ptype=PTYPE_BIG_APP) then if ((g_appinfo.mmap_flags and 1)<>0) then diff --git a/sys/kern/kern_proc.pas b/sys/kern/kern_proc.pas index eeb20c97..9d43ed98 100644 --- a/sys/kern/kern_proc.pas +++ b/sys/kern/kern_proc.pas @@ -33,7 +33,6 @@ var p_osrel:Integer; p_sdk_version:Integer; - p_sce_replay_exec:Integer; p_sysent:p_sysentvec; diff --git a/sys/kern/kern_rtld.pas b/sys/kern/kern_rtld.pas index 261e95bf..7f51b8b0 100644 --- a/sys/kern/kern_rtld.pas +++ b/sys/kern/kern_rtld.pas @@ -620,12 +620,12 @@ var begin map:=p_proc.p_vmspace; - if (p_proc.p_sce_replay_exec<>0) then + if (addr^=0) and ((g_appinfo.mmap_flags and 2)<>0) then begin addr^:=SCE_REPLAY_EXEC_START; end; - Result:=vm_mmap2(map,addr,size,0,0,MAP_ANON or MAP_PRIVATE or (21 shl MAP_ALIGNMENT_BIT),OBJT_DEFAULT,nil,0); + Result:=vm_mmap2(map,addr,size,0,0,MAP_ANON or MAP_PRIVATE or (21 shl MAP_ALIGNMENT_BIT),OBJT_DEFAULT,nil,0,nil); end; procedure rtld_munmap(base:Pointer;size:QWORD); diff --git a/sys/kern/kern_stub.pas b/sys/kern/kern_stub.pas index 62e8cac1..74ff5171 100644 --- a/sys/kern/kern_stub.pas +++ b/sys/kern/kern_stub.pas @@ -126,7 +126,8 @@ begin MAP_ANON or MAP_PRIVATE, OBJT_DEFAULT, nil, - 0); + 0, + nil); if (err<>0) then Exit; diff --git a/sys/md/md_systm.pas b/sys/md/md_systm.pas index 7f9ebd62..b99de639 100644 --- a/sys/md/md_systm.pas +++ b/sys/md/md_systm.pas @@ -33,6 +33,8 @@ function md_copyout(hProcess:THandle;kaddr,udaddr:Pointer;len:ptruint;lencopied function md_copyin (udaddr,kaddr:Pointer;len:ptruint;lencopied:pptruint):Integer; function md_copyout(kaddr,udaddr:Pointer;len:ptruint;lencopied:pptruint):Integer; +function md_fuword(var base:Pointer):Pointer; + function md_getppid:DWORD; function md_pidfd_getfd(pidfd,targetfd:THandle):THandle; function md_pidfd_open (pid:DWORD):THandle; @@ -99,6 +101,14 @@ begin Result:=md_copyout(NtCurrentProcess,kaddr,udaddr,len,lencopied); end; +function md_fuword(var base:Pointer):Pointer; +begin + if (md_copyin(@base,@Result,SizeOf(base),nil)<>0) then + begin + Result:=Pointer(QWORD(-1)); + end; +end; + function md_getppid:DWORD; begin Result:=ppid; diff --git a/sys/vm/vm_mmap.pas b/sys/vm/vm_mmap.pas index ca44e08a..9aafa082 100644 --- a/sys/vm/vm_mmap.pas +++ b/sys/vm/vm_mmap.pas @@ -45,7 +45,8 @@ function vm_mmap2(map :vm_map_t; flags :Integer; handle_type:objtype_t; handle :Pointer; - foff :vm_ooffset_t):Integer; + foff :vm_ooffset_t; + stack_addr :Pointer):Integer; function mirror_map (paddr,psize:QWORD):Pointer; procedure mirror_unmap(base:Pointer;size:QWORD); @@ -54,6 +55,7 @@ implementation uses vcapability, + md_systm, systm, errno, kern_thr, @@ -64,6 +66,7 @@ uses kern_resource, kern_mtx, kern_descrip, + kern_authinfo, vmount, vstat, vfile, @@ -371,7 +374,8 @@ function vm_mmap2(map :vm_map_t; flags :Integer; handle_type:objtype_t; handle :Pointer; - foff :vm_ooffset_t):Integer; + foff :vm_ooffset_t; + stack_addr :Pointer):Integer; var obj:vm_object_t; docow,error,findspace,rv:Integer; @@ -536,6 +540,11 @@ begin Exit(vm_mmap_to_errno(rv)); end; +procedure vm_map_set_name_str(map:vm_map_t;start,__end:vm_offset_t;const name:RawByteString); inline; +begin + vm_map_set_name(map,start,__end,PChar(name)); +end; + function sys_mmap(vaddr:Pointer; vlen :QWORD; prot :Integer; @@ -557,6 +566,10 @@ var handle_type:obj_type; align:Integer; rights:cap_rights_t; + + rbp:PPointer; + rip:Pointer; + stack_addr:Pointer; begin td:=curkthread; if (td=nil) then Exit(Pointer(-1)); @@ -566,6 +579,31 @@ begin size:=vlen; prot:=prot and VM_PROT_ALL; + //backtrace + rbp:=Pointer(td^.td_frame.tf_rbp); + stack_addr:=nil; + + while (QWORD(rbp) < QWORD($800000000000)) do + begin + rip:=md_fuword(rbp[1]); + rbp:=md_fuword(rbp[0]); + + if (QWORD(rip)=QWORD(-1)) or + (QWORD(rbp)=QWORD(-1)) then + begin + Break; + end; + + if (p_proc.p_libkernel_start_addr > rip) or + (p_proc.p_libkernel___end_addr <= rip) then + begin + stack_addr:=rip; + Break; + end; + + end; + //backtrace + fp:=nil; if ((flags and MAP_SANITIZER)<>0) {and (devkit_parameter(0)=0)} then @@ -644,7 +682,7 @@ begin begin if (addr=0) then begin - if (p_proc.p_sce_replay_exec=0) then + if ((g_appinfo.mmap_flags and 2)=0) then begin addr:=SCE_USR_HEAP_START; end; @@ -652,6 +690,10 @@ begin if ((addr and QWORD($fffffffdffffffff))=0) then begin addr:=SCE_USR_HEAP_START; + end else + if (addr=QWORD($880000000)) then + begin + addr:=SCE_SYS_HEAP_START; end; end; @@ -801,11 +843,35 @@ _map: td^.td_fpop:=fp; maxprot:=maxprot and cap_maxprot; - Result:=Pointer(vm_mmap2(map,@addr,size,prot,maxprot,flags,handle_type,handle,pos)); + if (((flags and MAP_SANITIZER) <> 0) and (addr < QWORD($800000000000))) then + begin + if (QWORD($fc00000000) < (addr + size)) then + begin + prot:=prot and $cf; + end; + if ((addr shr 34) > 62) then + begin + prot:=prot and $cf; + end; + end; + + if (addr=0) and ((g_appinfo.mmap_flags and 2)<>0) then + begin + addr:=SCE_REPLAY_EXEC_START; + end; + + Result:=Pointer(vm_mmap2(map,@addr,size,prot,maxprot,flags,handle_type,handle,pos,stack_addr)); td^.td_fpop:=nil; td^.td_retval[0]:=(addr+pageoff); + if (Result=nil) then + if (stack_addr<>nil) then + begin + //Do you really need it? + vm_map_set_name_str(map,addr,size + addr,'anon:'+HexStr(QWORD(stack_addr),10)); + end; + Writeln('sys_mmap(','0x',HexStr(QWORD(vaddr),10), ',0x',HexStr(vlen,10), ',0x',HexStr(prot,1), diff --git a/sys/vm/vmparam.pas b/sys/vm/vmparam.pas index 836b374b..eb7797bd 100644 --- a/sys/vm/vmparam.pas +++ b/sys/vm/vmparam.pas @@ -53,8 +53,8 @@ const USRSTACK =QWORD($007EFFF8000); - SCE_USR_HEAP_START =QWORD($00200000000); - SCE_SYS_HEAP_START =QWORD($00880000000); + SCE_USR_HEAP_START =QWORD($00200000000); //(rng & 0xffc000) | 0x200000000 ... (rng & 0xffc000) | 0x6ff000000 + SCE_SYS_HEAP_START =QWORD($00880000000); //(rng & 0xffc000) | 0x880000000 .. (rng & 0xffc000) | 0x8ff000000 SCE_KERNEL_GNMDRIVER =QWORD($00FE0000000);