aboutsummaryrefslogtreecommitdiff
path: root/gcc/varasm.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2001-08-03 18:31:41 -0700
committerRichard Henderson <rth@gcc.gnu.org>2001-08-03 18:31:41 -0700
commit7c262518a45491adb8a04f5ec4006dbe957ab7a4 (patch)
treef3a177e73b80eca5619e6a8d303a81b56c901052 /gcc/varasm.c
parent4e627c414436df3de424b718f70576abab682e04 (diff)
downloadgcc-7c262518a45491adb8a04f5ec4006dbe957ab7a4.zip
gcc-7c262518a45491adb8a04f5ec4006dbe957ab7a4.tar.gz
gcc-7c262518a45491adb8a04f5ec4006dbe957ab7a4.tar.bz2
target.h (gcc_target): Add asm_out.named_section, section_type_flags, have_named_sections.
* target.h (gcc_target): Add asm_out.named_section, section_type_flags, have_named_sections. * target-def.h (TARGET_ASM_NAMED_SECTION): New. (TARGET_HAVE_NAMED_SECTIONS): New. (TARGET_SECTION_TYPE_FLAGS): New. * Makefile.in (toplev.o): Depend on TARGET_H. (varasm.o, dbxout.o): Likewise. * c-common.c (decl_attributes): Check targetm.have_named_sections instead of ifdef ASM_OUTPUT_SECTION_NAME. * dbxout.c (dbxout_function_decl): Likewise. (dbxout_function_end): Likewise. * toplev.c (compile_file): Likewise. * varasm.c (exception_section): Likewise. * cp/decl2.c (finish_objects): Likewise. * defaults.h (EH_FRAME_SECTION): Remove. (EH_FRAME_SECTION_ASM_OP): Remove. (EH_FRAME_SECTION_NAME): New. (UNIQUE_SECTION): Don't depend on ASM_OUTPUT_SECTION_NAME. (UNIQUE_SECTION_P): Remove. * dwarf2out.c (SECTION_FORMAT): Remove. (ASM_OUTPUT_SECTION): Remove. (output_call_frame_info): Use named_section_flags. (output_comp_unit, dwarf2out_start_source_file): Likewise. (dwarf2out_end_source_file, dwarf2out_define): Likewise. (dwarf2out_undef, dwarf2out_init, dwarf2out_finish): Likewise. * varasm.c (in_eh_frame, eh_frame_section): Remove. (named_section_flags): New. (named_section): Use it and targetm.section_type_flags. (resolve_unique_section): New. (assemble_start_function): Use it. (asm_emit_uninitialised, assemble_variable): Likewise. (default_section_type_flags): New. (default_no_named_section, default_elf_asm_named_section): New. (default_coff_asm_named_section, default_pe_asm_named_section): New. * output.h: Update varasm.c decls. (SECTION_*): New flags. * crtstuff.c: Check EH_FRAME_SECTION_NAME not EH_FRAME_SECTION_ASM_OP. (__EH_FRAME_BEGIN__, __FRAME_END__): Use attribute section. * config/elfos.h (UNIQUE_SECTION_P): Remove. * config/alpha/elf.h, config/arm/linux-elf.h: Likewise. * config/arm/pe.h, config/arm/unknown-elf.h: Likewise. * config/i386/cygwin.h, config/i386/djgpp.h: Likewise. * config/i386/i386-interix.h, config/i386/win32.h: Likewise. * config/ia64/sysv4.h, config/mcore/mcore-pe.h: Likewise. * config/mips/elf.h, config/mips/elf64.h: Likewise. * config/mips/iris6gld.h, config/mips/mips.h: Likewise. * config/pa/pa64-hpux.h, * config/elfos.h (ASM_OUTPUT_SECTION_NAME): Remove. (TARGET_ASM_NAMED_SECTION): New. * config/psos.h, config/a29k/a29k.h, config/alpha/elf.h: Likewise. * config/alpha/vms.h, config/arm/coff.h: Likewise. * config/arm/conix-elf.h, config/arm/elf.h: Likewise. * config/arm/linux-elf.h, config/arm/pe.h: Likewise. * config/arm/unknown-elf.h, config/avr/avr.h: Likewise. * config/c4x/c4x.h, config/h8300/h8300.h: Likewise. * config/i386/cygwin.h, config/i386/djgpp.h: Likewise. * config/i386/i386-interix.h, config/i386/i386elf.h : Likewise. * config/i386/sco5.h, config/i386/win32.h: Likewise. * config/m68k/coff.h, config/mcore/mcore-pe.h: Likewise. * config/mcore/mcore.h, config/mips/elf.h: Likewise. * config/mips/elf64.h, config/mips/iris6.h: Likewise. * config/mips/netbsd.h, config/mips/openbsd.h: Likewise. * config/pa/pa64-hpux.h, config/rs6000/sysv4.h: Likewise. * config/rs6000/xcoff.h, config/sh/sh.h: Likewise. * config/sparc/sysv4.h: Likewise. * config/nextstep.h: Error until named sections implemented. * config/a29k/a29k.c (a29k_asm_named_section): New. * config/alpha/alpha.c (SECTION_VMS_OVERLAY): New. (vms_section_type_flags, vms_asm_named_section): New. * config/arm/arm.c (arm_elf_asm_named_section): New. * config/avr/avr.c (asm_output_section_name): Remove. * config/avr/avr-protos.h: Update. * config/c4x/c4x.c (c4x_asm_named_section): New. * config/h8300/h8300.c (h8300_asm_named_section): New. * config/i386/i386.c (sco_asm_named_section): New. * config/i386/winnt.c (SECTION_PE_SHARED): New. (i386_pe_section_type_flags): New. (i386_pe_asm_named_section): New. * config/i386/i386-protos.h: Update. * config/m68k/m68k.c (m68k_coff_asm_named_section): New. * config/mcore/mcore.c (mcore_asm_named_section): New. * config/mips/mips.c (iris6_asm_named_section): New. * config/mips/mips.h (ENCODE_SECTION_INFO): Use DECL_ONE_ONLY instead of UNIQUE_SECTION_P. * config/rs6000/rs6000.c (rs6000_elf_section_type_flags): New. (xcoff_asm_named_section): New. * config/sh/sh.c (sh_asm_named_section): New. * config/sparc/sparc.c (sparc_elf_asm_named_section): New. * config/i386/djgpp.h (EH_FRAME_SECTION_ASM_OP): Remove. * config/i386/sco5.h (EH_FRAME_SECTION_ASM_OP*): Remove. (EH_FRAME_SECTION_NAME): New. (EXCEPTION_SECTION): New. * config/ia64/ia64.h (EH_FRAME_SECTION_ASM_OP): Remove. (DEBUG_*_SECTION): Remove. * config/m68k/rtemself.h (EH_FRAME_SECTION_ASM_OP): Remove. * config/mips/iris6.h (DEBUG_*_SECTION): Remove. (EH_FRAME_SECTION_ASM_OP): Remove. * doc/tm.texi (UNIQUE_SECTION_P): Remove. (ASM_OUTPUT_SECTION_NAME): Remove. (TARGET_ASM_NAMED_SECTION): New. (TARGET_HAVE_NAMED_SECTIONS): New. (TARGET_SECTION_TYPE_FLAGS): New. (EH_FRAME_SECTION_ASM_OP): Remove. (EH_FRAME_SECTION_NAME): New. From-SVN: r44623
Diffstat (limited to 'gcc/varasm.c')
-rw-r--r--gcc/varasm.c243
1 files changed, 188 insertions, 55 deletions
diff --git a/gcc/varasm.c b/gcc/varasm.c
index bb723c8..d574a80 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -46,6 +46,7 @@ Boston, MA 02111-1307, USA. */
#include "ggc.h"
#include "tm_p.h"
#include "debug.h"
+#include "target.h"
#ifdef XCOFF_DEBUGGING_INFO
#include "xcoffout.h" /* Needed for external data
@@ -181,14 +182,12 @@ static hashval_t const_str_htab_hash PARAMS ((const void *x));
static int const_str_htab_eq PARAMS ((const void *x, const void *y));
static void const_str_htab_del PARAMS ((void *));
static void asm_emit_uninitialised PARAMS ((tree, const char*, int, int));
+static void resolve_unique_section PARAMS ((tree, int));
static enum in_section { no_section, in_text, in_data, in_named
#ifdef BSS_SECTION_ASM_OP
, in_bss
#endif
-#ifdef EH_FRAME_SECTION_ASM_OP
- , in_eh_frame
-#endif
#ifdef EXTRA_SECTIONS
, EXTRA_SECTIONS
#endif
@@ -281,6 +280,28 @@ in_data_section ()
return in_section == in_data;
}
+/* Tell assembler to change to section NAME with attributes FLAGS. */
+
+void
+named_section_flags (name, flags, align)
+ const char *name;
+ unsigned int flags;
+ unsigned int align;
+{
+ if (in_section != in_named || strcmp (name, in_named_name))
+ {
+ (* targetm.asm_out.named_section) (name, flags, align);
+
+ if (flags & SECTION_FORGET)
+ in_section = no_section;
+ else
+ {
+ in_named_name = ggc_strdup (name);
+ in_section = in_named;
+ }
+ }
+}
+
/* Tell assembler to change to section NAME for DECL.
If DECL is NULL, just switch to section NAME.
If NAME is NULL, get the name from DECL.
@@ -290,27 +311,31 @@ void
named_section (decl, name, reloc)
tree decl;
const char *name;
- int reloc ATTRIBUTE_UNUSED;
+ int reloc;
{
+ unsigned int flags;
+
if (decl != NULL_TREE && !DECL_P (decl))
abort ();
if (name == NULL)
name = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
- if (in_section != in_named || strcmp (name, in_named_name))
- {
-#ifdef ASM_OUTPUT_SECTION_NAME
- ASM_OUTPUT_SECTION_NAME (asm_out_file, decl, name, reloc);
-#else
- /* Section attributes are not supported if this macro isn't provided -
- some host formats don't support them at all. The front-end should
- already have flagged this as an error. */
- abort ();
-#endif
+ flags = (* targetm.section_type_flags) (decl, name, reloc);
+ named_section_flags (name, flags, 0);
+}
- in_named_name = ggc_strdup (name);
- in_section = in_named;
- }
+/* If required, set DECL_SECTION_NAME to a unique name. */
+
+static void
+resolve_unique_section (decl, reloc)
+ tree decl;
+ int reloc;
+{
+ if (DECL_SECTION_NAME (decl) == NULL_TREE
+ && (flag_function_sections
+ || (targetm.have_named_sections
+ && DECL_ONE_ONLY (decl))))
+ UNIQUE_SECTION (decl, reloc);
}
#ifdef BSS_SECTION_ASM_OP
@@ -392,18 +417,6 @@ asm_output_aligned_bss (file, decl, name, size, align)
#endif /* BSS_SECTION_ASM_OP */
-#ifdef EH_FRAME_SECTION_ASM_OP
-void
-eh_frame_section ()
-{
- if (in_section != in_eh_frame)
- {
- fprintf (asm_out_file, "%s\n", EH_FRAME_SECTION_ASM_OP);
- in_section = in_eh_frame;
- }
-}
-#endif
-
/* Switch to the section for function DECL.
If DECL is NULL_TREE, switch to the text section.
@@ -467,15 +480,13 @@ exception_section ()
#if defined (EXCEPTION_SECTION)
EXCEPTION_SECTION ();
#else
-#ifdef ASM_OUTPUT_SECTION_NAME
- named_section (NULL_TREE, ".gcc_except_table", 0);
-#else
- if (flag_pic)
+ if (targetm.have_named_sections)
+ named_section (NULL_TREE, ".gcc_except_table", 0);
+ else if (flag_pic)
data_section ();
else
readonly_data_section ();
#endif
-#endif
}
/* Given NAME, a putative register name, discard any customary prefixes. */
@@ -896,15 +907,7 @@ assemble_start_function (decl, fnname)
if (CONSTANT_POOL_BEFORE_FUNCTION)
output_constant_pool (fnname, decl);
-#ifdef ASM_OUTPUT_SECTION_NAME
- /* If the function is to be put in its own section and it's not in a section
- already, indicate so. */
- if ((flag_function_sections
- && DECL_SECTION_NAME (decl) == NULL_TREE)
- || UNIQUE_SECTION_P (decl))
- UNIQUE_SECTION (decl, 0);
-#endif
-
+ resolve_unique_section (decl, 0);
function_section (decl);
/* Tell assembler to move to target machine's alignment for functions. */
@@ -1163,12 +1166,8 @@ asm_emit_uninitialised (decl, name, size, rounded)
}
}
-#ifdef ASM_OUTPUT_SECTION_NAME
- /* We already know that DECL_SECTION_NAME() == NULL. */
- if (flag_data_sections != 0 || UNIQUE_SECTION_P (decl))
- UNIQUE_SECTION (decl, 0);
-#endif
-
+ resolve_unique_section (decl, 0);
+
switch (destination)
{
#ifdef ASM_EMIT_BSS
@@ -1396,13 +1395,8 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
else if (DECL_INITIAL (decl))
reloc = output_addressed_constants (DECL_INITIAL (decl));
-#ifdef ASM_OUTPUT_SECTION_NAME
- if ((flag_data_sections != 0 && DECL_SECTION_NAME (decl) == NULL_TREE)
- || UNIQUE_SECTION_P (decl))
- UNIQUE_SECTION (decl, reloc);
-#endif
-
/* Switch to the appropriate section. */
+ resolve_unique_section (decl, reloc);
variable_section (decl, reloc);
/* dbxout.c needs to know this. */
@@ -4765,3 +4759,142 @@ init_varasm_once ()
ggc_add_root (&const_str_htab, 1, sizeof const_str_htab,
mark_const_str_htab);
}
+
+/* Select a set of attributes for section NAME based on the properties
+ of DECL and whether or not RELOC indicates that DECL's initializer
+ might contain runtime relocations.
+
+ We make the section read-only and executable for a function decl,
+ read-only for a const data decl, and writable for a non-const data decl.
+
+ If the section has already been defined, to not allow it to have
+ different attributes, as (1) this is ambiguous since we're not seeing
+ all the declarations up front and (2) some assemblers (e.g. SVR4)
+ do not recoginize section redefinitions. */
+
+unsigned int
+default_section_type_flags (decl, name, reloc)
+ tree decl;
+ const char *name;
+ int reloc;
+{
+ static htab_t htab;
+ unsigned int flags;
+ unsigned int **slot;
+
+ /* The names we put in the hashtable will always be the unique
+ versions gived to us by the stringtable, so we can just use
+ their addresses as the keys. */
+ if (!htab)
+ htab = htab_create (31, htab_hash_pointer, htab_eq_pointer, NULL);
+
+ if (decl && TREE_CODE (decl) == FUNCTION_DECL)
+ flags = SECTION_CODE;
+ else if (decl && DECL_READONLY_SECTION (decl, reloc))
+ flags = 0;
+ else
+ flags = SECTION_WRITE;
+
+ if (decl && DECL_ONE_ONLY (decl))
+ flags |= SECTION_LINKONCE;
+
+ if (strcmp (name, ".bss") == 0
+ || strncmp (name, ".bss.", 5) == 0
+ || strncmp (name, ".gnu.linkonce.b.", 16) == 0
+ || strcmp (name, ".sbss") == 0
+ || strncmp (name, ".sbss.", 6) == 0
+ || strncmp (name, ".gnu.linkonce.sb.", 17) == 0)
+ flags |= SECTION_BSS;
+
+ /* See if we already have an entry for this section. */
+ slot = (unsigned int **) htab_find_slot (htab, name, INSERT);
+ if (!*slot)
+ {
+ *slot = (unsigned int *) xmalloc (sizeof (unsigned int));
+ **slot = flags;
+ }
+ else
+ {
+ if (decl && **slot != flags)
+ error_with_decl (decl, "%s causes a section type conflict");
+ }
+
+ return flags;
+}
+
+/* Output assembly to switch to section NAME with attribute FLAGS.
+ Four variants for common object file formats. */
+
+void
+default_no_named_section (name, flags, align)
+ const char *name ATTRIBUTE_UNUSED;
+ unsigned int flags ATTRIBUTE_UNUSED;
+ unsigned int align ATTRIBUTE_UNUSED;
+{
+ /* Some object formats don't support named sections at all. The
+ front-end should already have flagged this as an error. */
+ abort ();
+}
+
+void
+default_elf_asm_named_section (name, flags, align)
+ const char *name;
+ unsigned int flags;
+ unsigned int align ATTRIBUTE_UNUSED;
+{
+ char flagchars[8], *f = flagchars;
+ const char *type;
+
+ if (!(flags & SECTION_DEBUG))
+ *f++ = 'a';
+ if (flags & SECTION_WRITE)
+ *f++ = 'w';
+ if (flags & SECTION_CODE)
+ *f++ = 'x';
+ if (flags & SECTION_SMALL)
+ *f++ = 's';
+ *f = '\0';
+
+ if (flags & SECTION_BSS)
+ type = "nobits";
+ else
+ type = "progbits";
+
+ fprintf (asm_out_file, "\t.section\t%s,\"%s\",@%s\n",
+ name, flagchars, type);
+}
+
+void
+default_coff_asm_named_section (name, flags, align)
+ const char *name;
+ unsigned int flags;
+ unsigned int align ATTRIBUTE_UNUSED;
+{
+ char flagchars[8], *f = flagchars;
+
+ if (flags & SECTION_WRITE)
+ *f++ = 'w';
+ if (flags & SECTION_CODE)
+ *f++ = 'x';
+ *f = '\0';
+
+ fprintf (asm_out_file, "\t.section\t%s,\"%s\"\n", name, flagchars);
+}
+
+void
+default_pe_asm_named_section (name, flags, align)
+ const char *name;
+ unsigned int flags;
+ unsigned int align ATTRIBUTE_UNUSED;
+{
+ default_coff_asm_named_section (name, flags, align);
+
+ if (flags & SECTION_LINKONCE)
+ {
+ /* Functions may have been compiled at various levels of
+ optimization so we can't use `same_size' here.
+ Instead, have the linker pick one. */
+ fprintf (asm_out_file, "\t.linkonce %s\n",
+ (flags & SECTION_CODE ? "discard" : "same_size"));
+ }
+}