mirror of https://github.com/red-prig/fpPS4.git
This commit is contained in:
parent
3d30b3cc6e
commit
751c9bf520
|
@ -1558,6 +1558,10 @@
|
|||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="ps4_libSceNpGameIntent"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="sys\vm\vm_nt_sub_map.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
|
|
|
@ -14,7 +14,7 @@ const
|
|||
MD_PAGE_SHIFT = 12;
|
||||
MD_PAGE_SIZE = 4*1024;
|
||||
MD_PAGE_MASK = MD_PAGE_SIZE-1;
|
||||
MD_ALLOC_GRANULARITY=64*1024;
|
||||
MD_ALLOC_GRANULARITY= 64*1024;
|
||||
|
||||
const
|
||||
VM_RW =VM_PROT_READ or VM_PROT_WRITE;
|
||||
|
|
|
@ -98,22 +98,10 @@ procedure pmap_protect(pmap :pmap_t;
|
|||
__end :vm_offset_t;
|
||||
prot :vm_prot_t);
|
||||
|
||||
{
|
||||
procedure _pmap_prot_fix(pmap :pmap_t;
|
||||
start:vm_offset_t;
|
||||
__end:vm_offset_t;
|
||||
mode :Integer);
|
||||
|
||||
procedure _pmap_prot_int(pmap :pmap_t;
|
||||
start:vm_offset_t;
|
||||
__end:vm_offset_t;
|
||||
prot :vm_prot_t);
|
||||
}
|
||||
|
||||
procedure pmap_prot_track(pmap :pmap_t;
|
||||
start:vm_offset_t;
|
||||
__end:vm_offset_t;
|
||||
prots:Byte);
|
||||
prot :Byte);
|
||||
|
||||
procedure pmap_prot_restore(pmap :pmap_t;
|
||||
start:vm_offset_t;
|
||||
|
@ -1009,15 +997,10 @@ begin
|
|||
begin
|
||||
_default:
|
||||
|
||||
vm_nt_map_prot_fix(@pmap^.nt_map,
|
||||
start,
|
||||
__end,
|
||||
TRACK_PROT or REMAP_PROT);
|
||||
|
||||
//vm_nt_map_protect(@pmap^.nt_map,
|
||||
// start,
|
||||
// __end,
|
||||
// (prot and VM_RW));
|
||||
vm_nt_map_protect(@pmap^.nt_map,
|
||||
start,
|
||||
__end,
|
||||
(prot and VM_RW));
|
||||
|
||||
end;
|
||||
OBJT_DEVICE:
|
||||
|
@ -1054,58 +1037,34 @@ begin
|
|||
pmap_unlock(pmap,lock);
|
||||
end;
|
||||
|
||||
procedure _pmap_prot_fix(pmap :pmap_t;
|
||||
start:vm_offset_t;
|
||||
__end:vm_offset_t;
|
||||
mode :Integer);
|
||||
begin
|
||||
start:=start and (not PMAPP_MASK);
|
||||
__end:=(__end+PMAPP_MASK) and (not PMAPP_MASK);
|
||||
|
||||
vm_nt_map_prot_fix(@pmap^.nt_map,
|
||||
start,
|
||||
__end,
|
||||
mode);
|
||||
end;
|
||||
|
||||
procedure _pmap_prot_int(pmap :pmap_t;
|
||||
start:vm_offset_t;
|
||||
__end:vm_offset_t;
|
||||
prot :vm_prot_t);
|
||||
begin
|
||||
start:=start and (not PMAPP_MASK);
|
||||
__end:=(__end+PMAPP_MASK) and (not PMAPP_MASK);
|
||||
|
||||
vm_nt_map_protect(@pmap^.nt_map,
|
||||
start,
|
||||
__end,
|
||||
(prot and VM_RW));
|
||||
end;
|
||||
|
||||
procedure pmap_prot_track(pmap :pmap_t;
|
||||
start:vm_offset_t;
|
||||
__end:vm_offset_t;
|
||||
prots:Byte); public;
|
||||
prot :Byte); public;
|
||||
begin
|
||||
if (p_print_pmap) then
|
||||
begin
|
||||
Writeln('pmap_prot_track:',HexStr(start,11),':',HexStr(__end,11),':',HexStr(prots,2));
|
||||
Writeln('pmap_prot_track:',HexStr(start,11),':',HexStr(__end,11),':',HexStr(prot,2));
|
||||
end;
|
||||
|
||||
start:=start and (not PMAPP_MASK);
|
||||
__end:=(__end+PMAPP_MASK) and (not PMAPP_MASK);
|
||||
|
||||
ppmap_track(start,__end,prots);
|
||||
//Don't do range lock here!
|
||||
|
||||
vm_nt_map_prot_fix(@pmap^.nt_map,
|
||||
ppmap_track(start,__end,prot);
|
||||
|
||||
vm_nt_map_tracking(@pmap^.nt_map,
|
||||
start,
|
||||
__end,
|
||||
TRACK_PROT or REMAP_PROT);
|
||||
prot);
|
||||
end;
|
||||
|
||||
procedure pmap_prot_restore(pmap :pmap_t;
|
||||
start:vm_offset_t;
|
||||
__end:vm_offset_t);
|
||||
var
|
||||
lock:Pointer;
|
||||
begin
|
||||
if (p_print_pmap) then
|
||||
begin
|
||||
|
@ -1115,10 +1074,14 @@ begin
|
|||
start:=start and (not PMAPP_MASK);
|
||||
__end:=(__end+PMAPP_MASK) and (not PMAPP_MASK);
|
||||
|
||||
lock:=pmap_wlock(pmap,start,__end);
|
||||
|
||||
vm_nt_map_prot_fix(@pmap^.nt_map,
|
||||
start,
|
||||
__end,
|
||||
REMAP_PROT);
|
||||
|
||||
pmap_unlock(pmap,lock);
|
||||
end;
|
||||
|
||||
procedure pmap_madvise(pmap :pmap_t;
|
||||
|
|
|
@ -9,7 +9,8 @@ uses
|
|||
sysutils,
|
||||
vm,
|
||||
kern_mtx,
|
||||
vm_pmap_prot;
|
||||
vm_pmap_prot,
|
||||
vm_nt_sub_map;
|
||||
|
||||
const
|
||||
NT_FILE_FREE=1;
|
||||
|
@ -44,30 +45,31 @@ type
|
|||
maxp :Byte;
|
||||
end;
|
||||
|
||||
///
|
||||
|
||||
pp_vm_nt_entry=^p_vm_nt_entry;
|
||||
p_vm_nt_entry=^vm_nt_entry;
|
||||
vm_nt_entry=packed record
|
||||
prev :p_vm_nt_entry; // previous entry
|
||||
next :p_vm_nt_entry; // next entry
|
||||
left :p_vm_nt_entry; // left child in binary search tree
|
||||
right :p_vm_nt_entry; // right child in binary search tree
|
||||
start :vm_offset_t; // start address
|
||||
__end :vm_offset_t; // end address
|
||||
size :vm_offset_t; // unaligned size
|
||||
obj :p_vm_nt_file_obj; // object I point to
|
||||
offset :vm_ooffset_t; // offset into object
|
||||
vm_nt_entry=packed object
|
||||
prev :p_vm_nt_entry; // previous entry
|
||||
next :p_vm_nt_entry; // next entry
|
||||
left :p_vm_nt_entry; // left child in binary search tree
|
||||
right :p_vm_nt_entry; // right child in binary search tree
|
||||
usize :vm_offset_t; // unaligned size
|
||||
offset:vm_ooffset_t; // offset into object
|
||||
obj :p_vm_nt_file_obj; // object I point to
|
||||
sub :t_vm_nt_sub_map;
|
||||
property start:vm_offset_t read sub.header.start write sub.header.start; // start address
|
||||
property __end:vm_offset_t read sub.header.__end write sub.header.__end; // end address
|
||||
end;
|
||||
|
||||
p_vm_nt_map=^t_vm_nt_map;
|
||||
t_vm_nt_map=object
|
||||
header :vm_nt_entry; // List of entries
|
||||
size :vm_size_t; // virtual size
|
||||
nentries :Integer; // Number of entries
|
||||
lock :mtx; // Lock for map data
|
||||
root :p_vm_nt_entry; // Root of a binary search tree
|
||||
danger_zone:t_danger_zone;
|
||||
lock :mtx;
|
||||
property min_offset:vm_offset_t read header.start write header.start;
|
||||
property max_offset:vm_offset_t read header.__end write header.__end;
|
||||
property min_offset:vm_offset_t read header.sub.header.start write header.sub.header.start;
|
||||
property max_offset:vm_offset_t read header.sub.header.__end write header.sub.header.__end;
|
||||
end;
|
||||
|
||||
function vm_nt_file_obj_allocate (hfile:THandle;maxp:Byte):p_vm_nt_file_obj;
|
||||
|
@ -86,27 +88,36 @@ function vm_nt_map_insert(
|
|||
offset:vm_ooffset_t;
|
||||
start :vm_offset_t;
|
||||
__end :vm_offset_t;
|
||||
size :vm_offset_t;
|
||||
usize :vm_offset_t;
|
||||
prot :Integer):Integer;
|
||||
|
||||
function vm_nt_map_delete(map:p_vm_nt_map;start:vm_offset_t;__end:vm_offset_t):Integer;
|
||||
|
||||
procedure vm_nt_map_protect(map:p_vm_nt_map;
|
||||
//Change protection taking into account tracking
|
||||
procedure vm_nt_map_protect(map :p_vm_nt_map;
|
||||
start:vm_offset_t;
|
||||
__end:vm_offset_t;
|
||||
prot :Integer);
|
||||
prot :Integer);
|
||||
|
||||
procedure vm_nt_map_prot_fix(map:p_vm_nt_map;
|
||||
//Change protection tracking
|
||||
procedure vm_nt_map_tracking(map :p_vm_nt_map;
|
||||
start:vm_offset_t;
|
||||
__end:vm_offset_t;
|
||||
prot :Integer);
|
||||
|
||||
//Update page protection by mode
|
||||
procedure vm_nt_map_prot_fix(map :p_vm_nt_map;
|
||||
start:vm_offset_t;
|
||||
__end:vm_offset_t;
|
||||
mode :Integer);
|
||||
|
||||
procedure vm_nt_map_madvise(map:p_vm_nt_map;
|
||||
start:vm_offset_t;
|
||||
__end:vm_offset_t;
|
||||
procedure vm_nt_map_madvise(map :p_vm_nt_map;
|
||||
start :vm_offset_t;
|
||||
__end :vm_offset_t;
|
||||
advise:Integer);
|
||||
|
||||
function vm_nt_map_mirror(map:p_vm_nt_map;
|
||||
//Create a memory mirror of the current state of the pages
|
||||
function vm_nt_map_mirror(map :p_vm_nt_map;
|
||||
start:vm_offset_t;
|
||||
__end:vm_offset_t):Pointer;
|
||||
|
||||
|
@ -191,60 +202,6 @@ end;
|
|||
|
||||
//
|
||||
|
||||
procedure vm_prot_fixup(map:p_vm_nt_map;
|
||||
start:vm_offset_t;
|
||||
__end:vm_offset_t;
|
||||
max :Integer;
|
||||
mode :Integer);
|
||||
var
|
||||
next:vm_offset_t;
|
||||
base,size:vm_size_t;
|
||||
prot:Integer;
|
||||
mask:Integer;
|
||||
r:Integer;
|
||||
begin
|
||||
if (PAGE_PROT=nil) then Exit;
|
||||
if (start=__end) then Exit;
|
||||
|
||||
while (start<__end) do
|
||||
begin
|
||||
if ((mode and TRACK_PROT)=0) then
|
||||
begin
|
||||
next:=ppmap_scan_rwx(start,__end);
|
||||
|
||||
prot:=ppmap_get_prot(start);
|
||||
|
||||
prot:=(prot and VM_RW);
|
||||
end else
|
||||
begin
|
||||
next:=ppmap_scan(start,__end);
|
||||
|
||||
prot:=ppmap_get_prot(start);
|
||||
|
||||
mask:=not (prot shr PAGE_TRACK_SHIFT);
|
||||
|
||||
prot:=(prot and VM_RW) and mask;
|
||||
end;
|
||||
|
||||
base:=start;
|
||||
size:=next-start;
|
||||
|
||||
if ((mode and REMAP_PROT)<>0) or (prot<>(max and VM_RW)) then
|
||||
begin
|
||||
r:=md_protect(Pointer(base),size,prot);
|
||||
if (r<>0) then
|
||||
begin
|
||||
Writeln('failed md_protect(',HexStr(base,11),',',HexStr(base+size,11),'):0x',HexStr(r,8));
|
||||
Assert(false,'vm_prot_fixup');
|
||||
end;
|
||||
end;
|
||||
|
||||
start:=next;
|
||||
end;
|
||||
end;
|
||||
|
||||
//
|
||||
|
||||
procedure vm_init_stat(var stat:t_range_stat;entry:p_vm_nt_entry); inline;
|
||||
begin
|
||||
stat:=Default(t_range_stat);
|
||||
|
@ -313,7 +270,7 @@ begin
|
|||
r:=md_file_mmap_ex(entry^.obj^.hfile,
|
||||
Pointer(entry^.start),
|
||||
entry^.offset,
|
||||
entry^.size, //unaligned size
|
||||
entry^.usize, //unaligned size
|
||||
(max and VM_RW));
|
||||
if (r<>0) then
|
||||
begin
|
||||
|
@ -562,7 +519,7 @@ begin
|
|||
r:=md_file_mmap_ex(stat.obj^.hfile,
|
||||
Pointer(ets[i]^.start),
|
||||
ets[i]^.offset,
|
||||
ets[i]^.size, //unaligned size
|
||||
ets[i]^.usize, //unaligned size
|
||||
(max and VM_RW));
|
||||
if (r<>0) then
|
||||
begin
|
||||
|
@ -584,12 +541,11 @@ begin
|
|||
if (ets[i]^.obj<>nil) then
|
||||
if (stat.obj^.hfile<>0) then
|
||||
begin
|
||||
vm_prot_fixup(map,
|
||||
ets[i]^.start,
|
||||
ets[i]^.__end,
|
||||
max,
|
||||
TRACK_PROT or REMAP_PROT //untrack trigger or restore track?
|
||||
);
|
||||
vm_nt_sub_map_prot_fixup(@ets[i]^.sub,
|
||||
ets[i]^.start,
|
||||
ets[i]^.__end,
|
||||
TRACK_PROT or REMAP_PROT //untrack trigger or restore track?
|
||||
);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
@ -690,6 +646,13 @@ begin
|
|||
FreeMem(entry);
|
||||
end;
|
||||
|
||||
procedure vm_nt_entry_deallocate(map:p_vm_nt_map;entry:p_vm_nt_entry); inline;
|
||||
begin
|
||||
vm_nt_sub_map_free (@entry^.sub);
|
||||
vm_nt_file_obj_deallocate(entry^.obj);
|
||||
vm_nt_entry_dispose (map,entry);
|
||||
end;
|
||||
|
||||
function vm_nt_entry_create(map:p_vm_nt_map):p_vm_nt_entry;
|
||||
var
|
||||
new_entry:p_vm_nt_entry;
|
||||
|
@ -779,7 +742,6 @@ procedure vm_nt_entry_link(
|
|||
after_where:p_vm_nt_entry;
|
||||
entry :p_vm_nt_entry);
|
||||
begin
|
||||
Inc(map^.nentries);
|
||||
entry^.prev:=after_where;
|
||||
entry^.next:=after_where^.next;
|
||||
entry^.next^.prev:=entry;
|
||||
|
@ -826,7 +788,6 @@ begin
|
|||
next:=entry^.next;
|
||||
next^.prev:=prev;
|
||||
prev^.next:=next;
|
||||
Dec(map^.nentries);
|
||||
end;
|
||||
|
||||
function vm_nt_map_lookup_entry(
|
||||
|
@ -874,7 +835,7 @@ function _vm_nt_map_insert(
|
|||
offset:vm_ooffset_t;
|
||||
start :vm_offset_t;
|
||||
__end :vm_offset_t;
|
||||
size :vm_offset_t; //unaligned size
|
||||
usize :vm_offset_t; //unaligned size
|
||||
prot :Integer):Integer;
|
||||
var
|
||||
new_entry :p_vm_nt_entry;
|
||||
|
@ -903,12 +864,16 @@ begin
|
|||
new_entry:=vm_nt_entry_create(map);
|
||||
new_entry^.start :=start;
|
||||
new_entry^.__end :=__end;
|
||||
new_entry^.size :=size; //unaligned size
|
||||
new_entry^.usize :=usize; //unaligned size
|
||||
new_entry^.obj :=obj;
|
||||
new_entry^.offset:=offset;
|
||||
|
||||
vm_nt_sub_map_init (@new_entry^.sub,start,__end);
|
||||
|
||||
//fill full map
|
||||
vm_nt_sub_map_insert(@new_entry^.sub,start,__end,prot);
|
||||
|
||||
vm_nt_entry_link(map, prev_entry, new_entry);
|
||||
map^.size:=map^.size+(new_entry^.__end - new_entry^.start);
|
||||
|
||||
vm_map(map,new_entry,prot);
|
||||
|
||||
|
@ -925,7 +890,7 @@ function vm_nt_map_insert(
|
|||
offset:vm_ooffset_t;
|
||||
start :vm_offset_t;
|
||||
__end :vm_offset_t;
|
||||
size :vm_offset_t; //unaligned size
|
||||
usize :vm_offset_t; //unaligned size
|
||||
prot :Integer):Integer;
|
||||
begin
|
||||
if (start=__end) then
|
||||
|
@ -941,7 +906,7 @@ begin
|
|||
offset,
|
||||
start ,
|
||||
__end ,
|
||||
size ,
|
||||
usize ,
|
||||
prot );
|
||||
|
||||
vm_nt_map_unlock(map);
|
||||
|
@ -985,10 +950,15 @@ begin
|
|||
|
||||
entry^.start :=prev^.start;
|
||||
entry^.offset:=prev^.offset;
|
||||
entry^.size :=entry^.size+prev^.size; //unaligned size
|
||||
entry^.usize :=entry^.usize+prev^.usize; //unaligned size
|
||||
|
||||
vm_nt_file_obj_deallocate(prev^.obj);
|
||||
vm_nt_entry_dispose(map, prev);
|
||||
//update (implicitly)
|
||||
//entry^.sub.min_offset:=entry^.start;
|
||||
|
||||
//move
|
||||
vm_nt_sub_map_move(@entry^.sub,@prev^.sub);
|
||||
|
||||
vm_nt_entry_deallocate(map,prev);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -1002,18 +972,21 @@ begin
|
|||
((stat.obj=nil) or (entry^.offset + esize=next^.offset))
|
||||
then
|
||||
begin
|
||||
begin
|
||||
vm_nt_entry_unlink(map, next);
|
||||
vm_nt_entry_unlink(map, next);
|
||||
|
||||
stat.rnext.start:=next^.start;
|
||||
stat.rnext.__end:=next^.__end;
|
||||
stat.rnext.start:=next^.start;
|
||||
stat.rnext.__end:=next^.__end;
|
||||
|
||||
entry^.__end:=next^.__end;
|
||||
entry^.size :=entry^.size+next^.size; //unaligned size
|
||||
entry^.__end:=next^.__end;
|
||||
entry^.usize:=entry^.usize+next^.usize; //unaligned size
|
||||
|
||||
vm_nt_file_obj_deallocate(next^.obj);
|
||||
vm_nt_entry_dispose(map, next);
|
||||
end;
|
||||
//update (implicitly)
|
||||
//entry^.sub.max_offset:=entry^.__end;
|
||||
|
||||
//move
|
||||
vm_nt_sub_map_move(@entry^.sub,@next^.sub);
|
||||
|
||||
vm_nt_entry_deallocate(map,next);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -1047,11 +1020,21 @@ begin
|
|||
prev^:=entry^;
|
||||
|
||||
prev^.__end:=start;
|
||||
prev^.size :=(prev^.__end-prev^.start); //unaligned size
|
||||
prev^.usize:=(prev^.__end-prev^.start); //unaligned size
|
||||
|
||||
entry^.offset:=entry^.offset + (start - entry^.start);
|
||||
entry^.start :=start;
|
||||
entry^.size :=entry^.size-prev^.size; //unaligned size
|
||||
entry^.usize :=entry^.usize-prev^.usize; //unaligned size
|
||||
|
||||
//update (implicitly)
|
||||
//prev ^.sub.max_offset:=start;
|
||||
//entry^.sub.min_offset:=start;
|
||||
|
||||
//new map
|
||||
vm_nt_sub_map_init(@prev^.sub,prev^.start,prev^.__end);
|
||||
|
||||
//move
|
||||
vm_nt_sub_map_move(@prev^.sub,@entry^.sub);
|
||||
|
||||
vm_nt_entry_link(map, entry^.prev, prev);
|
||||
vm_nt_file_obj_reference(prev^.obj);
|
||||
|
@ -1065,10 +1048,20 @@ begin
|
|||
next^.start :=__end;
|
||||
|
||||
entry^.__end:=__end;
|
||||
entry^.size :=(entry^.__end-entry^.start); //unaligned size
|
||||
entry^.usize:=(entry^.__end-entry^.start); //unaligned size
|
||||
|
||||
next^.offset:=next^.offset + (__end - entry^.start);
|
||||
next^.size :=next^.size-entry^.size; //unaligned size
|
||||
next^.usize :=next^.usize-entry^.usize; //unaligned size
|
||||
|
||||
//update (implicitly)
|
||||
//next ^.sub.min_offset:=__end;
|
||||
//entry^.sub.max_offset:=__end;
|
||||
|
||||
//new map
|
||||
vm_nt_sub_map_init(@next^.sub,next^.start,next^.__end);
|
||||
|
||||
//move
|
||||
vm_nt_sub_map_move(@next^.sub,@entry^.sub);
|
||||
|
||||
vm_nt_entry_link(map, entry, next);
|
||||
vm_nt_file_obj_reference(next^.obj);
|
||||
|
@ -1106,10 +1099,20 @@ begin
|
|||
next^.start :=__end;
|
||||
|
||||
entry^.__end:=__end;
|
||||
entry^.size :=(entry^.__end-entry^.size); //unaligned size
|
||||
entry^.usize:=(entry^.__end-entry^.usize); //unaligned size
|
||||
|
||||
next^.offset:=next^.offset + (__end - entry^.start);
|
||||
next^.size :=next^.size-entry^.size; //unaligned size
|
||||
next^.usize :=next^.usize-entry^.usize; //unaligned size
|
||||
|
||||
//update (implicitly)
|
||||
//next ^.sub.min_offset:=__end;
|
||||
//entry^.sub.max_offset:=__end;
|
||||
|
||||
//new map
|
||||
vm_nt_sub_map_init(@next^.sub,next^.start,next^.__end);
|
||||
|
||||
//move
|
||||
vm_nt_sub_map_move(@next^.sub,@entry^.sub);
|
||||
|
||||
vm_nt_entry_link(map, entry, next);
|
||||
vm_nt_file_obj_reference(next^.obj);
|
||||
|
@ -1128,22 +1131,10 @@ begin
|
|||
|
||||
end;
|
||||
|
||||
procedure vm_nt_entry_deallocate(entry:p_vm_nt_entry);
|
||||
procedure vm_nt_entry_delete(map:p_vm_nt_map;entry:p_vm_nt_entry); inline;
|
||||
begin
|
||||
vm_nt_file_obj_deallocate(entry^.obj);
|
||||
Freemem(entry);
|
||||
end;
|
||||
|
||||
procedure vm_nt_entry_delete(map:p_vm_nt_map;entry:p_vm_nt_entry);
|
||||
var
|
||||
size:vm_ooffset_t;
|
||||
begin
|
||||
vm_nt_entry_unlink(map, entry);
|
||||
|
||||
size:=entry^.__end - entry^.start;
|
||||
map^.size:=map^.size-size;
|
||||
|
||||
vm_nt_entry_deallocate(entry);
|
||||
vm_nt_entry_unlink (map, entry);
|
||||
vm_nt_entry_deallocate(map, entry);
|
||||
end;
|
||||
|
||||
function vm_nt_map_delete(map:p_vm_nt_map;start:vm_offset_t;__end:vm_offset_t):Integer;
|
||||
|
@ -1189,16 +1180,15 @@ begin
|
|||
Result:=(KERN_SUCCESS);
|
||||
end;
|
||||
|
||||
procedure vm_nt_map_protect(map:p_vm_nt_map;
|
||||
procedure vm_nt_map_protect(map :p_vm_nt_map;
|
||||
start:vm_offset_t;
|
||||
__end:vm_offset_t;
|
||||
prot :Integer);
|
||||
prot :Integer);
|
||||
var
|
||||
entry:p_vm_nt_entry;
|
||||
e_start:vm_offset_t;
|
||||
e___end:vm_offset_t;
|
||||
max:Integer;
|
||||
r:Integer;
|
||||
begin
|
||||
if (start=__end) then Exit;
|
||||
|
||||
|
@ -1209,7 +1199,7 @@ begin
|
|||
entry:=entry^.next;
|
||||
end else
|
||||
begin
|
||||
entry:=entry;
|
||||
//
|
||||
end;
|
||||
|
||||
while (entry<>@map^.header) and (entry^.start<__end) do
|
||||
|
@ -1238,13 +1228,7 @@ begin
|
|||
max:=0;
|
||||
end;
|
||||
|
||||
r:=md_protect(Pointer(e_start),e___end-e_start,(prot and max and VM_RW));
|
||||
if (r<>0) then
|
||||
begin
|
||||
Writeln('failed md_protect(',HexStr(e_start,11),',',HexStr(e___end,11),'):0x',HexStr(r,8));
|
||||
Assert(false,'vm_nt_map_protect');
|
||||
end;
|
||||
|
||||
vm_nt_sub_map_protect(@entry^.sub,e_start,e___end,(prot and max and VM_RW));
|
||||
end;
|
||||
|
||||
entry:=entry^.next;
|
||||
|
@ -1253,7 +1237,57 @@ begin
|
|||
vm_nt_map_unlock(map);
|
||||
end;
|
||||
|
||||
procedure vm_nt_map_prot_fix(map:p_vm_nt_map;
|
||||
procedure vm_nt_map_tracking(map :p_vm_nt_map;
|
||||
start:vm_offset_t;
|
||||
__end:vm_offset_t;
|
||||
prot :Integer);
|
||||
var
|
||||
entry:p_vm_nt_entry;
|
||||
e_start:vm_offset_t;
|
||||
e___end:vm_offset_t;
|
||||
begin
|
||||
if (start=__end) then Exit;
|
||||
|
||||
vm_nt_map_lock(map);
|
||||
|
||||
if (not vm_nt_map_lookup_entry(map, start, @entry)) then
|
||||
begin
|
||||
entry:=entry^.next;
|
||||
end else
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
||||
while (entry<>@map^.header) and (entry^.start<__end) do
|
||||
begin
|
||||
e_start:=entry^.start;
|
||||
e___end:=entry^.__end;
|
||||
|
||||
if (e_start<start) then
|
||||
begin
|
||||
e_start:=start;
|
||||
end;
|
||||
|
||||
if (e___end>__end) then
|
||||
begin
|
||||
e___end:=__end;
|
||||
end;
|
||||
|
||||
if (e___end>e_start) then
|
||||
begin
|
||||
vm_nt_sub_map_tracking(@entry^.sub,e_start,e___end,prot);
|
||||
end;
|
||||
|
||||
entry:=entry^.next;
|
||||
end;
|
||||
|
||||
vm_nt_map_unlock(map);
|
||||
end;
|
||||
|
||||
|
||||
|
||||
|
||||
procedure vm_nt_map_prot_fix(map :p_vm_nt_map;
|
||||
start:vm_offset_t;
|
||||
__end:vm_offset_t;
|
||||
mode :Integer);
|
||||
|
@ -1294,7 +1328,7 @@ begin
|
|||
|
||||
if (e___end>e_start) then
|
||||
begin
|
||||
vm_prot_fixup(map,e_start,e___end,entry^.obj^.maxp,mode);
|
||||
vm_nt_sub_map_prot_fixup(@entry^.sub,e_start,e___end,mode);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -1327,9 +1361,9 @@ asm
|
|||
_exit:
|
||||
end;
|
||||
|
||||
procedure vm_nt_map_madvise(map:p_vm_nt_map;
|
||||
start:vm_offset_t;
|
||||
__end:vm_offset_t;
|
||||
procedure vm_nt_map_madvise(map :p_vm_nt_map;
|
||||
start :vm_offset_t;
|
||||
__end :vm_offset_t;
|
||||
advise:Integer);
|
||||
var
|
||||
entry:p_vm_nt_entry;
|
||||
|
@ -1379,7 +1413,7 @@ begin
|
|||
mirror:=vm_nt_map_mirror(map,base,base+size);
|
||||
if (mirror<>nil) then
|
||||
begin
|
||||
ZeroPages(mirror,size);
|
||||
ZeroPages (mirror,size);
|
||||
md_unmap_ex(mirror,size);
|
||||
end;
|
||||
|
||||
|
@ -1396,7 +1430,7 @@ begin
|
|||
end;
|
||||
|
||||
|
||||
function vm_nt_map_mirror(map:p_vm_nt_map;
|
||||
function vm_nt_map_mirror(map :p_vm_nt_map;
|
||||
start:vm_offset_t;
|
||||
__end:vm_offset_t):Pointer;
|
||||
var
|
||||
|
|
|
@ -0,0 +1,653 @@
|
|||
unit vm_nt_sub_map;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
{$CALLING SysV_ABI_CDecl}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
sysutils,
|
||||
vm,
|
||||
vm_pmap_prot;
|
||||
|
||||
type
|
||||
pp_vm_nt_sub_entry=^p_vm_nt_sub_entry;
|
||||
p_vm_nt_sub_entry=^vm_nt_sub_entry;
|
||||
vm_nt_sub_entry=packed record
|
||||
prev :p_vm_nt_sub_entry; // previous entry
|
||||
next :p_vm_nt_sub_entry; // next entry
|
||||
left :p_vm_nt_sub_entry; // left child in binary search tree
|
||||
right:p_vm_nt_sub_entry; // right child in binary search tree
|
||||
start:vm_offset_t; // start address
|
||||
__end:vm_offset_t; // end address
|
||||
//
|
||||
decl_prot:Byte; // declared protection (with tracking bits)
|
||||
real_prot:Byte; // real page protection
|
||||
align :Word;
|
||||
end;
|
||||
|
||||
p_vm_nt_sub_map=^t_vm_nt_sub_map;
|
||||
t_vm_nt_sub_map=object
|
||||
header:vm_nt_sub_entry; // List of entries
|
||||
root :p_vm_nt_sub_entry; // Root of a binary search tree
|
||||
property min_offset:vm_offset_t read header.start write header.start;
|
||||
property max_offset:vm_offset_t read header.__end write header.__end;
|
||||
end;
|
||||
|
||||
procedure vm_nt_sub_map_init(map:p_vm_nt_sub_map;min,max:vm_offset_t);
|
||||
|
||||
function vm_nt_sub_map_insert(
|
||||
map :p_vm_nt_sub_map;
|
||||
start:vm_offset_t;
|
||||
__end:vm_offset_t;
|
||||
prot :Byte):Integer;
|
||||
|
||||
// Move nodes from one submap to another
|
||||
procedure vm_nt_sub_map_move(dst,src:p_vm_nt_sub_map);
|
||||
|
||||
procedure vm_nt_sub_map_free(map:p_vm_nt_sub_map);
|
||||
|
||||
//Change protection taking into account tracking
|
||||
function vm_nt_sub_map_protect(map :p_vm_nt_sub_map;
|
||||
start:vm_offset_t;
|
||||
__end:vm_offset_t;
|
||||
prot :Byte):Integer;
|
||||
|
||||
//Change protection tracking
|
||||
function vm_nt_sub_map_tracking(map :p_vm_nt_sub_map;
|
||||
start:vm_offset_t;
|
||||
__end:vm_offset_t;
|
||||
prot :Byte):Integer;
|
||||
|
||||
//Update page protection by mode
|
||||
procedure vm_nt_sub_map_prot_fixup(map :p_vm_nt_sub_map;
|
||||
start:vm_offset_t;
|
||||
__end:vm_offset_t;
|
||||
mode :Integer);
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
md_map;
|
||||
|
||||
procedure vm_nt_sub_map_init(map:p_vm_nt_sub_map;min,max:vm_offset_t); inline;
|
||||
begin
|
||||
map^:=Default(t_vm_nt_sub_map);
|
||||
map^.header.next:=@map^.header;
|
||||
map^.header.prev:=@map^.header;
|
||||
map^.min_offset :=min;
|
||||
map^.max_offset :=max;
|
||||
end;
|
||||
|
||||
function vm_nt_sub_entry_create(map:p_vm_nt_sub_map):p_vm_nt_sub_entry;
|
||||
var
|
||||
new_entry:p_vm_nt_sub_entry;
|
||||
begin
|
||||
new_entry:=AllocMem(SizeOf(vm_nt_sub_entry));
|
||||
Assert((new_entry<>nil),'vm_nt_sub_entry_create: kernel resources exhausted');
|
||||
Result:=new_entry;
|
||||
end;
|
||||
|
||||
procedure vm_nt_sub_entry_dispose(map:p_vm_nt_sub_map;entry:p_vm_nt_sub_entry); inline;
|
||||
begin
|
||||
FreeMem(entry);
|
||||
end;
|
||||
|
||||
function vm_nt_sub_entry_splay(addr:vm_offset_t;root:p_vm_nt_sub_entry):p_vm_nt_sub_entry;
|
||||
var
|
||||
llist,rlist:p_vm_nt_sub_entry;
|
||||
ltree,rtree:p_vm_nt_sub_entry;
|
||||
y :p_vm_nt_sub_entry;
|
||||
begin
|
||||
if (root=nil) then Exit(root);
|
||||
|
||||
llist:=nil;
|
||||
rlist:=nil;
|
||||
repeat
|
||||
{ root is never nil in here. }
|
||||
if (addr<root^.start) then
|
||||
begin
|
||||
y:=root^.left;
|
||||
if (y=nil) then break;
|
||||
if (addr<y^.start) and (y^.left<>nil) then
|
||||
begin
|
||||
{ Rotate right and put y on rlist. }
|
||||
root^.left:=y^.right;
|
||||
y^.right:=root;
|
||||
root:=y^.left;
|
||||
y^.left:=rlist;
|
||||
rlist:=y;
|
||||
end else
|
||||
begin
|
||||
{ Put root on rlist. }
|
||||
root^.left:=rlist;
|
||||
rlist:=root;
|
||||
root:=y;
|
||||
end;
|
||||
end else
|
||||
if (addr>=root^.__end) then
|
||||
begin
|
||||
y:=root^.right;
|
||||
if (y=nil) then break;
|
||||
if (addr>=y^.__end) and (y^.right<>nil) then
|
||||
begin
|
||||
{ Rotate left and put y on llist. }
|
||||
root^.right:=y^.left;
|
||||
y^.left:=root;
|
||||
root:=y^.right;
|
||||
y^.right:=llist;
|
||||
llist:=y;
|
||||
end else
|
||||
begin
|
||||
{ Put root on llist. }
|
||||
root^.right:=llist;
|
||||
llist:=root;
|
||||
root:=y;
|
||||
end;
|
||||
end else
|
||||
begin
|
||||
break;
|
||||
end;
|
||||
until false;
|
||||
|
||||
ltree:=root^.left;
|
||||
while (llist<>nil) do
|
||||
begin
|
||||
y:=llist^.right;
|
||||
llist^.right:=ltree;
|
||||
ltree:=llist;
|
||||
llist:=y;
|
||||
end;
|
||||
rtree:=root^.right;
|
||||
while (rlist<>nil) do
|
||||
begin
|
||||
y:=rlist^.left;
|
||||
rlist^.left:=rtree;
|
||||
rtree:=rlist;
|
||||
rlist:=y;
|
||||
end;
|
||||
|
||||
root^.left :=ltree;
|
||||
root^.right:=rtree;
|
||||
|
||||
Result:=(root);
|
||||
end;
|
||||
|
||||
procedure vm_nt_sub_entry_link(
|
||||
map :p_vm_nt_sub_map;
|
||||
after_where:p_vm_nt_sub_entry;
|
||||
entry :p_vm_nt_sub_entry);
|
||||
begin
|
||||
entry^.prev:=after_where;
|
||||
entry^.next:=after_where^.next;
|
||||
entry^.next^.prev:=entry;
|
||||
after_where^.next:=entry;
|
||||
|
||||
if (after_where<>@map^.header) then
|
||||
begin
|
||||
if (after_where<>map^.root) then
|
||||
begin
|
||||
vm_nt_sub_entry_splay(after_where^.start, map^.root);
|
||||
end;
|
||||
entry^.right:=after_where^.right;
|
||||
entry^.left :=after_where;
|
||||
after_where^.right:=nil;
|
||||
end else
|
||||
begin
|
||||
entry^.right:=map^.root;
|
||||
entry^.left :=nil;
|
||||
end;
|
||||
map^.root:=entry;
|
||||
end;
|
||||
|
||||
procedure vm_nt_sub_entry_unlink(
|
||||
map :p_vm_nt_sub_map;
|
||||
entry:p_vm_nt_sub_entry);
|
||||
var
|
||||
next,prev,root:p_vm_nt_sub_entry;
|
||||
begin
|
||||
if (entry<>map^.root) then
|
||||
begin
|
||||
vm_nt_sub_entry_splay(entry^.start, map^.root);
|
||||
end;
|
||||
if (entry^.left=nil) then
|
||||
begin
|
||||
root:=entry^.right;
|
||||
end else
|
||||
begin
|
||||
root:=vm_nt_sub_entry_splay(entry^.start, entry^.left);
|
||||
root^.right:=entry^.right;
|
||||
end;
|
||||
map^.root:=root;
|
||||
|
||||
prev:=entry^.prev;
|
||||
next:=entry^.next;
|
||||
next^.prev:=prev;
|
||||
prev^.next:=next;
|
||||
end;
|
||||
|
||||
function vm_nt_sub_map_lookup_entry(
|
||||
map :p_vm_nt_sub_map;
|
||||
address:vm_offset_t;
|
||||
entry :pp_vm_nt_sub_entry):Boolean;
|
||||
var
|
||||
cur:p_vm_nt_sub_entry;
|
||||
begin
|
||||
cur:=map^.root;
|
||||
if (cur=nil) then
|
||||
begin
|
||||
entry^:=@map^.header;
|
||||
end else
|
||||
if (address>=cur^.start) and (cur^.__end>address) then
|
||||
begin
|
||||
entry^:=cur;
|
||||
Exit(TRUE);
|
||||
end else
|
||||
begin
|
||||
cur:=vm_nt_sub_entry_splay(address,cur);
|
||||
map^.root:=cur;
|
||||
|
||||
if (address>=cur^.start) then
|
||||
begin
|
||||
entry^:=cur;
|
||||
if (cur^.__end>address) then
|
||||
begin
|
||||
Exit(TRUE);
|
||||
end;
|
||||
end else
|
||||
begin
|
||||
entry^:=cur^.prev;
|
||||
end;
|
||||
end;
|
||||
Result:=(FALSE);
|
||||
end;
|
||||
|
||||
procedure vm_nt_sub_simplify_entry(map:p_vm_nt_sub_map;entry:p_vm_nt_sub_entry); forward;
|
||||
|
||||
function vm_nt_sub_map_insert(
|
||||
map :p_vm_nt_sub_map;
|
||||
start:vm_offset_t;
|
||||
__end:vm_offset_t;
|
||||
prot :Byte):Integer;
|
||||
var
|
||||
new_entry :p_vm_nt_sub_entry;
|
||||
prev_entry :p_vm_nt_sub_entry;
|
||||
temp_entry :p_vm_nt_sub_entry;
|
||||
|
||||
begin
|
||||
if (start<map^.min_offset) or (__end>map^.max_offset) or (start>=__end) then
|
||||
begin
|
||||
Exit(KERN_INVALID_ADDRESS);
|
||||
end;
|
||||
|
||||
if vm_nt_sub_map_lookup_entry(map,start,@temp_entry) then
|
||||
begin
|
||||
Exit(KERN_NO_SPACE);
|
||||
end;
|
||||
|
||||
prev_entry:=temp_entry;
|
||||
|
||||
if (prev_entry^.next<>@map^.header) and
|
||||
(prev_entry^.next^.start<__end) then
|
||||
begin
|
||||
Exit(KERN_NO_SPACE);
|
||||
end;
|
||||
|
||||
if (prev_entry<>@map^.header) and
|
||||
(prev_entry^.decl_prot=prot) and
|
||||
(prev_entry^.real_prot=0) and
|
||||
(prev_entry^.__end=start) then
|
||||
begin
|
||||
prev_entry^.__end:=__end;
|
||||
|
||||
vm_nt_sub_simplify_entry(map, prev_entry);
|
||||
|
||||
Exit(KERN_SUCCESS);
|
||||
end;
|
||||
|
||||
new_entry:=vm_nt_sub_entry_create(map);
|
||||
new_entry^.start:=start;
|
||||
new_entry^.__end:=__end;
|
||||
|
||||
new_entry^.decl_prot:=prot;
|
||||
new_entry^.real_prot:=0; //do fixup
|
||||
|
||||
vm_nt_sub_entry_link(map, prev_entry, new_entry);
|
||||
|
||||
vm_nt_sub_simplify_entry(map, new_entry);
|
||||
|
||||
Result:=KERN_SUCCESS;
|
||||
end;
|
||||
|
||||
procedure vm_nt_sub_map_entry_delete(map:p_vm_nt_sub_map;entry:p_vm_nt_sub_entry); inline;
|
||||
begin
|
||||
vm_nt_sub_entry_unlink (map, entry);
|
||||
vm_nt_sub_entry_dispose(map, entry);
|
||||
end;
|
||||
|
||||
procedure vm_nt_sub_simplify_entry(map:p_vm_nt_sub_map;entry:p_vm_nt_sub_entry);
|
||||
var
|
||||
next,prev:p_vm_nt_sub_entry;
|
||||
begin
|
||||
prev:=entry^.prev;
|
||||
if (prev<>@map^.header) then
|
||||
begin
|
||||
if (prev^.__end=entry^.start) and
|
||||
(prev^.decl_prot=entry^.decl_prot) and
|
||||
(prev^.real_prot=entry^.real_prot) then
|
||||
begin
|
||||
vm_nt_sub_entry_unlink(map, prev);
|
||||
entry^.start:=prev^.start;
|
||||
|
||||
vm_nt_sub_entry_dispose(map, prev);
|
||||
end;
|
||||
end;
|
||||
|
||||
next:=entry^.next;
|
||||
if (next<>@map^.header) then
|
||||
begin
|
||||
if (entry^.__end=next^.start) and
|
||||
(next^.decl_prot=entry^.decl_prot) and
|
||||
(next^.real_prot=entry^.real_prot) then
|
||||
begin
|
||||
vm_nt_sub_entry_unlink(map, next);
|
||||
entry^.__end:=next^.__end;
|
||||
|
||||
vm_nt_sub_entry_dispose(map, next);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure _vm_nt_sub_map_clip_start(map:p_vm_nt_sub_map;entry:p_vm_nt_sub_entry;start:vm_offset_t);
|
||||
var
|
||||
new_entry:p_vm_nt_sub_entry;
|
||||
begin
|
||||
vm_nt_sub_simplify_entry(map, entry);
|
||||
|
||||
new_entry:=vm_nt_sub_entry_create(map);
|
||||
new_entry^:=entry^;
|
||||
|
||||
new_entry^.__end:=start;
|
||||
entry^.start :=start;
|
||||
|
||||
vm_nt_sub_entry_link(map, entry^.prev, new_entry);
|
||||
end;
|
||||
|
||||
procedure vm_nt_sub_map_clip_start(map:p_vm_nt_sub_map;entry:p_vm_nt_sub_entry;start:vm_offset_t); inline;
|
||||
begin
|
||||
if (start>entry^.start) then
|
||||
begin
|
||||
_vm_nt_sub_map_clip_start(map,entry,start);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure _vm_nt_sub_map_clip_end(map:p_vm_nt_sub_map;entry:p_vm_nt_sub_entry;__end:vm_offset_t);
|
||||
var
|
||||
new_entry:p_vm_nt_sub_entry;
|
||||
begin
|
||||
new_entry:=vm_nt_sub_entry_create(map);
|
||||
new_entry^:=entry^;
|
||||
|
||||
new_entry^.start:=__end;
|
||||
entry^.__end :=__end;
|
||||
|
||||
vm_nt_sub_entry_link(map, entry, new_entry);
|
||||
end;
|
||||
|
||||
procedure vm_nt_sub_map_clip_end(map:p_vm_nt_sub_map;entry:p_vm_nt_sub_entry;__end:vm_offset_t); inline;
|
||||
begin
|
||||
if (__end<entry^.__end) then
|
||||
begin
|
||||
_vm_nt_sub_map_clip_end(map,entry,__end);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure vm_nt_sub_map_move(dst,src:p_vm_nt_sub_map);
|
||||
var
|
||||
entry,next,after:p_vm_nt_sub_entry;
|
||||
begin
|
||||
entry:=nil;
|
||||
if (vm_nt_sub_map_lookup_entry(src, dst^.min_offset, @entry)) then
|
||||
begin
|
||||
vm_nt_sub_map_clip_start(src, entry, dst^.min_offset); //devide src by dst
|
||||
end else
|
||||
begin
|
||||
entry:=entry^.next;
|
||||
end;
|
||||
//
|
||||
after:=nil;
|
||||
//
|
||||
while (entry<>@src^.header) do
|
||||
begin
|
||||
vm_nt_sub_map_clip_end(src, entry, dst^.max_offset); //devide src by dst
|
||||
//
|
||||
if (after=nil) then
|
||||
begin
|
||||
vm_nt_sub_map_lookup_entry(dst, entry^.__end, @after); //get first position of insert
|
||||
end;
|
||||
//
|
||||
next:=entry^.next;
|
||||
//
|
||||
vm_nt_sub_entry_unlink (src,entry);
|
||||
vm_nt_sub_entry_link (dst,after,entry);
|
||||
vm_nt_sub_simplify_entry(dst,entry);
|
||||
//
|
||||
after:=entry;
|
||||
//
|
||||
entry:=next;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure vm_nt_sub_map_free(map:p_vm_nt_sub_map);
|
||||
var
|
||||
entry,next:p_vm_nt_sub_entry;
|
||||
begin
|
||||
entry:=map^.header.next;
|
||||
//
|
||||
while (entry<>@map^.header) do
|
||||
begin
|
||||
next:=entry^.next;
|
||||
//
|
||||
vm_nt_sub_map_entry_delete(map,entry);
|
||||
//
|
||||
entry:=next;
|
||||
end;
|
||||
end;
|
||||
|
||||
//
|
||||
|
||||
function vm_nt_sub_map_protect(map :p_vm_nt_sub_map;
|
||||
start:vm_offset_t;
|
||||
__end:vm_offset_t;
|
||||
prot :Byte):Integer;
|
||||
var
|
||||
entry:p_vm_nt_sub_entry;
|
||||
|
||||
base,size:vm_size_t;
|
||||
mask:Integer;
|
||||
r:Integer;
|
||||
begin
|
||||
if (start=__end) then
|
||||
begin
|
||||
Exit(KERN_SUCCESS);
|
||||
end;
|
||||
|
||||
if (vm_nt_sub_map_lookup_entry(map, start, @entry)) then
|
||||
begin
|
||||
vm_nt_sub_map_clip_start(map, entry, start);
|
||||
end else
|
||||
begin
|
||||
entry:=entry^.next;
|
||||
end;
|
||||
|
||||
while (entry<>@map^.header) and (entry^.start<__end) do
|
||||
begin
|
||||
vm_nt_sub_map_clip_end(map, entry, __end);
|
||||
|
||||
//save trac, change prot
|
||||
prot:=(prot and VM_RW) or (entry^.decl_prot and PAGE_TRACK_RWX);
|
||||
entry^.decl_prot:=prot;
|
||||
|
||||
//masking
|
||||
mask:=not (prot shr PAGE_TRACK_SHIFT);
|
||||
prot:=(prot and VM_RW) and mask;
|
||||
|
||||
if (prot<>(entry^.real_prot and VM_RW)) then
|
||||
begin
|
||||
base:=entry^.start;
|
||||
size:=entry^.__end-entry^.start;
|
||||
|
||||
r:=md_protect(Pointer(base),size,prot);
|
||||
if (r<>0) then
|
||||
begin
|
||||
Writeln('failed md_protect(',HexStr(base,11),',',HexStr(base+size,11),'):0x',HexStr(r,8));
|
||||
Assert(false,'vm_nt_sub_map_protect');
|
||||
end;
|
||||
//save changes
|
||||
entry^.real_prot:=prot;
|
||||
end;
|
||||
|
||||
vm_nt_sub_simplify_entry(map, entry);
|
||||
entry:=entry^.next;
|
||||
end;
|
||||
|
||||
Result:=(KERN_SUCCESS);
|
||||
end;
|
||||
|
||||
function vm_nt_sub_map_tracking(map :p_vm_nt_sub_map;
|
||||
start:vm_offset_t;
|
||||
__end:vm_offset_t;
|
||||
prot :Byte):Integer;
|
||||
var
|
||||
entry:p_vm_nt_sub_entry;
|
||||
|
||||
base,size:vm_size_t;
|
||||
mask:Integer;
|
||||
r:Integer;
|
||||
begin
|
||||
if (start=__end) then
|
||||
begin
|
||||
Exit(KERN_SUCCESS);
|
||||
end;
|
||||
|
||||
if (vm_nt_sub_map_lookup_entry(map, start, @entry)) then
|
||||
begin
|
||||
vm_nt_sub_map_clip_start(map, entry, start);
|
||||
end else
|
||||
begin
|
||||
entry:=entry^.next;
|
||||
end;
|
||||
|
||||
while (entry<>@map^.header) and (entry^.start<__end) do
|
||||
begin
|
||||
vm_nt_sub_map_clip_end(map, entry, __end);
|
||||
|
||||
//save prot, change track
|
||||
prot:=(prot and PAGE_TRACK_RWX) or (entry^.decl_prot and VM_RW);
|
||||
entry^.decl_prot:=prot;
|
||||
|
||||
//masking
|
||||
mask:=not (prot shr PAGE_TRACK_SHIFT);
|
||||
prot:=(prot and VM_RW) and mask;
|
||||
|
||||
if (prot<>(entry^.real_prot and VM_RW)) then
|
||||
begin
|
||||
base:=entry^.start;
|
||||
size:=entry^.__end-entry^.start;
|
||||
|
||||
r:=md_protect(Pointer(base),size,prot);
|
||||
if (r<>0) then
|
||||
begin
|
||||
Writeln('failed md_protect(',HexStr(base,11),',',HexStr(base+size,11),'):0x',HexStr(r,8));
|
||||
Assert(false,'vm_nt_sub_map_protect');
|
||||
end;
|
||||
//save changes
|
||||
entry^.real_prot:=prot;
|
||||
end;
|
||||
|
||||
vm_nt_sub_simplify_entry(map, entry);
|
||||
entry:=entry^.next;
|
||||
end;
|
||||
|
||||
Result:=(KERN_SUCCESS);
|
||||
end;
|
||||
|
||||
procedure vm_nt_sub_map_prot_fixup(map :p_vm_nt_sub_map;
|
||||
start:vm_offset_t;
|
||||
__end:vm_offset_t;
|
||||
mode :Integer);
|
||||
var
|
||||
entry :p_vm_nt_sub_entry;
|
||||
e_start:vm_offset_t;
|
||||
e___end:vm_offset_t;
|
||||
|
||||
base,size:vm_size_t;
|
||||
prot:Integer;
|
||||
mask:Integer;
|
||||
r:Integer;
|
||||
begin
|
||||
if (start=__end) then Exit;
|
||||
|
||||
if (vm_nt_sub_map_lookup_entry(map, start, @entry)) then
|
||||
begin
|
||||
//
|
||||
end else
|
||||
begin
|
||||
entry:=entry^.next;
|
||||
end;
|
||||
|
||||
while (entry<>@map^.header) and (entry^.start<__end) do
|
||||
begin
|
||||
|
||||
e_start:=entry^.start;
|
||||
e___end:=entry^.__end;
|
||||
|
||||
if (e_start<start) then
|
||||
begin
|
||||
e_start:=start;
|
||||
end;
|
||||
|
||||
if (e___end>__end) then
|
||||
begin
|
||||
e___end:=__end;
|
||||
end;
|
||||
|
||||
if (e_start<>e___end) then
|
||||
begin
|
||||
prot:=entry^.decl_prot;
|
||||
|
||||
//TRACK_PROT Take tracking bits into account
|
||||
if ((mode and TRACK_PROT)=0) then
|
||||
begin
|
||||
prot:=(prot and VM_RW);
|
||||
end else
|
||||
begin
|
||||
mask:=not (prot shr PAGE_TRACK_SHIFT);
|
||||
prot:=(prot and VM_RW) and mask;
|
||||
end;
|
||||
|
||||
//REMAP_PROT Ignore protect bit checking
|
||||
if ((mode and REMAP_PROT)<>0) or (prot<>(entry^.real_prot and VM_RW)) then
|
||||
begin
|
||||
base:=e_start;
|
||||
size:=e___end-e_start;
|
||||
|
||||
r:=md_protect(Pointer(base),size,prot);
|
||||
if (r<>0) then
|
||||
begin
|
||||
Writeln('failed md_protect(',HexStr(base,11),',',HexStr(base+size,11),'):0x',HexStr(r,8));
|
||||
Assert(false,'vm_nt_sub_map_prot_fixup');
|
||||
end;
|
||||
//save changes
|
||||
entry^.real_prot:=prot;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
entry:=entry^.next;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
|
|
@ -153,7 +153,7 @@ implementation
|
|||
procedure pmap_prot_track(pmap :Pointer;
|
||||
start:vm_offset_t;
|
||||
__end:vm_offset_t;
|
||||
prots:Byte); external;
|
||||
prot :Byte); external;
|
||||
|
||||
function vm_track_object_allocate(handle:Pointer;start,__end:vm_offset_t;htype:T_THANDLE_TYPE;prot:Byte):p_vm_track_object;
|
||||
begin
|
||||
|
|
Loading…
Reference in New Issue