diff options
Diffstat (limited to 'clang/lib/CodeGen/ItaniumCXXABI.cpp')
| -rw-r--r-- | clang/lib/CodeGen/ItaniumCXXABI.cpp | 98 |
1 files changed, 62 insertions, 36 deletions
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 4ed3775f156c..7dc2eaf1e9f7 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -91,6 +91,8 @@ public: case Dtor_Comdat: llvm_unreachable("emitting dtor comdat as function?"); + case Dtor_Unified: + llvm_unreachable("emitting unified dtor as function?"); } llvm_unreachable("bad dtor kind"); } @@ -108,6 +110,9 @@ public: case Ctor_Comdat: llvm_unreachable("emitting ctor comdat as function?"); + + case Ctor_Unified: + llvm_unreachable("emitting unified ctor as function?"); } llvm_unreachable("bad dtor kind"); } @@ -1397,9 +1402,7 @@ void ItaniumCXXABI::emitVirtualObjectDelete(CodeGenFunction &CGF, // to pass to the deallocation function. // Grab the vtable pointer as an intptr_t*. - auto *ClassDecl = cast<CXXRecordDecl>( - ElementType->castAs<RecordType>()->getOriginalDecl()) - ->getDefinitionOrSelf(); + auto *ClassDecl = ElementType->castAsCXXRecordDecl(); llvm::Value *VTable = CGF.GetVTablePtr(Ptr, CGF.UnqualPtrTy, ClassDecl); // Track back to entry -2 and pull out the offset there. @@ -1484,21 +1487,18 @@ void ItaniumCXXABI::emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) { // The address of the destructor. If the exception type has a // trivial destructor (or isn't a record), we just pass null. llvm::Constant *Dtor = nullptr; - if (const RecordType *RecordTy = ThrowType->getAs<RecordType>()) { - CXXRecordDecl *Record = - cast<CXXRecordDecl>(RecordTy->getOriginalDecl())->getDefinitionOrSelf(); - if (!Record->hasTrivialDestructor()) { - // __cxa_throw is declared to take its destructor as void (*)(void *). We - // must match that if function pointers can be authenticated with a - // discriminator based on their type. - const ASTContext &Ctx = getContext(); - QualType DtorTy = Ctx.getFunctionType(Ctx.VoidTy, {Ctx.VoidPtrTy}, - FunctionProtoType::ExtProtoInfo()); - - CXXDestructorDecl *DtorD = Record->getDestructor(); - Dtor = CGM.getAddrOfCXXStructor(GlobalDecl(DtorD, Dtor_Complete)); - Dtor = CGM.getFunctionPointer(Dtor, DtorTy); - } + if (const auto *Record = ThrowType->getAsCXXRecordDecl(); + Record && !Record->hasTrivialDestructor()) { + // __cxa_throw is declared to take its destructor as void (*)(void *). We + // must match that if function pointers can be authenticated with a + // discriminator based on their type. + const ASTContext &Ctx = getContext(); + QualType DtorTy = Ctx.getFunctionType(Ctx.VoidTy, {Ctx.VoidPtrTy}, + FunctionProtoType::ExtProtoInfo()); + + CXXDestructorDecl *DtorD = Record->getDestructor(); + Dtor = CGM.getAddrOfCXXStructor(GlobalDecl(DtorD, Dtor_Complete)); + Dtor = CGM.getFunctionPointer(Dtor, DtorTy); } if (!Dtor) Dtor = llvm::Constant::getNullValue(CGM.Int8PtrTy); @@ -1612,9 +1612,7 @@ llvm::Value *ItaniumCXXABI::EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy, Address ThisPtr, llvm::Type *StdTypeInfoPtrTy) { - auto *ClassDecl = - cast<CXXRecordDecl>(SrcRecordTy->castAs<RecordType>()->getOriginalDecl()) - ->getDefinitionOrSelf(); + auto *ClassDecl = SrcRecordTy->castAsCXXRecordDecl(); llvm::Value *Value = CGF.GetVTablePtr(ThisPtr, CGM.GlobalsInt8PtrTy, ClassDecl); @@ -1748,7 +1746,14 @@ llvm::Value *ItaniumCXXABI::emitExactDynamicCast( llvm::BasicBlock *CastFail) { const CXXRecordDecl *SrcDecl = SrcRecordTy->getAsCXXRecordDecl(); const CXXRecordDecl *DestDecl = DestRecordTy->getAsCXXRecordDecl(); + auto AuthenticateVTable = [&](Address ThisAddr, const CXXRecordDecl *Decl) { + if (!CGF.getLangOpts().PointerAuthCalls) + return; + (void)CGF.GetVTablePtr(ThisAddr, CGF.UnqualPtrTy, Decl, + CodeGenFunction::VTableAuthMode::MustTrap); + }; + bool PerformPostCastAuthentication = false; llvm::Value *VTable = nullptr; if (ExactCastInfo.RequiresCastToPrimaryBase) { // Base appears in at least two different places. Find the most-derived @@ -1759,8 +1764,16 @@ llvm::Value *ItaniumCXXABI::emitExactDynamicCast( emitDynamicCastToVoid(CGF, ThisAddr, SrcRecordTy); ThisAddr = Address(PrimaryBase, CGF.VoidPtrTy, ThisAddr.getAlignment()); SrcDecl = DestDecl; + // This unauthenticated load is unavoidable, so we're relying on the + // authenticated load in the dynamic cast to void, and we'll manually + // authenticate the resulting v-table at the end of the cast check. + PerformPostCastAuthentication = CGF.getLangOpts().PointerAuthCalls; + CGPointerAuthInfo StrippingAuthInfo(0, PointerAuthenticationMode::Strip, + false, false, nullptr); Address VTablePtrPtr = ThisAddr.withElementType(CGF.VoidPtrPtrTy); VTable = CGF.Builder.CreateLoad(VTablePtrPtr, "vtable"); + if (PerformPostCastAuthentication) + VTable = CGF.EmitPointerAuthAuth(StrippingAuthInfo, VTable); } else VTable = CGF.GetVTablePtr(ThisAddr, CGF.UnqualPtrTy, SrcDecl); @@ -1777,8 +1790,32 @@ llvm::Value *ItaniumCXXABI::emitExactDynamicCast( llvm::ConstantInt::get(CGF.PtrDiffTy, -Offset); AdjustedThisPtr = CGF.Builder.CreateInBoundsGEP(CGF.CharTy, AdjustedThisPtr, OffsetConstant); + PerformPostCastAuthentication = CGF.getLangOpts().PointerAuthCalls; } + if (PerformPostCastAuthentication) { + // If we've changed the object pointer we authenticate the vtable pointer + // of the resulting object. + llvm::BasicBlock *NonNullBlock = CGF.Builder.GetInsertBlock(); + llvm::BasicBlock *PostCastAuthSuccess = + CGF.createBasicBlock("dynamic_cast.postauth.success"); + llvm::BasicBlock *PostCastAuthComplete = + CGF.createBasicBlock("dynamic_cast.postauth.complete"); + CGF.Builder.CreateCondBr(Success, PostCastAuthSuccess, + PostCastAuthComplete); + CGF.EmitBlock(PostCastAuthSuccess); + Address AdjustedThisAddr = + Address(AdjustedThisPtr, CGF.IntPtrTy, CGF.getPointerAlign()); + AuthenticateVTable(AdjustedThisAddr, DestDecl); + CGF.EmitBranch(PostCastAuthComplete); + CGF.EmitBlock(PostCastAuthComplete); + llvm::PHINode *PHI = CGF.Builder.CreatePHI(AdjustedThisPtr->getType(), 2); + PHI->addIncoming(AdjustedThisPtr, PostCastAuthSuccess); + llvm::Value *NullValue = + llvm::Constant::getNullValue(AdjustedThisPtr->getType()); + PHI->addIncoming(NullValue, NonNullBlock); + AdjustedThisPtr = PHI; + } CGF.Builder.CreateCondBr(Success, CastSuccess, CastFail); return AdjustedThisPtr; } @@ -1786,9 +1823,7 @@ llvm::Value *ItaniumCXXABI::emitExactDynamicCast( llvm::Value *ItaniumCXXABI::emitDynamicCastToVoid(CodeGenFunction &CGF, Address ThisAddr, QualType SrcRecordTy) { - auto *ClassDecl = - cast<CXXRecordDecl>(SrcRecordTy->castAs<RecordType>()->getOriginalDecl()) - ->getDefinitionOrSelf(); + auto *ClassDecl = SrcRecordTy->castAsCXXRecordDecl(); llvm::Value *OffsetToTop; if (CGM.getItaniumVTableContext().isRelativeLayout()) { // Get the vtable pointer. @@ -3872,9 +3907,7 @@ static bool CanUseSingleInheritance(const CXXRecordDecl *RD) { return false; // Check that the class is dynamic iff the base is. - auto *BaseDecl = cast<CXXRecordDecl>( - Base->getType()->castAs<RecordType>()->getOriginalDecl()) - ->getDefinitionOrSelf(); + auto *BaseDecl = Base->getType()->castAsCXXRecordDecl(); if (!BaseDecl->isEmpty() && BaseDecl->isDynamicClass() != RD->isDynamicClass()) return false; @@ -4394,10 +4427,7 @@ static unsigned ComputeVMIClassTypeInfoFlags(const CXXBaseSpecifier *Base, unsigned Flags = 0; - auto *BaseDecl = cast<CXXRecordDecl>( - Base->getType()->castAs<RecordType>()->getOriginalDecl()) - ->getDefinitionOrSelf(); - + auto *BaseDecl = Base->getType()->castAsCXXRecordDecl(); if (Base->isVirtual()) { // Mark the virtual base as seen. if (!Bases.VirtualBases.insert(BaseDecl).second) { @@ -4495,11 +4525,7 @@ void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) { // The __base_type member points to the RTTI for the base type. Fields.push_back(ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(Base.getType())); - auto *BaseDecl = - cast<CXXRecordDecl>( - Base.getType()->castAs<RecordType>()->getOriginalDecl()) - ->getDefinitionOrSelf(); - + auto *BaseDecl = Base.getType()->castAsCXXRecordDecl(); int64_t OffsetFlags = 0; // All but the lower 8 bits of __offset_flags are a signed offset. |
