Commit 7fece979 by Jakub Jelinek Committed by Jakub Jelinek

re PR middle-end/31490 (Compile error section type conflict)

	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.

From-SVN: r169804
parent d18d5478
2011-02-03 Jakub Jelinek <jakub@redhat.com>
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.
2011-02-03 Jakub Jelinek <jakub@redhat.com>
* config/darwin.h (SECTION_NO_ANCHOR): Remove.
* config/darwin.c (SECTION_NO_ANCHOR): Define.
(darwin_init_sections): Remove assertion.
......
/* Callgraph handling code.
Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
Contributed by Jan Hubicka
......@@ -720,6 +720,7 @@ bool cgraph_node_can_be_local_p (struct cgraph_node *);
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);
......
......@@ -1715,6 +1715,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)
{
......
/* Declarations for insn-output.c. These functions are defined in recog.c,
final.c, and varasm.c.
Copyright (C) 1987, 1991, 1994, 1997, 1998, 1999, 2000, 2001, 2002,
2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
This file is part of GCC.
......@@ -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 (unsigned int, void (*) (const void *),
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);
......
2011-02-03 Jakub Jelinek <jakub@redhat.com>
PR middle-end/31490
* gcc.dg/pr31490-2.c: New test.
* gcc.dg/pr31490-3.c: New test.
* gcc.dg/pr31490-4.c: New test.
2011-02-03 Nathan Froyd <froydnj@codesourcery.com>
Jakub Jelinek <jakub@redhat.com>
......
/* 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;
/* 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";
/* 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";
......@@ -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 *
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment