+ if (ssect != NULL)
+ {
+ bfd_boolean override = FALSE;
+
+ if (type == SHT_NULL)
+ type = ssect->type;
+ else if (type != ssect->type)
+ {
+ if (old_sec == NULL
+ /* FIXME: gcc, as of 2002-10-22, will emit
+
+ .section .init_array,"aw",@progbits
+
+ for __attribute__ ((section (".init_array"))).
+ "@progbits" is incorrect. */
+ && ssect->type != SHT_INIT_ARRAY
+ && ssect->type != SHT_FINI_ARRAY
+ && ssect->type != SHT_PREINIT_ARRAY)
+ {
+ /* We allow to specify any type for a .note section. */
+ if (ssect->type != SHT_NOTE)
+ as_warn (_("setting incorrect section type for %s"),
+ name);
+ }
+ else
+ {
+ as_warn (_("ignoring incorrect section type for %s"),
+ name);
+ type = ssect->type;
+ }
+ }
+
+ if (old_sec == NULL && (attr & ~ssect->attr) != 0)
+ {
+ /* As a GNU extension, we permit a .note section to be
+ allocatable. If the linker sees an allocatable .note
+ section, it will create a PT_NOTE segment in the output
+ file. We also allow "x" for .note.GNU-stack. */
+ if (ssect->type == SHT_NOTE
+ && (attr == SHF_ALLOC || attr == SHF_EXECINSTR))
+ ;
+ /* Allow different SHF_MERGE and SHF_STRINGS if we have
+ something like .rodata.str. */
+ else if (ssect->suffix_length == -2
+ && name[ssect->prefix_length] == '.'
+ && (attr
+ & ~ssect->attr
+ & ~SHF_MERGE
+ & ~SHF_STRINGS) == 0)
+ ;
+ /* .interp, .strtab and .symtab can have SHF_ALLOC. */
+ else if (attr == SHF_ALLOC
+ && (strcmp (name, ".interp") == 0
+ || strcmp (name, ".strtab") == 0
+ || strcmp (name, ".symtab") == 0))
+ override = TRUE;
+ else
+ {
+ as_warn (_("setting incorrect section attributes for %s"),
+ name);
+ override = TRUE;
+ }
+ }
+ if (!override && old_sec == NULL)
+ attr |= ssect->attr;
+ }
+
+ if (type != SHT_NULL)
+ elf_section_type (sec) = type;
+ if (attr != 0)
+ elf_section_flags (sec) = attr;
+
+ /* Convert ELF type and flags to BFD flags. */
+ flags = (SEC_RELOC
+ | ((attr & SHF_WRITE) ? 0 : SEC_READONLY)
+ | ((attr & SHF_ALLOC) ? SEC_ALLOC : 0)
+ | (((attr & SHF_ALLOC) && type != SHT_NOBITS) ? SEC_LOAD : 0)
+ | ((attr & SHF_EXECINSTR) ? SEC_CODE : 0)
+ | ((attr & SHF_MERGE) ? SEC_MERGE : 0)
+ | ((attr & SHF_STRINGS) ? SEC_STRINGS : 0)
+ | ((attr & SHF_TLS) ? SEC_THREAD_LOCAL : 0));
+#ifdef md_elf_section_flags
+ flags = md_elf_section_flags (flags, attr, type);
+#endif
+
+ if (old_sec == NULL)
+ {
+ symbolS *secsym;
+
+ /* Prevent SEC_HAS_CONTENTS from being inadvertently set. */
+ if (type == SHT_NOBITS)
+ seg_info (sec)->bss = 1;
+
+ if (linkonce)
+ flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
+ bfd_set_section_flags (stdoutput, sec, flags);
+ if (flags & SEC_MERGE)
+ sec->entsize = entsize;
+ elf_group_name (sec) = group_name;
+
+ /* Add a symbol for this section to the symbol table. */
+ secsym = symbol_find (name);
+ if (secsym != NULL)
+ symbol_set_bfdsym (secsym, sec->symbol);
+ else
+ symbol_table_insert (section_symbol (sec));
+ }
+ else if (attr != 0)
+ {
+ /* If section attributes are specified the second time we see a
+ particular section, then check that they are the same as we
+ saw the first time. */
+ if (((old_sec->flags ^ flags)
+ & (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
+ | SEC_EXCLUDE | SEC_SORT_ENTRIES | SEC_MERGE | SEC_STRINGS
+ | SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
+ | SEC_THREAD_LOCAL)))
+ as_warn (_("ignoring changed section attributes for %s"), name);
+ if ((flags & SEC_MERGE) && old_sec->entsize != (unsigned) entsize)
+ as_warn (_("ignoring changed section entity size for %s"), name);
+ if ((attr & SHF_GROUP) != 0
+ && (elf_group_name (old_sec) == NULL
+ || strcmp (elf_group_name (old_sec), group_name) != 0))
+ as_warn (_("ignoring new section group for %s"), name);
+ }