Ensures that the stack pointer remains 16-byte aligned for the duration of the provided function. This alignment is necessary for AArch64 compliance, particularly for signal handlers that may be invoked during execution. While the compiler doesn't directly use the stack pointer for memory addressing, maintaining this alignment is crucial to prevent issues when handling signals.
(&mut self, f: F)
| 99 | /// pointer for memory addressing, maintaining this alignment is crucial |
| 100 | /// to prevent issues when handling signals. |
| 101 | pub fn with_aligned_sp<F, T>(&mut self, f: F) -> Result<T> |
| 102 | where |
| 103 | F: FnOnce(&mut Self) -> Result<T>, |
| 104 | { |
| 105 | let mut aligned = false; |
| 106 | let alignment: u32 = <Aarch64ABI as ABI>::call_stack_align().into(); |
| 107 | let addend: u32 = <Aarch64ABI as ABI>::initial_frame_size().into(); |
| 108 | let delta = calculate_frame_adjustment(self.sp_offset()?.as_u32(), addend, alignment); |
| 109 | if delta != 0 { |
| 110 | self.sub( |
| 111 | writable!(regs::sp()), |
| 112 | // Since we don't need to synchronize the shadow stack pointer |
| 113 | // when freeing stack space [^1], the stack pointer may become |
| 114 | // out of sync with the primary shadow stack pointer. Therefore, |
| 115 | // we use the shadow stack pointer as the reference for |
| 116 | // calculating any alignment delta (self.sp_offset). |
| 117 | // |
| 118 | // [1]: This approach avoids an unnecessary move instruction and |
| 119 | // maintains the invariant of not accessing memory below the |
| 120 | // current stack pointer, preventing issues with signal handlers |
| 121 | // and interrupts. |
| 122 | regs::shadow_sp(), |
| 123 | RegImm::i32(delta as i32), |
| 124 | OperandSize::S64, |
| 125 | )?; |
| 126 | |
| 127 | aligned = true; |
| 128 | } |
| 129 | |
| 130 | let res = f(self)?; |
| 131 | |
| 132 | if aligned { |
| 133 | self.move_shadow_sp_to_sp(); |
| 134 | } |
| 135 | |
| 136 | Ok(res) |
| 137 | } |
| 138 | } |
| 139 | |
| 140 | impl Masm for MacroAssembler { |
no test coverage detected