FPPS4/sys/md/vm_pmap_prot.pas

245 lines
4.6 KiB
Plaintext

unit vm_pmap_prot;
{$mode ObjFPC}{$H+}
{$CALLING SysV_ABI_CDecl}
interface
uses
atomic,
vm,
vmparam,
md_map;
const
PMAPP_SHIFT=MD_PAGE_SHIFT; //12;
PMAPP_SIZE =MD_PAGE_SIZE; //1 shl PMAPP_SHIFT; //4*1024
PMAPP_MASK =MD_PAGE_MASK; //PMAPP_SIZE-1;
PAGE_MAP_COUNT =(QWORD(VM_MAXUSER_ADDRESS) shr PMAPP_SHIFT);
PAGE_MAP_MASK =PAGE_MAP_COUNT-1;
PAGE_PROT_READ =VM_PROT_READ;
PAGE_PROT_WRITE =VM_PROT_WRITE;
PAGE_PROT_EXECUTE=VM_PROT_EXECUTE;
PAGE_PROT_RW =PAGE_PROT_READ or PAGE_PROT_WRITE;
PAGE_PROT_RWX =PAGE_PROT_READ or PAGE_PROT_WRITE or PAGE_PROT_EXECUTE;
PAGE_TRACK_R =$08;
PAGE_TRACK_W =$10;
PAGE_TRACK_X =$20;
PAGE_TRACK_RWX =PAGE_TRACK_R or PAGE_TRACK_W or PAGE_TRACK_X;
PAGE_TRACK_SHIFT =3;
TRACK_PROT=1; //Take tracking bits into account
REMAP_PROT=2; //Ignore protect bit checking
var
PAGE_PROT:PBYTE=nil;
procedure ppmap_mark_rwx (start,__end:vm_offset_t;prots:Byte);
procedure ppmap_unmark (start,__end:vm_offset_t);
procedure ppmap_unmark_rwx(start,__end:vm_offset_t);
procedure ppmap_track (start,__end:vm_offset_t;prots:Byte);
//procedure ppmap_untrack (start,__end:vm_offset_t;prots:Byte);
function ppmap_scan (start,__end:vm_offset_t):vm_offset_t;
function ppmap_scan_rwx (start,__end:vm_offset_t):vm_offset_t;
function ppmap_get_prot (addr:vm_offset_t):Byte;
function ppmap_get_prot (addr,size:vm_offset_t):Byte;
implementation
//PAGE_MAP
function IDX_TO_OFF(x:DWORD):QWORD; inline;
begin
Result:=QWORD(x) shl PMAPP_SHIFT;
end;
function OFF_TO_IDX(x:QWORD):DWORD; inline;
begin
Result:=QWORD(x) shr PMAPP_SHIFT;
end;
function MAX_IDX(x:DWORD):DWORD; inline;
begin
if (x>PAGE_MAP_MASK) then
Result:=PAGE_MAP_MASK
else
Result:=x;
end;
procedure ppmap_mark_rwx(start,__end:vm_offset_t;prots:Byte);
var
clear:Byte;
begin
prots:=prots and PAGE_PROT_RWX;
clear:=(not prots) and PAGE_PROT_RWX;
start:=OFF_TO_IDX(start);
__end:=OFF_TO_IDX(__end);
start:=MAX_IDX(start);
__end:=MAX_IDX(__end);
while (start<__end) do
begin
atomic_clear_byte(@PAGE_PROT[start],clear);
atomic_set_byte (@PAGE_PROT[start],prots);
//PAGE_PROT[start]:=prots;
Inc(start);
end;
WriteBarrier;
end;
procedure ppmap_unmark(start,__end:vm_offset_t);
begin
start:=OFF_TO_IDX(start);
__end:=OFF_TO_IDX(__end);
start:=MAX_IDX(start);
__end:=MAX_IDX(__end);
while (start<__end) do
begin
//PAGE_PROT[start]:=0;
Inc(start);
end;
WriteBarrier;
end;
procedure ppmap_unmark_rwx(start,__end:vm_offset_t);
begin
start:=OFF_TO_IDX(start);
__end:=OFF_TO_IDX(__end);
start:=MAX_IDX(start);
__end:=MAX_IDX(__end);
while (start<__end) do
begin
atomic_clear_byte(@PAGE_PROT[start],PAGE_PROT_RWX);
Inc(start);
end;
WriteBarrier;
end;
procedure ppmap_track(start,__end:vm_offset_t;prots:Byte);
var
s_prots:Byte;
c_prots:Byte;
begin
s_prots:=prots and PAGE_TRACK_RWX;
c_prots:=(not prots) and PAGE_TRACK_RWX;
start:=OFF_TO_IDX(start);
__end:=OFF_TO_IDX(__end);
start:=MAX_IDX(start);
__end:=MAX_IDX(__end);
while (start<__end) do
begin
atomic_set_byte (@PAGE_PROT[start],s_prots);
atomic_clear_byte(@PAGE_PROT[start],c_prots);
Inc(start);
end;
WriteBarrier;
end;
{
procedure ppmap_untrack(start,__end:vm_offset_t;prots:Byte);
begin
prots:=prots and PAGE_TRACK_RWX;
start:=OFF_TO_IDX(start);
__end:=OFF_TO_IDX(__end);
start:=MAX_IDX(start);
__end:=MAX_IDX(__end);
while (start<__end) do
begin
atomic_clear_byte(@PAGE_PROT[start],prots);
Inc(start);
end;
WriteBarrier;
end;
}
function ppmap_scan(start,__end:vm_offset_t):vm_offset_t;
var
b,v:Byte;
begin
start:=OFF_TO_IDX(start);
__end:=OFF_TO_IDX(__end);
start:=MAX_IDX(start);
__end:=MAX_IDX(__end);
ReadBarrier;
b:=PAGE_PROT[start];
Inc(start);
while (start<__end) do
begin
v:=PAGE_PROT[start];
if (b<>v) then
begin
start:=IDX_TO_OFF(start);
Exit(start);
end;
Inc(start);
end;
__end:=IDX_TO_OFF(__end);
Result:=__end;
end;
function ppmap_scan_rwx(start,__end:vm_offset_t):vm_offset_t;
var
b,v:Byte;
begin
start:=OFF_TO_IDX(start);
__end:=OFF_TO_IDX(__end);
start:=MAX_IDX(start);
__end:=MAX_IDX(__end);
ReadBarrier;
b:=(PAGE_PROT[start] and PAGE_PROT_RWX);
Inc(start);
while (start<__end) do
begin
v:=(PAGE_PROT[start] and PAGE_PROT_RWX);
if (b<>v) then
begin
start:=IDX_TO_OFF(start);
Exit(start);
end;
Inc(start);
end;
__end:=IDX_TO_OFF(__end);
Result:=__end;
end;
function ppmap_get_prot(addr:vm_offset_t):Byte;
begin
addr:=OFF_TO_IDX(addr);
if (addr>PAGE_MAP_MASK) then
begin
Result:=0
end else
begin
Result:=PAGE_PROT[addr];
end;
end;
function ppmap_get_prot(addr,size:vm_offset_t):Byte;
begin
Result:=ppmap_get_prot(addr) or ppmap_get_prot(addr+size);
end;
end.