xref: /freebsd/contrib/llvm-project/clang/include/clang/Basic/PointerAuthOptions.h (revision e64bea71c21eb42e97aa615188ba91f6cce0d36d)
1 //===--- PointerAuthOptions.h -----------------------------------*- 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 //  This file defines options for configuring pointer-auth technologies
10 //  like ARMv8.3.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H
15 #define LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H
16 
17 #include "clang/Basic/LLVM.h"
18 #include "clang/Basic/LangOptions.h"
19 #include "llvm/ADT/STLForwardCompat.h"
20 #include "llvm/Support/ErrorHandling.h"
21 #include "llvm/Target/TargetOptions.h"
22 #include <optional>
23 
24 namespace clang {
25 
26 /// Constant discriminator to be used with block descriptor pointers. The value
27 /// is ptrauth_string_discriminator("block_descriptor")
28 constexpr uint16_t BlockDescriptorConstantDiscriminator = 0xC0BB;
29 
30 /// Constant discriminator to be used with function pointers in .init_array and
31 /// .fini_array. The value is ptrauth_string_discriminator("init_fini")
32 constexpr uint16_t InitFiniPointerConstantDiscriminator = 0xD9D4;
33 
34 /// Constant discriminator to be used with method list pointers. The value is
35 /// ptrauth_string_discriminator("method_list_t")
36 constexpr uint16_t MethodListPointerConstantDiscriminator = 0xC310;
37 
38 /// Constant discriminator to be used with objective-c isa pointers. The value
39 /// is ptrauth_string_discriminator("isa")
40 constexpr uint16_t IsaPointerConstantDiscriminator = 0x6AE1;
41 
42 /// Constant discriminator to be used with objective-c superclass pointers.
43 /// The value is ptrauth_string_discriminator("objc_class:superclass")
44 constexpr uint16_t SuperPointerConstantDiscriminator = 0xB5AB;
45 
46 /// Constant discriminator to be used with objective-c sel pointers. The value
47 /// is ptrauth_string_discriminator("sel")
48 constexpr uint16_t SelPointerConstantDiscriminator = 0x57c2;
49 
50 /// Constant discriminator to be used with objective-c class_ro_t pointers.
51 /// The value is ptrauth_string_discriminator("class_data_bits")
52 constexpr uint16_t ClassROConstantDiscriminator = 0x61F8;
53 
54 constexpr unsigned PointerAuthKeyNone = -1;
55 
56 /// Constant discriminator for std::type_info vtable pointers: 0xB1EA/45546
57 /// The value is ptrauth_string_discriminator("_ZTVSt9type_info"), i.e.,
58 /// the vtable type discriminator for classes derived from std::type_info.
59 constexpr uint16_t StdTypeInfoVTablePointerConstantDiscrimination = 0xB1EA;
60 
61 class PointerAuthSchema {
62 public:
63   enum class Kind : unsigned {
64     None,
65     ARM8_3,
66   };
67 
68   /// Hardware pointer-signing keys in ARM8.3.
69   ///
70   /// These values are the same used in ptrauth.h.
71   enum class ARM8_3Key : unsigned {
72     ASIA = 0,
73     ASIB = 1,
74     ASDA = 2,
75     ASDB = 3
76   };
77 
78   /// Forms of extra discrimination.
79   enum class Discrimination : unsigned {
80     /// No additional discrimination.
81     None,
82 
83     /// Include a hash of the entity's type.
84     Type,
85 
86     /// Include a hash of the entity's identity.
87     Decl,
88 
89     /// Discriminate using a constant value.
90     Constant,
91   };
92 
93 private:
94   Kind TheKind : 2;
95   unsigned IsAddressDiscriminated : 1;
96   unsigned IsIsaPointer : 1;
97   unsigned AuthenticatesNullValues : 1;
98   PointerAuthenticationMode SelectedAuthenticationMode : 2;
99   Discrimination DiscriminationKind : 2;
100   unsigned Key : 2;
101   unsigned ConstantDiscriminator : 16;
102 
103 public:
PointerAuthSchema()104   PointerAuthSchema() : TheKind(Kind::None) {}
105 
106   PointerAuthSchema(
107       ARM8_3Key Key, bool IsAddressDiscriminated,
108       PointerAuthenticationMode AuthenticationMode,
109       Discrimination OtherDiscrimination,
110       std::optional<uint16_t> ConstantDiscriminatorOrNone = std::nullopt,
111       bool IsIsaPointer = false, bool AuthenticatesNullValues = false)
TheKind(Kind::ARM8_3)112       : TheKind(Kind::ARM8_3), IsAddressDiscriminated(IsAddressDiscriminated),
113         IsIsaPointer(IsIsaPointer),
114         AuthenticatesNullValues(AuthenticatesNullValues),
115         SelectedAuthenticationMode(AuthenticationMode),
116         DiscriminationKind(OtherDiscrimination), Key(llvm::to_underlying(Key)) {
117     assert((getOtherDiscrimination() != Discrimination::Constant ||
118             ConstantDiscriminatorOrNone) &&
119            "constant discrimination requires a constant!");
120     if (ConstantDiscriminatorOrNone)
121       ConstantDiscriminator = *ConstantDiscriminatorOrNone;
122   }
123 
124   PointerAuthSchema(
125       ARM8_3Key Key, bool IsAddressDiscriminated,
126       Discrimination OtherDiscrimination,
127       std::optional<uint16_t> ConstantDiscriminatorOrNone = std::nullopt,
128       bool IsIsaPointer = false, bool AuthenticatesNullValues = false)
PointerAuthSchema(Key,IsAddressDiscriminated,PointerAuthenticationMode::SignAndAuth,OtherDiscrimination,ConstantDiscriminatorOrNone,IsIsaPointer,AuthenticatesNullValues)129       : PointerAuthSchema(Key, IsAddressDiscriminated,
130                           PointerAuthenticationMode::SignAndAuth,
131                           OtherDiscrimination, ConstantDiscriminatorOrNone,
132                           IsIsaPointer, AuthenticatesNullValues) {}
133 
getKind()134   Kind getKind() const { return TheKind; }
135 
136   explicit operator bool() const { return isEnabled(); }
137 
isEnabled()138   bool isEnabled() const { return getKind() != Kind::None; }
139 
isAddressDiscriminated()140   bool isAddressDiscriminated() const {
141     assert(getKind() != Kind::None);
142     return IsAddressDiscriminated;
143   }
144 
isIsaPointer()145   bool isIsaPointer() const {
146     assert(getKind() != Kind::None);
147     return IsIsaPointer;
148   }
149 
authenticatesNullValues()150   bool authenticatesNullValues() const {
151     assert(getKind() != Kind::None);
152     return AuthenticatesNullValues;
153   }
154 
hasOtherDiscrimination()155   bool hasOtherDiscrimination() const {
156     return getOtherDiscrimination() != Discrimination::None;
157   }
158 
getOtherDiscrimination()159   Discrimination getOtherDiscrimination() const {
160     assert(getKind() != Kind::None);
161     return DiscriminationKind;
162   }
163 
getConstantDiscrimination()164   uint16_t getConstantDiscrimination() const {
165     assert(getOtherDiscrimination() == Discrimination::Constant);
166     return ConstantDiscriminator;
167   }
168 
getKey()169   unsigned getKey() const {
170     switch (getKind()) {
171     case Kind::None:
172       llvm_unreachable("calling getKey() on disabled schema");
173     case Kind::ARM8_3:
174       return llvm::to_underlying(getARM8_3Key());
175     }
176     llvm_unreachable("bad key kind");
177   }
178 
getAuthenticationMode()179   PointerAuthenticationMode getAuthenticationMode() const {
180     return SelectedAuthenticationMode;
181   }
182 
getARM8_3Key()183   ARM8_3Key getARM8_3Key() const {
184     assert(getKind() == Kind::ARM8_3);
185     return ARM8_3Key(Key);
186   }
187 };
188 
189 struct PointerAuthOptions {
190   /// Should return addresses be authenticated?
191   bool ReturnAddresses = false;
192 
193   /// Do authentication failures cause a trap?
194   bool AuthTraps = false;
195 
196   /// Do indirect goto label addresses need to be authenticated?
197   bool IndirectGotos = false;
198 
199   /// Use hardened lowering for jump-table dispatch?
200   bool AArch64JumpTableHardening = false;
201 
202   /// The ABI for C function pointers.
203   PointerAuthSchema FunctionPointers;
204 
205   /// The ABI for C++ virtual table pointers (the pointer to the table
206   /// itself) as installed in an actual class instance.
207   PointerAuthSchema CXXVTablePointers;
208 
209   /// TypeInfo has external ABI requirements and is emitted without
210   /// actually having parsed the libcxx definition, so we can't simply
211   /// perform a look up. The settings for this should match the exact
212   /// specification in type_info.h
213   PointerAuthSchema CXXTypeInfoVTablePointer;
214 
215   /// The ABI for C++ virtual table pointers as installed in a VTT.
216   PointerAuthSchema CXXVTTVTablePointers;
217 
218   /// The ABI for most C++ virtual function pointers, i.e. v-table entries.
219   PointerAuthSchema CXXVirtualFunctionPointers;
220 
221   /// The ABI for variadic C++ virtual function pointers.
222   PointerAuthSchema CXXVirtualVariadicFunctionPointers;
223 
224   /// The ABI for C++ member function pointers.
225   PointerAuthSchema CXXMemberFunctionPointers;
226 
227   /// The ABI for function addresses in .init_array and .fini_array
228   PointerAuthSchema InitFiniPointers;
229 
230   /// The ABI for block invocation function pointers.
231   PointerAuthSchema BlockInvocationFunctionPointers;
232 
233   /// The ABI for block object copy/destroy function pointers.
234   PointerAuthSchema BlockHelperFunctionPointers;
235 
236   /// The ABI for __block variable copy/destroy function pointers.
237   PointerAuthSchema BlockByrefHelperFunctionPointers;
238 
239   /// The ABI for pointers to block descriptors.
240   PointerAuthSchema BlockDescriptorPointers;
241 
242   /// The ABI for Objective-C method lists.
243   PointerAuthSchema ObjCMethodListFunctionPointers;
244 
245   /// The ABI for a reference to an Objective-C method list in _class_ro_t.
246   PointerAuthSchema ObjCMethodListPointer;
247 
248   /// The ABI for Objective-C isa pointers.
249   PointerAuthSchema ObjCIsaPointers;
250 
251   /// The ABI for Objective-C superclass pointers.
252   PointerAuthSchema ObjCSuperPointers;
253 
254   /// The ABI for Objective-C class_ro_t pointers.
255   PointerAuthSchema ObjCClassROPointers;
256 };
257 
258 } // end namespace clang
259 
260 #endif
261