]> granicus.if.org Git - clang/commitdiff
Tag CFI-generated data structures with "#pragma clang section" attributes.
authorDmitry Mikulin <dmitry.mikulin@sony.com>
Wed, 16 Oct 2019 17:51:40 +0000 (17:51 +0000)
committerDmitry Mikulin <dmitry.mikulin@sony.com>
Wed, 16 Oct 2019 17:51:40 +0000 (17:51 +0000)
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
lib/CodeGen/CodeGenModule.cpp
lib/CodeGen/CodeGenModule.h
lib/Sema/SemaDecl.cpp
test/CodeGen/cfi-pragma-section.c [new file with mode: 0644]

index 2bd1b0ba7e3062df76895d26163e60038386c8b8..570d1601566f52bf19c951eadd0e39a3c9b7677f 100644 (file)
@@ -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<llvm::GlobalVariable>(FilenameGV.getPointer()));
     CGM.getSanitizerMetadata()->disableSanitizerForGlobal(
                           cast<llvm::GlobalVariable>(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);
index 8eb2176ca3a8ebe2463a24eaa0f1b07b98772f35..a4859e7fbbf4a1dd22707f580c945a9c27e6d176 100644 (file)
@@ -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<llvm::GlobalVariable>(GO)) {
       if (auto *SA = D->getAttr<PragmaClangBSSSectionAttr>())
@@ -1721,6 +1718,26 @@ void CodeGenModule::setNonAliasAttributes(GlobalDecl GD,
         if (!D->getAttr<SectionAttr>())
           F->addFnAttr("implicit-section-name", SA->getName());
 
+      if (auto *SA = D->getAttr<PragmaClangBSSSectionAttr>())
+        F->addFnAttr("bss-section", SA->getName());
+      if (auto *SA = D->getAttr<PragmaClangDataSectionAttr>())
+        F->addFnAttr("data-section", SA->getName());
+      if (auto *SA = D->getAttr<PragmaClangRodataSectionAttr>())
+        F->addFnAttr("rodata-section", SA->getName());
+      if (auto *SA = D->getAttr<PragmaClangRelroSectionAttr>())
+        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<llvm::Function>(GO)) {
       llvm::AttrBuilder Attrs;
       if (GetCPUAndFeaturesAttributes(GD, Attrs)) {
         // We know that GetCPUAndFeaturesAttributes will always have the
index 597b8d712caa1fa17684e60ea003f31f38717315..a6662da5f55bfdfb7d56f8efa8ae8ceac58c6d07 100644 (file)
@@ -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,
index 62ec83967bff040d13bdc2b72651839ea6ecea40..658cff0212fe0972c5d219a7e52f6e36922742f9 100644 (file)
@@ -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<SectionAttr>()) {
diff --git a/test/CodeGen/cfi-pragma-section.c b/test/CodeGen/cfi-pragma-section.c
new file mode 100644 (file)
index 0000000..c2aae39
--- /dev/null
@@ -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);
+}