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