Memory v0.1.0

Source
Mapping, protecting and advising on pages of memory.

ProtectionNone

pub const ProtectionNone: int32 = 0x00;

PROT_NONE: the pages may not be touched at all.

Source

ProtectionRead

pub const ProtectionRead: int32 = 0x01;

PROT_READ: the pages may be read.

Source

ProtectionWrite

pub const ProtectionWrite: int32 = 0x02;

PROT_WRITE: the pages may be written.

Source

ProtectionExecute

pub const ProtectionExecute: int32 = 0x04;

PROT_EXEC: the pages may be executed.

Source

MapShared

pub const MapShared: int32 = 0x0001;

MAP_SHARED: writes are visible to other mappings of the same object and reach it.

Source

MapPrivate

pub const MapPrivate: int32 = 0x0002;

MAP_PRIVATE: writes are private to this mapping and never reach the object.

Source

MapFixed

pub const MapFixed: int32 = 0x0010;

MAP_FIXED: place the mapping exactly at the requested address, replacing whatever was there.

Source

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.

Source

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.

Source

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.

Source

Parameters

NameTypeDescription
address*opaquea hint for where to map, or null to let the kernel choose
lengthuinthow many bytes, rounded up to whole pages
protectionint32what may be done with the pages, as Protection* flags
flagsint32the mapping flags, as Map* values
fdint32the file to map, or -1 with MapAnonymous
offsetuint64where 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.

Source

Parameters

NameTypeDescription
address*opaquea page-aligned address to release from
lengthuinthow 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.

Source

Parameters

NameTypeDescription
address*opaquewhere 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.

Source

AdviseRandom

pub const AdviseRandom: int32 = 1;

MADV_RANDOM: the pages will be touched in no useful order.

Source

AdviseSequential

pub const AdviseSequential: int32 = 2;

MADV_SEQUENTIAL: the pages will be touched in order.

Source

AdviseWillNeed

pub const AdviseWillNeed: int32 = 3;

MADV_WILLNEED: the pages will be read soon.

Source

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.

Source

AdviseFree

pub const AdviseFree: int32 = 5;

MADV_FREE: the pages may be reclaimed, and read back as zero if they are.

Source

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.

Source

Parameters

NameTypeDescription
address*opaquea page-aligned address
lengthuinthow many bytes, rounded up to whole pages
protectionint32what 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.

Source

Parameters

NameTypeDescription
address*opaquea page-aligned address
lengthuinthow many bytes the advice covers
adviceint32one 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.

Source

HardwarePageSize

pub const HardwarePageSize: int32 = 7;

HW_PAGESIZE: the leaf under CtlHardware holding the page size, in bytes.

Source

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.

Source

Returns: the page size in bytes, or a negative error number