+
+/* Sections marked with the SEC_LINK_ONCE flag should only be linked
+ once into the output. This routine checks each sections, and
+ arranges to discard it if a section of the same name has already
+ been linked. This code assumes that all relevant sections have the
+ SEC_LINK_ONCE flag set; that is, it does not depend solely upon the
+ section name. This is called via bfd_map_over_sections. */
+
+/*ARGSUSED*/
+static void
+section_already_linked (abfd, sec, ignore)
+ bfd *abfd;
+ asection *sec;
+ PTR ignore;
+{
+ struct sec_link_once
+ {
+ struct sec_link_once *next;
+ asection *sec;
+ };
+ static struct sec_link_once *sec_link_once_list;
+ flagword flags;
+ const char *name;
+ struct sec_link_once *l;
+
+ flags = bfd_get_section_flags (abfd, sec);
+
+ if ((flags & SEC_LINK_ONCE) == 0)
+ return;
+
+ name = bfd_get_section_name (abfd, sec);
+
+ for (l = sec_link_once_list; l != NULL; l = l->next)
+ {
+ if (strcmp (name, bfd_get_section_name (l->sec->owner, l->sec)) == 0)
+ {
+ /* The section has already been linked. See if we should
+ issue a warning. */
+ switch (flags & SEC_LINK_DUPLICATES)
+ {
+ default:
+ abort ();
+
+ case SEC_LINK_DUPLICATES_DISCARD:
+ break;
+
+ case SEC_LINK_DUPLICATES_ONE_ONLY:
+ einfo ("%P: %B: warning: ignoring duplicate section `%s'",
+ abfd, name);
+ break;
+
+ case SEC_LINK_DUPLICATES_SAME_CONTENTS:
+ /* FIXME: We should really dig out the contents of both
+ sections and memcmp them. The COFF/PE spec says that
+ the Microsoft linker does not implement this
+ correctly, so I'm not going to bother doing it
+ either. */
+ /* Fall through. */
+ case SEC_LINK_DUPLICATES_SAME_SIZE:
+ if (bfd_section_size (abfd, sec)
+ != bfd_section_size (l->sec->owner, l->sec))
+ einfo ("%P: %B: warning: duplicate section `%s' has different size",
+ abfd, sec);
+ break;
+ }
+
+ /* Set the output_section field so that wild_doit does not
+ create a lang_input_section structure for this section. */
+ sec->output_section = bfd_abs_section_ptr;
+
+ return;
+ }
+ }
+
+ /* This is the first section with this name. Record it. */
+
+ l = (struct sec_link_once *) xmalloc (sizeof *l);
+ l->sec = sec;
+ l->next = sec_link_once_list;
+ sec_link_once_list = l;
+}