Browse Source

Add `Protect_Flags` for `virtual.protect`

gingerBill 3 years ago
parent
commit
586a000152

+ 13 - 5
core/mem/virtual/virtual.odin

@@ -16,12 +16,11 @@ commit :: proc(data: rawptr, size: uint) {
 }
 
 reserve_and_commit :: proc(size: uint) -> (data: []byte, err: Allocator_Error) {
-	data = _reserve(size) or_return
+	data = reserve(size) or_return
 	commit(raw_data(data), size)
 	return
 }
 
-
 decommit :: proc(data: rawptr, size: uint) {
 	_decommit(data, size)
 }
@@ -30,12 +29,21 @@ release :: proc(data: rawptr, size: uint) {
 	_release(data, size)
 }
 
-protect :: proc(data: rawptr, size: uint) -> bool {
-	return _protect(data, size)
+Protect_Flag :: enum u32 {
+	Read,
+	Write,
+	Execute,
+}
+Protect_Flags :: distinct bit_set[Protect_Flag; u32]
+Protect_No_Access :: Protect_Flags{}
+
+protect :: proc(data: rawptr, size: uint, flags: Protect_Flags) -> bool {
+	return _protect(data, size, flags)
 }
 
 
 
+
 Memory_Block :: struct {
 	prev: ^Memory_Block,
 	base: [^]byte,
@@ -73,7 +81,7 @@ memory_alloc :: proc(size: int) -> (block: ^Memory_Block, err: Allocator_Error)
 	assert(pmblock.block.prev == nil)
 	
 	if (do_protection) {
-		protect(rawptr(uintptr(pmblock) + protect_offset), page_size)
+		protect(rawptr(uintptr(pmblock) + protect_offset), page_size, Protect_No_Access)
 	}
 	
 	pmblock.block.size = size

+ 7 - 2
core/mem/virtual/virtual_linux.odin

@@ -86,8 +86,13 @@ _decommit :: proc(data: rawptr, size: uint) {
 _release :: proc(data: rawptr, size: uint) {
 	munmap(data, size)
 }
-_protect :: proc(data: rawptr, size: uint) -> bool {
-	err := mprotect(data, size, PROT_NONE) 
+_protect :: proc(data: rawptr, size: uint, flags: Protect_Flags) -> bool {
+	pflags: c.int
+	pflags = PROT_NONE
+	if .Read    in flags { pflags |= PROT_READ  }
+	if .Write   in flags { pflags |= PROT_WRITE }
+	if .Execute in flags { pflags |= PROT_EXEC  }
+	err := mprotect(data, size, pflags)
 	return err != 0
 }
 

+ 18 - 2
core/mem/virtual/virtual_windows.odin

@@ -77,9 +77,25 @@ _decommit :: proc(data: rawptr, size: uint) {
 _release :: proc(data: rawptr, size: uint) {
 	VirtualFree(data, 0, MEM_RELEASE)
 }
-_protect :: proc(data: rawptr, size: uint) -> bool {
+_protect :: proc(data: rawptr, size: uint, flags: Protect_Flags) -> bool {
+	pflags: u32
+	pflags = PAGE_NOACCESS
+	switch flags {
+	case {}:                        pflags = PAGE_NOACCESS
+	case {.Read}:                   pflags = PAGE_READONLY
+	case {.Read, .Write}:           pflags = PAGE_READWRITE
+	case {.Write}:                  pflags = PAGE_WRITECOPY
+	case {.Execute}:                pflags = PAGE_EXECUTE
+	case {.Execute, .Read}:         pflags = PAGE_EXECUTE_READ
+	case {.Execute, .Read, .Write}: pflags = PAGE_EXECUTE_READWRITE
+	case {.Execute, .Write}:        pflags = PAGE_EXECUTE_WRITECOPY
+	case: 
+		return false
+	}
+	
+	
 	old_protect: u32
-	ok := VirtualProtect(data, size, PAGE_NOACCESS, &old_protect)
+	ok := VirtualProtect(data, size, pflags, &old_protect)
 	return bool(ok)
 }