summaryrefslogtreecommitdiff
path: root/gcc/config/i386
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/i386')
-rw-r--r--gcc/config/i386/cygwin.h63
-rw-r--r--gcc/config/i386/djgpp.h19
-rw-r--r--gcc/config/i386/i386-interix.h74
-rw-r--r--gcc/config/i386/i386-protos.h4
-rw-r--r--gcc/config/i386/i386.c41
-rw-r--r--gcc/config/i386/i386elf.h17
-rw-r--r--gcc/config/i386/sco5.h68
-rw-r--r--gcc/config/i386/win32.h27
-rw-r--r--gcc/config/i386/winnt.c96
9 files changed, 159 insertions, 250 deletions
diff --git a/gcc/config/i386/cygwin.h b/gcc/config/i386/cygwin.h
index 6e76f1c7bec..9ea367f3a8f 100644
--- a/gcc/config/i386/cygwin.h
+++ b/gcc/config/i386/cygwin.h
@@ -407,69 +407,16 @@ do { \
symbols must be explicitly imported from shared libraries (DLLs). */
#define MULTIPLE_SYMBOL_SPACES
-#define UNIQUE_SECTION_P(DECL) DECL_ONE_ONLY (DECL)
extern void i386_pe_unique_section PARAMS ((TREE, int));
#define UNIQUE_SECTION(DECL,RELOC) i386_pe_unique_section (DECL, RELOC)
#define SUPPORTS_ONE_ONLY 1
-/* A C statement to output something to the assembler file to switch to section
- NAME for object DECL which is either a FUNCTION_DECL, a VAR_DECL or
- NULL_TREE. Some target formats do not support arbitrary sections. Do not
- define this macro in such cases. */
-#undef ASM_OUTPUT_SECTION_NAME
-#define ASM_OUTPUT_SECTION_NAME(STREAM, DECL, NAME, RELOC) \
-do { \
- static struct section_info \
- { \
- struct section_info *next; \
- char *name; \
- enum sect_enum {SECT_RW, SECT_RO, SECT_EXEC} type; \
- } *sections; \
- struct section_info *s; \
- const char *mode; \
- enum sect_enum type; \
- \
- for (s = sections; s; s = s->next) \
- if (!strcmp (NAME, s->name)) \
- break; \
- \
- if (DECL && TREE_CODE (DECL) == FUNCTION_DECL) \
- type = SECT_EXEC, mode = "x"; \
- else if (DECL && DECL_READONLY_SECTION (DECL, RELOC)) \
- type = SECT_RO, mode = ""; \
- else \
- { \
- type = SECT_RW; \
- if (DECL && TREE_CODE (DECL) == VAR_DECL \
- && lookup_attribute ("shared", DECL_MACHINE_ATTRIBUTES (DECL))) \
- mode = "ws"; \
- else \
- mode = "w"; \
- } \
- \
- if (s == 0) \
- { \
- s = (struct section_info *) xmalloc (sizeof (struct section_info)); \
- s->name = xmalloc ((strlen (NAME) + 1) * sizeof (*NAME)); \
- strcpy (s->name, NAME); \
- s->type = type; \
- s->next = sections; \
- sections = s; \
- fprintf (STREAM, ".section\t%s,\"%s\"\n", NAME, mode); \
- /* Functions may have been compiled at various levels of \
- optimization so we can't use `same_size' here. Instead, \
- have the linker pick one. */ \
- if ((DECL) && DECL_ONE_ONLY (DECL)) \
- fprintf (STREAM, "\t.linkonce %s\n", \
- TREE_CODE (DECL) == FUNCTION_DECL \
- ? "discard" : "same_size"); \
- } \
- else \
- { \
- fprintf (STREAM, ".section\t%s,\"%s\"\n", NAME, mode); \
- } \
-} while (0)
+/* Switch into a generic section. */
+#define TARGET_ASM_NAMED_SECTION i386_pe_asm_named_section
+
+/* Select attributes for named sections. */
+#define TARGET_SECTION_TYPE_FLAGS i386_pe_section_type_flags
/* Write the extra assembler code needed to declare a function
properly. If we are generating SDB debugging information, this
diff --git a/gcc/config/i386/djgpp.h b/gcc/config/i386/djgpp.h
index 14a43570e75..f5e79c2ba0f 100644
--- a/gcc/config/i386/djgpp.h
+++ b/gcc/config/i386/djgpp.h
@@ -57,10 +57,6 @@ Boston, MA 02111-1307, USA. */
#undef DTORS_SECTION_ASM_OP
#define DTORS_SECTION_ASM_OP "\t.section .dtor"
-/* Define the name of the .eh_frame section. */
-#undef EH_FRAME_SECTION_ASM_OP
-#define EH_FRAME_SECTION_ASM_OP "\t.section .eh_frame"
-
/* Define the name of the .ident op. */
#undef IDENT_ASM_OP
#define IDENT_ASM_OP "\t.ident\t"
@@ -189,14 +185,8 @@ dtor_section () \
fprintf (FILE, "\n"); \
} while (0)
-/* Tell GCC how to output a section name. Add "x" for code sections. */
-#define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC)\
- do { \
- if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL) \
- fprintf ((FILE), "\t.section %s,\"x\"\n", (NAME)); \
- else \
- fprintf ((FILE), "\t.section %s\n", (NAME)); \
- } while (0)
+/* Switch into a generic section. */
+#define TARGET_ASM_NAMED_SECTION default_coff_asm_named_section
#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \
do { \
@@ -287,11 +277,6 @@ while (0)
#undef MAKE_DECL_ONE_ONLY
#define MAKE_DECL_ONE_ONLY(DECL) (DECL_WEAK (DECL) = 1)
-/* Additional support for C++ templates and support for
- garbage collection. */
-#undef UNIQUE_SECTION_P
-#define UNIQUE_SECTION_P(DECL) (DECL_ONE_ONLY (DECL))
-
#undef UNIQUE_SECTION
#define UNIQUE_SECTION(DECL,RELOC) \
do { \
diff --git a/gcc/config/i386/i386-interix.h b/gcc/config/i386/i386-interix.h
index 0460b64b07b..864f5200c7c 100644
--- a/gcc/config/i386/i386-interix.h
+++ b/gcc/config/i386/i386-interix.h
@@ -341,26 +341,6 @@ dtors_section () \
} \
}
-#if 0
-/* Currently gas chokes on this; that's not too hard to fix, but there's
- not a lot of impeteus to do it, either. If it is done, gas will have
- to handle long section name escapes (which are defined in the COFF/PE
- document as /nnn where nnn is a string table index). The benefit:
- section attributes and -ffunction-sections, neither of which seem to
- be critical. */
-/* gas may have been fixed? bfd was. */
-
-/* Switch into a generic section.
- This is currently only used to support section attributes.
-
- 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. */
-#define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME) \
- fprintf (FILE, ".section\t%s,\"%s\",@progbits\n", NAME, \
- (DECL) && TREE_CODE (DECL) == FUNCTION_DECL ? "ax" : \
- (DECL) && TREE_READONLY (DECL) ? "a" : "aw")
-#endif
-
/* The MS compilers take alignment as a number of bytes, so we do as well */
#undef ASM_OUTPUT_ALIGN
#define ASM_OUTPUT_ALIGN(FILE,LOG) \
@@ -505,63 +485,13 @@ do { \
symbols must be explicitly imported from shared libraries (DLLs). */
#define MULTIPLE_SYMBOL_SPACES
-#define UNIQUE_SECTION_P(DECL) DECL_ONE_ONLY (DECL)
extern void i386_pe_unique_section ();
#define UNIQUE_SECTION(DECL,RELOC) i386_pe_unique_section (DECL, RELOC)
#define SUPPORTS_ONE_ONLY 1
-/* A C statement to output something to the assembler file to switch to section
- NAME for object DECL which is either a FUNCTION_DECL, a VAR_DECL or
- NULL_TREE. Some target formats do not support arbitrary sections. Do not
- define this macro in such cases. */
-#undef ASM_OUTPUT_SECTION_NAME
-#define ASM_OUTPUT_SECTION_NAME(STREAM, DECL, NAME, RELOC) \
-do { \
- static struct section_info \
- { \
- struct section_info *next; \
- char *name; \
- enum sect_enum {SECT_RW, SECT_RO, SECT_EXEC} type; \
- } *sections; \
- struct section_info *s; \
- const char *mode; \
- enum sect_enum type; \
- \
- for (s = sections; s; s = s->next) \
- if (!strcmp (NAME, s->name)) \
- break; \
- \
- if (DECL && TREE_CODE (DECL) == FUNCTION_DECL) \
- type = SECT_EXEC, mode = "x"; \
- else if (DECL && DECL_READONLY_SECTION (DECL, RELOC)) \
- type = SECT_RO, mode = "r"; \
- else \
- type = SECT_RW, mode = "w"; \
- \
- if (s == 0) \
- { \
- s = (struct section_info *) xmalloc (sizeof (struct section_info)); \
- s->name = xmalloc ((strlen (NAME) + 1) * sizeof (*NAME)); \
- strcpy (s->name, NAME); \
- s->type = type; \
- s->next = sections; \
- sections = s; \
- fprintf (STREAM, ".section\t%s,\"%s\"\n", NAME, mode); \
- /* Functions may have been compiled at various levels of \
- optimization so we can't use `same_size' here. Instead, \
- have the linker pick one. */ \
- if ((DECL) && DECL_ONE_ONLY (DECL)) \
- fprintf (STREAM, "\t.linkonce %s\n", \
- TREE_CODE (DECL) == FUNCTION_DECL \
- ? "discard" : "same_size"); \
- } \
- else \
- { \
- fprintf (STREAM, ".section\t%s,\"%s\"\n", NAME, mode); \
- } \
-} while (0)
-
+/* Switch into a generic section. */
+#define TARGET_ASM_NAMED_SECTION default_pe_asm_named_section
#endif /* 0 */
/* DWARF2 Unwinding doesn't work with exception handling yet. */
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 5b9e9792e1f..e263116ace3 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -181,4 +181,8 @@ extern int ix86_constant_alignment PARAMS ((tree, int));
extern int ix86_valid_type_attribute_p PARAMS ((tree, tree, tree, tree));
extern int i386_pe_valid_decl_attribute_p PARAMS ((tree, tree, tree, tree));
extern int i386_pe_valid_type_attribute_p PARAMS ((tree, tree, tree, tree));
+extern unsigned int i386_pe_section_type_flags PARAMS ((tree, const char *,
+ int));
+extern void i386_pe_asm_named_section PARAMS ((const char *, unsigned int,
+ unsigned int));
#endif
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 9017207e292..2547ea40a53 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -608,6 +608,11 @@ static int ix86_fp_comparison_cost PARAMS ((enum rtx_code code));
static int ix86_save_reg PARAMS ((int, int));
static void ix86_compute_frame_layout PARAMS ((struct ix86_frame *));
static int ix86_comp_type_attributes PARAMS ((tree, tree));
+
+#if defined(TARGET_ELF) && defined(TARGET_COFF)
+static void sco_asm_named_section PARAMS ((const char *, unsigned int,
+ unsigned int));
+#endif
/* Initialize the GCC target structure. */
#undef TARGET_VALID_TYPE_ATTRIBUTE
@@ -2323,7 +2328,7 @@ ix86_asm_file_end (file)
/* ??? Binutils 2.10 and earlier has a linkonce elimination bug related
to updating relocations to a section being discarded such that this
doesn't work. Ought to detect this at configure time. */
-#if 0 && defined (ASM_OUTPUT_SECTION_NAME)
+#if 0
/* The trick here is to create a linkonce section containing the
pic label thunk, but to refer to it with an internal label.
Because the label is internal, we don't have inter-dso name
@@ -2331,16 +2336,18 @@ ix86_asm_file_end (file)
In order to use these macros, however, we must create a fake
function decl. */
- {
- tree decl = build_decl (FUNCTION_DECL,
- get_identifier ("i686.get_pc_thunk"),
- error_mark_node);
- DECL_ONE_ONLY (decl) = 1;
- UNIQUE_SECTION (decl, 0);
- named_section (decl, NULL, 0);
- }
+ if (targetm.have_named_sections)
+ {
+ tree decl = build_decl (FUNCTION_DECL,
+ get_identifier ("i686.get_pc_thunk"),
+ error_mark_node);
+ DECL_ONE_ONLY (decl) = 1;
+ UNIQUE_SECTION (decl, 0);
+ named_section (decl, NULL, 0);
+ }
+ else
#else
- text_section ();
+ text_section ();
#endif
/* This used to call ASM_DECLARE_FUNCTION_NAME() but since it's an
@@ -10822,3 +10829,17 @@ ix86_output_main_function_alignment_hack (file, size)
fprintf (file, "\tret\n");
ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (label));
}
+
+#if defined(TARGET_ELF) && defined(TARGET_COFF)
+static void
+sco_asm_named_section (name, flags, align)
+ const char *name;
+ unsigned int flags;
+ unsigned int align;
+{
+ if (TARGET_ELF)
+ default_elf_asm_named_section (name, flags, align);
+ else
+ default_coff_asm_named_section (name, flags, align);
+}
+#endif
diff --git a/gcc/config/i386/i386elf.h b/gcc/config/i386/i386elf.h
index 1d7d4b7e650..c2c5cff7513 100644
--- a/gcc/config/i386/i386elf.h
+++ b/gcc/config/i386/i386elf.h
@@ -170,21 +170,8 @@ do { long value[3]; \
#define LOCAL_LABEL_PREFIX "."
-/* A C statement to output something to the assembler file to switch to section
- NAME for object DECL which is either a FUNCTION_DECL, a VAR_DECL or
- NULL_TREE. Some target formats do not support arbitrary sections. Do not
- define this macro in such cases. */
-
-#undef ASM_OUTPUT_SECTION_NAME
-#define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC) \
-do { \
- if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL) \
- fprintf (FILE, ".section\t%s,\"ax\"\n", (NAME)); \
- else if ((DECL) && DECL_READONLY_SECTION (DECL, RELOC)) \
- fprintf (FILE, ".section\t%s,\"a\"\n", (NAME)); \
- else \
- fprintf (FILE, ".section\t%s,\"aw\"\n", (NAME)); \
-} while (0)
+/* Switch into a generic section. */
+#define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section
/* If defined, a C expression whose value is a string containing the
assembler operation to identify the following data as
diff --git a/gcc/config/i386/sco5.h b/gcc/config/i386/sco5.h
index 2477b6a0cdc..b7a7cdbfd29 100644
--- a/gcc/config/i386/sco5.h
+++ b/gcc/config/i386/sco5.h
@@ -75,10 +75,10 @@ Boston, MA 02111-1307, USA. */
#define GLOBAL_ASM_OP "\t.globl\t"
#undef EH_FRAME_SECTION_ASM_OP
-#define EH_FRAME_SECTION_ASM_OP_COFF "\t.section\t.ehfram, \"x\""
-#define EH_FRAME_SECTION_ASM_OP_ELF "\t.section\t.eh_frame, \"aw\""
-#define EH_FRAME_SECTION_ASM_OP \
- ((TARGET_ELF) ? EH_FRAME_SECTION_ASM_OP_ELF : EH_FRAME_SECTION_ASM_OP_COFF)
+#define EH_FRAME_SECTION_NAME_COFF ".ehfram"
+#define EH_FRAME_SECTION_NAME_ELF ".eh_frame"
+#define EH_FRAME_SECTION_NAME \
+ ((TARGET_ELF) ? EH_FRAME_SECTION_NAME_ELF : EH_FRAME_SECTION_NAME_COFF)
/* Avoid problems (long sectino names, forward assembler refs) with DWARF
exception unwinding when we're generating COFF */
@@ -444,56 +444,14 @@ do { \
#define USER_LABEL_PREFIX ""
/*
- * Compensate for the difference between ELF and COFF assembler syntax.
- * Otherwise, this is cribbed from ../svr4.h.
* We rename 'gcc_except_table' to the shorter name in preparation
- * for the day when we're ready to do DWARF2 eh unwinding under COFF
+ * for the day when we're ready to do DWARF2 eh unwinding under COFF.
*/
-#undef ASM_OUTPUT_SECTION_NAME
-#define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC) \
-do { \
- static struct section_info \
- { \
- struct section_info *next; \
- char *name; \
- enum sect_enum {SECT_RW, SECT_RO, SECT_EXEC} type; \
- } *sections; \
- struct section_info *s; \
- const char *mode; \
- enum sect_enum type; \
- const char *sname = NAME ; \
- if (strcmp(NAME, ".gcc_except_table") == 0) sname = ".gccexc" ; \
- \
- for (s = sections; s; s = s->next) \
- if (!strcmp (NAME, s->name)) \
- break; \
- \
- if (DECL && TREE_CODE (DECL) == FUNCTION_DECL) \
- type = SECT_EXEC, mode = (TARGET_ELF) ? "ax" : "x" ; \
- else if (DECL && DECL_READONLY_SECTION (DECL, RELOC)) \
- type = SECT_RO, mode = "a"; \
- else \
- type = SECT_RW, mode = (TARGET_ELF) ? "aw" : "w" ; \
- \
- if (s == 0) \
- { \
- s = (struct section_info *) xmalloc (sizeof (struct section_info)); \
- s->name = xmalloc ((strlen (NAME) + 1) * sizeof (*NAME)); \
- strcpy (s->name, NAME); \
- s->type = type; \
- s->next = sections; \
- sections = s; \
- fprintf (FILE, ".section\t%s,\"%s\"%s\n", sname, mode, \
- (TARGET_ELF) ? ",@progbits" : "" ); \
- } \
- else \
- { \
- if (DECL && s->type != type) \
- error_with_decl (DECL, "%s causes a section type conflict"); \
- \
- fprintf (FILE, ".section\t%s\n", sname); \
- } \
-} while (0)
+#define EXCEPTION_SECTION() named_section (NULL, ".gccexc", 1)
+
+/* Switch into a generic section. */
+#undef TARGET_ASM_NAMED_SECTION
+#define TARGET_ASM_NAMED_SECTION sco_asm_named_section
#undef ASM_OUTPUT_SKIP
#define ASM_OUTPUT_SKIP(FILE,SIZE) \
@@ -925,7 +883,7 @@ compiler at the end of the day. Onward we go ...
# undef FINI_SECTION_ASM_OP
# undef CTORS_SECTION_ASM_OP
# undef DTORS_SECTION_ASM_OP
-# undef EH_FRAME_SECTION_ASM_OP
+# undef EH_FRAME_SECTION_NAME
# undef CTOR_LIST_BEGIN
# undef CTOR_LIST_END
# undef DO_GLOBAL_CTORS_BODY
@@ -936,13 +894,13 @@ compiler at the end of the day. Onward we go ...
# define FINI_SECTION_ASM_OP FINI_SECTION_ASM_OP_ELF
# define DTORS_SECTION_ASM_OP DTORS_SECTION_ASM_OP_ELF
# define CTORS_SECTION_ASM_OP CTORS_SECTION_ASM_OP_ELF
-# define EH_FRAME_SECTION_ASM_OP EH_FRAME_SECTION_ASM_OP_ELF
+# define EH_FRAME_SECTION_NAME EH_FRAME_SECTION_NAME_ELF
# else /* ! _SCO_ELF */
# define INIT_SECTION_ASM_OP INIT_SECTION_ASM_OP_COFF
# define FINI_SECTION_ASM_OP FINI_SECTION_ASM_OP_COFF
# define DTORS_SECTION_ASM_OP DTORS_SECTION_ASM_OP_COFF
# define CTORS_SECTION_ASM_OP CTORS_SECTION_ASM_OP_COFF
-# define EH_FRAME_SECTION_ASM_OP EH_FRAME_SECTION_ASM_OP_COFF
+# define EH_FRAME_SECTION_NAME EH_FRAME_SECTION_NAME_COFF
# define CTOR_LIST_BEGIN asm (INIT_SECTION_ASM_OP); asm ("pushl $0")
# define CTOR_LIST_END CTOR_LIST_BEGIN
# define DO_GLOBAL_CTORS_BODY \
diff --git a/gcc/config/i386/win32.h b/gcc/config/i386/win32.h
index 24d8e2d278d..7e03383f29f 100644
--- a/gcc/config/i386/win32.h
+++ b/gcc/config/i386/win32.h
@@ -233,33 +233,16 @@ do { \
symbols must be explicitly imported from shared libraries (DLLs). */
#define MULTIPLE_SYMBOL_SPACES
-#define UNIQUE_SECTION_P(DECL) DECL_ONE_ONLY (DECL)
extern void i386_pe_unique_section ();
#define UNIQUE_SECTION(DECL,RELOC) i386_pe_unique_section (DECL, RELOC)
#define SUPPORTS_ONE_ONLY 1
-/* A C statement to output something to the assembler file to switch to section
- NAME for object DECL which is either a FUNCTION_DECL, a VAR_DECL or
- NULL_TREE. Some target formats do not support arbitrary sections. Do not
- define this macro in such cases. */
-#undef ASM_OUTPUT_SECTION_NAME
-#define ASM_OUTPUT_SECTION_NAME(STREAM, DECL, NAME, RELOC) \
-do { \
- if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL) \
- fprintf (STREAM, "\t.section %s,\"x\"\n", (NAME)); \
- else if ((DECL) && DECL_READONLY_SECTION (DECL, RELOC)) \
- fprintf (STREAM, "\t.section %s,\"\"\n", (NAME)); \
- else \
- fprintf (STREAM, "\t.section %s,\"w\"\n", (NAME)); \
- /* Functions may have been compiled at various levels of \
- optimization so we can't use `same_size' here. Instead, \
- have the linker pick one. */ \
- if ((DECL) && DECL_ONE_ONLY (DECL)) \
- fprintf (STREAM, "\t.linkonce %s\n", \
- TREE_CODE (DECL) == FUNCTION_DECL \
- ? "discard" : "same_size"); \
-} while (0)
+/* Switch into a generic section. */
+#define TARGET_ASM_NAMED_SECTION i386_pe_asm_named_section
+
+/* Select attributes for named sections. */
+#define TARGET_SECTION_TYPE_FLAGS i386_pe_section_type_flags
#undef ASM_COMMENT_START
#define ASM_COMMENT_START " #"
diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c
index 2d85b66930e..ff13c3863b7 100644
--- a/gcc/config/i386/winnt.c
+++ b/gcc/config/i386/winnt.c
@@ -29,6 +29,7 @@ Boston, MA 02111-1307, USA. */
#include "flags.h"
#include "tm_p.h"
#include "toplev.h"
+#include "hashtab.h"
/* i386/PE specific attribute support.
@@ -55,7 +56,7 @@ void i386_pe_mark_dllimport PARAMS ((tree));
int
i386_pe_valid_decl_attribute_p (decl, attributes, attr, args)
tree decl;
- tree attributes;
+ tree attributes ATTRIBUTE_UNUSED;
tree attr;
tree args;
{
@@ -455,6 +456,99 @@ i386_pe_unique_section (decl, reloc)
DECL_SECTION_NAME (decl) = build_string (len, string);
}
+
+/* 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. */
+/* ??? This differs from the "standard" PE implementation in that we
+ handle the SHARED variable attribute. Should this be done for all
+ PE targets? */
+
+#define SECTION_PE_SHARED SECTION_MACH_DEP
+
+unsigned int
+i386_pe_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 && TREE_CODE (decl) == VAR_DECL
+ && lookup_attribute ("shared", DECL_MACHINE_ATTRIBUTES (decl)))
+ flags |= SECTION_PE_SHARED;
+ }
+
+ if (decl && DECL_ONE_ONLY (decl))
+ flags |= SECTION_LINKONCE;
+
+ /* 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;
+}
+
+void
+i386_pe_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_CODE)
+ *f++ = 'x';
+ if (flags & SECTION_WRITE)
+ *f++ = 'w';
+ if (flags & SECTION_PE_SHARED)
+ *f++ = 's';
+ *f = '\0';
+
+ fprintf (asm_out_file, "\t.section\t%s,\"%s\"\n", name, flagchars);
+
+ 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"));
+ }
+}
/* The Microsoft linker requires that every function be marked as
DT_FCN. When using gas on cygwin, we must emit appropriate .type