forked from OSchip/llvm-project
Added support for "#pragma clang section relro=<name>"
Differential Revision: https://reviews.llvm.org/D68806 llvm-svn: 374934
This commit is contained in:
parent
2cb27072ce
commit
f14642f2f1
|
@ -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:
|
||||
|
||||
|
|
|
@ -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 = [];
|
||||
|
|
|
@ -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<IgnoredPragmas>;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -419,6 +419,8 @@ void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D,
|
|||
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());
|
||||
|
|
|
@ -1717,6 +1717,8 @@ void CodeGenModule::setNonAliasAttributes(GlobalDecl GD,
|
|||
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 @@ static bool isVarDeclStrongDefinition(const ASTContext &Context,
|
|||
// 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;
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<DecompositionDecl>(ThisDecl)) {
|
||||
|
|
|
@ -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".*}} }
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -243,6 +243,7 @@ public:
|
|||
bool hasImplicitSection() const {
|
||||
return getAttributes().hasAttribute("bss-section") ||
|
||||
getAttributes().hasAttribute("data-section") ||
|
||||
getAttributes().hasAttribute("relro-section") ||
|
||||
getAttributes().hasAttribute("rodata-section");
|
||||
}
|
||||
|
||||
|
|
|
@ -568,6 +568,8 @@ MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal(
|
|||
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();
|
||||
}
|
||||
|
|
|
@ -253,6 +253,7 @@ MCSection *TargetLoweringObjectFile::SectionForGlobal(
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -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: }
|
Loading…
Reference in New Issue