mirror of https://github.com/red-prig/fpPS4.git
127 lines
2.4 KiB
Plaintext
127 lines
2.4 KiB
Plaintext
unit vm_fault;
|
|
|
|
{$mode ObjFPC}{$H+}
|
|
{$CALLING SysV_ABI_CDecl}
|
|
|
|
interface
|
|
|
|
uses
|
|
kern_thr,
|
|
vm,
|
|
vmparam,
|
|
vm_map,
|
|
vm_pmap,
|
|
sys_vm_object;
|
|
|
|
function vm_fault(map :vm_map_t;
|
|
mem_addr :vm_offset_t;
|
|
rip_addr :vm_offset_t;
|
|
fault_type :vm_prot_t;
|
|
fault_flags:Integer):Integer;
|
|
|
|
implementation
|
|
|
|
uses
|
|
systm,
|
|
trap,
|
|
x86_fpdbgdisas,
|
|
kern_stub,
|
|
vm_patch_link;
|
|
|
|
function vm_check_patch_entry(map:vm_map_t;vaddr:vm_offset_t;p_entry:p_vm_map_entry_t):Boolean;
|
|
var
|
|
entry:vm_map_entry_t;
|
|
begin
|
|
if (vm_map_lookup_entry(map,vaddr,@entry)) then
|
|
begin
|
|
p_entry^:=entry;
|
|
Result:=(entry^.inheritance=VM_INHERIT_PATCH);
|
|
end else
|
|
begin
|
|
p_entry^:=nil;
|
|
Result:=True;
|
|
end;
|
|
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;
|
|
|
|
function AlignDw(addr:PtrUInt;alignment:PtrUInt):PtrUInt; inline;
|
|
begin
|
|
Result:=addr-(addr mod alignment);
|
|
end;
|
|
|
|
function vm_fault(map :vm_map_t;
|
|
mem_addr :vm_offset_t;
|
|
rip_addr :vm_offset_t;
|
|
fault_type :vm_prot_t;
|
|
fault_flags:Integer):Integer;
|
|
label
|
|
RetryFault;
|
|
var
|
|
growstack:Boolean;
|
|
entry:vm_map_entry_t;
|
|
obj:vm_object_t;
|
|
pindex:vm_pindex_t;
|
|
prot:vm_prot_t;
|
|
begin
|
|
growstack:=true;
|
|
|
|
RetryFault:
|
|
|
|
Result:=vm_map_lookup(@map,
|
|
mem_addr,
|
|
fault_type,
|
|
@entry,
|
|
@obj,
|
|
@pindex,
|
|
@prot);
|
|
|
|
if (Result<>KERN_SUCCESS) then
|
|
begin
|
|
if growstack and
|
|
(Result=KERN_INVALID_ADDRESS) then
|
|
begin
|
|
Result:=vm_map_growstack(map, mem_addr);
|
|
if (Result<>KERN_SUCCESS) then
|
|
begin
|
|
Exit(KERN_FAILURE);
|
|
end;
|
|
growstack:=false;
|
|
goto RetryFault;
|
|
end;
|
|
Exit();
|
|
end;
|
|
|
|
if ((entry^.eflags and MAP_ENTRY_NOFAULT)<>0) then
|
|
begin
|
|
if ((curkthread^.td_pflags and TDP_DEVMEMIO)<>0) then
|
|
begin
|
|
vm_map_lookup_done(map,entry);
|
|
Exit(KERN_FAILURE);
|
|
end;
|
|
Assert(false,'vm_fault: fault on nofault entry 0x'+HexStr(mem_addr,16));
|
|
end;
|
|
|
|
//Next, various actions with a vm map
|
|
|
|
if (Result=KERN_SUCCESS) then
|
|
if is_guest_addr(rip_addr) then
|
|
begin
|
|
//Result:=vm_try_jit_patch(map,mem_addr,rip_addr);
|
|
end;
|
|
|
|
vm_map_lookup_done(map,entry);
|
|
end;
|
|
|
|
|
|
|
|
end.
|
|
|