+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
#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. */
#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
{
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";
/* 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:
/* 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>
/* 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
/* 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>.
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;
glibc doesn't have them. */
}
\f
+/* 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. */
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)
{
|| 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;
}
} 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
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)
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);
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);
-}
\f
/* For a SYMBOL_REF, set generic flags and then perform some
target-specific processing.
#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
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)
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;
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)
/* 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.
/* 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
#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. */
/* 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.
#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
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
/* 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. */
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);
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,
/* 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
#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
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, \
/* 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
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.
/* 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.
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"
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);
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
}
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;
|| 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
}
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;
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:
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. */
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.";
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);
}