25
25
#include " clang/Basic/Diagnostic.h"
26
26
#include " clang/Basic/ExceptionSpecificationType.h"
27
27
#include " clang/Basic/LLVM.h"
28
+ #include " clang/Basic/LangOptions.h"
28
29
#include " clang/Basic/Linkage.h"
29
30
#include " clang/Basic/PartialDiagnostic.h"
31
+ #include " clang/Basic/PointerAuthOptions.h"
30
32
#include " clang/Basic/SourceLocation.h"
31
33
#include " clang/Basic/Specifiers.h"
32
34
#include " clang/Basic/Visibility.h"
@@ -138,6 +140,166 @@ using CanQualType = CanQual<Type>;
138
140
#define TYPE (Class, Base ) class Class ##Type;
139
141
#include " clang/AST/TypeNodes.inc"
140
142
143
+ // / Pointer-authentication qualifiers.
144
+ class PointerAuthQualifier {
145
+ enum : uint32_t {
146
+ EnabledShift = 0 ,
147
+ EnabledBits = 1 ,
148
+ EnabledMask = 1 << EnabledShift,
149
+ AddressDiscriminatedShift = EnabledShift + EnabledBits,
150
+ AddressDiscriminatedBits = 1 ,
151
+ AddressDiscriminatedMask = 1 << AddressDiscriminatedShift,
152
+ AuthenticationModeShift =
153
+ AddressDiscriminatedShift + AddressDiscriminatedBits,
154
+ AuthenticationModeBits = 2 ,
155
+ AuthenticationModeMask = ((1 << AuthenticationModeBits) - 1 )
156
+ << AuthenticationModeShift,
157
+ IsaPointerShift = AuthenticationModeShift + AuthenticationModeBits,
158
+ IsaPointerBits = 1 ,
159
+ IsaPointerMask = ((1 << IsaPointerBits) - 1 ) << IsaPointerShift,
160
+ AuthenticatesNullValuesShift = IsaPointerShift + IsaPointerBits,
161
+ AuthenticatesNullValuesBits = 1 ,
162
+ AuthenticatesNullValuesMask = ((1 << AuthenticatesNullValuesBits) - 1 )
163
+ << AuthenticatesNullValuesShift,
164
+ KeyShift = AuthenticatesNullValuesShift + AuthenticatesNullValuesBits,
165
+ KeyBits = 10 ,
166
+ KeyMask = ((1 << KeyBits) - 1 ) << KeyShift,
167
+ DiscriminatorShift = KeyShift + KeyBits,
168
+ DiscriminatorBits = 16 ,
169
+ DiscriminatorMask = ((1u << DiscriminatorBits) - 1 ) << DiscriminatorShift,
170
+ };
171
+
172
+ // bits: |0 |1 |2..3 |4 |5 |6..15| 16...31 |
173
+ // |Enabled|Address|AuthenticationMode|ISA pointer|AuthenticatesNull|Key |Discriminator|
174
+ uint32_t Data;
175
+
176
+ static_assert ((EnabledBits + AddressDiscriminatedBits +
177
+ AuthenticationModeBits + IsaPointerBits +
178
+ AuthenticatesNullValuesBits + KeyBits + DiscriminatorBits) ==
179
+ 32 ,
180
+ " PointerAuthQualifier should be exactly 32 bits" );
181
+ static_assert ((EnabledMask + AddressDiscriminatedMask +
182
+ AuthenticationModeMask + IsaPointerMask +
183
+ AuthenticatesNullValuesMask + KeyMask + DiscriminatorMask) ==
184
+ 0xFFFFFFFF ,
185
+ " All masks should cover the entire bits" );
186
+ static_assert ((EnabledMask ^ AddressDiscriminatedMask ^
187
+ AuthenticationModeMask ^ IsaPointerMask ^
188
+ AuthenticatesNullValuesMask ^ KeyMask ^ DiscriminatorMask) ==
189
+ 0xFFFFFFFF ,
190
+ " All masks should cover the entire bits" );
191
+
192
+ PointerAuthQualifier (unsigned key, bool isAddressDiscriminated,
193
+ unsigned extraDiscriminator,
194
+ PointerAuthenticationMode authenticationMode,
195
+ bool isIsaPointer, bool authenticatesNullValues)
196
+ : Data(EnabledMask |
197
+ (isAddressDiscriminated
198
+ ? static_cast <uint32_t >(AddressDiscriminatedMask)
199
+ : 0 ) |
200
+ (key << KeyShift) |
201
+ (unsigned (authenticationMode) << AuthenticationModeShift) |
202
+ (extraDiscriminator << DiscriminatorShift) |
203
+ (isIsaPointer << IsaPointerShift) |
204
+ (authenticatesNullValues << AuthenticatesNullValuesShift)) {
205
+ assert (key <= KeyNoneInternal);
206
+ assert (extraDiscriminator <= MaxDiscriminator);
207
+ }
208
+
209
+ public:
210
+ enum {
211
+ KeyNoneInternal = (1u << KeyBits) - 1 ,
212
+
213
+ // / The maximum supported pointer-authentication key.
214
+ MaxKey = KeyNoneInternal - 1 ,
215
+
216
+ // / The maximum supported pointer-authentication discriminator.
217
+ MaxDiscriminator = (1u << DiscriminatorBits) - 1
218
+ };
219
+
220
+ public:
221
+ PointerAuthQualifier () : Data(0 ) {}
222
+
223
+ static PointerAuthQualifier
224
+ Create (int key, bool isAddressDiscriminated, unsigned extraDiscriminator,
225
+ PointerAuthenticationMode authenticationMode, bool isIsaPointer,
226
+ bool authenticatesNullValues) {
227
+ if (key == PointerAuthKeyNone)
228
+ key = KeyNoneInternal;
229
+ assert ((key >= 0 && key <= KeyNoneInternal) && " out-of-range key value" );
230
+ return PointerAuthQualifier (key, isAddressDiscriminated,
231
+ extraDiscriminator, authenticationMode,
232
+ isIsaPointer, authenticatesNullValues);
233
+ }
234
+
235
+ bool isPresent () const {
236
+ return getAuthenticationMode () != PointerAuthenticationMode::None;
237
+ }
238
+
239
+ explicit operator bool () const { return isPresent (); }
240
+
241
+ unsigned getKey () const {
242
+ assert (isPresent ());
243
+ return (Data & KeyMask) >> KeyShift;
244
+ }
245
+
246
+ bool hasKeyNone () const {
247
+ return isPresent () && getKey () == KeyNoneInternal;
248
+ }
249
+
250
+ bool isAddressDiscriminated () const {
251
+ assert (isPresent ());
252
+ return (Data & AddressDiscriminatedMask) >> AddressDiscriminatedShift;
253
+ }
254
+
255
+ unsigned getExtraDiscriminator () const {
256
+ assert (isPresent ());
257
+ return (Data >> DiscriminatorShift);
258
+ }
259
+
260
+ PointerAuthenticationMode getAuthenticationMode () const {
261
+ return PointerAuthenticationMode ((Data & AuthenticationModeMask) >>
262
+ AuthenticationModeShift);
263
+ }
264
+
265
+ bool isIsaPointer () const {
266
+ assert (isPresent ());
267
+ return (Data & IsaPointerMask) >> IsaPointerShift;
268
+ }
269
+
270
+ bool authenticatesNullValues () const {
271
+ assert (isPresent ());
272
+ return (Data & AuthenticatesNullValuesMask) >>
273
+ AuthenticatesNullValuesShift;
274
+ }
275
+
276
+ PointerAuthQualifier withoutKeyNone () const {
277
+ return hasKeyNone () ? PointerAuthQualifier () : *this ;
278
+ }
279
+
280
+ friend bool operator ==(PointerAuthQualifier Lhs, PointerAuthQualifier Rhs) {
281
+ return Lhs.Data == Rhs.Data ;
282
+ }
283
+ friend bool operator !=(PointerAuthQualifier Lhs, PointerAuthQualifier Rhs) {
284
+ return Lhs.Data != Rhs.Data ;
285
+ }
286
+
287
+ bool isEquivalent (PointerAuthQualifier Other) const {
288
+ return withoutKeyNone () == Other.withoutKeyNone ();
289
+ }
290
+
291
+ uint32_t getAsOpaqueValue () const { return Data; }
292
+
293
+ // Deserialize pointer-auth qualifiers from an opaque representation.
294
+ static PointerAuthQualifier fromOpaqueValue (uint32_t opaque) {
295
+ PointerAuthQualifier result;
296
+ result.Data = opaque;
297
+ return result;
298
+ }
299
+
300
+ void Profile (llvm::FoldingSetNodeID &ID) const { ID.AddInteger (Data); }
301
+ };
302
+
141
303
// / The collection of all-type qualifiers we support.
142
304
// / Clang supports five independent qualifiers:
143
305
// / * C99: const, volatile, and restrict
@@ -193,19 +355,27 @@ class Qualifiers {
193
355
FastMask = (1 << FastWidth) - 1
194
356
};
195
357
358
+ Qualifiers () : Mask(0 ), PtrAuth() {}
359
+
196
360
// / Returns the common set of qualifiers while removing them from
197
361
// / the given sets.
198
362
static Qualifiers removeCommonQualifiers (Qualifiers &L, Qualifiers &R) {
363
+ Qualifiers Q;
364
+ if (L.getPointerAuth ().isEquivalent (R.getPointerAuth ())) {
365
+ Q.setPointerAuth (L.getPointerAuth ().withoutKeyNone ());
366
+ PointerAuthQualifier Empty;
367
+ L.setPointerAuth (Empty);
368
+ R.setPointerAuth (Empty);
369
+ }
370
+
199
371
// If both are only CVR-qualified, bit operations are sufficient.
200
372
if (!(L.Mask & ~CVRMask) && !(R.Mask & ~CVRMask)) {
201
- Qualifiers Q;
202
373
Q.Mask = L.Mask & R.Mask ;
203
374
L.Mask &= ~Q.Mask ;
204
375
R.Mask &= ~Q.Mask ;
205
376
return Q;
206
377
}
207
378
208
- Qualifiers Q;
209
379
unsigned CommonCRV = L.getCVRQualifiers () & R.getCVRQualifiers ();
210
380
Q.addCVRQualifiers (CommonCRV);
211
381
L.removeCVRQualifiers (CommonCRV);
@@ -250,15 +420,16 @@ class Qualifiers {
250
420
}
251
421
252
422
// Deserialize qualifiers from an opaque representation.
253
- static Qualifiers fromOpaqueValue (unsigned opaque) {
423
+ static Qualifiers fromOpaqueValue (uint64_t opaque) {
254
424
Qualifiers Qs;
255
- Qs.Mask = opaque;
425
+ Qs.Mask = uint32_t (opaque);
426
+ Qs.PtrAuth = PointerAuthQualifier::fromOpaqueValue (uint32_t (opaque >> 32 ));
256
427
return Qs;
257
428
}
258
429
259
430
// Serialize these qualifiers into an opaque representation.
260
- unsigned getAsOpaqueValue () const {
261
- return Mask;
431
+ uint64_t getAsOpaqueValue () const {
432
+ return uint64_t ( Mask) | ( uint64_t (PtrAuth. getAsOpaqueValue ()) << 32 ) ;
262
433
}
263
434
264
435
bool hasConst () const { return Mask & Const; }
@@ -406,6 +577,10 @@ class Qualifiers {
406
577
setAddressSpace (space);
407
578
}
408
579
580
+ PointerAuthQualifier getPointerAuth () const { return PtrAuth; }
581
+ void setPointerAuth (PointerAuthQualifier q) { PtrAuth = q; }
582
+ void removePtrAuth () { PtrAuth = PointerAuthQualifier (); }
583
+
409
584
// Fast qualifiers are those that can be allocated directly
410
585
// on a QualType object.
411
586
bool hasFastQualifiers () const { return getFastQualifiers (); }
@@ -428,16 +603,16 @@ class Qualifiers {
428
603
429
604
// / Return true if the set contains any qualifiers which require an ExtQuals
430
605
// / node to be allocated.
431
- bool hasNonFastQualifiers () const { return Mask & ~FastMask; }
606
+ bool hasNonFastQualifiers () const { return ( Mask & ~FastMask) || PtrAuth ; }
432
607
Qualifiers getNonFastQualifiers () const {
433
608
Qualifiers Quals = *this ;
434
609
Quals.setFastQualifiers (0 );
435
610
return Quals;
436
611
}
437
612
438
613
// / Return true if the set contains any qualifiers.
439
- bool hasQualifiers () const { return Mask; }
440
- bool empty () const { return !Mask ; }
614
+ bool hasQualifiers () const { return Mask || PtrAuth ; }
615
+ bool empty () const { return !hasQualifiers () ; }
441
616
442
617
// / Add the qualifiers from the given set to this set.
443
618
void addQualifiers (Qualifiers Q) {
@@ -454,6 +629,9 @@ class Qualifiers {
454
629
if (Q.hasObjCLifetime ())
455
630
addObjCLifetime (Q.getObjCLifetime ());
456
631
}
632
+
633
+ if (Q.PtrAuth )
634
+ PtrAuth = Q.PtrAuth ;
457
635
}
458
636
459
637
// / Remove the qualifiers from the given set from this set.
@@ -471,6 +649,9 @@ class Qualifiers {
471
649
if (getAddressSpace () == Q.getAddressSpace ())
472
650
removeAddressSpace ();
473
651
}
652
+
653
+ if (PtrAuth == Q.PtrAuth )
654
+ PtrAuth = PointerAuthQualifier ();
474
655
}
475
656
476
657
// / Add the qualifiers from the given set to this set, given that
@@ -482,7 +663,10 @@ class Qualifiers {
482
663
!hasObjCGCAttr () || !qs.hasObjCGCAttr ());
483
664
assert (getObjCLifetime () == qs.getObjCLifetime () ||
484
665
!hasObjCLifetime () || !qs.hasObjCLifetime ());
666
+ assert (!PtrAuth || !qs.PtrAuth || PtrAuth == qs.PtrAuth );
485
667
Mask |= qs.Mask ;
668
+ if (qs.PtrAuth )
669
+ PtrAuth = qs.PtrAuth ;
486
670
}
487
671
488
672
// / Returns true if address space A is equal to or a superset of B.
@@ -535,6 +719,8 @@ class Qualifiers {
535
719
// be changed.
536
720
(getObjCGCAttr () == other.getObjCGCAttr () || !hasObjCGCAttr () ||
537
721
!other.hasObjCGCAttr ()) &&
722
+ // Pointer-auth qualifiers must match exactly.
723
+ PtrAuth == other.PtrAuth &&
538
724
// ObjC lifetime qualifiers must match exactly.
539
725
getObjCLifetime () == other.getObjCLifetime () &&
540
726
// CVR qualifiers may subset.
@@ -567,8 +753,12 @@ class Qualifiers {
567
753
// / another set of qualifiers, not considering qualifier compatibility.
568
754
bool isStrictSupersetOf (Qualifiers Other) const ;
569
755
570
- bool operator ==(Qualifiers Other) const { return Mask == Other.Mask ; }
571
- bool operator !=(Qualifiers Other) const { return Mask != Other.Mask ; }
756
+ bool operator ==(Qualifiers Other) const {
757
+ return Mask == Other.Mask && PtrAuth == Other.PtrAuth ;
758
+ }
759
+ bool operator !=(Qualifiers Other) const {
760
+ return Mask != Other.Mask || PtrAuth != Other.PtrAuth ;
761
+ }
572
762
573
763
explicit operator bool () const { return hasQualifiers (); }
574
764
@@ -606,13 +796,17 @@ class Qualifiers {
606
796
607
797
void Profile (llvm::FoldingSetNodeID &ID) const {
608
798
ID.AddInteger (Mask);
799
+ PtrAuth.Profile (ID);
609
800
}
610
801
611
802
private:
612
803
// bits: |0 1 2|3|4 .. 5|6 .. 8|9 ... 31|
613
804
// |C R V|U|GCAttr|Lifetime|AddressSpace|
614
805
uint32_t Mask = 0 ;
615
806
807
+ PointerAuthQualifier PtrAuth;
808
+ static_assert (sizeof (PointerAuthQualifier) == sizeof (uint32_t ),
809
+ " PointerAuthQualifier must be 32 bits" );
616
810
static const uint32_t UMask = 0x8 ;
617
811
static const uint32_t UShift = 3 ;
618
812
static const uint32_t GCAttrMask = 0x30 ;
0 commit comments