This revision was automatically updated to reflect the committed changes.
Closed by commit rGf14642f2f185: Added support for "#pragma clang section 
relro=<name>" (authored by dmikulin).
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68806/new/

https://reviews.llvm.org/D68806

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGDecl.cpp
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/Parse/ParsePragma.cpp
  clang/lib/Sema/SemaAttr.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/test/CodeGenCXX/clang-sections.cpp
  clang/test/Sema/pragma-clang-section.c
  llvm/include/llvm/IR/GlobalVariable.h
  llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
  llvm/lib/Target/TargetLoweringObjectFile.cpp
  llvm/test/MC/ELF/section-relro.ll

Index: llvm/test/MC/ELF/section-relro.ll
===================================================================
--- /dev/null
+++ llvm/test/MC/ELF/section-relro.ll
@@ -0,0 +1,65 @@
+; Tests that data and relro are correctly placed in sections
+; specified by "#pragma clang section"
+; RUN: llc -filetype=obj -mtriple x86_64-unknown-linux %s -o - | llvm-readobj -S -t | FileCheck %s
+
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux"
+
+@funcs_relro = hidden constant [2 x i32 ()*] [i32 ()* bitcast (i32 (...)* @func1 to i32 ()*), i32 ()* bitcast (i32 (...)* @func2 to i32 ()*)], align 16 #0
+@var_data = hidden global i32 33, align 4 #0
+
+declare i32 @func1(...)
+declare i32 @func2(...)
+
+; Function Attrs: noinline nounwind optnone sspstrong uwtable
+define hidden i32 @foo(i32 %i) {
+entry:
+  %i.addr = alloca i32, align 4
+  store i32 %i, i32* %i.addr, align 4
+  %0 = load i32, i32* %i.addr, align 4
+  %idxprom = sext i32 %0 to i64
+  %arrayidx = getelementptr inbounds [2 x i32 ()*], [2 x i32 ()*]* @funcs_relro, i64 0, i64 %idxprom
+  %1 = load i32 ()*, i32 ()** %arrayidx, align 8
+  %call = call i32 %1()
+  %2 = load i32, i32* @var_data, align 4
+  %add = add nsw i32 %call, %2
+  ret i32 %add
+}
+
+attributes #0 = { "data-section"=".my_data" "relro-section"=".my_relro" "rodata-section"=".my_rodata" }
+
+; CHECK:  Section {
+; CHECK:    Index:
+; CHECK:    Name: .my_rodata
+; CHECK:    Type: SHT_PROGBITS (0x1)
+; CHECK:    Flags [ (0x2)
+; CHECK:      SHF_ALLOC (0x2)
+; CHECK:    ]
+; CHECK:    Size: 16
+; CHECK:  }
+; CHECK:  Section {
+; CHECK:    Index:
+; CHECK:    Name: .my_data
+; CHECK:    Type: SHT_PROGBITS (0x1)
+; CHECK:    Flags [ (0x3)
+; CHECK:      SHF_ALLOC (0x2)
+; CHECK:      SHF_WRITE (0x1)
+; CHECK:    ]
+; CHECK:    Size: 4
+; CHECK:  }
+; CHECK:   Symbol {
+; CHECK:    Name: funcs_relro
+; CHECK:    Value: 0x0
+; CHECK:    Size: 16
+; CHECK:    Binding: Global (0x1)
+; CHECK:    Type: Object (0x1)
+; CHECK:    Section: .my_rodata
+; CHECK:  }
+; CHECK:  Symbol {
+; CHECK:    Name: var_data
+; CHECK:    Value: 0x0
+; CHECK:    Size: 4
+; CHECK:    Binding: Global (0x1)
+; CHECK:    Type: Object (0x1)
+; CHECK:    Section: .my_data
+; CHECK:  }
Index: llvm/lib/Target/TargetLoweringObjectFile.cpp
===================================================================
--- llvm/lib/Target/TargetLoweringObjectFile.cpp
+++ llvm/lib/Target/TargetLoweringObjectFile.cpp
@@ -253,6 +253,7 @@
     auto Attrs = GVar->getAttributes();
     if ((Attrs.hasAttribute("bss-section") && Kind.isBSS()) ||
         (Attrs.hasAttribute("data-section") && Kind.isData()) ||
+        (Attrs.hasAttribute("relro-section") && Kind.isReadOnlyWithRel()) ||
         (Attrs.hasAttribute("rodata-section") && Kind.isReadOnly()))  {
        return getExplicitSectionGlobal(GO, Kind, TM);
     }
Index: llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
===================================================================
--- llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -568,6 +568,8 @@
       SectionName = Attrs.getAttribute("bss-section").getValueAsString();
     } else if (Attrs.hasAttribute("rodata-section") && Kind.isReadOnly()) {
       SectionName = Attrs.getAttribute("rodata-section").getValueAsString();
+    } else if (Attrs.hasAttribute("relro-section") && Kind.isReadOnlyWithRel()) {
+      SectionName = Attrs.getAttribute("relro-section").getValueAsString();
     } else if (Attrs.hasAttribute("data-section") && Kind.isData()) {
       SectionName = Attrs.getAttribute("data-section").getValueAsString();
     }
Index: llvm/include/llvm/IR/GlobalVariable.h
===================================================================
--- llvm/include/llvm/IR/GlobalVariable.h
+++ llvm/include/llvm/IR/GlobalVariable.h
@@ -243,6 +243,7 @@
   bool hasImplicitSection() const {
     return getAttributes().hasAttribute("bss-section") ||
            getAttributes().hasAttribute("data-section") ||
+           getAttributes().hasAttribute("relro-section") ||
            getAttributes().hasAttribute("rodata-section");
   }
 
Index: clang/test/Sema/pragma-clang-section.c
===================================================================
--- clang/test/Sema/pragma-clang-section.c
+++ clang/test/Sema/pragma-clang-section.c
@@ -3,15 +3,17 @@
 #pragma clang section bss="" data="" rodata="" text=""
 #pragma clang section
 
-#pragma clang section dss="mybss.2" // expected-error {{expected one of [bss|data|rodata|text] section kind in '#pragma clang section'}}
-#pragma clang section deta="mydata.2" // expected-error {{expected one of [bss|data|rodata|text] section kind in '#pragma clang section'}}
-#pragma clang section rodeta="rodata.2" // expected-error {{expected one of [bss|data|rodata|text] section kind in '#pragma clang section'}}
-#pragma clang section taxt="text.2" // expected-error {{expected one of [bss|data|rodata|text] section kind in '#pragma clang section'}}
+#pragma clang section dss="mybss.2" // expected-error {{expected one of [bss|data|rodata|text|relro] section kind in '#pragma clang section'}}
+#pragma clang section deta="mydata.2" // expected-error {{expected one of [bss|data|rodata|text|relro] section kind in '#pragma clang section'}}
+#pragma clang section rodeta="rodata.2" // expected-error {{expected one of [bss|data|rodata|text|relro] section kind in '#pragma clang section'}}
+#pragma clang section taxt="text.2" // expected-error {{expected one of [bss|data|rodata|text|relro] section kind in '#pragma clang section'}}
 
-#pragma clang section section bss="mybss.2"  // expected-error {{expected one of [bss|data|rodata|text] section kind in '#pragma clang section'}}
+#pragma clang section section bss="mybss.2"  // expected-error {{expected one of [bss|data|rodata|text|relro] section kind in '#pragma clang section'}}
 
 #pragma clang section bss "mybss.2"   // expected-error {{expected '=' following '#pragma clang section bss'}}
 #pragma clang section data "mydata.2"   // expected-error {{expected '=' following '#pragma clang section data'}}
 #pragma clang section rodata "myrodata.2"   // expected-error {{expected '=' following '#pragma clang section rodata'}}
-#pragma clang section bss="" data="" rodata="" text="" more //expected-error {{expected one of [bss|data|rodata|text] section kind in '#pragma clang section'}}
+#pragma clang section text "text.2"   // expected-error {{expected '=' following '#pragma clang section text'}}
+#pragma clang section relro "relro.2"   // expected-error {{expected '=' following '#pragma clang section relro'}}
+#pragma clang section bss="" data="" rodata="" text="" more //expected-error {{expected one of [bss|data|rodata|text|relro] section kind in '#pragma clang section'}}
 int a;
Index: clang/test/CodeGenCXX/clang-sections.cpp
===================================================================
--- clang/test/CodeGenCXX/clang-sections.cpp
+++ clang/test/CodeGenCXX/clang-sections.cpp
@@ -29,17 +29,20 @@
   static int lstat_h;  // my_bss.2
   return zoo(g, &lstat_h);
 }
-#pragma clang section rodata="my_rodata.2" data="my_data.2"
+#pragma clang section rodata="my_rodata.2" data="my_data.2" relro="my_relro.2"
 int l = 5; // my_data.2
 extern const int m;
 const int m = 6; // my_rodata.2
+
+typedef int (*fptr_t)(void);
+const fptr_t fptrs[2] = {&foo, &goo};
 #pragma clang section rodata="" data="" bss="" text=""
 int n; // default
 int o = 6; // default
 extern const int p;
 const int p = 7; // default
 int hoo(void) {
-  return b;
+  return b + fptrs[f]();
 }
 }
 //CHECK: @a = global i32 0, align 4 #0
@@ -62,17 +65,19 @@
 //CHECK: @n = global i32 0, align 4
 //CHECK: @o = global i32 6, align 4
 //CHECK: @p = constant i32 7, align 4
+//CHECK: @_ZL5fptrs = internal constant [2 x i32 ()*] [i32 ()* @foo, i32 ()* @goo], align 4 #3
 
-//CHECK: define i32 @foo() #4 {
-//CHECK: define i32 @goo() #5 {
-//CHECK: declare i32 @zoo(i32*, i32*) #6
-//CHECK: define i32 @hoo() #7 {
+//CHECK: define i32 @foo() #5 {
+//CHECK: define i32 @goo() #6 {
+//CHECK: declare i32 @zoo(i32*, i32*) #7
+//CHECK: define i32 @hoo() #8 {
 
 //CHECK: attributes #0 = { "bss-section"="my_bss.1" "data-section"="my_data.1" "rodata-section"="my_rodata.1" }
 //CHECK: attributes #1 = { "data-section"="my_data.1" "rodata-section"="my_rodata.1" }
 //CHECK: attributes #2 = { "bss-section"="my_bss.2" "rodata-section"="my_rodata.1" }
-//CHECK: attributes #3 = { "bss-section"="my_bss.2" "data-section"="my_data.2" "rodata-section"="my_rodata.2" }
-//CHECK: attributes #4 = { {{.*"implicit-section-name"="my_text.1".*}} }
-//CHECK: attributes #5 = { {{.*"implicit-section-name"="my_text.2".*}} }
-//CHECK-NOT: attributes #6 = { {{.*"implicit-section-name".*}} }
+//CHECK: attributes #3 = { "bss-section"="my_bss.2" "data-section"="my_data.2" "relro-section"="my_relro.2" "rodata-section"="my_rodata.2" }
+//CHECK: attributes #4 = { "relro-section"="my_relro.2" }
+//CHECK: attributes #5 = { {{.*"implicit-section-name"="my_text.1".*}} }
+//CHECK: attributes #6 = { {{.*"implicit-section-name"="my_text.2".*}} }
 //CHECK-NOT: attributes #7 = { {{.*"implicit-section-name".*}} }
+//CHECK-NOT: attributes #8 = { {{.*"implicit-section-name".*}} }
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -12657,6 +12657,11 @@
           Context, PragmaClangRodataSection.SectionName,
           PragmaClangRodataSection.PragmaLocation,
           AttributeCommonInfo::AS_Pragma));
+    if (PragmaClangRelroSection.Valid)
+      VD->addAttr(PragmaClangRelroSectionAttr::CreateImplicit(
+          Context, PragmaClangRelroSection.SectionName,
+          PragmaClangRelroSection.PragmaLocation,
+          AttributeCommonInfo::AS_Pragma));
   }
 
   if (auto *DD = dyn_cast<DecompositionDecl>(ThisDecl)) {
Index: clang/lib/Sema/SemaAttr.cpp
===================================================================
--- clang/lib/Sema/SemaAttr.cpp
+++ clang/lib/Sema/SemaAttr.cpp
@@ -266,6 +266,9 @@
     case PragmaClangSectionKind::PCSK_Rodata:
       CSec = &PragmaClangRodataSection;
       break;
+    case PragmaClangSectionKind::PCSK_Relro:
+      CSec = &PragmaClangRelroSection;
+      break;
     case PragmaClangSectionKind::PCSK_Text:
       CSec = &PragmaClangTextSection;
       break;
Index: clang/lib/Parse/ParsePragma.cpp
===================================================================
--- clang/lib/Parse/ParsePragma.cpp
+++ clang/lib/Parse/ParsePragma.cpp
@@ -1790,7 +1790,7 @@
                       /*IsReinject=*/false);
 }
 
-// #pragma clang section bss="abc" data="" rodata="def" text=""
+// #pragma clang section bss="abc" data="" rodata="def" text="" relro=""
 void PragmaClangSectionHandler::HandlePragma(Preprocessor &PP,
                                              PragmaIntroducer Introducer,
                                              Token &FirstToken) {
@@ -1812,6 +1812,8 @@
       SecKind = Sema::PragmaClangSectionKind::PCSK_Data;
     else if (SecType->isStr("rodata"))
       SecKind = Sema::PragmaClangSectionKind::PCSK_Rodata;
+    else if (SecType->isStr("relro"))
+      SecKind = Sema::PragmaClangSectionKind::PCSK_Relro;
     else if (SecType->isStr("text"))
       SecKind = Sema::PragmaClangSectionKind::PCSK_Text;
     else {
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -1717,6 +1717,8 @@
         GV->addAttribute("data-section", SA->getName());
       if (auto *SA = D->getAttr<PragmaClangRodataSectionAttr>())
         GV->addAttribute("rodata-section", SA->getName());
+      if (auto *SA = D->getAttr<PragmaClangRelroSectionAttr>())
+        GV->addAttribute("relro-section", SA->getName());
     }
 
     if (auto *F = dyn_cast<llvm::Function>(GO)) {
@@ -4118,6 +4120,7 @@
   // If no specialized section name is applicable, it will resort to default.
   if (D->hasAttr<PragmaClangBSSSectionAttr>() ||
       D->hasAttr<PragmaClangDataSectionAttr>() ||
+      D->hasAttr<PragmaClangRelroSectionAttr>() ||
       D->hasAttr<PragmaClangRodataSectionAttr>())
     return true;
 
Index: clang/lib/CodeGen/CGDecl.cpp
===================================================================
--- clang/lib/CodeGen/CGDecl.cpp
+++ clang/lib/CodeGen/CGDecl.cpp
@@ -419,6 +419,8 @@
     var->addAttribute("data-section", SA->getName());
   if (auto *SA = D.getAttr<PragmaClangRodataSectionAttr>())
     var->addAttribute("rodata-section", SA->getName());
+  if (auto *SA = D.getAttr<PragmaClangRelroSectionAttr>())
+    var->addAttribute("relro-section", SA->getName());
 
   if (const SectionAttr *SA = D.getAttr<SectionAttr>())
     var->setSection(SA->getName());
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -418,7 +418,8 @@
     PCSK_BSS          = 1,
     PCSK_Data         = 2,
     PCSK_Rodata       = 3,
-    PCSK_Text         = 4
+    PCSK_Text         = 4,
+    PCSK_Relro        = 5
    };
 
   enum PragmaClangSectionAction {
@@ -439,6 +440,7 @@
    PragmaClangSection PragmaClangBSSSection;
    PragmaClangSection PragmaClangDataSection;
    PragmaClangSection PragmaClangRodataSection;
+   PragmaClangSection PragmaClangRelroSection;
    PragmaClangSection PragmaClangTextSection;
 
   enum PragmaMsStackAction {
Index: clang/include/clang/Basic/DiagnosticParseKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticParseKinds.td
+++ clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -976,9 +976,9 @@
 
 // '#pragma clang section' related errors
 def err_pragma_expected_clang_section_name : Error<
-  "expected one of [bss|data|rodata|text] section kind in '#pragma %0'">;
+  "expected one of [bss|data|rodata|text|relro] section kind in '#pragma %0'">;
 def err_pragma_clang_section_expected_equal : Error<
-  "expected '=' following '#pragma clang section %select{invalid|bss|data|rodata|text}0'">;
+  "expected '=' following '#pragma clang section %select{invalid|bss|data|rodata|text|relro}0'">;
 def warn_pragma_expected_section_name : Warning<
   "expected a string literal for the section name in '#pragma %0' - ignored">,
   InGroup<IgnoredPragmas>;
Index: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -2020,6 +2020,14 @@
   let Documentation = [Undocumented];
 }
 
+def PragmaClangRelroSection : InheritableAttr {
+  // This attribute has no spellings as it is only ever created implicitly.
+  let Spellings = [];
+  let Args = [StringArgument<"Name">];
+  let Subjects = SubjectList<[GlobalVar], ErrorDiag>;
+  let Documentation = [Undocumented];
+}
+
 def PragmaClangTextSection : InheritableAttr {
   // This attribute has no spellings as it is only ever created implicitly.
   let Spellings = [];
Index: clang/docs/LanguageExtensions.rst
===================================================================
--- clang/docs/LanguageExtensions.rst
+++ clang/docs/LanguageExtensions.rst
@@ -3445,14 +3445,14 @@
 
 .. code-block:: c++
 
-  #pragma clang section bss="myBSS" data="myData" rodata="myRodata" text="myText"
+  #pragma clang section bss="myBSS" data="myData" rodata="myRodata" relro="myRelro" text="myText"
 
 The section names can be reverted back to default name by supplying an empty
 string to the section kind, for example:
 
 .. code-block:: c++
 
-  #pragma clang section bss="" data="" text="" rodata=""
+  #pragma clang section bss="" data="" text="" rodata="" relro=""
 
 The ``#pragma clang section`` directive obeys the following rules:
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to