aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>1996-08-08 20:33:39 +0000
committerIan Lance Taylor <ian@airs.com>1996-08-08 20:33:39 +0000
commitfbc4ed7dedc73753fbd583159848d6322ea6738a (patch)
treeb1674270b6cc4062e49b51800ead80525895eb9b /bfd
parent2d69131dabc5e776d8370a29553f048536c14684 (diff)
downloadfsf-binutils-gdb-fbc4ed7dedc73753fbd583159848d6322ea6738a.zip
fsf-binutils-gdb-fbc4ed7dedc73753fbd583159848d6322ea6738a.tar.gz
fsf-binutils-gdb-fbc4ed7dedc73753fbd583159848d6322ea6738a.tar.bz2
* xcofflink.c (XCOFF_MULTIPLY_DEFINED): Define.
(xcoff_link_add_symbols): Permit multiple definitions of a symbol as the AIX linker seems to do. PR 10304.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog6
-rw-r--r--bfd/xcofflink.c75
2 files changed, 74 insertions, 7 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 0fd25dd..16ff9cf 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,9 @@
+Thu Aug 8 16:24:55 1996 Ian Lance Taylor <ian@cygnus.com>
+
+ * xcofflink.c (XCOFF_MULTIPLY_DEFINED): Define.
+ (xcoff_link_add_symbols): Permit multiple definitions of a symbol
+ as the AIX linker seems to do.
+
Thu Aug 8 12:21:56 1996 Klaus Kaempf <kkaempf@progis.de>
* evax-alpha.c (evax_alpha_vec): Corrected flags, cleanup.
diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c
index a568043..8477444 100644
--- a/bfd/xcofflink.c
+++ b/bfd/xcofflink.c
@@ -300,6 +300,8 @@ struct xcoff_link_hash_entry
#define XCOFF_HAS_SIZE (04000)
/* Symbol is a function descriptor. */
#define XCOFF_DESCRIPTOR (010000)
+ /* Multiple definitions have been for the symbol. */
+#define XCOFF_MULTIPLY_DEFINED (020000)
/* The storage mapping class. */
unsigned char smclas;
@@ -2128,12 +2130,25 @@ xcoff_link_add_symbols (abfd, info)
|| sym._n._n_n._n_offset == 0)
copy = true;
+ /* The AIX linker appears to only detect multiple symbol
+ definitions when there is a reference to the symbol. If
+ a symbol is defined multiple times, and the only
+ references are from the same object file, the AIX linker
+ appears to permit it. It does not merge the different
+ definitions, but handles them independently. On the
+ other hand, if there is a reference, the linker reports
+ an error.
+
+ This matters because the AIX <net/net_globals.h> header
+ file actually defines an initialized array, so we have to
+ actually permit that to work.
+
+ We also have to handle the case of statically linking a
+ shared object, which will cause symbol redefinitions,
+ although this is an easier case to detect. */
+
if (info->hash->creator == abfd->xvec)
{
- /* If we are statically linking a shared object, it is
- OK for symbol redefinitions to occur. I can't figure
- out just what the XCOFF linker is doing, but
- something like this is required for -bnso to work. */
if (! bfd_is_und_section (section))
*sym_hash = xcoff_link_hash_lookup (xcoff_hash_table (info),
name, true, copy, false);
@@ -2148,25 +2163,71 @@ xcoff_link_add_symbols (abfd, info)
&& ! bfd_is_und_section (section)
&& ! bfd_is_com_section (section))
{
- /* If the existing symbol is to global linkage code,
- and this symbol is not global linkage code, then
- replace the existing symbol. */
+ /* This is a second definition of a defined symbol. */
if ((abfd->flags & DYNAMIC) != 0
&& ((*sym_hash)->smclas != XMC_GL
|| aux.x_csect.x_smclas == XMC_GL
|| ((*sym_hash)->root.u.def.section->owner->flags
& DYNAMIC) == 0))
{
+ /* The new symbol is from a shared library, and
+ either the existing symbol is not global
+ linkage code or this symbol is global linkage
+ code. If the existing symbol is global
+ linkage code and the new symbol is not, then
+ we want to use the new symbol. */
section = bfd_und_section_ptr;
value = 0;
}
else if (((*sym_hash)->root.u.def.section->owner->flags
& DYNAMIC) != 0)
{
+ /* The existing symbol is from a shared library.
+ Replace it. */
(*sym_hash)->root.type = bfd_link_hash_undefined;
(*sym_hash)->root.u.undef.abfd =
(*sym_hash)->root.u.def.section->owner;
}
+ else if ((*sym_hash)->root.next != NULL
+ || info->hash->undefs_tail == &(*sym_hash)->root)
+ {
+ /* This symbol has been referenced. In this
+ case, we just continue and permit the
+ multiple definition error. See the comment
+ above about the behaviour of the AIX linker. */
+ }
+ else if ((*sym_hash)->smclas == aux.x_csect.x_smclas)
+ {
+ /* The symbols are both csects of the same
+ class. There is at least a chance that this
+ is a semi-legitimate redefinition. */
+ section = bfd_und_section_ptr;
+ value = 0;
+ (*sym_hash)->flags |= XCOFF_MULTIPLY_DEFINED;
+ }
+ }
+ else if (((*sym_hash)->flags & XCOFF_MULTIPLY_DEFINED) != 0
+ && ((*sym_hash)->root.type == bfd_link_hash_defined
+ || (*sym_hash)->root.type == bfd_link_hash_defweak)
+ && (bfd_is_und_section (section)
+ || bfd_is_com_section (section)))
+ {
+ /* This is a reference to a multiply defined symbol.
+ Report the error now. See the comment above
+ about the behaviour of the AIX linker. We could
+ also do this with warning symbols, but I'm not
+ sure the XCOFF linker is wholly prepared to
+ handle them, and that would only be a warning,
+ not an error. */
+ if (! ((*info->callbacks->multiple_definition)
+ (info, (*sym_hash)->root.root.string,
+ (bfd *) NULL, (asection *) NULL, 0,
+ (*sym_hash)->root.u.def.section->owner,
+ (*sym_hash)->root.u.def.section,
+ (*sym_hash)->root.u.def.value)))
+ goto error_return;
+ /* Try not to give this error too many times. */
+ (*sym_hash)->flags &= ~XCOFF_MULTIPLY_DEFINED;
}
}