From 1d08493df33c295a8647a712884d7c634f8e8057 Mon Sep 17 00:00:00 2001 From: Dmitry Mikulin Date: Tue, 15 Oct 2019 18:31:10 +0000 Subject: Added support for "#pragma clang section relro=" Differential Revision: https://reviews.llvm.org/D68806 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@374934 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/LanguageExtensions.rst | 4 ++-- include/clang/Basic/Attr.td | 8 ++++++++ include/clang/Basic/DiagnosticParseKinds.td | 4 ++-- include/clang/Sema/Sema.h | 4 +++- lib/CodeGen/CGDecl.cpp | 2 ++ lib/CodeGen/CodeGenModule.cpp | 3 +++ lib/Parse/ParsePragma.cpp | 4 +++- lib/Sema/SemaAttr.cpp | 3 +++ lib/Sema/SemaDecl.cpp | 5 +++++ test/CodeGenCXX/clang-sections.cpp | 25 +++++++++++++++---------- test/Sema/pragma-clang-section.c | 14 ++++++++------ 11 files changed, 54 insertions(+), 22 deletions(-) diff --git a/docs/LanguageExtensions.rst b/docs/LanguageExtensions.rst index 967f4ad9bb..51e6a44603 100644 --- a/docs/LanguageExtensions.rst +++ b/docs/LanguageExtensions.rst @@ -3445,14 +3445,14 @@ The section names can be specified as: .. 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: diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index 279a43236a..c3a2ee325d 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -2020,6 +2020,14 @@ def PragmaClangRodataSection : InheritableAttr { 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 = []; diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index 48ef1fb369..7c9f4da778 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/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 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; diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 6b2d603206..7c93d40952 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -418,7 +418,8 @@ public: PCSK_BSS = 1, PCSK_Data = 2, PCSK_Rodata = 3, - PCSK_Text = 4 + PCSK_Text = 4, + PCSK_Relro = 5 }; enum PragmaClangSectionAction { @@ -439,6 +440,7 @@ public: PragmaClangSection PragmaClangBSSSection; PragmaClangSection PragmaClangDataSection; PragmaClangSection PragmaClangRodataSection; + PragmaClangSection PragmaClangRelroSection; PragmaClangSection PragmaClangTextSection; enum PragmaMsStackAction { diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index 46ea9c32ee..563841c068 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -419,6 +419,8 @@ void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D, var->addAttribute("data-section", SA->getName()); if (auto *SA = D.getAttr()) var->addAttribute("rodata-section", SA->getName()); + if (auto *SA = D.getAttr()) + var->addAttribute("relro-section", SA->getName()); if (const SectionAttr *SA = D.getAttr()) var->setSection(SA->getName()); diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index eab48ccb9b..c97e7b2217 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -1717,6 +1717,8 @@ void CodeGenModule::setNonAliasAttributes(GlobalDecl GD, GV->addAttribute("data-section", SA->getName()); if (auto *SA = D->getAttr()) GV->addAttribute("rodata-section", SA->getName()); + if (auto *SA = D->getAttr()) + GV->addAttribute("relro-section", SA->getName()); } if (auto *F = dyn_cast(GO)) { @@ -4118,6 +4120,7 @@ static bool isVarDeclStrongDefinition(const ASTContext &Context, // If no specialized section name is applicable, it will resort to default. if (D->hasAttr() || D->hasAttr() || + D->hasAttr() || D->hasAttr()) return true; diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp index d589cb690a..cdbf697cf7 100644 --- a/lib/Parse/ParsePragma.cpp +++ b/lib/Parse/ParsePragma.cpp @@ -1790,7 +1790,7 @@ void PragmaMSStructHandler::HandlePragma(Preprocessor &PP, /*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 @@ void PragmaClangSectionHandler::HandlePragma(Preprocessor &PP, 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 { diff --git a/lib/Sema/SemaAttr.cpp b/lib/Sema/SemaAttr.cpp index 3104ea88af..70186c966f 100644 --- a/lib/Sema/SemaAttr.cpp +++ b/lib/Sema/SemaAttr.cpp @@ -266,6 +266,9 @@ void Sema::ActOnPragmaClangSection(SourceLocation PragmaLoc, PragmaClangSectionA case PragmaClangSectionKind::PCSK_Rodata: CSec = &PragmaClangRodataSection; break; + case PragmaClangSectionKind::PCSK_Relro: + CSec = &PragmaClangRelroSection; + break; case PragmaClangSectionKind::PCSK_Text: CSec = &PragmaClangTextSection; break; diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 2c0ba67157..62ec83967b 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -12657,6 +12657,11 @@ void Sema::FinalizeDeclaration(Decl *ThisDecl) { 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(ThisDecl)) { diff --git a/test/CodeGenCXX/clang-sections.cpp b/test/CodeGenCXX/clang-sections.cpp index 4fe42eaf77..59faf27679 100644 --- a/test/CodeGenCXX/clang-sections.cpp +++ b/test/CodeGenCXX/clang-sections.cpp @@ -29,17 +29,20 @@ int goo(void) { // my_text.2 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 @@ int hoo(void) { //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".*}} } diff --git a/test/Sema/pragma-clang-section.c b/test/Sema/pragma-clang-section.c index 49463889d3..38a3bc9274 100644 --- a/test/Sema/pragma-clang-section.c +++ b/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; -- cgit v1.2.1