asection *old_sec;
segT sec;
flagword flags;
- int def_type;
- int def_attr;
+ const struct bfd_elf_special_section *ssect;
#ifdef md_flush_pending_output
md_flush_pending_output ();
old_sec = bfd_get_section_by_name (stdoutput, name);
sec = subseg_new (name, 0);
+ ssect = _bfd_elf_get_sec_type_attr (stdoutput, name);
- if (_bfd_elf_get_sec_type_attr (stdoutput, name, &def_type,
- &def_attr))
+ if (ssect != NULL)
{
+ bfd_boolean override = FALSE;
+
if (type == SHT_NULL)
- type = def_type;
- else if (type != def_type)
+ type = ssect->type;
+ else if (type != ssect->type)
{
if (old_sec == NULL
/* FIXME: gcc, as of 2002-10-22, will emit
for __attribute__ ((section (".init_array"))).
"@progbits" is incorrect. */
- && def_type != SHT_INIT_ARRAY
- && def_type != SHT_FINI_ARRAY
- && def_type != SHT_PREINIT_ARRAY)
+ && 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 (def_type != SHT_NOTE)
+ if (ssect->type != SHT_NOTE)
as_warn (_("setting incorrect section type for %s"),
name);
}
{
as_warn (_("ignoring incorrect section type for %s"),
name);
- type = def_type;
+ type = ssect->type;
}
}
- if (old_sec == NULL && (attr &~ def_attr) != 0)
+ 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 allocateable .note
+ 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 (!(def_type == SHT_NOTE
- && (attr == SHF_ALLOC || attr == SHF_EXECINSTR)))
- as_warn (_("setting incorrect section attributes for %s"),
- name);
+ 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;
+ }
}
- attr |= def_attr;
+ if (!override && old_sec == NULL)
+ attr |= ssect->attr;
}
if (type != SHT_NULL)