xref: /llvm-project/clang/lib/CodeGen/CGPointerAuth.cpp (revision 4dcd91aea3858fe60c65701a92060a04f789886f)
17c814c13SAhmed Bougacha //===--- CGPointerAuth.cpp - IR generation for pointer authentication -----===//
27c814c13SAhmed Bougacha //
37c814c13SAhmed Bougacha // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47c814c13SAhmed Bougacha // See https://llvm.org/LICENSE.txt for license information.
57c814c13SAhmed Bougacha // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67c814c13SAhmed Bougacha //
77c814c13SAhmed Bougacha //===----------------------------------------------------------------------===//
87c814c13SAhmed Bougacha //
97c814c13SAhmed Bougacha // This file contains common routines relating to the emission of
107c814c13SAhmed Bougacha // pointer authentication operations.
117c814c13SAhmed Bougacha //
127c814c13SAhmed Bougacha //===----------------------------------------------------------------------===//
137c814c13SAhmed Bougacha 
141b8ab2f0SOliver Hunt #include "CodeGenFunction.h"
157c814c13SAhmed Bougacha #include "CodeGenModule.h"
167c814c13SAhmed Bougacha #include "clang/CodeGen/CodeGenABITypes.h"
171b8ab2f0SOliver Hunt #include "clang/CodeGen/ConstantInitBuilder.h"
18f6b06b42SAkira Hatanaka #include "llvm/Analysis/ValueTracking.h"
191b8ab2f0SOliver Hunt #include "llvm/Support/SipHash.h"
207c814c13SAhmed Bougacha 
217c814c13SAhmed Bougacha using namespace clang;
227c814c13SAhmed Bougacha using namespace CodeGen;
237c814c13SAhmed Bougacha 
241b8ab2f0SOliver Hunt /// Given a pointer-authentication schema, return a concrete "other"
251b8ab2f0SOliver Hunt /// discriminator for it.
261b8ab2f0SOliver Hunt llvm::ConstantInt *CodeGenModule::getPointerAuthOtherDiscriminator(
271b8ab2f0SOliver Hunt     const PointerAuthSchema &Schema, GlobalDecl Decl, QualType Type) {
281b8ab2f0SOliver Hunt   switch (Schema.getOtherDiscrimination()) {
291b8ab2f0SOliver Hunt   case PointerAuthSchema::Discrimination::None:
301b8ab2f0SOliver Hunt     return nullptr;
311b8ab2f0SOliver Hunt 
321b8ab2f0SOliver Hunt   case PointerAuthSchema::Discrimination::Type:
33ae18b941SAkira Hatanaka     assert(!Type.isNull() && "type not provided for type-discriminated schema");
34ae18b941SAkira Hatanaka     return llvm::ConstantInt::get(
35ae18b941SAkira Hatanaka         IntPtrTy, getContext().getPointerAuthTypeDiscriminator(Type));
361b8ab2f0SOliver Hunt 
371b8ab2f0SOliver Hunt   case PointerAuthSchema::Discrimination::Decl:
381b8ab2f0SOliver Hunt     assert(Decl.getDecl() &&
391b8ab2f0SOliver Hunt            "declaration not provided for decl-discriminated schema");
401b8ab2f0SOliver Hunt     return llvm::ConstantInt::get(IntPtrTy,
411b8ab2f0SOliver Hunt                                   getPointerAuthDeclDiscriminator(Decl));
421b8ab2f0SOliver Hunt 
431b8ab2f0SOliver Hunt   case PointerAuthSchema::Discrimination::Constant:
441b8ab2f0SOliver Hunt     return llvm::ConstantInt::get(IntPtrTy, Schema.getConstantDiscrimination());
451b8ab2f0SOliver Hunt   }
461b8ab2f0SOliver Hunt   llvm_unreachable("bad discrimination kind");
471b8ab2f0SOliver Hunt }
481b8ab2f0SOliver Hunt 
49ae18b941SAkira Hatanaka uint16_t CodeGen::getPointerAuthTypeDiscriminator(CodeGenModule &CGM,
50ae18b941SAkira Hatanaka                                                   QualType FunctionType) {
51ae18b941SAkira Hatanaka   return CGM.getContext().getPointerAuthTypeDiscriminator(FunctionType);
52ae18b941SAkira Hatanaka }
53ae18b941SAkira Hatanaka 
541b8ab2f0SOliver Hunt uint16_t CodeGen::getPointerAuthDeclDiscriminator(CodeGenModule &CGM,
551b8ab2f0SOliver Hunt                                                   GlobalDecl Declaration) {
561b8ab2f0SOliver Hunt   return CGM.getPointerAuthDeclDiscriminator(Declaration);
571b8ab2f0SOliver Hunt }
581b8ab2f0SOliver Hunt 
591b8ab2f0SOliver Hunt /// Return the "other" decl-specific discriminator for the given decl.
601b8ab2f0SOliver Hunt uint16_t
611b8ab2f0SOliver Hunt CodeGenModule::getPointerAuthDeclDiscriminator(GlobalDecl Declaration) {
621b8ab2f0SOliver Hunt   uint16_t &EntityHash = PtrAuthDiscriminatorHashes[Declaration];
631b8ab2f0SOliver Hunt 
641b8ab2f0SOliver Hunt   if (EntityHash == 0) {
651b8ab2f0SOliver Hunt     StringRef Name = getMangledName(Declaration);
661b8ab2f0SOliver Hunt     EntityHash = llvm::getPointerAuthStableSipHash(Name);
671b8ab2f0SOliver Hunt   }
681b8ab2f0SOliver Hunt 
691b8ab2f0SOliver Hunt   return EntityHash;
701b8ab2f0SOliver Hunt }
711b8ab2f0SOliver Hunt 
72e23250ecSAhmed Bougacha /// Return the abstract pointer authentication schema for a pointer to the given
73e23250ecSAhmed Bougacha /// function type.
74e23250ecSAhmed Bougacha CGPointerAuthInfo CodeGenModule::getFunctionPointerAuthInfo(QualType T) {
75e23250ecSAhmed Bougacha   const auto &Schema = getCodeGenOpts().PointerAuth.FunctionPointers;
76e23250ecSAhmed Bougacha   if (!Schema)
77e23250ecSAhmed Bougacha     return CGPointerAuthInfo();
78e23250ecSAhmed Bougacha 
79e23250ecSAhmed Bougacha   assert(!Schema.isAddressDiscriminated() &&
80e23250ecSAhmed Bougacha          "function pointers cannot use address-specific discrimination");
81e23250ecSAhmed Bougacha 
82ae18b941SAkira Hatanaka   llvm::Constant *Discriminator = nullptr;
83ae18b941SAkira Hatanaka   if (T->isFunctionPointerType() || T->isFunctionReferenceType())
84ae18b941SAkira Hatanaka     T = T->getPointeeType();
85ae18b941SAkira Hatanaka   if (T->isFunctionType())
86ae18b941SAkira Hatanaka     Discriminator = getPointerAuthOtherDiscriminator(Schema, GlobalDecl(), T);
87e23250ecSAhmed Bougacha 
88e23250ecSAhmed Bougacha   return CGPointerAuthInfo(Schema.getKey(), Schema.getAuthenticationMode(),
89e23250ecSAhmed Bougacha                            /*IsaPointer=*/false, /*AuthenticatesNull=*/false,
90ae18b941SAkira Hatanaka                            Discriminator);
91e23250ecSAhmed Bougacha }
92e23250ecSAhmed Bougacha 
931b8ab2f0SOliver Hunt llvm::Value *
941b8ab2f0SOliver Hunt CodeGenFunction::EmitPointerAuthBlendDiscriminator(llvm::Value *StorageAddress,
951b8ab2f0SOliver Hunt                                                    llvm::Value *Discriminator) {
961b8ab2f0SOliver Hunt   StorageAddress = Builder.CreatePtrToInt(StorageAddress, IntPtrTy);
971b8ab2f0SOliver Hunt   auto Intrinsic = CGM.getIntrinsic(llvm::Intrinsic::ptrauth_blend);
981b8ab2f0SOliver Hunt   return Builder.CreateCall(Intrinsic, {StorageAddress, Discriminator});
991b8ab2f0SOliver Hunt }
1001b8ab2f0SOliver Hunt 
1011b8ab2f0SOliver Hunt /// Emit the concrete pointer authentication informaton for the
1021b8ab2f0SOliver Hunt /// given authentication schema.
1031b8ab2f0SOliver Hunt CGPointerAuthInfo CodeGenFunction::EmitPointerAuthInfo(
1041b8ab2f0SOliver Hunt     const PointerAuthSchema &Schema, llvm::Value *StorageAddress,
1051b8ab2f0SOliver Hunt     GlobalDecl SchemaDecl, QualType SchemaType) {
1061b8ab2f0SOliver Hunt   if (!Schema)
1071b8ab2f0SOliver Hunt     return CGPointerAuthInfo();
1081b8ab2f0SOliver Hunt 
1091b8ab2f0SOliver Hunt   llvm::Value *Discriminator =
1101b8ab2f0SOliver Hunt       CGM.getPointerAuthOtherDiscriminator(Schema, SchemaDecl, SchemaType);
1111b8ab2f0SOliver Hunt 
1121b8ab2f0SOliver Hunt   if (Schema.isAddressDiscriminated()) {
1131b8ab2f0SOliver Hunt     assert(StorageAddress &&
1141b8ab2f0SOliver Hunt            "address not provided for address-discriminated schema");
1151b8ab2f0SOliver Hunt 
1161b8ab2f0SOliver Hunt     if (Discriminator)
1171b8ab2f0SOliver Hunt       Discriminator =
1181b8ab2f0SOliver Hunt           EmitPointerAuthBlendDiscriminator(StorageAddress, Discriminator);
1191b8ab2f0SOliver Hunt     else
1201b8ab2f0SOliver Hunt       Discriminator = Builder.CreatePtrToInt(StorageAddress, IntPtrTy);
1211b8ab2f0SOliver Hunt   }
1221b8ab2f0SOliver Hunt 
1231b8ab2f0SOliver Hunt   return CGPointerAuthInfo(Schema.getKey(), Schema.getAuthenticationMode(),
1241b8ab2f0SOliver Hunt                            Schema.isIsaPointer(),
1251b8ab2f0SOliver Hunt                            Schema.authenticatesNullValues(), Discriminator);
1261b8ab2f0SOliver Hunt }
1271b8ab2f0SOliver Hunt 
128ae18b941SAkira Hatanaka /// Return the natural pointer authentication for values of the given
129ae18b941SAkira Hatanaka /// pointee type.
130ae18b941SAkira Hatanaka static CGPointerAuthInfo
131ae18b941SAkira Hatanaka getPointerAuthInfoForPointeeType(CodeGenModule &CGM, QualType PointeeType) {
132ae18b941SAkira Hatanaka   if (PointeeType.isNull())
133ae18b941SAkira Hatanaka     return CGPointerAuthInfo();
134ae18b941SAkira Hatanaka 
135ae18b941SAkira Hatanaka   // Function pointers use the function-pointer schema by default.
136ae18b941SAkira Hatanaka   if (PointeeType->isFunctionType())
137ae18b941SAkira Hatanaka     return CGM.getFunctionPointerAuthInfo(PointeeType);
138ae18b941SAkira Hatanaka 
139ae18b941SAkira Hatanaka   // Normal data pointers never use direct pointer authentication by default.
140ae18b941SAkira Hatanaka   return CGPointerAuthInfo();
141ae18b941SAkira Hatanaka }
142ae18b941SAkira Hatanaka 
143ae18b941SAkira Hatanaka CGPointerAuthInfo CodeGenModule::getPointerAuthInfoForPointeeType(QualType T) {
144ae18b941SAkira Hatanaka   return ::getPointerAuthInfoForPointeeType(*this, T);
145ae18b941SAkira Hatanaka }
146ae18b941SAkira Hatanaka 
147ae18b941SAkira Hatanaka /// Return the natural pointer authentication for values of the given
148ae18b941SAkira Hatanaka /// pointer type.
149ae18b941SAkira Hatanaka static CGPointerAuthInfo getPointerAuthInfoForType(CodeGenModule &CGM,
150ae18b941SAkira Hatanaka                                                    QualType PointerType) {
151ae18b941SAkira Hatanaka   assert(PointerType->isSignableType());
152ae18b941SAkira Hatanaka 
153ae18b941SAkira Hatanaka   // Block pointers are currently not signed.
154ae18b941SAkira Hatanaka   if (PointerType->isBlockPointerType())
155ae18b941SAkira Hatanaka     return CGPointerAuthInfo();
156ae18b941SAkira Hatanaka 
157ae18b941SAkira Hatanaka   auto PointeeType = PointerType->getPointeeType();
158ae18b941SAkira Hatanaka 
159ae18b941SAkira Hatanaka   if (PointeeType.isNull())
160ae18b941SAkira Hatanaka     return CGPointerAuthInfo();
161ae18b941SAkira Hatanaka 
162ae18b941SAkira Hatanaka   return ::getPointerAuthInfoForPointeeType(CGM, PointeeType);
163ae18b941SAkira Hatanaka }
164ae18b941SAkira Hatanaka 
165ae18b941SAkira Hatanaka CGPointerAuthInfo CodeGenModule::getPointerAuthInfoForType(QualType T) {
166ae18b941SAkira Hatanaka   return ::getPointerAuthInfoForType(*this, T);
167ae18b941SAkira Hatanaka }
168ae18b941SAkira Hatanaka 
169f6b06b42SAkira Hatanaka static bool isZeroConstant(const llvm::Value *Value) {
170f6b06b42SAkira Hatanaka   if (const auto *CI = dyn_cast<llvm::ConstantInt>(Value))
171f6b06b42SAkira Hatanaka     return CI->isZero();
172f6b06b42SAkira Hatanaka   return false;
173f6b06b42SAkira Hatanaka }
174f6b06b42SAkira Hatanaka 
175f6b06b42SAkira Hatanaka static bool equalAuthPolicies(const CGPointerAuthInfo &Left,
176f6b06b42SAkira Hatanaka                               const CGPointerAuthInfo &Right) {
177f6b06b42SAkira Hatanaka   assert((Left.isSigned() || Right.isSigned()) &&
178f6b06b42SAkira Hatanaka          "shouldn't be called if neither is signed");
179f6b06b42SAkira Hatanaka   if (Left.isSigned() != Right.isSigned())
180f6b06b42SAkira Hatanaka     return false;
181f6b06b42SAkira Hatanaka   return Left.getKey() == Right.getKey() &&
182f6b06b42SAkira Hatanaka          Left.getAuthenticationMode() == Right.getAuthenticationMode();
183f6b06b42SAkira Hatanaka }
184f6b06b42SAkira Hatanaka 
185f6b06b42SAkira Hatanaka // Return the discriminator or return zero if the discriminator is null.
186f6b06b42SAkira Hatanaka static llvm::Value *getDiscriminatorOrZero(const CGPointerAuthInfo &Info,
187f6b06b42SAkira Hatanaka                                            CGBuilderTy &Builder) {
188f6b06b42SAkira Hatanaka   llvm::Value *Discriminator = Info.getDiscriminator();
189f6b06b42SAkira Hatanaka   return Discriminator ? Discriminator : Builder.getSize(0);
190f6b06b42SAkira Hatanaka }
191f6b06b42SAkira Hatanaka 
192f6b06b42SAkira Hatanaka llvm::Value *
193f6b06b42SAkira Hatanaka CodeGenFunction::emitPointerAuthResignCall(llvm::Value *Value,
194f6b06b42SAkira Hatanaka                                            const CGPointerAuthInfo &CurAuth,
195f6b06b42SAkira Hatanaka                                            const CGPointerAuthInfo &NewAuth) {
196f6b06b42SAkira Hatanaka   assert(CurAuth && NewAuth);
197f6b06b42SAkira Hatanaka 
198f6b06b42SAkira Hatanaka   if (CurAuth.getAuthenticationMode() !=
199f6b06b42SAkira Hatanaka           PointerAuthenticationMode::SignAndAuth ||
200f6b06b42SAkira Hatanaka       NewAuth.getAuthenticationMode() !=
201f6b06b42SAkira Hatanaka           PointerAuthenticationMode::SignAndAuth) {
202f6b06b42SAkira Hatanaka     llvm::Value *AuthedValue = EmitPointerAuthAuth(CurAuth, Value);
203f6b06b42SAkira Hatanaka     return EmitPointerAuthSign(NewAuth, AuthedValue);
204f6b06b42SAkira Hatanaka   }
205f6b06b42SAkira Hatanaka   // Convert the pointer to intptr_t before signing it.
206f6b06b42SAkira Hatanaka   auto *OrigType = Value->getType();
207f6b06b42SAkira Hatanaka   Value = Builder.CreatePtrToInt(Value, IntPtrTy);
208f6b06b42SAkira Hatanaka 
209f6b06b42SAkira Hatanaka   auto *CurKey = Builder.getInt32(CurAuth.getKey());
210f6b06b42SAkira Hatanaka   auto *NewKey = Builder.getInt32(NewAuth.getKey());
211f6b06b42SAkira Hatanaka 
212f6b06b42SAkira Hatanaka   llvm::Value *CurDiscriminator = getDiscriminatorOrZero(CurAuth, Builder);
213f6b06b42SAkira Hatanaka   llvm::Value *NewDiscriminator = getDiscriminatorOrZero(NewAuth, Builder);
214f6b06b42SAkira Hatanaka 
215f6b06b42SAkira Hatanaka   // call i64 @llvm.ptrauth.resign(i64 %pointer,
216f6b06b42SAkira Hatanaka   //                               i32 %curKey, i64 %curDiscriminator,
217f6b06b42SAkira Hatanaka   //                               i32 %newKey, i64 %newDiscriminator)
218f6b06b42SAkira Hatanaka   auto *Intrinsic = CGM.getIntrinsic(llvm::Intrinsic::ptrauth_resign);
219f6b06b42SAkira Hatanaka   Value = EmitRuntimeCall(
220f6b06b42SAkira Hatanaka       Intrinsic, {Value, CurKey, CurDiscriminator, NewKey, NewDiscriminator});
221f6b06b42SAkira Hatanaka 
222f6b06b42SAkira Hatanaka   // Convert back to the original type.
223f6b06b42SAkira Hatanaka   Value = Builder.CreateIntToPtr(Value, OrigType);
224f6b06b42SAkira Hatanaka   return Value;
225f6b06b42SAkira Hatanaka }
226f6b06b42SAkira Hatanaka 
227f6b06b42SAkira Hatanaka llvm::Value *CodeGenFunction::emitPointerAuthResign(
228f6b06b42SAkira Hatanaka     llvm::Value *Value, QualType Type, const CGPointerAuthInfo &CurAuthInfo,
229f6b06b42SAkira Hatanaka     const CGPointerAuthInfo &NewAuthInfo, bool IsKnownNonNull) {
230f6b06b42SAkira Hatanaka   // Fast path: if neither schema wants a signature, we're done.
231f6b06b42SAkira Hatanaka   if (!CurAuthInfo && !NewAuthInfo)
232f6b06b42SAkira Hatanaka     return Value;
233f6b06b42SAkira Hatanaka 
234f6b06b42SAkira Hatanaka   llvm::Value *Null = nullptr;
235f6b06b42SAkira Hatanaka   // If the value is obviously null, we're done.
236f6b06b42SAkira Hatanaka   if (auto *PointerValue = dyn_cast<llvm::PointerType>(Value->getType())) {
237f6b06b42SAkira Hatanaka     Null = CGM.getNullPointer(PointerValue, Type);
238f6b06b42SAkira Hatanaka   } else {
239f6b06b42SAkira Hatanaka     assert(Value->getType()->isIntegerTy());
240f6b06b42SAkira Hatanaka     Null = llvm::ConstantInt::get(IntPtrTy, 0);
241f6b06b42SAkira Hatanaka   }
242f6b06b42SAkira Hatanaka   if (Value == Null)
243f6b06b42SAkira Hatanaka     return Value;
244f6b06b42SAkira Hatanaka 
245f6b06b42SAkira Hatanaka   // If both schemas sign the same way, we're done.
246f6b06b42SAkira Hatanaka   if (equalAuthPolicies(CurAuthInfo, NewAuthInfo)) {
247f6b06b42SAkira Hatanaka     const llvm::Value *CurD = CurAuthInfo.getDiscriminator();
248f6b06b42SAkira Hatanaka     const llvm::Value *NewD = NewAuthInfo.getDiscriminator();
249f6b06b42SAkira Hatanaka     if (CurD == NewD)
250f6b06b42SAkira Hatanaka       return Value;
251f6b06b42SAkira Hatanaka 
252f6b06b42SAkira Hatanaka     if ((CurD == nullptr && isZeroConstant(NewD)) ||
253f6b06b42SAkira Hatanaka         (NewD == nullptr && isZeroConstant(CurD)))
254f6b06b42SAkira Hatanaka       return Value;
255f6b06b42SAkira Hatanaka   }
256f6b06b42SAkira Hatanaka 
257f6b06b42SAkira Hatanaka   llvm::BasicBlock *InitBB = Builder.GetInsertBlock();
258f6b06b42SAkira Hatanaka   llvm::BasicBlock *ResignBB = nullptr, *ContBB = nullptr;
259f6b06b42SAkira Hatanaka 
260f6b06b42SAkira Hatanaka   // Null pointers have to be mapped to null, and the ptrauth_resign
261f6b06b42SAkira Hatanaka   // intrinsic doesn't do that.
262f6b06b42SAkira Hatanaka   if (!IsKnownNonNull && !llvm::isKnownNonZero(Value, CGM.getDataLayout())) {
263f6b06b42SAkira Hatanaka     ContBB = createBasicBlock("resign.cont");
264f6b06b42SAkira Hatanaka     ResignBB = createBasicBlock("resign.nonnull");
265f6b06b42SAkira Hatanaka 
266f6b06b42SAkira Hatanaka     auto *IsNonNull = Builder.CreateICmpNE(Value, Null);
267f6b06b42SAkira Hatanaka     Builder.CreateCondBr(IsNonNull, ResignBB, ContBB);
268f6b06b42SAkira Hatanaka     EmitBlock(ResignBB);
269f6b06b42SAkira Hatanaka   }
270f6b06b42SAkira Hatanaka 
271f6b06b42SAkira Hatanaka   // Perform the auth/sign/resign operation.
272f6b06b42SAkira Hatanaka   if (!NewAuthInfo)
273f6b06b42SAkira Hatanaka     Value = EmitPointerAuthAuth(CurAuthInfo, Value);
274f6b06b42SAkira Hatanaka   else if (!CurAuthInfo)
275f6b06b42SAkira Hatanaka     Value = EmitPointerAuthSign(NewAuthInfo, Value);
276f6b06b42SAkira Hatanaka   else
277f6b06b42SAkira Hatanaka     Value = emitPointerAuthResignCall(Value, CurAuthInfo, NewAuthInfo);
278f6b06b42SAkira Hatanaka 
279f6b06b42SAkira Hatanaka   // Clean up with a phi if we branched before.
280f6b06b42SAkira Hatanaka   if (ContBB) {
281f6b06b42SAkira Hatanaka     EmitBlock(ContBB);
282f6b06b42SAkira Hatanaka     auto *Phi = Builder.CreatePHI(Value->getType(), 2);
283f6b06b42SAkira Hatanaka     Phi->addIncoming(Null, InitBB);
284f6b06b42SAkira Hatanaka     Phi->addIncoming(Value, ResignBB);
285f6b06b42SAkira Hatanaka     Value = Phi;
286f6b06b42SAkira Hatanaka   }
287f6b06b42SAkira Hatanaka 
288f6b06b42SAkira Hatanaka   return Value;
289f6b06b42SAkira Hatanaka }
290f6b06b42SAkira Hatanaka 
2917c814c13SAhmed Bougacha llvm::Constant *
2927c814c13SAhmed Bougacha CodeGenModule::getConstantSignedPointer(llvm::Constant *Pointer, unsigned Key,
2937c814c13SAhmed Bougacha                                         llvm::Constant *StorageAddress,
2947c814c13SAhmed Bougacha                                         llvm::ConstantInt *OtherDiscriminator) {
2957c814c13SAhmed Bougacha   llvm::Constant *AddressDiscriminator;
2967c814c13SAhmed Bougacha   if (StorageAddress) {
2977c814c13SAhmed Bougacha     assert(StorageAddress->getType() == UnqualPtrTy);
2987c814c13SAhmed Bougacha     AddressDiscriminator = StorageAddress;
2997c814c13SAhmed Bougacha   } else {
3007c814c13SAhmed Bougacha     AddressDiscriminator = llvm::Constant::getNullValue(UnqualPtrTy);
3017c814c13SAhmed Bougacha   }
3027c814c13SAhmed Bougacha 
3037c814c13SAhmed Bougacha   llvm::ConstantInt *IntegerDiscriminator;
3047c814c13SAhmed Bougacha   if (OtherDiscriminator) {
3057c814c13SAhmed Bougacha     assert(OtherDiscriminator->getType() == Int64Ty);
3067c814c13SAhmed Bougacha     IntegerDiscriminator = OtherDiscriminator;
3077c814c13SAhmed Bougacha   } else {
3087c814c13SAhmed Bougacha     IntegerDiscriminator = llvm::ConstantInt::get(Int64Ty, 0);
3097c814c13SAhmed Bougacha   }
3107c814c13SAhmed Bougacha 
3117c814c13SAhmed Bougacha   return llvm::ConstantPtrAuth::get(Pointer,
3127c814c13SAhmed Bougacha                                     llvm::ConstantInt::get(Int32Ty, Key),
3137c814c13SAhmed Bougacha                                     IntegerDiscriminator, AddressDiscriminator);
3147c814c13SAhmed Bougacha }
315e23250ecSAhmed Bougacha 
3161b8ab2f0SOliver Hunt /// Does a given PointerAuthScheme require us to sign a value
3171b8ab2f0SOliver Hunt bool CodeGenModule::shouldSignPointer(const PointerAuthSchema &Schema) {
3181b8ab2f0SOliver Hunt   auto AuthenticationMode = Schema.getAuthenticationMode();
3191b8ab2f0SOliver Hunt   return AuthenticationMode == PointerAuthenticationMode::SignAndStrip ||
3201b8ab2f0SOliver Hunt          AuthenticationMode == PointerAuthenticationMode::SignAndAuth;
3211b8ab2f0SOliver Hunt }
3221b8ab2f0SOliver Hunt 
3231b8ab2f0SOliver Hunt /// Sign a constant pointer using the given scheme, producing a constant
3241b8ab2f0SOliver Hunt /// with the same IR type.
3251b8ab2f0SOliver Hunt llvm::Constant *CodeGenModule::getConstantSignedPointer(
3261b8ab2f0SOliver Hunt     llvm::Constant *Pointer, const PointerAuthSchema &Schema,
3271b8ab2f0SOliver Hunt     llvm::Constant *StorageAddress, GlobalDecl SchemaDecl,
3281b8ab2f0SOliver Hunt     QualType SchemaType) {
3291b8ab2f0SOliver Hunt   assert(shouldSignPointer(Schema));
3301b8ab2f0SOliver Hunt   llvm::ConstantInt *OtherDiscriminator =
3311b8ab2f0SOliver Hunt       getPointerAuthOtherDiscriminator(Schema, SchemaDecl, SchemaType);
3321b8ab2f0SOliver Hunt 
3331b8ab2f0SOliver Hunt   return getConstantSignedPointer(Pointer, Schema.getKey(), StorageAddress,
3341b8ab2f0SOliver Hunt                                   OtherDiscriminator);
3351b8ab2f0SOliver Hunt }
3361b8ab2f0SOliver Hunt 
3371b8ab2f0SOliver Hunt /// If applicable, sign a given constant function pointer with the ABI rules for
3381b8ab2f0SOliver Hunt /// functionType.
339e23250ecSAhmed Bougacha llvm::Constant *CodeGenModule::getFunctionPointer(llvm::Constant *Pointer,
340e23250ecSAhmed Bougacha                                                   QualType FunctionType) {
341e23250ecSAhmed Bougacha   assert(FunctionType->isFunctionType() ||
342e23250ecSAhmed Bougacha          FunctionType->isFunctionReferenceType() ||
343e23250ecSAhmed Bougacha          FunctionType->isFunctionPointerType());
344e23250ecSAhmed Bougacha 
345e23250ecSAhmed Bougacha   if (auto PointerAuth = getFunctionPointerAuthInfo(FunctionType))
346e23250ecSAhmed Bougacha     return getConstantSignedPointer(
347e23250ecSAhmed Bougacha         Pointer, PointerAuth.getKey(), /*StorageAddress=*/nullptr,
348e23250ecSAhmed Bougacha         cast_or_null<llvm::ConstantInt>(PointerAuth.getDiscriminator()));
349e23250ecSAhmed Bougacha 
350e23250ecSAhmed Bougacha   return Pointer;
351e23250ecSAhmed Bougacha }
352e23250ecSAhmed Bougacha 
353e23250ecSAhmed Bougacha llvm::Constant *CodeGenModule::getFunctionPointer(GlobalDecl GD,
354e23250ecSAhmed Bougacha                                                   llvm::Type *Ty) {
355e23250ecSAhmed Bougacha   const auto *FD = cast<FunctionDecl>(GD.getDecl());
356e23250ecSAhmed Bougacha   QualType FuncType = FD->getType();
357ae18b941SAkira Hatanaka 
358ae18b941SAkira Hatanaka   // Annoyingly, K&R functions have prototypes in the clang AST, but
359ae18b941SAkira Hatanaka   // expressions referring to them are unprototyped.
360ae18b941SAkira Hatanaka   if (!FD->hasPrototype())
361ae18b941SAkira Hatanaka     if (const auto *Proto = FuncType->getAs<FunctionProtoType>())
362ae18b941SAkira Hatanaka       FuncType = Context.getFunctionNoProtoType(Proto->getReturnType(),
363ae18b941SAkira Hatanaka                                                 Proto->getExtInfo());
364ae18b941SAkira Hatanaka 
365e23250ecSAhmed Bougacha   return getFunctionPointer(getRawFunctionPointer(GD, Ty), FuncType);
366e23250ecSAhmed Bougacha }
3671b8ab2f0SOliver Hunt 
368*4dcd91aeSOliver Hunt CGPointerAuthInfo CodeGenModule::getMemberFunctionPointerAuthInfo(QualType FT) {
369*4dcd91aeSOliver Hunt   assert(FT->getAs<MemberPointerType>() && "MemberPointerType expected");
370*4dcd91aeSOliver Hunt   const auto &Schema = getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers;
371*4dcd91aeSOliver Hunt   if (!Schema)
372*4dcd91aeSOliver Hunt     return CGPointerAuthInfo();
373*4dcd91aeSOliver Hunt 
374*4dcd91aeSOliver Hunt   assert(!Schema.isAddressDiscriminated() &&
375*4dcd91aeSOliver Hunt          "function pointers cannot use address-specific discrimination");
376*4dcd91aeSOliver Hunt 
377*4dcd91aeSOliver Hunt   llvm::ConstantInt *Discriminator =
378*4dcd91aeSOliver Hunt       getPointerAuthOtherDiscriminator(Schema, GlobalDecl(), FT);
379*4dcd91aeSOliver Hunt   return CGPointerAuthInfo(Schema.getKey(), Schema.getAuthenticationMode(),
380*4dcd91aeSOliver Hunt                            /* IsIsaPointer */ false,
381*4dcd91aeSOliver Hunt                            /* AuthenticatesNullValues */ false, Discriminator);
382*4dcd91aeSOliver Hunt }
383*4dcd91aeSOliver Hunt 
384*4dcd91aeSOliver Hunt llvm::Constant *CodeGenModule::getMemberFunctionPointer(llvm::Constant *Pointer,
385*4dcd91aeSOliver Hunt                                                         QualType FT) {
386*4dcd91aeSOliver Hunt   if (CGPointerAuthInfo PointerAuth = getMemberFunctionPointerAuthInfo(FT))
387*4dcd91aeSOliver Hunt     return getConstantSignedPointer(
388*4dcd91aeSOliver Hunt         Pointer, PointerAuth.getKey(), nullptr,
389*4dcd91aeSOliver Hunt         cast_or_null<llvm::ConstantInt>(PointerAuth.getDiscriminator()));
390*4dcd91aeSOliver Hunt 
391*4dcd91aeSOliver Hunt   return Pointer;
392*4dcd91aeSOliver Hunt }
393*4dcd91aeSOliver Hunt 
394*4dcd91aeSOliver Hunt llvm::Constant *CodeGenModule::getMemberFunctionPointer(const FunctionDecl *FD,
395*4dcd91aeSOliver Hunt                                                         llvm::Type *Ty) {
396*4dcd91aeSOliver Hunt   QualType FT = FD->getType();
397*4dcd91aeSOliver Hunt   FT = getContext().getMemberPointerType(
398*4dcd91aeSOliver Hunt       FT, cast<CXXMethodDecl>(FD)->getParent()->getTypeForDecl());
399*4dcd91aeSOliver Hunt   return getMemberFunctionPointer(getRawFunctionPointer(FD, Ty), FT);
400*4dcd91aeSOliver Hunt }
401*4dcd91aeSOliver Hunt 
4021b8ab2f0SOliver Hunt std::optional<PointerAuthQualifier>
4031b8ab2f0SOliver Hunt CodeGenModule::computeVTPointerAuthentication(const CXXRecordDecl *ThisClass) {
4041b8ab2f0SOliver Hunt   auto DefaultAuthentication = getCodeGenOpts().PointerAuth.CXXVTablePointers;
4051b8ab2f0SOliver Hunt   if (!DefaultAuthentication)
4061b8ab2f0SOliver Hunt     return std::nullopt;
4071b8ab2f0SOliver Hunt   const CXXRecordDecl *PrimaryBase =
4081b8ab2f0SOliver Hunt       Context.baseForVTableAuthentication(ThisClass);
4091b8ab2f0SOliver Hunt 
4101b8ab2f0SOliver Hunt   unsigned Key = DefaultAuthentication.getKey();
4111b8ab2f0SOliver Hunt   bool AddressDiscriminated = DefaultAuthentication.isAddressDiscriminated();
4121b8ab2f0SOliver Hunt   auto DefaultDiscrimination = DefaultAuthentication.getOtherDiscrimination();
4131b8ab2f0SOliver Hunt   unsigned TypeBasedDiscriminator =
4141b8ab2f0SOliver Hunt       Context.getPointerAuthVTablePointerDiscriminator(PrimaryBase);
4151b8ab2f0SOliver Hunt   unsigned Discriminator;
4161b8ab2f0SOliver Hunt   if (DefaultDiscrimination == PointerAuthSchema::Discrimination::Type) {
4171b8ab2f0SOliver Hunt     Discriminator = TypeBasedDiscriminator;
4181b8ab2f0SOliver Hunt   } else if (DefaultDiscrimination ==
4191b8ab2f0SOliver Hunt              PointerAuthSchema::Discrimination::Constant) {
4201b8ab2f0SOliver Hunt     Discriminator = DefaultAuthentication.getConstantDiscrimination();
4211b8ab2f0SOliver Hunt   } else {
4221b8ab2f0SOliver Hunt     assert(DefaultDiscrimination == PointerAuthSchema::Discrimination::None);
4231b8ab2f0SOliver Hunt     Discriminator = 0;
4241b8ab2f0SOliver Hunt   }
4251b8ab2f0SOliver Hunt   if (auto ExplicitAuthentication =
4261b8ab2f0SOliver Hunt           PrimaryBase->getAttr<VTablePointerAuthenticationAttr>()) {
4271b8ab2f0SOliver Hunt     auto ExplicitAddressDiscrimination =
4281b8ab2f0SOliver Hunt         ExplicitAuthentication->getAddressDiscrimination();
4291b8ab2f0SOliver Hunt     auto ExplicitDiscriminator =
4301b8ab2f0SOliver Hunt         ExplicitAuthentication->getExtraDiscrimination();
4311b8ab2f0SOliver Hunt 
4321b8ab2f0SOliver Hunt     unsigned ExplicitKey = ExplicitAuthentication->getKey();
4331b8ab2f0SOliver Hunt     if (ExplicitKey == VTablePointerAuthenticationAttr::NoKey)
4341b8ab2f0SOliver Hunt       return std::nullopt;
4351b8ab2f0SOliver Hunt 
4361b8ab2f0SOliver Hunt     if (ExplicitKey != VTablePointerAuthenticationAttr::DefaultKey) {
4371b8ab2f0SOliver Hunt       if (ExplicitKey == VTablePointerAuthenticationAttr::ProcessIndependent)
4381b8ab2f0SOliver Hunt         Key = (unsigned)PointerAuthSchema::ARM8_3Key::ASDA;
4391b8ab2f0SOliver Hunt       else {
4401b8ab2f0SOliver Hunt         assert(ExplicitKey ==
4411b8ab2f0SOliver Hunt                VTablePointerAuthenticationAttr::ProcessDependent);
4421b8ab2f0SOliver Hunt         Key = (unsigned)PointerAuthSchema::ARM8_3Key::ASDB;
4431b8ab2f0SOliver Hunt       }
4441b8ab2f0SOliver Hunt     }
4451b8ab2f0SOliver Hunt 
4461b8ab2f0SOliver Hunt     if (ExplicitAddressDiscrimination !=
4471b8ab2f0SOliver Hunt         VTablePointerAuthenticationAttr::DefaultAddressDiscrimination)
4481b8ab2f0SOliver Hunt       AddressDiscriminated =
4491b8ab2f0SOliver Hunt           ExplicitAddressDiscrimination ==
4501b8ab2f0SOliver Hunt           VTablePointerAuthenticationAttr::AddressDiscrimination;
4511b8ab2f0SOliver Hunt 
4521b8ab2f0SOliver Hunt     if (ExplicitDiscriminator ==
4531b8ab2f0SOliver Hunt         VTablePointerAuthenticationAttr::TypeDiscrimination)
4541b8ab2f0SOliver Hunt       Discriminator = TypeBasedDiscriminator;
4551b8ab2f0SOliver Hunt     else if (ExplicitDiscriminator ==
4561b8ab2f0SOliver Hunt              VTablePointerAuthenticationAttr::CustomDiscrimination)
4571b8ab2f0SOliver Hunt       Discriminator = ExplicitAuthentication->getCustomDiscriminationValue();
4581b8ab2f0SOliver Hunt     else if (ExplicitDiscriminator ==
4591b8ab2f0SOliver Hunt              VTablePointerAuthenticationAttr::NoExtraDiscrimination)
4601b8ab2f0SOliver Hunt       Discriminator = 0;
4611b8ab2f0SOliver Hunt   }
4621b8ab2f0SOliver Hunt   return PointerAuthQualifier::Create(Key, AddressDiscriminated, Discriminator,
4631b8ab2f0SOliver Hunt                                       PointerAuthenticationMode::SignAndAuth,
4641b8ab2f0SOliver Hunt                                       /* IsIsaPointer */ false,
4651b8ab2f0SOliver Hunt                                       /* AuthenticatesNullValues */ false);
4661b8ab2f0SOliver Hunt }
4671b8ab2f0SOliver Hunt 
4681b8ab2f0SOliver Hunt std::optional<PointerAuthQualifier>
4691b8ab2f0SOliver Hunt CodeGenModule::getVTablePointerAuthentication(const CXXRecordDecl *Record) {
4701b8ab2f0SOliver Hunt   if (!Record->getDefinition() || !Record->isPolymorphic())
4711b8ab2f0SOliver Hunt     return std::nullopt;
4721b8ab2f0SOliver Hunt 
4731b8ab2f0SOliver Hunt   auto Existing = VTablePtrAuthInfos.find(Record);
4741b8ab2f0SOliver Hunt   std::optional<PointerAuthQualifier> Authentication;
4751b8ab2f0SOliver Hunt   if (Existing != VTablePtrAuthInfos.end()) {
4761b8ab2f0SOliver Hunt     Authentication = Existing->getSecond();
4771b8ab2f0SOliver Hunt   } else {
4781b8ab2f0SOliver Hunt     Authentication = computeVTPointerAuthentication(Record);
4791b8ab2f0SOliver Hunt     VTablePtrAuthInfos.insert(std::make_pair(Record, Authentication));
4801b8ab2f0SOliver Hunt   }
4811b8ab2f0SOliver Hunt   return Authentication;
4821b8ab2f0SOliver Hunt }
4831b8ab2f0SOliver Hunt 
4841b8ab2f0SOliver Hunt std::optional<CGPointerAuthInfo>
4851b8ab2f0SOliver Hunt CodeGenModule::getVTablePointerAuthInfo(CodeGenFunction *CGF,
4861b8ab2f0SOliver Hunt                                         const CXXRecordDecl *Record,
4871b8ab2f0SOliver Hunt                                         llvm::Value *StorageAddress) {
4881b8ab2f0SOliver Hunt   auto Authentication = getVTablePointerAuthentication(Record);
4891b8ab2f0SOliver Hunt   if (!Authentication)
4901b8ab2f0SOliver Hunt     return std::nullopt;
4911b8ab2f0SOliver Hunt 
4921b8ab2f0SOliver Hunt   llvm::Value *Discriminator = nullptr;
4931b8ab2f0SOliver Hunt   if (auto ExtraDiscriminator = Authentication->getExtraDiscriminator())
4941b8ab2f0SOliver Hunt     Discriminator = llvm::ConstantInt::get(IntPtrTy, ExtraDiscriminator);
4951b8ab2f0SOliver Hunt 
4961b8ab2f0SOliver Hunt   if (Authentication->isAddressDiscriminated()) {
4971b8ab2f0SOliver Hunt     assert(StorageAddress &&
4981b8ab2f0SOliver Hunt            "address not provided for address-discriminated schema");
4991b8ab2f0SOliver Hunt     if (Discriminator)
5001b8ab2f0SOliver Hunt       Discriminator =
5011b8ab2f0SOliver Hunt           CGF->EmitPointerAuthBlendDiscriminator(StorageAddress, Discriminator);
5021b8ab2f0SOliver Hunt     else
5031b8ab2f0SOliver Hunt       Discriminator = CGF->Builder.CreatePtrToInt(StorageAddress, IntPtrTy);
5041b8ab2f0SOliver Hunt   }
5051b8ab2f0SOliver Hunt 
5061b8ab2f0SOliver Hunt   return CGPointerAuthInfo(Authentication->getKey(),
5071b8ab2f0SOliver Hunt                            PointerAuthenticationMode::SignAndAuth,
5081b8ab2f0SOliver Hunt                            /* IsIsaPointer */ false,
5091b8ab2f0SOliver Hunt                            /* AuthenticatesNullValues */ false, Discriminator);
5101b8ab2f0SOliver Hunt }
511f6b06b42SAkira Hatanaka 
512f6b06b42SAkira Hatanaka llvm::Value *CodeGenFunction::authPointerToPointerCast(llvm::Value *ResultPtr,
513f6b06b42SAkira Hatanaka                                                        QualType SourceType,
514f6b06b42SAkira Hatanaka                                                        QualType DestType) {
515f6b06b42SAkira Hatanaka   CGPointerAuthInfo CurAuthInfo, NewAuthInfo;
516f6b06b42SAkira Hatanaka   if (SourceType->isSignableType())
517f6b06b42SAkira Hatanaka     CurAuthInfo = getPointerAuthInfoForType(CGM, SourceType);
518f6b06b42SAkira Hatanaka 
519f6b06b42SAkira Hatanaka   if (DestType->isSignableType())
520f6b06b42SAkira Hatanaka     NewAuthInfo = getPointerAuthInfoForType(CGM, DestType);
521f6b06b42SAkira Hatanaka 
522f6b06b42SAkira Hatanaka   if (!CurAuthInfo && !NewAuthInfo)
523f6b06b42SAkira Hatanaka     return ResultPtr;
524f6b06b42SAkira Hatanaka 
525f6b06b42SAkira Hatanaka   // If only one side of the cast is a function pointer, then we still need to
526f6b06b42SAkira Hatanaka   // resign to handle casts to/from opaque pointers.
527f6b06b42SAkira Hatanaka   if (!CurAuthInfo && DestType->isFunctionPointerType())
528f6b06b42SAkira Hatanaka     CurAuthInfo = CGM.getFunctionPointerAuthInfo(SourceType);
529f6b06b42SAkira Hatanaka 
530f6b06b42SAkira Hatanaka   if (!NewAuthInfo && SourceType->isFunctionPointerType())
531f6b06b42SAkira Hatanaka     NewAuthInfo = CGM.getFunctionPointerAuthInfo(DestType);
532f6b06b42SAkira Hatanaka 
533f6b06b42SAkira Hatanaka   return emitPointerAuthResign(ResultPtr, DestType, CurAuthInfo, NewAuthInfo,
534f6b06b42SAkira Hatanaka                                /*IsKnownNonNull=*/false);
535f6b06b42SAkira Hatanaka }
536f6b06b42SAkira Hatanaka 
537f6b06b42SAkira Hatanaka Address CodeGenFunction::authPointerToPointerCast(Address Ptr,
538f6b06b42SAkira Hatanaka                                                   QualType SourceType,
539f6b06b42SAkira Hatanaka                                                   QualType DestType) {
540f6b06b42SAkira Hatanaka   CGPointerAuthInfo CurAuthInfo, NewAuthInfo;
541f6b06b42SAkira Hatanaka   if (SourceType->isSignableType())
542f6b06b42SAkira Hatanaka     CurAuthInfo = getPointerAuthInfoForType(CGM, SourceType);
543f6b06b42SAkira Hatanaka 
544f6b06b42SAkira Hatanaka   if (DestType->isSignableType())
545f6b06b42SAkira Hatanaka     NewAuthInfo = getPointerAuthInfoForType(CGM, DestType);
546f6b06b42SAkira Hatanaka 
547f6b06b42SAkira Hatanaka   if (!CurAuthInfo && !NewAuthInfo)
548f6b06b42SAkira Hatanaka     return Ptr;
549f6b06b42SAkira Hatanaka 
550f6b06b42SAkira Hatanaka   if (!CurAuthInfo && DestType->isFunctionPointerType()) {
551f6b06b42SAkira Hatanaka     // When casting a non-signed pointer to a function pointer, just set the
552f6b06b42SAkira Hatanaka     // auth info on Ptr to the assumed schema. The pointer will be resigned to
553f6b06b42SAkira Hatanaka     // the effective type when used.
554f6b06b42SAkira Hatanaka     Ptr.setPointerAuthInfo(CGM.getFunctionPointerAuthInfo(SourceType));
555f6b06b42SAkira Hatanaka     return Ptr;
556f6b06b42SAkira Hatanaka   }
557f6b06b42SAkira Hatanaka 
558f6b06b42SAkira Hatanaka   if (!NewAuthInfo && SourceType->isFunctionPointerType()) {
559f6b06b42SAkira Hatanaka     NewAuthInfo = CGM.getFunctionPointerAuthInfo(DestType);
560f6b06b42SAkira Hatanaka     Ptr = Ptr.getResignedAddress(NewAuthInfo, *this);
561f6b06b42SAkira Hatanaka     Ptr.setPointerAuthInfo(CGPointerAuthInfo());
562f6b06b42SAkira Hatanaka     return Ptr;
563f6b06b42SAkira Hatanaka   }
564f6b06b42SAkira Hatanaka 
565f6b06b42SAkira Hatanaka   return Ptr;
566f6b06b42SAkira Hatanaka }
567f6b06b42SAkira Hatanaka 
568f6b06b42SAkira Hatanaka Address CodeGenFunction::getAsNaturalAddressOf(Address Addr,
569f6b06b42SAkira Hatanaka                                                QualType PointeeTy) {
570f6b06b42SAkira Hatanaka   CGPointerAuthInfo Info =
571f6b06b42SAkira Hatanaka       PointeeTy.isNull() ? CGPointerAuthInfo()
572f6b06b42SAkira Hatanaka                          : CGM.getPointerAuthInfoForPointeeType(PointeeTy);
573f6b06b42SAkira Hatanaka   return Addr.getResignedAddress(Info, *this);
574f6b06b42SAkira Hatanaka }
575f6b06b42SAkira Hatanaka 
576f6b06b42SAkira Hatanaka Address Address::getResignedAddress(const CGPointerAuthInfo &NewInfo,
577f6b06b42SAkira Hatanaka                                     CodeGenFunction &CGF) const {
578f6b06b42SAkira Hatanaka   assert(isValid() && "pointer isn't valid");
579f6b06b42SAkira Hatanaka   CGPointerAuthInfo CurInfo = getPointerAuthInfo();
580f6b06b42SAkira Hatanaka   llvm::Value *Val;
581f6b06b42SAkira Hatanaka 
582f6b06b42SAkira Hatanaka   // Nothing to do if neither the current or the new ptrauth info needs signing.
583f6b06b42SAkira Hatanaka   if (!CurInfo.isSigned() && !NewInfo.isSigned())
584f6b06b42SAkira Hatanaka     return Address(getBasePointer(), getElementType(), getAlignment(),
585f6b06b42SAkira Hatanaka                    isKnownNonNull());
586f6b06b42SAkira Hatanaka 
587f6b06b42SAkira Hatanaka   assert(ElementType && "Effective type has to be set");
588f6b06b42SAkira Hatanaka   assert(!Offset && "unexpected non-null offset");
589f6b06b42SAkira Hatanaka 
590f6b06b42SAkira Hatanaka   // If the current and the new ptrauth infos are the same and the offset is
591f6b06b42SAkira Hatanaka   // null, just cast the base pointer to the effective type.
592f6b06b42SAkira Hatanaka   if (CurInfo == NewInfo && !hasOffset())
593f6b06b42SAkira Hatanaka     Val = getBasePointer();
594f6b06b42SAkira Hatanaka   else
595f6b06b42SAkira Hatanaka     Val = CGF.emitPointerAuthResign(getBasePointer(), QualType(), CurInfo,
596f6b06b42SAkira Hatanaka                                     NewInfo, isKnownNonNull());
597f6b06b42SAkira Hatanaka 
598f6b06b42SAkira Hatanaka   Val = CGF.Builder.CreateBitCast(Val, getType());
599f6b06b42SAkira Hatanaka   return Address(Val, getElementType(), getAlignment(), NewInfo,
600f6b06b42SAkira Hatanaka                  /*Offset=*/nullptr, isKnownNonNull());
601f6b06b42SAkira Hatanaka }
602f6b06b42SAkira Hatanaka 
603cf50a84dSAkira Hatanaka llvm::Value *Address::emitRawPointerSlow(CodeGenFunction &CGF) const {
604cf50a84dSAkira Hatanaka   return CGF.getAsNaturalPointerTo(*this, QualType());
605cf50a84dSAkira Hatanaka }
606cf50a84dSAkira Hatanaka 
607f6b06b42SAkira Hatanaka llvm::Value *LValue::getPointer(CodeGenFunction &CGF) const {
608f6b06b42SAkira Hatanaka   assert(isSimple());
609f6b06b42SAkira Hatanaka   return emitResignedPointer(getType(), CGF);
610f6b06b42SAkira Hatanaka }
611f6b06b42SAkira Hatanaka 
612f6b06b42SAkira Hatanaka llvm::Value *LValue::emitResignedPointer(QualType PointeeTy,
613f6b06b42SAkira Hatanaka                                          CodeGenFunction &CGF) const {
614f6b06b42SAkira Hatanaka   assert(isSimple());
615f6b06b42SAkira Hatanaka   return CGF.getAsNaturalAddressOf(Addr, PointeeTy).getBasePointer();
616f6b06b42SAkira Hatanaka }
617f6b06b42SAkira Hatanaka 
618f6b06b42SAkira Hatanaka llvm::Value *LValue::emitRawPointer(CodeGenFunction &CGF) const {
619f6b06b42SAkira Hatanaka   assert(isSimple());
620f6b06b42SAkira Hatanaka   return Addr.isValid() ? Addr.emitRawPointer(CGF) : nullptr;
621f6b06b42SAkira Hatanaka }
622