mirror of
https://github.com/odin-lang/Odin.git
synced 2026-02-18 00:48:23 +00:00
mem/virtual: specify max protection on mmap call in NetBSD and FreeBSD
This commit is contained in:
20
core/mem/virtual/virtual_darwin.odin
Normal file
20
core/mem/virtual/virtual_darwin.odin
Normal file
@@ -0,0 +1,20 @@
|
||||
package mem_virtual
|
||||
|
||||
import "core:sys/posix"
|
||||
|
||||
_reserve :: proc "contextless" (size: uint) -> (data: []byte, err: Allocator_Error) {
|
||||
result := posix.mmap(nil, size, {}, {.ANONYMOUS, .PRIVATE})
|
||||
if result == posix.MAP_FAILED {
|
||||
assert_contextless(posix.errno() == .ENOMEM)
|
||||
return nil, .Out_Of_Memory
|
||||
}
|
||||
|
||||
return ([^]byte)(uintptr(result))[:size], nil
|
||||
}
|
||||
|
||||
_decommit :: proc "contextless" (data: rawptr, size: uint) {
|
||||
MADV_FREE :: 5
|
||||
|
||||
posix.mprotect(data, size, {})
|
||||
posix.posix_madvise(data, size, transmute(posix.MAdvice)i32(MADV_FREE))
|
||||
}
|
||||
26
core/mem/virtual/virtual_freebsd.odin
Normal file
26
core/mem/virtual/virtual_freebsd.odin
Normal file
@@ -0,0 +1,26 @@
|
||||
package mem_virtual
|
||||
|
||||
import "core:sys/posix"
|
||||
|
||||
_reserve :: proc "contextless" (size: uint) -> (data: []byte, err: Allocator_Error) {
|
||||
|
||||
PROT_MAX :: proc "contextless" (flags: posix.Prot_Flags) -> posix.Prot_Flags {
|
||||
_PROT_MAX_SHIFT :: 16
|
||||
return transmute(posix.Prot_Flags)(transmute(i32)flags << _PROT_MAX_SHIFT)
|
||||
}
|
||||
|
||||
result := posix.mmap(nil, size, PROT_MAX({.READ, .WRITE, .EXEC}), {.ANONYMOUS, .PRIVATE})
|
||||
if result == posix.MAP_FAILED {
|
||||
assert_contextless(posix.errno() == .ENOMEM)
|
||||
return nil, .Out_Of_Memory
|
||||
}
|
||||
|
||||
return ([^]byte)(uintptr(result))[:size], nil
|
||||
}
|
||||
|
||||
_decommit :: proc "contextless" (data: rawptr, size: uint) {
|
||||
MADV_FREE :: 5
|
||||
|
||||
posix.mprotect(data, size, {})
|
||||
posix.posix_madvise(data, size, transmute(posix.MAdvice)i32(MADV_FREE))
|
||||
}
|
||||
25
core/mem/virtual/virtual_netbsd.odin
Normal file
25
core/mem/virtual/virtual_netbsd.odin
Normal file
@@ -0,0 +1,25 @@
|
||||
package mem_virtual
|
||||
|
||||
import "core:sys/posix"
|
||||
|
||||
_reserve :: proc "contextless" (size: uint) -> (data: []byte, err: Allocator_Error) {
|
||||
|
||||
PROT_MPROTECT :: proc "contextless" (flags: posix.Prot_Flags) -> posix.Prot_Flags {
|
||||
return transmute(posix.Prot_Flags)(transmute(i32)flags << 3)
|
||||
}
|
||||
|
||||
result := posix.mmap(nil, size, PROT_MPROTECT({.READ, .WRITE, .EXEC}), {.ANONYMOUS, .PRIVATE})
|
||||
if result == posix.MAP_FAILED {
|
||||
assert_contextless(posix.errno() == .ENOMEM)
|
||||
return nil, .Out_Of_Memory
|
||||
}
|
||||
|
||||
return ([^]byte)(uintptr(result))[:size], nil
|
||||
}
|
||||
|
||||
_decommit :: proc "contextless" (data: rawptr, size: uint) {
|
||||
MADV_FREE :: 6
|
||||
|
||||
posix.mprotect(data, size, {})
|
||||
posix.posix_madvise(data, size, transmute(posix.MAdvice)i32(MADV_FREE))
|
||||
}
|
||||
20
core/mem/virtual/virtual_openbsd.odin
Normal file
20
core/mem/virtual/virtual_openbsd.odin
Normal file
@@ -0,0 +1,20 @@
|
||||
package mem_virtual
|
||||
|
||||
import "core:sys/posix"
|
||||
|
||||
_reserve :: proc "contextless" (size: uint) -> (data: []byte, err: Allocator_Error) {
|
||||
result := posix.mmap(nil, size, {}, {.ANONYMOUS, .PRIVATE})
|
||||
if result == posix.MAP_FAILED {
|
||||
assert_contextless(posix.errno() == .ENOMEM)
|
||||
return nil, .Out_Of_Memory
|
||||
}
|
||||
|
||||
return ([^]byte)(uintptr(result))[:size], nil
|
||||
}
|
||||
|
||||
_decommit :: proc "contextless" (data: rawptr, size: uint) {
|
||||
MADV_FREE :: 6
|
||||
|
||||
posix.mprotect(data, size, {})
|
||||
posix.posix_madvise(data, size, transmute(posix.MAdvice)i32(MADV_FREE))
|
||||
}
|
||||
@@ -15,7 +15,9 @@ platform_memory_alloc :: proc "contextless" (to_commit, to_reserve: uint) -> (bl
|
||||
to_commit = clamp(to_commit, size_of(Platform_Memory_Block), total_to_reserved)
|
||||
|
||||
data := reserve(total_to_reserved) or_return
|
||||
commit(raw_data(data), to_commit)
|
||||
|
||||
commit_err := commit(raw_data(data), to_commit)
|
||||
assert_contextless(commit_err == nil)
|
||||
|
||||
block = (^Platform_Memory_Block)(raw_data(data))
|
||||
block.committed = to_commit
|
||||
|
||||
@@ -4,36 +4,18 @@ package mem_virtual
|
||||
|
||||
import "core:sys/posix"
|
||||
|
||||
// Define non-posix needed flags:
|
||||
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD {
|
||||
MADV_FREE :: 5 /* pages unneeded, discard contents */
|
||||
} else when ODIN_OS == .OpenBSD || ODIN_OS == .NetBSD {
|
||||
MADV_FREE :: 6
|
||||
}
|
||||
|
||||
_reserve :: proc "contextless" (size: uint) -> (data: []byte, err: Allocator_Error) {
|
||||
flags := posix.Map_Flags{ .ANONYMOUS, .PRIVATE }
|
||||
result := posix.mmap(nil, size, {}, flags)
|
||||
if result == posix.MAP_FAILED {
|
||||
return nil, .Out_Of_Memory
|
||||
}
|
||||
|
||||
return ([^]byte)(uintptr(result))[:size], nil
|
||||
}
|
||||
|
||||
_commit :: proc "contextless" (data: rawptr, size: uint) -> Allocator_Error {
|
||||
if posix.mprotect(data, size, { .READ, .WRITE }) != .OK {
|
||||
return .Out_Of_Memory
|
||||
#partial switch posix.errno() {
|
||||
case .EACCES, .EPERM: return .Invalid_Pointer
|
||||
case .ENOTSUP, .EINVAL: return .Invalid_Argument
|
||||
case: return .Out_Of_Memory
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
_decommit :: proc "contextless" (data: rawptr, size: uint) {
|
||||
posix.mprotect(data, size, {})
|
||||
posix.posix_madvise(data, size, transmute(posix.MAdvice)i32(MADV_FREE))
|
||||
}
|
||||
|
||||
_release :: proc "contextless" (data: rawptr, size: uint) {
|
||||
posix.munmap(data, size)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user