Initial back-edge CFI implementation (#3606)

Give the user the option to sign and to authenticate function
return addresses with the operations introduced by the Pointer
Authentication extension to the Arm instruction set architecture.

Copyright (c) 2021, Arm Limited.
This commit is contained in:
Anton Kirilov
2022-08-03 19:08:29 +01:00
committed by GitHub
parent 709716bb8e
commit a897742593
17 changed files with 319 additions and 43 deletions

View File

@@ -10,7 +10,25 @@
//
// - AAPCS64 section 6.2.3 The Frame Pointer[0]
pub unsafe fn get_next_older_pc_from_fp(fp: usize) -> usize {
*(fp as *mut usize).offset(1)
let mut pc = *(fp as *mut usize).offset(1);
// The return address might be signed, so we need to strip the highest bits
// (where the authentication code might be located) in order to obtain a
// valid address. We use the `XPACLRI` instruction, which is executed as a
// no-op by processors that do not support pointer authentication, so that
// the implementation is backward-compatible and there is no duplication.
// However, this instruction requires the LR register for both its input and
// output.
std::arch::asm!(
"mov lr, {pc}",
"xpaclri",
"mov {pc}, lr",
pc = inout(reg) pc,
out("lr") _,
options(nomem, nostack, preserves_flags, pure),
);
pc
}
pub unsafe fn get_next_older_fp_from_fp(fp: usize) -> usize {
*(fp as *mut usize)