diff options
Diffstat (limited to 'gcc/config/i386')
-rw-r--r-- | gcc/config/i386/cygwin.h | 63 | ||||
-rw-r--r-- | gcc/config/i386/djgpp.h | 19 | ||||
-rw-r--r-- | gcc/config/i386/i386-interix.h | 74 | ||||
-rw-r--r-- | gcc/config/i386/i386-protos.h | 4 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 41 | ||||
-rw-r--r-- | gcc/config/i386/i386elf.h | 17 | ||||
-rw-r--r-- | gcc/config/i386/sco5.h | 68 | ||||
-rw-r--r-- | gcc/config/i386/win32.h | 27 | ||||
-rw-r--r-- | gcc/config/i386/winnt.c | 96 |
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 |