diff --git a/sys/sys_mmap.pas b/sys/sys_mmap.pas index 3a32c882..d1e684f5 100644 --- a/sys/sys_mmap.pas +++ b/sys/sys_mmap.pas @@ -5,6 +5,9 @@ unit sys_mmap; interface +uses + vm_mmap; + const PROT_NONE =$00; // no permissions PROT_READ =$01; // pages can be read @@ -71,6 +74,10 @@ const MADV_CORE = 9; // revert to including pages in a core file MADV_PROTECT =10; // protect process from pageout kill +type + p_query_memory_prot=vm_mmap.p_query_memory_prot; + t_query_memory_prot=vm_mmap.t_query_memory_prot; + function mmap(_addr :Pointer; _len :QWORD; _prot :Integer; @@ -82,11 +89,11 @@ function munmap(addr:Pointer;len:QWORD):Integer; function mprotect(addr:Pointer;len:QWORD;prot:Integer):Integer; function madvise(addr:Pointer;len:QWORD;behav:Integer):Integer; function mname(addr:Pointer;len:QWORD;name:PChar):Integer; +function query_memory_protection(addr:Pointer;len:QWORD;info:p_query_memory_prot):Integer; implementation uses - vm_mmap, trap, thr_error; @@ -130,6 +137,13 @@ asm call cerror end; +function query_memory_protection(addr:Pointer;len:QWORD;info:p_query_memory_prot):Integer; assembler; nostackframe; +asm + movq sys_query_memory_protection,%rax + call fast_syscall + call cerror +end; + end. diff --git a/sys/test/project1.lpr b/sys/test/project1.lpr index 680f4c1f..42ccdcb5 100644 --- a/sys/test/project1.lpr +++ b/sys/test/project1.lpr @@ -61,6 +61,7 @@ function _thread(parameter:pointer):ptrint; var td:p_kthread; p:Pointer; + qr:t_query_memory_prot; begin Result:=0; NtWaitForSingleObject(event,false,nil); @@ -83,6 +84,9 @@ begin p:=mmap(Pointer($700000000),16*1024,PROT_CPU_ALL,MAP_ANON or MAP_FIXED,-1,0); Writeln(HexStr(p)); + Result:=query_memory_protection(Pointer($700000000),16*1024,@qr); + Writeln(Result); + p:=mmap(Pointer($700000000+16*1024),16*1024,PROT_CPU_ALL,MAP_ANON {or MAP_VOID} or MAP_FIXED,-1,0); Writeln(HexStr(p)); diff --git a/sys/vm/vm_mmap.pas b/sys/vm/vm_mmap.pas index e1c6902d..44432c71 100644 --- a/sys/vm/vm_mmap.pas +++ b/sys/vm/vm_mmap.pas @@ -5,6 +5,15 @@ unit vm_mmap; interface +type + p_query_memory_prot=^t_query_memory_prot; + t_query_memory_prot=packed record + start:Pointer; + __end:Pointer; + prot :Integer; + eflags:Integer; + end; + function sys_mmap(_addr :Pointer; _len :QWORD; _prot :Integer; @@ -16,6 +25,7 @@ function sys_munmap(addr:Pointer;len:QWORD):Integer; function sys_mprotect(addr:Pointer;len:QWORD;prot:Integer):Integer; function sys_madvise(addr:Pointer;len:QWORD;behav:Integer):Integer; function sys_mname(addr:Pointer;len:QWORD;name:PChar):Integer; +function sys_query_memory_protection(addr:Pointer;len:QWORD;info:p_query_memory_prot):Integer; implementation @@ -616,7 +626,36 @@ begin vm_map_set_name(@g_vmspace.vm_map,start,__end,@_name); end; - +function sys_query_memory_protection(addr:Pointer;len:QWORD;info:p_query_memory_prot):Integer; +var + map:vm_map_t; + _addr:vm_offset_t; + __end:vm_offset_t; + entry:vm_map_entry_t; + data:t_query_memory_prot; +begin + Result:=EINVAL; + _addr:=trunc_page(vm_offset_t(addr)); + map:=@g_vmspace.vm_map; + __end:=vm_map_max(map); + if (_addr<__end) or (_addr=__end) then + begin + vm_map_lock(map); + if not vm_map_lookup_entry(map,_addr,@entry) then + begin + vm_map_unlock(map); + Result:=EACCES; + end else + begin + data.start:=Pointer(entry^.start); + data.__end:=Pointer(entry^.__end); + data.prot:=(entry^.max_protection and entry^.protection); + data.eflags:=entry^.eflags; + vm_map_unlock(map); + Result:=copyout(@data,info,SizeOf(t_query_memory_prot)); + end; + end; +end; end. diff --git a/sys/vm/vm_object.pas b/sys/vm/vm_object.pas index 66abc193..ecc1d1bf 100644 --- a/sys/vm/vm_object.pas +++ b/sys/vm/vm_object.pas @@ -60,8 +60,6 @@ const OBJPR_NOTMAPPED=$2; // Don't unmap pages. OBJPR_NOTWIRED =$4; // Don't remove wired pages. - -//function vm_object_is_merges (_object:vm_object_t):Boolean; procedure vm_object_reference (_object:vm_object_t); function vm_object_allocate (t:objtype_t;size:vm_pindex_t):vm_object_t; procedure vm_object_deallocate(_object:vm_object_t); @@ -158,19 +156,6 @@ begin FreeMem(_object); end; -{ -function vm_object_is_merges(_object:vm_object_t):Boolean; -begin - if (_object=nil) then - begin - Result:=True; - end else - begin - Result:=(obj_type(_object^.otype)=OBJT_DMEM); - end; -end; -} - procedure vm_object_reference(_object:vm_object_t); begin if (_object=nil) then Exit; diff --git a/sys/vm/vm_pmap.pas b/sys/vm/vm_pmap.pas index ecd20ef4..ab9aad03 100644 --- a/sys/vm/vm_pmap.pas +++ b/sys/vm/vm_pmap.pas @@ -222,6 +222,22 @@ begin base_old:=base_old+VM_MIN_GPU_ADDRESS; end; + //set old to readonly + r:=NtProtectVirtualMemory( + NtCurrentProcess, + @base_old, + @size, + PAGE_READONLY, + nil + ); + + if (r<>0) then + begin + Writeln('failed NtProtectVirtualMemory:',r); + Assert(false,'pmap_protect'); + end; + + //alloc new r:=NtAllocateVirtualMemory( NtCurrentProcess, @base_new, @@ -237,6 +253,10 @@ begin Assert(false,'pmap_protect'); end; + //move data + Move(base_old^,base_new^,size); + + //free old r:=NtFreeVirtualMemory( NtCurrentProcess, @base_old, @@ -279,15 +299,12 @@ var begin Writeln('pmap_madv_free:',HexStr(start,11),':',HexStr(__end,11),':',HexStr(prot,2)); + //dont reset gpu mem + if is_gpu(prot) then Exit; + base:=Pointer(trunc_page(start)); size:=trunc_page(__end-start); - if is_gpu(prot) then - begin - //shift - base:=base+VM_MIN_GPU_ADDRESS; - end; - r:=NtAllocateVirtualMemory( NtCurrentProcess, @base,