Memory v0.1.0
ProtectionNone
pub const ProtectionNone: int32 = 0x00;
PROT_NONE: the pages may not be touched at all.
ProtectionRead
pub const ProtectionRead: int32 = 0x01;
PROT_READ: the pages may be read.
ProtectionWrite
pub const ProtectionWrite: int32 = 0x02;
PROT_WRITE: the pages may be written.
ProtectionExecute
pub const ProtectionExecute: int32 = 0x04;
PROT_EXEC: the pages may be executed.
MapShared
pub const MapShared: int32 = 0x0001;
MAP_SHARED: writes are visible to other mappings of the same object and reach it.
MapPrivate
pub const MapPrivate: int32 = 0x0002;
MAP_PRIVATE: writes are private to this mapping and never reach the object.
MapFixed
pub const MapFixed: int32 = 0x0010;
MAP_FIXED: place the mapping exactly at the requested address, replacing whatever was there.
MapExclusive
pub const MapExclusive: int32 = 0x4000;
MAP_EXCL: with MapFixed, refuse the address rather than replace what occupies it.
The one way to ask whether a range is free: a fixed, exclusive request over anything already mapped fails with
ENOMEM, and one over a hole takes it. Mprotect cannot answer that question, since it skips the holes in a
range rather than refusing them.
MapAnonymous
pub const MapAnonymous: int32 = 0x1000;
MAP_ANON: the mapping is backed by zeroed pages rather than by a file.
FreeBSD numbers this differently from Linux, which is one of the reasons the two packages are separate.
Mmap
pub func Mmap(
address: *opaque,
length: uint,
protection: int32,
flags: int32,
fd: int32,
offset: uint64
) -> int64
Creates a mapping and returns its address, or a negative error number.
address is a hint unless MapFixed is set. fd is the object to map, or -1 with MapAnonymous. Testing the
result needs Errors::IsError rather than a sign test, since a valid address may have its top bit set.
MapFixed replaces whatever occupies the address, including a mapping this program depends on, unless
MapExclusive is set with it.
Parameters
| Name | Type | Description |
|---|---|---|
address | *opaque | a hint for where to map, or null to let the kernel choose |
length | uint | how many bytes, rounded up to whole pages |
protection | int32 | what may be done with the pages, as Protection* flags |
flags | int32 | the mapping flags, as Map* values |
fd | int32 | the file to map, or -1 with MapAnonymous |
offset | uint64 | where in the file the mapping starts |
Returns: the mapping's address, or a negative error number
Munmap
pub func Munmap(address: *opaque, length: uint) -> int64
Releases the mapping that begins at address and spans length bytes.
Returns zero, or a negative error number. Releasing a range that was never mapped succeeds and does nothing.
Every pointer into the range becomes invalid.
Parameters
| Name | Type | Description |
|---|---|---|
address | *opaque | a page-aligned address to release from |
length | uint | how many bytes to release |
Returns: zero, or a negative error number
Brk
pub func Brk(address: *opaque) -> int64
Sets the program break and returns where it ended up. Reports failure by not moving rather than by an error number. The break is a single process-wide value.
Parameters
| Name | Type | Description |
|---|---|---|
address | *opaque | where to move the program break, or null to read it |
Returns: the resulting break, or a negative error number
AdviseNormal
pub const AdviseNormal: int32 = 0;
MADV_NORMAL: no advice; the default.
AdviseRandom
pub const AdviseRandom: int32 = 1;
MADV_RANDOM: the pages will be touched in no useful order.
AdviseSequential
pub const AdviseSequential: int32 = 2;
MADV_SEQUENTIAL: the pages will be touched in order.
AdviseWillNeed
pub const AdviseWillNeed: int32 = 3;
MADV_WILLNEED: the pages will be read soon.
AdviseDontNeed
pub const AdviseDontNeed: int32 = 4;
MADV_DONTNEED: the pages are not needed soon.
FreeBSD's meaning is weaker than Linux's: it does not discard the pages, so an anonymous page does not read back
as zero afterwards. MADV_FREE is the one that lets the kernel take the storage, and that difference is exactly
why an advice value must not be carried between the two packages.
AdviseFree
pub const AdviseFree: int32 = 5;
MADV_FREE: the pages may be reclaimed, and read back as zero if they are.
Mprotect
pub func Mprotect(
address: *opaque,
length: uint,
protection: int32
) -> int64
Changes what may be done with the pages covering a range.
address must be page-aligned. Returns zero, or a negative error number. Removing a permission takes effect at
once, so a thread touching the range concurrently faults.
Nothing checks that the range was ever mapped, and a hardened system refuses writable executable memory.
Parameters
| Name | Type | Description |
|---|---|---|
address | *opaque | a page-aligned address |
length | uint | how many bytes, rounded up to whole pages |
protection | int32 | what may be done with them afterwards |
Returns: zero, or a negative error number
Madvise
pub func Madvise(
address: *opaque,
length: uint,
advice: int32
) -> int64
Tells the kernel how the pages covering a range are about to be used.
Advice is advice: the kernel is free to ignore it. AdviseFree is the one that actually releases storage.
AdviseFree loses whatever the range held.
Parameters
| Name | Type | Description |
|---|---|---|
address | *opaque | a page-aligned address |
length | uint | how many bytes the advice covers |
advice | int32 | one of the Advise* values |
Returns: zero, or a negative error number
CtlHardware
pub const CtlHardware: int32 = 6;
CTL_HW: the sysctl branch describing the machine.
HardwarePageSize
pub const HardwarePageSize: int32 = 7;
HW_PAGESIZE: the leaf under CtlHardware holding the page size, in bytes.
QueryPageSize
pub func QueryPageSize() -> int64
The size of a page, asked of the kernel.
FreeBSD publishes this as the hw.pagesize sysctl rather than as a dedicated call, and that is the query this
package uses: it needs no libc, no auxiliary vector and no state captured at process start. The value is a
power of two and is the granularity Mmap rounds to.
A caller that cannot use a failure has no business asking: the whole point of returning one is that a system
which will not answer is not a system to guess about.
Returns: the page size in bytes, or a negative error number