diff --git a/sys/md/md_exception.pas b/sys/md/md_exception.pas index 70002a74..d7308157 100644 --- a/sys/md/md_exception.pas +++ b/sys/md/md_exception.pas @@ -24,6 +24,7 @@ uses vm_map, vm_pmap, vm_pmap_prot, + vm_tracking_map, kern_proc, kern_jit_dynamic; @@ -110,7 +111,7 @@ begin Result:=VM_PROT_NONE; case v of 0:Result:=VM_PROT_READ; - 2:Result:=VM_PROT_WRITE; + 1:Result:=VM_PROT_WRITE; 8:Result:=VM_PROT_EXECUTE; end; end; @@ -273,7 +274,8 @@ begin if pmap_danger_zone(vm_map_t(p_proc.p_vmspace)^.pmap, get_pageflt_addr(p), - 256) then + 256 //TODO: access len + ) then begin Exit(EXCEPTION_CONTINUE_EXECUTION); end; @@ -281,6 +283,7 @@ begin case get_pageflt_err(p) of VM_PROT_READ: begin + //TODO: access len if ((ppmap_get_prot(get_pageflt_addr(p),256) and VM_PROT_READ)<>0) then begin Writeln(stderr,'Unhandled VM_PROT_READ'); @@ -288,9 +291,19 @@ begin end; VM_PROT_WRITE: begin + Writeln('TRACK_WRITE:',HexStr(get_pageflt_addr(p),10)); + + //TODO: access len if ((ppmap_get_prot(get_pageflt_addr(p),256) and VM_PROT_WRITE)<>0) then begin - Writeln(stderr,'Unhandled VM_PROT_WRITE'); + //trigger and restore + vm_map_track_trigger(p_proc.p_vmspace, + get_pageflt_addr(p), + get_pageflt_addr(p)+256, //TODO: access len + nil, + M_CPU_WRITE); + // + Exit(EXCEPTION_CONTINUE_EXECUTION); end; end; else; diff --git a/sys/md/vm_pmap.pas b/sys/md/vm_pmap.pas index 27b2ed80..7ab41c48 100644 --- a/sys/md/vm_pmap.pas +++ b/sys/md/vm_pmap.pas @@ -115,6 +115,10 @@ procedure pmap_prot_track(pmap :pmap_t; __end:vm_offset_t; prots:Byte); +procedure pmap_prot_restore(pmap :pmap_t; + start:vm_offset_t; + __end:vm_offset_t); + procedure pmap_madvise(pmap :pmap_t; obj :vm_object_t; start :vm_offset_t; @@ -1085,6 +1089,19 @@ begin TRACK_PROT or REMAP_PROT); end; +procedure pmap_prot_restore(pmap :pmap_t; + start:vm_offset_t; + __end:vm_offset_t); +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, + REMAP_PROT); +end; + procedure pmap_madvise(pmap :pmap_t; obj :vm_object_t; start :vm_offset_t; diff --git a/sys/vm/vm_map.pas b/sys/vm/vm_map.pas index aac464f1..ae69b28b 100644 --- a/sys/vm/vm_map.pas +++ b/sys/vm/vm_map.pas @@ -3425,6 +3425,11 @@ end; function vm_map_track_trigger(map:vm_map_t;start,__end:vm_offset_t;exclude:Pointer;mode:T_TRIGGER_MODE):Integer; begin Result:=vm_track_map_trigger(@map^.pmap^.tr_map,start,__end,exclude,mode); + + if (mode=M_CPU_WRITE) then + begin + pmap_prot_restore(map^.pmap,start,__end); + end; end; procedure vm_map_track_restore(map:vm_map_t;tobj:Pointer); diff --git a/sys/vm/vm_tracking_map.pas b/sys/vm/vm_tracking_map.pas index 65a7c529..b48a042e 100644 --- a/sys/vm/vm_tracking_map.pas +++ b/sys/vm/vm_tracking_map.pas @@ -499,7 +499,7 @@ begin vm_track_object_reference(obj); //update prot - if (pmap=nil) then //if not copy_obj_list + if (pmap<>nil) then //if not copy_obj_list begin _vm_track_entry_change_prot(pmap,entry,obj^.prot,0); end;