This commit is contained in:
Pavel 2024-11-01 21:35:54 +03:00
parent 1f697a5a8a
commit 2cca36d503
9 changed files with 156 additions and 35 deletions

View File

@ -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

View File

@ -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
(addr<QWORD($ff0000001)) and
((length+addr)>QWORD($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);

View File

@ -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

View File

@ -33,7 +33,6 @@ var
p_osrel:Integer;
p_sdk_version:Integer;
p_sce_replay_exec:Integer;
p_sysent:p_sysentvec;

View File

@ -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);

View File

@ -126,7 +126,8 @@ begin
MAP_ANON or MAP_PRIVATE,
OBJT_DEFAULT,
nil,
0);
0,
nil);
if (err<>0) then Exit;

View File

@ -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;

View File

@ -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),

View File

@ -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);