[clang] [PAC][clang] Define `PointerAuthQualifier` and `PointerAuthenticationMode` (PR #84384)
Daniil Kovalev via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 8 09:04:14 PDT 2024
================
@@ -138,6 +140,165 @@ using CanQualType = CanQual<Type>;
#define TYPE(Class, Base) class Class##Type;
#include "clang/AST/TypeNodes.inc"
+/// Pointer-authentication qualifiers.
+class PointerAuthQualifier {
+ enum : uint32_t {
+ EnabledShift = 0,
+ EnabledBits = 1,
+ EnabledMask = 1 << EnabledShift,
+ AddressDiscriminatedShift = EnabledShift + EnabledBits,
+ AddressDiscriminatedBits = 1,
+ AddressDiscriminatedMask = 1 << AddressDiscriminatedShift,
+ AuthenticationModeShift =
+ AddressDiscriminatedShift + AddressDiscriminatedBits,
+ AuthenticationModeBits = 2,
+ AuthenticationModeMask = ((1 << AuthenticationModeBits) - 1)
+ << AuthenticationModeShift,
+ IsaPointerShift = AuthenticationModeShift + AuthenticationModeBits,
+ IsaPointerBits = 1,
+ IsaPointerMask = ((1 << IsaPointerBits) - 1) << IsaPointerShift,
+ AuthenticatesNullValuesShift = IsaPointerShift + IsaPointerBits,
+ AuthenticatesNullValuesBits = 1,
+ AuthenticatesNullValuesMask = ((1 << AuthenticatesNullValuesBits) - 1)
+ << AuthenticatesNullValuesShift,
+ KeyShift = AuthenticatesNullValuesShift + AuthenticatesNullValuesBits,
+ KeyBits = 10,
+ KeyMask = ((1 << KeyBits) - 1) << KeyShift,
+ DiscriminatorShift = KeyShift + KeyBits,
+ DiscriminatorBits = 16,
+ DiscriminatorMask = ((1u << DiscriminatorBits) - 1) << DiscriminatorShift,
+ };
+
+ // bits: |0 |1 |2..3 |4 |
+ // |Enabled|Address|AuthenticationMode|ISA pointer|
+ // bits: |5 |6..15| 16...31 |
+ // |AuthenticatesNull|Key |Discriminator|
+ uint32_t Data;
+
+ static_assert((EnabledBits + AddressDiscriminatedBits +
+ AuthenticationModeBits + IsaPointerBits +
+ AuthenticatesNullValuesBits + KeyBits + DiscriminatorBits) ==
+ 32,
+ "PointerAuthQualifier should be exactly 32 bits");
+ static_assert((EnabledMask + AddressDiscriminatedMask +
+ AuthenticationModeMask + IsaPointerMask +
+ AuthenticatesNullValuesMask + KeyMask + DiscriminatorMask) ==
+ 0xFFFFFFFF,
+ "All masks should cover the entire bits");
+ static_assert((EnabledMask ^ AddressDiscriminatedMask ^
----------------
kovdan01 wrote:
I think that both static assertions should be left (probably with messages changed to distinguish them - suggestions are welcome). What we want to check is that every single bit out of all 32 bits is present in one and only one of the constants (added a comment in code mentioning that).
If we only check the sum of the constants, we might miss a situation when some bits are present in more than one constant while others are not present at all, like `0b111 = 0b100 + 0b10 + 0b1 = 0b11 + 0b11 + 0b1`. Counting xor would reveal the issue.
If we only check the xor of the constants, we might miss a situation when all the bits are present, but some of them are present not once, but odd number of times, like `0b111 = 0b111 ^ 0b111 ^ 0b111`. Counting sum would reveal the issue (keeping in mind that arithmetic on `uint32_t` works on 2^32 modulo).
Since constants definition is not trivial, it's probably better to leave both assertions here to avoid potential. Please let me know if I miss smth.
https://github.com/llvm/llvm-project/pull/84384
More information about the cfe-commits
mailing list