/* BFD backend for SunOS binaries.
- Copyright (C) 1990, 91, 92, 93, 94, 1995 Free Software Foundation, Inc.
+ Copyright (C) 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
#define MY_check_dynamic_reloc sunos_check_dynamic_reloc
#define MY_finish_dynamic_link sunos_finish_dynamic_link
+/* ??? Where should this go? */
+#define MACHTYPE_OK(mtype) \
+ (((mtype) == M_SPARC && bfd_lookup_arch (bfd_arch_sparc, 0) != NULL) \
+ || ((mtype) == M_SPARCLET \
+ && bfd_lookup_arch (bfd_arch_sparc, bfd_mach_sparc_sparclet) != NULL) \
+ || (((mtype) == M_UNKNOWN || (mtype) == M_68010 || (mtype) == M_68020) \
+ && bfd_lookup_arch (bfd_arch_m68k, 0) != NULL))
+
/* Include the usual a.out support. */
#include "aoutf1.h"
/* Symbol is defined by a regular object. */
#define SUNOS_DEF_REGULAR 02
/* Symbol is referenced by a dynamic object. */
-#define SUNOS_REF_DYNAMIC 010
+#define SUNOS_REF_DYNAMIC 04
/* Symbol is defined by a dynamic object. */
-#define SUNOS_DEF_DYNAMIC 020
+#define SUNOS_DEF_DYNAMIC 010
+ /* Symbol is a constructor symbol in a regular object. */
+#define SUNOS_CONSTRUCTOR 020
};
/* The SunOS linker hash table. */
return false;
}
- h = sunos_link_hash_lookup (sunos_hash_table (info), name, true, copy,
- false);
+ if ((flags & (BSF_INDIRECT | BSF_WARNING | BSF_CONSTRUCTOR)) != 0
+ || ! bfd_is_und_section (section))
+ h = sunos_link_hash_lookup (sunos_hash_table (info), name, true, copy,
+ false);
+ else
+ h = ((struct sunos_link_hash_entry *)
+ bfd_wrapped_link_hash_lookup (abfd, info, name, true, copy, false));
if (h == NULL)
return false;
}
}
+ if ((abfd->flags & DYNAMIC) != 0
+ && abfd->xvec == info->hash->creator
+ && (h->flags & SUNOS_CONSTRUCTOR) != 0)
+ {
+ /* The existing symbol is a constructor symbol, and this symbol
+ is from a dynamic object. A constructor symbol is actually a
+ definition, although the type will be bfd_link_hash_undefined
+ at this point. We want to ignore the definition from the
+ dynamic object. */
+ section = bfd_und_section_ptr;
+ }
+ else if ((flags & BSF_CONSTRUCTOR) != 0
+ && (abfd->flags & DYNAMIC) == 0
+ && h->root.root.type == bfd_link_hash_defined
+ && h->root.root.u.def.section->owner != NULL
+ && (h->root.root.u.def.section->owner->flags & DYNAMIC) != 0)
+ {
+ /* The existing symbol is defined by a dynamic object, and this
+ is a constructor symbol. As above, we want to force the use
+ of the constructor symbol from the regular object. */
+ h->root.root.type = bfd_link_hash_new;
+ }
+
/* Do the usual procedure for adding a symbol. */
if (! _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section,
value, string, copy, collect,
++sunos_hash_table (info)->dynsymcount;
h->dynindx = -2;
}
+
+ if ((flags & BSF_CONSTRUCTOR) != 0
+ && (abfd->flags & DYNAMIC) == 0)
+ h->flags |= SUNOS_CONSTRUCTOR;
}
return true;
|| (h->flags & SUNOS_DEF_REGULAR) != 0))
continue;
+ if (r_type == RELOC_JMP_TBL
+ && ! info->shared
+ && (h->flags & SUNOS_DEF_DYNAMIC) == 0
+ && (h->flags & SUNOS_DEF_REGULAR) == 0)
+ {
+ /* This symbol is apparently undefined. Don't do anything
+ here; just let the relocation routine report an undefined
+ symbol. */
+ continue;
+ }
+
if (strcmp (h->root.root.root.string, "__GLOBAL_OFFSET_TABLE_") == 0)
continue;