This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
| Other format: | [Raw text] | |
This patch fixes some problems with the gcc-3.2.x rs6000 section
selection code.
a) .gnu.linkonce.r* sections can be emitted with "aw" section flags.
This is due to a mismatch between DECL_READONLY_SECTION and
rs6000_unique_section. Testcase attached.
b) rs6000_elf_section_type_flags selects a "w" section flag when
TARGET_RELOCATABLE regardless of the section. This, like case a),
leads to ld marking .rodata as writable, which is a little silly.
It's better to always select .data when TARGET_RELOCATABLE.
c) rs6000_unique_section tests DECL_INITIAL (decl) on all but
FUNCTION_DECLs. In particular, STRING_CST decls are tested. These
decls don't have a decl.initial field, leading to seemingly random
segfaults depending on where the decl happened to be allocated.
To be honest, I didn't actually see this problem until I started
extracting rs6000_categorize_section from rs6000_select_section and
rs6000_unique_section, and then found segfaults when running the
libstdc++ testsuite. Hmm, and it looks like rs6000_unique_section
was never called with a STRING_CST decl. Oh well, there was code
in rs6000_unique_section to handle STRING_CSTs...
gcc/ChangeLog
* output.h (DECL_READONLY_SECTION): Allow it to be overridden.
* config/rs6000/rs6000-protos.h (rs6000_readonly_section): Declare.
* config/rs6000/rs6000.c (TARGET_SECTION_TYPE_FLAGS): Don't define.
(rs6000_elf_section_type_flags): Delete.
(rs6000_categorize_section): New function.
(rs6000_select_section): Use it here..
(rs6000_unique_section): ..and here.
(rs6000_readonly_section): New function.
(rs6000_binds_local_p): Delete unused var.
* config/rs6000/sysv4.h (DECL_READONLY_SECTION): Define.
Bootstrapped and regression tested c,c++,f77 powerpc-linux native.
If you look closely at rs6000_categorize_section, you'll see some
small functional differences between the old code and the new.
Besides the TARGET_RELOCATABLE hack mentioned above, I've changed
the test
(flag_pic || DEFAULT_ABI == ABI_AIX) && reloc
to
(flag_pic || rs6000_flag_pic) && reloc
I believe this to be correct as we're really testing for shared lib
semantics, and the DEFAULT_ABI test, while not wrong, results in rw
sections being used unnecessarily. A similar change should probably
be made to mainline.
The other change is that the default case (ie. not FUNCTION_DECL,
STRING_CST, VAR_DECL or CONSTRUCTOR) now no longer tests for shared
lib semantics and selects rodata.
Index: gcc/output.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/output.h,v
retrieving revision 1.94.2.2
diff -u -p -r1.94.2.2 output.h
--- gcc/output.h 28 Apr 2002 18:43:53 -0000 1.94.2.2
+++ gcc/output.h 7 Feb 2003 01:17:22 -0000
@@ -468,6 +468,7 @@ extern struct rtx_def *current_output_in
/* Decide whether DECL needs to be in a writable section. RELOC is the same
as for SELECT_SECTION. */
+#ifndef DECL_READONLY_SECTION
#define DECL_READONLY_SECTION(DECL,RELOC) \
(TREE_READONLY (DECL) \
&& ! TREE_THIS_VOLATILE (DECL) \
@@ -475,6 +476,7 @@ extern struct rtx_def *current_output_in
&& (DECL_INITIAL (DECL) == error_mark_node \
|| TREE_CONSTANT (DECL_INITIAL (DECL))) \
&& ! (RELOC && (flag_pic || DECL_ONE_ONLY (DECL))))
+#endif
/* User label prefix in effect for this compilation. */
extern const char *user_label_prefix;
Index: gcc/config/rs6000/rs6000-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000-protos.h,v
retrieving revision 1.30.6.3
diff -u -p -r1.30.6.3 rs6000-protos.h
--- gcc/config/rs6000/rs6000-protos.h 26 Nov 2002 15:59:55 -0000 1.30.6.3
+++ gcc/config/rs6000/rs6000-protos.h 7 Feb 2003 01:17:23 -0000
@@ -147,6 +147,7 @@ extern struct rtx_def *rs6000_va_arg PAR
extern void output_mi_thunk PARAMS ((FILE *, tree, int, tree));
extern void rs6000_encode_section_info PARAMS ((tree));
extern void rs6000_select_section PARAMS ((tree, int));
+extern bool rs6000_readonly_section PARAMS ((tree, int));
extern void rs6000_unique_section PARAMS ((tree, int));
#ifdef ARGS_SIZE_RTX
/* expr.h defines ARGS_SIZE_RTX and `enum direction' */
Index: gcc/config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.291.2.13.2.14
diff -u -p -r1.291.2.13.2.14 rs6000.c
--- gcc/config/rs6000/rs6000.c 23 Jan 2003 22:19:42 -0000 1.291.2.13.2.14
+++ gcc/config/rs6000/rs6000.c 7 Feb 2003 01:17:33 -0000
@@ -147,15 +147,16 @@ static void rs6000_output_function_epilo
static rtx rs6000_emit_set_long_const PARAMS ((rtx,
HOST_WIDE_INT, HOST_WIDE_INT));
#if TARGET_ELF
-static unsigned int rs6000_elf_section_type_flags PARAMS ((tree, const char *,
- int));
static void rs6000_elf_asm_out_constructor PARAMS ((rtx, int));
static void rs6000_elf_asm_out_destructor PARAMS ((rtx, int));
#endif
#ifdef OBJECT_FORMAT_COFF
static void xcoff_asm_named_section PARAMS ((const char *, unsigned int));
#endif
+#ifdef USING_ELFOS_H
+static unsigned int rs6000_categorize_section PARAMS ((tree, int));
static bool rs6000_binds_local_p PARAMS ((tree));
+#endif
static int rs6000_adjust_cost PARAMS ((rtx, rtx, rtx, int));
static int rs6000_adjust_priority PARAMS ((rtx, int));
static int rs6000_issue_rate PARAMS ((void));
@@ -266,11 +267,6 @@ static const char alt_reg_names[][8] =
#undef TARGET_ASM_FUNCTION_EPILOGUE
#define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
-#if TARGET_ELF
-#undef TARGET_SECTION_TYPE_FLAGS
-#define TARGET_SECTION_TYPE_FLAGS rs6000_elf_section_type_flags
-#endif
-
#undef TARGET_SCHED_ISSUE_RATE
#define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
#undef TARGET_SCHED_ADJUST_COST
@@ -10785,6 +10781,8 @@ rs6000_longcall_ref (call_ref)
}
+#ifdef USING_ELFOS_H
+
/* A C statement or statements to switch to the appropriate section
for output of RTX in mode MODE. You can assume that RTX is some
kind of constant in RTL. The argument MODE is redundant except in
@@ -10794,8 +10792,6 @@ rs6000_longcall_ref (call_ref)
Do not define this macro if you put all constants in the read-only
data section. */
-#ifdef USING_ELFOS_H
-
void
rs6000_select_rtx_section (mode, x)
enum machine_mode mode;
@@ -10812,6 +10808,95 @@ rs6000_select_rtx_section (mode, x)
const_section ();
}
+/* Return an index into the rs6000_select_section "prefixes" array to
+ select an appropriate section for DECL and RELOC. */
+
+#define SECCAT_RODATA 0
+#define SECCAT_SDATA2 1
+#define SECCAT_DATA 2
+#define SECCAT_SDATA 3
+#define SECCAT_BSS 4
+#define SECCAT_SBSS 5
+#define SECCAT_TEXT 6
+
+static unsigned int
+rs6000_categorize_section (decl, reloc)
+ tree decl;
+ int reloc;
+{
+ unsigned int sec;
+
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ sec = SECCAT_TEXT;
+ else
+ {
+ int needs_sdata;
+
+ if (TARGET_RELOCATABLE)
+ sec = SECCAT_DATA;
+ else if (TREE_CODE (decl) == STRING_CST)
+ {
+ if (flag_writable_strings)
+ sec = SECCAT_DATA;
+ else
+ sec = SECCAT_RODATA;
+ }
+ else if (TREE_CODE (decl) == VAR_DECL)
+ {
+ if (DECL_INITIAL (decl) == 0
+ || DECL_INITIAL (decl) == error_mark_node)
+ sec = SECCAT_BSS;
+ else if (((flag_pic || rs6000_flag_pic) && reloc)
+ || ! TREE_READONLY (decl)
+ || TREE_SIDE_EFFECTS (decl)
+ || ! TREE_CONSTANT (DECL_INITIAL (decl)))
+ sec = SECCAT_DATA;
+ else
+ sec = SECCAT_RODATA;
+ }
+ else if (TREE_CODE (decl) == CONSTRUCTOR)
+ {
+ if (((flag_pic || rs6000_flag_pic) && reloc)
+ || TREE_SIDE_EFFECTS (decl)
+ || ! TREE_CONSTANT (decl))
+ sec = SECCAT_DATA;
+ else
+ sec = SECCAT_RODATA;
+ }
+ else
+ sec = SECCAT_RODATA;
+
+ if (rs6000_sdata == SDATA_NONE
+ || (rs6000_sdata == SDATA_DATA && !TREE_PUBLIC (decl)))
+ needs_sdata = 0;
+ else
+ {
+ int size = int_size_in_bytes (TREE_TYPE (decl));
+ needs_sdata = size > 0 && size <= g_switch_value;
+ }
+
+ if (needs_sdata)
+ {
+ /* .sdata2 is only for EABI. */
+ if (sec == SECCAT_RODATA && rs6000_sdata != SDATA_EABI)
+ sec = SECCAT_DATA;
+ sec += 1;
+ }
+ }
+
+ return sec;
+}
+
+bool
+rs6000_readonly_section (decl, reloc)
+ tree decl;
+ int reloc;
+{
+ unsigned int sec = rs6000_categorize_section (decl, reloc);
+
+ return sec <= SECCAT_SDATA2 || sec == SECCAT_TEXT;
+}
+
/* A C statement or statements to switch to the appropriate
section for output of DECL. DECL is either a `VAR_DECL' node
or a constant of some sort. RELOC indicates whether forming
@@ -10822,9 +10907,7 @@ rs6000_select_section (decl, reloc)
tree decl;
int reloc;
{
- int size = int_size_in_bytes (TREE_TYPE (decl));
- int needs_sdata;
- int readonly;
+ unsigned int sec;
static void (* const sec_funcs[4]) PARAMS ((void)) = {
&const_section,
&sdata2_section,
@@ -10832,31 +10915,13 @@ rs6000_select_section (decl, reloc)
&sdata_section
};
- needs_sdata = (size > 0
- && size <= g_switch_value
- && rs6000_sdata != SDATA_NONE
- && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)));
-
- if (TREE_CODE (decl) == STRING_CST)
- readonly = ! flag_writable_strings;
- else if (TREE_CODE (decl) == VAR_DECL)
- readonly = (! ((flag_pic || DEFAULT_ABI == ABI_AIX) && reloc)
- && TREE_READONLY (decl)
- && ! TREE_SIDE_EFFECTS (decl)
- && DECL_INITIAL (decl)
- && DECL_INITIAL (decl) != error_mark_node
- && TREE_CONSTANT (DECL_INITIAL (decl)));
- else if (TREE_CODE (decl) == CONSTRUCTOR)
- readonly = (! ((flag_pic || DEFAULT_ABI == ABI_AIX) && reloc)
- && ! TREE_SIDE_EFFECTS (decl)
- && TREE_CONSTANT (decl));
- else
- readonly = ! ((flag_pic || DEFAULT_ABI == ABI_AIX) && reloc);
+ sec = rs6000_categorize_section (decl, reloc);
+ if (sec >= SECCAT_TEXT)
+ abort ();
+ else if (sec >= SECCAT_BSS)
+ sec -= 2;
- if (needs_sdata && rs6000_sdata != SDATA_EABI)
- readonly = 0;
-
- (*sec_funcs[(readonly ? 0 : 2) + (needs_sdata ? 1 : 0)])();
+ (*sec_funcs[sec]) ();
}
/* A C statement to build up a unique section name, expressed as a
@@ -10873,7 +10938,7 @@ rs6000_unique_section (decl, reloc)
int reloc;
{
int len;
- int sec;
+ unsigned int sec;
const char *name;
char *string;
const char *prefix;
@@ -10889,46 +10954,7 @@ rs6000_unique_section (decl, reloc)
{ ".text.", ".gnu.linkonce.t." }
};
- if (TREE_CODE (decl) == FUNCTION_DECL)
- sec = 6;
- else
- {
- int readonly;
- int needs_sdata;
- int size;
-
- if (TREE_CODE (decl) == STRING_CST)
- readonly = ! flag_writable_strings;
- else if (TREE_CODE (decl) == VAR_DECL)
- readonly = (! ((flag_pic || DEFAULT_ABI == ABI_AIX) && reloc)
- && TREE_READONLY (decl)
- && ! TREE_SIDE_EFFECTS (decl)
- && TREE_CONSTANT (DECL_INITIAL (decl)));
- else
- readonly = ! ((flag_pic || DEFAULT_ABI == ABI_AIX) && reloc);
-
- size = int_size_in_bytes (TREE_TYPE (decl));
- needs_sdata = (size > 0
- && size <= g_switch_value
- && rs6000_sdata != SDATA_NONE
- && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)));
-
- if (DECL_INITIAL (decl) == 0
- || DECL_INITIAL (decl) == error_mark_node)
- sec = 4;
- else if (! readonly)
- sec = 2;
- else
- sec = 0;
-
- if (needs_sdata)
- {
- /* .sdata2 is only for EABI. */
- if (sec == 0 && rs6000_sdata != SDATA_EABI)
- sec = 2;
- sec += 1;
- }
- }
+ sec = rs6000_categorize_section (decl, reloc);
STRIP_NAME_ENCODING (name, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
prefix = prefixes[sec][DECL_ONE_ONLY (decl)];
@@ -10940,13 +10966,19 @@ rs6000_unique_section (decl, reloc)
DECL_SECTION_NAME (decl) = build_string (len, string);
}
+#undef SECCAT_RODATA
+#undef SECCAT_SDATA2
+#undef SECCAT_DATA
+#undef SECCAT_SDATA
+#undef SECCAT_BSS
+#undef SECCAT_SBSS
+#undef SECCAT_TEXT
static bool
rs6000_binds_local_p (exp)
tree exp;
{
bool local_p;
- tree attr;
/* A non-decl is an entry in the constant pool. */
if (!DECL_P (exp))
@@ -11438,20 +11470,6 @@ toc_section ()
#endif /* TARGET_MACHO */
#if TARGET_ELF
-static unsigned int
-rs6000_elf_section_type_flags (decl, name, reloc)
- tree decl;
- const char *name;
- int reloc;
-{
- unsigned int flags = default_section_type_flags (decl, name, reloc);
-
- if (TARGET_RELOCATABLE)
- flags |= SECTION_WRITE;
-
- return flags;
-}
-
/* Record an element in the table of global constructors. SYMBOL is
a SYMBOL_REF of the function to be called; PRIORITY is a number
between 0 and MAX_INIT_PRIORITY.
Index: gcc/config/rs6000/sysv4.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/sysv4.h,v
retrieving revision 1.84.2.3.4.4
diff -u -p -r1.84.2.3.4.4 sysv4.h
--- gcc/config/rs6000/sysv4.h 30 Jan 2003 14:03:42 -0000 1.84.2.3.4.4
+++ gcc/config/rs6000/sysv4.h 7 Feb 2003 01:17:33 -0000
@@ -584,6 +584,12 @@ fini_section () \
#undef UNIQUE_SECTION
#define UNIQUE_SECTION(DECL, RELOC) rs6000_unique_section (DECL, RELOC)
+/* Decide whether DECL needs to be in a writable section. RELOC is the same
+ as for SELECT_SECTION. */
+
+#undef DECL_READONLY_SECTION
+#define DECL_READONLY_SECTION(DECL,RELOC) rs6000_readonly_section (DECL, RELOC)
+
/* Return non-zero if this entry is to be written into the constant pool
in a special way. We do so if this is a SYMBOL_REF, LABEL_REF or a CONST
containing one of them. If -mfp-in-toc (the default), we also do
--
Alan Modra
IBM OzLabs - Linux Technology Centre
Attachment:
dictionary_processed.cc.gz
Description: application/gunzip
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |