diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CodeGen/BackendUtil.cpp | 1 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGCall.cpp | 22 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGClass.cpp | 9 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 5 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExprCXX.cpp | 34 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGObjCMac.cpp | 8 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 34 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 4 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains/Clang.cpp | 4 |
9 files changed, 110 insertions, 11 deletions
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index c8b2a93..cba4064 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -420,6 +420,7 @@ static bool initTargetOptions(DiagnosticsEngine &Diags, Options.StackUsageOutput = CodeGenOpts.StackUsageOutput; Options.EmitAddrsig = CodeGenOpts.Addrsig; Options.ForceDwarfFrameSection = CodeGenOpts.ForceDwarfFrameSection; + Options.EmitCallGraphSection = CodeGenOpts.CallGraphSection; Options.EmitCallSiteInfo = CodeGenOpts.EmitCallSiteInfo; Options.EnableAIXExtendedAltivecABI = LangOpts.EnableAIXExtendedAltivecABI; Options.XRayFunctionIndex = CodeGenOpts.XRayFunctionIndex; diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index f12765b..51133b0 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -5681,6 +5681,28 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, AllocAlignAttrEmitter AllocAlignAttrEmitter(*this, TargetDecl, CallArgs); Attrs = AllocAlignAttrEmitter.TryEmitAsCallSiteAttribute(Attrs); + if (CGM.getCodeGenOpts().CallGraphSection) { + // FIXME: create operand bundle only for indirect calls, not for all + + assert((TargetDecl && TargetDecl->getFunctionType() || + Callee.getAbstractInfo().getCalleeFunctionProtoType()) && + "cannot find callsite type"); + + QualType CST; + if (TargetDecl && TargetDecl->getFunctionType()) + CST = QualType(TargetDecl->getFunctionType(), 0); + else if (const auto *FPT = + Callee.getAbstractInfo().getCalleeFunctionProtoType()) + CST = QualType(FPT, 0); + + if (!CST.isNull()) { + auto *TypeIdMD = CGM.CreateMetadataIdentifierGeneralized(CST); + auto *TypeIdMDVal = + llvm::MetadataAsValue::get(getLLVMContext(), TypeIdMD); + BundleList.emplace_back("type", TypeIdMDVal); + } + } + // Emit the actual call/invoke instruction. llvm::CallBase *CI; if (!InvokeDest) { diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index 8c1c8ee..2c347bd 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -2247,7 +2247,14 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, const CGFunctionInfo &Info = CGM.getTypes().arrangeCXXConstructorCall( Args, D, Type, ExtraArgs.Prefix, ExtraArgs.Suffix, PassPrototypeArgs); CGCallee Callee = CGCallee::forDirect(CalleePtr, GlobalDecl(D, Type)); - EmitCall(Info, Callee, ReturnValueSlot(), Args, nullptr, false, Loc); + llvm::CallBase *CallOrInvoke = nullptr; + EmitCall(Info, Callee, ReturnValueSlot(), Args, &CallOrInvoke, false, Loc); + + // Set type identifier metadata of indirect calls for call graph section. + if (CGM.getCodeGenOpts().CallGraphSection && CallOrInvoke && + CallOrInvoke->isIndirectCall()) + CGM.CreateFunctionTypeMetadataForIcall(D->getType(), CallOrInvoke); + // Generate vtable assumptions if we're constructing a complete object // with a vtable. We don't do this for base subobjects for two reasons: diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 5443235..467a7cf 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -5953,6 +5953,11 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, const CGCallee &OrigCallee } } + // Set type identifier metadata of indirect calls for call graph section. + if (CGM.getCodeGenOpts().CallGraphSection && CallOrInvoke && + CallOrInvoke->isIndirectCall()) + CGM.CreateFunctionTypeMetadataForIcall(QualType(FnType, 0), CallOrInvoke); + return Call; } diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp index a4fb673..4cbffd7 100644 --- a/clang/lib/CodeGen/CGExprCXX.cpp +++ b/clang/lib/CodeGen/CGExprCXX.cpp @@ -93,9 +93,17 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorCall( *this, MD, This, ImplicitParam, ImplicitParamTy, CE, Args, RtlArgs); auto &FnInfo = CGM.getTypes().arrangeCXXMethodCall( Args, FPT, CallInfo.ReqArgs, CallInfo.PrefixSize); - return EmitCall(FnInfo, Callee, ReturnValue, Args, nullptr, + llvm::CallBase *CallOrInvoke = nullptr; + auto Call = EmitCall(FnInfo, Callee, ReturnValue, Args, &CallOrInvoke, CE && CE == MustTailCall, CE ? CE->getExprLoc() : SourceLocation()); + + // Set type identifier metadata of indirect calls for call graph section. + if (CGM.getCodeGenOpts().CallGraphSection && CallOrInvoke && + CallOrInvoke->isIndirectCall()) + CGM.CreateFunctionTypeMetadataForIcall(MD->getType(), CallOrInvoke); + + return Call; } RValue CodeGenFunction::EmitCXXDestructorCall( @@ -119,9 +127,17 @@ RValue CodeGenFunction::EmitCXXDestructorCall( CallArgList Args; commonEmitCXXMemberOrOperatorCall(*this, Dtor, This, ImplicitParam, ImplicitParamTy, CE, Args, nullptr); - return EmitCall(CGM.getTypes().arrangeCXXStructorDeclaration(Dtor), Callee, - ReturnValueSlot(), Args, nullptr, CE && CE == MustTailCall, + llvm::CallBase *CallOrInvoke = nullptr; + auto Call = EmitCall(CGM.getTypes().arrangeCXXStructorDeclaration(Dtor), Callee, + ReturnValueSlot(), Args, &CallOrInvoke, CE && CE == MustTailCall, CE ? CE->getExprLoc() : SourceLocation{}); + + // Set type identifier metadata of indirect calls for call graph section. + if (CGM.getCodeGenOpts().CallGraphSection && CallOrInvoke && + CallOrInvoke->isIndirectCall()) + CGM.CreateFunctionTypeMetadataForIcall(DtorDecl->getType(), CallOrInvoke); + + return Call; } RValue CodeGenFunction::EmitCXXPseudoDestructorExpr( @@ -482,10 +498,18 @@ CodeGenFunction::EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E, // And the rest of the call args EmitCallArgs(Args, FPT, E->arguments()); - return EmitCall(CGM.getTypes().arrangeCXXMethodCall(Args, FPT, required, + llvm::CallBase *CallOrInvoke = nullptr; + auto Call = EmitCall(CGM.getTypes().arrangeCXXMethodCall(Args, FPT, required, /*PrefixSize=*/0), - Callee, ReturnValue, Args, nullptr, E == MustTailCall, + Callee, ReturnValue, Args, &CallOrInvoke, E == MustTailCall, E->getExprLoc()); + + // Set type identifier metadata of indirect calls for call graph section. + if (CGM.getCodeGenOpts().CallGraphSection && CallOrInvoke && + CallOrInvoke->isIndirectCall()) + CGM.CreateFunctionTypeMetadataForIcall(QualType(FPT, 0), CallOrInvoke); + + return Call; } RValue diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 8a599c1..291f5af 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -2220,6 +2220,14 @@ CGObjCCommonMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF, RValue rvalue = CGF.EmitCall(MSI.CallInfo, Callee, Return, ActualArgs, &CallSite); + // Set type identifier metadata of indirect calls for call graph section. + if (CGM.getCodeGenOpts().CallGraphSection && Method && CallSite && + CallSite->isIndirectCall()) { + if (const auto *FnType = Method->getFunctionType()) { + CGM.CreateFunctionTypeMetadataForIcall(QualType(FnType, 0), CallSite); + } + } + // Mark the call as noreturn if the method is marked noreturn and the // receiver cannot be null. if (Method && Method->hasAttr<NoReturnAttr>() && !ReceiverCanBeNull) { diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 00b3bfc..e19bbee 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -2486,8 +2486,8 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, // In the cross-dso CFI mode with canonical jump tables, we want !type // attributes on definitions only. - if (CodeGenOpts.SanitizeCfiCrossDso && - CodeGenOpts.SanitizeCfiCanonicalJumpTables) { + if ((CodeGenOpts.SanitizeCfiCrossDso && + CodeGenOpts.SanitizeCfiCanonicalJumpTables) || CodeGenOpts.CallGraphSection) { if (auto *FD = dyn_cast<FunctionDecl>(D)) { // Skip available_externally functions. They won't be codegen'ed in the // current module anyway. @@ -2677,7 +2677,17 @@ static void setLinkageForGV(llvm::GlobalValue *GV, const NamedDecl *ND) { void CodeGenModule::CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD, llvm::Function *F) { - // Only if we are checking indirect calls. + bool EmittedMDIdGeneralized = false; + if (CodeGenOpts.CallGraphSection && + (!F->hasLocalLinkage() || + F->getFunction().hasAddressTaken(nullptr, /* IgnoreCallbackUses */ true, + /* IgnoreAssumeLikeCalls */ true, + /* IgnoreLLVMUsed */ false))) { + F->addTypeMetadata(0, CreateMetadataIdentifierGeneralized(FD->getType())); + EmittedMDIdGeneralized = true; + } + + // Add additional metadata only if we are checking indirect calls with CFI. if (!LangOpts.Sanitize.has(SanitizerKind::CFIICall)) return; @@ -2688,7 +2698,9 @@ void CodeGenModule::CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD, llvm::Metadata *MD = CreateMetadataIdentifierForType(FD->getType()); F->addTypeMetadata(0, MD); - F->addTypeMetadata(0, CreateMetadataIdentifierGeneralized(FD->getType())); + // Add the generalized identifier if not added already. + if (!EmittedMDIdGeneralized) + F->addTypeMetadata(0, CreateMetadataIdentifierGeneralized(FD->getType())); // Emit a hash-based bit set entry for cross-DSO calls. if (CodeGenOpts.SanitizeCfiCrossDso) @@ -2696,6 +2708,17 @@ void CodeGenModule::CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD, F->addTypeMetadata(0, llvm::ConstantAsMetadata::get(CrossDsoTypeId)); } +void CodeGenModule::CreateFunctionTypeMetadataForIcall(const QualType &QT, + llvm::CallBase *CB) { + // Only if needed for call graph section and only for indirect calls. + if (!(CodeGenOpts.CallGraphSection && CB && CB->isIndirectCall())) + return; + + auto *MD = CreateMetadataIdentifierGeneralized(QT); + auto *MDN = llvm::MDNode::get(getLLVMContext(), MD); + CB->setMetadata(llvm::LLVMContext::MD_type, MDN); +} + void CodeGenModule::setKCFIType(const FunctionDecl *FD, llvm::Function *F) { llvm::LLVMContext &Ctx = F->getContext(); llvm::MDBuilder MDB(Ctx); @@ -2823,7 +2846,8 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F, // are non-canonical then we need type metadata in order to produce the local // jump table. if (!CodeGenOpts.SanitizeCfiCrossDso || - !CodeGenOpts.SanitizeCfiCanonicalJumpTables) + !CodeGenOpts.SanitizeCfiCanonicalJumpTables || + CodeGenOpts.CallGraphSection) CreateFunctionTypeMetadataForIcall(FD, F); if (LangOpts.Sanitize.has(SanitizerKind::KCFI)) diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 1cc4477..12ac8d0 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -1473,6 +1473,10 @@ public: void CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD, llvm::Function *F); + /// Create and attach type metadata to the given call. + void CreateFunctionTypeMetadataForIcall(const QualType &QT, + llvm::CallBase *CB); + /// Set type metadata to the given function. void setKCFIType(const FunctionDecl *FD, llvm::Function *F); diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index b7ec7e0..7cc2d9a 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -6407,6 +6407,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(A->getValue()); } + if (Args.hasFlag(options::OPT_fcall_graph_section, + options::OPT_fno_call_graph_section, false)) + CmdArgs.push_back("-fcall-graph-section"); + Args.addOptInFlag(CmdArgs, options::OPT_fstack_size_section, options::OPT_fno_stack_size_section); |