Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:50

0001 //===--- PointerAuthOptions.h -----------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 //  This file defines options for configuring pointer-auth technologies
0010 //  like ARMv8.3.
0011 //
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H
0015 #define LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H
0016 
0017 #include "clang/Basic/LLVM.h"
0018 #include "clang/Basic/LangOptions.h"
0019 #include "llvm/ADT/STLForwardCompat.h"
0020 #include "llvm/Support/ErrorHandling.h"
0021 #include "llvm/Target/TargetOptions.h"
0022 #include <optional>
0023 
0024 namespace clang {
0025 
0026 /// Constant discriminator to be used with function pointers in .init_array and
0027 /// .fini_array. The value is ptrauth_string_discriminator("init_fini")
0028 constexpr uint16_t InitFiniPointerConstantDiscriminator = 0xD9D4;
0029 
0030 constexpr unsigned PointerAuthKeyNone = -1;
0031 
0032 /// Constant discriminator for std::type_info vtable pointers: 0xB1EA/45546
0033 /// The value is ptrauth_string_discriminator("_ZTVSt9type_info"), i.e.,
0034 /// the vtable type discriminator for classes derived from std::type_info.
0035 constexpr uint16_t StdTypeInfoVTablePointerConstantDiscrimination = 0xB1EA;
0036 
0037 class PointerAuthSchema {
0038 public:
0039   enum class Kind : unsigned {
0040     None,
0041     ARM8_3,
0042   };
0043 
0044   /// Hardware pointer-signing keys in ARM8.3.
0045   ///
0046   /// These values are the same used in ptrauth.h.
0047   enum class ARM8_3Key : unsigned {
0048     ASIA = 0,
0049     ASIB = 1,
0050     ASDA = 2,
0051     ASDB = 3
0052   };
0053 
0054   /// Forms of extra discrimination.
0055   enum class Discrimination : unsigned {
0056     /// No additional discrimination.
0057     None,
0058 
0059     /// Include a hash of the entity's type.
0060     Type,
0061 
0062     /// Include a hash of the entity's identity.
0063     Decl,
0064 
0065     /// Discriminate using a constant value.
0066     Constant,
0067   };
0068 
0069 private:
0070   Kind TheKind : 2;
0071   unsigned IsAddressDiscriminated : 1;
0072   unsigned IsIsaPointer : 1;
0073   unsigned AuthenticatesNullValues : 1;
0074   PointerAuthenticationMode SelectedAuthenticationMode : 2;
0075   Discrimination DiscriminationKind : 2;
0076   unsigned Key : 2;
0077   unsigned ConstantDiscriminator : 16;
0078 
0079 public:
0080   PointerAuthSchema() : TheKind(Kind::None) {}
0081 
0082   PointerAuthSchema(
0083       ARM8_3Key Key, bool IsAddressDiscriminated,
0084       PointerAuthenticationMode AuthenticationMode,
0085       Discrimination OtherDiscrimination,
0086       std::optional<uint16_t> ConstantDiscriminatorOrNone = std::nullopt,
0087       bool IsIsaPointer = false, bool AuthenticatesNullValues = false)
0088       : TheKind(Kind::ARM8_3), IsAddressDiscriminated(IsAddressDiscriminated),
0089         IsIsaPointer(IsIsaPointer),
0090         AuthenticatesNullValues(AuthenticatesNullValues),
0091         SelectedAuthenticationMode(AuthenticationMode),
0092         DiscriminationKind(OtherDiscrimination), Key(llvm::to_underlying(Key)) {
0093     assert((getOtherDiscrimination() != Discrimination::Constant ||
0094             ConstantDiscriminatorOrNone) &&
0095            "constant discrimination requires a constant!");
0096     if (ConstantDiscriminatorOrNone)
0097       ConstantDiscriminator = *ConstantDiscriminatorOrNone;
0098   }
0099 
0100   PointerAuthSchema(
0101       ARM8_3Key Key, bool IsAddressDiscriminated,
0102       Discrimination OtherDiscrimination,
0103       std::optional<uint16_t> ConstantDiscriminatorOrNone = std::nullopt,
0104       bool IsIsaPointer = false, bool AuthenticatesNullValues = false)
0105       : PointerAuthSchema(Key, IsAddressDiscriminated,
0106                           PointerAuthenticationMode::SignAndAuth,
0107                           OtherDiscrimination, ConstantDiscriminatorOrNone,
0108                           IsIsaPointer, AuthenticatesNullValues) {}
0109 
0110   Kind getKind() const { return TheKind; }
0111 
0112   explicit operator bool() const { return isEnabled(); }
0113 
0114   bool isEnabled() const { return getKind() != Kind::None; }
0115 
0116   bool isAddressDiscriminated() const {
0117     assert(getKind() != Kind::None);
0118     return IsAddressDiscriminated;
0119   }
0120 
0121   bool isIsaPointer() const {
0122     assert(getKind() != Kind::None);
0123     return IsIsaPointer;
0124   }
0125 
0126   bool authenticatesNullValues() const {
0127     assert(getKind() != Kind::None);
0128     return AuthenticatesNullValues;
0129   }
0130 
0131   bool hasOtherDiscrimination() const {
0132     return getOtherDiscrimination() != Discrimination::None;
0133   }
0134 
0135   Discrimination getOtherDiscrimination() const {
0136     assert(getKind() != Kind::None);
0137     return DiscriminationKind;
0138   }
0139 
0140   uint16_t getConstantDiscrimination() const {
0141     assert(getOtherDiscrimination() == Discrimination::Constant);
0142     return ConstantDiscriminator;
0143   }
0144 
0145   unsigned getKey() const {
0146     switch (getKind()) {
0147     case Kind::None:
0148       llvm_unreachable("calling getKey() on disabled schema");
0149     case Kind::ARM8_3:
0150       return llvm::to_underlying(getARM8_3Key());
0151     }
0152     llvm_unreachable("bad key kind");
0153   }
0154 
0155   PointerAuthenticationMode getAuthenticationMode() const {
0156     return SelectedAuthenticationMode;
0157   }
0158 
0159   ARM8_3Key getARM8_3Key() const {
0160     assert(getKind() == Kind::ARM8_3);
0161     return ARM8_3Key(Key);
0162   }
0163 };
0164 
0165 struct PointerAuthOptions {
0166   /// Should return addresses be authenticated?
0167   bool ReturnAddresses = false;
0168 
0169   /// Do authentication failures cause a trap?
0170   bool AuthTraps = false;
0171 
0172   /// Do indirect goto label addresses need to be authenticated?
0173   bool IndirectGotos = false;
0174 
0175   /// Use hardened lowering for jump-table dispatch?
0176   bool AArch64JumpTableHardening = false;
0177 
0178   /// The ABI for C function pointers.
0179   PointerAuthSchema FunctionPointers;
0180 
0181   /// The ABI for C++ virtual table pointers (the pointer to the table
0182   /// itself) as installed in an actual class instance.
0183   PointerAuthSchema CXXVTablePointers;
0184 
0185   /// TypeInfo has external ABI requirements and is emitted without
0186   /// actually having parsed the libcxx definition, so we can't simply
0187   /// perform a look up. The settings for this should match the exact
0188   /// specification in type_info.h
0189   PointerAuthSchema CXXTypeInfoVTablePointer;
0190 
0191   /// The ABI for C++ virtual table pointers as installed in a VTT.
0192   PointerAuthSchema CXXVTTVTablePointers;
0193 
0194   /// The ABI for most C++ virtual function pointers, i.e. v-table entries.
0195   PointerAuthSchema CXXVirtualFunctionPointers;
0196 
0197   /// The ABI for variadic C++ virtual function pointers.
0198   PointerAuthSchema CXXVirtualVariadicFunctionPointers;
0199 
0200   /// The ABI for C++ member function pointers.
0201   PointerAuthSchema CXXMemberFunctionPointers;
0202 
0203   /// The ABI for function addresses in .init_array and .fini_array
0204   PointerAuthSchema InitFiniPointers;
0205 };
0206 
0207 } // end namespace clang
0208 
0209 #endif