Function maskerad_memory_allocators::utils::round_up [] [src]

pub fn round_up(base: usize, align: usize) -> usize

Returns an index to an aligned memory location, given a starting memory location index and an alignment.

Explanation

Every data has an alignment requirement:

  • 8-bit data (1 bytes, u8 for example) can be aligned to every address in memory.

  • 32-bit data (4 bytes, u32 for example) must be 4-byte aligned. Its memory address must finish with 0x0, 0x4, 0x8 or 0xC.

  • 128-bit data (16 bytes) must be 16-byte aligned. Its memory address must finish with 0x0.

To return aligned memory blocks, you just allocate a little bit more memory than requested, adjust the address of the memory block upward, and return the address. Even with the small upward offset, the returned block of memory will still be large enough, since we allocated a bit more memory than requested.

In general, the number of additional bytes allocated equals the alignment of the data.

To know the amount by which the block of memory must be adjusted we:

  • create a mask: alignment - 1.

  • mask the least significant byte of the original memory address, to get the misalignment: original_address & mask.

  • calculate the adjustment, according to the misalignment: alignment - misalignment.

  • Add the adjustment to the original memory address, to get an aligned memory location: original_address + adjustment.

Example

original_address: 0x60758912.

alignment: 4 = 0x00000004. 4-byte aligned data.

mask: 4 - 1 = 3 = 0x00000003.

misalignment: 0x60758912 & 0x00000003 = 0x00000002.

adjustment: 0x00000004 - 0x00000002 = 0x00000002.

aligned_address: 0x60758912 + 0x00000002 = 0x60758914.

4-byte aligned data must reside in memory addresses finishing by 0x0, 0x4, 0x8 and 0xC. Our aligned_address is properly aligned !