summaryrefslogtreecommitdiff
path: root/gcc/varasm.c
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2011-02-03 19:12:07 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2011-02-03 19:12:07 +0000
commit91da0f1cbba29c0c0d36e70d0d88842d5aaa496d (patch)
treed84c6553f07cd91230768e24b2d35f690b8488db /gcc/varasm.c
parent61aeb5015aac5a923b4a162b4bbf3cba566b5efe (diff)
downloadgcc-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.c61
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 *