| //===--- CGPointerAuth.cpp - IR generation for pointer authentication -----===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file contains common routines relating to the emission of |
| // pointer authentication operations. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "CodeGenModule.h" |
| #include "clang/CodeGen/CodeGenABITypes.h" |
| |
| using namespace clang; |
| using namespace CodeGen; |
| |
| /// Return the abstract pointer authentication schema for a pointer to the given |
| /// function type. |
| CGPointerAuthInfo CodeGenModule::getFunctionPointerAuthInfo(QualType T) { |
| const auto &Schema = getCodeGenOpts().PointerAuth.FunctionPointers; |
| if (!Schema) |
| return CGPointerAuthInfo(); |
| |
| assert(!Schema.isAddressDiscriminated() && |
| "function pointers cannot use address-specific discrimination"); |
| |
| assert(!Schema.hasOtherDiscrimination() && |
| "function pointers don't support any discrimination yet"); |
| |
| return CGPointerAuthInfo(Schema.getKey(), Schema.getAuthenticationMode(), |
| /*IsaPointer=*/false, /*AuthenticatesNull=*/false, |
| /*Discriminator=*/nullptr); |
| } |
| |
| llvm::Constant * |
| CodeGenModule::getConstantSignedPointer(llvm::Constant *Pointer, unsigned Key, |
| llvm::Constant *StorageAddress, |
| llvm::ConstantInt *OtherDiscriminator) { |
| llvm::Constant *AddressDiscriminator; |
| if (StorageAddress) { |
| assert(StorageAddress->getType() == UnqualPtrTy); |
| AddressDiscriminator = StorageAddress; |
| } else { |
| AddressDiscriminator = llvm::Constant::getNullValue(UnqualPtrTy); |
| } |
| |
| llvm::ConstantInt *IntegerDiscriminator; |
| if (OtherDiscriminator) { |
| assert(OtherDiscriminator->getType() == Int64Ty); |
| IntegerDiscriminator = OtherDiscriminator; |
| } else { |
| IntegerDiscriminator = llvm::ConstantInt::get(Int64Ty, 0); |
| } |
| |
| return llvm::ConstantPtrAuth::get(Pointer, |
| llvm::ConstantInt::get(Int32Ty, Key), |
| IntegerDiscriminator, AddressDiscriminator); |
| } |
| |
| llvm::Constant *CodeGenModule::getFunctionPointer(llvm::Constant *Pointer, |
| QualType FunctionType) { |
| assert(FunctionType->isFunctionType() || |
| FunctionType->isFunctionReferenceType() || |
| FunctionType->isFunctionPointerType()); |
| |
| if (auto PointerAuth = getFunctionPointerAuthInfo(FunctionType)) |
| return getConstantSignedPointer( |
| Pointer, PointerAuth.getKey(), /*StorageAddress=*/nullptr, |
| cast_or_null<llvm::ConstantInt>(PointerAuth.getDiscriminator())); |
| |
| return Pointer; |
| } |
| |
| llvm::Constant *CodeGenModule::getFunctionPointer(GlobalDecl GD, |
| llvm::Type *Ty) { |
| const auto *FD = cast<FunctionDecl>(GD.getDecl()); |
| QualType FuncType = FD->getType(); |
| return getFunctionPointer(getRawFunctionPointer(GD, Ty), FuncType); |
| } |