Skip to content

Commit f14642f

Browse files
committed
Added support for "#pragma clang section relro=<name>"
Differential Revision: https://reviews.llvm.org/D68806 llvm-svn: 374934
1 parent 2cb2707 commit f14642f

File tree

15 files changed

+123
-22
lines changed

15 files changed

+123
-22
lines changed

clang/docs/LanguageExtensions.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3445,14 +3445,14 @@ The section names can be specified as:
34453445
34463446
.. code-block:: c++
34473447
3448-
#pragma clang section bss="myBSS" data="myData" rodata="myRodata" text="myText"
3448+
#pragma clang section bss="myBSS" data="myData" rodata="myRodata" relro="myRelro" text="myText"
34493449
34503450
The section names can be reverted back to default name by supplying an empty
34513451
string to the section kind, for example:
34523452
34533453
.. code-block:: c++
34543454
3455-
#pragma clang section bss="" data="" text="" rodata=""
3455+
#pragma clang section bss="" data="" text="" rodata="" relro=""
34563456
34573457
The ``#pragma clang section`` directive obeys the following rules:
34583458

clang/include/clang/Basic/Attr.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2020,6 +2020,14 @@ def PragmaClangRodataSection : InheritableAttr {
20202020
let Documentation = [Undocumented];
20212021
}
20222022

2023+
def PragmaClangRelroSection : InheritableAttr {
2024+
// This attribute has no spellings as it is only ever created implicitly.
2025+
let Spellings = [];
2026+
let Args = [StringArgument<"Name">];
2027+
let Subjects = SubjectList<[GlobalVar], ErrorDiag>;
2028+
let Documentation = [Undocumented];
2029+
}
2030+
20232031
def PragmaClangTextSection : InheritableAttr {
20242032
// This attribute has no spellings as it is only ever created implicitly.
20252033
let Spellings = [];

clang/include/clang/Basic/DiagnosticParseKinds.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -976,9 +976,9 @@ def err_pragma_misplaced_in_decl : Error<"this pragma cannot appear in %0 declar
976976

977977
// '#pragma clang section' related errors
978978
def err_pragma_expected_clang_section_name : Error<
979-
"expected one of [bss|data|rodata|text] section kind in '#pragma %0'">;
979+
"expected one of [bss|data|rodata|text|relro] section kind in '#pragma %0'">;
980980
def err_pragma_clang_section_expected_equal : Error<
981-
"expected '=' following '#pragma clang section %select{invalid|bss|data|rodata|text}0'">;
981+
"expected '=' following '#pragma clang section %select{invalid|bss|data|rodata|text|relro}0'">;
982982
def warn_pragma_expected_section_name : Warning<
983983
"expected a string literal for the section name in '#pragma %0' - ignored">,
984984
InGroup<IgnoredPragmas>;

clang/include/clang/Sema/Sema.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,8 @@ class Sema {
418418
PCSK_BSS = 1,
419419
PCSK_Data = 2,
420420
PCSK_Rodata = 3,
421-
PCSK_Text = 4
421+
PCSK_Text = 4,
422+
PCSK_Relro = 5
422423
};
423424

424425
enum PragmaClangSectionAction {
@@ -439,6 +440,7 @@ class Sema {
439440
PragmaClangSection PragmaClangBSSSection;
440441
PragmaClangSection PragmaClangDataSection;
441442
PragmaClangSection PragmaClangRodataSection;
443+
PragmaClangSection PragmaClangRelroSection;
442444
PragmaClangSection PragmaClangTextSection;
443445

444446
enum PragmaMsStackAction {

clang/lib/CodeGen/CGDecl.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,8 @@ void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D,
419419
var->addAttribute("data-section", SA->getName());
420420
if (auto *SA = D.getAttr<PragmaClangRodataSectionAttr>())
421421
var->addAttribute("rodata-section", SA->getName());
422+
if (auto *SA = D.getAttr<PragmaClangRelroSectionAttr>())
423+
var->addAttribute("relro-section", SA->getName());
422424

423425
if (const SectionAttr *SA = D.getAttr<SectionAttr>())
424426
var->setSection(SA->getName());

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1717,6 +1717,8 @@ void CodeGenModule::setNonAliasAttributes(GlobalDecl GD,
17171717
GV->addAttribute("data-section", SA->getName());
17181718
if (auto *SA = D->getAttr<PragmaClangRodataSectionAttr>())
17191719
GV->addAttribute("rodata-section", SA->getName());
1720+
if (auto *SA = D->getAttr<PragmaClangRelroSectionAttr>())
1721+
GV->addAttribute("relro-section", SA->getName());
17201722
}
17211723

17221724
if (auto *F = dyn_cast<llvm::Function>(GO)) {
@@ -4118,6 +4120,7 @@ static bool isVarDeclStrongDefinition(const ASTContext &Context,
41184120
// If no specialized section name is applicable, it will resort to default.
41194121
if (D->hasAttr<PragmaClangBSSSectionAttr>() ||
41204122
D->hasAttr<PragmaClangDataSectionAttr>() ||
4123+
D->hasAttr<PragmaClangRelroSectionAttr>() ||
41214124
D->hasAttr<PragmaClangRodataSectionAttr>())
41224125
return true;
41234126

clang/lib/Parse/ParsePragma.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1790,7 +1790,7 @@ void PragmaMSStructHandler::HandlePragma(Preprocessor &PP,
17901790
/*IsReinject=*/false);
17911791
}
17921792

1793-
// #pragma clang section bss="abc" data="" rodata="def" text=""
1793+
// #pragma clang section bss="abc" data="" rodata="def" text="" relro=""
17941794
void PragmaClangSectionHandler::HandlePragma(Preprocessor &PP,
17951795
PragmaIntroducer Introducer,
17961796
Token &FirstToken) {
@@ -1812,6 +1812,8 @@ void PragmaClangSectionHandler::HandlePragma(Preprocessor &PP,
18121812
SecKind = Sema::PragmaClangSectionKind::PCSK_Data;
18131813
else if (SecType->isStr("rodata"))
18141814
SecKind = Sema::PragmaClangSectionKind::PCSK_Rodata;
1815+
else if (SecType->isStr("relro"))
1816+
SecKind = Sema::PragmaClangSectionKind::PCSK_Relro;
18151817
else if (SecType->isStr("text"))
18161818
SecKind = Sema::PragmaClangSectionKind::PCSK_Text;
18171819
else {

clang/lib/Sema/SemaAttr.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,9 @@ void Sema::ActOnPragmaClangSection(SourceLocation PragmaLoc, PragmaClangSectionA
266266
case PragmaClangSectionKind::PCSK_Rodata:
267267
CSec = &PragmaClangRodataSection;
268268
break;
269+
case PragmaClangSectionKind::PCSK_Relro:
270+
CSec = &PragmaClangRelroSection;
271+
break;
269272
case PragmaClangSectionKind::PCSK_Text:
270273
CSec = &PragmaClangTextSection;
271274
break;

clang/lib/Sema/SemaDecl.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12657,6 +12657,11 @@ void Sema::FinalizeDeclaration(Decl *ThisDecl) {
1265712657
Context, PragmaClangRodataSection.SectionName,
1265812658
PragmaClangRodataSection.PragmaLocation,
1265912659
AttributeCommonInfo::AS_Pragma));
12660+
if (PragmaClangRelroSection.Valid)
12661+
VD->addAttr(PragmaClangRelroSectionAttr::CreateImplicit(
12662+
Context, PragmaClangRelroSection.SectionName,
12663+
PragmaClangRelroSection.PragmaLocation,
12664+
AttributeCommonInfo::AS_Pragma));
1266012665
}
1266112666

1266212667
if (auto *DD = dyn_cast<DecompositionDecl>(ThisDecl)) {

clang/test/CodeGenCXX/clang-sections.cpp

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,20 @@ int goo(void) { // my_text.2
2929
static int lstat_h; // my_bss.2
3030
return zoo(g, &lstat_h);
3131
}
32-
#pragma clang section rodata="my_rodata.2" data="my_data.2"
32+
#pragma clang section rodata="my_rodata.2" data="my_data.2" relro="my_relro.2"
3333
int l = 5; // my_data.2
3434
extern const int m;
3535
const int m = 6; // my_rodata.2
36+
37+
typedef int (*fptr_t)(void);
38+
const fptr_t fptrs[2] = {&foo, &goo};
3639
#pragma clang section rodata="" data="" bss="" text=""
3740
int n; // default
3841
int o = 6; // default
3942
extern const int p;
4043
const int p = 7; // default
4144
int hoo(void) {
42-
return b;
45+
return b + fptrs[f]();
4346
}
4447
}
4548
//CHECK: @a = global i32 0, align 4 #0
@@ -62,17 +65,19 @@ int hoo(void) {
6265
//CHECK: @n = global i32 0, align 4
6366
//CHECK: @o = global i32 6, align 4
6467
//CHECK: @p = constant i32 7, align 4
68+
//CHECK: @_ZL5fptrs = internal constant [2 x i32 ()*] [i32 ()* @foo, i32 ()* @goo], align 4 #3
6569

66-
//CHECK: define i32 @foo() #4 {
67-
//CHECK: define i32 @goo() #5 {
68-
//CHECK: declare i32 @zoo(i32*, i32*) #6
69-
//CHECK: define i32 @hoo() #7 {
70+
//CHECK: define i32 @foo() #5 {
71+
//CHECK: define i32 @goo() #6 {
72+
//CHECK: declare i32 @zoo(i32*, i32*) #7
73+
//CHECK: define i32 @hoo() #8 {
7074

7175
//CHECK: attributes #0 = { "bss-section"="my_bss.1" "data-section"="my_data.1" "rodata-section"="my_rodata.1" }
7276
//CHECK: attributes #1 = { "data-section"="my_data.1" "rodata-section"="my_rodata.1" }
7377
//CHECK: attributes #2 = { "bss-section"="my_bss.2" "rodata-section"="my_rodata.1" }
74-
//CHECK: attributes #3 = { "bss-section"="my_bss.2" "data-section"="my_data.2" "rodata-section"="my_rodata.2" }
75-
//CHECK: attributes #4 = { {{.*"implicit-section-name"="my_text.1".*}} }
76-
//CHECK: attributes #5 = { {{.*"implicit-section-name"="my_text.2".*}} }
77-
//CHECK-NOT: attributes #6 = { {{.*"implicit-section-name".*}} }
78+
//CHECK: attributes #3 = { "bss-section"="my_bss.2" "data-section"="my_data.2" "relro-section"="my_relro.2" "rodata-section"="my_rodata.2" }
79+
//CHECK: attributes #4 = { "relro-section"="my_relro.2" }
80+
//CHECK: attributes #5 = { {{.*"implicit-section-name"="my_text.1".*}} }
81+
//CHECK: attributes #6 = { {{.*"implicit-section-name"="my_text.2".*}} }
7882
//CHECK-NOT: attributes #7 = { {{.*"implicit-section-name".*}} }
83+
//CHECK-NOT: attributes #8 = { {{.*"implicit-section-name".*}} }

clang/test/Sema/pragma-clang-section.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,17 @@
33
#pragma clang section bss="" data="" rodata="" text=""
44
#pragma clang section
55

6-
#pragma clang section dss="mybss.2" // expected-error {{expected one of [bss|data|rodata|text] section kind in '#pragma clang section'}}
7-
#pragma clang section deta="mydata.2" // expected-error {{expected one of [bss|data|rodata|text] section kind in '#pragma clang section'}}
8-
#pragma clang section rodeta="rodata.2" // expected-error {{expected one of [bss|data|rodata|text] section kind in '#pragma clang section'}}
9-
#pragma clang section taxt="text.2" // expected-error {{expected one of [bss|data|rodata|text] section kind in '#pragma clang section'}}
6+
#pragma clang section dss="mybss.2" // expected-error {{expected one of [bss|data|rodata|text|relro] section kind in '#pragma clang section'}}
7+
#pragma clang section deta="mydata.2" // expected-error {{expected one of [bss|data|rodata|text|relro] section kind in '#pragma clang section'}}
8+
#pragma clang section rodeta="rodata.2" // expected-error {{expected one of [bss|data|rodata|text|relro] section kind in '#pragma clang section'}}
9+
#pragma clang section taxt="text.2" // expected-error {{expected one of [bss|data|rodata|text|relro] section kind in '#pragma clang section'}}
1010

11-
#pragma clang section section bss="mybss.2" // expected-error {{expected one of [bss|data|rodata|text] section kind in '#pragma clang section'}}
11+
#pragma clang section section bss="mybss.2" // expected-error {{expected one of [bss|data|rodata|text|relro] section kind in '#pragma clang section'}}
1212

1313
#pragma clang section bss "mybss.2" // expected-error {{expected '=' following '#pragma clang section bss'}}
1414
#pragma clang section data "mydata.2" // expected-error {{expected '=' following '#pragma clang section data'}}
1515
#pragma clang section rodata "myrodata.2" // expected-error {{expected '=' following '#pragma clang section rodata'}}
16-
#pragma clang section bss="" data="" rodata="" text="" more //expected-error {{expected one of [bss|data|rodata|text] section kind in '#pragma clang section'}}
16+
#pragma clang section text "text.2" // expected-error {{expected '=' following '#pragma clang section text'}}
17+
#pragma clang section relro "relro.2" // expected-error {{expected '=' following '#pragma clang section relro'}}
18+
#pragma clang section bss="" data="" rodata="" text="" more //expected-error {{expected one of [bss|data|rodata|text|relro] section kind in '#pragma clang section'}}
1719
int a;

llvm/include/llvm/IR/GlobalVariable.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ class GlobalVariable : public GlobalObject, public ilist_node<GlobalVariable> {
243243
bool hasImplicitSection() const {
244244
return getAttributes().hasAttribute("bss-section") ||
245245
getAttributes().hasAttribute("data-section") ||
246+
getAttributes().hasAttribute("relro-section") ||
246247
getAttributes().hasAttribute("rodata-section");
247248
}
248249

llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,8 @@ MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal(
568568
SectionName = Attrs.getAttribute("bss-section").getValueAsString();
569569
} else if (Attrs.hasAttribute("rodata-section") && Kind.isReadOnly()) {
570570
SectionName = Attrs.getAttribute("rodata-section").getValueAsString();
571+
} else if (Attrs.hasAttribute("relro-section") && Kind.isReadOnlyWithRel()) {
572+
SectionName = Attrs.getAttribute("relro-section").getValueAsString();
571573
} else if (Attrs.hasAttribute("data-section") && Kind.isData()) {
572574
SectionName = Attrs.getAttribute("data-section").getValueAsString();
573575
}

llvm/lib/Target/TargetLoweringObjectFile.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ MCSection *TargetLoweringObjectFile::SectionForGlobal(
253253
auto Attrs = GVar->getAttributes();
254254
if ((Attrs.hasAttribute("bss-section") && Kind.isBSS()) ||
255255
(Attrs.hasAttribute("data-section") && Kind.isData()) ||
256+
(Attrs.hasAttribute("relro-section") && Kind.isReadOnlyWithRel()) ||
256257
(Attrs.hasAttribute("rodata-section") && Kind.isReadOnly())) {
257258
return getExplicitSectionGlobal(GO, Kind, TM);
258259
}

llvm/test/MC/ELF/section-relro.ll

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
; Tests that data and relro are correctly placed in sections
2+
; specified by "#pragma clang section"
3+
; RUN: llc -filetype=obj -mtriple x86_64-unknown-linux %s -o - | llvm-readobj -S -t | FileCheck %s
4+
5+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
6+
target triple = "x86_64-unknown-linux"
7+
8+
@funcs_relro = hidden constant [2 x i32 ()*] [i32 ()* bitcast (i32 (...)* @func1 to i32 ()*), i32 ()* bitcast (i32 (...)* @func2 to i32 ()*)], align 16 #0
9+
@var_data = hidden global i32 33, align 4 #0
10+
11+
declare i32 @func1(...)
12+
declare i32 @func2(...)
13+
14+
; Function Attrs: noinline nounwind optnone sspstrong uwtable
15+
define hidden i32 @foo(i32 %i) {
16+
entry:
17+
%i.addr = alloca i32, align 4
18+
store i32 %i, i32* %i.addr, align 4
19+
%0 = load i32, i32* %i.addr, align 4
20+
%idxprom = sext i32 %0 to i64
21+
%arrayidx = getelementptr inbounds [2 x i32 ()*], [2 x i32 ()*]* @funcs_relro, i64 0, i64 %idxprom
22+
%1 = load i32 ()*, i32 ()** %arrayidx, align 8
23+
%call = call i32 %1()
24+
%2 = load i32, i32* @var_data, align 4
25+
%add = add nsw i32 %call, %2
26+
ret i32 %add
27+
}
28+
29+
attributes #0 = { "data-section"=".my_data" "relro-section"=".my_relro" "rodata-section"=".my_rodata" }
30+
31+
; CHECK: Section {
32+
; CHECK: Index:
33+
; CHECK: Name: .my_rodata
34+
; CHECK: Type: SHT_PROGBITS (0x1)
35+
; CHECK: Flags [ (0x2)
36+
; CHECK: SHF_ALLOC (0x2)
37+
; CHECK: ]
38+
; CHECK: Size: 16
39+
; CHECK: }
40+
; CHECK: Section {
41+
; CHECK: Index:
42+
; CHECK: Name: .my_data
43+
; CHECK: Type: SHT_PROGBITS (0x1)
44+
; CHECK: Flags [ (0x3)
45+
; CHECK: SHF_ALLOC (0x2)
46+
; CHECK: SHF_WRITE (0x1)
47+
; CHECK: ]
48+
; CHECK: Size: 4
49+
; CHECK: }
50+
; CHECK: Symbol {
51+
; CHECK: Name: funcs_relro
52+
; CHECK: Value: 0x0
53+
; CHECK: Size: 16
54+
; CHECK: Binding: Global (0x1)
55+
; CHECK: Type: Object (0x1)
56+
; CHECK: Section: .my_rodata
57+
; CHECK: }
58+
; CHECK: Symbol {
59+
; CHECK: Name: var_data
60+
; CHECK: Value: 0x0
61+
; CHECK: Size: 4
62+
; CHECK: Binding: Global (0x1)
63+
; CHECK: Type: Object (0x1)
64+
; CHECK: Section: .my_data
65+
; CHECK: }

0 commit comments

Comments
 (0)