/* BFD backend for SunOS binaries.
   Copyright 1990, 1991, 1992, 1994, 1995, 1996, 1997, 1998, 2000, 2001,
   2002 Free Software Foundation, Inc.
   Written by Cygnus Support.

This file is part of BFD, the Binary File Descriptor library.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */

#define TARGETNAME "a.out-sunos-big"

/* Do not "beautify" the CONCAT* macro args.  Traditional C will not
   remove whitespace added here, and thus will fail to concatenate
   the tokens.  */
#define MY(OP) CONCAT2 (sunos_big_,OP)

#include "bfd.h"
#include "bfdlink.h"
#include "libaout.h"

/* Static routines defined in this file.  */

static bfd_boolean sunos_read_dynamic_info PARAMS ((bfd *));
static long sunos_get_dynamic_symtab_upper_bound PARAMS ((bfd *));
static bfd_boolean sunos_slurp_dynamic_symtab PARAMS ((bfd *));
static long sunos_canonicalize_dynamic_symtab PARAMS ((bfd *, asymbol **));
static long sunos_get_dynamic_reloc_upper_bound PARAMS ((bfd *));
static long sunos_canonicalize_dynamic_reloc
  PARAMS ((bfd *, arelent **, asymbol **));
static struct bfd_hash_entry *sunos_link_hash_newfunc
  PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
static struct bfd_link_hash_table *sunos_link_hash_table_create
  PARAMS ((bfd *));
static bfd_boolean sunos_create_dynamic_sections
  PARAMS ((bfd *, struct bfd_link_info *, bfd_boolean));
static bfd_boolean sunos_add_dynamic_symbols
  PARAMS ((bfd *, struct bfd_link_info *, struct external_nlist **,
	   bfd_size_type *, char **));
static bfd_boolean sunos_add_one_symbol
  PARAMS ((struct bfd_link_info *, bfd *, const char *, flagword, asection *,
	   bfd_vma, const char *, bfd_boolean, bfd_boolean,
	   struct bfd_link_hash_entry **));
static bfd_boolean sunos_scan_relocs
  PARAMS ((struct bfd_link_info *, bfd *, asection *, bfd_size_type));
static bfd_boolean sunos_scan_std_relocs
  PARAMS ((struct bfd_link_info *, bfd *, asection *,
	   const struct reloc_std_external *, bfd_size_type));
static bfd_boolean sunos_scan_ext_relocs
  PARAMS ((struct bfd_link_info *, bfd *, asection *,
	   const struct reloc_ext_external *, bfd_size_type));
static bfd_boolean sunos_link_dynamic_object
  PARAMS ((struct bfd_link_info *, bfd *));
static bfd_boolean sunos_write_dynamic_symbol
  PARAMS ((bfd *, struct bfd_link_info *, struct aout_link_hash_entry *));
static bfd_boolean sunos_check_dynamic_reloc
  PARAMS ((struct bfd_link_info *, bfd *, asection *,
	   struct aout_link_hash_entry *, PTR, bfd_byte *, bfd_boolean *,
	   bfd_vma *));
static bfd_boolean sunos_finish_dynamic_link
  PARAMS ((bfd *, struct bfd_link_info *));

#define MY_get_dynamic_symtab_upper_bound sunos_get_dynamic_symtab_upper_bound
#define MY_canonicalize_dynamic_symtab sunos_canonicalize_dynamic_symtab
#define MY_get_dynamic_reloc_upper_bound sunos_get_dynamic_reloc_upper_bound
#define MY_canonicalize_dynamic_reloc sunos_canonicalize_dynamic_reloc
#define MY_bfd_link_hash_table_create sunos_link_hash_table_create
#define MY_add_dynamic_symbols sunos_add_dynamic_symbols
#define MY_add_one_symbol sunos_add_one_symbol
#define MY_link_dynamic_object sunos_link_dynamic_object
#define MY_write_dynamic_symbol sunos_write_dynamic_symbol
#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_SPARCLITE_LE \
       && 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"

/* The SunOS 4.1.4 /usr/include/locale.h defines valid as a macro.  */
#undef valid

/* SunOS shared library support.  We store a pointer to this structure
   in obj_aout_dynamic_info (abfd).  */

struct sunos_dynamic_info
{
  /* Whether we found any dynamic information.  */
  bfd_boolean valid;
  /* Dynamic information.  */
  struct internal_sun4_dynamic_link dyninfo;
  /* Number of dynamic symbols.  */
  unsigned long dynsym_count;
  /* Read in nlists for dynamic symbols.  */
  struct external_nlist *dynsym;
  /* asymbol structures for dynamic symbols.  */
  aout_symbol_type *canonical_dynsym;
  /* Read in dynamic string table.  */
  char *dynstr;
  /* Number of dynamic relocs.  */
  unsigned long dynrel_count;
  /* Read in dynamic relocs.  This may be reloc_std_external or
     reloc_ext_external.  */
  PTR dynrel;
  /* arelent structures for dynamic relocs.  */
  arelent *canonical_dynrel;
};

/* The hash table of dynamic symbols is composed of two word entries.
   See include/aout/sun4.h for details.  */

#define HASH_ENTRY_SIZE (2 * BYTES_IN_WORD)

/* Read in the basic dynamic information.  This locates the __DYNAMIC
   structure and uses it to find the dynamic_link structure.  It
   creates and saves a sunos_dynamic_info structure.  If it can't find
   __DYNAMIC, it sets the valid field of the sunos_dynamic_info
   structure to FALSE to avoid doing this work again.  */

static bfd_boolean
sunos_read_dynamic_info (abfd)
     bfd *abfd;
{
  struct sunos_dynamic_info *info;
  asection *dynsec;
  bfd_vma dynoff;
  struct external_sun4_dynamic dyninfo;
  unsigned long dynver;
  struct external_sun4_dynamic_link linkinfo;
  bfd_size_type amt;

  if (obj_aout_dynamic_info (abfd) != (PTR) NULL)
    return TRUE;

  if ((abfd->flags & DYNAMIC) == 0)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return FALSE;
    }

  amt = sizeof (struct sunos_dynamic_info);
  info = (struct sunos_dynamic_info *) bfd_zalloc (abfd, amt);
  if (!info)
    return FALSE;
  info->valid = FALSE;
  info->dynsym = NULL;
  info->dynstr = NULL;
  info->canonical_dynsym = NULL;
  info->dynrel = NULL;
  info->canonical_dynrel = NULL;
  obj_aout_dynamic_info (abfd) = (PTR) info;

  /* This code used to look for the __DYNAMIC symbol to locate the dynamic
     linking information.
     However this inhibits recovering the dynamic symbols from a
     stripped object file, so blindly assume that the dynamic linking
     information is located at the start of the data section.
     We could verify this assumption later by looking through the dynamic
     symbols for the __DYNAMIC symbol.  */
  if ((abfd->flags & DYNAMIC) == 0)
    return TRUE;
  if (! bfd_get_section_contents (abfd, obj_datasec (abfd), (PTR) &dyninfo,
				  (file_ptr) 0,
				  (bfd_size_type) sizeof dyninfo))
    return TRUE;

  dynver = GET_WORD (abfd, dyninfo.ld_version);
  if (dynver != 2 && dynver != 3)
    return TRUE;

  dynoff = GET_WORD (abfd, dyninfo.ld);

  /* dynoff is a virtual address.  It is probably always in the .data
     section, but this code should work even if it moves.  */
  if (dynoff < bfd_get_section_vma (abfd, obj_datasec (abfd)))
    dynsec = obj_textsec (abfd);
  else
    dynsec = obj_datasec (abfd);
  dynoff -= bfd_get_section_vma (abfd, dynsec);
  if (dynoff > bfd_section_size (abfd, dynsec))
    return TRUE;

  /* This executable appears to be dynamically linked in a way that we
     can understand.  */
  if (! bfd_get_section_contents (abfd, dynsec, (PTR) &linkinfo,
				  (file_ptr) dynoff,
				  (bfd_size_type) sizeof linkinfo))
    return TRUE;

  /* Swap in the dynamic link information.  */
  info->dyninfo.ld_loaded = GET_WORD (abfd, linkinfo.ld_loaded);
  info->dyninfo.ld_need = GET_WORD (abfd, linkinfo.ld_need);
  info->dyninfo.ld_rules = GET_WORD (abfd, linkinfo.ld_rules);
  info->dyninfo.ld_got = GET_WORD (abfd, linkinfo.ld_got);
  info->dyninfo.ld_plt = GET_WORD (abfd, linkinfo.ld_plt);
  info->dyninfo.ld_rel = GET_WORD (abfd, linkinfo.ld_rel);
  info->dyninfo.ld_hash = GET_WORD (abfd, linkinfo.ld_hash);
  info->dyninfo.ld_stab = GET_WORD (abfd, linkinfo.ld_stab);
  info->dyninfo.ld_stab_hash = GET_WORD (abfd, linkinfo.ld_stab_hash);
  info->dyninfo.ld_buckets = GET_WORD (abfd, linkinfo.ld_buckets);
  info->dyninfo.ld_symbols = GET_WORD (abfd, linkinfo.ld_symbols);
  info->dyninfo.ld_symb_size = GET_WORD (abfd, linkinfo.ld_symb_size);
  info->dyninfo.ld_text = GET_WORD (abfd, linkinfo.ld_text);
  info->dyninfo.ld_plt_sz = GET_WORD (abfd, linkinfo.ld_plt_sz);

  /* Reportedly the addresses need to be offset by the size of the
     exec header in an NMAGIC file.  */
  if (adata (abfd).magic == n_magic)
    {
      unsigned long exec_bytes_size = adata (abfd).exec_bytes_size;

      info->dyninfo.ld_need += exec_bytes_size;
      info->dyninfo.ld_rules += exec_bytes_size;
      info->dyninfo.ld_rel += exec_bytes_size;
      info->dyninfo.ld_hash += exec_bytes_size;
      info->dyninfo.ld_stab += exec_bytes_size;
      info->dyninfo.ld_symbols += exec_bytes_size;
    }

  /* The only way to get the size of the symbol information appears to
     be to determine the distance between it and the string table.  */
  info->dynsym_count = ((info->dyninfo.ld_symbols - info->dyninfo.ld_stab)
			/ EXTERNAL_NLIST_SIZE);
  BFD_ASSERT (info->dynsym_count * EXTERNAL_NLIST_SIZE
	      == (unsigned long) (info->dyninfo.ld_symbols
				  - info->dyninfo.ld_stab));

  /* Similarly, the relocs end at the hash table.  */
  info->dynrel_count = ((info->dyninfo.ld_hash - info->dyninfo.ld_rel)
			/ obj_reloc_entry_size (abfd));
  BFD_ASSERT (info->dynrel_count * obj_reloc_entry_size (abfd)
	      == (unsigned long) (info->dyninfo.ld_hash
				  - info->dyninfo.ld_rel));

  info->valid = TRUE;

  return TRUE;
}

/* Return the amount of memory required for the dynamic symbols.  */

static long
sunos_get_dynamic_symtab_upper_bound (abfd)
     bfd *abfd;
{
  struct sunos_dynamic_info *info;

  if (! sunos_read_dynamic_info (abfd))
    return -1;

  info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd);
  if (! info->valid)
    {
      bfd_set_error (bfd_error_no_symbols);
      return -1;
    }

  return (info->dynsym_count + 1) * sizeof (asymbol *);
}

/* Read the external dynamic symbols.  */

static bfd_boolean
sunos_slurp_dynamic_symtab (abfd)
     bfd *abfd;
{
  struct sunos_dynamic_info *info;
  bfd_size_type amt;

  /* Get the general dynamic information.  */
  if (obj_aout_dynamic_info (abfd) == NULL)
    {
      if (! sunos_read_dynamic_info (abfd))
	  return FALSE;
    }

  info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd);
  if (! info->valid)
    {
      bfd_set_error (bfd_error_no_symbols);
      return FALSE;
    }

  /* Get the dynamic nlist structures.  */
  if (info->dynsym == (struct external_nlist *) NULL)
    {
      amt = (bfd_size_type) info->dynsym_count * EXTERNAL_NLIST_SIZE;
      info->dynsym = (struct external_nlist *) bfd_alloc (abfd, amt);
      if (info->dynsym == NULL && info->dynsym_count != 0)
	return FALSE;
      if (bfd_seek (abfd, (file_ptr) info->dyninfo.ld_stab, SEEK_SET) != 0
	  || bfd_bread ((PTR) info->dynsym, amt, abfd) != amt)
	{
	  if (info->dynsym != NULL)
	    {
	      bfd_release (abfd, info->dynsym);
	      info->dynsym = NULL;
	    }
	  return FALSE;
	}
    }

  /* Get the dynamic strings.  */
  if (info->dynstr == (char *) NULL)
    {
      amt = info->dyninfo.ld_symb_size;
      info->dynstr = (char *) bfd_alloc (abfd, amt);
      if (info->dynstr == NULL && info->dyninfo.ld_symb_size != 0)
	return FALSE;
      if (bfd_seek (abfd, (file_ptr) info->dyninfo.ld_symbols, SEEK_SET) != 0
	  || bfd_bread ((PTR) info->dynstr, amt, abfd) != amt)
	{
	  if (info->dynstr != NULL)
	    {
	      bfd_release (abfd, info->dynstr);
	      info->dynstr = NULL;
	    }
	  return FALSE;
	}
    }

  return TRUE;
}

/* Read in the dynamic symbols.  */

static long
sunos_canonicalize_dynamic_symtab (abfd, storage)
     bfd *abfd;
     asymbol **storage;
{
  struct sunos_dynamic_info *info;
  unsigned long i;

  if (! sunos_slurp_dynamic_symtab (abfd))
    return -1;

  info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd);

#ifdef CHECK_DYNAMIC_HASH
  /* Check my understanding of the dynamic hash table by making sure
     that each symbol can be located in the hash table.  */
  {
    bfd_size_type table_size;
    bfd_byte *table;
    bfd_size_type i;

    if (info->dyninfo.ld_buckets > info->dynsym_count)
      abort ();
    table_size = info->dyninfo.ld_stab - info->dyninfo.ld_hash;
    table = (bfd_byte *) bfd_malloc (table_size);
    if (table == NULL && table_size != 0)
      abort ();
    if (bfd_seek (abfd, (file_ptr) info->dyninfo.ld_hash, SEEK_SET) != 0
	|| bfd_bread ((PTR) table, table_size, abfd) != table_size)
      abort ();
    for (i = 0; i < info->dynsym_count; i++)
      {
	unsigned char *name;
	unsigned long hash;

	name = ((unsigned char *) info->dynstr
		+ GET_WORD (abfd, info->dynsym[i].e_strx));
	hash = 0;
	while (*name != '\0')
	  hash = (hash << 1) + *name++;
	hash &= 0x7fffffff;
	hash %= info->dyninfo.ld_buckets;
	while (GET_WORD (abfd, table + hash * HASH_ENTRY_SIZE) != i)
	  {
	    hash = GET_WORD (abfd,
			     table + hash * HASH_ENTRY_SIZE + BYTES_IN_WORD);
	    if (hash == 0 || hash >= table_size / HASH_ENTRY_SIZE)
	      abort ();
	  }
      }
    free (table);
  }
#endif /* CHECK_DYNAMIC_HASH */

  /* Get the asymbol structures corresponding to the dynamic nlist
     structures.  */
  if (info->canonical_dynsym == (aout_symbol_type *) NULL)
    {
      bfd_size_type size;
      bfd_size_type strsize = info->dyninfo.ld_symb_size;

      size = (bfd_size_type) info->dynsym_count * sizeof (aout_symbol_type);
      info->canonical_dynsym = (aout_symbol_type *) bfd_alloc (abfd, size);
      if (info->canonical_dynsym == NULL && info->dynsym_count != 0)
	return -1;

      if (! aout_32_translate_symbol_table (abfd, info->canonical_dynsym,
					    info->dynsym,
					    (bfd_size_type) info->dynsym_count,
					    info->dynstr, strsize, TRUE))
	{
	  if (info->canonical_dynsym != NULL)
	    {
	      bfd_release (abfd, info->canonical_dynsym);
	      info->canonical_dynsym = NULL;
	    }
	  return -1;
	}
    }

  /* Return pointers to the dynamic asymbol structures.  */
  for (i = 0; i < info->dynsym_count; i++)
    *storage++ = (asymbol *) (info->canonical_dynsym + i);
  *storage = NULL;

  return info->dynsym_count;
}

/* Return the amount of memory required for the dynamic relocs.  */

static long
sunos_get_dynamic_reloc_upper_bound (abfd)
     bfd *abfd;
{
  struct sunos_dynamic_info *info;

  if (! sunos_read_dynamic_info (abfd))
    return -1;

  info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd);
  if (! info->valid)
    {
      bfd_set_error (bfd_error_no_symbols);
      return -1;
    }

  return (info->dynrel_count + 1) * sizeof (arelent *);
}

/* Read in the dynamic relocs.  */

static long
sunos_canonicalize_dynamic_reloc (abfd, storage, syms)
     bfd *abfd;
     arelent **storage;
     asymbol **syms;
{
  struct sunos_dynamic_info *info;
  unsigned long i;
  bfd_size_type size;

  /* Get the general dynamic information.  */
  if (obj_aout_dynamic_info (abfd) == (PTR) NULL)
    {
      if (! sunos_read_dynamic_info (abfd))
	return -1;
    }

  info = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd);
  if (! info->valid)
    {
      bfd_set_error (bfd_error_no_symbols);
      return -1;
    }

  /* Get the dynamic reloc information.  */
  if (info->dynrel == NULL)
    {
      size = (bfd_size_type) info->dynrel_count * obj_reloc_entry_size (abfd);
      info->dynrel = (PTR) bfd_alloc (abfd, size);
      if (info->dynrel == NULL && size != 0)
	return -1;
      if (bfd_seek (abfd, (file_ptr) info->dyninfo.ld_rel, SEEK_SET) != 0
	  || bfd_bread ((PTR) info->dynrel, size, abfd) != size)
	{
	  if (info->dynrel != NULL)
	    {
	      bfd_release (abfd, info->dynrel);
	      info->dynrel = NULL;
	    }
	  return -1;
	}
    }

  /* Get the arelent structures corresponding to the dynamic reloc
     information.  */
  if (info->canonical_dynrel == (arelent *) NULL)
    {
      arelent *to;

      size = (bfd_size_type) info->dynrel_count * sizeof (arelent);
      info->canonical_dynrel = (arelent *) bfd_alloc (abfd, size);
      if (info->canonical_dynrel == NULL && info->dynrel_count != 0)
	return -1;

      to = info->canonical_dynrel;

      if (obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE)
	{
	  register struct reloc_ext_external *p;
	  struct reloc_ext_external *pend;

	  p = (struct reloc_ext_external *) info->dynrel;
	  pend = p + info->dynrel_count;
	  for (; p < pend; p++, to++)
	    NAME(aout,swap_ext_reloc_in) (abfd, p, to, syms,
					  (bfd_size_type) info->dynsym_count);
	}
      else
	{
	  register struct reloc_std_external *p;
	  struct reloc_std_external *pend;

	  p = (struct reloc_std_external *) info->dynrel;
	  pend = p + info->dynrel_count;
	  for (; p < pend; p++, to++)
	    NAME(aout,swap_std_reloc_in) (abfd, p, to, syms,
					  (bfd_size_type) info->dynsym_count);
	}
    }

  /* Return pointers to the dynamic arelent structures.  */
  for (i = 0; i < info->dynrel_count; i++)
    *storage++ = info->canonical_dynrel + i;
  *storage = NULL;

  return info->dynrel_count;
}

/* Code to handle linking of SunOS shared libraries.  */

/* A SPARC procedure linkage table entry is 12 bytes.  The first entry
   in the table is a jump which is filled in by the runtime linker.
   The remaining entries are branches back to the first entry,
   followed by an index into the relocation table encoded to look like
   a sethi of %g0.  */

#define SPARC_PLT_ENTRY_SIZE (12)

static const bfd_byte sparc_plt_first_entry[SPARC_PLT_ENTRY_SIZE] =
{
  /* sethi %hi(0),%g1; address filled in by runtime linker.  */
  0x3, 0, 0, 0,
  /* jmp %g1; offset filled in by runtime linker.  */
  0x81, 0xc0, 0x60, 0,
  /* nop */
  0x1, 0, 0, 0
};

/* save %sp, -96, %sp */
#define SPARC_PLT_ENTRY_WORD0 ((bfd_vma) 0x9de3bfa0)
/* call; address filled in later.  */
#define SPARC_PLT_ENTRY_WORD1 ((bfd_vma) 0x40000000)
/* sethi; reloc index filled in later.  */
#define SPARC_PLT_ENTRY_WORD2 ((bfd_vma) 0x01000000)

/* This sequence is used when for the jump table entry to a defined
   symbol in a complete executable.  It is used when linking PIC
   compiled code which is not being put into a shared library.  */
/* sethi <address to be filled in later>, %g1 */
#define SPARC_PLT_PIC_WORD0 ((bfd_vma) 0x03000000)
/* jmp %g1 + <address to be filled in later> */
#define SPARC_PLT_PIC_WORD1 ((bfd_vma) 0x81c06000)
/* nop */
#define SPARC_PLT_PIC_WORD2 ((bfd_vma) 0x01000000)

/* An m68k procedure linkage table entry is 8 bytes.  The first entry
   in the table is a jump which is filled in the by the runtime
   linker.  The remaining entries are branches back to the first
   entry, followed by a two byte index into the relocation table.  */

#define M68K_PLT_ENTRY_SIZE (8)

static const bfd_byte m68k_plt_first_entry[M68K_PLT_ENTRY_SIZE] =
{
  /* jmps @# */
  0x4e, 0xf9,
  /* Filled in by runtime linker with a magic address.  */
  0, 0, 0, 0,
  /* Not used?  */
  0, 0
};

/* bsrl */
#define M68K_PLT_ENTRY_WORD0 ((bfd_vma) 0x61ff)
/* Remaining words filled in later.  */

/* An entry in the SunOS linker hash table.  */

struct sunos_link_hash_entry
{
  struct aout_link_hash_entry root;

  /* If this is a dynamic symbol, this is its index into the dynamic
     symbol table.  This is initialized to -1.  As the linker looks at
     the input files, it changes this to -2 if it will be added to the
     dynamic symbol table.  After all the input files have been seen,
     the linker will know whether to build a dynamic symbol table; if
     it does build one, this becomes the index into the table.  */
  long dynindx;

  /* If this is a dynamic symbol, this is the index of the name in the
     dynamic symbol string table.  */
  long dynstr_index;

  /* The offset into the global offset table used for this symbol.  If
     the symbol does not require a GOT entry, this is 0.  */
  bfd_vma got_offset;

  /* The offset into the procedure linkage table used for this symbol.
     If the symbol does not require a PLT entry, this is 0.  */
  bfd_vma plt_offset;

  /* Some linker flags.  */
  unsigned char flags;
  /* Symbol is referenced by a regular object.  */
#define SUNOS_REF_REGULAR 01
  /* Symbol is defined by a regular object.  */
#define SUNOS_DEF_REGULAR 02
  /* Symbol is referenced by a dynamic object.  */
#define SUNOS_REF_DYNAMIC 04
  /* Symbol is defined by a dynamic object.  */
#define SUNOS_DEF_DYNAMIC 010
  /* Symbol is a constructor symbol in a regular object.  */
#define SUNOS_CONSTRUCTOR 020
};

/* The SunOS linker hash table.  */

struct sunos_link_hash_table
{
  struct aout_link_hash_table root;

  /* The object which holds the dynamic sections.  */
  bfd *dynobj;

  /* Whether we have created the dynamic sections.  */
  bfd_boolean dynamic_sections_created;

  /* Whether we need the dynamic sections.  */
  bfd_boolean dynamic_sections_needed;

  /* Whether we need the .got table.  */
  bfd_boolean got_needed;

  /* The number of dynamic symbols.  */
  size_t dynsymcount;

  /* The number of buckets in the hash table.  */
  size_t bucketcount;

  /* The list of dynamic objects needed by dynamic objects included in
     the link.  */
  struct bfd_link_needed_list *needed;

  /* The offset of __GLOBAL_OFFSET_TABLE_ into the .got section.  */
  bfd_vma got_base;
};

/* Routine to create an entry in an SunOS link hash table.  */

static struct bfd_hash_entry *
sunos_link_hash_newfunc (entry, table, string)
     struct bfd_hash_entry *entry;
     struct bfd_hash_table *table;
     const char *string;
{
  struct sunos_link_hash_entry *ret = (struct sunos_link_hash_entry *) entry;

  /* Allocate the structure if it has not already been allocated by a
     subclass.  */
  if (ret == (struct sunos_link_hash_entry *) NULL)
    ret = ((struct sunos_link_hash_entry *)
	   bfd_hash_allocate (table, sizeof (struct sunos_link_hash_entry)));
  if (ret == (struct sunos_link_hash_entry *) NULL)
    return (struct bfd_hash_entry *) ret;

  /* Call the allocation method of the superclass.  */
  ret = ((struct sunos_link_hash_entry *)
	 NAME(aout,link_hash_newfunc) ((struct bfd_hash_entry *) ret,
				       table, string));
  if (ret != NULL)
    {
      /* Set local fields.  */
      ret->dynindx = -1;
      ret->dynstr_index = -1;
      ret->got_offset = 0;
      ret->plt_offset = 0;
      ret->flags = 0;
    }

  return (struct bfd_hash_entry *) ret;
}

/* Create a SunOS link hash table.  */

static struct bfd_link_hash_table *
sunos_link_hash_table_create (abfd)
     bfd *abfd;
{
  struct sunos_link_hash_table *ret;
  bfd_size_type amt = sizeof (struct sunos_link_hash_table);

  ret = (struct sunos_link_hash_table *) bfd_malloc (amt);
  if (ret == (struct sunos_link_hash_table *) NULL)
    return (struct bfd_link_hash_table *) NULL;
  if (! NAME(aout,link_hash_table_init) (&ret->root, abfd,
					 sunos_link_hash_newfunc))
    {
      free (ret);
      return (struct bfd_link_hash_table *) NULL;
    }

  ret->dynobj = NULL;
  ret->dynamic_sections_created = FALSE;
  ret->dynamic_sections_needed = FALSE;
  ret->got_needed = FALSE;
  ret->dynsymcount = 0;
  ret->bucketcount = 0;
  ret->needed = NULL;
  ret->got_base = 0;

  return &ret->root.root;
}

/* Look up an entry in an SunOS link hash table.  */

#define sunos_link_hash_lookup(table, string, create, copy, follow) \
  ((struct sunos_link_hash_entry *) \
   aout_link_hash_lookup (&(table)->root, (string), (create), (copy),\
			  (follow)))

/* Traverse a SunOS link hash table.  */

#define sunos_link_hash_traverse(table, func, info)			\
  (aout_link_hash_traverse						\
   (&(table)->root,							\
    (bfd_boolean (*) PARAMS ((struct aout_link_hash_entry *, PTR))) (func), \
    (info)))

/* Get the SunOS link hash table from the info structure.  This is
   just a cast.  */

#define sunos_hash_table(p) ((struct sunos_link_hash_table *) ((p)->hash))

static bfd_boolean sunos_scan_dynamic_symbol
  PARAMS ((struct sunos_link_hash_entry *, PTR));

/* Create the dynamic sections needed if we are linking against a
   dynamic object, or if we are linking PIC compiled code.  ABFD is a
   bfd we can attach the dynamic sections to.  The linker script will
   look for these special sections names and put them in the right
   place in the output file.  See include/aout/sun4.h for more details
   of the dynamic linking information.  */

static bfd_boolean
sunos_create_dynamic_sections (abfd, info, needed)
     bfd *abfd;
     struct bfd_link_info *info;
     bfd_boolean needed;
{
  asection *s;

  if (! sunos_hash_table (info)->dynamic_sections_created)
    {
      flagword flags;

      sunos_hash_table (info)->dynobj = abfd;

      flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
	       | SEC_LINKER_CREATED);

      /* The .dynamic section holds the basic dynamic information: the
	 sun4_dynamic structure, the dynamic debugger information, and
	 the sun4_dynamic_link structure.  */
      s = bfd_make_section (abfd, ".dynamic");
      if (s == NULL
	  || ! bfd_set_section_flags (abfd, s, flags)
	  || ! bfd_set_section_alignment (abfd, s, 2))
	return FALSE;

      /* The .got section holds the global offset table.  The address
	 is put in the ld_got field.  */
      s = bfd_make_section (abfd, ".got");
      if (s == NULL
	  || ! bfd_set_section_flags (abfd, s, flags)
	  || ! bfd_set_section_alignment (abfd, s, 2))
	return FALSE;

      /* The .plt section holds the procedure linkage table.  The
	 address is put in the ld_plt field.  */
      s = bfd_make_section (abfd, ".plt");
      if (s == NULL
	  || ! bfd_set_section_flags (abfd, s, flags | SEC_CODE)
	  || ! bfd_set_section_alignment (abfd, s, 2))
	return FALSE;

      /* The .dynrel section holds the dynamic relocs.  The address is
	 put in the ld_rel field.  */
      s = bfd_make_section (abfd, ".dynrel");
      if (s == NULL
	  || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
	  || ! bfd_set_section_alignment (abfd, s, 2))
	return FALSE;

      /* The .hash section holds the dynamic hash table.  The address
	 is put in the ld_hash field.  */
      s = bfd_make_section (abfd, ".hash");
      if (s == NULL
	  || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
	  || ! bfd_set_section_alignment (abfd, s, 2))
	return FALSE;

      /* The .dynsym section holds the dynamic symbols.  The address
	 is put in the ld_stab field.  */
      s = bfd_make_section (abfd, ".dynsym");
      if (s == NULL
	  || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
	  || ! bfd_set_section_alignment (abfd, s, 2))
	return FALSE;

      /* The .dynstr section holds the dynamic symbol string table.
	 The address is put in the ld_symbols field.  */
      s = bfd_make_section (abfd, ".dynstr");
      if (s == NULL
	  || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
	  || ! bfd_set_section_alignment (abfd, s, 2))
	return FALSE;

      sunos_hash_table (info)->dynamic_sections_created = TRUE;
    }

  if ((needed && ! sunos_hash_table (info)->dynamic_sections_needed)
      || info->shared)
    {
      bfd *dynobj;

      dynobj = sunos_hash_table (info)->dynobj;

      s = bfd_get_section_by_name (dynobj, ".got");
      if (s->_raw_size == 0)
	s->_raw_size = BYTES_IN_WORD;

      sunos_hash_table (info)->dynamic_sections_needed = TRUE;
      sunos_hash_table (info)->got_needed = TRUE;
    }

  return TRUE;
}

/* Add dynamic symbols during a link.  This is called by the a.out
   backend linker for each object it encounters.  */

static bfd_boolean
sunos_add_dynamic_symbols (abfd, info, symsp, sym_countp, stringsp)
     bfd *abfd;
     struct bfd_link_info *info;
     struct external_nlist **symsp;
     bfd_size_type *sym_countp;
     char **stringsp;
{
  bfd *dynobj;
  struct sunos_dynamic_info *dinfo;
  unsigned long need;
  asection **ps;

  /* Make sure we have all the required sections.  */
  if (info->hash->creator == abfd->xvec)
    {
      if (! sunos_create_dynamic_sections (abfd, info,
					   ((abfd->flags & DYNAMIC) != 0
					    && !info->relocateable)))
	return FALSE;
    }

  /* There is nothing else to do for a normal object.  */
  if ((abfd->flags & DYNAMIC) == 0)
    return TRUE;

  dynobj = sunos_hash_table (info)->dynobj;

  /* We do not want to include the sections in a dynamic object in the
     output file.  We hack by simply clobbering the list of sections
     in the BFD.  This could be handled more cleanly by, say, a new
     section flag; the existing SEC_NEVER_LOAD flag is not the one we
     want, because that one still implies that the section takes up
     space in the output file.  If this is the first object we have
     seen, we must preserve the dynamic sections we just created.  */
  for (ps = &abfd->sections; *ps != NULL; )
    {
      if (abfd != dynobj || ((*ps)->flags & SEC_LINKER_CREATED) == 0)
	bfd_section_list_remove (abfd, ps);
      else
	ps = &(*ps)->next;
    }

  /* The native linker seems to just ignore dynamic objects when -r is
     used.  */
  if (info->relocateable)
    return TRUE;

  /* There's no hope of using a dynamic object which does not exactly
     match the format of the output file.  */
  if (info->hash->creator != abfd->xvec)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return FALSE;
    }

  /* Make sure we have a .need and a .rules sections.  These are only
     needed if there really is a dynamic object in the link, so they
     are not added by sunos_create_dynamic_sections.  */
  if (bfd_get_section_by_name (dynobj, ".need") == NULL)
    {
      /* The .need section holds the list of names of shared objets
	 which must be included at runtime.  The address of this
	 section is put in the ld_need field.  */
      asection *s = bfd_make_section (dynobj, ".need");
      if (s == NULL
	  || ! bfd_set_section_flags (dynobj, s,
				      (SEC_ALLOC
				       | SEC_LOAD
				       | SEC_HAS_CONTENTS
				       | SEC_IN_MEMORY
				       | SEC_READONLY))
	  || ! bfd_set_section_alignment (dynobj, s, 2))
	return FALSE;
    }

  if (bfd_get_section_by_name (dynobj, ".rules") == NULL)
    {
      /* The .rules section holds the path to search for shared
	 objects.  The address of this section is put in the ld_rules
	 field.  */
      asection *s = bfd_make_section (dynobj, ".rules");
      if (s == NULL
	  || ! bfd_set_section_flags (dynobj, s,
				      (SEC_ALLOC
				       | SEC_LOAD
				       | SEC_HAS_CONTENTS
				       | SEC_IN_MEMORY
				       | SEC_READONLY))
	  || ! bfd_set_section_alignment (dynobj, s, 2))
	return FALSE;
    }

  /* Pick up the dynamic symbols and return them to the caller.  */
  if (! sunos_slurp_dynamic_symtab (abfd))
    return FALSE;

  dinfo = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd);
  *symsp = dinfo->dynsym;
  *sym_countp = dinfo->dynsym_count;
  *stringsp = dinfo->dynstr;

  /* Record information about any other objects needed by this one.  */
  need = dinfo->dyninfo.ld_need;
  while (need != 0)
    {
      bfd_byte buf[16];
      unsigned long name, flags;
      unsigned short major_vno, minor_vno;
      struct bfd_link_needed_list *needed, **pp;
      char *namebuf, *p;
      bfd_size_type alc;
      bfd_byte b;
      char *namecopy;

      if (bfd_seek (abfd, (file_ptr) need, SEEK_SET) != 0
	  || bfd_bread (buf, (bfd_size_type) 16, abfd) != 16)
	return FALSE;

      /* For the format of an ld_need entry, see aout/sun4.h.  We
	 should probably define structs for this manipulation.  */

      name = bfd_get_32 (abfd, buf);
      flags = bfd_get_32 (abfd, buf + 4);
      major_vno = (unsigned short) bfd_get_16 (abfd, buf + 8);
      minor_vno = (unsigned short) bfd_get_16 (abfd, buf + 10);
      need = bfd_get_32 (abfd, buf + 12);

      alc = sizeof (struct bfd_link_needed_list);
      needed = (struct bfd_link_needed_list *) bfd_alloc (abfd, alc);
      if (needed == NULL)
	return FALSE;
      needed->by = abfd;

      /* We return the name as [-l]name[.maj][.min].  */
      alc = 30;
      namebuf = (char *) bfd_malloc (alc + 1);
      if (namebuf == NULL)
	return FALSE;
      p = namebuf;

      if ((flags & 0x80000000) != 0)
	{
	  *p++ = '-';
	  *p++ = 'l';
	}
      if (bfd_seek (abfd, (file_ptr) name, SEEK_SET) != 0)
	{
	  free (namebuf);
	  return FALSE;
	}

      do
	{
	  if (bfd_bread (&b, (bfd_size_type) 1, abfd) != 1)
	    {
	      free (namebuf);
	      return FALSE;
	    }

	  if ((bfd_size_type) (p - namebuf) >= alc)
	    {
	      char *n;

	      alc *= 2;
	      n = (char *) bfd_realloc (namebuf, alc + 1);
	      if (n == NULL)
		{
		  free (namebuf);
		  return FALSE;
		}
	      p = n + (p - namebuf);
	      namebuf = n;
	    }

	  *p++ = b;
	}
      while (b != '\0');

      if (major_vno == 0)
	*p = '\0';
      else
	{
	  char majbuf[30];
	  char minbuf[30];

	  sprintf (majbuf, ".%d", major_vno);
	  if (minor_vno == 0)
	    minbuf[0] = '\0';
	  else
	    sprintf (minbuf, ".%d", minor_vno);

	  if ((p - namebuf) + strlen (majbuf) + strlen (minbuf) >= alc)
	    {
	      char *n;

	      alc = (p - namebuf) + strlen (majbuf) + strlen (minbuf);
	      n = (char *) bfd_realloc (namebuf, alc + 1);
	      if (n == NULL)
		{
		  free (namebuf);
		  return FALSE;
		}
	      p = n + (p - namebuf);
	      namebuf = n;
	    }

	  strcpy (p, majbuf);
	  strcat (p, minbuf);
	}

      namecopy = bfd_alloc (abfd, (bfd_size_type) strlen (namebuf) + 1);
      if (namecopy == NULL)
	{
	  free (namebuf);
	  return FALSE;
	}
      strcpy (namecopy, namebuf);
      free (namebuf);
      needed->name = namecopy;

      needed->next = NULL;

      for (pp = &sunos_hash_table (info)->needed;
	   *pp != NULL;
	   pp = &(*pp)->next)
	;
      *pp = needed;
    }

  return TRUE;
}

/* Function to add a single symbol to the linker hash table.  This is
   a wrapper around _bfd_generic_link_add_one_symbol which handles the
   tweaking needed for dynamic linking support.  */

static bfd_boolean
sunos_add_one_symbol (info, abfd, name, flags, section, value, string,
		      copy, collect, hashp)
     struct bfd_link_info *info;
     bfd *abfd;
     const char *name;
     flagword flags;
     asection *section;
     bfd_vma value;
     const char *string;
     bfd_boolean copy;
     bfd_boolean collect;
     struct bfd_link_hash_entry **hashp;
{
  struct sunos_link_hash_entry *h;
  int new_flag;

  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 (hashp != NULL)
    *hashp = (struct bfd_link_hash_entry *) h;

  /* Treat a common symbol in a dynamic object as defined in the .bss
     section of the dynamic object.  We don't want to allocate space
     for it in our process image.  */
  if ((abfd->flags & DYNAMIC) != 0
      && bfd_is_com_section (section))
    section = obj_bsssec (abfd);

  if (! bfd_is_und_section (section)
      && h->root.root.type != bfd_link_hash_new
      && h->root.root.type != bfd_link_hash_undefined
      && h->root.root.type != bfd_link_hash_defweak)
    {
      /* We are defining the symbol, and it is already defined.  This
	 is a potential multiple definition error.  */
      if ((abfd->flags & DYNAMIC) != 0)
	{
	  /* The definition we are adding is from a dynamic object.
	     We do not want this new definition to override the
	     existing definition, so we pretend it is just a
	     reference.  */
	  section = bfd_und_section_ptr;
	}
      else if (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 definition is from a dynamic object.  We
	     want to override it with the definition we just found.
	     Clobber the existing definition.  */
	  h->root.root.type = bfd_link_hash_undefined;
	  h->root.root.u.undef.abfd = h->root.root.u.def.section->owner;
	}
      else if (h->root.root.type == bfd_link_hash_common
	       && (h->root.root.u.c.p->section->owner->flags & DYNAMIC) != 0)
	{
	  /* The existing definition is from a dynamic object.  We
	     want to override it with the definition we just found.
	     Clobber the existing definition.  We can't set it to new,
	     because it is on the undefined list.  */
	  h->root.root.type = bfd_link_hash_undefined;
	  h->root.root.u.undef.abfd = h->root.root.u.c.p->section->owner;
	}
    }

  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,
					  hashp))
    return FALSE;

  if (abfd->xvec == info->hash->creator)
    {
      /* Set a flag in the hash table entry indicating the type of
	 reference or definition we just found.  Keep a count of the
	 number of dynamic symbols we find.  A dynamic symbol is one
	 which is referenced or defined by both a regular object and a
	 shared object.  */
      if ((abfd->flags & DYNAMIC) == 0)
	{
	  if (bfd_is_und_section (section))
	    new_flag = SUNOS_REF_REGULAR;
	  else
	    new_flag = SUNOS_DEF_REGULAR;
	}
      else
	{
	  if (bfd_is_und_section (section))
	    new_flag = SUNOS_REF_DYNAMIC;
	  else
	    new_flag = SUNOS_DEF_DYNAMIC;
	}
      h->flags |= new_flag;

      if (h->dynindx == -1
	  && (h->flags & (SUNOS_DEF_REGULAR | SUNOS_REF_REGULAR)) != 0)
	{
	  ++sunos_hash_table (info)->dynsymcount;
	  h->dynindx = -2;
	}

      if ((flags & BSF_CONSTRUCTOR) != 0
	  && (abfd->flags & DYNAMIC) == 0)
	h->flags |= SUNOS_CONSTRUCTOR;
    }

  return TRUE;
}

/* Return the list of objects needed by BFD.  */

/*ARGSUSED*/
struct bfd_link_needed_list *
bfd_sunos_get_needed_list (abfd, info)
     bfd *abfd ATTRIBUTE_UNUSED;
     struct bfd_link_info *info;
{
  if (info->hash->creator != &MY(vec))
    return NULL;
  return sunos_hash_table (info)->needed;
}

/* Record an assignment made to a symbol by a linker script.  We need
   this in case some dynamic object refers to this symbol.  */

bfd_boolean
bfd_sunos_record_link_assignment (output_bfd, info, name)
     bfd *output_bfd;
     struct bfd_link_info *info;
     const char *name;
{
  struct sunos_link_hash_entry *h;

  if (output_bfd->xvec != &MY(vec))
    return TRUE;

  /* This is called after we have examined all the input objects.  If
     the symbol does not exist, it merely means that no object refers
     to it, and we can just ignore it at this point.  */
  h = sunos_link_hash_lookup (sunos_hash_table (info), name,
			      FALSE, FALSE, FALSE);
  if (h == NULL)
    return TRUE;

  /* In a shared library, the __DYNAMIC symbol does not appear in the
     dynamic symbol table.  */
  if (! info->shared || strcmp (name, "__DYNAMIC") != 0)
    {
      h->flags |= SUNOS_DEF_REGULAR;

      if (h->dynindx == -1)
	{
	  ++sunos_hash_table (info)->dynsymcount;
	  h->dynindx = -2;
	}
    }

  return TRUE;
}

/* Set up the sizes and contents of the dynamic sections created in
   sunos_add_dynamic_symbols.  This is called by the SunOS linker
   emulation before_allocation routine.  We must set the sizes of the
   sections before the linker sets the addresses of the various
   sections.  This unfortunately requires reading all the relocs so
   that we can work out which ones need to become dynamic relocs.  If
   info->keep_memory is TRUE, we keep the relocs in memory; otherwise,
   we discard them, and will read them again later.  */

bfd_boolean
bfd_sunos_size_dynamic_sections (output_bfd, info, sdynptr, sneedptr,
				 srulesptr)
     bfd *output_bfd;
     struct bfd_link_info *info;
     asection **sdynptr;
     asection **sneedptr;
     asection **srulesptr;
{
  bfd *dynobj;
  bfd_size_type dynsymcount;
  struct sunos_link_hash_entry *h;
  asection *s;
  size_t bucketcount;
  bfd_size_type hashalloc;
  size_t i;
  bfd *sub;

  *sdynptr = NULL;
  *sneedptr = NULL;
  *srulesptr = NULL;

  if (info->relocateable)
    return TRUE;

  if (output_bfd->xvec != &MY(vec))
    return TRUE;

  /* Look through all the input BFD's and read their relocs.  It would
     be better if we didn't have to do this, but there is no other way
     to determine the number of dynamic relocs we need, and, more
     importantly, there is no other way to know which symbols should
     get an entry in the procedure linkage table.  */
  for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
    {
      if ((sub->flags & DYNAMIC) == 0
	  && sub->xvec == output_bfd->xvec)
	{
	  if (! sunos_scan_relocs (info, sub, obj_textsec (sub),
				   exec_hdr (sub)->a_trsize)
	      || ! sunos_scan_relocs (info, sub, obj_datasec (sub),
				      exec_hdr (sub)->a_drsize))
	    return FALSE;
	}
    }

  dynobj = sunos_hash_table (info)->dynobj;
  dynsymcount = sunos_hash_table (info)->dynsymcount;

  /* If there were no dynamic objects in the link, and we don't need
     to build a global offset table, there is nothing to do here.  */
  if (! sunos_hash_table (info)->dynamic_sections_needed
      && ! sunos_hash_table (info)->got_needed)
    return TRUE;

  /* If __GLOBAL_OFFSET_TABLE_ was mentioned, define it.  */
  h = sunos_link_hash_lookup (sunos_hash_table (info),
			      "__GLOBAL_OFFSET_TABLE_", FALSE, FALSE, FALSE);
  if (h != NULL && (h->flags & SUNOS_REF_REGULAR) != 0)
    {
      h->flags |= SUNOS_DEF_REGULAR;
      if (h->dynindx == -1)
	{
	  ++sunos_hash_table (info)->dynsymcount;
	  h->dynindx = -2;
	}
      h->root.root.type = bfd_link_hash_defined;
      h->root.root.u.def.section = bfd_get_section_by_name (dynobj, ".got");

      /* If the .got section is more than 0x1000 bytes, we set
	 __GLOBAL_OFFSET_TABLE_ to be 0x1000 bytes into the section,
	 so that 13 bit relocations have a greater chance of working.  */
      s = bfd_get_section_by_name (dynobj, ".got");
      BFD_ASSERT (s != NULL);
      if (s->_raw_size >= 0x1000)
	h->root.root.u.def.value = 0x1000;
      else
	h->root.root.u.def.value = 0;

      sunos_hash_table (info)->got_base = h->root.root.u.def.value;
    }

  /* If there are any shared objects in the link, then we need to set
     up the dynamic linking information.  */
  if (sunos_hash_table (info)->dynamic_sections_needed)
    {
      *sdynptr = bfd_get_section_by_name (dynobj, ".dynamic");

      /* The .dynamic section is always the same size.  */
      s = *sdynptr;
      BFD_ASSERT (s != NULL);
      s->_raw_size = (sizeof (struct external_sun4_dynamic)
		      + EXTERNAL_SUN4_DYNAMIC_DEBUGGER_SIZE
		      + sizeof (struct external_sun4_dynamic_link));

      /* Set the size of the .dynsym and .hash sections.  We counted
	 the number of dynamic symbols as we read the input files.  We
	 will build the dynamic symbol table (.dynsym) and the hash
	 table (.hash) when we build the final symbol table, because
	 until then we do not know the correct value to give the
	 symbols.  We build the dynamic symbol string table (.dynstr)
	 in a traversal of the symbol table using
	 sunos_scan_dynamic_symbol.  */
      s = bfd_get_section_by_name (dynobj, ".dynsym");
      BFD_ASSERT (s != NULL);
      s->_raw_size = dynsymcount * sizeof (struct external_nlist);
      s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size);
      if (s->contents == NULL && s->_raw_size != 0)
	return FALSE;

      /* The number of buckets is just the number of symbols divided
	 by four.  To compute the final size of the hash table, we
	 must actually compute the hash table.  Normally we need
	 exactly as many entries in the hash table as there are
	 dynamic symbols, but if some of the buckets are not used we
	 will need additional entries.  In the worst case, every
	 symbol will hash to the same bucket, and we will need
	 BUCKETCOUNT - 1 extra entries.  */
      if (dynsymcount >= 4)
	bucketcount = dynsymcount / 4;
      else if (dynsymcount > 0)
	bucketcount = dynsymcount;
      else
	bucketcount = 1;
      s = bfd_get_section_by_name (dynobj, ".hash");
      BFD_ASSERT (s != NULL);
      hashalloc = (dynsymcount + bucketcount - 1) * HASH_ENTRY_SIZE;
      s->contents = (bfd_byte *) bfd_zalloc (dynobj, hashalloc);
      if (s->contents == NULL && dynsymcount > 0)
	return FALSE;
      for (i = 0; i < bucketcount; i++)
	PUT_WORD (output_bfd, (bfd_vma) -1, s->contents + i * HASH_ENTRY_SIZE);
      s->_raw_size = bucketcount * HASH_ENTRY_SIZE;

      sunos_hash_table (info)->bucketcount = bucketcount;

      /* Scan all the symbols, place them in the dynamic symbol table,
	 and build the dynamic hash table.  We reuse dynsymcount as a
	 counter for the number of symbols we have added so far.  */
      sunos_hash_table (info)->dynsymcount = 0;
      sunos_link_hash_traverse (sunos_hash_table (info),
				sunos_scan_dynamic_symbol,
				(PTR) info);
      BFD_ASSERT (sunos_hash_table (info)->dynsymcount == dynsymcount);

      /* The SunOS native linker seems to align the total size of the
	 symbol strings to a multiple of 8.  I don't know if this is
	 important, but it can't hurt much.  */
      s = bfd_get_section_by_name (dynobj, ".dynstr");
      BFD_ASSERT (s != NULL);
      if ((s->_raw_size & 7) != 0)
	{
	  bfd_size_type add;
	  bfd_byte *contents;

	  add = 8 - (s->_raw_size & 7);
	  contents = (bfd_byte *) bfd_realloc (s->contents,
					       s->_raw_size + add);
	  if (contents == NULL)
	    return FALSE;
	  memset (contents + s->_raw_size, 0, (size_t) add);
	  s->contents = contents;
	  s->_raw_size += add;
	}
    }

  /* Now that we have worked out the sizes of the procedure linkage
     table and the dynamic relocs, allocate storage for them.  */
  s = bfd_get_section_by_name (dynobj, ".plt");
  BFD_ASSERT (s != NULL);
  if (s->_raw_size != 0)
    {
      s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size);
      if (s->contents == NULL)
	return FALSE;

      /* Fill in the first entry in the table.  */
      switch (bfd_get_arch (dynobj))
	{
	case bfd_arch_sparc:
	  memcpy (s->contents, sparc_plt_first_entry, SPARC_PLT_ENTRY_SIZE);
	  break;

	case bfd_arch_m68k:
	  memcpy (s->contents, m68k_plt_first_entry, M68K_PLT_ENTRY_SIZE);
	  break;

	default:
	  abort ();
	}
    }

  s = bfd_get_section_by_name (dynobj, ".dynrel");
  if (s->_raw_size != 0)
    {
      s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size);
      if (s->contents == NULL)
	return FALSE;
    }
  /* We use the reloc_count field to keep track of how many of the
     relocs we have output so far.  */
  s->reloc_count = 0;

  /* Make space for the global offset table.  */
  s = bfd_get_section_by_name (dynobj, ".got");
  s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size);
  if (s->contents == NULL)
    return FALSE;

  *sneedptr = bfd_get_section_by_name (dynobj, ".need");
  *srulesptr = bfd_get_section_by_name (dynobj, ".rules");

  return TRUE;
}

/* Scan the relocs for an input section.  */

static bfd_boolean
sunos_scan_relocs (info, abfd, sec, rel_size)
     struct bfd_link_info *info;
     bfd *abfd;
     asection *sec;
     bfd_size_type rel_size;
{
  PTR relocs;
  PTR free_relocs = NULL;

  if (rel_size == 0)
    return TRUE;

  if (! info->keep_memory)
    relocs = free_relocs = bfd_malloc (rel_size);
  else
    {
      struct aout_section_data_struct *n;
      bfd_size_type amt = sizeof (struct aout_section_data_struct);

      n = (struct aout_section_data_struct *) bfd_alloc (abfd, amt);
      if (n == NULL)
	relocs = NULL;
      else
	{
	  set_aout_section_data (sec, n);
	  relocs = bfd_malloc (rel_size);
	  aout_section_data (sec)->relocs = relocs;
	}
    }
  if (relocs == NULL)
    return FALSE;

  if (bfd_seek (abfd, sec->rel_filepos, SEEK_SET) != 0
      || bfd_bread (relocs, rel_size, abfd) != rel_size)
    goto error_return;

  if (obj_reloc_entry_size (abfd) == RELOC_STD_SIZE)
    {
      if (! sunos_scan_std_relocs (info, abfd, sec,
				   (struct reloc_std_external *) relocs,
				   rel_size))
	goto error_return;
    }
  else
    {
      if (! sunos_scan_ext_relocs (info, abfd, sec,
				   (struct reloc_ext_external *) relocs,
				   rel_size))
	goto error_return;
    }

  if (free_relocs != NULL)
    free (free_relocs);

  return TRUE;

 error_return:
  if (free_relocs != NULL)
    free (free_relocs);
  return FALSE;
}

/* Scan the relocs for an input section using standard relocs.  We
   need to figure out what to do for each reloc against a dynamic
   symbol.  If the symbol is in the .text section, an entry is made in
   the procedure linkage table.  Note that this will do the wrong
   thing if the symbol is actually data; I don't think the Sun 3
   native linker handles this case correctly either.  If the symbol is
   not in the .text section, we must preserve the reloc as a dynamic
   reloc.  FIXME: We should also handle the PIC relocs here by
   building global offset table entries.  */

static bfd_boolean
sunos_scan_std_relocs (info, abfd, sec, relocs, rel_size)
     struct bfd_link_info *info;
     bfd *abfd;
     asection *sec ATTRIBUTE_UNUSED;
     const struct reloc_std_external *relocs;
     bfd_size_type rel_size;
{
  bfd *dynobj;
  asection *splt = NULL;
  asection *srel = NULL;
  struct sunos_link_hash_entry **sym_hashes;
  const struct reloc_std_external *rel, *relend;

  /* We only know how to handle m68k plt entries.  */
  if (bfd_get_arch (abfd) != bfd_arch_m68k)
    {
      bfd_set_error (bfd_error_invalid_target);
      return FALSE;
    }

  dynobj = NULL;

  sym_hashes = (struct sunos_link_hash_entry **) obj_aout_sym_hashes (abfd);

  relend = relocs + rel_size / RELOC_STD_SIZE;
  for (rel = relocs; rel < relend; rel++)
    {
      int r_index;
      struct sunos_link_hash_entry *h;

      /* We only want relocs against external symbols.  */
      if (bfd_header_big_endian (abfd))
	{
	  if ((rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG) == 0)
	    continue;
	}
      else
	{
	  if ((rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE) == 0)
	    continue;
	}

      /* Get the symbol index.  */
      if (bfd_header_big_endian (abfd))
	r_index = ((rel->r_index[0] << 16)
		   | (rel->r_index[1] << 8)
		   | rel->r_index[2]);
      else
	r_index = ((rel->r_index[2] << 16)
		   | (rel->r_index[1] << 8)
		   | rel->r_index[0]);

      /* Get the hash table entry.  */
      h = sym_hashes[r_index];
      if (h == NULL)
	{
	  /* This should not normally happen, but it will in any case
	     be caught in the relocation phase.  */
	  continue;
	}

      /* At this point common symbols have already been allocated, so
	 we don't have to worry about them.  We need to consider that
	 we may have already seen this symbol and marked it undefined;
	 if the symbol is really undefined, then SUNOS_DEF_DYNAMIC
	 will be zero.  */
      if (h->root.root.type != bfd_link_hash_defined
	  && h->root.root.type != bfd_link_hash_defweak
	  && h->root.root.type != bfd_link_hash_undefined)
	continue;

      if ((h->flags & SUNOS_DEF_DYNAMIC) == 0
	  || (h->flags & SUNOS_DEF_REGULAR) != 0)
	continue;

      if (dynobj == NULL)
	{
	  asection *sgot;

	  if (! sunos_create_dynamic_sections (abfd, info, FALSE))
	    return FALSE;
	  dynobj = sunos_hash_table (info)->dynobj;
	  splt = bfd_get_section_by_name (dynobj, ".plt");
	  srel = bfd_get_section_by_name (dynobj, ".dynrel");
	  BFD_ASSERT (splt != NULL && srel != NULL);

	  sgot = bfd_get_section_by_name (dynobj, ".got");
	  BFD_ASSERT (sgot != NULL);
	  if (sgot->_raw_size == 0)
	    sgot->_raw_size = BYTES_IN_WORD;
	  sunos_hash_table (info)->got_needed = TRUE;
	}

      BFD_ASSERT ((h->flags & SUNOS_REF_REGULAR) != 0);
      BFD_ASSERT (h->plt_offset != 0
		  || ((h->root.root.type == bfd_link_hash_defined
		       || h->root.root.type == bfd_link_hash_defweak)
		      ? (h->root.root.u.def.section->owner->flags
			 & DYNAMIC) != 0
		      : (h->root.root.u.undef.abfd->flags & DYNAMIC) != 0));

      /* This reloc is against a symbol defined only by a dynamic
	 object.  */

      if (h->root.root.type == bfd_link_hash_undefined)
	{
	  /* Presumably this symbol was marked as being undefined by
	     an earlier reloc.  */
	  srel->_raw_size += RELOC_STD_SIZE;
	}
      else if ((h->root.root.u.def.section->flags & SEC_CODE) == 0)
	{
	  bfd *sub;

	  /* This reloc is not in the .text section.  It must be
	     copied into the dynamic relocs.  We mark the symbol as
	     being undefined.  */
	  srel->_raw_size += RELOC_STD_SIZE;
	  sub = h->root.root.u.def.section->owner;
	  h->root.root.type = bfd_link_hash_undefined;
	  h->root.root.u.undef.abfd = sub;
	}
      else
	{
	  /* This symbol is in the .text section.  We must give it an
	     entry in the procedure linkage table, if we have not
	     already done so.  We change the definition of the symbol
	     to the .plt section; this will cause relocs against it to
	     be handled correctly.  */
	  if (h->plt_offset == 0)
	    {
	      if (splt->_raw_size == 0)
		splt->_raw_size = M68K_PLT_ENTRY_SIZE;
	      h->plt_offset = splt->_raw_size;

	      if ((h->flags & SUNOS_DEF_REGULAR) == 0)
		{
		  h->root.root.u.def.section = splt;
		  h->root.root.u.def.value = splt->_raw_size;
		}

	      splt->_raw_size += M68K_PLT_ENTRY_SIZE;

	      /* We may also need a dynamic reloc entry.  */
	      if ((h->flags & SUNOS_DEF_REGULAR) == 0)
		srel->_raw_size += RELOC_STD_SIZE;
	    }
	}
    }

  return TRUE;
}

/* Scan the relocs for an input section using extended relocs.  We
   need to figure out what to do for each reloc against a dynamic
   symbol.  If the reloc is a WDISP30, and the symbol is in the .text
   section, an entry is made in the procedure linkage table.
   Otherwise, we must preserve the reloc as a dynamic reloc.  */

static bfd_boolean
sunos_scan_ext_relocs (info, abfd, sec, relocs, rel_size)
     struct bfd_link_info *info;
     bfd *abfd;
     asection *sec ATTRIBUTE_UNUSED;
     const struct reloc_ext_external *relocs;
     bfd_size_type rel_size;
{
  bfd *dynobj;
  struct sunos_link_hash_entry **sym_hashes;
  const struct reloc_ext_external *rel, *relend;
  asection *splt = NULL;
  asection *sgot = NULL;
  asection *srel = NULL;
  bfd_size_type amt;

  /* We only know how to handle SPARC plt entries.  */
  if (bfd_get_arch (abfd) != bfd_arch_sparc)
    {
      bfd_set_error (bfd_error_invalid_target);
      return FALSE;
    }

  dynobj = NULL;

  sym_hashes = (struct sunos_link_hash_entry **) obj_aout_sym_hashes (abfd);

  relend = relocs + rel_size / RELOC_EXT_SIZE;
  for (rel = relocs; rel < relend; rel++)
    {
      unsigned int r_index;
      int r_extern;
      int r_type;
      struct sunos_link_hash_entry *h = NULL;

      /* Swap in the reloc information.  */
      if (bfd_header_big_endian (abfd))
	{
	  r_index = ((rel->r_index[0] << 16)
		     | (rel->r_index[1] << 8)
		     | rel->r_index[2]);
	  r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
	  r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
		    >> RELOC_EXT_BITS_TYPE_SH_BIG);
	}
      else
	{
	  r_index = ((rel->r_index[2] << 16)
		     | (rel->r_index[1] << 8)
		     | rel->r_index[0]);
	  r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
	  r_type = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
		    >> RELOC_EXT_BITS_TYPE_SH_LITTLE);
	}

      if (r_extern)
	{
	  h = sym_hashes[r_index];
	  if (h == NULL)
	    {
	      /* This should not normally happen, but it will in any
		 case be caught in the relocation phase.  */
	      continue;
	    }
	}

      /* If this is a base relative reloc, we need to make an entry in
	 the .got section.  */
      if (r_type == RELOC_BASE10
	  || r_type == RELOC_BASE13
	  || r_type == RELOC_BASE22)
	{
	  if (dynobj == NULL)
	    {
	      if (! sunos_create_dynamic_sections (abfd, info, FALSE))
		return FALSE;
	      dynobj = sunos_hash_table (info)->dynobj;
	      splt = bfd_get_section_by_name (dynobj, ".plt");
	      sgot = bfd_get_section_by_name (dynobj, ".got");
	      srel = bfd_get_section_by_name (dynobj, ".dynrel");
	      BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL);

	      /* Make sure we have an initial entry in the .got table.  */
	      if (sgot->_raw_size == 0)
		sgot->_raw_size = BYTES_IN_WORD;
	      sunos_hash_table (info)->got_needed = TRUE;
	    }

	  if (r_extern)
	    {
	      if (h->got_offset != 0)
		continue;

	      h->got_offset = sgot->_raw_size;
	    }
	  else
	    {
	      if (r_index >= bfd_get_symcount (abfd))
		{
		  /* This is abnormal, but should be caught in the
		     relocation phase.  */
		  continue;
		}

	      if (adata (abfd).local_got_offsets == NULL)
		{
		  amt = bfd_get_symcount (abfd);
		  amt *= sizeof (bfd_vma);
		  adata (abfd).local_got_offsets =
		    (bfd_vma *) bfd_zalloc (abfd, amt);
		  if (adata (abfd).local_got_offsets == NULL)
		    return FALSE;
		}

	      if (adata (abfd).local_got_offsets[r_index] != 0)
		continue;

	      adata (abfd).local_got_offsets[r_index] = sgot->_raw_size;
	    }

	  sgot->_raw_size += BYTES_IN_WORD;

	  /* If we are making a shared library, or if the symbol is
	     defined by a dynamic object, we will need a dynamic reloc
	     entry.  */
	  if (info->shared
	      || (h != NULL
		  && (h->flags & SUNOS_DEF_DYNAMIC) != 0
		  && (h->flags & SUNOS_DEF_REGULAR) == 0))
	    srel->_raw_size += RELOC_EXT_SIZE;

	  continue;
	}

      /* Otherwise, we are only interested in relocs against symbols
	 defined in dynamic objects but not in regular objects.  We
	 only need to consider relocs against external symbols.  */
      if (! r_extern)
	{
	  /* But, if we are creating a shared library, we need to
	     generate an absolute reloc.  */
	  if (info->shared)
	    {
	      if (dynobj == NULL)
		{
		  if (! sunos_create_dynamic_sections (abfd, info, TRUE))
		    return FALSE;
		  dynobj = sunos_hash_table (info)->dynobj;
		  splt = bfd_get_section_by_name (dynobj, ".plt");
		  sgot = bfd_get_section_by_name (dynobj, ".got");
		  srel = bfd_get_section_by_name (dynobj, ".dynrel");
		  BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL);
		}

	      srel->_raw_size += RELOC_EXT_SIZE;
	    }

	  continue;
	}

      /* At this point common symbols have already been allocated, so
	 we don't have to worry about them.  We need to consider that
	 we may have already seen this symbol and marked it undefined;
	 if the symbol is really undefined, then SUNOS_DEF_DYNAMIC
	 will be zero.  */
      if (h->root.root.type != bfd_link_hash_defined
	  && h->root.root.type != bfd_link_hash_defweak
	  && h->root.root.type != bfd_link_hash_undefined)
	continue;

      if (r_type != RELOC_JMP_TBL
	  && ! info->shared
	  && ((h->flags & SUNOS_DEF_DYNAMIC) == 0
	      || (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;

      if (dynobj == NULL)
	{
	  if (! sunos_create_dynamic_sections (abfd, info, FALSE))
	    return FALSE;
	  dynobj = sunos_hash_table (info)->dynobj;
	  splt = bfd_get_section_by_name (dynobj, ".plt");
	  sgot = bfd_get_section_by_name (dynobj, ".got");
	  srel = bfd_get_section_by_name (dynobj, ".dynrel");
	  BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL);

	  /* Make sure we have an initial entry in the .got table.  */
	  if (sgot->_raw_size == 0)
	    sgot->_raw_size = BYTES_IN_WORD;
	  sunos_hash_table (info)->got_needed = TRUE;
	}

      BFD_ASSERT (r_type == RELOC_JMP_TBL
		  || info->shared
		  || (h->flags & SUNOS_REF_REGULAR) != 0);
      BFD_ASSERT (r_type == RELOC_JMP_TBL
		  || info->shared
		  || h->plt_offset != 0
		  || ((h->root.root.type == bfd_link_hash_defined
		       || h->root.root.type == bfd_link_hash_defweak)
		      ? (h->root.root.u.def.section->owner->flags
			 & DYNAMIC) != 0
		      : (h->root.root.u.undef.abfd->flags & DYNAMIC) != 0));

      /* This reloc is against a symbol defined only by a dynamic
	 object, or it is a jump table reloc from PIC compiled code.  */

      if (r_type != RELOC_JMP_TBL
	  && h->root.root.type == bfd_link_hash_undefined)
	{
	  /* Presumably this symbol was marked as being undefined by
	     an earlier reloc.  */
	  srel->_raw_size += RELOC_EXT_SIZE;
	}
      else if (r_type != RELOC_JMP_TBL
	       && (h->root.root.u.def.section->flags & SEC_CODE) == 0)
	{
	  bfd *sub;

	  /* This reloc is not in the .text section.  It must be
	     copied into the dynamic relocs.  We mark the symbol as
	     being undefined.  */
	  srel->_raw_size += RELOC_EXT_SIZE;
	  if ((h->flags & SUNOS_DEF_REGULAR) == 0)
	    {
	      sub = h->root.root.u.def.section->owner;
	      h->root.root.type = bfd_link_hash_undefined;
	      h->root.root.u.undef.abfd = sub;
	    }
	}
      else
	{
	  /* This symbol is in the .text section.  We must give it an
	     entry in the procedure linkage table, if we have not
	     already done so.  We change the definition of the symbol
	     to the .plt section; this will cause relocs against it to
	     be handled correctly.  */
	  if (h->plt_offset == 0)
	    {
	      if (splt->_raw_size == 0)
		splt->_raw_size = SPARC_PLT_ENTRY_SIZE;
	      h->plt_offset = splt->_raw_size;

	      if ((h->flags & SUNOS_DEF_REGULAR) == 0)
		{
		  if (h->root.root.type == bfd_link_hash_undefined)
		    h->root.root.type = bfd_link_hash_defined;
		  h->root.root.u.def.section = splt;
		  h->root.root.u.def.value = splt->_raw_size;
		}

	      splt->_raw_size += SPARC_PLT_ENTRY_SIZE;

	      /* We will also need a dynamic reloc entry, unless this
		 is a JMP_TBL reloc produced by linking PIC compiled
		 code, and we are not making a shared library.  */
	      if (info->shared || (h->flags & SUNOS_DEF_REGULAR) == 0)
		srel->_raw_size += RELOC_EXT_SIZE;
	    }

	  /* If we are creating a shared library, we need to copy over
	     any reloc other than a jump table reloc.  */
	  if (info->shared && r_type != RELOC_JMP_TBL)
	    srel->_raw_size += RELOC_EXT_SIZE;
	}
    }

  return TRUE;
}

/* Build the hash table of dynamic symbols, and to mark as written all
   symbols from dynamic objects which we do not plan to write out.  */

static bfd_boolean
sunos_scan_dynamic_symbol (h, data)
     struct sunos_link_hash_entry *h;
     PTR data;
{
  struct bfd_link_info *info = (struct bfd_link_info *) data;

  if (h->root.root.type == bfd_link_hash_warning)
    h = (struct sunos_link_hash_entry *) h->root.root.u.i.link;

  /* Set the written flag for symbols we do not want to write out as
     part of the regular symbol table.  This is all symbols which are
     not defined in a regular object file.  For some reason symbols
     which are referenced by a regular object and defined by a dynamic
     object do not seem to show up in the regular symbol table.  It is
     possible for a symbol to have only SUNOS_REF_REGULAR set here, it
     is an undefined symbol which was turned into a common symbol
     because it was found in an archive object which was not included
     in the link.  */
  if ((h->flags & SUNOS_DEF_REGULAR) == 0
      && (h->flags & SUNOS_DEF_DYNAMIC) != 0
      && strcmp (h->root.root.root.string, "__DYNAMIC") != 0)
    h->root.written = TRUE;

  /* If this symbol is defined by a dynamic object and referenced by a
     regular object, see whether we gave it a reasonable value while
     scanning the relocs.  */

  if ((h->flags & SUNOS_DEF_REGULAR) == 0
      && (h->flags & SUNOS_DEF_DYNAMIC) != 0
      && (h->flags & SUNOS_REF_REGULAR) != 0)
    {
      if ((h->root.root.type == bfd_link_hash_defined
	   || h->root.root.type == bfd_link_hash_defweak)
	  && ((h->root.root.u.def.section->owner->flags & DYNAMIC) != 0)
	  && h->root.root.u.def.section->output_section == NULL)
	{
	  bfd *sub;

	  /* This symbol is currently defined in a dynamic section
	     which is not being put into the output file.  This
	     implies that there is no reloc against the symbol.  I'm
	     not sure why this case would ever occur.  In any case, we
	     change the symbol to be undefined.  */
	  sub = h->root.root.u.def.section->owner;
	  h->root.root.type = bfd_link_hash_undefined;
	  h->root.root.u.undef.abfd = sub;
	}
    }

  /* If this symbol is defined or referenced by a regular file, add it
     to the dynamic symbols.  */
  if ((h->flags & (SUNOS_DEF_REGULAR | SUNOS_REF_REGULAR)) != 0)
    {
      asection *s;
      size_t len;
      bfd_byte *contents;
      unsigned char *name;
      unsigned long hash;
      bfd *dynobj;

      BFD_ASSERT (h->dynindx == -2);

      dynobj = sunos_hash_table (info)->dynobj;

      h->dynindx = sunos_hash_table (info)->dynsymcount;
      ++sunos_hash_table (info)->dynsymcount;

      len = strlen (h->root.root.root.string);

      /* We don't bother to construct a BFD hash table for the strings
	 which are the names of the dynamic symbols.  Using a hash
	 table for the regular symbols is beneficial, because the
	 regular symbols includes the debugging symbols, which have
	 long names and are often duplicated in several object files.
	 There are no debugging symbols in the dynamic symbols.  */
      s = bfd_get_section_by_name (dynobj, ".dynstr");
      BFD_ASSERT (s != NULL);
      contents = (bfd_byte *) bfd_realloc (s->contents,
					   s->_raw_size + len + 1);
      if (contents == NULL)
	return FALSE;
      s->contents = contents;

      h->dynstr_index = s->_raw_size;
      strcpy ((char *) contents + s->_raw_size, h->root.root.root.string);
      s->_raw_size += len + 1;

      /* Add it to the dynamic hash table.  */
      name = (unsigned char *) h->root.root.root.string;
      hash = 0;
      while (*name != '\0')
	hash = (hash << 1) + *name++;
      hash &= 0x7fffffff;
      hash %= sunos_hash_table (info)->bucketcount;

      s = bfd_get_section_by_name (dynobj, ".hash");
      BFD_ASSERT (s != NULL);

      if (GET_SWORD (dynobj, s->contents + hash * HASH_ENTRY_SIZE) == -1)
	PUT_WORD (dynobj, h->dynindx, s->contents + hash * HASH_ENTRY_SIZE);
      else
	{
	  bfd_vma next;

	  next = GET_WORD (dynobj,
			   (s->contents
			    + hash * HASH_ENTRY_SIZE
			    + BYTES_IN_WORD));
	  PUT_WORD (dynobj, s->_raw_size / HASH_ENTRY_SIZE,
		    s->contents + hash * HASH_ENTRY_SIZE + BYTES_IN_WORD);
	  PUT_WORD (dynobj, h->dynindx, s->contents + s->_raw_size);
	  PUT_WORD (dynobj, next, s->contents + s->_raw_size + BYTES_IN_WORD);
	  s->_raw_size += HASH_ENTRY_SIZE;
	}
    }

  return TRUE;
}

/* Link a dynamic object.  We actually don't have anything to do at
   this point.  This entry point exists to prevent the regular linker
   code from doing anything with the object.  */

/*ARGSUSED*/
static bfd_boolean
sunos_link_dynamic_object (info, abfd)
     struct bfd_link_info *info ATTRIBUTE_UNUSED;
     bfd *abfd ATTRIBUTE_UNUSED;
{
  return TRUE;
}

/* Write out a dynamic symbol.  This is called by the final traversal
   over the symbol table.  */

static bfd_boolean
sunos_write_dynamic_symbol (output_bfd, info, harg)
     bfd *output_bfd;
     struct bfd_link_info *info;
     struct aout_link_hash_entry *harg;
{
  struct sunos_link_hash_entry *h = (struct sunos_link_hash_entry *) harg;
  int type;
  bfd_vma val;
  asection *s;
  struct external_nlist *outsym;

  /* If this symbol is in the procedure linkage table, fill in the
     table entry.  */
  if (h->plt_offset != 0)
    {
      bfd *dynobj;
      asection *splt;
      bfd_byte *p;
      bfd_vma r_address;

      dynobj = sunos_hash_table (info)->dynobj;
      splt = bfd_get_section_by_name (dynobj, ".plt");
      p = splt->contents + h->plt_offset;

      s = bfd_get_section_by_name (dynobj, ".dynrel");

      r_address = (splt->output_section->vma
		   + splt->output_offset
		   + h->plt_offset);

      switch (bfd_get_arch (output_bfd))
	{
	case bfd_arch_sparc:
	  if (info->shared || (h->flags & SUNOS_DEF_REGULAR) == 0)
	    {
	      bfd_put_32 (output_bfd, SPARC_PLT_ENTRY_WORD0, p);
	      bfd_put_32 (output_bfd,
			  (SPARC_PLT_ENTRY_WORD1
			   + (((- (h->plt_offset + 4) >> 2)
			       & 0x3fffffff))),
			  p + 4);
	      bfd_put_32 (output_bfd, SPARC_PLT_ENTRY_WORD2 + s->reloc_count,
			  p + 8);
	    }
	  else
	    {
	      val = (h->root.root.u.def.section->output_section->vma
		     + h->root.root.u.def.section->output_offset
		     + h->root.root.u.def.value);
	      bfd_put_32 (output_bfd,
			  SPARC_PLT_PIC_WORD0 + ((val >> 10) & 0x3fffff),
			  p);
	      bfd_put_32 (output_bfd,
			  SPARC_PLT_PIC_WORD1 + (val & 0x3ff),
			  p + 4);
	      bfd_put_32 (output_bfd, SPARC_PLT_PIC_WORD2, p + 8);
	    }
	  break;

	case bfd_arch_m68k:
	  if (! info->shared && (h->flags & SUNOS_DEF_REGULAR) != 0)
	    abort ();
	  bfd_put_16 (output_bfd, M68K_PLT_ENTRY_WORD0, p);
	  bfd_put_32 (output_bfd, (- (h->plt_offset + 2)), p + 2);
	  bfd_put_16 (output_bfd, (bfd_vma) s->reloc_count, p + 6);
	  r_address += 2;
	  break;

	default:
	  abort ();
	}

      /* We also need to add a jump table reloc, unless this is the
	 result of a JMP_TBL reloc from PIC compiled code.  */
      if (info->shared || (h->flags & SUNOS_DEF_REGULAR) == 0)
	{
	  BFD_ASSERT (h->dynindx >= 0);
	  BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj)
		      < s->_raw_size);
	  p = s->contents + s->reloc_count * obj_reloc_entry_size (output_bfd);
	  if (obj_reloc_entry_size (output_bfd) == RELOC_STD_SIZE)
	    {
	      struct reloc_std_external *srel;

	      srel = (struct reloc_std_external *) p;
	      PUT_WORD (output_bfd, r_address, srel->r_address);
	      if (bfd_header_big_endian (output_bfd))
		{
		  srel->r_index[0] = (bfd_byte) (h->dynindx >> 16);
		  srel->r_index[1] = (bfd_byte) (h->dynindx >> 8);
		  srel->r_index[2] = (bfd_byte) (h->dynindx);
		  srel->r_type[0] = (RELOC_STD_BITS_EXTERN_BIG
				     | RELOC_STD_BITS_JMPTABLE_BIG);
		}
	      else
		{
		  srel->r_index[2] = (bfd_byte) (h->dynindx >> 16);
		  srel->r_index[1] = (bfd_byte) (h->dynindx >> 8);
		  srel->r_index[0] = (bfd_byte)h->dynindx;
		  srel->r_type[0] = (RELOC_STD_BITS_EXTERN_LITTLE
				     | RELOC_STD_BITS_JMPTABLE_LITTLE);
		}
	    }
	  else
	    {
	      struct reloc_ext_external *erel;

	      erel = (struct reloc_ext_external *) p;
	      PUT_WORD (output_bfd, r_address, erel->r_address);
	      if (bfd_header_big_endian (output_bfd))
		{
		  erel->r_index[0] = (bfd_byte) (h->dynindx >> 16);
		  erel->r_index[1] = (bfd_byte) (h->dynindx >> 8);
		  erel->r_index[2] = (bfd_byte)h->dynindx;
		  erel->r_type[0] =
		    (RELOC_EXT_BITS_EXTERN_BIG
		     | (RELOC_JMP_SLOT << RELOC_EXT_BITS_TYPE_SH_BIG));
		}
	      else
		{
		  erel->r_index[2] = (bfd_byte) (h->dynindx >> 16);
		  erel->r_index[1] = (bfd_byte) (h->dynindx >> 8);
		  erel->r_index[0] = (bfd_byte)h->dynindx;
		  erel->r_type[0] =
		    (RELOC_EXT_BITS_EXTERN_LITTLE
		     | (RELOC_JMP_SLOT << RELOC_EXT_BITS_TYPE_SH_LITTLE));
		}
	      PUT_WORD (output_bfd, (bfd_vma) 0, erel->r_addend);
	    }

	  ++s->reloc_count;
	}
    }

  /* If this is not a dynamic symbol, we don't have to do anything
     else.  We only check this after handling the PLT entry, because
     we can have a PLT entry for a nondynamic symbol when linking PIC
     compiled code from a regular object.  */
  if (h->dynindx < 0)
    return TRUE;

  switch (h->root.root.type)
    {
    default:
    case bfd_link_hash_new:
      abort ();
      /* Avoid variable not initialized warnings.  */
      return TRUE;
    case bfd_link_hash_undefined:
      type = N_UNDF | N_EXT;
      val = 0;
      break;
    case bfd_link_hash_defined:
    case bfd_link_hash_defweak:
      {
	asection *sec;
	asection *output_section;

	sec = h->root.root.u.def.section;
	output_section = sec->output_section;
	BFD_ASSERT (bfd_is_abs_section (output_section)
		    || output_section->owner == output_bfd);
	if (h->plt_offset != 0
	    && (h->flags & SUNOS_DEF_REGULAR) == 0)
	  {
	    type = N_UNDF | N_EXT;
	    val = 0;
	  }
	else
	  {
	    if (output_section == obj_textsec (output_bfd))
	      type = (h->root.root.type == bfd_link_hash_defined
		      ? N_TEXT
		      : N_WEAKT);
	    else if (output_section == obj_datasec (output_bfd))
	      type = (h->root.root.type == bfd_link_hash_defined
		      ? N_DATA
		      : N_WEAKD);
	    else if (output_section == obj_bsssec (output_bfd))
	      type = (h->root.root.type == bfd_link_hash_defined
		      ? N_BSS
		      : N_WEAKB);
	    else
	      type = (h->root.root.type == bfd_link_hash_defined
		      ? N_ABS
		      : N_WEAKA);
	    type |= N_EXT;
	    val = (h->root.root.u.def.value
		   + output_section->vma
		   + sec->output_offset);
	  }
      }
      break;
    case bfd_link_hash_common:
      type = N_UNDF | N_EXT;
      val = h->root.root.u.c.size;
      break;
    case bfd_link_hash_undefweak:
      type = N_WEAKU;
      val = 0;
      break;
    case bfd_link_hash_indirect:
    case bfd_link_hash_warning:
      /* FIXME: Ignore these for now.  The circumstances under which
	 they should be written out are not clear to me.  */
      return TRUE;
    }

  s = bfd_get_section_by_name (sunos_hash_table (info)->dynobj, ".dynsym");
  BFD_ASSERT (s != NULL);
  outsym = ((struct external_nlist *)
	    (s->contents + h->dynindx * EXTERNAL_NLIST_SIZE));

  H_PUT_8 (output_bfd, type, outsym->e_type);
  H_PUT_8 (output_bfd, 0, outsym->e_other);

  /* FIXME: The native linker doesn't use 0 for desc.  It seems to use
     one less than the desc value in the shared library, although that
     seems unlikely.  */
  H_PUT_16 (output_bfd, 0, outsym->e_desc);

  PUT_WORD (output_bfd, h->dynstr_index, outsym->e_strx);
  PUT_WORD (output_bfd, val, outsym->e_value);

  return TRUE;
}

/* This is called for each reloc against an external symbol.  If this
   is a reloc which are are going to copy as a dynamic reloc, then
   copy it over, and tell the caller to not bother processing this
   reloc.  */

/*ARGSUSED*/
static bfd_boolean
sunos_check_dynamic_reloc (info, input_bfd, input_section, harg, reloc,
			   contents, skip, relocationp)
     struct bfd_link_info *info;
     bfd *input_bfd;
     asection *input_section;
     struct aout_link_hash_entry *harg;
     PTR reloc;
     bfd_byte *contents ATTRIBUTE_UNUSED;
     bfd_boolean *skip;
     bfd_vma *relocationp;
{
  struct sunos_link_hash_entry *h = (struct sunos_link_hash_entry *) harg;
  bfd *dynobj;
  bfd_boolean baserel;
  bfd_boolean jmptbl;
  bfd_boolean pcrel;
  asection *s;
  bfd_byte *p;
  long indx;

  *skip = FALSE;

  dynobj = sunos_hash_table (info)->dynobj;

  if (h != NULL
      && h->plt_offset != 0
      && (info->shared
	  || (h->flags & SUNOS_DEF_REGULAR) == 0))
    {
      asection *splt;

      /* Redirect the relocation to the PLT entry.  */
      splt = bfd_get_section_by_name (dynobj, ".plt");
      *relocationp = (splt->output_section->vma
		      + splt->output_offset
		      + h->plt_offset);
    }

  if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE)
    {
      struct reloc_std_external *srel;

      srel = (struct reloc_std_external *) reloc;
      if (bfd_header_big_endian (input_bfd))
	{
	  baserel = (0 != (srel->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
	  jmptbl = (0 != (srel->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
	  pcrel = (0 != (srel->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
	}
      else
	{
	  baserel = (0 != (srel->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
	  jmptbl = (0 != (srel->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
	  pcrel = (0 != (srel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
	}
    }
  else
    {
      struct reloc_ext_external *erel;
      int r_type;

      erel = (struct reloc_ext_external *) reloc;
      if (bfd_header_big_endian (input_bfd))
	r_type = ((erel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
		  >> RELOC_EXT_BITS_TYPE_SH_BIG);
      else
	r_type = ((erel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
		  >> RELOC_EXT_BITS_TYPE_SH_LITTLE);
      baserel = (r_type == RELOC_BASE10
		 || r_type == RELOC_BASE13
		 || r_type == RELOC_BASE22);
      jmptbl = r_type == RELOC_JMP_TBL;
      pcrel = (r_type == RELOC_DISP8
	       || r_type == RELOC_DISP16
	       || r_type == RELOC_DISP32
	       || r_type == RELOC_WDISP30
	       || r_type == RELOC_WDISP22);
      /* We don't consider the PC10 and PC22 types to be PC relative,
	 because they are pcrel_offset.  */
    }

  if (baserel)
    {
      bfd_vma *got_offsetp;
      asection *sgot;

      if (h != NULL)
	got_offsetp = &h->got_offset;
      else if (adata (input_bfd).local_got_offsets == NULL)
	got_offsetp = NULL;
      else
	{
	  struct reloc_std_external *srel;
	  int r_index;

	  srel = (struct reloc_std_external *) reloc;
	  if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE)
	    {
	      if (bfd_header_big_endian (input_bfd))
		r_index = ((srel->r_index[0] << 16)
			   | (srel->r_index[1] << 8)
			   | srel->r_index[2]);
	      else
		r_index = ((srel->r_index[2] << 16)
			   | (srel->r_index[1] << 8)
			   | srel->r_index[0]);
	    }
	  else
	    {
	      struct reloc_ext_external *erel;

	      erel = (struct reloc_ext_external *) reloc;
	      if (bfd_header_big_endian (input_bfd))
		r_index = ((erel->r_index[0] << 16)
			   | (erel->r_index[1] << 8)
			   | erel->r_index[2]);
	      else
		r_index = ((erel->r_index[2] << 16)
			   | (erel->r_index[1] << 8)
			   | erel->r_index[0]);
	    }

	  got_offsetp = adata (input_bfd).local_got_offsets + r_index;
	}

      BFD_ASSERT (got_offsetp != NULL && *got_offsetp != 0);

      sgot = bfd_get_section_by_name (dynobj, ".got");

      /* We set the least significant bit to indicate whether we have
	 already initialized the GOT entry.  */
      if ((*got_offsetp & 1) == 0)
	{
	  if (h == NULL
	      || (! info->shared
		  && ((h->flags & SUNOS_DEF_DYNAMIC) == 0
		      || (h->flags & SUNOS_DEF_REGULAR) != 0)))
	    PUT_WORD (dynobj, *relocationp, sgot->contents + *got_offsetp);
	  else
	    PUT_WORD (dynobj, 0, sgot->contents + *got_offsetp);

	  if (info->shared
	      || (h != NULL
		  && (h->flags & SUNOS_DEF_DYNAMIC) != 0
		  && (h->flags & SUNOS_DEF_REGULAR) == 0))
	    {
	      /* We need to create a GLOB_DAT or 32 reloc to tell the
		 dynamic linker to fill in this entry in the table.  */

	      s = bfd_get_section_by_name (dynobj, ".dynrel");
	      BFD_ASSERT (s != NULL);
	      BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj)
			  < s->_raw_size);

	      p = (s->contents
		   + s->reloc_count * obj_reloc_entry_size (dynobj));

	      if (h != NULL)
		indx = h->dynindx;
	      else
		indx = 0;

	      if (obj_reloc_entry_size (dynobj) == RELOC_STD_SIZE)
		{
		  struct reloc_std_external *srel;

		  srel = (struct reloc_std_external *) p;
		  PUT_WORD (dynobj,
			    (*got_offsetp
			     + sgot->output_section->vma
			     + sgot->output_offset),
			    srel->r_address);
		  if (bfd_header_big_endian (dynobj))
		    {
		      srel->r_index[0] = (bfd_byte) (indx >> 16);
		      srel->r_index[1] = (bfd_byte) (indx >> 8);
		      srel->r_index[2] = (bfd_byte)indx;
		      if (h == NULL)
			srel->r_type[0] = 2 << RELOC_STD_BITS_LENGTH_SH_BIG;
		      else
			srel->r_type[0] =
			  (RELOC_STD_BITS_EXTERN_BIG
			   | RELOC_STD_BITS_BASEREL_BIG
			   | RELOC_STD_BITS_RELATIVE_BIG
			   | (2 << RELOC_STD_BITS_LENGTH_SH_BIG));
		    }
		  else
		    {
		      srel->r_index[2] = (bfd_byte) (indx >> 16);
		      srel->r_index[1] = (bfd_byte) (indx >> 8);
		      srel->r_index[0] = (bfd_byte)indx;
		      if (h == NULL)
			srel->r_type[0] = 2 << RELOC_STD_BITS_LENGTH_SH_LITTLE;
		      else
			srel->r_type[0] =
			  (RELOC_STD_BITS_EXTERN_LITTLE
			   | RELOC_STD_BITS_BASEREL_LITTLE
			   | RELOC_STD_BITS_RELATIVE_LITTLE
			   | (2 << RELOC_STD_BITS_LENGTH_SH_LITTLE));
		    }
		}
	      else
		{
		  struct reloc_ext_external *erel;

		  erel = (struct reloc_ext_external *) p;
		  PUT_WORD (dynobj,
			    (*got_offsetp
			     + sgot->output_section->vma
			     + sgot->output_offset),
			    erel->r_address);
		  if (bfd_header_big_endian (dynobj))
		    {
		      erel->r_index[0] = (bfd_byte) (indx >> 16);
		      erel->r_index[1] = (bfd_byte) (indx >> 8);
		      erel->r_index[2] = (bfd_byte)indx;
		      if (h == NULL)
			erel->r_type[0] =
			  RELOC_32 << RELOC_EXT_BITS_TYPE_SH_BIG;
		      else
			erel->r_type[0] =
			  (RELOC_EXT_BITS_EXTERN_BIG
			   | (RELOC_GLOB_DAT << RELOC_EXT_BITS_TYPE_SH_BIG));
		    }
		  else
		    {
		      erel->r_index[2] = (bfd_byte) (indx >> 16);
		      erel->r_index[1] = (bfd_byte) (indx >> 8);
		      erel->r_index[0] = (bfd_byte)indx;
		      if (h == NULL)
			erel->r_type[0] =
			  RELOC_32 << RELOC_EXT_BITS_TYPE_SH_LITTLE;
		      else
			erel->r_type[0] =
			  (RELOC_EXT_BITS_EXTERN_LITTLE
			   | (RELOC_GLOB_DAT
			      << RELOC_EXT_BITS_TYPE_SH_LITTLE));
		    }
		  PUT_WORD (dynobj, 0, erel->r_addend);
		}

	      ++s->reloc_count;
	    }

	  *got_offsetp |= 1;
	}

      *relocationp = (sgot->vma
		      + (*got_offsetp &~ (bfd_vma) 1)
		      - sunos_hash_table (info)->got_base);

      /* There is nothing else to do for a base relative reloc.  */
      return TRUE;
    }

  if (! sunos_hash_table (info)->dynamic_sections_needed)
    return TRUE;
  if (! info->shared)
    {
      if (h == NULL
	  || h->dynindx == -1
	  || h->root.root.type != bfd_link_hash_undefined
	  || (h->flags & SUNOS_DEF_REGULAR) != 0
	  || (h->flags & SUNOS_DEF_DYNAMIC) == 0
	  || (h->root.root.u.undef.abfd->flags & DYNAMIC) == 0)
	return TRUE;
    }
  else
    {
      if (h != NULL
	  && (h->dynindx == -1
	      || jmptbl
	      || strcmp (h->root.root.root.string,
			 "__GLOBAL_OFFSET_TABLE_") == 0))
	return TRUE;
    }

  /* It looks like this is a reloc we are supposed to copy.  */

  s = bfd_get_section_by_name (dynobj, ".dynrel");
  BFD_ASSERT (s != NULL);
  BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj) < s->_raw_size);

  p = s->contents + s->reloc_count * obj_reloc_entry_size (dynobj);

  /* Copy the reloc over.  */
  memcpy (p, reloc, obj_reloc_entry_size (dynobj));

  if (h != NULL)
    indx = h->dynindx;
  else
    indx = 0;

  /* Adjust the address and symbol index.  */
  if (obj_reloc_entry_size (dynobj) == RELOC_STD_SIZE)
    {
      struct reloc_std_external *srel;

      srel = (struct reloc_std_external *) p;
      PUT_WORD (dynobj,
		(GET_WORD (dynobj, srel->r_address)
		 + input_section->output_section->vma
		 + input_section->output_offset),
		srel->r_address);
      if (bfd_header_big_endian (dynobj))
	{
	  srel->r_index[0] = (bfd_byte) (indx >> 16);
	  srel->r_index[1] = (bfd_byte) (indx >> 8);
	  srel->r_index[2] = (bfd_byte)indx;
	}
      else
	{
	  srel->r_index[2] = (bfd_byte) (indx >> 16);
	  srel->r_index[1] = (bfd_byte) (indx >> 8);
	  srel->r_index[0] = (bfd_byte)indx;
	}
      /* FIXME: We may have to change the addend for a PC relative
	 reloc.  */
    }
  else
    {
      struct reloc_ext_external *erel;

      erel = (struct reloc_ext_external *) p;
      PUT_WORD (dynobj,
		(GET_WORD (dynobj, erel->r_address)
		 + input_section->output_section->vma
		 + input_section->output_offset),
		erel->r_address);
      if (bfd_header_big_endian (dynobj))
	{
	  erel->r_index[0] = (bfd_byte) (indx >> 16);
	  erel->r_index[1] = (bfd_byte) (indx >> 8);
	  erel->r_index[2] = (bfd_byte)indx;
	}
      else
	{
	  erel->r_index[2] = (bfd_byte) (indx >> 16);
	  erel->r_index[1] = (bfd_byte) (indx >> 8);
	  erel->r_index[0] = (bfd_byte)indx;
	}
      if (pcrel && h != NULL)
	{
	  /* Adjust the addend for the change in address.  */
	  PUT_WORD (dynobj,
		    (GET_WORD (dynobj, erel->r_addend)
		     - (input_section->output_section->vma
			+ input_section->output_offset
			- input_section->vma)),
		    erel->r_addend);
	}
    }

  ++s->reloc_count;

  if (h != NULL)
    *skip = TRUE;

  return TRUE;
}

/* Finish up the dynamic linking information.  */

static bfd_boolean
sunos_finish_dynamic_link (abfd, info)
     bfd *abfd;
     struct bfd_link_info *info;
{
  bfd *dynobj;
  asection *o;
  asection *s;
  asection *sdyn;

  if (! sunos_hash_table (info)->dynamic_sections_needed
      && ! sunos_hash_table (info)->got_needed)
    return TRUE;

  dynobj = sunos_hash_table (info)->dynobj;

  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
  BFD_ASSERT (sdyn != NULL);

  /* Finish up the .need section.  The linker emulation code filled it
     in, but with offsets from the start of the section instead of
     real addresses.  Now that we know the section location, we can
     fill in the final values.  */
  s = bfd_get_section_by_name (dynobj, ".need");
  if (s != NULL && s->_raw_size != 0)
    {
      file_ptr filepos;
      bfd_byte *p;

      filepos = s->output_section->filepos + s->output_offset;
      p = s->contents;
      while (1)
	{
	  bfd_vma val;

	  PUT_WORD (dynobj, GET_WORD (dynobj, p) + filepos, p);
	  val = GET_WORD (dynobj, p + 12);
	  if (val == 0)
	    break;
	  PUT_WORD (dynobj, val + filepos, p + 12);
	  p += 16;
	}
    }

  /* The first entry in the .got section is the address of the
     dynamic information, unless this is a shared library.  */
  s = bfd_get_section_by_name (dynobj, ".got");
  BFD_ASSERT (s != NULL);
  if (info->shared || sdyn->_raw_size == 0)
    PUT_WORD (dynobj, 0, s->contents);
  else
    PUT_WORD (dynobj, sdyn->output_section->vma + sdyn->output_offset,
	      s->contents);

  for (o = dynobj->sections; o != NULL; o = o->next)
    {
      if ((o->flags & SEC_HAS_CONTENTS) != 0
	  && o->contents != NULL)
	{
	  BFD_ASSERT (o->output_section != NULL
		      && o->output_section->owner == abfd);
	  if (! bfd_set_section_contents (abfd, o->output_section,
					  o->contents,
					  (file_ptr) o->output_offset,
					  o->_raw_size))
	    return FALSE;
	}
    }

  if (sdyn->_raw_size > 0)
    {
      struct external_sun4_dynamic esd;
      struct external_sun4_dynamic_link esdl;
      file_ptr pos;

      /* Finish up the dynamic link information.  */
      PUT_WORD (dynobj, (bfd_vma) 3, esd.ld_version);
      PUT_WORD (dynobj,
		sdyn->output_section->vma + sdyn->output_offset + sizeof esd,
		esd.ldd);
      PUT_WORD (dynobj,
		(sdyn->output_section->vma
		 + sdyn->output_offset
		 + sizeof esd
		 + EXTERNAL_SUN4_DYNAMIC_DEBUGGER_SIZE),
		esd.ld);

      if (! bfd_set_section_contents (abfd, sdyn->output_section, &esd,
				      (file_ptr) sdyn->output_offset,
				      (bfd_size_type) sizeof esd))
	return FALSE;

      PUT_WORD (dynobj, (bfd_vma) 0, esdl.ld_loaded);

      s = bfd_get_section_by_name (dynobj, ".need");
      if (s == NULL || s->_raw_size == 0)
	PUT_WORD (dynobj, (bfd_vma) 0, esdl.ld_need);
      else
	PUT_WORD (dynobj, s->output_section->filepos + s->output_offset,
		  esdl.ld_need);

      s = bfd_get_section_by_name (dynobj, ".rules");
      if (s == NULL || s->_raw_size == 0)
	PUT_WORD (dynobj, (bfd_vma) 0, esdl.ld_rules);
      else
	PUT_WORD (dynobj, s->output_section->filepos + s->output_offset,
		  esdl.ld_rules);

      s = bfd_get_section_by_name (dynobj, ".got");
      BFD_ASSERT (s != NULL);
      PUT_WORD (dynobj, s->output_section->vma + s->output_offset,
		esdl.ld_got);

      s = bfd_get_section_by_name (dynobj, ".plt");
      BFD_ASSERT (s != NULL);
      PUT_WORD (dynobj, s->output_section->vma + s->output_offset,
		esdl.ld_plt);
      PUT_WORD (dynobj, s->_raw_size, esdl.ld_plt_sz);

      s = bfd_get_section_by_name (dynobj, ".dynrel");
      BFD_ASSERT (s != NULL);
      BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj)
		  == s->_raw_size);
      PUT_WORD (dynobj, s->output_section->filepos + s->output_offset,
		esdl.ld_rel);

      s = bfd_get_section_by_name (dynobj, ".hash");
      BFD_ASSERT (s != NULL);
      PUT_WORD (dynobj, s->output_section->filepos + s->output_offset,
		esdl.ld_hash);

      s = bfd_get_section_by_name (dynobj, ".dynsym");
      BFD_ASSERT (s != NULL);
      PUT_WORD (dynobj, s->output_section->filepos + s->output_offset,
		esdl.ld_stab);

      PUT_WORD (dynobj, (bfd_vma) 0, esdl.ld_stab_hash);

      PUT_WORD (dynobj, (bfd_vma) sunos_hash_table (info)->bucketcount,
		esdl.ld_buckets);

      s = bfd_get_section_by_name (dynobj, ".dynstr");
      BFD_ASSERT (s != NULL);
      PUT_WORD (dynobj, s->output_section->filepos + s->output_offset,
		esdl.ld_symbols);
      PUT_WORD (dynobj, s->_raw_size, esdl.ld_symb_size);

      /* The size of the text area is the size of the .text section
	 rounded up to a page boundary.  FIXME: Should the page size be
	 conditional on something?  */
      PUT_WORD (dynobj,
		BFD_ALIGN (obj_textsec (abfd)->_raw_size, 0x2000),
		esdl.ld_text);

      pos = sdyn->output_offset;
      pos += sizeof esd + EXTERNAL_SUN4_DYNAMIC_DEBUGGER_SIZE;
      if (! bfd_set_section_contents (abfd, sdyn->output_section, &esdl,
				      pos, (bfd_size_type) sizeof esdl))
	return FALSE;

      abfd->flags |= DYNAMIC;
    }

  return TRUE;
}
