File indexing completed on 2026-05-10 08:36:50
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
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
0027
0028 constexpr uint16_t InitFiniPointerConstantDiscriminator = 0xD9D4;
0029
0030 constexpr unsigned PointerAuthKeyNone = -1;
0031
0032
0033
0034
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
0045
0046
0047 enum class ARM8_3Key : unsigned {
0048 ASIA = 0,
0049 ASIB = 1,
0050 ASDA = 2,
0051 ASDB = 3
0052 };
0053
0054
0055 enum class Discrimination : unsigned {
0056
0057 None,
0058
0059
0060 Type,
0061
0062
0063 Decl,
0064
0065
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
0167 bool ReturnAddresses = false;
0168
0169
0170 bool AuthTraps = false;
0171
0172
0173 bool IndirectGotos = false;
0174
0175
0176 bool AArch64JumpTableHardening = false;
0177
0178
0179 PointerAuthSchema FunctionPointers;
0180
0181
0182
0183 PointerAuthSchema CXXVTablePointers;
0184
0185
0186
0187
0188
0189 PointerAuthSchema CXXTypeInfoVTablePointer;
0190
0191
0192 PointerAuthSchema CXXVTTVTablePointers;
0193
0194
0195 PointerAuthSchema CXXVirtualFunctionPointers;
0196
0197
0198 PointerAuthSchema CXXVirtualVariadicFunctionPointers;
0199
0200
0201 PointerAuthSchema CXXMemberFunctionPointers;
0202
0203
0204 PointerAuthSchema InitFiniPointers;
0205 };
0206
0207 }
0208
0209 #endif