newsect->entsize = hdr->sh_entsize;
}
if ((hdr->sh_flags & SHF_STRINGS) != 0)
- flags |= SEC_STRINGS;
+ {
+ flags |= SEC_STRINGS;
+ newsect->entsize = hdr->sh_entsize;
+ }
if ((hdr->sh_flags & SHF_TLS) != 0)
flags |= SEC_THREAD_LOCAL;
if ((hdr->sh_flags & SHF_EXCLUDE) != 0)
this_hdr->sh_entsize = asect->entsize;
}
if ((asect->flags & SEC_STRINGS) != 0)
- this_hdr->sh_flags |= SHF_STRINGS;
+ {
+ this_hdr->sh_flags |= SHF_STRINGS;
+ this_hdr->sh_entsize = asect->entsize;
+ }
if ((asect->flags & SEC_GROUP) == 0 && elf_group_name (asect) != NULL)
this_hdr->sh_flags |= SHF_GROUP;
if ((asect->flags & SEC_THREAD_LOCAL) != 0)
= match_p->linked_to_symbol_name;
bfd_set_section_flags (sec, flags);
- if (flags & SEC_MERGE)
+ if (flags & (SEC_MERGE | SEC_STRINGS))
sec->entsize = entsize;
elf_group_name (sec) = match_p->group_name;
processor or application specific attribute as suspicious? */
elf_section_flags (sec) = attr;
- if ((flags & SEC_MERGE) && old_sec->entsize != (unsigned) entsize)
+ if ((flags & (SEC_MERGE | SEC_STRINGS))
+ && old_sec->entsize != (unsigned) entsize)
as_bad (_("changed section entity size for %s"), name);
}
}
}
SKIP_WHITESPACE ();
- if ((attr & SHF_MERGE) != 0 && *input_line_pointer == ',')
+ if ((attr & (SHF_MERGE | SHF_STRINGS)) != 0
+ && *input_line_pointer == ',')
{
++input_line_pointer;
SKIP_WHITESPACE ();
if (inherit && *input_line_pointer == ','
- && (bfd_section_flags (now_seg) & SEC_MERGE) != 0)
+ && (bfd_section_flags (now_seg)
+ & (SEC_MERGE | SEC_STRINGS)) != 0)
goto fetch_entsize;
entsize = get_absolute_expression ();
SKIP_WHITESPACE ();
if (entsize <= 0)
{
- as_warn (_("invalid merge entity size"));
- attr &= ~SHF_MERGE;
+ as_warn (_("invalid merge / string entity size"));
+ attr &= ~(SHF_MERGE | SHF_STRINGS);
entsize = 0;
}
}
- else if ((attr & SHF_MERGE) != 0 && inherit
- && (bfd_section_flags (now_seg) & SEC_MERGE) != 0)
+ else if ((attr & (SHF_MERGE | SHF_STRINGS)) != 0 && inherit
+ && (bfd_section_flags (now_seg)
+ & (SEC_MERGE | SEC_STRINGS)) != 0)
{
fetch_entsize:
entsize = now_seg->entsize;
}
- else if ((attr & SHF_MERGE) != 0)
+ else if ((attr & (SHF_MERGE | SHF_STRINGS)) != 0)
{
- as_warn (_("entity size for SHF_MERGE not specified"));
- attr &= ~SHF_MERGE;
+ as_warn (_("entity size for SHF_MERGE / SHF_STRINGS not specified"));
+ attr &= ~(SHF_MERGE | SHF_STRINGS);
}
- if ((attr & SHF_MERGE) != 0 && type == SHT_NOBITS)
- as_warn (_("bogus SHF_MERGE for SHT_NOBITS section"));
+ if ((attr & (SHF_MERGE | SHF_STRINGS)) != 0 && type == SHT_NOBITS)
+ as_warn (_("bogus SHF_MERGE / SHF_STRINGS for SHT_NOBITS section"));
if ((attr & SHF_LINK_ORDER) != 0 && *input_line_pointer == ',')
{
special and have fixed types. Any attempt to declare them with a different
type will generate an error from the assembler.
-If @var{flags} contains the @code{M} symbol then the @var{type} argument must
-be specified as well as an extra argument---@var{entsize}---like this:
+If @var{flags} contains the @code{M} and/or @code{S} symbol then the @var{type}
+argument must be specified as well as an extra argument---@var{entsize}---like
+this:
@smallexample
.section @var{name} , "@var{flags}"M, @@@var{type}, @var{entsize}
@end smallexample
Sections with the @code{M} flag but not @code{S} flag must contain fixed size
-constants, each @var{entsize} octets long. Sections with both @code{M} and
-@code{S} must contain zero terminated strings where each character is
-@var{entsize} bytes long. The linker may remove duplicates within sections with
+constants, each @var{entsize} octets long. Sections with @code{S} must contain
+zero terminated strings where each character is @var{entsize} bytes long. For
+@code{M} sections the linker may remove duplicates within sections with
the same name, same entity size and same flags. @var{entsize} must be an
absolute expression. For sections with both @code{M} and @code{S}, a string
which is a suffix of a larger string is considered a duplicate. Thus
time, but the facility is provided for testing purposes. An index of zero is
allowed. It indicates that the linked-to section has already been discarded.
-Note: If both the @var{M} and @var{o} flags are present, then the fields
-for the Merge flag should come first, like this:
+Note: If both one of @var{M} or @var{S} and @var{o} flags are present, then the
+fields for the Merge/String flag should come first, like this:
@smallexample
.section @var{name},"@var{flags}"Mo,@@@var{type},@var{entsize},@var{SymbolName}
an alias for comdat
@end table
-Note: if both the @var{M} and @var{G} flags are present then the fields for
-the Merge flag should come first, like this:
+Note: Uf both one of @var{M} or @var{S} and @var{G} flags are present then the
+fields for the Merge/String flag should come first, like this:
@smallexample
.section @var{name} , "@var{flags}"MG, @@@var{type}, @var{entsize}, @var{GroupName}[, @var{linkage}]
do_not_pad_sections_to_alignment = 1;
alignment = SUB_SEGMENT_ALIGN (now_seg, frchainP);
- if ((bfd_section_flags (now_seg) & SEC_MERGE)
+ if ((bfd_section_flags (now_seg) & (SEC_MERGE | SEC_STRINGS))
&& now_seg->entsize)
{
unsigned int entsize = now_seg->entsize;