clang  20.0.0git
CGPointerAuth.cpp
Go to the documentation of this file.
1 //===--- CGPointerAuth.cpp - IR generation for pointer authentication -----===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains common routines relating to the emission of
10 // pointer authentication operations.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "CodeGenFunction.h"
15 #include "CodeGenModule.h"
18 #include "llvm/Analysis/ValueTracking.h"
19 #include "llvm/Support/SipHash.h"
20 
21 using namespace clang;
22 using namespace CodeGen;
23 
24 /// Given a pointer-authentication schema, return a concrete "other"
25 /// discriminator for it.
27  const PointerAuthSchema &Schema, GlobalDecl Decl, QualType Type) {
28  switch (Schema.getOtherDiscrimination()) {
30  return nullptr;
31 
33  assert(!Type.isNull() && "type not provided for type-discriminated schema");
34  return llvm::ConstantInt::get(
36 
38  assert(Decl.getDecl() &&
39  "declaration not provided for decl-discriminated schema");
40  return llvm::ConstantInt::get(IntPtrTy,
42 
44  return llvm::ConstantInt::get(IntPtrTy, Schema.getConstantDiscrimination());
45  }
46  llvm_unreachable("bad discrimination kind");
47 }
48 
52 }
53 
55  GlobalDecl Declaration) {
56  return CGM.getPointerAuthDeclDiscriminator(Declaration);
57 }
58 
59 /// Return the "other" decl-specific discriminator for the given decl.
60 uint16_t
62  uint16_t &EntityHash = PtrAuthDiscriminatorHashes[Declaration];
63 
64  if (EntityHash == 0) {
65  StringRef Name = getMangledName(Declaration);
66  EntityHash = llvm::getPointerAuthStableSipHash(Name);
67  }
68 
69  return EntityHash;
70 }
71 
72 /// Return the abstract pointer authentication schema for a pointer to the given
73 /// function type.
75  const auto &Schema = getCodeGenOpts().PointerAuth.FunctionPointers;
76  if (!Schema)
77  return CGPointerAuthInfo();
78 
79  assert(!Schema.isAddressDiscriminated() &&
80  "function pointers cannot use address-specific discrimination");
81 
82  llvm::Constant *Discriminator = nullptr;
84  T = T->getPointeeType();
85  if (T->isFunctionType())
86  Discriminator = getPointerAuthOtherDiscriminator(Schema, GlobalDecl(), T);
87 
88  return CGPointerAuthInfo(Schema.getKey(), Schema.getAuthenticationMode(),
89  /*IsaPointer=*/false, /*AuthenticatesNull=*/false,
90  Discriminator);
91 }
92 
93 llvm::Value *
95  llvm::Value *Discriminator) {
96  StorageAddress = Builder.CreatePtrToInt(StorageAddress, IntPtrTy);
97  auto Intrinsic = CGM.getIntrinsic(llvm::Intrinsic::ptrauth_blend);
98  return Builder.CreateCall(Intrinsic, {StorageAddress, Discriminator});
99 }
100 
101 /// Emit the concrete pointer authentication informaton for the
102 /// given authentication schema.
104  const PointerAuthSchema &Schema, llvm::Value *StorageAddress,
105  GlobalDecl SchemaDecl, QualType SchemaType) {
106  if (!Schema)
107  return CGPointerAuthInfo();
108 
109  llvm::Value *Discriminator =
110  CGM.getPointerAuthOtherDiscriminator(Schema, SchemaDecl, SchemaType);
111 
112  if (Schema.isAddressDiscriminated()) {
113  assert(StorageAddress &&
114  "address not provided for address-discriminated schema");
115 
116  if (Discriminator)
117  Discriminator =
118  EmitPointerAuthBlendDiscriminator(StorageAddress, Discriminator);
119  else
120  Discriminator = Builder.CreatePtrToInt(StorageAddress, IntPtrTy);
121  }
122 
123  return CGPointerAuthInfo(Schema.getKey(), Schema.getAuthenticationMode(),
124  Schema.isIsaPointer(),
125  Schema.authenticatesNullValues(), Discriminator);
126 }
127 
128 /// Return the natural pointer authentication for values of the given
129 /// pointee type.
130 static CGPointerAuthInfo
132  if (PointeeType.isNull())
133  return CGPointerAuthInfo();
134 
135  // Function pointers use the function-pointer schema by default.
136  if (PointeeType->isFunctionType())
137  return CGM.getFunctionPointerAuthInfo(PointeeType);
138 
139  // Normal data pointers never use direct pointer authentication by default.
140  return CGPointerAuthInfo();
141 }
142 
145 }
146 
147 /// Return the natural pointer authentication for values of the given
148 /// pointer type.
151  assert(PointerType->isSignableType());
152 
153  // Block pointers are currently not signed.
155  return CGPointerAuthInfo();
156 
157  auto PointeeType = PointerType->getPointeeType();
158 
159  if (PointeeType.isNull())
160  return CGPointerAuthInfo();
161 
163 }
164 
167 }
168 
169 static bool isZeroConstant(const llvm::Value *Value) {
170  if (const auto *CI = dyn_cast<llvm::ConstantInt>(Value))
171  return CI->isZero();
172  return false;
173 }
174 
175 static bool equalAuthPolicies(const CGPointerAuthInfo &Left,
176  const CGPointerAuthInfo &Right) {
177  assert((Left.isSigned() || Right.isSigned()) &&
178  "shouldn't be called if neither is signed");
179  if (Left.isSigned() != Right.isSigned())
180  return false;
181  return Left.getKey() == Right.getKey() &&
182  Left.getAuthenticationMode() == Right.getAuthenticationMode();
183 }
184 
185 // Return the discriminator or return zero if the discriminator is null.
186 static llvm::Value *getDiscriminatorOrZero(const CGPointerAuthInfo &Info,
187  CGBuilderTy &Builder) {
188  llvm::Value *Discriminator = Info.getDiscriminator();
189  return Discriminator ? Discriminator : Builder.getSize(0);
190 }
191 
192 llvm::Value *
194  const CGPointerAuthInfo &CurAuth,
195  const CGPointerAuthInfo &NewAuth) {
196  assert(CurAuth && NewAuth);
197 
198  if (CurAuth.getAuthenticationMode() !=
200  NewAuth.getAuthenticationMode() !=
202  llvm::Value *AuthedValue = EmitPointerAuthAuth(CurAuth, Value);
203  return EmitPointerAuthSign(NewAuth, AuthedValue);
204  }
205  // Convert the pointer to intptr_t before signing it.
206  auto *OrigType = Value->getType();
207  Value = Builder.CreatePtrToInt(Value, IntPtrTy);
208 
209  auto *CurKey = Builder.getInt32(CurAuth.getKey());
210  auto *NewKey = Builder.getInt32(NewAuth.getKey());
211 
212  llvm::Value *CurDiscriminator = getDiscriminatorOrZero(CurAuth, Builder);
213  llvm::Value *NewDiscriminator = getDiscriminatorOrZero(NewAuth, Builder);
214 
215  // call i64 @llvm.ptrauth.resign(i64 %pointer,
216  // i32 %curKey, i64 %curDiscriminator,
217  // i32 %newKey, i64 %newDiscriminator)
218  auto *Intrinsic = CGM.getIntrinsic(llvm::Intrinsic::ptrauth_resign);
220  Intrinsic, {Value, CurKey, CurDiscriminator, NewKey, NewDiscriminator});
221 
222  // Convert back to the original type.
223  Value = Builder.CreateIntToPtr(Value, OrigType);
224  return Value;
225 }
226 
228  llvm::Value *Value, QualType Type, const CGPointerAuthInfo &CurAuthInfo,
229  const CGPointerAuthInfo &NewAuthInfo, bool IsKnownNonNull) {
230  // Fast path: if neither schema wants a signature, we're done.
231  if (!CurAuthInfo && !NewAuthInfo)
232  return Value;
233 
234  llvm::Value *Null = nullptr;
235  // If the value is obviously null, we're done.
236  if (auto *PointerValue = dyn_cast<llvm::PointerType>(Value->getType())) {
237  Null = CGM.getNullPointer(PointerValue, Type);
238  } else {
239  assert(Value->getType()->isIntegerTy());
240  Null = llvm::ConstantInt::get(IntPtrTy, 0);
241  }
242  if (Value == Null)
243  return Value;
244 
245  // If both schemas sign the same way, we're done.
246  if (equalAuthPolicies(CurAuthInfo, NewAuthInfo)) {
247  const llvm::Value *CurD = CurAuthInfo.getDiscriminator();
248  const llvm::Value *NewD = NewAuthInfo.getDiscriminator();
249  if (CurD == NewD)
250  return Value;
251 
252  if ((CurD == nullptr && isZeroConstant(NewD)) ||
253  (NewD == nullptr && isZeroConstant(CurD)))
254  return Value;
255  }
256 
257  llvm::BasicBlock *InitBB = Builder.GetInsertBlock();
258  llvm::BasicBlock *ResignBB = nullptr, *ContBB = nullptr;
259 
260  // Null pointers have to be mapped to null, and the ptrauth_resign
261  // intrinsic doesn't do that.
262  if (!IsKnownNonNull && !llvm::isKnownNonZero(Value, CGM.getDataLayout())) {
263  ContBB = createBasicBlock("resign.cont");
264  ResignBB = createBasicBlock("resign.nonnull");
265 
266  auto *IsNonNull = Builder.CreateICmpNE(Value, Null);
267  Builder.CreateCondBr(IsNonNull, ResignBB, ContBB);
268  EmitBlock(ResignBB);
269  }
270 
271  // Perform the auth/sign/resign operation.
272  if (!NewAuthInfo)
273  Value = EmitPointerAuthAuth(CurAuthInfo, Value);
274  else if (!CurAuthInfo)
275  Value = EmitPointerAuthSign(NewAuthInfo, Value);
276  else
277  Value = emitPointerAuthResignCall(Value, CurAuthInfo, NewAuthInfo);
278 
279  // Clean up with a phi if we branched before.
280  if (ContBB) {
281  EmitBlock(ContBB);
282  auto *Phi = Builder.CreatePHI(Value->getType(), 2);
283  Phi->addIncoming(Null, InitBB);
284  Phi->addIncoming(Value, ResignBB);
285  Value = Phi;
286  }
287 
288  return Value;
289 }
290 
291 llvm::Constant *
292 CodeGenModule::getConstantSignedPointer(llvm::Constant *Pointer, unsigned Key,
293  llvm::Constant *StorageAddress,
294  llvm::ConstantInt *OtherDiscriminator) {
295  llvm::Constant *AddressDiscriminator;
296  if (StorageAddress) {
297  assert(StorageAddress->getType() == UnqualPtrTy);
298  AddressDiscriminator = StorageAddress;
299  } else {
300  AddressDiscriminator = llvm::Constant::getNullValue(UnqualPtrTy);
301  }
302 
303  llvm::ConstantInt *IntegerDiscriminator;
304  if (OtherDiscriminator) {
305  assert(OtherDiscriminator->getType() == Int64Ty);
306  IntegerDiscriminator = OtherDiscriminator;
307  } else {
308  IntegerDiscriminator = llvm::ConstantInt::get(Int64Ty, 0);
309  }
310 
311  return llvm::ConstantPtrAuth::get(Pointer,
312  llvm::ConstantInt::get(Int32Ty, Key),
313  IntegerDiscriminator, AddressDiscriminator);
314 }
315 
316 /// Does a given PointerAuthScheme require us to sign a value
318  auto AuthenticationMode = Schema.getAuthenticationMode();
319  return AuthenticationMode == PointerAuthenticationMode::SignAndStrip ||
320  AuthenticationMode == PointerAuthenticationMode::SignAndAuth;
321 }
322 
323 /// Sign a constant pointer using the given scheme, producing a constant
324 /// with the same IR type.
326  llvm::Constant *Pointer, const PointerAuthSchema &Schema,
327  llvm::Constant *StorageAddress, GlobalDecl SchemaDecl,
328  QualType SchemaType) {
329  assert(shouldSignPointer(Schema));
330  llvm::ConstantInt *OtherDiscriminator =
331  getPointerAuthOtherDiscriminator(Schema, SchemaDecl, SchemaType);
332 
333  return getConstantSignedPointer(Pointer, Schema.getKey(), StorageAddress,
334  OtherDiscriminator);
335 }
336 
337 /// If applicable, sign a given constant function pointer with the ABI rules for
338 /// functionType.
339 llvm::Constant *CodeGenModule::getFunctionPointer(llvm::Constant *Pointer,
341  assert(FunctionType->isFunctionType() ||
344 
345  if (auto PointerAuth = getFunctionPointerAuthInfo(FunctionType))
347  Pointer, PointerAuth.getKey(), /*StorageAddress=*/nullptr,
348  cast_or_null<llvm::ConstantInt>(PointerAuth.getDiscriminator()));
349 
350  return Pointer;
351 }
352 
354  llvm::Type *Ty) {
355  const auto *FD = cast<FunctionDecl>(GD.getDecl());
356  QualType FuncType = FD->getType();
357 
358  // Annoyingly, K&R functions have prototypes in the clang AST, but
359  // expressions referring to them are unprototyped.
360  if (!FD->hasPrototype())
361  if (const auto *Proto = FuncType->getAs<FunctionProtoType>())
362  FuncType = Context.getFunctionNoProtoType(Proto->getReturnType(),
363  Proto->getExtInfo());
364 
365  return getFunctionPointer(getRawFunctionPointer(GD, Ty), FuncType);
366 }
367 
369  assert(FT->getAs<MemberPointerType>() && "MemberPointerType expected");
371  if (!Schema)
372  return CGPointerAuthInfo();
373 
374  assert(!Schema.isAddressDiscriminated() &&
375  "function pointers cannot use address-specific discrimination");
376 
377  llvm::ConstantInt *Discriminator =
379  return CGPointerAuthInfo(Schema.getKey(), Schema.getAuthenticationMode(),
380  /* IsIsaPointer */ false,
381  /* AuthenticatesNullValues */ false, Discriminator);
382 }
383 
384 llvm::Constant *CodeGenModule::getMemberFunctionPointer(llvm::Constant *Pointer,
385  QualType FT) {
388  Pointer, PointerAuth.getKey(), nullptr,
389  cast_or_null<llvm::ConstantInt>(PointerAuth.getDiscriminator()));
390 
391  return Pointer;
392 }
393 
395  llvm::Type *Ty) {
396  QualType FT = FD->getType();
398  FT, cast<CXXMethodDecl>(FD)->getParent()->getTypeForDecl());
400 }
401 
402 std::optional<PointerAuthQualifier>
403 CodeGenModule::computeVTPointerAuthentication(const CXXRecordDecl *ThisClass) {
404  auto DefaultAuthentication = getCodeGenOpts().PointerAuth.CXXVTablePointers;
405  if (!DefaultAuthentication)
406  return std::nullopt;
407  const CXXRecordDecl *PrimaryBase =
408  Context.baseForVTableAuthentication(ThisClass);
409 
410  unsigned Key = DefaultAuthentication.getKey();
411  bool AddressDiscriminated = DefaultAuthentication.isAddressDiscriminated();
412  auto DefaultDiscrimination = DefaultAuthentication.getOtherDiscrimination();
413  unsigned TypeBasedDiscriminator =
414  Context.getPointerAuthVTablePointerDiscriminator(PrimaryBase);
415  unsigned Discriminator;
416  if (DefaultDiscrimination == PointerAuthSchema::Discrimination::Type) {
417  Discriminator = TypeBasedDiscriminator;
418  } else if (DefaultDiscrimination ==
420  Discriminator = DefaultAuthentication.getConstantDiscrimination();
421  } else {
422  assert(DefaultDiscrimination == PointerAuthSchema::Discrimination::None);
423  Discriminator = 0;
424  }
425  if (auto ExplicitAuthentication =
426  PrimaryBase->getAttr<VTablePointerAuthenticationAttr>()) {
427  auto ExplicitAddressDiscrimination =
428  ExplicitAuthentication->getAddressDiscrimination();
429  auto ExplicitDiscriminator =
430  ExplicitAuthentication->getExtraDiscrimination();
431 
432  unsigned ExplicitKey = ExplicitAuthentication->getKey();
433  if (ExplicitKey == VTablePointerAuthenticationAttr::NoKey)
434  return std::nullopt;
435 
436  if (ExplicitKey != VTablePointerAuthenticationAttr::DefaultKey) {
437  if (ExplicitKey == VTablePointerAuthenticationAttr::ProcessIndependent)
439  else {
440  assert(ExplicitKey ==
441  VTablePointerAuthenticationAttr::ProcessDependent);
443  }
444  }
445 
446  if (ExplicitAddressDiscrimination !=
447  VTablePointerAuthenticationAttr::DefaultAddressDiscrimination)
448  AddressDiscriminated =
449  ExplicitAddressDiscrimination ==
450  VTablePointerAuthenticationAttr::AddressDiscrimination;
451 
452  if (ExplicitDiscriminator ==
453  VTablePointerAuthenticationAttr::TypeDiscrimination)
454  Discriminator = TypeBasedDiscriminator;
455  else if (ExplicitDiscriminator ==
456  VTablePointerAuthenticationAttr::CustomDiscrimination)
457  Discriminator = ExplicitAuthentication->getCustomDiscriminationValue();
458  else if (ExplicitDiscriminator ==
459  VTablePointerAuthenticationAttr::NoExtraDiscrimination)
460  Discriminator = 0;
461  }
462  return PointerAuthQualifier::Create(Key, AddressDiscriminated, Discriminator,
464  /* IsIsaPointer */ false,
465  /* AuthenticatesNullValues */ false);
466 }
467 
468 std::optional<PointerAuthQualifier>
470  if (!Record->getDefinition() || !Record->isPolymorphic())
471  return std::nullopt;
472 
473  auto Existing = VTablePtrAuthInfos.find(Record);
474  std::optional<PointerAuthQualifier> Authentication;
475  if (Existing != VTablePtrAuthInfos.end()) {
476  Authentication = Existing->getSecond();
477  } else {
478  Authentication = computeVTPointerAuthentication(Record);
479  VTablePtrAuthInfos.insert(std::make_pair(Record, Authentication));
480  }
481  return Authentication;
482 }
483 
484 std::optional<CGPointerAuthInfo>
486  const CXXRecordDecl *Record,
487  llvm::Value *StorageAddress) {
488  auto Authentication = getVTablePointerAuthentication(Record);
489  if (!Authentication)
490  return std::nullopt;
491 
492  llvm::Value *Discriminator = nullptr;
493  if (auto ExtraDiscriminator = Authentication->getExtraDiscriminator())
494  Discriminator = llvm::ConstantInt::get(IntPtrTy, ExtraDiscriminator);
495 
496  if (Authentication->isAddressDiscriminated()) {
497  assert(StorageAddress &&
498  "address not provided for address-discriminated schema");
499  if (Discriminator)
500  Discriminator =
501  CGF->EmitPointerAuthBlendDiscriminator(StorageAddress, Discriminator);
502  else
503  Discriminator = CGF->Builder.CreatePtrToInt(StorageAddress, IntPtrTy);
504  }
505 
506  return CGPointerAuthInfo(Authentication->getKey(),
508  /* IsIsaPointer */ false,
509  /* AuthenticatesNullValues */ false, Discriminator);
510 }
511 
512 llvm::Value *CodeGenFunction::authPointerToPointerCast(llvm::Value *ResultPtr,
513  QualType SourceType,
514  QualType DestType) {
515  CGPointerAuthInfo CurAuthInfo, NewAuthInfo;
516  if (SourceType->isSignableType())
517  CurAuthInfo = getPointerAuthInfoForType(CGM, SourceType);
518 
519  if (DestType->isSignableType())
520  NewAuthInfo = getPointerAuthInfoForType(CGM, DestType);
521 
522  if (!CurAuthInfo && !NewAuthInfo)
523  return ResultPtr;
524 
525  // If only one side of the cast is a function pointer, then we still need to
526  // resign to handle casts to/from opaque pointers.
527  if (!CurAuthInfo && DestType->isFunctionPointerType())
528  CurAuthInfo = CGM.getFunctionPointerAuthInfo(SourceType);
529 
530  if (!NewAuthInfo && SourceType->isFunctionPointerType())
531  NewAuthInfo = CGM.getFunctionPointerAuthInfo(DestType);
532 
533  return emitPointerAuthResign(ResultPtr, DestType, CurAuthInfo, NewAuthInfo,
534  /*IsKnownNonNull=*/false);
535 }
536 
538  QualType SourceType,
539  QualType DestType) {
540  CGPointerAuthInfo CurAuthInfo, NewAuthInfo;
541  if (SourceType->isSignableType())
542  CurAuthInfo = getPointerAuthInfoForType(CGM, SourceType);
543 
544  if (DestType->isSignableType())
545  NewAuthInfo = getPointerAuthInfoForType(CGM, DestType);
546 
547  if (!CurAuthInfo && !NewAuthInfo)
548  return Ptr;
549 
550  if (!CurAuthInfo && DestType->isFunctionPointerType()) {
551  // When casting a non-signed pointer to a function pointer, just set the
552  // auth info on Ptr to the assumed schema. The pointer will be resigned to
553  // the effective type when used.
555  return Ptr;
556  }
557 
558  if (!NewAuthInfo && SourceType->isFunctionPointerType()) {
559  NewAuthInfo = CGM.getFunctionPointerAuthInfo(DestType);
560  Ptr = Ptr.getResignedAddress(NewAuthInfo, *this);
562  return Ptr;
563  }
564 
565  return Ptr;
566 }
567 
569  QualType PointeeTy) {
570  CGPointerAuthInfo Info =
571  PointeeTy.isNull() ? CGPointerAuthInfo()
573  return Addr.getResignedAddress(Info, *this);
574 }
575 
577  CodeGenFunction &CGF) const {
578  assert(isValid() && "pointer isn't valid");
580  llvm::Value *Val;
581 
582  // Nothing to do if neither the current or the new ptrauth info needs signing.
583  if (!CurInfo.isSigned() && !NewInfo.isSigned())
585  isKnownNonNull());
586 
587  assert(ElementType && "Effective type has to be set");
588  assert(!Offset && "unexpected non-null offset");
589 
590  // If the current and the new ptrauth infos are the same and the offset is
591  // null, just cast the base pointer to the effective type.
592  if (CurInfo == NewInfo && !hasOffset())
593  Val = getBasePointer();
594  else
595  Val = CGF.emitPointerAuthResign(getBasePointer(), QualType(), CurInfo,
596  NewInfo, isKnownNonNull());
597 
598  Val = CGF.Builder.CreateBitCast(Val, getType());
599  return Address(Val, getElementType(), getAlignment(), NewInfo,
600  /*Offset=*/nullptr, isKnownNonNull());
601 }
602 
603 llvm::Value *Address::emitRawPointerSlow(CodeGenFunction &CGF) const {
604  return CGF.getAsNaturalPointerTo(*this, QualType());
605 }
606 
607 llvm::Value *LValue::getPointer(CodeGenFunction &CGF) const {
608  assert(isSimple());
609  return emitResignedPointer(getType(), CGF);
610 }
611 
612 llvm::Value *LValue::emitResignedPointer(QualType PointeeTy,
613  CodeGenFunction &CGF) const {
614  assert(isSimple());
615  return CGF.getAsNaturalAddressOf(Addr, PointeeTy).getBasePointer();
616 }
617 
618 llvm::Value *LValue::emitRawPointer(CodeGenFunction &CGF) const {
619  assert(isSimple());
620  return Addr.isValid() ? Addr.emitRawPointer(CGF) : nullptr;
621 }
static llvm::Value * getDiscriminatorOrZero(const CGPointerAuthInfo &Info, CGBuilderTy &Builder)
static bool isZeroConstant(const llvm::Value *Value)
static bool equalAuthPolicies(const CGPointerAuthInfo &Left, const CGPointerAuthInfo &Right)
static CGPointerAuthInfo getPointerAuthInfoForPointeeType(CodeGenModule &CGM, QualType PointeeType)
Return the natural pointer authentication for values of the given pointee type.
static CGPointerAuthInfo getPointerAuthInfoForType(CodeGenModule &CGM, QualType PointerType)
Return the natural pointer authentication for values of the given pointer type.
llvm::MachO::Record Record
Definition: MachO.h:31
QualType getMemberPointerType(QualType T, const Type *Cls) const
Return the uniqued reference to the type for a member pointer to the specified type in the specified ...
QualType getFunctionNoProtoType(QualType ResultTy, const FunctionType::ExtInfo &Info) const
Return a K&R style C function type like 'int()'.
const CXXRecordDecl * baseForVTableAuthentication(const CXXRecordDecl *ThisClass)
Resolve the root record to be used to derive the vtable pointer authentication policy for the specifi...
uint16_t getPointerAuthVTablePointerDiscriminator(const CXXRecordDecl *RD)
Return the "other" discriminator used for the pointer auth schema used for vtable pointers in instanc...
uint16_t getPointerAuthTypeDiscriminator(QualType T)
Return the "other" type-specific discriminator for the given type.
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
PointerAuthOptions PointerAuth
Configuration for pointer-signing.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
Definition: Address.h:128
Address(std::nullptr_t)
Definition: Address.h:151
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
Definition: Address.h:251
CharUnits getAlignment() const
Definition: Address.h:189
llvm::Type * getElementType() const
Return the type of the values stored in this address.
Definition: Address.h:207
void setPointerAuthInfo(const CGPointerAuthInfo &Info)
Definition: Address.h:219
bool hasOffset() const
Definition: Address.h:242
KnownNonNull_t isKnownNonNull() const
Whether the pointer is known not to be null.
Definition: Address.h:231
llvm::PointerType * getType() const
Return the type of the pointer value.
Definition: Address.h:199
llvm::Value * getBasePointer() const
Definition: Address.h:193
const CGPointerAuthInfo & getPointerAuthInfo() const
Definition: Address.h:218
Address getResignedAddress(const CGPointerAuthInfo &NewInfo, CodeGenFunction &CGF) const
bool isValid() const
Definition: Address.h:177
PointerAuthenticationMode getAuthenticationMode() const
llvm::Value * getDiscriminator() const
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
llvm::Value * emitPointerAuthResignCall(llvm::Value *Pointer, const CGPointerAuthInfo &CurInfo, const CGPointerAuthInfo &NewInfo)
llvm::Value * getAsNaturalPointerTo(Address Addr, QualType PointeeType)
llvm::Value * EmitPointerAuthSign(const CGPointerAuthInfo &Info, llvm::Value *Pointer)
Address getAsNaturalAddressOf(Address Addr, QualType PointeeTy)
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
CGPointerAuthInfo EmitPointerAuthInfo(const PointerAuthSchema &Schema, llvm::Value *StorageAddress, GlobalDecl SchemaDecl, QualType SchemaType)
Emit the concrete pointer authentication informaton for the given authentication schema.
llvm::Value * emitPointerAuthResign(llvm::Value *Pointer, QualType PointerType, const CGPointerAuthInfo &CurAuthInfo, const CGPointerAuthInfo &NewAuthInfo, bool IsKnownNonNull)
llvm::Value * authPointerToPointerCast(llvm::Value *ResultPtr, QualType SourceType, QualType DestType)
llvm::Value * EmitPointerAuthBlendDiscriminator(llvm::Value *StorageAddress, llvm::Value *Discriminator)
Create the discriminator from the storage address and the entity hash.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
Definition: CGStmt.cpp:591
llvm::Value * EmitPointerAuthAuth(const CGPointerAuthInfo &Info, llvm::Value *Pointer)
This class organizes the cross-function state that is used while generating LLVM code.
const llvm::DataLayout & getDataLayout() const
llvm::Constant * getRawFunctionPointer(GlobalDecl GD, llvm::Type *Ty=nullptr)
Return a function pointer for a reference to the given function.
Definition: CGExpr.cpp:2880
llvm::Constant * getFunctionPointer(GlobalDecl GD, llvm::Type *Ty=nullptr)
Return the ABI-correct function pointer value for a reference to the given function.
llvm::Constant * getNullPointer(llvm::PointerType *T, QualType QT)
Get target specific null pointer.
CGPointerAuthInfo getMemberFunctionPointerAuthInfo(QualType FT)
llvm::ConstantInt * getPointerAuthOtherDiscriminator(const PointerAuthSchema &Schema, GlobalDecl SchemaDecl, QualType SchemaType)
Given a pointer-authentication schema, return a concrete "other" discriminator for it.
CGPointerAuthInfo getPointerAuthInfoForPointeeType(QualType type)
CGPointerAuthInfo getFunctionPointerAuthInfo(QualType T)
Return the abstract pointer authentication schema for a pointer to the given function type.
llvm::Constant * getMemberFunctionPointer(const FunctionDecl *FD, llvm::Type *Ty=nullptr)
std::optional< PointerAuthQualifier > getVTablePointerAuthentication(const CXXRecordDecl *thisClass)
uint16_t getPointerAuthDeclDiscriminator(GlobalDecl GD)
Return the "other" decl-specific discriminator for the given decl.
StringRef getMangledName(GlobalDecl GD)
ASTContext & getContext() const
const CodeGenOptions & getCodeGenOpts() const
std::optional< CGPointerAuthInfo > getVTablePointerAuthInfo(CodeGenFunction *Context, const CXXRecordDecl *Record, llvm::Value *StorageAddress)
llvm::Constant * getConstantSignedPointer(llvm::Constant *Pointer, const PointerAuthSchema &Schema, llvm::Constant *StorageAddress, GlobalDecl SchemaDecl, QualType SchemaType)
Sign a constant pointer using the given scheme, producing a constant with the same IR type.
bool shouldSignPointer(const PointerAuthSchema &Schema)
Does a given PointerAuthScheme require us to sign a value.
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys=std::nullopt)
CGPointerAuthInfo getPointerAuthInfoForType(QualType type)
llvm::Value * emitResignedPointer(QualType PointeeTy, CodeGenFunction &CGF) const
bool isSimple() const
Definition: CGValue.h:278
llvm::Value * getPointer(CodeGenFunction &CGF) const
QualType getType() const
Definition: CGValue.h:291
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
T * getAttr() const
Definition: DeclBase.h:580
Represents a function declaration or definition.
Definition: Decl.h:1933
Represents a prototype with parameter type info, e.g.
Definition: Type.h:5012
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition: Type.h:4318
GlobalDecl - represents a global declaration.
Definition: GlobalDecl.h:56
const Decl * getDecl() const
Definition: GlobalDecl.h:103
A pointer to member type per C++ 8.3.3 - Pointers to members.
Definition: Type.h:3518
static PointerAuthQualifier Create(unsigned Key, bool IsAddressDiscriminated, unsigned ExtraDiscriminator, PointerAuthenticationMode AuthenticationMode, bool IsIsaPointer, bool AuthenticatesNullValues)
Definition: Type.h:233
Discrimination getOtherDiscrimination() const
@ None
No additional discrimination.
@ Type
Include a hash of the entity's type.
@ Decl
Include a hash of the entity's identity.
@ Constant
Discriminate using a constant value.
PointerAuthenticationMode getAuthenticationMode() const
uint16_t getConstantDiscrimination() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:3197
QualType getPointeeType() const
Definition: Type.h:3207
A (possibly-)qualified type.
Definition: Type.h:941
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:1008
The base class of the type hierarchy.
Definition: Type.h:1829
bool isBlockPointerType() const
Definition: Type.h:8027
bool isFunctionReferenceType() const
Definition: Type.h:8060
bool isFunctionPointerType() const
Definition: Type.h:8053
bool isSignableType() const
Definition: Type.h:8025
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:705
bool isFunctionType() const
Definition: Type.h:8009
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8568
QualType getType() const
Definition: Decl.h:679
QualType getType() const
Definition: Value.cpp:234
uint16_t getPointerAuthDeclDiscriminator(CodeGenModule &CGM, GlobalDecl GD)
Return a declaration discriminator for the given global decl.
uint16_t getPointerAuthTypeDiscriminator(CodeGenModule &CGM, QualType FunctionType)
Return a type discriminator for the given function type.
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
PointerAuthSchema CXXVTablePointers
The ABI for C++ virtual table pointers (the pointer to the table itself) as installed in an actual cl...
PointerAuthSchema FunctionPointers
The ABI for C function pointers.
PointerAuthSchema CXXMemberFunctionPointers
The ABI for C++ member function pointers.