From 4da6acb783d62e0d65c3543e874fd8e883ed3370 Mon Sep 17 00:00:00 2001 From: Dmitry Mikulin Date: Wed, 16 Oct 2019 17:51:40 +0000 Subject: [PATCH] Tag CFI-generated data structures with "#pragma clang section" attributes. Differential Revision: https://reviews.llvm.org/D68808 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@375022 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGExpr.cpp | 3 +++ lib/CodeGen/CodeGenModule.cpp | 27 +++++++++++++++++++++----- lib/CodeGen/CodeGenModule.h | 5 +++++ lib/Sema/SemaDecl.cpp | 19 ++++++++++++++++++ test/CodeGen/cfi-pragma-section.c | 32 +++++++++++++++++++++++++++++++ 5 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 test/CodeGen/cfi-pragma-section.c diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 2bd1b0ba7e..570d160156 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -2821,6 +2821,7 @@ llvm::Constant *CodeGenFunction::EmitCheckTypeDescriptor(QualType T) { CGM.getModule(), Descriptor->getType(), /*isConstant=*/true, llvm::GlobalVariable::PrivateLinkage, Descriptor); GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); + CGM.setPragmaSectionAttributes(CurFuncDecl, GV); CGM.getSanitizerMetadata()->disableSanitizerForGlobal(GV); // Remember the descriptor for this type. @@ -2900,6 +2901,7 @@ llvm::Constant *CodeGenFunction::EmitCheckSourceLocation(SourceLocation Loc) { } auto FilenameGV = CGM.GetAddrOfConstantCString(FilenameString, ".src"); + CGM.setPragmaSectionAttributes(CurFuncDecl, cast(FilenameGV.getPointer())); CGM.getSanitizerMetadata()->disableSanitizerForGlobal( cast(FilenameGV.getPointer())); Filename = FilenameGV.getPointer(); @@ -3073,6 +3075,7 @@ void CodeGenFunction::EmitCheck( new llvm::GlobalVariable(CGM.getModule(), Info->getType(), false, llvm::GlobalVariable::PrivateLinkage, Info); InfoPtr->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); + CGM.setPragmaSectionAttributes(CurFuncDecl, InfoPtr); CGM.getSanitizerMetadata()->disableSanitizerForGlobal(InfoPtr); Args.push_back(Builder.CreateBitCast(InfoPtr, Int8PtrTy)); ArgTypes.push_back(Int8PtrTy); diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 8eb2176ca3..a4859e7fbb 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -1699,11 +1699,8 @@ bool CodeGenModule::GetCPUAndFeaturesAttributes(GlobalDecl GD, return AddedAttr; } -void CodeGenModule::setNonAliasAttributes(GlobalDecl GD, - llvm::GlobalObject *GO) { - const Decl *D = GD.getDecl(); - SetCommonAttributes(GD, GO); - +void CodeGenModule::setPragmaSectionAttributes(const Decl *D, + llvm::GlobalObject *GO) { if (D) { if (auto *GV = dyn_cast(GO)) { if (auto *SA = D->getAttr()) @@ -1721,6 +1718,26 @@ void CodeGenModule::setNonAliasAttributes(GlobalDecl GD, if (!D->getAttr()) F->addFnAttr("implicit-section-name", SA->getName()); + if (auto *SA = D->getAttr()) + F->addFnAttr("bss-section", SA->getName()); + if (auto *SA = D->getAttr()) + F->addFnAttr("data-section", SA->getName()); + if (auto *SA = D->getAttr()) + F->addFnAttr("rodata-section", SA->getName()); + if (auto *SA = D->getAttr()) + F->addFnAttr("relro-section", SA->getName()); + } + } +} + +void CodeGenModule::setNonAliasAttributes(GlobalDecl GD, + llvm::GlobalObject *GO) { + const Decl *D = GD.getDecl(); + SetCommonAttributes(GD, GO); + setPragmaSectionAttributes(D, GO); + + if (D) { + if (auto *F = dyn_cast(GO)) { llvm::AttrBuilder Attrs; if (GetCPUAndFeaturesAttributes(GD, Attrs)) { // We know that GetCPUAndFeaturesAttributes will always have the diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 597b8d712c..a6662da5f5 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -1347,6 +1347,11 @@ public: /// \param QT is the clang QualType of the null pointer. llvm::Constant *getNullPointer(llvm::PointerType *T, QualType QT); + /// Set section attributes requested by "#pragma clang section" + /// \param D is the declaration to read semantic attributes from. + /// \param GO is the global object to set section attributes. + void setPragmaSectionAttributes(const Decl *D, llvm::GlobalObject *GO); + private: llvm::Constant *GetOrCreateLLVMFunction( StringRef MangledName, llvm::Type *Ty, GlobalDecl D, bool ForVTable, diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 62ec83967b..658cff0212 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -9062,6 +9062,25 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, Context, PragmaClangTextSection.SectionName, PragmaClangTextSection.PragmaLocation, AttributeCommonInfo::AS_Pragma)); + if (D.isFunctionDefinition()) { + if (PragmaClangBSSSection.Valid) + NewFD->addAttr(PragmaClangBSSSectionAttr::CreateImplicit( + Context, PragmaClangBSSSection.SectionName, + PragmaClangBSSSection.PragmaLocation)); + if (PragmaClangDataSection.Valid) + NewFD->addAttr(PragmaClangDataSectionAttr::CreateImplicit( + Context, PragmaClangDataSection.SectionName, + PragmaClangDataSection.PragmaLocation)); + if (PragmaClangRodataSection.Valid) + NewFD->addAttr(PragmaClangRodataSectionAttr::CreateImplicit( + Context, PragmaClangRodataSection.SectionName, + PragmaClangRodataSection.PragmaLocation)); + if (PragmaClangRelroSection.Valid) + NewFD->addAttr(PragmaClangRelroSectionAttr::CreateImplicit( + Context, PragmaClangRelroSection.SectionName, + PragmaClangRelroSection.PragmaLocation)); + } + // Apply an implicit SectionAttr if #pragma code_seg is active. if (CodeSegStack.CurrentValue && D.isFunctionDefinition() && !NewFD->hasAttr()) { diff --git a/test/CodeGen/cfi-pragma-section.c b/test/CodeGen/cfi-pragma-section.c new file mode 100644 index 0000000000..c2aae39cd9 --- /dev/null +++ b/test/CodeGen/cfi-pragma-section.c @@ -0,0 +1,32 @@ +// Check that CFI-generated data structures are tagged with +// "#pragma clang section" attributes + +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-icall \ +// RUN: -fno-sanitize-trap=cfi-icall -emit-llvm -o - %s | FileCheck %s + +// CHECK-DAG: attributes [[ATTR:#[0-9]+]]{{.*}}bss-section{{.*}}data-section{{.*}}rodata-section +// CHECK-DAG: @.src = private unnamed_addr constant{{.*}}cfi-pragma-section.c{{.*}}[[ATTR]] +// CHECK-DAG: @{{[0-9]+}} = private unnamed_addr constant{{.*}}int (int){{.*}}[[ATTR]] +// CHECK-DAG: @{{[0-9]+}} = private unnamed_addr global{{.*}}@.src{{.*}}[[ATTR]] + +typedef int (*int_arg_fn)(int); + +static int int_arg1(int arg) { + return 0; +} + +static int int_arg2(int arg) { + return 1; +} + +int_arg_fn int_funcs[2] = {int_arg1, int_arg2}; + +#pragma clang section bss = ".bss.mycfi" +#pragma clang section data = ".data.mycfi" +#pragma clang section rodata = ".rodata.mycfi" + +int main(int argc, const char *argv[]) { + + int idx = argv[1][0] - '0'; + return int_funcs[argc](idx); +} -- 2.40.0