aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2007-03-09 16:53:09 -0800
committerRichard Henderson <rth@gcc.gnu.org>2007-03-09 16:53:09 -0800
commit9b580a0b53a3e81eef0656670c4a4a09a5683b42 (patch)
treeddb930f60eed9d2395dd9b4695e612928d440a18
parentb22eec88d248d584189d02ff7cc0e199ed7206f6 (diff)
downloadgcc-9b580a0b53a3e81eef0656670c4a4a09a5683b42.zip
gcc-9b580a0b53a3e81eef0656670c4a4a09a5683b42.tar.gz
gcc-9b580a0b53a3e81eef0656670c4a4a09a5683b42.tar.bz2
re PR target/26090 (IA-64 creates DT_TEXTREL binaries)
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. From-SVN: r122781
-rw-r--r--gcc/ChangeLog46
-rw-r--r--gcc/config/alpha/alpha.c10
-rw-r--r--gcc/config/i386/i386.c4
-rw-r--r--gcc/config/ia64/hpux.h11
-rw-r--r--gcc/config/ia64/ia64.c62
-rw-r--r--gcc/config/ia64/sysv4.h2
-rw-r--r--gcc/config/rs6000/rs6000.c58
-rw-r--r--gcc/config/rs6000/sysv4.h8
-rw-r--r--gcc/config/rs6000/xcoff.h3
-rw-r--r--gcc/doc/tm.texi12
-rw-r--r--gcc/output.h14
-rw-r--r--gcc/target-def.h7
-rw-r--r--gcc/target.h8
-rw-r--r--gcc/targhooks.c11
-rw-r--r--gcc/targhooks.h1
-rw-r--r--gcc/varasm.c135
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 <rth@redhat.com>
+
+ 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 <roger@eyesopen.com>
* 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 <sje@cup.hp.com> and
Reva Cuthbertson <reva@cup.hp.com>
@@ -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 <wilson@cygnus.com> and
David Mosberger <davidm@hpl.hp.com>.
@@ -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);
}