/* BFD backend for SunOS binaries.
   Copyright 1990, 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2011, 2012
   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 3 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., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, 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 "sysdep.h"
#include "bfd.h"
#include "bfdlink.h"
#include "libaout.h"

/* ??? 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))

#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_synthetic_symtab            _bfd_nodynamic_get_synthetic_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

static bfd_boolean sunos_add_dynamic_symbols            (bfd *, struct bfd_link_info *, struct external_nlist **, bfd_size_type *, char **);
static bfd_boolean sunos_add_one_symbol                 (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_link_dynamic_object            (struct bfd_link_info *, bfd *);
static bfd_boolean sunos_write_dynamic_symbol           (bfd *, struct bfd_link_info *, struct aout_link_hash_entry *);
static bfd_boolean sunos_check_dynamic_reloc            (struct bfd_link_info *, bfd *, asection *, struct aout_link_hash_entry *, void *, bfd_byte *, bfd_boolean *, bfd_vma *);
static bfd_boolean sunos_finish_dynamic_link            (bfd *, struct bfd_link_info *);
static struct bfd_link_hash_table *sunos_link_hash_table_create  (bfd *);
static long        sunos_get_dynamic_symtab_upper_bound (bfd *);
static long        sunos_canonicalize_dynamic_symtab    (bfd *, asymbol **);
static long        sunos_get_dynamic_reloc_upper_bound  (bfd *);
static long        sunos_canonicalize_dynamic_reloc     (bfd *, arelent **, asymbol **);

/* 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.  */
  void * 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 (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) != NULL)
    return TRUE;

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

  amt = sizeof (struct sunos_dynamic_info);
  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) = (void *) 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), (void *) &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 > dynsec->size)
    return TRUE;

  /* This executable appears to be dynamically linked in a way that we
     can understand.  */
  if (! bfd_get_section_contents (abfd, dynsec, (void *) &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 (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 (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 == NULL)
    {
      amt = (bfd_size_type) info->dynsym_count * EXTERNAL_NLIST_SIZE;
      info->dynsym = 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 ((void *) 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 == NULL)
    {
      amt = info->dyninfo.ld_symb_size;
      info->dynstr = 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 ((void *) 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 (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_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 ((void *) 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 == 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 = 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 (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 (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) == 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 = 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 ((void *) 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 == NULL)
    {
      arelent *to;

      size = (bfd_size_type) info->dynrel_count * sizeof (arelent);
      info->canonical_dynrel = 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)
	{
	  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
	{
	  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 (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 ==  NULL)
    ret = bfd_hash_allocate (table, sizeof (* ret));
  if (ret == NULL)
    return NULL;

  /* 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 (bfd *abfd)
{
  struct sunos_link_hash_table *ret;
  bfd_size_type amt = sizeof (struct sunos_link_hash_table);

  ret = bfd_malloc (amt);
  if (ret ==  NULL)
    return NULL;
  if (!NAME (aout, link_hash_table_init) (&ret->root, abfd,
					  sunos_link_hash_newfunc,
					  sizeof (struct sunos_link_hash_entry)))
    {
      free (ret);
      return 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 (*) (struct aout_link_hash_entry *, void *)) (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))

/* 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 (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_anyway_with_flags (abfd, ".dynamic", flags);
      if (s == NULL
	  || ! 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_anyway_with_flags (abfd, ".got", flags);
      if (s == NULL
	  || ! 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_anyway_with_flags (abfd, ".plt", flags | SEC_CODE);
      if (s == NULL
	  || ! 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_anyway_with_flags (abfd, ".dynrel",
					      flags | SEC_READONLY);
      if (s == NULL
	  || ! 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_anyway_with_flags (abfd, ".hash",
					      flags | SEC_READONLY);
      if (s == NULL
	  || ! 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_anyway_with_flags (abfd, ".dynsym",
					      flags | SEC_READONLY);
      if (s == NULL
	  || ! 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_anyway_with_flags (abfd, ".dynstr",
					      flags | SEC_READONLY);
      if (s == NULL
	  || ! 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_linker_section (dynobj, ".got");
      if (s->size == 0)
	s->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 (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;

  /* Make sure we have all the required sections.  */
  if (info->output_bfd->xvec == abfd->xvec)
    {
      if (! sunos_create_dynamic_sections (abfd, info,
					   ((abfd->flags & DYNAMIC) != 0
					    && !info->relocatable)))
	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.  */
  if (abfd != dynobj)
    abfd->sections = NULL;
  else
    {
      asection *s;

      for (s = abfd->sections; s != NULL; s = s->next)
	{
	  if ((s->flags & SEC_LINKER_CREATED) == 0)
	    bfd_section_list_remove (abfd, s);
	}
    }

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

  /* There's no hope of using a dynamic object which does not exactly
     match the format of the output file.  */
  if (info->output_bfd->xvec != 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.  */
      flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
			| SEC_IN_MEMORY | SEC_READONLY);
      asection *s = bfd_make_section_with_flags (dynobj, ".need", flags);
      if (s == NULL
	  || ! 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.  */
      flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
			| SEC_IN_MEMORY | SEC_READONLY);
      asection *s = bfd_make_section_with_flags (dynobj, ".rules", flags);
      if (s == NULL
	  || ! 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 = bfd_alloc (abfd, alc);
      if (needed == NULL)
	return FALSE;
      needed->by = abfd;

      /* We return the name as [-l]name[.maj][.min].  */
      alc = 30;
      namebuf = 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 = 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 = 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 (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->output_bfd->xvec
      && (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->output_bfd->xvec)
    {
      /* 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;
}

extern const bfd_target MY (vec);

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

struct bfd_link_needed_list *
bfd_sunos_get_needed_list (bfd *abfd ATTRIBUTE_UNUSED,
			   struct bfd_link_info *info)
{
  if (info->output_bfd->xvec != &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 (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;
}

/* 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 (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_linker_section (dynobj, ".plt");
	  srel = bfd_get_linker_section (dynobj, ".dynrel");
	  BFD_ASSERT (splt != NULL && srel != NULL);

	  sgot = bfd_get_linker_section (dynobj, ".got");
	  BFD_ASSERT (sgot != NULL);
	  if (sgot->size == 0)
	    sgot->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->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->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->size == 0)
		splt->size = M68K_PLT_ENTRY_SIZE;
	      h->plt_offset = splt->size;

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

	      splt->size += M68K_PLT_ENTRY_SIZE;

	      /* We may also need a dynamic reloc entry.  */
	      if ((h->flags & SUNOS_DEF_REGULAR) == 0)
		srel->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 (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_linker_section (dynobj, ".plt");
	      sgot = bfd_get_linker_section (dynobj, ".got");
	      srel = bfd_get_linker_section (dynobj, ".dynrel");
	      BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL);

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

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

	      h->got_offset = sgot->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_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->size;
	    }

	  sgot->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->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_linker_section (dynobj, ".plt");
		  sgot = bfd_get_linker_section (dynobj, ".got");
		  srel = bfd_get_linker_section (dynobj, ".dynrel");
		  BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL);
		}

	      srel->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_linker_section (dynobj, ".plt");
	  sgot = bfd_get_linker_section (dynobj, ".got");
	  srel = bfd_get_linker_section (dynobj, ".dynrel");
	  BFD_ASSERT (splt != NULL && sgot != NULL && srel != NULL);

	  /* Make sure we have an initial entry in the .got table.  */
	  if (sgot->size == 0)
	    sgot->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->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->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->size == 0)
		splt->size = SPARC_PLT_ENTRY_SIZE;
	      h->plt_offset = splt->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->size;
		}

	      splt->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->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->size += RELOC_EXT_SIZE;
	}
    }

  return TRUE;
}

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

static bfd_boolean
sunos_scan_relocs (struct bfd_link_info *info,
		   bfd *abfd,
		   asection *sec,
		   bfd_size_type rel_size)
{
  void * relocs;
  void * 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 = 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;
}

/* 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 (struct sunos_link_hash_entry *h, void * data)
{
  struct bfd_link_info *info = (struct bfd_link_info *) data;

  /* 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_linker_section (dynobj, ".dynstr");
      BFD_ASSERT (s != NULL);
      contents = bfd_realloc (s->contents, s->size + len + 1);
      if (contents == NULL)
	return FALSE;
      s->contents = contents;

      h->dynstr_index = s->size;
      strcpy ((char *) contents + s->size, h->root.root.root.string);
      s->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_linker_section (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->size / HASH_ENTRY_SIZE,
		    s->contents + hash * HASH_ENTRY_SIZE + BYTES_IN_WORD);
	  PUT_WORD (dynobj, h->dynindx, s->contents + s->size);
	  PUT_WORD (dynobj, next, s->contents + s->size + BYTES_IN_WORD);
	  s->size += HASH_ENTRY_SIZE;
	}
    }

  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 (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->relocatable)
    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;
	}
      s = bfd_get_linker_section (dynobj, ".got");
      BFD_ASSERT (s != NULL);
      h->root.root.type = bfd_link_hash_defined;
      h->root.root.u.def.section = s;

      /* 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.  */
      if (s->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_linker_section (dynobj, ".dynamic");

      /* The .dynamic section is always the same size.  */
      s = *sdynptr;
      BFD_ASSERT (s != NULL);
      s->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_linker_section (dynobj, ".dynsym");
      BFD_ASSERT (s != NULL);
      s->size = dynsymcount * sizeof (struct external_nlist);
      s->contents = bfd_alloc (output_bfd, s->size);
      if (s->contents == NULL && s->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_linker_section (dynobj, ".hash");
      BFD_ASSERT (s != NULL);
      hashalloc = (dynsymcount + bucketcount - 1) * HASH_ENTRY_SIZE;
      s->contents = 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->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,
				(void *) 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_linker_section (dynobj, ".dynstr");
      BFD_ASSERT (s != NULL);
      if ((s->size & 7) != 0)
	{
	  bfd_size_type add;
	  bfd_byte *contents;

	  add = 8 - (s->size & 7);
	  contents = bfd_realloc (s->contents, s->size + add);
	  if (contents == NULL)
	    return FALSE;
	  memset (contents + s->size, 0, (size_t) add);
	  s->contents = contents;
	  s->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_linker_section (dynobj, ".plt");
  BFD_ASSERT (s != NULL);
  if (s->size != 0)
    {
      s->contents = bfd_alloc (dynobj, s->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_linker_section (dynobj, ".dynrel");
  if (s->size != 0)
    {
      s->contents = bfd_alloc (dynobj, s->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_linker_section (dynobj, ".got");
  s->contents = bfd_alloc (dynobj, s->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;
}

/* 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.  */

static bfd_boolean
sunos_link_dynamic_object (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 (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_linker_section (dynobj, ".plt");
      p = splt->contents + h->plt_offset;

      s = bfd_get_linker_section (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->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_linker_section (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.  */

static bfd_boolean
sunos_check_dynamic_reloc (struct bfd_link_info *info,
			   bfd *input_bfd,
			   asection *input_section,
			   struct aout_link_hash_entry *harg,
			   void * 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_linker_section (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_linker_section (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_linker_section (dynobj, ".dynrel");
	      BFD_ASSERT (s != NULL);
	      BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj)
			  < s->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_linker_section (dynobj, ".dynrel");
  BFD_ASSERT (s != NULL);
  BFD_ASSERT (s->reloc_count * obj_reloc_entry_size (dynobj) < s->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 (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_linker_section (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->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_linker_section (dynobj, ".got");
  BFD_ASSERT (s != NULL);
  if (info->shared || sdyn->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->size))
	    return FALSE;
	}
    }

  if (sdyn->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->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->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_linker_section (dynobj, ".got");
      BFD_ASSERT (s != NULL);
      PUT_WORD (dynobj, s->output_section->vma + s->output_offset,
		esdl.ld_got);

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

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

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

      s = bfd_get_linker_section (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_linker_section (dynobj, ".dynstr");
      BFD_ASSERT (s != NULL);
      PUT_WORD (dynobj, s->output_section->filepos + s->output_offset,
		esdl.ld_symbols);
      PUT_WORD (dynobj, s->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)->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;
}
