Procházet zdrojové kódy

Added support for "#pragma clang section relro=<name>"

Differential Revision: https://reviews.llvm.org/D68806

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@374934 91177308-0d34-0410-b5e6-96231b3b80d8
Dmitry Mikulin před 5 roky
rodič
revize
1d08493df3

+ 2 - 2
docs/LanguageExtensions.rst

@@ -3445,14 +3445,14 @@ The section names can be specified as:
 
 
 .. code-block:: c++
 .. 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
 The section names can be reverted back to default name by supplying an empty
 string to the section kind, for example:
 string to the section kind, for example:
 
 
 .. code-block:: c++
 .. 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:
 The ``#pragma clang section`` directive obeys the following rules:
 
 

+ 8 - 0
include/clang/Basic/Attr.td

@@ -2020,6 +2020,14 @@ def PragmaClangRodataSection : InheritableAttr {
   let Documentation = [Undocumented];
   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 {
 def PragmaClangTextSection : InheritableAttr {
   // This attribute has no spellings as it is only ever created implicitly.
   // This attribute has no spellings as it is only ever created implicitly.
   let Spellings = [];
   let Spellings = [];

+ 2 - 2
include/clang/Basic/DiagnosticParseKinds.td

@@ -976,9 +976,9 @@ def err_pragma_misplaced_in_decl : Error<"this pragma cannot appear in %0 declar
 
 
 // '#pragma clang section' related errors
 // '#pragma clang section' related errors
 def err_pragma_expected_clang_section_name : Error<
 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<
 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<
 def warn_pragma_expected_section_name : Warning<
   "expected a string literal for the section name in '#pragma %0' - ignored">,
   "expected a string literal for the section name in '#pragma %0' - ignored">,
   InGroup<IgnoredPragmas>;
   InGroup<IgnoredPragmas>;

+ 3 - 1
include/clang/Sema/Sema.h

@@ -418,7 +418,8 @@ public:
     PCSK_BSS          = 1,
     PCSK_BSS          = 1,
     PCSK_Data         = 2,
     PCSK_Data         = 2,
     PCSK_Rodata       = 3,
     PCSK_Rodata       = 3,
-    PCSK_Text         = 4
+    PCSK_Text         = 4,
+    PCSK_Relro        = 5
    };
    };
 
 
   enum PragmaClangSectionAction {
   enum PragmaClangSectionAction {
@@ -439,6 +440,7 @@ public:
    PragmaClangSection PragmaClangBSSSection;
    PragmaClangSection PragmaClangBSSSection;
    PragmaClangSection PragmaClangDataSection;
    PragmaClangSection PragmaClangDataSection;
    PragmaClangSection PragmaClangRodataSection;
    PragmaClangSection PragmaClangRodataSection;
+   PragmaClangSection PragmaClangRelroSection;
    PragmaClangSection PragmaClangTextSection;
    PragmaClangSection PragmaClangTextSection;
 
 
   enum PragmaMsStackAction {
   enum PragmaMsStackAction {

+ 2 - 0
lib/CodeGen/CGDecl.cpp

@@ -419,6 +419,8 @@ void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D,
     var->addAttribute("data-section", SA->getName());
     var->addAttribute("data-section", SA->getName());
   if (auto *SA = D.getAttr<PragmaClangRodataSectionAttr>())
   if (auto *SA = D.getAttr<PragmaClangRodataSectionAttr>())
     var->addAttribute("rodata-section", SA->getName());
     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>())
   if (const SectionAttr *SA = D.getAttr<SectionAttr>())
     var->setSection(SA->getName());
     var->setSection(SA->getName());

+ 3 - 0
lib/CodeGen/CodeGenModule.cpp

@@ -1717,6 +1717,8 @@ void CodeGenModule::setNonAliasAttributes(GlobalDecl GD,
         GV->addAttribute("data-section", SA->getName());
         GV->addAttribute("data-section", SA->getName());
       if (auto *SA = D->getAttr<PragmaClangRodataSectionAttr>())
       if (auto *SA = D->getAttr<PragmaClangRodataSectionAttr>())
         GV->addAttribute("rodata-section", SA->getName());
         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)) {
     if (auto *F = dyn_cast<llvm::Function>(GO)) {
@@ -4118,6 +4120,7 @@ static bool isVarDeclStrongDefinition(const ASTContext &Context,
   // If no specialized section name is applicable, it will resort to default.
   // If no specialized section name is applicable, it will resort to default.
   if (D->hasAttr<PragmaClangBSSSectionAttr>() ||
   if (D->hasAttr<PragmaClangBSSSectionAttr>() ||
       D->hasAttr<PragmaClangDataSectionAttr>() ||
       D->hasAttr<PragmaClangDataSectionAttr>() ||
+      D->hasAttr<PragmaClangRelroSectionAttr>() ||
       D->hasAttr<PragmaClangRodataSectionAttr>())
       D->hasAttr<PragmaClangRodataSectionAttr>())
     return true;
     return true;
 
 

+ 3 - 1
lib/Parse/ParsePragma.cpp

@@ -1790,7 +1790,7 @@ void PragmaMSStructHandler::HandlePragma(Preprocessor &PP,
                       /*IsReinject=*/false);
                       /*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,
 void PragmaClangSectionHandler::HandlePragma(Preprocessor &PP,
                                              PragmaIntroducer Introducer,
                                              PragmaIntroducer Introducer,
                                              Token &FirstToken) {
                                              Token &FirstToken) {
@@ -1812,6 +1812,8 @@ void PragmaClangSectionHandler::HandlePragma(Preprocessor &PP,
       SecKind = Sema::PragmaClangSectionKind::PCSK_Data;
       SecKind = Sema::PragmaClangSectionKind::PCSK_Data;
     else if (SecType->isStr("rodata"))
     else if (SecType->isStr("rodata"))
       SecKind = Sema::PragmaClangSectionKind::PCSK_Rodata;
       SecKind = Sema::PragmaClangSectionKind::PCSK_Rodata;
+    else if (SecType->isStr("relro"))
+      SecKind = Sema::PragmaClangSectionKind::PCSK_Relro;
     else if (SecType->isStr("text"))
     else if (SecType->isStr("text"))
       SecKind = Sema::PragmaClangSectionKind::PCSK_Text;
       SecKind = Sema::PragmaClangSectionKind::PCSK_Text;
     else {
     else {

+ 3 - 0
lib/Sema/SemaAttr.cpp

@@ -266,6 +266,9 @@ void Sema::ActOnPragmaClangSection(SourceLocation PragmaLoc, PragmaClangSectionA
     case PragmaClangSectionKind::PCSK_Rodata:
     case PragmaClangSectionKind::PCSK_Rodata:
       CSec = &PragmaClangRodataSection;
       CSec = &PragmaClangRodataSection;
       break;
       break;
+    case PragmaClangSectionKind::PCSK_Relro:
+      CSec = &PragmaClangRelroSection;
+      break;
     case PragmaClangSectionKind::PCSK_Text:
     case PragmaClangSectionKind::PCSK_Text:
       CSec = &PragmaClangTextSection;
       CSec = &PragmaClangTextSection;
       break;
       break;

+ 5 - 0
lib/Sema/SemaDecl.cpp

@@ -12657,6 +12657,11 @@ void Sema::FinalizeDeclaration(Decl *ThisDecl) {
           Context, PragmaClangRodataSection.SectionName,
           Context, PragmaClangRodataSection.SectionName,
           PragmaClangRodataSection.PragmaLocation,
           PragmaClangRodataSection.PragmaLocation,
           AttributeCommonInfo::AS_Pragma));
           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)) {
   if (auto *DD = dyn_cast<DecompositionDecl>(ThisDecl)) {

+ 15 - 10
test/CodeGenCXX/clang-sections.cpp

@@ -29,17 +29,20 @@ int goo(void) {  // my_text.2
   static int lstat_h;  // my_bss.2
   static int lstat_h;  // my_bss.2
   return zoo(g, &lstat_h);
   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
 int l = 5; // my_data.2
 extern const int m;
 extern const int m;
 const int m = 6; // my_rodata.2
 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=""
 #pragma clang section rodata="" data="" bss="" text=""
 int n; // default
 int n; // default
 int o = 6; // default
 int o = 6; // default
 extern const int p;
 extern const int p;
 const int p = 7; // default
 const int p = 7; // default
 int hoo(void) {
 int hoo(void) {
-  return b;
+  return b + fptrs[f]();
 }
 }
 }
 }
 //CHECK: @a = global i32 0, align 4 #0
 //CHECK: @a = global i32 0, align 4 #0
@@ -62,17 +65,19 @@ int hoo(void) {
 //CHECK: @n = global i32 0, align 4
 //CHECK: @n = global i32 0, align 4
 //CHECK: @o = global i32 6, align 4
 //CHECK: @o = global i32 6, align 4
 //CHECK: @p = constant i32 7, 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 #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 #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 #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 #7 = { {{.*"implicit-section-name".*}} }
+//CHECK-NOT: attributes #8 = { {{.*"implicit-section-name".*}} }

+ 8 - 6
test/Sema/pragma-clang-section.c

@@ -3,15 +3,17 @@
 #pragma clang section bss="" data="" rodata="" text=""
 #pragma clang section bss="" data="" rodata="" text=""
 #pragma clang section
 #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 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 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 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;
 int a;