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