gcc/gcc46-pr31490.patch
Jakub Jelinek f7f5fb5d3e 4.6.0-0.5
2011-01-28 11:21:01 +01:00

290 lines
11 KiB
Diff

2011-01-27 Jakub Jelinek <jakub@redhat.com>
PR middle-end/31490
* output.h (SECTION_RELRO): Define.
(SECTION_MACH_DEP): Adjust.
(get_variable_section): New prototype.
* config/darwin.h (SECTION_NO_ANCHOR): Adjust.
* 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.
--- gcc/output.h.jj 2011-01-27 17:33:28.200496345 +0100
+++ gcc/output.h 2011-01-27 17:40:33.355649071 +0100
@@ -441,7 +441,8 @@ extern void no_asm_to_stream (FILE *);
#define SECTION_DECLARED 0x100000 /* section has been used */
#define SECTION_STYLE_MASK 0x600000 /* bits used for SECTION_STYLE */
#define SECTION_COMMON 0x800000 /* contains common data */
-#define SECTION_MACH_DEP 0x1000000 /* subsequent bits reserved for target */
+#define SECTION_RELRO 0x1000000 /* data is readonly after relocation processing */
+#define SECTION_MACH_DEP 0x2000000 /* subsequent bits reserved for target */
/* This SECTION_STYLE is used for unnamed sections that we can switch
to using a special assembler directive. */
@@ -585,6 +586,7 @@ extern section *get_unnamed_section (uns
const void *);
extern section *get_section (const char *, unsigned int, tree);
extern section *get_named_section (tree, const char *, int);
+extern section *get_variable_section (tree, bool);
extern void place_block_symbol (rtx);
extern rtx get_section_anchor (struct object_block *, HOST_WIDE_INT,
enum tls_model);
--- gcc/varpool.c.jj 2011-01-27 17:33:28.229830104 +0100
+++ gcc/varpool.c 2011-01-27 19:48:24.567639053 +0100
@@ -565,11 +565,29 @@ varpool_remove_unreferenced_decls (void)
varpool_analyze_pending_decls ();
}
+/* For variables in named sections make sure get_variable_section
+ is called before we switch to those sections. Then section
+ conflicts between read-only and read-only requiring relocations
+ sections can be resolved. */
+void
+varpool_finalize_named_section_flags (struct varpool_node *node)
+{
+ if (!TREE_ASM_WRITTEN (node->decl)
+ && !node->alias
+ && !node->in_other_partition
+ && !DECL_EXTERNAL (node->decl)
+ && TREE_CODE (node->decl) == VAR_DECL
+ && !DECL_HAS_VALUE_EXPR_P (node->decl)
+ && DECL_SECTION_NAME (node->decl))
+ get_variable_section (node->decl, false);
+}
+
/* Output all variables enqueued to be assembled. */
bool
varpool_assemble_pending_decls (void)
{
bool changed = false;
+ struct varpool_node *node;
if (seen_error ())
return false;
@@ -580,6 +598,9 @@ varpool_assemble_pending_decls (void)
elsewhere. */
varpool_analyze_pending_decls ();
+ for (node = varpool_nodes_queue; node; node = node->next_needed)
+ varpool_finalize_named_section_flags (node);
+
while (varpool_nodes_queue)
{
struct varpool_node *node = varpool_nodes_queue;
--- gcc/config/darwin.h.jj 2011-01-27 17:33:28.217391021 +0100
+++ gcc/config/darwin.h 2011-01-27 17:40:33.356655497 +0100
@@ -654,7 +654,7 @@ int darwin_label_is_anonymous_local_objc
/* Private flag applied to disable section-anchors in a particular section.
This needs to be kept in sync with the flags used by varasm.c (defined in
output.h). */
-#define SECTION_NO_ANCHOR 0x2000000
+#define SECTION_NO_ANCHOR 0x4000000
/* Declare the section variables. */
#ifndef USED_FOR_TARGET
--- gcc/cgraph.h.jj 2011-01-27 17:33:28.011433405 +0100
+++ gcc/cgraph.h 2011-01-27 17:33:28.011433405 +0100
@@ -720,6 +720,7 @@ bool cgraph_node_can_be_local_p (struct
struct varpool_node * varpool_get_node (const_tree decl);
void varpool_remove_node (struct varpool_node *node);
+void varpool_finalize_named_section_flags (struct varpool_node *node);
bool varpool_assemble_pending_decls (void);
bool varpool_assemble_decl (struct varpool_node *node);
bool varpool_analyze_pending_decls (void);
--- gcc/varasm.c.jj 2011-01-27 17:40:25.196565130 +0100
+++ gcc/varasm.c 2011-01-27 17:40:33.361429176 +0100
@@ -119,6 +119,7 @@ static void output_addressed_constants (
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
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_out
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, c
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
/* 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
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,
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 *
--- gcc/cgraphunit.c.jj 2011-01-27 17:33:29.416940770 +0100
+++ gcc/cgraphunit.c 2011-01-27 19:48:24.567639053 +0100
@@ -1708,6 +1708,10 @@ cgraph_output_in_order (void)
varpool_empty_needed_queue ();
for (i = 0; i < max; ++i)
+ if (nodes[i].kind == ORDER_VAR)
+ varpool_finalize_named_section_flags (nodes[i].u.v);
+
+ for (i = 0; i < max; ++i)
{
switch (nodes[i].kind)
{
--- gcc/testsuite/gcc.dg/pr31490-2.c.jj 2011-01-27 17:40:33.365546146 +0100
+++ gcc/testsuite/gcc.dg/pr31490-2.c 2011-01-27 17:40:33.365546146 +0100
@@ -0,0 +1,7 @@
+/* PR middle-end/31490 */
+/* { dg-do compile } */
+/* { dg-options "-fpic" { target fpic } } */
+/* { dg-require-named-sections "" } */
+
+const char *const x __attribute__((section("foo"))) = "";
+const char *const g __attribute__((section("foo"))) = (const char *) 0;
--- gcc/testsuite/gcc.dg/pr31490-3.c.jj 2011-01-27 17:40:33.365546146 +0100
+++ gcc/testsuite/gcc.dg/pr31490-3.c 2011-01-27 17:40:33.365546146 +0100
@@ -0,0 +1,7 @@
+/* PR middle-end/31490 */
+/* { dg-do compile } */
+/* { dg-options "-fpic" { target fpic } } */
+/* { dg-require-named-sections "" } */
+
+const char *const x __attribute__((section("foo"))) = (const char *) 0;
+const char *const g __attribute__((section("foo"))) = "bar";
--- gcc/testsuite/gcc.dg/pr31490-4.c.jj 2011-01-27 17:40:33.366545270 +0100
+++ gcc/testsuite/gcc.dg/pr31490-4.c 2011-01-27 17:40:33.366545270 +0100
@@ -0,0 +1,10 @@
+/* PR middle-end/31490 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-options "-O2 -fpic" { target fpic } } */
+/* { dg-require-named-sections "" } */
+
+const char *const x __attribute__((section("foo"))) = "";
+const char *const g __attribute__((section("foo"))) = (const char *) 0;
+const char *const y __attribute__((section("bar"))) = (const char *) 0;
+const char *const h __attribute__((section("bar"))) = "bar";