From 4e151b05f8a87e819f4c0f74fb6dbccc1c6e3f4d Mon Sep 17 00:00:00 2001 From: rth Date: Sat, 10 Mar 2007 00:53:09 +0000 Subject: [PATCH] PR target/26090 * target.h (targetm.asm.out.reloc_rw_mask): New. * target-def.h (TARGET_ASM_RELOC_RW_MASK): New. (TARGET_ASM_OUT): Use it. * targhooks.c, targhooks.h (default_reloc_rw_mask): New. * varasm.c (categorize_decl_for_section): Remove shlib argument; use the new reloc_rw_mask target hook instead. (default_section_type_flags_1): Merge into... (default_section_type_flags): ... here. (decl_readonly_section_1): Merge into... (decl_readonly_section): ... here. (default_elf_select_section_1): Merge into... (default_elf_select_section): ... here. (default_unique_section_1): Merge into... (default_unique_section): ... here. (compute_reloc_for_rtx_1, compute_reloc_for_rtx): New. (default_select_rtx_section): Use it. (default_elf_select_rtx_section): Likewise. * output.h: Update to match. * doc/tm.texi (TARGET_ASM_RELOC_RW_MASK): New. * config/alpha/alpha.c (alpha_elf_reloc_rw_mask): New. (TARGET_ASM_RELOC_RW_MASK): New. * config/i386/i386.c (x86_64_elf_select_section): Adjust call to categorize_decl_for_section. (x86_64_elf_unique_section): Likewise. * config/ia64/hpux.h (TARGET_ASM_SELECT_SECTION, TARGET_ASM_UNIQUE_SECTION, TARGET_ASM_SELECT_RTX_SECTION): Remove. (TARGET_ASM_RELOC_RW_MASK): New. * config/ia64/ia64.c (ia64_rwreloc_select_section, ia64_rwreloc_unique_section, ia64_rwreloc_select_rtx_section): Remove. (ia64_hpux_reloc_rw_mask, ia64_reloc_rw_mask): New. (TARGET_RWRELOC): Remove. (ia64_section_type_flags): Adjust call to default_section_type_flags. * config/ia64/sysv4.h (TARGET_ASM_RELOC_RW_MASK): New. * config/rs6000/rs6000.c (rs6000_elf_section_type_flags): Remove. (rs6000_elf_select_section, rs6000_elf_unique_section): Remove. (rs6000_elf_reloc_rw_mask, rs6000_xcoff_reloc_rw_mask): New. (rs6000_xcoff_select_section): Use decl_readonly_section. (rs6000_xcoff_section_type_flags): Use default_section_type_flags. * config/rs6000/sysv4.h (TARGET_ASM_RELOC_RW_MASK): New. (TARGET_ASM_SELECT_SECTION, TARGET_ASM_UNIQUE_SECTION): Remove. (TARGET_SECTION_TYPE_FLAGS): Remove. * config/rs6000/xcoff.h (TARGET_ASM_RELOC_RW_MASK): New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@122781 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 46 +++++++++++++++ gcc/config/alpha/alpha.c | 10 ++++ gcc/config/i386/i386.c | 4 +- gcc/config/ia64/hpux.h | 11 +--- gcc/config/ia64/ia64.c | 62 ++++++++------------- gcc/config/ia64/sysv4.h | 2 + gcc/config/rs6000/rs6000.c | 58 ++++++------------- gcc/config/rs6000/sysv4.h | 8 +-- gcc/config/rs6000/xcoff.h | 3 +- gcc/doc/tm.texi | 12 ++++ gcc/output.h | 14 +---- gcc/target-def.h | 7 ++- gcc/target.h | 8 ++- gcc/targhooks.c | 11 +++- gcc/targhooks.h | 1 + gcc/varasm.c | 135 +++++++++++++++++++++++---------------------- 16 files changed, 217 insertions(+), 175 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1cfe8e3..2ca30ef 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,49 @@ +2007-03-09 Richard Henderson + + PR target/26090 + * target.h (targetm.asm.out.reloc_rw_mask): New. + * target-def.h (TARGET_ASM_RELOC_RW_MASK): New. + (TARGET_ASM_OUT): Use it. + * targhooks.c, targhooks.h (default_reloc_rw_mask): New. + * varasm.c (categorize_decl_for_section): Remove shlib argument; + use the new reloc_rw_mask target hook instead. + (default_section_type_flags_1): Merge into... + (default_section_type_flags): ... here. + (decl_readonly_section_1): Merge into... + (decl_readonly_section): ... here. + (default_elf_select_section_1): Merge into... + (default_elf_select_section): ... here. + (default_unique_section_1): Merge into... + (default_unique_section): ... here. + (compute_reloc_for_rtx_1, compute_reloc_for_rtx): New. + (default_select_rtx_section): Use it. + (default_elf_select_rtx_section): Likewise. + * output.h: Update to match. + * doc/tm.texi (TARGET_ASM_RELOC_RW_MASK): New. + * config/alpha/alpha.c (alpha_elf_reloc_rw_mask): New. + (TARGET_ASM_RELOC_RW_MASK): New. + * config/i386/i386.c (x86_64_elf_select_section): Adjust call + to categorize_decl_for_section. + (x86_64_elf_unique_section): Likewise. + * config/ia64/hpux.h (TARGET_ASM_SELECT_SECTION, + TARGET_ASM_UNIQUE_SECTION, TARGET_ASM_SELECT_RTX_SECTION): Remove. + (TARGET_ASM_RELOC_RW_MASK): New. + * config/ia64/ia64.c (ia64_rwreloc_select_section, + ia64_rwreloc_unique_section, ia64_rwreloc_select_rtx_section): Remove. + (ia64_hpux_reloc_rw_mask, ia64_reloc_rw_mask): New. + (TARGET_RWRELOC): Remove. + (ia64_section_type_flags): Adjust call to default_section_type_flags. + * config/ia64/sysv4.h (TARGET_ASM_RELOC_RW_MASK): New. + * config/rs6000/rs6000.c (rs6000_elf_section_type_flags): Remove. + (rs6000_elf_select_section, rs6000_elf_unique_section): Remove. + (rs6000_elf_reloc_rw_mask, rs6000_xcoff_reloc_rw_mask): New. + (rs6000_xcoff_select_section): Use decl_readonly_section. + (rs6000_xcoff_section_type_flags): Use default_section_type_flags. + * config/rs6000/sysv4.h (TARGET_ASM_RELOC_RW_MASK): New. + (TARGET_ASM_SELECT_SECTION, TARGET_ASM_UNIQUE_SECTION): Remove. + (TARGET_SECTION_TYPE_FLAGS): Remove. + * config/rs6000/xcoff.h (TARGET_ASM_RELOC_RW_MASK): New. + 2007-03-09 Roger Sayle * fold-const.c (fold_comparison): Remove compile-time evaluation of diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index ae00e1c..e6ea03f 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -9320,6 +9320,14 @@ alpha_file_start (void) #endif #ifdef OBJECT_FORMAT_ELF +/* Since we don't have a .dynbss section, we should not allow global + relocations in the .rodata section. */ + +static int +alpha_elf_reloc_rw_mask (void) +{ + return flag_pic ? 3 : 2; +} /* Return a section for X. The only special thing we do here is to honor small data. */ @@ -10568,6 +10576,8 @@ alpha_init_libfuncs (void) #endif #ifdef OBJECT_FORMAT_ELF +#undef TARGET_ASM_RELOC_RW_MASK +#define TARGET_ASM_RELOC_RW_MASK alpha_elf_reloc_rw_mask #undef TARGET_ASM_SELECT_RTX_SECTION #define TARGET_ASM_SELECT_RTX_SECTION alpha_elf_select_rtx_section #endif diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 70fd96c..469d909 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -2509,7 +2509,7 @@ x86_64_elf_select_section (tree decl, int reloc, { const char *sname = NULL; unsigned int flags = SECTION_WRITE; - switch (categorize_decl_for_section (decl, reloc, flag_pic)) + switch (categorize_decl_for_section (decl, reloc)) { case SECCAT_DATA: sname = ".ldata"; @@ -2576,7 +2576,7 @@ x86_64_elf_unique_section (tree decl, int reloc) /* We only need to use .gnu.linkonce if we don't have COMDAT groups. */ bool one_only = DECL_ONE_ONLY (decl) && !HAVE_COMDAT_GROUP; - switch (categorize_decl_for_section (decl, reloc, flag_pic)) + switch (categorize_decl_for_section (decl, reloc)) { case SECCAT_DATA: case SECCAT_DATA_REL: diff --git a/gcc/config/ia64/hpux.h b/gcc/config/ia64/hpux.h index 186f339..bdf3968 100644 --- a/gcc/config/ia64/hpux.h +++ b/gcc/config/ia64/hpux.h @@ -1,5 +1,5 @@ /* Definitions of target machine GNU compiler. IA-64 version. - Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 + Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc. Contributed by Steve Ellcey and Reva Cuthbertson @@ -174,13 +174,8 @@ do { \ /* It is illegal to have relocations in shared segments on HPUX. Pretend flag_pic is always set. */ -#undef TARGET_ASM_SELECT_SECTION -#define TARGET_ASM_SELECT_SECTION ia64_rwreloc_select_section -#undef TARGET_ASM_UNIQUE_SECTION -#define TARGET_ASM_UNIQUE_SECTION ia64_rwreloc_unique_section -#undef TARGET_ASM_SELECT_RTX_SECTION -#define TARGET_ASM_SELECT_RTX_SECTION ia64_rwreloc_select_rtx_section -#define TARGET_RWRELOC true +#undef TARGET_ASM_RELOC_RW_MASK +#define TARGET_ASM_RELOC_RW_MASK ia64_hpux_reloc_rw_mask /* ia64 HPUX has the float and long double forms of math functions. */ #undef TARGET_C99_FUNCTIONS diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index f1dbfc3..dc10abb 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -1,5 +1,5 @@ /* Definitions of target machine for GNU compiler. - Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. Contributed by James E. Wilson and David Mosberger . @@ -244,17 +244,12 @@ static void ia64_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, static void ia64_file_start (void); static void ia64_globalize_decl_name (FILE *, tree); +static int ia64_hpux_reloc_rw_mask (void) ATTRIBUTE_UNUSED; +static int ia64_reloc_rw_mask (void) ATTRIBUTE_UNUSED; static section *ia64_select_rtx_section (enum machine_mode, rtx, unsigned HOST_WIDE_INT); static void ia64_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED; -static section *ia64_rwreloc_select_section (tree, int, unsigned HOST_WIDE_INT) - ATTRIBUTE_UNUSED; -static void ia64_rwreloc_unique_section (tree, int) - ATTRIBUTE_UNUSED; -static section *ia64_rwreloc_select_rtx_section (enum machine_mode, rtx, - unsigned HOST_WIDE_INT) - ATTRIBUTE_UNUSED; static unsigned int ia64_section_type_flags (tree, const char *, int); static void ia64_init_libfuncs (void) ATTRIBUTE_UNUSED; @@ -9374,6 +9369,24 @@ ia64_sysv4_init_libfuncs (void) glibc doesn't have them. */ } +/* For HPUX, it is illegal to have relocations in shared segments. */ + +static int +ia64_hpux_reloc_rw_mask (void) +{ + return 3; +} + +/* For others, relax this so that relocations to local data goes in + read-only segments, but we still cannot allow global relocations + in read-only segments. */ + +static int +ia64_reloc_rw_mask (void) +{ + return flag_pic ? 3 : 2; +} + /* Return the section to use for X. The only special thing we do here is to honor small data. */ @@ -9389,37 +9402,6 @@ ia64_select_rtx_section (enum machine_mode mode, rtx x, return default_elf_select_rtx_section (mode, x, align); } -/* It is illegal to have relocations in shared segments on AIX and HPUX. - Pretend flag_pic is always set. */ - -static section * -ia64_rwreloc_select_section (tree exp, int reloc, unsigned HOST_WIDE_INT align) -{ - return default_elf_select_section_1 (exp, reloc, align, true); -} - -static void -ia64_rwreloc_unique_section (tree decl, int reloc) -{ - default_unique_section_1 (decl, reloc, true); -} - -static section * -ia64_rwreloc_select_rtx_section (enum machine_mode mode, rtx x, - unsigned HOST_WIDE_INT align) -{ - section *sect; - int save_pic = flag_pic; - flag_pic = 1; - sect = ia64_select_rtx_section (mode, x, align); - flag_pic = save_pic; - return sect; -} - -#ifndef TARGET_RWRELOC -#define TARGET_RWRELOC flag_pic -#endif - static unsigned int ia64_section_type_flags (tree decl, const char *name, int reloc) { @@ -9435,7 +9417,7 @@ ia64_section_type_flags (tree decl, const char *name, int reloc) || strncmp (name, ".gnu.linkonce.sb.", 17) == 0) flags = SECTION_SMALL; - flags |= default_section_type_flags_1 (decl, name, reloc, TARGET_RWRELOC); + flags |= default_section_type_flags (decl, name, reloc); return flags; } diff --git a/gcc/config/ia64/sysv4.h b/gcc/config/ia64/sysv4.h index 5e93d4c..0e03e7d 100644 --- a/gcc/config/ia64/sysv4.h +++ b/gcc/config/ia64/sysv4.h @@ -121,6 +121,8 @@ do { \ } while (0) /* Override default elf definition. */ +#undef TARGET_ASM_RELOC_RW_MASK +#define TARGET_ASM_RELOC_RW_MASK ia64_reloc_rw_mask #undef TARGET_ASM_SELECT_RTX_SECTION #define TARGET_ASM_SELECT_RTX_SECTION ia64_select_rtx_section diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index fd1b835..d80d061 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -656,13 +656,11 @@ static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT); static bool rs6000_return_in_memory (tree, tree); static void rs6000_file_start (void); #if TARGET_ELF -static unsigned int rs6000_elf_section_type_flags (tree, const char *, int); +static int rs6000_elf_reloc_rw_mask (void); static void rs6000_elf_asm_out_constructor (rtx, int); static void rs6000_elf_asm_out_destructor (rtx, int); static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED; static void rs6000_elf_asm_init_sections (void); -static section *rs6000_elf_select_section (tree, int, unsigned HOST_WIDE_INT); -static void rs6000_elf_unique_section (tree, int); static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx, unsigned HOST_WIDE_INT); static void rs6000_elf_encode_section_info (tree, rtx, int) @@ -673,6 +671,7 @@ static bool rs6000_use_blocks_for_constant_p (enum machine_mode, rtx); static void rs6000_xcoff_asm_output_anchor (rtx); static void rs6000_xcoff_asm_globalize_label (FILE *, const char *); static void rs6000_xcoff_asm_init_sections (void); +static int rs6000_xcoff_reloc_rw_mask (void); static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree); static section *rs6000_xcoff_select_section (tree, int, unsigned HOST_WIDE_INT); @@ -18928,37 +18927,6 @@ rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x, else return default_elf_select_rtx_section (mode, x, align); } - -/* Implement TARGET_ASM_SELECT_SECTION for ELF targets. */ - -static section * -rs6000_elf_select_section (tree decl, int reloc, - unsigned HOST_WIDE_INT align) -{ - /* Pretend that we're always building for a shared library when - ABI_AIX, because otherwise we end up with dynamic relocations - in read-only sections. This happens for function pointers, - references to vtables in typeinfo, and probably other cases. */ - return default_elf_select_section_1 (decl, reloc, align, - flag_pic || DEFAULT_ABI == ABI_AIX); -} - -/* A C statement to build up a unique section name, expressed as a - STRING_CST node, and assign it to DECL_SECTION_NAME (decl). - RELOC indicates whether the initial value of EXP requires - link-time relocations. If you do not define this macro, GCC will use - the symbol name prefixed by `.' as the section name. Note - this - macro can now be called for uninitialized data items as well as - initialized data and functions. */ - -static void -rs6000_elf_unique_section (tree decl, int reloc) -{ - /* As above, pretend that we're always building for a shared library - when ABI_AIX, to avoid dynamic relocations in read-only sections. */ - default_unique_section_1 (decl, reloc, - flag_pic || DEFAULT_ABI == ABI_AIX); -} /* For a SYMBOL_REF, set generic flags and then perform some target-specific processing. @@ -19437,11 +19405,15 @@ rs6000_darwin_file_start (void) #endif /* TARGET_MACHO */ #if TARGET_ELF -static unsigned int -rs6000_elf_section_type_flags (tree decl, const char *name, int reloc) +static int +rs6000_elf_reloc_rw_mask (void) { - return default_section_type_flags_1 (decl, name, reloc, - flag_pic || DEFAULT_ABI == ABI_AIX); + if (flag_pic) + return 3; + else if (DEFAULT_ABI == ABI_AIX) + return 2; + else + return 0; } /* Record an element in the table of global constructors. SYMBOL is @@ -19679,6 +19651,12 @@ rs6000_xcoff_asm_init_sections (void) exception_section = data_section; } +static int +rs6000_xcoff_reloc_rw_mask (void) +{ + return 3; +} + static void rs6000_xcoff_asm_named_section (const char *name, unsigned int flags, tree decl ATTRIBUTE_UNUSED) @@ -19702,7 +19680,7 @@ static section * rs6000_xcoff_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED) { - if (decl_readonly_section_1 (decl, reloc, 1)) + if (decl_readonly_section (decl, reloc)) { if (TREE_PUBLIC (decl)) return read_only_data_section; @@ -19774,7 +19752,7 @@ static unsigned int rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc) { unsigned int align; - unsigned int flags = default_section_type_flags_1 (decl, name, reloc, 1); + unsigned int flags = default_section_type_flags (decl, name, reloc); /* Align to at least UNIT size. */ if (flags & SECTION_CODE) diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h index d7c1002..0b1eb1e 100644 --- a/gcc/config/rs6000/sysv4.h +++ b/gcc/config/rs6000/sysv4.h @@ -1,6 +1,6 @@ /* Target definitions for GNU compiler for PowerPC running System V.4 Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, - 2004, 2005, 2006 Free Software Foundation, Inc. + 2004, 2005, 2006, 2007 Free Software Foundation, Inc. Contributed by Cygnus Support. This file is part of GCC. @@ -364,11 +364,10 @@ do { \ /* Override default elf definitions. */ #define TARGET_ASM_INIT_SECTIONS rs6000_elf_asm_init_sections +#undef TARGET_ASM_RELOC_RW_MASK +#define TARGET_ASM_RELOC_RW_MASK rs6000_elf_reloc_rw_mask #undef TARGET_ASM_SELECT_RTX_SECTION #define TARGET_ASM_SELECT_RTX_SECTION rs6000_elf_select_rtx_section -#undef TARGET_ASM_SELECT_SECTION -#define TARGET_ASM_SELECT_SECTION rs6000_elf_select_section -#define TARGET_ASM_UNIQUE_SECTION rs6000_elf_unique_section /* Return nonzero 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 @@ -533,7 +532,6 @@ extern int fixuplabelno; #define TARGET_ENCODE_SECTION_INFO rs6000_elf_encode_section_info #define TARGET_IN_SMALL_DATA_P rs6000_elf_in_small_data_p -#define TARGET_SECTION_TYPE_FLAGS rs6000_elf_section_type_flags /* The ELF version doesn't encode [DS] or whatever at the end of symbols. */ diff --git a/gcc/config/rs6000/xcoff.h b/gcc/config/rs6000/xcoff.h index 6a95465..ebf79b5 100644 --- a/gcc/config/rs6000/xcoff.h +++ b/gcc/config/rs6000/xcoff.h @@ -1,6 +1,6 @@ /* Definitions of target machine for GNU compiler, for some generic XCOFF file format - Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2001, 2002, 2003, 2004, 2007 Free Software Foundation, Inc. This file is part of GCC. @@ -88,6 +88,7 @@ #define TARGET_ASM_OUTPUT_ANCHOR rs6000_xcoff_asm_output_anchor #define TARGET_ASM_GLOBALIZE_LABEL rs6000_xcoff_asm_globalize_label #define TARGET_ASM_INIT_SECTIONS rs6000_xcoff_asm_init_sections +#define TARGET_ASM_RELOC_RW_MASK rs6000_xcoff_reloc_rw_mask #define TARGET_ASM_NAMED_SECTION rs6000_xcoff_asm_named_section #define TARGET_ASM_SELECT_SECTION rs6000_xcoff_select_section #define TARGET_ASM_SELECT_RTX_SECTION rs6000_xcoff_select_rtx_section diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index c5920d0..ac09e4e 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -6397,6 +6397,18 @@ any assembly code, and before calling any of the section-returning hooks described below. @end deftypefn +@deftypefn {Target Hook} TARGET_ASM_RELOC_RW_MASK (void) +Return a mask describing how relocations should be treated when +selecting sections. Bit 1 should be set if global relocations +should be placed in a read-write section; bit 0 should be set if +local relocations should be placed in a read-write section. + +The default version of this function returns 3 when @option{-fpic} +is in effect, and 0 otherwise. The hook is typically redefined +when the target cannot support (some kinds of) dynamic relocations +in read-only sections even in executables. +@end deftypefn + @deftypefn {Target Hook} {section *} TARGET_ASM_SELECT_SECTION (tree @var{exp}, int @var{reloc}, unsigned HOST_WIDE_INT @var{align}) Return the section into which @var{exp} should be placed. You can assume that @var{exp} is either a @code{VAR_DECL} node or a constant of diff --git a/gcc/output.h b/gcc/output.h index a5c29f0d..4cb41d4f 100644 --- a/gcc/output.h +++ b/gcc/output.h @@ -383,7 +383,6 @@ extern bool first_function_block_is_cold; /* Decide whether DECL needs to be in a writable section. RELOC is the same as for SELECT_SECTION. */ extern bool decl_readonly_section (tree, int); -extern bool decl_readonly_section_1 (tree, int, int); /* This can be used to compute RELOC for the function above, when given a constant expression. */ @@ -580,12 +579,11 @@ extern void switch_to_section (section *); extern void output_section_asm_op (const void *); extern unsigned int default_section_type_flags (tree, const char *, int); -extern unsigned int default_section_type_flags_1 (tree, const char *, int, int); extern bool have_global_bss_p (void); extern void default_no_named_section (const char *, unsigned int, tree); extern void default_elf_asm_named_section (const char *, unsigned int, tree); -extern enum section_category categorize_decl_for_section (tree, int, int); +extern enum section_category categorize_decl_for_section (tree, int); extern void default_coff_asm_named_section (const char *, unsigned int, tree); extern void default_pe_asm_named_section (const char *, unsigned int, tree); @@ -596,15 +594,9 @@ extern void default_stabs_asm_out_constructor (rtx, int); extern void default_named_section_asm_out_constructor (rtx, int); extern void default_ctor_section_asm_out_constructor (rtx, int); -extern section *default_select_section (tree, int, - unsigned HOST_WIDE_INT); -extern section *default_elf_select_section (tree, int, - unsigned HOST_WIDE_INT); -extern section *default_elf_select_section_1 (tree, int, - unsigned HOST_WIDE_INT, - int); +extern section *default_select_section (tree, int, unsigned HOST_WIDE_INT); +extern section *default_elf_select_section (tree, int, unsigned HOST_WIDE_INT); extern void default_unique_section (tree, int); -extern void default_unique_section_1 (tree, int, int); extern section *default_function_rodata_section (tree); extern section *default_no_function_rodata_section (tree); extern section *default_select_rtx_section (enum machine_mode, rtx, diff --git a/gcc/target-def.h b/gcc/target-def.h index fb9af5a..3a17c12 100644 --- a/gcc/target-def.h +++ b/gcc/target-def.h @@ -1,5 +1,5 @@ /* Default initializers for a generic GCC target. - Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it @@ -97,6 +97,10 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #define TARGET_ASM_FUNCTION_END_PROLOGUE no_asm_to_stream #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE no_asm_to_stream +#ifndef TARGET_ASM_RELOC_RW_MASK +#define TARGET_ASM_RELOC_RW_MASK default_reloc_rw_mask +#endif + #ifndef TARGET_ASM_SELECT_SECTION #define TARGET_ASM_SELECT_SECTION default_select_section #endif @@ -271,6 +275,7 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. TARGET_ASM_FUNCTION_EPILOGUE, \ TARGET_ASM_INIT_SECTIONS, \ TARGET_ASM_NAMED_SECTION, \ + TARGET_ASM_RELOC_RW_MASK, \ TARGET_ASM_SELECT_SECTION, \ TARGET_ASM_SELECT_RTX_SECTION, \ TARGET_ASM_UNIQUE_SECTION, \ diff --git a/gcc/target.h b/gcc/target.h index 029d183..476eb88 100644 --- a/gcc/target.h +++ b/gcc/target.h @@ -1,5 +1,5 @@ /* Data structure definitions for a generic GCC target. - Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it @@ -162,6 +162,12 @@ struct gcc_target which this section is associated. */ void (* named_section) (const char *name, unsigned int flags, tree decl); + /* Return a mask describing how relocations should be treated when + selecting sections. Bit 1 should be set if global relocations + should be placed in a read-write section; bit 0 should be set if + local relocations should be placed in a read-write section. */ + int (*reloc_rw_mask) (void); + /* Return a section for EXP. It may be a DECL or a constant. RELOC is nonzero if runtime relocations must be applied; bit 1 will be set if the runtime relocations require non-local name resolution. diff --git a/gcc/targhooks.c b/gcc/targhooks.c index f1e4637..baad65b 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -1,5 +1,5 @@ /* Default target hook functions. - Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation, Inc. This file is part of GCC. @@ -622,4 +622,13 @@ default_handle_c_option (size_t code ATTRIBUTE_UNUSED, return false; } +/* By default, if flag_pic is true, then neither local nor global relocs + should be placed in readonly memory. */ + +int +default_reloc_rw_mask (void) +{ + return flag_pic ? 3 : 0; +} + #include "gt-targhooks.h" diff --git a/gcc/targhooks.h b/gcc/targhooks.h index 33b5348..062d4f0 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -83,3 +83,4 @@ extern enum reg_class default_secondary_reload (bool, rtx, enum reg_class, secondary_reload_info *); extern void hook_void_bitmap (bitmap); extern bool default_handle_c_option (size_t, const char *, int); +extern int default_reloc_rw_mask (void); diff --git a/gcc/varasm.c b/gcc/varasm.c index 7e482b3..cf880e8 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -5537,18 +5537,11 @@ decl_default_tls_model (tree decl) unsigned int default_section_type_flags (tree decl, const char *name, int reloc) { - return default_section_type_flags_1 (decl, name, reloc, flag_pic); -} - -unsigned int -default_section_type_flags_1 (tree decl, const char *name, int reloc, - int shlib) -{ unsigned int flags; if (decl && TREE_CODE (decl) == FUNCTION_DECL) flags = SECTION_CODE; - else if (decl && decl_readonly_section_1 (decl, reloc, shlib)) + else if (decl && decl_readonly_section (decl, reloc)) flags = 0; else if (current_function_decl && cfun @@ -5748,7 +5741,7 @@ default_select_section (tree decl, int reloc, } enum section_category -categorize_decl_for_section (tree decl, int reloc, int shlib) +categorize_decl_for_section (tree decl, int reloc) { enum section_category ret; @@ -5769,17 +5762,17 @@ categorize_decl_for_section (tree decl, int reloc, int shlib) || TREE_SIDE_EFFECTS (decl) || ! TREE_CONSTANT (DECL_INITIAL (decl))) { - if (shlib && (reloc & 2)) - ret = SECCAT_DATA_REL; - else if (shlib && reloc) - ret = SECCAT_DATA_REL_LOCAL; + /* 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 (reloc & targetm.asm_out.reloc_rw_mask ()) + ret = reloc == 1 ? SECCAT_DATA_REL_LOCAL : SECCAT_DATA_REL; else ret = SECCAT_DATA; } - else if (shlib && (reloc & 2)) - ret = SECCAT_DATA_REL_RO; - else if (shlib && reloc) - ret = SECCAT_DATA_REL_RO_LOCAL; + 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 location. -fmerge-all-constants allows even that (at the @@ -5792,7 +5785,7 @@ categorize_decl_for_section (tree decl, int reloc, int shlib) } else if (TREE_CODE (decl) == CONSTRUCTOR) { - if ((shlib && reloc) + if ((reloc & targetm.asm_out.reloc_rw_mask ()) || TREE_SIDE_EFFECTS (decl) || ! TREE_CONSTANT (decl)) ret = SECCAT_DATA; @@ -5832,13 +5825,7 @@ categorize_decl_for_section (tree decl, int reloc, int shlib) bool decl_readonly_section (tree decl, int reloc) { - return decl_readonly_section_1 (decl, reloc, flag_pic); -} - -bool -decl_readonly_section_1 (tree decl, int reloc, int shlib) -{ - switch (categorize_decl_for_section (decl, reloc, shlib)) + switch (categorize_decl_for_section (decl, reloc)) { case SECCAT_RODATA: case SECCAT_RODATA_MERGE_STR: @@ -5859,15 +5846,8 @@ section * default_elf_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align) { - return default_elf_select_section_1 (decl, reloc, align, flag_pic); -} - -section * -default_elf_select_section_1 (tree decl, int reloc, - unsigned HOST_WIDE_INT align, int shlib) -{ const char *sname; - switch (categorize_decl_for_section (decl, reloc, shlib)) + switch (categorize_decl_for_section (decl, reloc)) { case SECCAT_TEXT: /* We're not supposed to be called on FUNCTION_DECLs. */ @@ -5929,19 +5909,13 @@ default_elf_select_section_1 (tree decl, int reloc, void default_unique_section (tree decl, int reloc) { - default_unique_section_1 (decl, reloc, flag_pic); -} - -void -default_unique_section_1 (tree decl, int reloc, int shlib) -{ /* We only need to use .gnu.linkonce if we don't have COMDAT groups. */ bool one_only = DECL_ONE_ONLY (decl) && !HAVE_COMDAT_GROUP; const char *prefix, *name; size_t nlen, plen; char *string; - switch (categorize_decl_for_section (decl, reloc, shlib)) + switch (categorize_decl_for_section (decl, reloc)) { case SECCAT_TEXT: prefix = one_only ? ".gnu.linkonce.t." : ".text."; @@ -6002,45 +5976,76 @@ default_unique_section_1 (tree decl, int reloc, int shlib) DECL_SECTION_NAME (decl) = build_string (nlen + plen, string); } +/* Like compute_reloc_for_constant, except for an RTX. The return value + is a mask for which bit 1 indicates a global relocation, and bit 0 + indicates a local relocation. */ + +static int +compute_reloc_for_rtx_1 (rtx *xp, void *data) +{ + int *preloc = data; + rtx x = *xp; + + switch (GET_CODE (x)) + { + case SYMBOL_REF: + *preloc |= SYMBOL_REF_LOCAL_P (x) ? 1 : 2; + break; + case LABEL_REF: + *preloc |= 1; + break; + default: + break; + } + + return 0; +} + +static int +compute_reloc_for_rtx (rtx x) +{ + int reloc; + + switch (GET_CODE (x)) + { + case CONST: + case SYMBOL_REF: + case LABEL_REF: + reloc = 0; + for_each_rtx (&x, compute_reloc_for_rtx_1, &reloc); + return reloc; + + default: + return 0; + } +} + section * default_select_rtx_section (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x, unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED) { - if (flag_pic) - switch (GET_CODE (x)) - { - case CONST: - case SYMBOL_REF: - case LABEL_REF: - return data_section; - - default: - break; - } - - return readonly_data_section; + if (compute_reloc_for_rtx (x) & targetm.asm_out.reloc_rw_mask ()) + return data_section; + else + return readonly_data_section; } section * default_elf_select_rtx_section (enum machine_mode mode, rtx x, unsigned HOST_WIDE_INT align) { - /* ??? Handle small data here somehow. */ + int reloc = compute_reloc_for_rtx (x); - if (flag_pic) - switch (GET_CODE (x)) - { - case CONST: - case SYMBOL_REF: - return get_named_section (NULL, ".data.rel.ro", 3); + /* ??? Handle small data here somehow. */ - case LABEL_REF: + if (reloc & targetm.asm_out.reloc_rw_mask ()) + { + if (reloc == 1) return get_named_section (NULL, ".data.rel.ro.local", 1); - - default: - break; - } + else + return get_named_section (NULL, ".data.rel.ro", 3); + } return mergeable_constant_section (mode, align, 0); } -- 2.7.4