mirror of https://github.com/red-prig/fpPS4.git
This commit is contained in:
parent
eb614ec4fb
commit
cf6f0435e4
|
@ -329,10 +329,12 @@ type
|
|||
function leap(reg:TRegValue):t_jit_i_link;
|
||||
//
|
||||
Procedure jmp(reg:TRegValue);
|
||||
Procedure jmp(mem:t_jit_leas);
|
||||
Procedure call(reg:TRegValue);
|
||||
Procedure call(mem:t_jit_leas);
|
||||
Procedure reta;
|
||||
Procedure ud2;
|
||||
Procedure nop(length:DWORD);
|
||||
//
|
||||
Function GetInstructionsSize:Integer;
|
||||
Function GetDataSize:Integer;
|
||||
|
@ -1530,6 +1532,13 @@ begin
|
|||
_R(desc,reg);
|
||||
end;
|
||||
|
||||
Procedure t_jit_builder.jmp(mem:t_jit_leas);
|
||||
const
|
||||
desc:t_op_type=(op:$FF;index:4);
|
||||
begin
|
||||
_M(desc,mem);
|
||||
end;
|
||||
|
||||
Procedure t_jit_builder.call(reg:TRegValue);
|
||||
const
|
||||
desc:t_op_type=(op:$FF;index:2);
|
||||
|
@ -1556,6 +1565,43 @@ begin
|
|||
_O($0F0B);
|
||||
end;
|
||||
|
||||
Procedure t_jit_builder.nop(length:DWORD);
|
||||
var
|
||||
i:DWORD;
|
||||
|
||||
ji:t_jit_instruction;
|
||||
begin
|
||||
if (length=0) then Exit;
|
||||
|
||||
ji:=default_jit_instruction;
|
||||
|
||||
i:=length div 9;
|
||||
while (i<>0) do
|
||||
begin
|
||||
|
||||
ji.EmitInt64($00000000841F0F66);
|
||||
ji.EmitByte ($00);
|
||||
|
||||
Dec(i);
|
||||
end;
|
||||
|
||||
i:=length mod 9;
|
||||
|
||||
case i of
|
||||
1: ji.EmitByte($90);
|
||||
2: ji.EmitWord($9066);
|
||||
3: begin ji.EmitWord($1F0F); ji.EmitByte($00); end;
|
||||
4: ji.EmitInt32($00401F0F);
|
||||
5: begin ji.EmitInt32($00441F0F); ji.EmitByte($00); end;
|
||||
6: begin ji.EmitInt32($441F0F66); ji.EmitWord($00); end;
|
||||
7: begin ji.EmitInt32($00801F0F); ji.EmitWord($00); ji.EmitByte($00); end;
|
||||
8: ji.EmitInt64($0000000000841F0F);
|
||||
else;
|
||||
end;
|
||||
|
||||
_add(ji);
|
||||
end;
|
||||
|
||||
Function t_jit_builder.GetInstructionsSize:Integer;
|
||||
begin
|
||||
Result:=AInstructionSize;
|
||||
|
|
|
@ -1374,11 +1374,17 @@ var
|
|||
map:vm_map_t;
|
||||
lock:Pointer;
|
||||
node:p_jit_entry_point;
|
||||
|
||||
lock_start:QWORD;
|
||||
lock___end:QWORD;
|
||||
begin
|
||||
map:=p_proc.p_vmspace;
|
||||
|
||||
lock_start:=ctx.text_start;
|
||||
lock___end:=ctx.text___end;
|
||||
|
||||
//vm_map_lock(map);
|
||||
lock:=pmap_wlock(map^.pmap,ctx.text_start,ctx.text___end);
|
||||
lock:=pmap_wlock(map^.pmap,lock_start,lock___end);
|
||||
|
||||
if (preload<>nil) then
|
||||
begin
|
||||
|
@ -1391,10 +1397,10 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
//lock pageflt read-only
|
||||
//vm_map_lock(map);
|
||||
// _pmap_prot_int(map^.pmap,ctx.text_start,ctx.text___end,PAGE_PROT_READ);
|
||||
//vm_map_unlock(map);
|
||||
//lock pageflt read-only (mirrors?)
|
||||
vm_map_lock(map);
|
||||
_pmap_prot_int(map^.pmap,lock_start,lock___end,PAGE_PROT_READ);
|
||||
vm_map_unlock(map);
|
||||
|
||||
if (cmInternal in ctx.modes) then
|
||||
begin
|
||||
|
@ -1404,38 +1410,16 @@ begin
|
|||
pick_locked(ctx);
|
||||
end;
|
||||
|
||||
//restore non tracked
|
||||
//vm_map_lock(map);
|
||||
// _pmap_prot_fix(map^.pmap,ctx.text_start,ctx.text___end,TRACK_PROT or REMAP_PROT);
|
||||
//vm_map_unlock(map);
|
||||
//restore non tracked (mirrors?)
|
||||
vm_map_lock(map);
|
||||
_pmap_prot_fix(map^.pmap,lock_start,lock___end,TRACK_PROT or REMAP_PROT);
|
||||
vm_map_unlock(map);
|
||||
|
||||
_exit:
|
||||
pmap_unlock(map^.pmap,lock);
|
||||
//vm_map_unlock(map);
|
||||
end;
|
||||
|
||||
procedure pick_track(var ctx:t_jit_context2);
|
||||
var
|
||||
chunk:p_jit_code_chunk;
|
||||
begin
|
||||
chunk:=TAILQ_FIRST(@ctx.builder.ACodeChunkList);
|
||||
|
||||
while (chunk<>nil) do
|
||||
begin
|
||||
if (chunk^.start<>chunk^.__end) then
|
||||
begin
|
||||
|
||||
pmap_track(chunk^.start,
|
||||
chunk^.__end+PAGE_MASK,
|
||||
PAGE_TRACK_W or PAGE_TRACK_X);
|
||||
|
||||
end;
|
||||
//
|
||||
chunk:=TAILQ_NEXT(chunk,@chunk^.entry);
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
procedure pick_locked_internal(var ctx:t_jit_context2);
|
||||
var
|
||||
node:t_jit_context2.p_export_point;
|
||||
|
@ -1493,9 +1477,8 @@ begin
|
|||
|
||||
ctx.end_chunk(ctx.ptr_next);
|
||||
|
||||
pick_track(ctx);
|
||||
|
||||
build(ctx);
|
||||
|
||||
ctx.Free;
|
||||
end;
|
||||
|
||||
|
@ -1909,9 +1892,8 @@ begin
|
|||
ctx.builder.int3;
|
||||
ctx.builder.ud2;
|
||||
|
||||
pick_track(ctx);
|
||||
|
||||
build(ctx);
|
||||
|
||||
ctx.Free;
|
||||
|
||||
end;
|
||||
|
|
|
@ -265,9 +265,17 @@ procedure op_emit_bmi_rrm(var ctx:t_jit_context2;const desc:t_op_type);
|
|||
|
||||
procedure print_disassemble(addr:Pointer;vsize:Integer);
|
||||
|
||||
type
|
||||
t_instruction_info=record
|
||||
code_size:Byte;
|
||||
mema_size:Byte;
|
||||
end;
|
||||
|
||||
function get_instruction_info(addr:Pointer):t_instruction_info;
|
||||
|
||||
var
|
||||
jit_relative_analize:Boolean=True;
|
||||
jit_memory_guard:Boolean=False;
|
||||
jit_memory_guard :Boolean=False;
|
||||
|
||||
implementation
|
||||
|
||||
|
@ -3907,6 +3915,40 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
//
|
||||
|
||||
function get_instruction_info(addr:Pointer):t_instruction_info;
|
||||
var
|
||||
ptr:Pointer;
|
||||
|
||||
dis:TX86Disassembler;
|
||||
din:TInstruction;
|
||||
|
||||
i:Byte;
|
||||
begin
|
||||
dis:=Default(TX86Disassembler);
|
||||
din:=Default(TInstruction);
|
||||
|
||||
ptr:=addr;
|
||||
|
||||
dis.Disassemble(dm64,ptr,din);
|
||||
|
||||
Result.code_size:=(ptr-addr);
|
||||
Result.mema_size:=0;
|
||||
|
||||
if (din.OperCnt<>0) then
|
||||
For i:=1 to din.OperCnt do
|
||||
if is_memory(din.Operand[i]) then
|
||||
begin
|
||||
Result.mema_size:=OPERAND_BYTES[din.Operand[i].Size];
|
||||
Exit;
|
||||
end;
|
||||
|
||||
Assert(false,'get_instruction_info');
|
||||
end;
|
||||
|
||||
//
|
||||
|
||||
end.
|
||||
|
||||
|
||||
|
|
|
@ -54,11 +54,12 @@ type
|
|||
pLeft :p_jcode_chunk;
|
||||
pRight:p_jcode_chunk;
|
||||
blob :p_jit_dynamic_blob;
|
||||
start :QWORD; //<-guest
|
||||
__end :QWORD; //<-guest
|
||||
dest :QWORD; //<-host
|
||||
d_end :QWORD; //<-host
|
||||
hash :QWORD; //MurmurHash64A(Pointer(start),__end-start,$010CA1C0DE);
|
||||
tobj :Pointer; //p_vm_track_object
|
||||
start :QWORD; //<-guest
|
||||
__end :QWORD; //<-guest
|
||||
dest :QWORD; //<-host
|
||||
d_end :QWORD; //<-host
|
||||
hash :QWORD; //MurmurHash64A(Pointer(start),__end-start,$010CA1C0DE);
|
||||
count :QWORD;
|
||||
table :record end; //p_jinstr_len[]
|
||||
function c(n1,n2:p_jcode_chunk):Integer; static;
|
||||
|
@ -162,9 +163,13 @@ uses
|
|||
sysutils,
|
||||
vmparam,
|
||||
sys_bootparam,
|
||||
kern_proc,
|
||||
vm,
|
||||
vm_map,
|
||||
vm_pmap_prot,
|
||||
vm_pmap,
|
||||
md_map,
|
||||
vm_tracking_map,
|
||||
kern_dlsym;
|
||||
|
||||
//
|
||||
|
@ -1349,6 +1354,51 @@ begin
|
|||
dec_ref
|
||||
end;
|
||||
|
||||
function on_destroy(handle:Pointer):Integer;
|
||||
begin
|
||||
p_jcode_chunk(handle)^.tobj:=nil;
|
||||
Result:=DO_DELETE;
|
||||
end;
|
||||
|
||||
function on_trigger(handle:Pointer;start,__end:vm_offset_t):Integer;
|
||||
begin
|
||||
Result:=DO_INCREMENT;
|
||||
end;
|
||||
|
||||
procedure blob_track(blob:p_jit_dynamic_blob);
|
||||
var
|
||||
node:p_jcode_chunk;
|
||||
tobj:p_vm_track_object;
|
||||
begin
|
||||
node:=blob^.chunk_list;
|
||||
|
||||
while (node<>nil) do
|
||||
begin
|
||||
if (node^.start<>node^.__end) then
|
||||
begin
|
||||
|
||||
tobj:=vm_track_object_allocate(node,node^.start,node^.__end);
|
||||
tobj^.on_destroy:=@on_destroy;
|
||||
tobj^.on_trigger:=@on_trigger;
|
||||
|
||||
node^.tobj:=tobj;
|
||||
|
||||
vm_map_track(p_proc.p_vmspace,node^.start,node^.__end,tobj);
|
||||
|
||||
vm_track_object_deallocate(tobj);
|
||||
|
||||
//pmap_track(node^.start,
|
||||
// node^.__end+PAGE_MASK,
|
||||
// PAGE_TRACK_W or PAGE_TRACK_X);
|
||||
//
|
||||
end;
|
||||
//
|
||||
node:=node^.next;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
|
||||
|
||||
|
|
|
@ -149,6 +149,8 @@ begin
|
|||
|
||||
dmem.vmap:=vmap;
|
||||
dmem.rmap:=@rmap;
|
||||
|
||||
rmap.tmap:=@vmap^.pmap^.tr_map;
|
||||
end;
|
||||
|
||||
const
|
||||
|
|
|
@ -16,6 +16,7 @@ uses
|
|||
kern_rangelock,
|
||||
md_map,
|
||||
vm_pmap_prot,
|
||||
vm_tracking_map,
|
||||
vm_nt_map;
|
||||
|
||||
const
|
||||
|
@ -41,11 +42,12 @@ function uplift(addr:Pointer):Pointer;
|
|||
procedure iov_uplift(iov:p_iovec);
|
||||
|
||||
type
|
||||
p_pmap=^_pmap;
|
||||
_pmap=packed object
|
||||
p_pmap=^t_pmap;
|
||||
t_pmap=packed object
|
||||
rmlock:rangelock;
|
||||
rm_mtx:mtx;
|
||||
nt_map:_vm_nt_map;
|
||||
nt_map:t_vm_nt_map;
|
||||
tr_map:t_vm_track_map;
|
||||
end;
|
||||
|
||||
pmap_t=p_pmap;
|
||||
|
@ -306,6 +308,8 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
vm_track_map_init(@pmap^.tr_map,VM_MINUSER_ADDRESS,VM_MAXUSER_ADDRESS);
|
||||
|
||||
end;
|
||||
|
||||
type
|
||||
|
@ -626,12 +630,12 @@ end;
|
|||
* is mapped; only those for which a resident page exists with the
|
||||
* corresponding offset from m_start are mapped.
|
||||
}
|
||||
procedure pmap_enter_object(pmap :pmap_t;
|
||||
obj :vm_object_t;
|
||||
offset :vm_ooffset_t;
|
||||
start :vm_offset_t;
|
||||
__end :vm_offset_t;
|
||||
prot :vm_prot_t);
|
||||
procedure pmap_enter_object(pmap :pmap_t;
|
||||
obj :vm_object_t;
|
||||
offset:vm_ooffset_t;
|
||||
start :vm_offset_t;
|
||||
__end :vm_offset_t;
|
||||
prot :vm_prot_t);
|
||||
label
|
||||
_default;
|
||||
var
|
||||
|
@ -968,7 +972,7 @@ begin
|
|||
vm_nt_map_prot_fix(@pmap^.nt_map,
|
||||
start,
|
||||
__end,
|
||||
TRACK_PROT);
|
||||
TRACK_PROT or REMAP_PROT);
|
||||
|
||||
//vm_nt_map_protect(@pmap^.nt_map,
|
||||
// start,
|
||||
|
@ -1124,6 +1128,8 @@ begin
|
|||
pmap_untrack (start,__end,PAGE_TRACK_RWX);
|
||||
//untrack?
|
||||
|
||||
vm_track_map_remove_memory(@pmap^.tr_map,start,__end);
|
||||
|
||||
r:=0;
|
||||
case vm_object_type(obj) of
|
||||
OBJT_SELF , // same?
|
||||
|
|
|
@ -31,8 +31,8 @@ const
|
|||
PAGE_TRACK_RWX =PAGE_TRACK_R or PAGE_TRACK_W or PAGE_TRACK_X;
|
||||
PAGE_TRACK_SHIFT =3;
|
||||
|
||||
TRACK_PROT=1;
|
||||
REMAP_PROT=2;
|
||||
TRACK_PROT=1; //Take tracking bits into account
|
||||
REMAP_PROT=2; //Ignore protect bit checking
|
||||
|
||||
var
|
||||
PAGE_PROT:PBYTE=nil;
|
||||
|
|
|
@ -36,6 +36,7 @@ type
|
|||
lock :mtx; // Lock for map data
|
||||
root :p_rmem_map_entry; // Root of a binary search tree
|
||||
nentries:DWORD; // Number of entries
|
||||
tmap :Pointer; // p_vm_track_map
|
||||
property min_offset:DWORD read header.start write header.start;
|
||||
property max_offset:DWORD read header.__end write header.__end;
|
||||
end;
|
||||
|
@ -59,11 +60,16 @@ function rmem_map_delete(map:p_rmem_map;
|
|||
vaddr:QWORD;
|
||||
start,__end:DWORD):Integer;
|
||||
|
||||
procedure rmem_map_track(map:p_rmem_map;
|
||||
start,__end:DWORD;
|
||||
tobj:Pointer);
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
errno,
|
||||
kern_thr;
|
||||
kern_thr,
|
||||
vm_tracking_map;
|
||||
|
||||
function IDX_TO_OFF(x:DWORD):QWORD; inline;
|
||||
begin
|
||||
|
@ -102,7 +108,7 @@ begin
|
|||
TAILQ_INSERT_TAIL(@entry^.vlist,node,@node^.entry);
|
||||
end;
|
||||
|
||||
procedure rmem_entry_add_vaddr(entry:p_rmem_map_entry;vaddr:QWORD);
|
||||
function rmem_entry_add_vaddr(entry:p_rmem_map_entry;vaddr:QWORD):Boolean;
|
||||
var
|
||||
node:p_rmem_vaddr_instance;
|
||||
begin
|
||||
|
@ -113,15 +119,45 @@ begin
|
|||
|
||||
if (node^.vaddr=vaddr) then
|
||||
begin
|
||||
Exit;
|
||||
Exit(False);
|
||||
end;
|
||||
|
||||
node:=TAILQ_NEXT(node,@node^.entry);
|
||||
end;
|
||||
|
||||
//if not one vaddr
|
||||
Result:=(TAILQ_FIRST(@entry^.vlist)<>nil);
|
||||
|
||||
_rmem_entry_add_vaddr(entry,vaddr);
|
||||
end;
|
||||
|
||||
procedure rmem_entry_add_track(tmap:Pointer;entry:p_rmem_map_entry;vaddr:QWORD);
|
||||
var
|
||||
node:p_rmem_vaddr_instance;
|
||||
size:vm_offset_t;
|
||||
begin
|
||||
//try add mirror track
|
||||
|
||||
size:=IDX_TO_OFF(entry^.__end-entry^.start);
|
||||
|
||||
vm_track_map_lock(tmap);
|
||||
|
||||
node:=TAILQ_FIRST(@entry^.vlist);
|
||||
|
||||
while (node<>nil) do
|
||||
begin
|
||||
|
||||
if (node^.vaddr<>vaddr) then
|
||||
begin
|
||||
_vm_track_map_insert_mirror(tmap,node^.vaddr,vaddr,size);
|
||||
end;
|
||||
|
||||
node:=TAILQ_NEXT(node,@node^.entry);
|
||||
end;
|
||||
|
||||
vm_track_map_unlock(tmap);
|
||||
end;
|
||||
|
||||
function _rmem_entry_del_node(entry:p_rmem_map_entry;node:p_rmem_vaddr_instance):Boolean;
|
||||
begin
|
||||
TAILQ_REMOVE(@entry^.vlist,node,@node^.entry);
|
||||
|
@ -211,18 +247,18 @@ begin
|
|||
Result:=True;
|
||||
end;
|
||||
|
||||
procedure copy_vaddr_list(const src:TAILQ_HEAD;entry:p_rmem_map_entry);
|
||||
procedure copy_vaddr_list(src,dst:p_rmem_map_entry);
|
||||
var
|
||||
node:p_rmem_vaddr_instance;
|
||||
begin
|
||||
|
||||
TAILQ_INIT(@entry^.vlist);
|
||||
TAILQ_INIT(@dst^.vlist);
|
||||
|
||||
node:=TAILQ_FIRST(@src);
|
||||
node:=TAILQ_FIRST(@src^.vlist);
|
||||
|
||||
while (node<>nil) do
|
||||
begin
|
||||
_rmem_entry_add_vaddr(entry,node^.vaddr);
|
||||
_rmem_entry_add_vaddr(dst,node^.vaddr);
|
||||
|
||||
node:=TAILQ_NEXT(node,@node^.entry);
|
||||
end;
|
||||
|
@ -625,7 +661,7 @@ begin
|
|||
|
||||
new_entry^.__end:=start;
|
||||
|
||||
copy_vaddr_list(entry^.vlist,new_entry);
|
||||
copy_vaddr_list(entry,new_entry);
|
||||
|
||||
entry^.start:=start;
|
||||
|
||||
|
@ -653,7 +689,7 @@ begin
|
|||
|
||||
entry^.__end:=__end;
|
||||
|
||||
copy_vaddr_list(entry^.vlist,new_entry);
|
||||
copy_vaddr_list(entry,new_entry);
|
||||
|
||||
rmem_entry_link(map, entry, new_entry);
|
||||
end;
|
||||
|
@ -701,7 +737,10 @@ begin
|
|||
|
||||
current:=rmem_map_insert_internal(map,current,current^.__end,__end);
|
||||
|
||||
rmem_entry_add_vaddr(current,vaddr);
|
||||
if rmem_entry_add_vaddr(current,vaddr) then
|
||||
begin
|
||||
rmem_entry_add_track(map^.tmap,entry,vaddr);
|
||||
end;
|
||||
|
||||
current:=current^.next;
|
||||
end;
|
||||
|
@ -772,9 +811,9 @@ begin
|
|||
until false;
|
||||
end;
|
||||
|
||||
function rmem_map_delete(map:p_rmem_map;
|
||||
vaddr:QWORD;
|
||||
start,__end:DWORD):Integer;
|
||||
function rmem_map_delete(map:p_rmem_map;
|
||||
vaddr:QWORD;
|
||||
start,__end:DWORD):Integer;
|
||||
var
|
||||
entry :p_rmem_map_entry;
|
||||
first_entry:p_rmem_map_entry;
|
||||
|
@ -840,6 +879,84 @@ begin
|
|||
Result:=(KERN_SUCCESS);
|
||||
end;
|
||||
|
||||
procedure rmem_entry_track(tmap:Pointer;entry:p_rmem_map_entry;diff,size:QWORD;tobj:Pointer);
|
||||
var
|
||||
node:p_rmem_vaddr_instance;
|
||||
start:vm_offset_t;
|
||||
__end:vm_offset_t;
|
||||
begin
|
||||
node:=TAILQ_FIRST(@entry^.vlist);
|
||||
|
||||
while (node<>nil) do
|
||||
begin
|
||||
|
||||
start:=node^.vaddr+diff;
|
||||
__end:=start+size;
|
||||
|
||||
_vm_track_map_insert(tmap,start,__end,tobj);
|
||||
|
||||
node:=TAILQ_NEXT(node,@node^.entry);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure rmem_map_track(map:p_rmem_map;
|
||||
start,__end:DWORD;
|
||||
tobj:Pointer);
|
||||
var
|
||||
entry:p_rmem_map_entry;
|
||||
|
||||
e_start:DWORD;
|
||||
e___end:DWORD;
|
||||
|
||||
diff:QWORD;
|
||||
size:QWORD;
|
||||
begin
|
||||
rmem_map_lock(map);
|
||||
|
||||
vm_track_map_lock(map^.tmap);
|
||||
|
||||
if (rmem_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 (start>e_start) then
|
||||
begin
|
||||
e_start:=start;
|
||||
end;
|
||||
|
||||
if (__end<e___end) then
|
||||
begin
|
||||
e___end:=__end;
|
||||
end;
|
||||
|
||||
if (e___end>e_start) then
|
||||
begin
|
||||
diff:=IDX_TO_OFF(e_start-entry^.start);
|
||||
size:=IDX_TO_OFF(e___end-e_start);
|
||||
|
||||
rmem_entry_track(map^.tmap,entry,diff,size,tobj);
|
||||
end;
|
||||
|
||||
entry:=entry^.next;
|
||||
end;
|
||||
|
||||
vm_track_map_unlock(map^.tmap);
|
||||
|
||||
rmem_map_unlock(map);
|
||||
end;
|
||||
|
||||
|
||||
|
||||
|
||||
end.
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ type
|
|||
busy :Integer;
|
||||
root :vm_map_entry_t; // Root of a binary search tree
|
||||
pmap :pmap_t; // (c) Physical map
|
||||
rmap :Pointer;
|
||||
rmap :Pointer; // p_rmem_map
|
||||
entry_id :QWORD;
|
||||
property min_offset:vm_offset_t read header.start write header.start;
|
||||
property max_offset:vm_offset_t read header.__end write header.__end;
|
||||
|
@ -81,7 +81,7 @@ type
|
|||
vm_daddr :caddr_t; // (c) user virtual address of data
|
||||
vm_maxsaddr :caddr_t; // user VA at max stack growth
|
||||
//
|
||||
vm_pmap :_pmap; // private physical map
|
||||
vm_pmap :t_pmap; // private physical map
|
||||
end;
|
||||
|
||||
const
|
||||
|
@ -276,6 +276,8 @@ procedure vm_map_set_name(map:vm_map_t;start,__end:vm_offset_t;name:PChar);
|
|||
procedure vm_map_set_name_locked(map:vm_map_t;start,__end:vm_offset_t;name:PChar);
|
||||
procedure vm_map_set_name_locked(map:vm_map_t;start,__end:vm_offset_t;name:PChar;i:vm_inherit_t);
|
||||
|
||||
procedure vm_map_track(map:vm_map_t;start,__end:vm_offset_t;tobj:Pointer);
|
||||
|
||||
function vmspace_pmap(vm:p_vmspace):pmap_t; inline;
|
||||
|
||||
procedure vm_map_entry_deallocate(entry:vm_map_entry_t);
|
||||
|
@ -288,6 +290,7 @@ uses
|
|||
md_map,
|
||||
kern_proc,
|
||||
rmem_map,
|
||||
vm_tracking_map,
|
||||
kern_budget;
|
||||
|
||||
var
|
||||
|
@ -3292,10 +3295,94 @@ begin
|
|||
vm_map_unlock(map);
|
||||
end;
|
||||
|
||||
procedure vm_map_track(map:vm_map_t;start,__end:vm_offset_t;tobj:Pointer);
|
||||
var
|
||||
entry:vm_map_entry_t;
|
||||
obj:vm_object_t;
|
||||
|
||||
e_start:vm_offset_t;
|
||||
e___end:vm_offset_t;
|
||||
|
||||
diff:DWORD;
|
||||
size:DWORD;
|
||||
offset:DWORD;
|
||||
begin
|
||||
vm_map_lock(map);
|
||||
|
||||
VM_MAP_RANGE_CHECK(map, start, __end);
|
||||
|
||||
if (vm_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 (start>e_start) then
|
||||
begin
|
||||
e_start:=start;
|
||||
end;
|
||||
|
||||
if (__end<e___end) then
|
||||
begin
|
||||
e___end:=__end;
|
||||
end;
|
||||
|
||||
if (e___end>e_start) then
|
||||
begin
|
||||
obj:=entry^.vm_obj;
|
||||
|
||||
if (obj<>nil) then
|
||||
begin
|
||||
if ((obj^.flags and OBJ_DMEM_EXT)<>0) then
|
||||
begin
|
||||
//ext rmap track
|
||||
|
||||
diff:=OFF_TO_IDX(e_start-entry^.start);
|
||||
size:=OFF_TO_IDX(e___end-e_start);
|
||||
|
||||
offset:=OFF_TO_IDX(entry^.offset);
|
||||
offset:=offset+diff;
|
||||
|
||||
rmem_map_track(map^.rmap,
|
||||
offset,
|
||||
offset + size,
|
||||
tobj);
|
||||
|
||||
//next
|
||||
entry:=entry^.next;
|
||||
Continue;
|
||||
end;
|
||||
|
||||
//file mirrors TODO
|
||||
end;
|
||||
|
||||
//one map track
|
||||
vm_track_map_lock(@map^.pmap^.tr_map);
|
||||
_vm_track_map_insert(@map^.pmap^.tr_map,e_start,e___end,tobj);
|
||||
vm_track_map_unlock(@map^.pmap^.tr_map)
|
||||
end; //
|
||||
|
||||
entry:=entry^.next;
|
||||
end;
|
||||
|
||||
vm_map_unlock(map);
|
||||
end;
|
||||
|
||||
procedure vminit;
|
||||
begin
|
||||
p_proc.p_vmspace:=vmspace_alloc();
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -58,8 +58,8 @@ type
|
|||
offset :vm_ooffset_t; // offset into object
|
||||
end;
|
||||
|
||||
p_vm_nt_map=^_vm_nt_map;
|
||||
_vm_nt_map=object
|
||||
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
|
||||
|
@ -206,6 +206,7 @@ var
|
|||
next:vm_offset_t;
|
||||
base,size:vm_size_t;
|
||||
prot:Integer;
|
||||
mask:Integer;
|
||||
r:Integer;
|
||||
begin
|
||||
if (PAGE_PROT=nil) then Exit;
|
||||
|
@ -218,19 +219,23 @@ begin
|
|||
next:=pmap_scan_rwx(start,__end);
|
||||
|
||||
prot:=pmap_get_prot(start);
|
||||
|
||||
prot:=(prot and VM_RW);
|
||||
end else
|
||||
begin
|
||||
next:=pmap_scan(start,__end);
|
||||
|
||||
prot:=pmap_get_prot(start);
|
||||
prot:=(prot and VM_RW) and (not (prot shr PAGE_TRACK_SHIFT));
|
||||
|
||||
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
|
||||
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
|
||||
|
@ -1152,7 +1157,8 @@ procedure vm_nt_map_protect(map:p_vm_nt_map;
|
|||
prot :Integer);
|
||||
var
|
||||
entry:p_vm_nt_entry;
|
||||
base,size:vm_size_t;
|
||||
e_start:vm_offset_t;
|
||||
e___end:vm_offset_t;
|
||||
max:Integer;
|
||||
r:Integer;
|
||||
begin
|
||||
|
@ -1168,34 +1174,37 @@ begin
|
|||
|
||||
while (entry<>@map^.header) and (entry^.start<__end) do
|
||||
begin
|
||||
base:=entry^.start;
|
||||
size:=entry^.__end;
|
||||
e_start:=entry^.start;
|
||||
e___end:=entry^.__end;
|
||||
|
||||
if (base<start) then
|
||||
if (e_start<start) then
|
||||
begin
|
||||
base:=start;
|
||||
e_start:=start;
|
||||
end;
|
||||
|
||||
if (size>__end) then
|
||||
if (e___end>__end) then
|
||||
begin
|
||||
size:=__end;
|
||||
e___end:=__end;
|
||||
end;
|
||||
|
||||
size:=size-base;
|
||||
if (e___end>e_start) then
|
||||
begin
|
||||
|
||||
if (entry^.obj<>nil) then
|
||||
begin
|
||||
max:=entry^.obj^.maxp;
|
||||
end else
|
||||
begin
|
||||
max:=0;
|
||||
end;
|
||||
if (entry^.obj<>nil) then
|
||||
begin
|
||||
max:=entry^.obj^.maxp;
|
||||
end else
|
||||
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;
|
||||
|
||||
r:=md_protect(Pointer(base),size,(prot and max and VM_RW));
|
||||
if (r<>0) then
|
||||
begin
|
||||
Writeln('failed md_protect(',HexStr(base,11),',',HexStr(base+size,11),'):0x',HexStr(r,8));
|
||||
Assert(false,'vm_nt_map_protect');
|
||||
end;
|
||||
|
||||
entry:=entry^.next;
|
||||
|
@ -1208,7 +1217,8 @@ procedure vm_nt_map_prot_fix(map:p_vm_nt_map;
|
|||
mode :Integer);
|
||||
var
|
||||
entry:p_vm_nt_entry;
|
||||
e_start,e___end:vm_size_t;
|
||||
e_start:vm_offset_t;
|
||||
e___end:vm_offset_t;
|
||||
begin
|
||||
if (start=__end) then Exit;
|
||||
|
||||
|
@ -1238,7 +1248,10 @@ begin
|
|||
e___end:=__end;
|
||||
end;
|
||||
|
||||
vm_prot_fixup(map,e_start,e___end,entry^.obj^.maxp,mode);
|
||||
if (e___end>e_start) then
|
||||
begin
|
||||
vm_prot_fixup(map,e_start,e___end,entry^.obj^.maxp,mode);
|
||||
end;
|
||||
end;
|
||||
|
||||
entry:=entry^.next;
|
||||
|
|
|
@ -17,8 +17,14 @@ type
|
|||
__end:vm_offset_t;
|
||||
end;
|
||||
|
||||
t_on_destroy=function (handle:Pointer):Boolean;
|
||||
t_on_trigger=procedure(handle:Pointer;start,__end:vm_offset_t);
|
||||
const
|
||||
DO_NOTHING =0;
|
||||
DO_DELETE =1;
|
||||
DO_INCREMENT=2;
|
||||
|
||||
type
|
||||
t_on_destroy=function(handle:Pointer):Integer;
|
||||
t_on_trigger=function(handle:Pointer;start,__end:vm_offset_t):Integer;
|
||||
|
||||
p_vm_track_object=^t_vm_track_object;
|
||||
t_vm_track_object=record
|
||||
|
@ -63,15 +69,25 @@ type
|
|||
property max_offset:vm_offset_t read header.__end write header.__end;
|
||||
end;
|
||||
|
||||
procedure vm_track_map_init(map:p_vm_track_map;min,max:vm_offset_t);
|
||||
|
||||
//
|
||||
|
||||
function vm_track_object_allocate (handle:TObject;start,__end:vm_offset_t):p_vm_track_object;
|
||||
function vm_track_object_allocate (handle:Pointer;start,__end:vm_offset_t):p_vm_track_object;
|
||||
procedure vm_track_object_deallocate(obj:p_vm_track_object);
|
||||
procedure vm_track_object_reference (obj:p_vm_track_object);
|
||||
|
||||
//
|
||||
|
||||
procedure vm_track_map_lock (map:p_vm_track_map);
|
||||
procedure vm_track_map_unlock(map:p_vm_track_map);
|
||||
|
||||
function _vm_track_map_insert(map:p_vm_track_map;start,__end:vm_offset_t;obj:p_vm_track_object):Integer;
|
||||
|
||||
function _vm_track_map_insert_mirror(map:p_vm_track_map;src,dst,size:vm_offset_t):Integer;
|
||||
|
||||
//
|
||||
|
||||
function vm_track_map_insert_object(map:p_vm_track_map;obj:p_vm_track_object):Integer;
|
||||
function vm_track_map_remove_object(map:p_vm_track_map;obj:p_vm_track_object):Integer;
|
||||
function vm_track_map_remove_memory(map:p_vm_track_map;start,__end:vm_offset_t):Integer;
|
||||
|
@ -79,7 +95,7 @@ function vm_track_map_trigger (map:p_vm_track_map;start,__end:vm_offset_t)
|
|||
|
||||
implementation
|
||||
|
||||
function vm_track_object_allocate(handle:TObject;start,__end:vm_offset_t):p_vm_track_object;
|
||||
function vm_track_object_allocate(handle:Pointer;start,__end:vm_offset_t):p_vm_track_object;
|
||||
begin
|
||||
Result:=AllocMem(SizeOf(t_vm_track_object));
|
||||
|
||||
|
@ -106,7 +122,7 @@ begin
|
|||
|
||||
if (obj^.on_destroy<>nil) then
|
||||
begin
|
||||
if not obj^.on_destroy(obj^.handle) then
|
||||
if ((obj^.on_destroy(obj^.handle) and DO_DELETE)=0) then
|
||||
begin
|
||||
Exit;
|
||||
end;
|
||||
|
@ -123,8 +139,9 @@ begin
|
|||
System.InterlockedIncrement(obj^.ref_count);
|
||||
end;
|
||||
|
||||
procedure vm_track_object_trigger(map:p_vm_track_map;obj:p_vm_track_object;start,__end:vm_offset_t);
|
||||
function vm_track_object_trigger(map:p_vm_track_map;obj:p_vm_track_object;start,__end:vm_offset_t):Integer;
|
||||
begin
|
||||
Result:=DO_NOTHING;
|
||||
if (obj=nil) then Exit;
|
||||
|
||||
if (obj^.timestamp<>map^.timestamp) then
|
||||
|
@ -133,7 +150,10 @@ begin
|
|||
|
||||
if (obj^.on_trigger<>nil) then
|
||||
begin
|
||||
obj^.on_trigger(obj^.handle,start,__end);
|
||||
Result:=obj^.on_trigger(obj^.handle,start,__end);
|
||||
end else
|
||||
begin
|
||||
Result:=DO_INCREMENT;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
@ -230,21 +250,6 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure vm_track_entry_trigger(map:p_vm_track_map;entry:p_vm_track_map_entry;start,__end:vm_offset_t);
|
||||
var
|
||||
node:p_vm_track_object_instance;
|
||||
begin
|
||||
node:=TAILQ_FIRST(@entry^.instances);
|
||||
|
||||
while (node<>nil) do
|
||||
begin
|
||||
|
||||
vm_track_object_trigger(map,node^.obj,start,__end);
|
||||
|
||||
node:=TAILQ_NEXT(node,@node^.entry_link);
|
||||
end;
|
||||
end;
|
||||
|
||||
//
|
||||
|
||||
function in_obj_list(const b:TAILQ_HEAD;obj:p_vm_track_object):Boolean;
|
||||
|
@ -287,19 +292,19 @@ begin
|
|||
Result:=True;
|
||||
end;
|
||||
|
||||
procedure copy_obj_list(const src:TAILQ_HEAD;entry:p_vm_track_map_entry);
|
||||
procedure copy_obj_list(src,dst:p_vm_track_map_entry);
|
||||
var
|
||||
node:p_vm_track_object_instance;
|
||||
begin
|
||||
|
||||
TAILQ_INIT(@entry^.instances);
|
||||
TAILQ_INIT(@dst^.instances);
|
||||
|
||||
node:=TAILQ_FIRST(@src);
|
||||
node:=TAILQ_FIRST(@src^.instances);
|
||||
|
||||
while (node<>nil) do
|
||||
begin
|
||||
|
||||
_vm_track_entry_add_obj(entry,node^.obj);
|
||||
_vm_track_entry_add_obj(dst,node^.obj);
|
||||
|
||||
node:=TAILQ_NEXT(node,@node^.entry_link);
|
||||
end;
|
||||
|
@ -650,7 +655,7 @@ begin
|
|||
|
||||
new_entry^.__end:=start;
|
||||
|
||||
copy_obj_list(entry^.instances,new_entry);
|
||||
copy_obj_list(entry,new_entry);
|
||||
|
||||
entry^.start:=start;
|
||||
|
||||
|
@ -678,7 +683,7 @@ begin
|
|||
|
||||
entry^.__end:=__end;
|
||||
|
||||
copy_obj_list(entry^.instances,new_entry);
|
||||
copy_obj_list(entry,new_entry);
|
||||
|
||||
vm_track_map_entry_link(map, entry, new_entry);
|
||||
end;
|
||||
|
@ -691,11 +696,11 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function vm_track_map_insert(map:p_vm_track_map;start,__end:vm_offset_t;obj:p_vm_track_object):Integer;
|
||||
function _vm_track_map_insert(map:p_vm_track_map;start,__end:vm_offset_t;obj:p_vm_track_object):Integer;
|
||||
var
|
||||
current,entry:p_vm_track_map_entry;
|
||||
begin
|
||||
if (start=__end) then
|
||||
if (start>=__end) then
|
||||
begin
|
||||
Exit(KERN_SUCCESS);
|
||||
end;
|
||||
|
@ -736,7 +741,7 @@ begin
|
|||
|
||||
vm_track_map_lock(map);
|
||||
|
||||
Result:=vm_track_map_insert(map,obj^.main.start,obj^.main.__end,obj);
|
||||
Result:=_vm_track_map_insert(map,obj^.main.start,obj^.main.__end,obj);
|
||||
|
||||
vm_track_map_unlock(map);
|
||||
end;
|
||||
|
@ -889,24 +894,37 @@ begin
|
|||
end;
|
||||
|
||||
function vm_track_map_trigger(map:p_vm_track_map;start,__end:vm_offset_t):Integer;
|
||||
label
|
||||
_repeat;
|
||||
var
|
||||
last:vm_offset_t;
|
||||
current,entry:p_vm_track_map_entry;
|
||||
node,next:p_vm_track_object_instance;
|
||||
ret:Integer;
|
||||
change:Boolean;
|
||||
begin
|
||||
if (start=__end) then
|
||||
Result:=0; //count
|
||||
|
||||
if (start>=__end) or (map=nil) then
|
||||
begin
|
||||
Exit(KERN_SUCCESS);
|
||||
Exit;
|
||||
end;
|
||||
|
||||
if (map=nil) then
|
||||
begin
|
||||
Exit(KERN_INVALID_ARGUMENT);
|
||||
end;
|
||||
last:=start;
|
||||
|
||||
vm_track_map_lock(map);
|
||||
|
||||
vm_track_map_RANGE_CHECK(map, start, __end);
|
||||
vm_track_map_RANGE_CHECK(map, last, __end);
|
||||
|
||||
if (vm_track_map_lookup_entry(map, start, @entry)) then
|
||||
_repeat:
|
||||
|
||||
if (last>=__end) then
|
||||
begin
|
||||
vm_track_map_unlock(map);
|
||||
Exit;
|
||||
end;
|
||||
|
||||
if (vm_track_map_lookup_entry(map, last, @entry)) then
|
||||
begin
|
||||
//
|
||||
end else
|
||||
|
@ -918,12 +936,121 @@ begin
|
|||
while (current<>@map^.header) and (current^.start<__end) do
|
||||
begin
|
||||
|
||||
vm_track_entry_trigger(map,current,start,__end);
|
||||
last:=current^.__end;
|
||||
|
||||
change:=False;
|
||||
|
||||
node:=TAILQ_FIRST(@entry^.instances);
|
||||
|
||||
while (node<>nil) do
|
||||
begin
|
||||
next:=TAILQ_NEXT(node,@node^.entry_link);
|
||||
|
||||
ret:=vm_track_object_trigger(map,node^.obj,start,__end);
|
||||
|
||||
if ((ret and DO_DELETE)<>0) then
|
||||
begin
|
||||
//delete full object
|
||||
vm_track_map_delete_object(map, node^.obj);
|
||||
change:=True;
|
||||
end;
|
||||
|
||||
if ((ret and DO_INCREMENT)<>0) then
|
||||
begin
|
||||
Inc(Result);
|
||||
end;
|
||||
|
||||
node:=next;
|
||||
end;
|
||||
|
||||
if change then
|
||||
begin
|
||||
goto _repeat;
|
||||
end;
|
||||
|
||||
current:=current^.next;
|
||||
end;
|
||||
|
||||
vm_track_map_unlock(map);
|
||||
end;
|
||||
|
||||
function _vm_track_map_insert_mirror(map:p_vm_track_map;src,dst,size:vm_offset_t):Integer;
|
||||
label
|
||||
_repeat;
|
||||
var
|
||||
last :vm_offset_t;
|
||||
start:vm_offset_t;
|
||||
__end:vm_offset_t;
|
||||
e_start:vm_offset_t;
|
||||
e___end:vm_offset_t;
|
||||
d_start:vm_offset_t;
|
||||
d___end:vm_offset_t;
|
||||
entry:p_vm_track_map_entry;
|
||||
node,next:p_vm_track_object_instance;
|
||||
begin
|
||||
start:=src;
|
||||
__end:=src+size;
|
||||
|
||||
VM_MAP_ASSERT_LOCKED(map);
|
||||
|
||||
vm_track_map_RANGE_CHECK(map, start, __end);
|
||||
|
||||
last:=start;
|
||||
|
||||
_repeat:
|
||||
|
||||
if (last>=__end) then
|
||||
begin
|
||||
Exit;
|
||||
end;
|
||||
|
||||
if (vm_track_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;
|
||||
|
||||
last:=e___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
|
||||
d_start:=dst+(e_start-src);
|
||||
d___end:=d_start+(e___end-e_start);
|
||||
|
||||
node:=TAILQ_FIRST(@entry^.instances);
|
||||
|
||||
while (node<>nil) do
|
||||
begin
|
||||
next:=TAILQ_NEXT(node,@node^.entry_link);
|
||||
|
||||
_vm_track_map_insert(map,d_start,d___end,node^.obj);
|
||||
|
||||
node:=next;
|
||||
end;
|
||||
|
||||
goto _repeat;
|
||||
end;
|
||||
|
||||
entry:=entry^.next;
|
||||
end;
|
||||
|
||||
Result:=(KERN_SUCCESS);
|
||||
end;
|
||||
|
|
Loading…
Reference in New Issue