diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-02-03 19:12:07 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-02-03 19:12:07 +0000 |
commit | 91da0f1cbba29c0c0d36e70d0d88842d5aaa496d (patch) | |
tree | d84c6553f07cd91230768e24b2d35f690b8488db /gcc/varasm.c | |
parent | 61aeb5015aac5a923b4a162b4bbf3cba566b5efe (diff) | |
download | gcc-91da0f1cbba29c0c0d36e70d0d88842d5aaa496d.tar.gz |
PR middle-end/31490
* output.h (SECTION_RELRO): Define.
(SECTION_MACH_DEP): Adjust.
(get_variable_section): New prototype.
* varpool.c (varpool_finalize_named_section_flags): New function.
(varpool_assemble_pending_decls): Call it.
* cgraph.h (varpool_finalize_named_section_flags): New prototype.
* cgraphunit.c (cgraph_output_in_order): Call
varpool_finalize_named_section_flags.
* varasm.c (get_section): Allow section flags conflicts between
relro and read-only sections if the section hasn't been declared yet.
Set SECTION_OVERRIDE after diagnosing section type conflict.
(get_variable_section): No longer static.
(default_section_type_flags): Use SECTION_WRITE | SECTION_RELRO for
readonly sections that need relocations.
(decl_readonly_section_1): New function.
(decl_readonly_section): Use it.
Revert:
2010-11-17 Dinar Temirbulatov <dtemirbulatov@gmail.com>
Steve Ellcey <sje@cup.hp.com>
PR middle-end/31490
* varasm.c (categorize_decl_for_section): Ignore reloc_rw_mask
if section attribute used.
* gcc.dg/pr31490-2.c: New test.
* gcc.dg/pr31490-3.c: New test.
* gcc.dg/pr31490-4.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@169804 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/varasm.c')
-rw-r--r-- | gcc/varasm.c | 61 |
1 files changed, 46 insertions, 15 deletions
diff --git a/gcc/varasm.c b/gcc/varasm.c index a1cddac16c1..3a9fbae5901 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -119,6 +119,7 @@ static void output_addressed_constants (tree); static unsigned HOST_WIDE_INT array_size_for_constructor (tree); static unsigned min_align (unsigned, unsigned); static void globalize_decl (tree); +static bool decl_readonly_section_1 (enum section_category); #ifdef BSS_SECTION_ASM_OP #ifdef ASM_OUTPUT_BSS static void asm_output_bss (FILE *, tree, const char *, @@ -294,11 +295,31 @@ get_section (const char *name, unsigned int flags, tree decl) if ((sect->common.flags & ~SECTION_DECLARED) != flags && ((sect->common.flags | flags) & SECTION_OVERRIDE) == 0) { + /* It is fine if one of the section flags is + SECTION_WRITE | SECTION_RELRO and the other has none of these + flags (i.e. read-only) in named sections and either the + section hasn't been declared yet or has been declared as writable. + In that case just make sure the resulting flags are + SECTION_WRITE | SECTION_RELRO, ie. writable only because of + relocations. */ + if (((sect->common.flags ^ flags) & (SECTION_WRITE | SECTION_RELRO)) + == (SECTION_WRITE | SECTION_RELRO) + && (sect->common.flags + & ~(SECTION_DECLARED | SECTION_WRITE | SECTION_RELRO)) + == (flags & ~(SECTION_WRITE | SECTION_RELRO)) + && ((sect->common.flags & SECTION_DECLARED) == 0 + || (sect->common.flags & SECTION_WRITE))) + { + sect->common.flags |= (SECTION_WRITE | SECTION_RELRO); + return sect; + } /* Sanity check user variables for flag changes. */ if (decl == 0) decl = sect->named.decl; gcc_assert (decl); error ("%+D causes a section type conflict", decl); + /* Make sure we don't error about one section multiple times. */ + sect->common.flags |= SECTION_OVERRIDE; } } return sect; @@ -985,7 +1006,7 @@ align_variable (tree decl, bool dont_output_data) should be placed. PREFER_NOSWITCH_P is true if a noswitch section should be used wherever possible. */ -static section * +section * get_variable_section (tree decl, bool prefer_noswitch_p) { addr_space_t as = ADDR_SPACE_GENERIC; @@ -6026,8 +6047,18 @@ default_section_type_flags (tree decl, const char *name, int reloc) if (decl && TREE_CODE (decl) == FUNCTION_DECL) flags = SECTION_CODE; - else if (decl && decl_readonly_section (decl, reloc)) - flags = 0; + else if (decl) + { + enum section_category category + = categorize_decl_for_section (decl, reloc); + if (decl_readonly_section_1 (category)) + flags = 0; + else if (category == SECCAT_DATA_REL_RO + || category == SECCAT_DATA_REL_RO_LOCAL) + flags = SECTION_WRITE | SECTION_RELRO; + else + flags = SECTION_WRITE; + } else flags = SECTION_WRITE; @@ -6250,17 +6281,13 @@ categorize_decl_for_section (const_tree decl, int reloc) /* Here the reloc_rw_mask is not testing whether the section should be read-only or not, but whether the dynamic link will have to do something. If so, we wish to segregate the data in order to - minimize cache misses inside the dynamic linker. If the data - has a section attribute, ignore reloc_rw_mask() so that all data - in a given named section is catagorized in the same way. */ - if (reloc & targetm.asm_out.reloc_rw_mask () - && !lookup_attribute ("section", DECL_ATTRIBUTES (decl))) + minimize cache misses inside the dynamic linker. */ + if (reloc & targetm.asm_out.reloc_rw_mask ()) ret = reloc == 1 ? SECCAT_DATA_REL_LOCAL : SECCAT_DATA_REL; else ret = SECCAT_DATA; } - else if (reloc & targetm.asm_out.reloc_rw_mask () - && !lookup_attribute ("section", DECL_ATTRIBUTES (decl))) + else if (reloc & targetm.asm_out.reloc_rw_mask ()) ret = reloc == 1 ? SECCAT_DATA_REL_RO_LOCAL : SECCAT_DATA_REL_RO; else if (reloc || flag_merge_constants < 2) /* C and C++ don't allow different variables to share the same @@ -6311,10 +6338,10 @@ categorize_decl_for_section (const_tree decl, int reloc) return ret; } -bool -decl_readonly_section (const_tree decl, int reloc) +static bool +decl_readonly_section_1 (enum section_category category) { - switch (categorize_decl_for_section (decl, reloc)) + switch (category) { case SECCAT_RODATA: case SECCAT_RODATA_MERGE_STR: @@ -6322,13 +6349,17 @@ decl_readonly_section (const_tree decl, int reloc) case SECCAT_RODATA_MERGE_CONST: case SECCAT_SRODATA: return true; - break; default: return false; - break; } } +bool +decl_readonly_section (const_tree decl, int reloc) +{ + return decl_readonly_section_1 (categorize_decl_for_section (decl, reloc)); +} + /* Select a section based on the above categorization. */ section * |