* section.c (SEC_LINK_ONCE): Define.

(SEC_LINK_DUPLICATES): Define.
	(SEC_LINK_DUPLICATES_DISCARD): Define.
	(SEC_LINK_DUPLICATES_ONE_ONLY): Define.
	(SEC_LINK_DUPLICATES_SAME_SIZE): Define.
	(SEC_LINK_DUPLICATES_SAME_CONTENTS): Define.
	* bfd-in2.h: Rebuild.
	* coffcode.h (sec_to_styp_flags): If COFF_WITH_PE, turn
	SEC_LINK_ONCE into IMAGE_SCN_LNK_COMDAT.
	(styp_to_sec_flags): If COFF_WITH_PE, turn IMAGE_SCN_LNK_REMOVE
	into SEC_EXCLUDE.  If IMAGE_SCN_LNK_COMDAT is set, set
	SEC_LINK_ONCE, and look through the symbol table for the setting
	for SEC_LINK_DUPLICATES.
	(coff_write_object_contents): If COFF_WITH_PE, if SEC_LINK_ONCE is
	set for a section, find the section symbol in the symbol table,
	and set the aux entry based on SEC_LINK_DUPLICATES.
	* coffgen.c (coff_print_symbol): Add a space before "checksum".
	* coff-arm.c (armcoff_big_vec): If COFF_WITH_PE is defined, add
	SEC_LINK_ONCE and SEC_LINK_DUPLICATES to section_flags.
	* coff-i386.c (i386coff_vec): Likewise.
	* coff-ppc.c (TARGET_LITTLE_SYM, TARGET_BIG_SYM): Likewise.
This commit is contained in:
Ian Lance Taylor 1996-03-29 21:33:59 +00:00
parent c31418c180
commit 5a28331f6d
5 changed files with 227 additions and 14 deletions

View File

@ -1,5 +1,27 @@
Fri Mar 29 12:44:36 1996 Ian Lance Taylor <ian@cygnus.com>
* section.c (SEC_LINK_ONCE): Define.
(SEC_LINK_DUPLICATES): Define.
(SEC_LINK_DUPLICATES_DISCARD): Define.
(SEC_LINK_DUPLICATES_ONE_ONLY): Define.
(SEC_LINK_DUPLICATES_SAME_SIZE): Define.
(SEC_LINK_DUPLICATES_SAME_CONTENTS): Define.
* bfd-in2.h: Rebuild.
* coffcode.h (sec_to_styp_flags): If COFF_WITH_PE, turn
SEC_LINK_ONCE into IMAGE_SCN_LNK_COMDAT.
(styp_to_sec_flags): If COFF_WITH_PE, turn IMAGE_SCN_LNK_REMOVE
into SEC_EXCLUDE. If IMAGE_SCN_LNK_COMDAT is set, set
SEC_LINK_ONCE, and look through the symbol table for the setting
for SEC_LINK_DUPLICATES.
(coff_write_object_contents): If COFF_WITH_PE, if SEC_LINK_ONCE is
set for a section, find the section symbol in the symbol table,
and set the aux entry based on SEC_LINK_DUPLICATES.
* coffgen.c (coff_print_symbol): Add a space before "checksum".
* coff-arm.c (armcoff_big_vec): If COFF_WITH_PE is defined, add
SEC_LINK_ONCE and SEC_LINK_DUPLICATES to section_flags.
* coff-i386.c (i386coff_vec): Likewise.
* coff-ppc.c (TARGET_LITTLE_SYM, TARGET_BIG_SYM): Likewise.
* VERSION: Bump to 2.6.1.
* Makefile.in (stamp-h): Depend upon VERSION.

View File

@ -862,7 +862,7 @@ typedef struct sec
sections. */
#define SEC_COFF_SHARED_LIBRARY 0x800
/* The section is a common section (symbols may be defined
/* The section contains common symbols (symbols may be defined
multiple times, the value of a symbol is the amount of
space it requires, and the largest symbol value is the one
used). Most targets have exactly one of these (which we
@ -891,6 +891,34 @@ typedef struct sec
table. */
#define SEC_SORT_ENTRIES 0x80000
/* When linking, duplicate sections of the same name should be
discarded, rather than being combined into a single section as
is usually done. This is similar to how common symbols are
handled. See SEC_LINK_DUPLICATES below. */
#define SEC_LINK_ONCE 0x100000
/* If SEC_LINK_ONCE is set, this bitfield describes how the linker
should handle duplicate sections. */
#define SEC_LINK_DUPLICATES 0x600000
/* This value for SEC_LINK_DUPLICATES means that duplicate
sections with the same name should simply be discarded. */
#define SEC_LINK_DUPLICATES_DISCARD 0x0
/* This value for SEC_LINK_DUPLICATES means that the linker
should warn if there are any duplicate sections, although
it should still only link one copy. */
#define SEC_LINK_DUPLICATES_ONE_ONLY 0x200000
/* This value for SEC_LINK_DUPLICATES means that the linker
should warn if any duplicate sections are a different size. */
#define SEC_LINK_DUPLICATES_SAME_SIZE 0x400000
/* This value for SEC_LINK_DUPLICATES means that the linker
should warn if any duplicate sections contain different
contents. */
#define SEC_LINK_DUPLICATES_SAME_CONTENTS 0x600000
/* End of section flags. */
/* Some internal packed boolean fields. */

View File

@ -3191,7 +3191,13 @@ TARGET_LITTLE_SYM =
HAS_LINENO | HAS_DEBUG |
HAS_SYMS | HAS_LOCALS | WP_TEXT),
#ifndef COFF_WITH_PE
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
#else
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
| SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
#endif
0, /* leading char */
'/', /* ar_pad_char */
15, /* ar_max_namelen??? FIXMEmgo */
@ -3238,7 +3244,13 @@ TARGET_BIG_SYM =
HAS_LINENO | HAS_DEBUG |
HAS_SYMS | HAS_LOCALS | WP_TEXT),
#ifndef COFF_WITH_PE
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
#else
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* section flags */
| SEC_LINK_ONCE | SEC_LINK_DUPLICATES),
#endif
0, /* leading char */
'/', /* ar_pad_char */
15, /* ar_max_namelen??? FIXMEmgo */

View File

@ -414,6 +414,11 @@ sec_to_styp_flags (sec_name, sec_flags)
styp_flags |= STYP_NOLOAD;
#endif
#ifdef COFF_WITH_PE
if (sec_flags & SEC_LINK_ONCE)
styp_flags |= IMAGE_SCN_LNK_COMDAT;
#endif
return (styp_flags);
}
/*
@ -542,6 +547,96 @@ styp_to_sec_flags (abfd, hdr, name)
}
#endif /* STYP_SDATA */
#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. */
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
&& isym._n._n_n._n_zeroes != 0)
{
char buf[SYMNMLEN + 1];
memcpy (buf, isym._n._n_name, SYMNMLEN);
buf[SYMNMLEN] = '\0';
if (strcmp (name, buf) == 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);
switch (aux.x_scn.x_comdat)
{
case IMAGE_COMDAT_SELECT_NODUPLICATES:
sec_flags |= SEC_LINK_DUPLICATES_ONE_ONLY;
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:
/* FIXME: This is not currently implemented. */
sec_flags |= SEC_LINK_DUPLICATES_DISCARD;
break;
}
break;
}
}
esym += (isym.n_numaux + 1) * SYMESZ;
}
}
}
#endif
return (sec_flags);
}
@ -2361,6 +2456,63 @@ coff_write_object_contents (abfd)
|| bfd_write ((PTR) (&buff), 1, SCNHSZ, abfd) != SCNHSZ)
return false;
}
#ifdef COFF_WITH_PE
/* PE stores COMDAT section information in the symbol table. If
this section is supposed to have some COMDAT info, track down
the symbol in the symbol table and modify it. */
if ((current->flags & SEC_LINK_ONCE) != 0)
{
unsigned int i, count;
asymbol **psym;
count = bfd_get_symcount (abfd);
for (i = 0, psym = abfd->outsymbols; i < count; i++, psym++)
{
coff_symbol_type *csym;
combined_entry_type *aux;
if (strcmp ((*psym)->name, current->name) != 0)
continue;
csym = coff_symbol_from (abfd, *psym);
if (csym == NULL
|| csym->native == NULL
|| csym->native->u.syment.n_numaux < 1
|| csym->native->u.syment.n_sclass != C_STAT
|| csym->native->u.syment.n_type != T_NULL)
continue;
/* Here *PSYM is the section symbol for CURRENT. */
/* We don't touch the x_checksum field. The
x_associated field is not currently supported. */
aux = csym->native + 1;
switch (current->flags & SEC_LINK_DUPLICATES)
{
case SEC_LINK_DUPLICATES_DISCARD:
aux->u.auxent.x_scn.x_comdat = IMAGE_COMDAT_SELECT_ANY;
break;
case SEC_LINK_DUPLICATES_ONE_ONLY:
aux->u.auxent.x_scn.x_comdat =
IMAGE_COMDAT_SELECT_NODUPLICATES;
break;
case SEC_LINK_DUPLICATES_SAME_SIZE:
aux->u.auxent.x_scn.x_comdat =
IMAGE_COMDAT_SELECT_SAME_SIZE;
break;
case SEC_LINK_DUPLICATES_SAME_CONTENTS:
aux->u.auxent.x_scn.x_comdat =
IMAGE_COMDAT_SELECT_EXACT_MATCH;
break;
}
}
}
#endif /* COFF_WITH_PE */
}
#ifdef RS6000COFF_C
@ -3055,15 +3207,14 @@ coff_slurp_symbol_table (abfd)
dst->symbol.flags = BSF_DEBUGGING;
else
dst->symbol.flags = BSF_LOCAL;
/*
Base the value as an index from the base of the section, if
there is one
*/
/* Base the value as an index from the base of the
section, if there is one. */
if (dst->symbol.section)
dst->symbol.value = (src->u.syment.n_value) -
dst->symbol.section->vma;
dst->symbol.value = (src->u.syment.n_value
- dst->symbol.section->vma);
else
dst->symbol.value = (src->u.syment.n_value);
dst->symbol.value = src->u.syment.n_value;
break;
case C_MOS: /* member of structure */
@ -3154,13 +3305,13 @@ coff_slurp_symbol_table (abfd)
#endif
case C_BLOCK: /* ".bb" or ".eb" */
case C_FCN: /* ".bf" or ".ef" */
case C_FCN: /* ".bf" or ".ef" */
case C_EFCN: /* physical end of function */
dst->symbol.flags = BSF_LOCAL;
/*
Base the value as an index from the base of the section
*/
dst->symbol.value = (src->u.syment.n_value) - dst->symbol.section->vma;
/* Base the value as an index from the base of the
section. */
dst->symbol.value = (src->u.syment.n_value
- dst->symbol.section->vma);
break;
case C_NULL:

View File

@ -1877,7 +1877,7 @@ coff_print_symbol (abfd, filep, symbol, how)
if (auxp->u.auxent.x_scn.x_checksum != 0
|| auxp->u.auxent.x_scn.x_associated != 0
|| auxp->u.auxent.x_scn.x_comdat != 0)
fprintf (file, "checksum 0x%lx assoc %d comdat %d",
fprintf (file, " checksum 0x%lx assoc %d comdat %d",
auxp->u.auxent.x_scn.x_checksum,
auxp->u.auxent.x_scn.x_associated,
auxp->u.auxent.x_scn.x_comdat);