* 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:
parent
c31418c180
commit
5a28331f6d
|
@ -1,5 +1,27 @@
|
||||||
Fri Mar 29 12:44:36 1996 Ian Lance Taylor <ian@cygnus.com>
|
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.
|
* VERSION: Bump to 2.6.1.
|
||||||
* Makefile.in (stamp-h): Depend upon VERSION.
|
* Makefile.in (stamp-h): Depend upon VERSION.
|
||||||
|
|
||||||
|
|
|
@ -862,7 +862,7 @@ typedef struct sec
|
||||||
sections. */
|
sections. */
|
||||||
#define SEC_COFF_SHARED_LIBRARY 0x800
|
#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
|
multiple times, the value of a symbol is the amount of
|
||||||
space it requires, and the largest symbol value is the one
|
space it requires, and the largest symbol value is the one
|
||||||
used). Most targets have exactly one of these (which we
|
used). Most targets have exactly one of these (which we
|
||||||
|
@ -891,6 +891,34 @@ typedef struct sec
|
||||||
table. */
|
table. */
|
||||||
#define SEC_SORT_ENTRIES 0x80000
|
#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. */
|
/* End of section flags. */
|
||||||
|
|
||||||
/* Some internal packed boolean fields. */
|
/* Some internal packed boolean fields. */
|
||||||
|
|
|
@ -3191,7 +3191,13 @@ TARGET_LITTLE_SYM =
|
||||||
HAS_LINENO | HAS_DEBUG |
|
HAS_LINENO | HAS_DEBUG |
|
||||||
HAS_SYMS | HAS_LOCALS | WP_TEXT),
|
HAS_SYMS | HAS_LOCALS | WP_TEXT),
|
||||||
|
|
||||||
|
#ifndef COFF_WITH_PE
|
||||||
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
|
(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 */
|
0, /* leading char */
|
||||||
'/', /* ar_pad_char */
|
'/', /* ar_pad_char */
|
||||||
15, /* ar_max_namelen??? FIXMEmgo */
|
15, /* ar_max_namelen??? FIXMEmgo */
|
||||||
|
@ -3238,7 +3244,13 @@ TARGET_BIG_SYM =
|
||||||
HAS_LINENO | HAS_DEBUG |
|
HAS_LINENO | HAS_DEBUG |
|
||||||
HAS_SYMS | HAS_LOCALS | WP_TEXT),
|
HAS_SYMS | HAS_LOCALS | WP_TEXT),
|
||||||
|
|
||||||
|
#ifndef COFF_WITH_PE
|
||||||
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
|
(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 */
|
0, /* leading char */
|
||||||
'/', /* ar_pad_char */
|
'/', /* ar_pad_char */
|
||||||
15, /* ar_max_namelen??? FIXMEmgo */
|
15, /* ar_max_namelen??? FIXMEmgo */
|
||||||
|
|
173
bfd/coffcode.h
173
bfd/coffcode.h
|
@ -414,6 +414,11 @@ sec_to_styp_flags (sec_name, sec_flags)
|
||||||
styp_flags |= STYP_NOLOAD;
|
styp_flags |= STYP_NOLOAD;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef COFF_WITH_PE
|
||||||
|
if (sec_flags & SEC_LINK_ONCE)
|
||||||
|
styp_flags |= IMAGE_SCN_LNK_COMDAT;
|
||||||
|
#endif
|
||||||
|
|
||||||
return (styp_flags);
|
return (styp_flags);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -542,6 +547,96 @@ styp_to_sec_flags (abfd, hdr, name)
|
||||||
}
|
}
|
||||||
#endif /* STYP_SDATA */
|
#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);
|
return (sec_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2361,6 +2456,63 @@ coff_write_object_contents (abfd)
|
||||||
|| bfd_write ((PTR) (&buff), 1, SCNHSZ, abfd) != SCNHSZ)
|
|| bfd_write ((PTR) (&buff), 1, SCNHSZ, abfd) != SCNHSZ)
|
||||||
return false;
|
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
|
#ifdef RS6000COFF_C
|
||||||
|
@ -3055,15 +3207,14 @@ coff_slurp_symbol_table (abfd)
|
||||||
dst->symbol.flags = BSF_DEBUGGING;
|
dst->symbol.flags = BSF_DEBUGGING;
|
||||||
else
|
else
|
||||||
dst->symbol.flags = BSF_LOCAL;
|
dst->symbol.flags = BSF_LOCAL;
|
||||||
/*
|
|
||||||
Base the value as an index from the base of the section, if
|
/* Base the value as an index from the base of the
|
||||||
there is one
|
section, if there is one. */
|
||||||
*/
|
|
||||||
if (dst->symbol.section)
|
if (dst->symbol.section)
|
||||||
dst->symbol.value = (src->u.syment.n_value) -
|
dst->symbol.value = (src->u.syment.n_value
|
||||||
dst->symbol.section->vma;
|
- dst->symbol.section->vma);
|
||||||
else
|
else
|
||||||
dst->symbol.value = (src->u.syment.n_value);
|
dst->symbol.value = src->u.syment.n_value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case C_MOS: /* member of structure */
|
case C_MOS: /* member of structure */
|
||||||
|
@ -3157,10 +3308,10 @@ coff_slurp_symbol_table (abfd)
|
||||||
case C_FCN: /* ".bf" or ".ef" */
|
case C_FCN: /* ".bf" or ".ef" */
|
||||||
case C_EFCN: /* physical end of function */
|
case C_EFCN: /* physical end of function */
|
||||||
dst->symbol.flags = BSF_LOCAL;
|
dst->symbol.flags = BSF_LOCAL;
|
||||||
/*
|
/* Base the value as an index from the base of the
|
||||||
Base the value as an index from the base of the section
|
section. */
|
||||||
*/
|
dst->symbol.value = (src->u.syment.n_value
|
||||||
dst->symbol.value = (src->u.syment.n_value) - dst->symbol.section->vma;
|
- dst->symbol.section->vma);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case C_NULL:
|
case C_NULL:
|
||||||
|
|
|
@ -1877,7 +1877,7 @@ coff_print_symbol (abfd, filep, symbol, how)
|
||||||
if (auxp->u.auxent.x_scn.x_checksum != 0
|
if (auxp->u.auxent.x_scn.x_checksum != 0
|
||||||
|| auxp->u.auxent.x_scn.x_associated != 0
|
|| auxp->u.auxent.x_scn.x_associated != 0
|
||||||
|| auxp->u.auxent.x_scn.x_comdat != 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_checksum,
|
||||||
auxp->u.auxent.x_scn.x_associated,
|
auxp->u.auxent.x_scn.x_associated,
|
||||||
auxp->u.auxent.x_scn.x_comdat);
|
auxp->u.auxent.x_scn.x_comdat);
|
||||||
|
|
Loading…
Reference in New Issue