1//===-- AArch64PointerAuth.h -- Harden code using PAuth ---------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_LIB_TARGET_AARCH64_AARCH64POINTERAUTH_H
10#define LLVM_LIB_TARGET_AARCH64_AARCH64POINTERAUTH_H
11
12#include "llvm/CodeGen/MachineBasicBlock.h"
13#include "llvm/CodeGen/Register.h"
14
15namespace llvm {
16namespace AArch64PAuth {
17
18/// Variants of check performed on an authenticated pointer.
19///
20/// In cases such as authenticating the LR value when performing a tail call
21/// or when re-signing a signed pointer with a different signing schema,
22/// a failed authentication may not generate an exception on its own and may
23/// create an authentication or signing oracle if not checked explicitly.
24///
25/// A number of check methods modify control flow in a similar way by
26/// rewriting the code
27///
28/// ```
29/// <authenticate LR>
30/// <more instructions>
31/// ```
32///
33/// as follows:
34///
35/// ```
36/// <authenticate LR>
37/// <method-specific checker>
38/// ret_block:
39/// <more instructions>
40/// ...
41///
42/// break_block:
43/// brk <code>
44/// ```
45enum class AuthCheckMethod {
46 /// Do not check the value at all
47 None,
48 /// Perform a load to a temporary register
49 DummyLoad,
50 /// Check by comparing bits 62 and 61 of the authenticated address.
51 ///
52 /// This method modifies control flow and inserts the following checker:
53 ///
54 /// ```
55 /// eor Xtmp, Xn, Xn, lsl #1
56 /// tbnz Xtmp, #62, break_block
57 /// ```
58 HighBitsNoTBI,
59 /// Check by comparing the authenticated value with an XPAC-ed one without
60 /// using PAuth instructions not encoded as HINT. Can only be applied to LR.
61 ///
62 /// This method modifies control flow and inserts the following checker:
63 ///
64 /// ```
65 /// mov Xtmp, LR
66 /// xpaclri ; encoded as "hint #7"
67 /// ; Note: at this point, the LR register contains the address as if
68 /// ; the authentication succeeded and the temporary register contains the
69 /// ; *real* result of authentication.
70 /// cmp Xtmp, LR
71 /// b.ne break_block
72 /// ```
73 XPACHint,
74};
75
76#define AUTH_CHECK_METHOD_CL_VALUES_COMMON \
77 clEnumValN(AArch64PAuth::AuthCheckMethod::None, "none", \
78 "Do not check authenticated address"), \
79 clEnumValN(AArch64PAuth::AuthCheckMethod::DummyLoad, "load", \
80 "Perform dummy load from authenticated address"), \
81 clEnumValN(AArch64PAuth::AuthCheckMethod::HighBitsNoTBI, \
82 "high-bits-notbi", \
83 "Compare bits 62 and 61 of address (TBI should be disabled)")
84
85#define AUTH_CHECK_METHOD_CL_VALUES_LR \
86 AUTH_CHECK_METHOD_CL_VALUES_COMMON, \
87 clEnumValN(AArch64PAuth::AuthCheckMethod::XPACHint, "xpac-hint", \
88 "Compare with the result of XPACLRI")
89
90/// Explicitly checks that pointer authentication succeeded.
91///
92/// Assuming AuthenticatedReg contains a value returned by one of the AUT*
93/// instructions, check the value using Method just before the instruction
94/// pointed to by MBBI. If the check succeeds, execution proceeds to the
95/// instruction pointed to by MBBI, otherwise a CPU exception is generated.
96///
97/// Some of the methods may need to know if the pointer was authenticated
98/// using an I-key or D-key and which register can be used as temporary.
99/// If an explicit BRK instruction is used to generate an exception, BrkImm
100/// specifies its immediate operand.
101void checkAuthenticatedRegister(MachineBasicBlock::iterator MBBI,
102 AuthCheckMethod Method,
103 Register AuthenticatedReg, Register TmpReg,
104 bool UseIKey, unsigned BrkImm);
105
106/// Returns the number of bytes added by checkAuthenticatedRegister.
107unsigned getCheckerSizeInBytes(AuthCheckMethod Method);
108
109} // end namespace AArch64PAuth
110} // end namespace llvm
111
112#endif
113