diff options
Diffstat (limited to 'clang/lib/CodeGen/CGPointerAuth.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGPointerAuth.cpp | 67 |
1 files changed, 63 insertions, 4 deletions
diff --git a/clang/lib/CodeGen/CGPointerAuth.cpp b/clang/lib/CodeGen/CGPointerAuth.cpp index 673f6e6..621d567 100644 --- a/clang/lib/CodeGen/CGPointerAuth.cpp +++ b/clang/lib/CodeGen/CGPointerAuth.cpp @@ -29,7 +29,9 @@ llvm::ConstantInt *CodeGenModule::getPointerAuthOtherDiscriminator( return nullptr; case PointerAuthSchema::Discrimination::Type: - llvm_unreachable("type discrimination not implemented yet"); + assert(!Type.isNull() && "type not provided for type-discriminated schema"); + return llvm::ConstantInt::get( + IntPtrTy, getContext().getPointerAuthTypeDiscriminator(Type)); case PointerAuthSchema::Discrimination::Decl: assert(Decl.getDecl() && @@ -43,6 +45,11 @@ llvm::ConstantInt *CodeGenModule::getPointerAuthOtherDiscriminator( llvm_unreachable("bad discrimination kind"); } +uint16_t CodeGen::getPointerAuthTypeDiscriminator(CodeGenModule &CGM, + QualType FunctionType) { + return CGM.getContext().getPointerAuthTypeDiscriminator(FunctionType); +} + uint16_t CodeGen::getPointerAuthDeclDiscriminator(CodeGenModule &CGM, GlobalDecl Declaration) { return CGM.getPointerAuthDeclDiscriminator(Declaration); @@ -71,12 +78,15 @@ CGPointerAuthInfo CodeGenModule::getFunctionPointerAuthInfo(QualType T) { assert(!Schema.isAddressDiscriminated() && "function pointers cannot use address-specific discrimination"); - assert(!Schema.hasOtherDiscrimination() && - "function pointers don't support any discrimination yet"); + llvm::Constant *Discriminator = nullptr; + if (T->isFunctionPointerType() || T->isFunctionReferenceType()) + T = T->getPointeeType(); + if (T->isFunctionType()) + Discriminator = getPointerAuthOtherDiscriminator(Schema, GlobalDecl(), T); return CGPointerAuthInfo(Schema.getKey(), Schema.getAuthenticationMode(), /*IsaPointer=*/false, /*AuthenticatesNull=*/false, - /*Discriminator=*/nullptr); + Discriminator); } llvm::Value * @@ -114,6 +124,47 @@ CGPointerAuthInfo CodeGenFunction::EmitPointerAuthInfo( Schema.authenticatesNullValues(), Discriminator); } +/// Return the natural pointer authentication for values of the given +/// pointee type. +static CGPointerAuthInfo +getPointerAuthInfoForPointeeType(CodeGenModule &CGM, QualType PointeeType) { + if (PointeeType.isNull()) + return CGPointerAuthInfo(); + + // Function pointers use the function-pointer schema by default. + if (PointeeType->isFunctionType()) + return CGM.getFunctionPointerAuthInfo(PointeeType); + + // Normal data pointers never use direct pointer authentication by default. + return CGPointerAuthInfo(); +} + +CGPointerAuthInfo CodeGenModule::getPointerAuthInfoForPointeeType(QualType T) { + return ::getPointerAuthInfoForPointeeType(*this, T); +} + +/// Return the natural pointer authentication for values of the given +/// pointer type. +static CGPointerAuthInfo getPointerAuthInfoForType(CodeGenModule &CGM, + QualType PointerType) { + assert(PointerType->isSignableType()); + + // Block pointers are currently not signed. + if (PointerType->isBlockPointerType()) + return CGPointerAuthInfo(); + + auto PointeeType = PointerType->getPointeeType(); + + if (PointeeType.isNull()) + return CGPointerAuthInfo(); + + return ::getPointerAuthInfoForPointeeType(CGM, PointeeType); +} + +CGPointerAuthInfo CodeGenModule::getPointerAuthInfoForType(QualType T) { + return ::getPointerAuthInfoForType(*this, T); +} + llvm::Constant * CodeGenModule::getConstantSignedPointer(llvm::Constant *Pointer, unsigned Key, llvm::Constant *StorageAddress, @@ -180,6 +231,14 @@ llvm::Constant *CodeGenModule::getFunctionPointer(GlobalDecl GD, llvm::Type *Ty) { const auto *FD = cast<FunctionDecl>(GD.getDecl()); QualType FuncType = FD->getType(); + + // Annoyingly, K&R functions have prototypes in the clang AST, but + // expressions referring to them are unprototyped. + if (!FD->hasPrototype()) + if (const auto *Proto = FuncType->getAs<FunctionProtoType>()) + FuncType = Context.getFunctionNoProtoType(Proto->getReturnType(), + Proto->getExtInfo()); + return getFunctionPointer(getRawFunctionPointer(GD, Ty), FuncType); } |