+#ifdef COFF_WITH_PE
+ if (styp_flags & IMAGE_SCN_LNK_REMOVE)
+ sec_flags |= SEC_EXCLUDE;
+
+ if (styp_flags & IMAGE_SCN_LNK_COMDAT)
+ {
+ sec_flags |= SEC_LINK_ONCE;
+
+ /* Unfortunately, the PE format stores essential information in
+ the symbol table, of all places. We need to extract that
+ information now, so that objdump and the linker will know how
+ to handle the section without worrying about the symbols. We
+ can't call slurp_symtab, because the linker doesn't want the
+ swapped symbols. */
+
+ /* COMDAT sections are special. The first symbol is the section
+ symbol, which tells what kind of COMDAT section it is. The
+ *second* symbol is the "comdat symbol" - the one with the
+ unique name. GNU uses the section symbol for the unique
+ name; MS uses ".text" for every comdat section. Sigh. - DJ */
+
+ if (_bfd_coff_get_external_symbols (abfd))
+ {
+ bfd_byte *esym, *esymend;
+
+ esym = (bfd_byte *) obj_coff_external_syms (abfd);
+ esymend = esym + obj_raw_syment_count (abfd) * SYMESZ;
+
+ while (esym < esymend)
+ {
+ struct internal_syment isym;
+
+ bfd_coff_swap_sym_in (abfd, (PTR) esym, (PTR) &isym);
+
+ if (sizeof (internal_s->s_name) > SYMNMLEN)
+ {
+ /* This case implies that the matching symbol name
+ will be in the string table. */
+ abort ();
+ }
+
+ if (isym.n_sclass == C_STAT
+ && isym.n_type == T_NULL
+ && isym.n_numaux == 1)
+ {
+ char buf[SYMNMLEN + 1];
+ const char *symname;
+
+ symname = _bfd_coff_internal_syment_name (abfd, &isym, buf);
+ if (symname == NULL)
+ abort ();
+
+ if (strcmp (name, symname) == 0)
+ {
+ union internal_auxent aux;
+
+ /* This is the section symbol. */
+
+ bfd_coff_swap_aux_in (abfd, (PTR) (esym + SYMESZ),
+ isym.n_type, isym.n_sclass,
+ 0, isym.n_numaux, (PTR) &aux);
+
+ /* FIXME: Microsoft uses NODUPLICATES and
+ ASSOCIATIVE, but gnu uses ANY and SAME_SIZE.
+ Unfortunately, gnu doesn't do the comdat
+ symbols right. So, until we can fix it to do
+ the right thing, we are temporarily disabling
+ comdats for the MS types (they're used in
+ DLLs and C++, but we don't support *their*
+ C++ libraries anyway - DJ */
+
+ switch (aux.x_scn.x_comdat)
+ {
+ case IMAGE_COMDAT_SELECT_NODUPLICATES:
+#if 0
+ sec_flags |= SEC_LINK_DUPLICATES_ONE_ONLY;
+#else
+ sec_flags &= ~SEC_LINK_ONCE;
+#endif
+ break;
+
+ default:
+ case IMAGE_COMDAT_SELECT_ANY:
+ sec_flags |= SEC_LINK_DUPLICATES_DISCARD;
+ break;
+
+ case IMAGE_COMDAT_SELECT_SAME_SIZE:
+ sec_flags |= SEC_LINK_DUPLICATES_SAME_SIZE;
+ break;
+
+ case IMAGE_COMDAT_SELECT_EXACT_MATCH:
+ sec_flags |= SEC_LINK_DUPLICATES_SAME_CONTENTS;
+ break;
+
+ case IMAGE_COMDAT_SELECT_ASSOCIATIVE:
+#if 0
+ /* FIXME: This is not currently implemented. */
+ sec_flags |= SEC_LINK_DUPLICATES_DISCARD;
+#else
+ sec_flags &= ~SEC_LINK_ONCE;
+#endif
+ break;
+ }
+
+ break;
+ }
+ }
+
+ esym += (isym.n_numaux + 1) * SYMESZ;
+ }
+ }
+ }
+#endif
+