aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>1996-03-29 21:33:59 +0000
committerIan Lance Taylor <ian@airs.com>1996-03-29 21:33:59 +0000
commit5a28331f6dc965462a5380c381283b26edd283ca (patch)
treee63ec7fdb09e3dd1844229799eb0180d5d54e9fa /bfd
parentc31418c180236eb1aae59e3e415ab7578efb4d73 (diff)
downloadgdb-5a28331f6dc965462a5380c381283b26edd283ca.zip
gdb-5a28331f6dc965462a5380c381283b26edd283ca.tar.gz
gdb-5a28331f6dc965462a5380c381283b26edd283ca.tar.bz2
* 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.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog22
-rw-r--r--bfd/bfd-in2.h30
-rw-r--r--bfd/coff-ppc.c12
-rw-r--r--bfd/coffcode.h175
-rw-r--r--bfd/coffgen.c2
5 files changed, 227 insertions, 14 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 138afbc..be95467 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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.
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 148ee13..cd0f8d7 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -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. */
diff --git a/bfd/coff-ppc.c b/bfd/coff-ppc.c
index efc3776..d49348f 100644
--- a/bfd/coff-ppc.c
+++ b/bfd/coff-ppc.c
@@ -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 */
diff --git a/bfd/coffcode.h b/bfd/coffcode.h
index 0a7c730..7f15ef8 100644
--- a/bfd/coffcode.h
+++ b/bfd/coffcode.h
@@ -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:
diff --git a/bfd/coffgen.c b/bfd/coffgen.c
index bb9882b..14df3a3 100644
--- a/bfd/coffgen.c
+++ b/bfd/coffgen.c
@@ -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);