/* Generic ECOFF (Extended-COFF) routines.
   Copyright (C) 1990-2016 Free Software Foundation, Inc.
   Original version by Per Bothner.
   Full support added by Ian Lance Taylor, ian@cygnus.com.

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

#include "sysdep.h"
#include "bfd.h"
#include "bfdlink.h"
#include "libbfd.h"
#include "aout/ar.h"
#include "aout/stab_gnu.h"

/* FIXME: We need the definitions of N_SET[ADTB], but aout64.h defines
   some other stuff which we don't want and which conflicts with stuff
   we do want.  */
#include "libaout.h"
#include "aout/aout64.h"
#undef N_ABS
#undef exec_hdr
#undef obj_sym_filepos

#include "coff/internal.h"
#include "coff/sym.h"
#include "coff/symconst.h"
#include "coff/ecoff.h"
#include "libcoff.h"
#include "libecoff.h"
#include "libiberty.h"

#define streq(a, b)	(strcmp ((a), (b)) == 0)
#define strneq(a, b, n)	(strncmp ((a), (b), (n)) == 0)


/* This stuff is somewhat copied from coffcode.h.  */
static asection bfd_debug_section =
{
  /* name,      id,  index, next, prev, flags, user_set_vma,       */
     "*DEBUG*", 0,   0,     NULL, NULL, 0,     0,
  /* linker_mark, linker_has_input, gc_mark, compress_status,      */
     0,           0,                1,       0,
  /* segment_mark, sec_info_type, use_rela_p,                      */
     0,            0,             0,
  /* sec_flg0, sec_flg1, sec_flg2, sec_flg3, sec_flg4, sec_flg5,   */
     0,        0,        0,        0,        0,        0,
  /* vma, lma, size, rawsize, compressed_size, relax, relax_count, */
     0,   0,   0,    0,       0,               0,     0,
  /* output_offset, output_section, alignment_power,               */
     0,             NULL,           0,
  /* relocation, orelocation, reloc_count, filepos, rel_filepos,   */
     NULL,       NULL,        0,           0,       0,
  /* line_filepos, userdata, contents, lineno, lineno_count,       */
     0,            NULL,     NULL,     NULL,   0,
  /* entsize, kept_section, moving_line_filepos,                   */
     0,       NULL,         0,
  /* target_index, used_by_bfd, constructor_chain, owner,          */
     0,            NULL,        NULL,              NULL,
  /* symbol,                                                       */
     NULL,
  /* symbol_ptr_ptr,                                               */
     NULL,
  /* map_head, map_tail                                            */
     { NULL }, { NULL }
};

/* Create an ECOFF object.  */

bfd_boolean
_bfd_ecoff_mkobject (bfd *abfd)
{
  bfd_size_type amt = sizeof (ecoff_data_type);

  abfd->tdata.ecoff_obj_data = (struct ecoff_tdata *) bfd_zalloc (abfd, amt);
  if (abfd->tdata.ecoff_obj_data == NULL)
    return FALSE;

  return TRUE;
}

/* This is a hook called by coff_real_object_p to create any backend
   specific information.  */

void *
_bfd_ecoff_mkobject_hook (bfd *abfd, void * filehdr, void * aouthdr)
{
  struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
  struct internal_aouthdr *internal_a = (struct internal_aouthdr *) aouthdr;
  ecoff_data_type *ecoff;

  if (! _bfd_ecoff_mkobject (abfd))
    return NULL;

  ecoff = ecoff_data (abfd);
  ecoff->gp_size = 8;
  ecoff->sym_filepos = internal_f->f_symptr;

  if (internal_a != NULL)
    {
      int i;

      ecoff->text_start = internal_a->text_start;
      ecoff->text_end = internal_a->text_start + internal_a->tsize;
      ecoff->gp = internal_a->gp_value;
      ecoff->gprmask = internal_a->gprmask;
      for (i = 0; i < 4; i++)
	ecoff->cprmask[i] = internal_a->cprmask[i];
      ecoff->fprmask = internal_a->fprmask;
      if (internal_a->magic == ECOFF_AOUT_ZMAGIC)
	abfd->flags |= D_PAGED;
      else
	abfd->flags &=~ D_PAGED;
    }

  /* It turns out that no special action is required by the MIPS or
     Alpha ECOFF backends.  They have different information in the
     a.out header, but we just copy it all (e.g., gprmask, cprmask and
     fprmask) and let the swapping routines ensure that only relevant
     information is written out.  */

  return (void *) ecoff;
}

/* Initialize a new section.  */

bfd_boolean
_bfd_ecoff_new_section_hook (bfd *abfd, asection *section)
{
  unsigned int i;
  static struct
  {
    const char * name;
    flagword flags;
  }
  section_flags [] =
  {
    { _TEXT,   SEC_ALLOC | SEC_CODE | SEC_LOAD },
    { _INIT,   SEC_ALLOC | SEC_CODE | SEC_LOAD },
    { _FINI,   SEC_ALLOC | SEC_CODE | SEC_LOAD },
    { _DATA,   SEC_ALLOC | SEC_DATA | SEC_LOAD },
    { _SDATA,  SEC_ALLOC | SEC_DATA | SEC_LOAD },
    { _RDATA,  SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY},
    { _LIT8,   SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY},
    { _LIT4,   SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY},
    { _RCONST, SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY},
    { _PDATA,  SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY},
    { _BSS,    SEC_ALLOC},
    { _SBSS,   SEC_ALLOC},
    /* An Irix 4 shared libary.  */
    { _LIB,    SEC_COFF_SHARED_LIBRARY}
  };

  section->alignment_power = 4;

  for (i = 0; i < ARRAY_SIZE (section_flags); i++)
    if (streq (section->name, section_flags[i].name))
      {
	section->flags |= section_flags[i].flags;
	break;
      }


  /* Probably any other section name is SEC_NEVER_LOAD, but I'm
     uncertain about .init on some systems and I don't know how shared
     libraries work.  */

  return _bfd_generic_new_section_hook (abfd, section);
}

/* Determine the machine architecture and type.  This is called from
   the generic COFF routines.  It is the inverse of ecoff_get_magic,
   below.  This could be an ECOFF backend routine, with one version
   for each target, but there aren't all that many ECOFF targets.  */

bfd_boolean
_bfd_ecoff_set_arch_mach_hook (bfd *abfd, void * filehdr)
{
  struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
  enum bfd_architecture arch;
  unsigned long mach;

  switch (internal_f->f_magic)
    {
    case MIPS_MAGIC_1:
    case MIPS_MAGIC_LITTLE:
    case MIPS_MAGIC_BIG:
      arch = bfd_arch_mips;
      mach = bfd_mach_mips3000;
      break;

    case MIPS_MAGIC_LITTLE2:
    case MIPS_MAGIC_BIG2:
      /* MIPS ISA level 2: the r6000.  */
      arch = bfd_arch_mips;
      mach = bfd_mach_mips6000;
      break;

    case MIPS_MAGIC_LITTLE3:
    case MIPS_MAGIC_BIG3:
      /* MIPS ISA level 3: the r4000.  */
      arch = bfd_arch_mips;
      mach = bfd_mach_mips4000;
      break;

    case ALPHA_MAGIC:
      arch = bfd_arch_alpha;
      mach = 0;
      break;

    default:
      arch = bfd_arch_obscure;
      mach = 0;
      break;
    }

  return bfd_default_set_arch_mach (abfd, arch, mach);
}

bfd_boolean
_bfd_ecoff_no_long_sections (bfd *abfd, int enable)
{
  (void) abfd;
  (void) enable;
  return FALSE;
}

/* Get the magic number to use based on the architecture and machine.
   This is the inverse of _bfd_ecoff_set_arch_mach_hook, above.  */

static int
ecoff_get_magic (bfd *abfd)
{
  int big, little;

  switch (bfd_get_arch (abfd))
    {
    case bfd_arch_mips:
      switch (bfd_get_mach (abfd))
	{
	default:
	case 0:
	case bfd_mach_mips3000:
	  big = MIPS_MAGIC_BIG;
	  little = MIPS_MAGIC_LITTLE;
	  break;

	case bfd_mach_mips6000:
	  big = MIPS_MAGIC_BIG2;
	  little = MIPS_MAGIC_LITTLE2;
	  break;

	case bfd_mach_mips4000:
	  big = MIPS_MAGIC_BIG3;
	  little = MIPS_MAGIC_LITTLE3;
	  break;
	}

      return bfd_big_endian (abfd) ? big : little;

    case bfd_arch_alpha:
      return ALPHA_MAGIC;

    default:
      abort ();
      return 0;
    }
}

/* Get the section s_flags to use for a section.  */

static long
ecoff_sec_to_styp_flags (const char *name, flagword flags)
{
  unsigned int i;
  static struct
  {
    const char * name;
    long flags;
  }
  styp_flags [] =
  {
    { _TEXT,    STYP_TEXT       },
    { _DATA,    STYP_DATA       },
    { _SDATA,   STYP_SDATA      },
    { _RDATA,   STYP_RDATA      },
    { _LITA,    STYP_LITA       },
    { _LIT8,    STYP_LIT8       },
    { _LIT4,    STYP_LIT4       },
    { _BSS,     STYP_BSS        },
    { _SBSS,    STYP_SBSS       },
    { _INIT,    STYP_ECOFF_INIT },
    { _FINI,    STYP_ECOFF_FINI },
    { _PDATA,   STYP_PDATA      },
    { _XDATA,   STYP_XDATA      },
    { _LIB,     STYP_ECOFF_LIB  },
    { _GOT,     STYP_GOT        },
    { _HASH,    STYP_HASH       },
    { _DYNAMIC, STYP_DYNAMIC    },
    { _LIBLIST, STYP_LIBLIST    },
    { _RELDYN,  STYP_RELDYN     },
    { _CONFLIC, STYP_CONFLIC    },
    { _DYNSTR,  STYP_DYNSTR     },
    { _DYNSYM,  STYP_DYNSYM     },
    { _RCONST,  STYP_RCONST     }
  };
  long styp = 0;

  for (i = 0; i < ARRAY_SIZE (styp_flags); i++)
    if (streq (name, styp_flags[i].name))
      {
	styp = styp_flags[i].flags;
	break;
      }

  if (styp == 0)
    {
      if (streq (name, _COMMENT))
	{
	  styp = STYP_COMMENT;
	  flags &=~ SEC_NEVER_LOAD;
	}
      else if (flags & SEC_CODE)
	styp = STYP_TEXT;
      else if (flags & SEC_DATA)
	styp = STYP_DATA;
      else if (flags & SEC_READONLY)
	styp = STYP_RDATA;
      else if (flags & SEC_LOAD)
	styp = STYP_REG;
      else
	styp = STYP_BSS;
    }

  if (flags & SEC_NEVER_LOAD)
    styp |= STYP_NOLOAD;

  return styp;
}

/* Get the BFD flags to use for a section.  */

bfd_boolean
_bfd_ecoff_styp_to_sec_flags (bfd *abfd ATTRIBUTE_UNUSED,
			      void * hdr,
			      const char *name ATTRIBUTE_UNUSED,
			      asection *section ATTRIBUTE_UNUSED,
			      flagword * flags_ptr)
{
  struct internal_scnhdr *internal_s = (struct internal_scnhdr *) hdr;
  long styp_flags = internal_s->s_flags;
  flagword sec_flags = 0;

  if (styp_flags & STYP_NOLOAD)
    sec_flags |= SEC_NEVER_LOAD;

  /* For 386 COFF, at least, an unloadable text or data section is
     actually a shared library section.  */
  if ((styp_flags & STYP_TEXT)
      || (styp_flags & STYP_ECOFF_INIT)
      || (styp_flags & STYP_ECOFF_FINI)
      || (styp_flags & STYP_DYNAMIC)
      || (styp_flags & STYP_LIBLIST)
      || (styp_flags & STYP_RELDYN)
      || styp_flags == STYP_CONFLIC
      || (styp_flags & STYP_DYNSTR)
      || (styp_flags & STYP_DYNSYM)
      || (styp_flags & STYP_HASH))
    {
      if (sec_flags & SEC_NEVER_LOAD)
	sec_flags |= SEC_CODE | SEC_COFF_SHARED_LIBRARY;
      else
	sec_flags |= SEC_CODE | SEC_LOAD | SEC_ALLOC;
    }
  else if ((styp_flags & STYP_DATA)
	   || (styp_flags & STYP_RDATA)
	   || (styp_flags & STYP_SDATA)
	   || styp_flags == STYP_PDATA
	   || styp_flags == STYP_XDATA
	   || (styp_flags & STYP_GOT)
	   || styp_flags == STYP_RCONST)
    {
      if (sec_flags & SEC_NEVER_LOAD)
	sec_flags |= SEC_DATA | SEC_COFF_SHARED_LIBRARY;
      else
	sec_flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC;
      if ((styp_flags & STYP_RDATA)
	  || styp_flags == STYP_PDATA
	  || styp_flags == STYP_RCONST)
	sec_flags |= SEC_READONLY;
    }
  else if ((styp_flags & STYP_BSS)
	   || (styp_flags & STYP_SBSS))
    sec_flags |= SEC_ALLOC;
  else if ((styp_flags & STYP_INFO) || styp_flags == STYP_COMMENT)
    sec_flags |= SEC_NEVER_LOAD;
  else if ((styp_flags & STYP_LITA)
	   || (styp_flags & STYP_LIT8)
	   || (styp_flags & STYP_LIT4))
    sec_flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC | SEC_READONLY;
  else if (styp_flags & STYP_ECOFF_LIB)
    sec_flags |= SEC_COFF_SHARED_LIBRARY;
  else
    sec_flags |= SEC_ALLOC | SEC_LOAD;

  * flags_ptr = sec_flags;
  return TRUE;
}

/* Read in the symbolic header for an ECOFF object file.  */

static bfd_boolean
ecoff_slurp_symbolic_header (bfd *abfd)
{
  const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
  bfd_size_type external_hdr_size;
  void * raw = NULL;
  HDRR *internal_symhdr;

  /* See if we've already read it in.  */
  if (ecoff_data (abfd)->debug_info.symbolic_header.magic ==
      backend->debug_swap.sym_magic)
    return TRUE;

  /* See whether there is a symbolic header.  */
  if (ecoff_data (abfd)->sym_filepos == 0)
    {
      bfd_get_symcount (abfd) = 0;
      return TRUE;
    }

  /* At this point bfd_get_symcount (abfd) holds the number of symbols
     as read from the file header, but on ECOFF this is always the
     size of the symbolic information header.  It would be cleaner to
     handle this when we first read the file in coffgen.c.  */
  external_hdr_size = backend->debug_swap.external_hdr_size;
  if (bfd_get_symcount (abfd) != external_hdr_size)
    {
      bfd_set_error (bfd_error_bad_value);
      return FALSE;
    }

  /* Read the symbolic information header.  */
  raw = bfd_malloc (external_hdr_size);
  if (raw == NULL)
    goto error_return;

  if (bfd_seek (abfd, ecoff_data (abfd)->sym_filepos, SEEK_SET) != 0
      || bfd_bread (raw, external_hdr_size, abfd) != external_hdr_size)
    goto error_return;
  internal_symhdr = &ecoff_data (abfd)->debug_info.symbolic_header;
  (*backend->debug_swap.swap_hdr_in) (abfd, raw, internal_symhdr);

  if (internal_symhdr->magic != backend->debug_swap.sym_magic)
    {
      bfd_set_error (bfd_error_bad_value);
      goto error_return;
    }

  /* Now we can get the correct number of symbols.  */
  bfd_get_symcount (abfd) = (internal_symhdr->isymMax
			     + internal_symhdr->iextMax);

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

/* Read in and swap the important symbolic information for an ECOFF
   object file.  This is called by gdb via the read_debug_info entry
   point in the backend structure.  */

bfd_boolean
_bfd_ecoff_slurp_symbolic_info (bfd *abfd,
				asection *ignore ATTRIBUTE_UNUSED,
				struct ecoff_debug_info *debug)
{
  const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
  HDRR *internal_symhdr;
  bfd_size_type raw_base;
  bfd_size_type raw_size;
  void * raw;
  bfd_size_type external_fdr_size;
  char *fraw_src;
  char *fraw_end;
  struct fdr *fdr_ptr;
  bfd_size_type raw_end;
  bfd_size_type cb_end;
  file_ptr pos;

  BFD_ASSERT (debug == &ecoff_data (abfd)->debug_info);

  /* Check whether we've already gotten it, and whether there's any to
     get.  */
  if (ecoff_data (abfd)->raw_syments != NULL)
    return TRUE;
  if (ecoff_data (abfd)->sym_filepos == 0)
    {
      bfd_get_symcount (abfd) = 0;
      return TRUE;
    }

  if (! ecoff_slurp_symbolic_header (abfd))
    return FALSE;

  internal_symhdr = &debug->symbolic_header;

  /* Read all the symbolic information at once.  */
  raw_base = (ecoff_data (abfd)->sym_filepos
	      + backend->debug_swap.external_hdr_size);

  /* Alpha ecoff makes the determination of raw_size difficult. It has
     an undocumented debug data section between the symhdr and the first
     documented section. And the ordering of the sections varies between
     statically and dynamically linked executables.
     If bfd supports SEEK_END someday, this code could be simplified.  */
  raw_end = 0;

#define UPDATE_RAW_END(start, count, size) \
  cb_end = internal_symhdr->start + internal_symhdr->count * (size); \
  if (cb_end > raw_end) \
    raw_end = cb_end

  UPDATE_RAW_END (cbLineOffset, cbLine, sizeof (unsigned char));
  UPDATE_RAW_END (cbDnOffset, idnMax, backend->debug_swap.external_dnr_size);
  UPDATE_RAW_END (cbPdOffset, ipdMax, backend->debug_swap.external_pdr_size);
  UPDATE_RAW_END (cbSymOffset, isymMax, backend->debug_swap.external_sym_size);
  /* eraxxon@alumni.rice.edu: ioptMax refers to the size of the
     optimization symtab, not the number of entries.  */
  UPDATE_RAW_END (cbOptOffset, ioptMax, sizeof (char));
  UPDATE_RAW_END (cbAuxOffset, iauxMax, sizeof (union aux_ext));
  UPDATE_RAW_END (cbSsOffset, issMax, sizeof (char));
  UPDATE_RAW_END (cbSsExtOffset, issExtMax, sizeof (char));
  UPDATE_RAW_END (cbFdOffset, ifdMax, backend->debug_swap.external_fdr_size);
  UPDATE_RAW_END (cbRfdOffset, crfd, backend->debug_swap.external_rfd_size);
  UPDATE_RAW_END (cbExtOffset, iextMax, backend->debug_swap.external_ext_size);

#undef UPDATE_RAW_END

  raw_size = raw_end - raw_base;
  if (raw_size == 0)
    {
      ecoff_data (abfd)->sym_filepos = 0;
      return TRUE;
    }
  raw = bfd_alloc (abfd, raw_size);
  if (raw == NULL)
    return FALSE;

  pos = ecoff_data (abfd)->sym_filepos;
  pos += backend->debug_swap.external_hdr_size;
  if (bfd_seek (abfd, pos, SEEK_SET) != 0
      || bfd_bread (raw, raw_size, abfd) != raw_size)
    {
      bfd_release (abfd, raw);
      return FALSE;
    }

  ecoff_data (abfd)->raw_syments = raw;

  /* Get pointers for the numeric offsets in the HDRR structure.  */
#define FIX(off1, off2, type)				\
  if (internal_symhdr->off1 == 0)			\
    debug->off2 = NULL;					\
  else							\
    debug->off2 = (type) ((char *) raw			\
			  + (internal_symhdr->off1	\
			     - raw_base))

  FIX (cbLineOffset, line, unsigned char *);
  FIX (cbDnOffset, external_dnr, void *);
  FIX (cbPdOffset, external_pdr, void *);
  FIX (cbSymOffset, external_sym, void *);
  FIX (cbOptOffset, external_opt, void *);
  FIX (cbAuxOffset, external_aux, union aux_ext *);
  FIX (cbSsOffset, ss, char *);
  FIX (cbSsExtOffset, ssext, char *);
  FIX (cbFdOffset, external_fdr, void *);
  FIX (cbRfdOffset, external_rfd, void *);
  FIX (cbExtOffset, external_ext, void *);
#undef FIX

  /* I don't want to always swap all the data, because it will just
     waste time and most programs will never look at it.  The only
     time the linker needs most of the debugging information swapped
     is when linking big-endian and little-endian MIPS object files
     together, which is not a common occurrence.

     We need to look at the fdr to deal with a lot of information in
     the symbols, so we swap them here.  */
  debug->fdr = (FDR *) bfd_alloc2 (abfd, internal_symhdr->ifdMax,
				   sizeof (struct fdr));
  if (debug->fdr == NULL)
    return FALSE;
  external_fdr_size = backend->debug_swap.external_fdr_size;
  fdr_ptr = debug->fdr;
  fraw_src = (char *) debug->external_fdr;
  /* PR 17512: file: 3372-1243-0.004.  */
  if (fraw_src == NULL && internal_symhdr->ifdMax > 0)
    return FALSE;
  fraw_end = fraw_src + internal_symhdr->ifdMax * external_fdr_size;
  for (; fraw_src < fraw_end; fraw_src += external_fdr_size, fdr_ptr++)
    (*backend->debug_swap.swap_fdr_in) (abfd, (void *) fraw_src, fdr_ptr);

  return TRUE;
}

/* ECOFF symbol table routines.  The ECOFF symbol table is described
   in gcc/mips-tfile.c.  */

/* ECOFF uses two common sections.  One is the usual one, and the
   other is for small objects.  All the small objects are kept
   together, and then referenced via the gp pointer, which yields
   faster assembler code.  This is what we use for the small common
   section.  */
static asection ecoff_scom_section;
static asymbol ecoff_scom_symbol;
static asymbol *ecoff_scom_symbol_ptr;

/* Create an empty symbol.  */

asymbol *
_bfd_ecoff_make_empty_symbol (bfd *abfd)
{
  ecoff_symbol_type *new_symbol;
  bfd_size_type amt = sizeof (ecoff_symbol_type);

  new_symbol = (ecoff_symbol_type *) bfd_zalloc (abfd, amt);
  if (new_symbol == NULL)
    return NULL;
  new_symbol->symbol.section = NULL;
  new_symbol->fdr = NULL;
  new_symbol->local = FALSE;
  new_symbol->native = NULL;
  new_symbol->symbol.the_bfd = abfd;
  return &new_symbol->symbol;
}

/* Set the BFD flags and section for an ECOFF symbol.  */

static bfd_boolean
ecoff_set_symbol_info (bfd *abfd,
		       SYMR *ecoff_sym,
		       asymbol *asym,
		       int ext,
		       int weak)
{
  asym->the_bfd = abfd;
  asym->value = ecoff_sym->value;
  asym->section = &bfd_debug_section;
  asym->udata.i = 0;

  /* Most symbol types are just for debugging.  */
  switch (ecoff_sym->st)
    {
    case stGlobal:
    case stStatic:
    case stLabel:
    case stProc:
    case stStaticProc:
      break;
    case stNil:
      if (ECOFF_IS_STAB (ecoff_sym))
	{
	  asym->flags = BSF_DEBUGGING;
	  return TRUE;
	}
      break;
    default:
      asym->flags = BSF_DEBUGGING;
      return TRUE;
    }

  if (weak)
    asym->flags = BSF_EXPORT | BSF_WEAK;
  else if (ext)
    asym->flags = BSF_EXPORT | BSF_GLOBAL;
  else
    {
      asym->flags = BSF_LOCAL;
      /* Normally, a local stProc symbol will have a corresponding
         external symbol.  We mark the local symbol as a debugging
         symbol, in order to prevent nm from printing both out.
         Similarly, we mark stLabel and stabs symbols as debugging
         symbols.  In both cases, we do want to set the value
         correctly based on the symbol class.  */
      if (ecoff_sym->st == stProc
	  || ecoff_sym->st == stLabel
	  || ECOFF_IS_STAB (ecoff_sym))
	asym->flags |= BSF_DEBUGGING;
    }

  if (ecoff_sym->st == stProc || ecoff_sym->st == stStaticProc)
    asym->flags |= BSF_FUNCTION;

  switch (ecoff_sym->sc)
    {
    case scNil:
      /* Used for compiler generated labels.  Leave them in the
	 debugging section, and mark them as local.  If BSF_DEBUGGING
	 is set, then nm does not display them for some reason.  If no
	 flags are set then the linker whines about them.  */
      asym->flags = BSF_LOCAL;
      break;
    case scText:
      asym->section = bfd_make_section_old_way (abfd, _TEXT);
      asym->value -= asym->section->vma;
      break;
    case scData:
      asym->section = bfd_make_section_old_way (abfd, _DATA);
      asym->value -= asym->section->vma;
      break;
    case scBss:
      asym->section = bfd_make_section_old_way (abfd, _BSS);
      asym->value -= asym->section->vma;
      break;
    case scRegister:
      asym->flags = BSF_DEBUGGING;
      break;
    case scAbs:
      asym->section = bfd_abs_section_ptr;
      break;
    case scUndefined:
      asym->section = bfd_und_section_ptr;
      asym->flags = 0;
      asym->value = 0;
      break;
    case scCdbLocal:
    case scBits:
    case scCdbSystem:
    case scRegImage:
    case scInfo:
    case scUserStruct:
      asym->flags = BSF_DEBUGGING;
      break;
    case scSData:
      asym->section = bfd_make_section_old_way (abfd, ".sdata");
      asym->value -= asym->section->vma;
      break;
    case scSBss:
      asym->section = bfd_make_section_old_way (abfd, ".sbss");
      asym->value -= asym->section->vma;
      break;
    case scRData:
      asym->section = bfd_make_section_old_way (abfd, ".rdata");
      asym->value -= asym->section->vma;
      break;
    case scVar:
      asym->flags = BSF_DEBUGGING;
      break;
    case scCommon:
      if (asym->value > ecoff_data (abfd)->gp_size)
	{
	  asym->section = bfd_com_section_ptr;
	  asym->flags = 0;
	  break;
	}
      /* Fall through.  */
    case scSCommon:
      if (ecoff_scom_section.name == NULL)
	{
	  /* Initialize the small common section.  */
	  ecoff_scom_section.name = SCOMMON;
	  ecoff_scom_section.flags = SEC_IS_COMMON;
	  ecoff_scom_section.output_section = &ecoff_scom_section;
	  ecoff_scom_section.symbol = &ecoff_scom_symbol;
	  ecoff_scom_section.symbol_ptr_ptr = &ecoff_scom_symbol_ptr;
	  ecoff_scom_symbol.name = SCOMMON;
	  ecoff_scom_symbol.flags = BSF_SECTION_SYM;
	  ecoff_scom_symbol.section = &ecoff_scom_section;
	  ecoff_scom_symbol_ptr = &ecoff_scom_symbol;
	}
      asym->section = &ecoff_scom_section;
      asym->flags = 0;
      break;
    case scVarRegister:
    case scVariant:
      asym->flags = BSF_DEBUGGING;
      break;
    case scSUndefined:
      asym->section = bfd_und_section_ptr;
      asym->flags = 0;
      asym->value = 0;
      break;
    case scInit:
      asym->section = bfd_make_section_old_way (abfd, ".init");
      asym->value -= asym->section->vma;
      break;
    case scBasedVar:
    case scXData:
    case scPData:
      asym->flags = BSF_DEBUGGING;
      break;
    case scFini:
      asym->section = bfd_make_section_old_way (abfd, ".fini");
      asym->value -= asym->section->vma;
      break;
    case scRConst:
      asym->section = bfd_make_section_old_way (abfd, ".rconst");
      asym->value -= asym->section->vma;
      break;
    default:
      break;
    }

  /* Look for special constructors symbols and make relocation entries
     in a special construction section.  These are produced by the
     -fgnu-linker argument to g++.  */
  if (ECOFF_IS_STAB (ecoff_sym))
    {
      switch (ECOFF_UNMARK_STAB (ecoff_sym->index))
	{
	default:
	  break;

	case N_SETA:
	case N_SETT:
	case N_SETD:
	case N_SETB:
	  /* Mark the symbol as a constructor.  */
	  asym->flags |= BSF_CONSTRUCTOR;
	  break;
	}
    }
  return TRUE;
}

/* Read an ECOFF symbol table.  */

bfd_boolean
_bfd_ecoff_slurp_symbol_table (bfd *abfd)
{
  const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
  const bfd_size_type external_ext_size
    = backend->debug_swap.external_ext_size;
  const bfd_size_type external_sym_size
    = backend->debug_swap.external_sym_size;
  void (* const swap_ext_in) (bfd *, void *, EXTR *)
    = backend->debug_swap.swap_ext_in;
  void (* const swap_sym_in) (bfd *, void *, SYMR *)
    = backend->debug_swap.swap_sym_in;
  ecoff_symbol_type *internal;
  ecoff_symbol_type *internal_ptr;
  char *eraw_src;
  char *eraw_end;
  FDR *fdr_ptr;
  FDR *fdr_end;

  /* If we've already read in the symbol table, do nothing.  */
  if (ecoff_data (abfd)->canonical_symbols != NULL)
    return TRUE;

  /* Get the symbolic information.  */
  if (! _bfd_ecoff_slurp_symbolic_info (abfd, NULL,
					&ecoff_data (abfd)->debug_info))
    return FALSE;
  if (bfd_get_symcount (abfd) == 0)
    return TRUE;

  internal = (ecoff_symbol_type *) bfd_alloc2 (abfd, bfd_get_symcount (abfd),
					       sizeof (ecoff_symbol_type));
  if (internal == NULL)
    return FALSE;

  internal_ptr = internal;
  eraw_src = (char *) ecoff_data (abfd)->debug_info.external_ext;
  eraw_end = (eraw_src
	      + (ecoff_data (abfd)->debug_info.symbolic_header.iextMax
		 * external_ext_size));
  for (; eraw_src < eraw_end; eraw_src += external_ext_size, internal_ptr++)
    {
      EXTR internal_esym;

      (*swap_ext_in) (abfd, (void *) eraw_src, &internal_esym);

      /* PR 17512: file: 3372-1000-0.004.  */
      if (internal_esym.asym.iss >= ecoff_data (abfd)->debug_info.symbolic_header.issExtMax
	  || internal_esym.asym.iss < 0)
	return FALSE;

      internal_ptr->symbol.name = (ecoff_data (abfd)->debug_info.ssext
				   + internal_esym.asym.iss);

      if (!ecoff_set_symbol_info (abfd, &internal_esym.asym,
				  &internal_ptr->symbol, 1,
				  internal_esym.weakext))
	return FALSE;

      /* The alpha uses a negative ifd field for section symbols.  */
      if (internal_esym.ifd >= 0)
	{
	  /* PR 17512: file: 3372-1983-0.004.  */
	  if (internal_esym.ifd >= ecoff_data (abfd)->debug_info.symbolic_header.ifdMax)
	    internal_ptr->fdr = NULL;
	  else
	    internal_ptr->fdr = (ecoff_data (abfd)->debug_info.fdr
				 + internal_esym.ifd);
	}
      else
	internal_ptr->fdr = NULL;
      internal_ptr->local = FALSE;
      internal_ptr->native = (void *) eraw_src;
    }

  /* The local symbols must be accessed via the fdr's, because the
     string and aux indices are relative to the fdr information.  */
  fdr_ptr = ecoff_data (abfd)->debug_info.fdr;
  fdr_end = fdr_ptr + ecoff_data (abfd)->debug_info.symbolic_header.ifdMax;
  for (; fdr_ptr < fdr_end; fdr_ptr++)
    {
      char *lraw_src;
      char *lraw_end;

      lraw_src = ((char *) ecoff_data (abfd)->debug_info.external_sym
		  + fdr_ptr->isymBase * external_sym_size);
      lraw_end = lraw_src + fdr_ptr->csym * external_sym_size;
      for (;
	   lraw_src < lraw_end;
	   lraw_src += external_sym_size, internal_ptr++)
	{
	  SYMR internal_sym;

	  (*swap_sym_in) (abfd, (void *) lraw_src, &internal_sym);
	  internal_ptr->symbol.name = (ecoff_data (abfd)->debug_info.ss
				       + fdr_ptr->issBase
				       + internal_sym.iss);
	  if (!ecoff_set_symbol_info (abfd, &internal_sym,
				      &internal_ptr->symbol, 0, 0))
	    return FALSE;
	  internal_ptr->fdr = fdr_ptr;
	  internal_ptr->local = TRUE;
	  internal_ptr->native = (void *) lraw_src;
	}
    }

  /* PR 17512: file: 3372-3080-0.004.
     A discrepancy between ecoff_data (abfd)->debug_info.symbolic_header.isymMax
     and ecoff_data (abfd)->debug_info.symbolic_header.ifdMax can mean that
     we have fewer symbols than we were expecting.  Allow for this by updating
     the symbol count and warning the user.  */
  if (internal_ptr - internal < (ptrdiff_t) bfd_get_symcount (abfd))
    {
      bfd_get_symcount (abfd) = internal_ptr - internal;
      _bfd_error_handler
	/* xgettext:c-format */
	(_("%B: warning: isymMax (%ld) is greater than ifdMax (%d)\n"),
	 abfd, ecoff_data (abfd)->debug_info.symbolic_header.isymMax,
	 ecoff_data (abfd)->debug_info.symbolic_header.ifdMax);
    }

  ecoff_data (abfd)->canonical_symbols = internal;

  return TRUE;
}

/* Return the amount of space needed for the canonical symbols.  */

long
_bfd_ecoff_get_symtab_upper_bound (bfd *abfd)
{
  if (! _bfd_ecoff_slurp_symbolic_info (abfd, NULL,
					&ecoff_data (abfd)->debug_info))
    return -1;

  if (bfd_get_symcount (abfd) == 0)
    return 0;

  return (bfd_get_symcount (abfd) + 1) * (sizeof (ecoff_symbol_type *));
}

/* Get the canonical symbols.  */

long
_bfd_ecoff_canonicalize_symtab (bfd *abfd, asymbol **alocation)
{
  unsigned int counter = 0;
  ecoff_symbol_type *symbase;
  ecoff_symbol_type **location = (ecoff_symbol_type **) alocation;

  if (! _bfd_ecoff_slurp_symbol_table (abfd))
    return -1;
  if (bfd_get_symcount (abfd) == 0)
    return 0;

  symbase = ecoff_data (abfd)->canonical_symbols;
  while (counter < bfd_get_symcount (abfd))
    {
      *(location++) = symbase++;
      counter++;
    }
  *location++ = NULL;
  return bfd_get_symcount (abfd);
}

/* Turn ECOFF type information into a printable string.
   ecoff_emit_aggregate and ecoff_type_to_string are from
   gcc/mips-tdump.c, with swapping added and used_ptr removed.  */

/* Write aggregate information to a string.  */

static void
ecoff_emit_aggregate (bfd *abfd,
		      FDR *fdr,
		      char *string,
		      RNDXR *rndx,
		      long isym,
		      const char *which)
{
  const struct ecoff_debug_swap * const debug_swap =
    &ecoff_backend (abfd)->debug_swap;
  struct ecoff_debug_info * const debug_info = &ecoff_data (abfd)->debug_info;
  unsigned int ifd = rndx->rfd;
  unsigned int indx = rndx->index;
  const char *name;

  if (ifd == 0xfff)
    ifd = isym;

  /* An ifd of -1 is an opaque type.  An escaped index of 0 is a
     struct return type of a procedure compiled without -g.  */
  if (ifd == 0xffffffff
      || (rndx->rfd == 0xfff && indx == 0))
    name = "<undefined>";
  else if (indx == indexNil)
    name = "<no name>";
  else
    {
      SYMR sym;

      if (debug_info->external_rfd == NULL)
	fdr = debug_info->fdr + ifd;
      else
	{
	  RFDT rfd;

	  (*debug_swap->swap_rfd_in) (abfd,
				      ((char *) debug_info->external_rfd
				       + ((fdr->rfdBase + ifd)
					  * debug_swap->external_rfd_size)),
				      &rfd);
	  fdr = debug_info->fdr + rfd;
	}

      indx += fdr->isymBase;

      (*debug_swap->swap_sym_in) (abfd,
				  ((char *) debug_info->external_sym
				   + indx * debug_swap->external_sym_size),
				  &sym);

      name = debug_info->ss + fdr->issBase + sym.iss;
    }

  sprintf (string,
	   "%s %s { ifd = %u, index = %lu }",
	   which, name, ifd,
	   ((unsigned long) indx
	    + debug_info->symbolic_header.iextMax));
}

/* Convert the type information to string format.  */

static char *
ecoff_type_to_string (bfd *abfd, FDR *fdr, unsigned int indx)
{
  union aux_ext *aux_ptr;
  int bigendian;
  AUXU u;
  struct qual
  {
    unsigned int  type;
    int  low_bound;
    int  high_bound;
    int  stride;
  } qualifiers[7];
  unsigned int basic_type;
  int i;
  char buffer1[1024];
  static char buffer2[1024];
  char *p1 = buffer1;
  char *p2 = buffer2;
  RNDXR rndx;

  aux_ptr = ecoff_data (abfd)->debug_info.external_aux + fdr->iauxBase;
  bigendian = fdr->fBigendian;

  for (i = 0; i < 7; i++)
    {
      qualifiers[i].low_bound = 0;
      qualifiers[i].high_bound = 0;
      qualifiers[i].stride = 0;
    }

  if (AUX_GET_ISYM (bigendian, &aux_ptr[indx]) == (bfd_vma) -1)
    return "-1 (no type)";
  _bfd_ecoff_swap_tir_in (bigendian, &aux_ptr[indx++].a_ti, &u.ti);

  basic_type = u.ti.bt;
  qualifiers[0].type = u.ti.tq0;
  qualifiers[1].type = u.ti.tq1;
  qualifiers[2].type = u.ti.tq2;
  qualifiers[3].type = u.ti.tq3;
  qualifiers[4].type = u.ti.tq4;
  qualifiers[5].type = u.ti.tq5;
  qualifiers[6].type = tqNil;

  /* Go get the basic type.  */
  switch (basic_type)
    {
    case btNil:			/* Undefined.  */
      strcpy (p1, "nil");
      break;

    case btAdr:			/* Address - integer same size as pointer.  */
      strcpy (p1, "address");
      break;

    case btChar:		/* Character.  */
      strcpy (p1, "char");
      break;

    case btUChar:		/* Unsigned character.  */
      strcpy (p1, "unsigned char");
      break;

    case btShort:		/* Short.  */
      strcpy (p1, "short");
      break;

    case btUShort:		/* Unsigned short.  */
      strcpy (p1, "unsigned short");
      break;

    case btInt:			/* Int.  */
      strcpy (p1, "int");
      break;

    case btUInt:		/* Unsigned int.  */
      strcpy (p1, "unsigned int");
      break;

    case btLong:		/* Long.  */
      strcpy (p1, "long");
      break;

    case btULong:		/* Unsigned long.  */
      strcpy (p1, "unsigned long");
      break;

    case btFloat:		/* Float (real).  */
      strcpy (p1, "float");
      break;

    case btDouble:		/* Double (real).  */
      strcpy (p1, "double");
      break;

      /* Structures add 1-2 aux words:
	 1st word is [ST_RFDESCAPE, offset] pointer to struct def;
	 2nd word is file index if 1st word rfd is ST_RFDESCAPE.  */

    case btStruct:		/* Structure (Record).  */
      _bfd_ecoff_swap_rndx_in (bigendian, &aux_ptr[indx].a_rndx, &rndx);
      ecoff_emit_aggregate (abfd, fdr, p1, &rndx,
			    (long) AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]),
			    "struct");
      indx++;			/* Skip aux words.  */
      break;

      /* Unions add 1-2 aux words:
	 1st word is [ST_RFDESCAPE, offset] pointer to union def;
	 2nd word is file index if 1st word rfd is ST_RFDESCAPE.  */

    case btUnion:		/* Union.  */
      _bfd_ecoff_swap_rndx_in (bigendian, &aux_ptr[indx].a_rndx, &rndx);
      ecoff_emit_aggregate (abfd, fdr, p1, &rndx,
			    (long) AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]),
			    "union");
      indx++;			/* Skip aux words.  */
      break;

      /* Enumerations add 1-2 aux words:
	 1st word is [ST_RFDESCAPE, offset] pointer to enum def;
	 2nd word is file index if 1st word rfd is ST_RFDESCAPE.  */

    case btEnum:		/* Enumeration.  */
      _bfd_ecoff_swap_rndx_in (bigendian, &aux_ptr[indx].a_rndx, &rndx);
      ecoff_emit_aggregate (abfd, fdr, p1, &rndx,
			    (long) AUX_GET_ISYM (bigendian, &aux_ptr[indx+1]),
			    "enum");
      indx++;			/* Skip aux words.  */
      break;

    case btTypedef:		/* Defined via a typedef, isymRef points.  */
      strcpy (p1, "typedef");
      break;

    case btRange:		/* Subrange of int.  */
      strcpy (p1, "subrange");
      break;

    case btSet:			/* Pascal sets.  */
      strcpy (p1, "set");
      break;

    case btComplex:		/* Fortran complex.  */
      strcpy (p1, "complex");
      break;

    case btDComplex:		/* Fortran double complex.  */
      strcpy (p1, "double complex");
      break;

    case btIndirect:		/* Forward or unnamed typedef.  */
      strcpy (p1, "forward/unamed typedef");
      break;

    case btFixedDec:		/* Fixed Decimal.  */
      strcpy (p1, "fixed decimal");
      break;

    case btFloatDec:		/* Float Decimal.  */
      strcpy (p1, "float decimal");
      break;

    case btString:		/* Varying Length Character String.  */
      strcpy (p1, "string");
      break;

    case btBit:			/* Aligned Bit String.  */
      strcpy (p1, "bit");
      break;

    case btPicture:		/* Picture.  */
      strcpy (p1, "picture");
      break;

    case btVoid:		/* Void.  */
      strcpy (p1, "void");
      break;

    default:
      sprintf (p1, _("Unknown basic type %d"), (int) basic_type);
      break;
    }

  p1 += strlen (buffer1);

  /* If this is a bitfield, get the bitsize.  */
  if (u.ti.fBitfield)
    {
      int bitsize;

      bitsize = AUX_GET_WIDTH (bigendian, &aux_ptr[indx++]);
      sprintf (p1, " : %d", bitsize);
      p1 += strlen (buffer1);
    }

  /* Deal with any qualifiers.  */
  if (qualifiers[0].type != tqNil)
    {
      /* Snarf up any array bounds in the correct order.  Arrays
         store 5 successive words in the aux. table:
        	word 0	RNDXR to type of the bounds (ie, int)
        	word 1	Current file descriptor index
        	word 2	low bound
        	word 3	high bound (or -1 if [])
        	word 4	stride size in bits.  */
      for (i = 0; i < 7; i++)
	{
	  if (qualifiers[i].type == tqArray)
	    {
	      qualifiers[i].low_bound =
		AUX_GET_DNLOW (bigendian, &aux_ptr[indx+2]);
	      qualifiers[i].high_bound =
		AUX_GET_DNHIGH (bigendian, &aux_ptr[indx+3]);
	      qualifiers[i].stride =
		AUX_GET_WIDTH (bigendian, &aux_ptr[indx+4]);
	      indx += 5;
	    }
	}

      /* Now print out the qualifiers.  */
      for (i = 0; i < 6; i++)
	{
	  switch (qualifiers[i].type)
	    {
	    case tqNil:
	    case tqMax:
	      break;

	    case tqPtr:
	      strcpy (p2, "ptr to ");
	      p2 += sizeof ("ptr to ")-1;
	      break;

	    case tqVol:
	      strcpy (p2, "volatile ");
	      p2 += sizeof ("volatile ")-1;
	      break;

	    case tqFar:
	      strcpy (p2, "far ");
	      p2 += sizeof ("far ")-1;
	      break;

	    case tqProc:
	      strcpy (p2, "func. ret. ");
	      p2 += sizeof ("func. ret. ");
	      break;

	    case tqArray:
	      {
		int first_array = i;
		int j;

		/* Print array bounds reversed (ie, in the order the C
		   programmer writes them).  C is such a fun language....  */
		while (i < 5 && qualifiers[i+1].type == tqArray)
		  i++;

		for (j = i; j >= first_array; j--)
		  {
		    strcpy (p2, "array [");
		    p2 += sizeof ("array [")-1;
		    if (qualifiers[j].low_bound != 0)
		      sprintf (p2,
			       "%ld:%ld {%ld bits}",
			       (long) qualifiers[j].low_bound,
			       (long) qualifiers[j].high_bound,
			       (long) qualifiers[j].stride);

		    else if (qualifiers[j].high_bound != -1)
		      sprintf (p2,
			       "%ld {%ld bits}",
			       (long) (qualifiers[j].high_bound + 1),
			       (long) (qualifiers[j].stride));

		    else
		      sprintf (p2, " {%ld bits}", (long) (qualifiers[j].stride));

		    p2 += strlen (p2);
		    strcpy (p2, "] of ");
		    p2 += sizeof ("] of ")-1;
		  }
	      }
	      break;
	    }
	}
    }

  strcpy (p2, buffer1);
  return buffer2;
}

/* Return information about ECOFF symbol SYMBOL in RET.  */

void
_bfd_ecoff_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
			    asymbol *symbol,
			    symbol_info *ret)
{
  bfd_symbol_info (symbol, ret);
}

/* Return whether this is a local label.  */

bfd_boolean
_bfd_ecoff_bfd_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED,
				    const char *name)
{
  return name[0] == '$';
}

/* Print information about an ECOFF symbol.  */

void
_bfd_ecoff_print_symbol (bfd *abfd,
			 void * filep,
			 asymbol *symbol,
			 bfd_print_symbol_type how)
{
  const struct ecoff_debug_swap * const debug_swap
    = &ecoff_backend (abfd)->debug_swap;
  FILE *file = (FILE *)filep;

  switch (how)
    {
    case bfd_print_symbol_name:
      fprintf (file, "%s", symbol->name);
      break;
    case bfd_print_symbol_more:
      if (ecoffsymbol (symbol)->local)
	{
	  SYMR ecoff_sym;

	  (*debug_swap->swap_sym_in) (abfd, ecoffsymbol (symbol)->native,
				      &ecoff_sym);
	  fprintf (file, "ecoff local ");
	  fprintf_vma (file, (bfd_vma) ecoff_sym.value);
	  fprintf (file, " %x %x", (unsigned) ecoff_sym.st,
		   (unsigned) ecoff_sym.sc);
	}
      else
	{
	  EXTR ecoff_ext;

	  (*debug_swap->swap_ext_in) (abfd, ecoffsymbol (symbol)->native,
				      &ecoff_ext);
	  fprintf (file, "ecoff extern ");
	  fprintf_vma (file, (bfd_vma) ecoff_ext.asym.value);
	  fprintf (file, " %x %x", (unsigned) ecoff_ext.asym.st,
		   (unsigned) ecoff_ext.asym.sc);
	}
      break;
    case bfd_print_symbol_all:
      /* Print out the symbols in a reasonable way.  */
      {
	char type;
	int pos;
	EXTR ecoff_ext;
	char jmptbl;
	char cobol_main;
	char weakext;

	if (ecoffsymbol (symbol)->local)
	  {
	    (*debug_swap->swap_sym_in) (abfd, ecoffsymbol (symbol)->native,
					&ecoff_ext.asym);
	    type = 'l';
	    pos = ((((char *) ecoffsymbol (symbol)->native
		     - (char *) ecoff_data (abfd)->debug_info.external_sym)
		    / debug_swap->external_sym_size)
		   + ecoff_data (abfd)->debug_info.symbolic_header.iextMax);
	    jmptbl = ' ';
	    cobol_main = ' ';
	    weakext = ' ';
	  }
	else
	  {
	    (*debug_swap->swap_ext_in) (abfd, ecoffsymbol (symbol)->native,
					&ecoff_ext);
	    type = 'e';
	    pos = (((char *) ecoffsymbol (symbol)->native
		    - (char *) ecoff_data (abfd)->debug_info.external_ext)
		   / debug_swap->external_ext_size);
	    jmptbl = ecoff_ext.jmptbl ? 'j' : ' ';
	    cobol_main = ecoff_ext.cobol_main ? 'c' : ' ';
	    weakext = ecoff_ext.weakext ? 'w' : ' ';
	  }

	fprintf (file, "[%3d] %c ",
		 pos, type);
	fprintf_vma (file, (bfd_vma) ecoff_ext.asym.value);
	fprintf (file, " st %x sc %x indx %x %c%c%c %s",
		 (unsigned) ecoff_ext.asym.st,
		 (unsigned) ecoff_ext.asym.sc,
		 (unsigned) ecoff_ext.asym.index,
		 jmptbl, cobol_main, weakext,
		 symbol->name);

	if (ecoffsymbol (symbol)->fdr != NULL
	    && ecoff_ext.asym.index != indexNil)
	  {
	    FDR *fdr;
	    unsigned int indx;
	    int bigendian;
	    bfd_size_type sym_base;
	    union aux_ext *aux_base;

	    fdr = ecoffsymbol (symbol)->fdr;
	    indx = ecoff_ext.asym.index;

	    /* sym_base is used to map the fdr relative indices which
	       appear in the file to the position number which we are
	       using.  */
	    sym_base = fdr->isymBase;
	    if (ecoffsymbol (symbol)->local)
	      sym_base +=
		ecoff_data (abfd)->debug_info.symbolic_header.iextMax;

	    /* aux_base is the start of the aux entries for this file;
	       asym.index is an offset from this.  */
	    aux_base = (ecoff_data (abfd)->debug_info.external_aux
			+ fdr->iauxBase);

	    /* The aux entries are stored in host byte order; the
	       order is indicated by a bit in the fdr.  */
	    bigendian = fdr->fBigendian;

	    /* This switch is basically from gcc/mips-tdump.c.  */
	    switch (ecoff_ext.asym.st)
	      {
	      case stNil:
	      case stLabel:
		break;

	      case stFile:
	      case stBlock:
		fprintf (file, _("\n      End+1 symbol: %ld"),
			 (long) (indx + sym_base));
		break;

	      case stEnd:
		if (ecoff_ext.asym.sc == scText
		    || ecoff_ext.asym.sc == scInfo)
		  fprintf (file, _("\n      First symbol: %ld"),
			   (long) (indx + sym_base));
		else
		  fprintf (file, _("\n      First symbol: %ld"),
			   ((long)
			    (AUX_GET_ISYM (bigendian,
					   &aux_base[ecoff_ext.asym.index])
			     + sym_base)));
		break;

	      case stProc:
	      case stStaticProc:
		if (ECOFF_IS_STAB (&ecoff_ext.asym))
		  ;
		else if (ecoffsymbol (symbol)->local)
		  /* xgettext:c-format */
		  fprintf (file, _("\n      End+1 symbol: %-7ld   Type:  %s"),
			   ((long)
			    (AUX_GET_ISYM (bigendian,
					   &aux_base[ecoff_ext.asym.index])
			     + sym_base)),
			   ecoff_type_to_string (abfd, fdr, indx + 1));
		else
		  fprintf (file, _("\n      Local symbol: %ld"),
			   ((long) indx
			    + (long) sym_base
			    + (ecoff_data (abfd)
			       ->debug_info.symbolic_header.iextMax)));
		break;

	      case stStruct:
		fprintf (file, _("\n      struct; End+1 symbol: %ld"),
			 (long) (indx + sym_base));
		break;

	      case stUnion:
		fprintf (file, _("\n      union; End+1 symbol: %ld"),
			 (long) (indx + sym_base));
		break;

	      case stEnum:
		fprintf (file, _("\n      enum; End+1 symbol: %ld"),
			 (long) (indx + sym_base));
		break;

	      default:
		if (! ECOFF_IS_STAB (&ecoff_ext.asym))
		  fprintf (file, _("\n      Type: %s"),
			   ecoff_type_to_string (abfd, fdr, indx));
		break;
	      }
	  }
      }
      break;
    }
}

/* Read in the relocs for a section.  */

static bfd_boolean
ecoff_slurp_reloc_table (bfd *abfd,
			 asection *section,
			 asymbol **symbols)
{
  const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
  arelent *internal_relocs;
  bfd_size_type external_reloc_size;
  bfd_size_type amt;
  char *external_relocs;
  arelent *rptr;
  unsigned int i;

  if (section->relocation != NULL
      || section->reloc_count == 0
      || (section->flags & SEC_CONSTRUCTOR) != 0)
    return TRUE;

  if (! _bfd_ecoff_slurp_symbol_table (abfd))
    return FALSE;

  amt = section->reloc_count;
  amt *= sizeof (arelent);
  internal_relocs = (arelent *) bfd_alloc (abfd, amt);

  external_reloc_size = backend->external_reloc_size;
  amt = external_reloc_size * section->reloc_count;
  external_relocs = (char *) bfd_alloc (abfd, amt);
  if (internal_relocs == NULL || external_relocs == NULL)
    return FALSE;
  if (bfd_seek (abfd, section->rel_filepos, SEEK_SET) != 0)
    return FALSE;
  if (bfd_bread (external_relocs, amt, abfd) != amt)
    return FALSE;

  for (i = 0, rptr = internal_relocs; i < section->reloc_count; i++, rptr++)
    {
      struct internal_reloc intern;

      (*backend->swap_reloc_in) (abfd,
				 external_relocs + i * external_reloc_size,
				 &intern);

      if (intern.r_extern)
	{
	  /* r_symndx is an index into the external symbols.  */
	  BFD_ASSERT (intern.r_symndx >= 0
		      && (intern.r_symndx
			  < (ecoff_data (abfd)
			     ->debug_info.symbolic_header.iextMax)));
	  rptr->sym_ptr_ptr = symbols + intern.r_symndx;
	  rptr->addend = 0;
	}
      else if (intern.r_symndx == RELOC_SECTION_NONE
	       || intern.r_symndx == RELOC_SECTION_ABS)
	{
	  rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
	  rptr->addend = 0;
	}
      else
	{
	  const char *sec_name;
	  asection *sec;

	  /* r_symndx is a section key.  */
	  switch (intern.r_symndx)
	    {
	    case RELOC_SECTION_TEXT:  sec_name = _TEXT;  break;
	    case RELOC_SECTION_RDATA: sec_name = _RDATA; break;
	    case RELOC_SECTION_DATA:  sec_name = _DATA;  break;
	    case RELOC_SECTION_SDATA: sec_name = _SDATA; break;
	    case RELOC_SECTION_SBSS:  sec_name = _SBSS;  break;
	    case RELOC_SECTION_BSS:   sec_name = _BSS;   break;
	    case RELOC_SECTION_INIT:  sec_name = _INIT;  break;
	    case RELOC_SECTION_LIT8:  sec_name = _LIT8;  break;
	    case RELOC_SECTION_LIT4:  sec_name = _LIT4;  break;
	    case RELOC_SECTION_XDATA: sec_name = _XDATA; break;
	    case RELOC_SECTION_PDATA: sec_name = _PDATA; break;
	    case RELOC_SECTION_FINI:  sec_name = _FINI;  break;
	    case RELOC_SECTION_LITA:  sec_name = _LITA;  break;
	    case RELOC_SECTION_RCONST: sec_name = _RCONST; break;
	    default: abort ();
	    }

	  sec = bfd_get_section_by_name (abfd, sec_name);
	  if (sec == NULL)
	    abort ();
	  rptr->sym_ptr_ptr = sec->symbol_ptr_ptr;

	  rptr->addend = - bfd_get_section_vma (abfd, sec);
	}

      rptr->address = intern.r_vaddr - bfd_get_section_vma (abfd, section);

      /* Let the backend select the howto field and do any other
	 required processing.  */
      (*backend->adjust_reloc_in) (abfd, &intern, rptr);
    }

  bfd_release (abfd, external_relocs);

  section->relocation = internal_relocs;

  return TRUE;
}

/* Get a canonical list of relocs.  */

long
_bfd_ecoff_canonicalize_reloc (bfd *abfd,
			       asection *section,
			       arelent **relptr,
			       asymbol **symbols)
{
  unsigned int count;

  if (section->flags & SEC_CONSTRUCTOR)
    {
      arelent_chain *chain;

      /* This section has relocs made up by us, not the file, so take
	 them out of their chain and place them into the data area
	 provided.  */
      for (count = 0, chain = section->constructor_chain;
	   count < section->reloc_count;
	   count++, chain = chain->next)
	*relptr++ = &chain->relent;
    }
  else
    {
      arelent *tblptr;

      if (! ecoff_slurp_reloc_table (abfd, section, symbols))
	return -1;

      tblptr = section->relocation;

      for (count = 0; count < section->reloc_count; count++)
	*relptr++ = tblptr++;
    }

  *relptr = NULL;

  return section->reloc_count;
}

/* Provided a BFD, a section and an offset into the section, calculate
   and return the name of the source file and the line nearest to the
   wanted location.  */

bfd_boolean
_bfd_ecoff_find_nearest_line (bfd *abfd,
			      asymbol **symbols ATTRIBUTE_UNUSED,
			      asection *section,
			      bfd_vma offset,
			      const char **filename_ptr,
			      const char **functionname_ptr,
			      unsigned int *retline_ptr,
			      unsigned int *discriminator_ptr)
{
  const struct ecoff_debug_swap * const debug_swap
    = &ecoff_backend (abfd)->debug_swap;
  struct ecoff_debug_info * const debug_info = &ecoff_data (abfd)->debug_info;
  struct ecoff_find_line *line_info;

  /* Make sure we have the FDR's.  */
  if (! _bfd_ecoff_slurp_symbolic_info (abfd, NULL, debug_info)
      || bfd_get_symcount (abfd) == 0)
    return FALSE;

  if (ecoff_data (abfd)->find_line_info == NULL)
    {
      bfd_size_type amt = sizeof (struct ecoff_find_line);

      ecoff_data (abfd)->find_line_info =
          (struct ecoff_find_line *) bfd_zalloc (abfd, amt);
      if (ecoff_data (abfd)->find_line_info == NULL)
	return FALSE;
    }

  if (discriminator_ptr)
    *discriminator_ptr = 0;
  line_info = ecoff_data (abfd)->find_line_info;
  return _bfd_ecoff_locate_line (abfd, section, offset, debug_info,
				 debug_swap, line_info, filename_ptr,
				 functionname_ptr, retline_ptr);
}

/* Copy private BFD data.  This is called by objcopy and strip.  We
   use it to copy the ECOFF debugging information from one BFD to the
   other.  It would be theoretically possible to represent the ECOFF
   debugging information in the symbol table.  However, it would be a
   lot of work, and there would be little gain (gas, gdb, and ld
   already access the ECOFF debugging information via the
   ecoff_debug_info structure, and that structure would have to be
   retained in order to support ECOFF debugging in MIPS ELF).

   The debugging information for the ECOFF external symbols comes from
   the symbol table, so this function only handles the other debugging
   information.  */

bfd_boolean
_bfd_ecoff_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
{
  struct ecoff_debug_info *iinfo = &ecoff_data (ibfd)->debug_info;
  struct ecoff_debug_info *oinfo = &ecoff_data (obfd)->debug_info;
  int i;
  asymbol **sym_ptr_ptr;
  size_t c;
  bfd_boolean local;

  /* We only want to copy information over if both BFD's use ECOFF
     format.  */
  if (bfd_get_flavour (ibfd) != bfd_target_ecoff_flavour
      || bfd_get_flavour (obfd) != bfd_target_ecoff_flavour)
    return TRUE;

  /* Copy the GP value and the register masks.  */
  ecoff_data (obfd)->gp = ecoff_data (ibfd)->gp;
  ecoff_data (obfd)->gprmask = ecoff_data (ibfd)->gprmask;
  ecoff_data (obfd)->fprmask = ecoff_data (ibfd)->fprmask;
  for (i = 0; i < 3; i++)
    ecoff_data (obfd)->cprmask[i] = ecoff_data (ibfd)->cprmask[i];

  /* Copy the version stamp.  */
  oinfo->symbolic_header.vstamp = iinfo->symbolic_header.vstamp;

  /* If there are no symbols, don't copy any debugging information.  */
  c = bfd_get_symcount (obfd);
  sym_ptr_ptr = bfd_get_outsymbols (obfd);
  if (c == 0 || sym_ptr_ptr == NULL)
    return TRUE;

  /* See if there are any local symbols.  */
  local = FALSE;
  for (; c > 0; c--, sym_ptr_ptr++)
    {
      if (ecoffsymbol (*sym_ptr_ptr)->local)
	{
	  local = TRUE;
	  break;
	}
    }

  if (local)
    {
      /* There are some local symbols.  We just bring over all the
	 debugging information.  FIXME: This is not quite the right
	 thing to do.  If the user has asked us to discard all
	 debugging information, then we are probably going to wind up
	 keeping it because there will probably be some local symbol
	 which objcopy did not discard.  We should actually break
	 apart the debugging information and only keep that which
	 applies to the symbols we want to keep.  */
      oinfo->symbolic_header.ilineMax = iinfo->symbolic_header.ilineMax;
      oinfo->symbolic_header.cbLine = iinfo->symbolic_header.cbLine;
      oinfo->line = iinfo->line;

      oinfo->symbolic_header.idnMax = iinfo->symbolic_header.idnMax;
      oinfo->external_dnr = iinfo->external_dnr;

      oinfo->symbolic_header.ipdMax = iinfo->symbolic_header.ipdMax;
      oinfo->external_pdr = iinfo->external_pdr;

      oinfo->symbolic_header.isymMax = iinfo->symbolic_header.isymMax;
      oinfo->external_sym = iinfo->external_sym;

      oinfo->symbolic_header.ioptMax = iinfo->symbolic_header.ioptMax;
      oinfo->external_opt = iinfo->external_opt;

      oinfo->symbolic_header.iauxMax = iinfo->symbolic_header.iauxMax;
      oinfo->external_aux = iinfo->external_aux;

      oinfo->symbolic_header.issMax = iinfo->symbolic_header.issMax;
      oinfo->ss = iinfo->ss;

      oinfo->symbolic_header.ifdMax = iinfo->symbolic_header.ifdMax;
      oinfo->external_fdr = iinfo->external_fdr;

      oinfo->symbolic_header.crfd = iinfo->symbolic_header.crfd;
      oinfo->external_rfd = iinfo->external_rfd;
    }
  else
    {
      /* We are discarding all the local symbol information.  Look
	 through the external symbols and remove all references to FDR
	 or aux information.  */
      c = bfd_get_symcount (obfd);
      sym_ptr_ptr = bfd_get_outsymbols (obfd);
      for (; c > 0; c--, sym_ptr_ptr++)
	{
	  EXTR esym;

	  (*(ecoff_backend (obfd)->debug_swap.swap_ext_in))
	    (obfd, ecoffsymbol (*sym_ptr_ptr)->native, &esym);
	  esym.ifd = ifdNil;
	  esym.asym.index = indexNil;
	  (*(ecoff_backend (obfd)->debug_swap.swap_ext_out))
	    (obfd, &esym, ecoffsymbol (*sym_ptr_ptr)->native);
	}
    }

  return TRUE;
}

/* Set the architecture.  The supported architecture is stored in the
   backend pointer.  We always set the architecture anyhow, since many
   callers ignore the return value.  */

bfd_boolean
_bfd_ecoff_set_arch_mach (bfd *abfd,
			  enum bfd_architecture arch,
			  unsigned long machine)
{
  bfd_default_set_arch_mach (abfd, arch, machine);
  return arch == ecoff_backend (abfd)->arch;
}

/* Get the size of the section headers.  */

int
_bfd_ecoff_sizeof_headers (bfd *abfd,
			   struct bfd_link_info *info ATTRIBUTE_UNUSED)
{
  asection *current;
  int c;
  int ret;

  c = 0;
  for (current = abfd->sections;
       current != NULL;
       current = current->next)
    ++c;

  ret = (bfd_coff_filhsz (abfd)
	 + bfd_coff_aoutsz (abfd)
	 + c * bfd_coff_scnhsz (abfd));
  return (int) BFD_ALIGN (ret, 16);
}

/* Get the contents of a section.  */

bfd_boolean
_bfd_ecoff_get_section_contents (bfd *abfd,
				 asection *section,
				 void * location,
				 file_ptr offset,
				 bfd_size_type count)
{
  return _bfd_generic_get_section_contents (abfd, section, location,
					    offset, count);
}

/* Sort sections by VMA, but put SEC_ALLOC sections first.  This is
   called via qsort.  */

static int
ecoff_sort_hdrs (const void * arg1, const void * arg2)
{
  const asection *hdr1 = *(const asection **) arg1;
  const asection *hdr2 = *(const asection **) arg2;

  if ((hdr1->flags & SEC_ALLOC) != 0)
    {
      if ((hdr2->flags & SEC_ALLOC) == 0)
	return -1;
    }
  else
    {
      if ((hdr2->flags & SEC_ALLOC) != 0)
	return 1;
    }
  if (hdr1->vma < hdr2->vma)
    return -1;
  else if (hdr1->vma > hdr2->vma)
    return 1;
  else
    return 0;
}

/* Calculate the file position for each section, and set
   reloc_filepos.  */

static bfd_boolean
ecoff_compute_section_file_positions (bfd *abfd)
{
  file_ptr sofar, file_sofar;
  asection **sorted_hdrs;
  asection *current;
  unsigned int i;
  file_ptr old_sofar;
  bfd_boolean rdata_in_text;
  bfd_boolean first_data, first_nonalloc;
  const bfd_vma round = ecoff_backend (abfd)->round;
  bfd_size_type amt;

  sofar = _bfd_ecoff_sizeof_headers (abfd, NULL);
  file_sofar = sofar;

  /* Sort the sections by VMA.  */
  amt = abfd->section_count;
  amt *= sizeof (asection *);
  sorted_hdrs = (asection **) bfd_malloc (amt);
  if (sorted_hdrs == NULL)
    return FALSE;
  for (current = abfd->sections, i = 0;
       current != NULL;
       current = current->next, i++)
    sorted_hdrs[i] = current;
  BFD_ASSERT (i == abfd->section_count);

  qsort (sorted_hdrs, abfd->section_count, sizeof (asection *),
	 ecoff_sort_hdrs);

  /* Some versions of the OSF linker put the .rdata section in the
     text segment, and some do not.  */
  rdata_in_text = ecoff_backend (abfd)->rdata_in_text;
  if (rdata_in_text)
    {
      for (i = 0; i < abfd->section_count; i++)
	{
	  current = sorted_hdrs[i];
	  if (streq (current->name, _RDATA))
	    break;
	  if ((current->flags & SEC_CODE) == 0
	      && ! streq (current->name, _PDATA)
	      && ! streq (current->name, _RCONST))
	    {
	      rdata_in_text = FALSE;
	      break;
	    }
	}
    }
  ecoff_data (abfd)->rdata_in_text = rdata_in_text;

  first_data = TRUE;
  first_nonalloc = TRUE;
  for (i = 0; i < abfd->section_count; i++)
    {
      unsigned int alignment_power;

      current = sorted_hdrs[i];

      /* For the Alpha ECOFF .pdata section the lnnoptr field is
	 supposed to indicate the number of .pdata entries that are
	 really in the section.  Each entry is 8 bytes.  We store this
	 away in line_filepos before increasing the section size.  */
      if (streq (current->name, _PDATA))
	current->line_filepos = current->size / 8;

      alignment_power = current->alignment_power;

      /* On Ultrix, the data sections in an executable file must be
	 aligned to a page boundary within the file.  This does not
	 affect the section size, though.  FIXME: Does this work for
	 other platforms?  It requires some modification for the
	 Alpha, because .rdata on the Alpha goes with the text, not
	 the data.  */
      if ((abfd->flags & EXEC_P) != 0
	  && (abfd->flags & D_PAGED) != 0
	  && ! first_data
	  && (current->flags & SEC_CODE) == 0
	  && (! rdata_in_text
	      || ! streq (current->name, _RDATA))
	  && ! streq (current->name, _PDATA)
	  && ! streq (current->name, _RCONST))
	{
	  sofar = (sofar + round - 1) &~ (round - 1);
	  file_sofar = (file_sofar + round - 1) &~ (round - 1);
	  first_data = FALSE;
	}
      else if (streq (current->name, _LIB))
	{
	  /* On Irix 4, the location of contents of the .lib section
	     from a shared library section is also rounded up to a
	     page boundary.  */

	  sofar = (sofar + round - 1) &~ (round - 1);
	  file_sofar = (file_sofar + round - 1) &~ (round - 1);
	}
      else if (first_nonalloc
	       && (current->flags & SEC_ALLOC) == 0
	       && (abfd->flags & D_PAGED) != 0)
	{
	  /* Skip up to the next page for an unallocated section, such
             as the .comment section on the Alpha.  This leaves room
             for the .bss section.  */
	  first_nonalloc = FALSE;
	  sofar = (sofar + round - 1) &~ (round - 1);
	  file_sofar = (file_sofar + round - 1) &~ (round - 1);
	}

      /* Align the sections in the file to the same boundary on
	 which they are aligned in virtual memory.  */
      sofar = BFD_ALIGN (sofar, 1 << alignment_power);
      if ((current->flags & SEC_HAS_CONTENTS) != 0)
	file_sofar = BFD_ALIGN (file_sofar, 1 << alignment_power);

      if ((abfd->flags & D_PAGED) != 0
	  && (current->flags & SEC_ALLOC) != 0)
	{
	  sofar += (current->vma - sofar) % round;
	  if ((current->flags & SEC_HAS_CONTENTS) != 0)
	    file_sofar += (current->vma - file_sofar) % round;
	}

      if ((current->flags & (SEC_HAS_CONTENTS | SEC_LOAD)) != 0)
	current->filepos = file_sofar;

      sofar += current->size;
      if ((current->flags & SEC_HAS_CONTENTS) != 0)
	file_sofar += current->size;

      /* Make sure that this section is of the right size too.  */
      old_sofar = sofar;
      sofar = BFD_ALIGN (sofar, 1 << alignment_power);
      if ((current->flags & SEC_HAS_CONTENTS) != 0)
	file_sofar = BFD_ALIGN (file_sofar, 1 << alignment_power);
      current->size += sofar - old_sofar;
    }

  free (sorted_hdrs);
  sorted_hdrs = NULL;

  ecoff_data (abfd)->reloc_filepos = file_sofar;

  return TRUE;
}

/* Determine the location of the relocs for all the sections in the
   output file, as well as the location of the symbolic debugging
   information.  */

static bfd_size_type
ecoff_compute_reloc_file_positions (bfd *abfd)
{
  const bfd_size_type external_reloc_size =
    ecoff_backend (abfd)->external_reloc_size;
  file_ptr reloc_base;
  bfd_size_type reloc_size;
  asection *current;
  file_ptr sym_base;

  if (! abfd->output_has_begun)
    {
      if (! ecoff_compute_section_file_positions (abfd))
	abort ();
      abfd->output_has_begun = TRUE;
    }

  reloc_base = ecoff_data (abfd)->reloc_filepos;

  reloc_size = 0;
  for (current = abfd->sections;
       current != NULL;
       current = current->next)
    {
      if (current->reloc_count == 0)
	current->rel_filepos = 0;
      else
	{
	  bfd_size_type relsize;

	  current->rel_filepos = reloc_base;
	  relsize = current->reloc_count * external_reloc_size;
	  reloc_size += relsize;
	  reloc_base += relsize;
	}
    }

  sym_base = ecoff_data (abfd)->reloc_filepos + reloc_size;

  /* At least on Ultrix, the symbol table of an executable file must
     be aligned to a page boundary.  FIXME: Is this true on other
     platforms?  */
  if ((abfd->flags & EXEC_P) != 0
      && (abfd->flags & D_PAGED) != 0)
    sym_base = ((sym_base + ecoff_backend (abfd)->round - 1)
		&~ (ecoff_backend (abfd)->round - 1));

  ecoff_data (abfd)->sym_filepos = sym_base;

  return reloc_size;
}

/* Set the contents of a section.  */

bfd_boolean
_bfd_ecoff_set_section_contents (bfd *abfd,
				 asection *section,
				 const void * location,
				 file_ptr offset,
				 bfd_size_type count)
{
  file_ptr pos;

  /* This must be done first, because bfd_set_section_contents is
     going to set output_has_begun to TRUE.  */
  if (! abfd->output_has_begun
      && ! ecoff_compute_section_file_positions (abfd))
    return FALSE;

  /* Handle the .lib section specially so that Irix 4 shared libraries
     work out.  See coff_set_section_contents in coffcode.h.  */
  if (streq (section->name, _LIB))
    {
      bfd_byte *rec, *recend;

      rec = (bfd_byte *) location;
      recend = rec + count;
      while (rec < recend)
	{
	  ++section->lma;
	  rec += bfd_get_32 (abfd, rec) * 4;
	}

      BFD_ASSERT (rec == recend);
    }

  if (count == 0)
    return TRUE;

  pos = section->filepos + offset;
  if (bfd_seek (abfd, pos, SEEK_SET) != 0
      || bfd_bwrite (location, count, abfd) != count)
    return FALSE;

  return TRUE;
}

/* Get the GP value for an ECOFF file.  This is a hook used by
   nlmconv.  */

bfd_vma
bfd_ecoff_get_gp_value (bfd *abfd)
{
  if (bfd_get_flavour (abfd) != bfd_target_ecoff_flavour
      || bfd_get_format (abfd) != bfd_object)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return 0;
    }

  return ecoff_data (abfd)->gp;
}

/* Set the GP value for an ECOFF file.  This is a hook used by the
   assembler.  */

bfd_boolean
bfd_ecoff_set_gp_value (bfd *abfd, bfd_vma gp_value)
{
  if (bfd_get_flavour (abfd) != bfd_target_ecoff_flavour
      || bfd_get_format (abfd) != bfd_object)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return FALSE;
    }

  ecoff_data (abfd)->gp = gp_value;

  return TRUE;
}

/* Set the register masks for an ECOFF file.  This is a hook used by
   the assembler.  */

bfd_boolean
bfd_ecoff_set_regmasks (bfd *abfd,
			unsigned long gprmask,
			unsigned long fprmask,
			unsigned long *cprmask)
{
  ecoff_data_type *tdata;

  if (bfd_get_flavour (abfd) != bfd_target_ecoff_flavour
      || bfd_get_format (abfd) != bfd_object)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return FALSE;
    }

  tdata = ecoff_data (abfd);
  tdata->gprmask = gprmask;
  tdata->fprmask = fprmask;
  if (cprmask != NULL)
    {
      int i;

      for (i = 0; i < 3; i++)
	tdata->cprmask[i] = cprmask[i];
    }

  return TRUE;
}

/* Get ECOFF EXTR information for an external symbol.  This function
   is passed to bfd_ecoff_debug_externals.  */

static bfd_boolean
ecoff_get_extr (asymbol *sym, EXTR *esym)
{
  ecoff_symbol_type *ecoff_sym_ptr;
  bfd *input_bfd;

  if (bfd_asymbol_flavour (sym) != bfd_target_ecoff_flavour
      || ecoffsymbol (sym)->native == NULL)
    {
      /* Don't include debugging, local, or section symbols.  */
      if ((sym->flags & BSF_DEBUGGING) != 0
	  || (sym->flags & BSF_LOCAL) != 0
	  || (sym->flags & BSF_SECTION_SYM) != 0)
	return FALSE;

      esym->jmptbl = 0;
      esym->cobol_main = 0;
      esym->weakext = (sym->flags & BSF_WEAK) != 0;
      esym->reserved = 0;
      esym->ifd = ifdNil;
      /* FIXME: we can do better than this for st and sc.  */
      esym->asym.st = stGlobal;
      esym->asym.sc = scAbs;
      esym->asym.reserved = 0;
      esym->asym.index = indexNil;
      return TRUE;
    }

  ecoff_sym_ptr = ecoffsymbol (sym);

  if (ecoff_sym_ptr->local)
    return FALSE;

  input_bfd = bfd_asymbol_bfd (sym);
  (*(ecoff_backend (input_bfd)->debug_swap.swap_ext_in))
    (input_bfd, ecoff_sym_ptr->native, esym);

  /* If the symbol was defined by the linker, then esym will be
     undefined but sym will not be.  Get a better class for such a
     symbol.  */
  if ((esym->asym.sc == scUndefined
       || esym->asym.sc == scSUndefined)
      && ! bfd_is_und_section (bfd_get_section (sym)))
    esym->asym.sc = scAbs;

  /* Adjust the FDR index for the symbol by that used for the input
     BFD.  */
  if (esym->ifd != -1)
    {
      struct ecoff_debug_info *input_debug;

      input_debug = &ecoff_data (input_bfd)->debug_info;
      BFD_ASSERT (esym->ifd < input_debug->symbolic_header.ifdMax);
      if (input_debug->ifdmap != NULL)
	esym->ifd = input_debug->ifdmap[esym->ifd];
    }

  return TRUE;
}

/* Set the external symbol index.  This routine is passed to
   bfd_ecoff_debug_externals.  */

static void
ecoff_set_index (asymbol *sym, bfd_size_type indx)
{
  ecoff_set_sym_index (sym, indx);
}

/* Write out an ECOFF file.  */

bfd_boolean
_bfd_ecoff_write_object_contents (bfd *abfd)
{
  const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
  const bfd_vma round = backend->round;
  const bfd_size_type filhsz = bfd_coff_filhsz (abfd);
  const bfd_size_type aoutsz = bfd_coff_aoutsz (abfd);
  const bfd_size_type scnhsz = bfd_coff_scnhsz (abfd);
  const bfd_size_type external_hdr_size
    = backend->debug_swap.external_hdr_size;
  const bfd_size_type external_reloc_size = backend->external_reloc_size;
  void (* const adjust_reloc_out) (bfd *, const arelent *, struct internal_reloc *)
    = backend->adjust_reloc_out;
  void (* const swap_reloc_out) (bfd *, const struct internal_reloc *, void *)
    = backend->swap_reloc_out;
  struct ecoff_debug_info * const debug = &ecoff_data (abfd)->debug_info;
  HDRR * const symhdr = &debug->symbolic_header;
  asection *current;
  unsigned int count;
  bfd_size_type reloc_size;
  bfd_size_type text_size;
  bfd_vma text_start;
  bfd_boolean set_text_start;
  bfd_size_type data_size;
  bfd_vma data_start;
  bfd_boolean set_data_start;
  bfd_size_type bss_size;
  void * buff = NULL;
  void * reloc_buff = NULL;
  struct internal_filehdr internal_f;
  struct internal_aouthdr internal_a;
  int i;

  /* Determine where the sections and relocs will go in the output
     file.  */
  reloc_size = ecoff_compute_reloc_file_positions (abfd);

  count = 1;
  for (current = abfd->sections;
       current != NULL;
       current = current->next)
    {
      current->target_index = count;
      ++count;
    }

  if ((abfd->flags & D_PAGED) != 0)
    text_size = _bfd_ecoff_sizeof_headers (abfd, NULL);
  else
    text_size = 0;
  text_start = 0;
  set_text_start = FALSE;
  data_size = 0;
  data_start = 0;
  set_data_start = FALSE;
  bss_size = 0;

  /* Write section headers to the file.  */

  /* Allocate buff big enough to hold a section header,
     file header, or a.out header.  */
  {
    bfd_size_type siz;

    siz = scnhsz;
    if (siz < filhsz)
      siz = filhsz;
    if (siz < aoutsz)
      siz = aoutsz;
    buff = bfd_malloc (siz);
    if (buff == NULL)
      goto error_return;
  }

  internal_f.f_nscns = 0;
  if (bfd_seek (abfd, (file_ptr) (filhsz + aoutsz), SEEK_SET) != 0)
    goto error_return;

  for (current = abfd->sections;
       current != NULL;
       current = current->next)
    {
      struct internal_scnhdr section;
      bfd_vma vma;

      ++internal_f.f_nscns;

      strncpy (section.s_name, current->name, sizeof section.s_name);

      /* This seems to be correct for Irix 4 shared libraries.  */
      vma = bfd_get_section_vma (abfd, current);
      if (streq (current->name, _LIB))
	section.s_vaddr = 0;
      else
	section.s_vaddr = vma;

      section.s_paddr = current->lma;
      section.s_size = current->size;

      /* If this section is unloadable then the scnptr will be 0.  */
      if ((current->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
	section.s_scnptr = 0;
      else
	section.s_scnptr = current->filepos;
      section.s_relptr = current->rel_filepos;

      /* FIXME: the lnnoptr of the .sbss or .sdata section of an
	 object file produced by the assembler is supposed to point to
	 information about how much room is required by objects of
	 various different sizes.  I think this only matters if we
	 want the linker to compute the best size to use, or
	 something.  I don't know what happens if the information is
	 not present.  */
      if (! streq (current->name, _PDATA))
	section.s_lnnoptr = 0;
      else
	{
	  /* The Alpha ECOFF .pdata section uses the lnnoptr field to
	     hold the number of entries in the section (each entry is
	     8 bytes).  We stored this in the line_filepos field in
	     ecoff_compute_section_file_positions.  */
	  section.s_lnnoptr = current->line_filepos;
	}

      section.s_nreloc = current->reloc_count;
      section.s_nlnno = 0;
      section.s_flags = ecoff_sec_to_styp_flags (current->name,
						 current->flags);

      if (bfd_coff_swap_scnhdr_out (abfd, (void *) &section, buff) == 0
	  || bfd_bwrite (buff, scnhsz, abfd) != scnhsz)
	goto error_return;

      if ((section.s_flags & STYP_TEXT) != 0
	  || ((section.s_flags & STYP_RDATA) != 0
	      && ecoff_data (abfd)->rdata_in_text)
	  || section.s_flags == STYP_PDATA
	  || (section.s_flags & STYP_DYNAMIC) != 0
	  || (section.s_flags & STYP_LIBLIST) != 0
	  || (section.s_flags & STYP_RELDYN) != 0
	  || section.s_flags == STYP_CONFLIC
	  || (section.s_flags & STYP_DYNSTR) != 0
	  || (section.s_flags & STYP_DYNSYM) != 0
	  || (section.s_flags & STYP_HASH) != 0
	  || (section.s_flags & STYP_ECOFF_INIT) != 0
	  || (section.s_flags & STYP_ECOFF_FINI) != 0
	  || section.s_flags == STYP_RCONST)
	{
	  text_size += current->size;
	  if (! set_text_start || text_start > vma)
	    {
	      text_start = vma;
	      set_text_start = TRUE;
	    }
	}
      else if ((section.s_flags & STYP_RDATA) != 0
	       || (section.s_flags & STYP_DATA) != 0
	       || (section.s_flags & STYP_LITA) != 0
	       || (section.s_flags & STYP_LIT8) != 0
	       || (section.s_flags & STYP_LIT4) != 0
	       || (section.s_flags & STYP_SDATA) != 0
	       || section.s_flags == STYP_XDATA
	       || (section.s_flags & STYP_GOT) != 0)
	{
	  data_size += current->size;
	  if (! set_data_start || data_start > vma)
	    {
	      data_start = vma;
	      set_data_start = TRUE;
	    }
	}
      else if ((section.s_flags & STYP_BSS) != 0
	       || (section.s_flags & STYP_SBSS) != 0)
	bss_size += current->size;
      else if (section.s_flags == 0
	       || (section.s_flags & STYP_ECOFF_LIB) != 0
	       || section.s_flags == STYP_COMMENT)
	/* Do nothing.  */ ;
      else
	abort ();
    }

  /* Set up the file header.  */
  internal_f.f_magic = ecoff_get_magic (abfd);

  /* We will NOT put a fucking timestamp in the header here. Every
     time you put it back, I will come in and take it out again.  I'm
     sorry.  This field does not belong here.  We fill it with a 0 so
     it compares the same but is not a reasonable time. --
     gnu@cygnus.com.  */
  internal_f.f_timdat = 0;

  if (bfd_get_symcount (abfd) != 0)
    {
      /* The ECOFF f_nsyms field is not actually the number of
	 symbols, it's the size of symbolic information header.  */
      internal_f.f_nsyms = external_hdr_size;
      internal_f.f_symptr = ecoff_data (abfd)->sym_filepos;
    }
  else
    {
      internal_f.f_nsyms = 0;
      internal_f.f_symptr = 0;
    }

  internal_f.f_opthdr = aoutsz;

  internal_f.f_flags = F_LNNO;
  if (reloc_size == 0)
    internal_f.f_flags |= F_RELFLG;
  if (bfd_get_symcount (abfd) == 0)
    internal_f.f_flags |= F_LSYMS;
  if (abfd->flags & EXEC_P)
    internal_f.f_flags |= F_EXEC;

  if (bfd_little_endian (abfd))
    internal_f.f_flags |= F_AR32WR;
  else
    internal_f.f_flags |= F_AR32W;

  /* Set up the ``optional'' header.  */
  if ((abfd->flags & D_PAGED) != 0)
    internal_a.magic = ECOFF_AOUT_ZMAGIC;
  else
    internal_a.magic = ECOFF_AOUT_OMAGIC;

  /* FIXME: Is this really correct?  */
  internal_a.vstamp = symhdr->vstamp;

  /* At least on Ultrix, these have to be rounded to page boundaries.
     FIXME: Is this true on other platforms?  */
  if ((abfd->flags & D_PAGED) != 0)
    {
      internal_a.tsize = (text_size + round - 1) &~ (round - 1);
      internal_a.text_start = text_start &~ (round - 1);
      internal_a.dsize = (data_size + round - 1) &~ (round - 1);
      internal_a.data_start = data_start &~ (round - 1);
    }
  else
    {
      internal_a.tsize = text_size;
      internal_a.text_start = text_start;
      internal_a.dsize = data_size;
      internal_a.data_start = data_start;
    }

  /* On Ultrix, the initial portions of the .sbss and .bss segments
     are at the end of the data section.  The bsize field in the
     optional header records how many bss bytes are required beyond
     those in the data section.  The value is not rounded to a page
     boundary.  */
  if (bss_size < internal_a.dsize - data_size)
    bss_size = 0;
  else
    bss_size -= internal_a.dsize - data_size;
  internal_a.bsize = bss_size;
  internal_a.bss_start = internal_a.data_start + internal_a.dsize;

  internal_a.entry = bfd_get_start_address (abfd);

  internal_a.gp_value = ecoff_data (abfd)->gp;

  internal_a.gprmask = ecoff_data (abfd)->gprmask;
  internal_a.fprmask = ecoff_data (abfd)->fprmask;
  for (i = 0; i < 4; i++)
    internal_a.cprmask[i] = ecoff_data (abfd)->cprmask[i];

  /* Let the backend adjust the headers if necessary.  */
  if (backend->adjust_headers)
    {
      if (! (*backend->adjust_headers) (abfd, &internal_f, &internal_a))
	goto error_return;
    }

  /* Write out the file header and the optional header.  */
  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
    goto error_return;

  bfd_coff_swap_filehdr_out (abfd, (void *) &internal_f, buff);
  if (bfd_bwrite (buff, filhsz, abfd) != filhsz)
    goto error_return;

  bfd_coff_swap_aouthdr_out (abfd, (void *) &internal_a, buff);
  if (bfd_bwrite (buff, aoutsz, abfd) != aoutsz)
    goto error_return;

  /* Build the external symbol information.  This must be done before
     writing out the relocs so that we know the symbol indices.  We
     don't do this if this BFD was created by the backend linker,
     since it will have already handled the symbols and relocs.  */
  if (! ecoff_data (abfd)->linker)
    {
      symhdr->iextMax = 0;
      symhdr->issExtMax = 0;
      debug->external_ext = debug->external_ext_end = NULL;
      debug->ssext = debug->ssext_end = NULL;
      if (! bfd_ecoff_debug_externals (abfd, debug, &backend->debug_swap,
				       (abfd->flags & EXEC_P) == 0,
				       ecoff_get_extr, ecoff_set_index))
	goto error_return;

      /* Write out the relocs.  */
      for (current = abfd->sections;
	   current != NULL;
	   current = current->next)
	{
	  arelent **reloc_ptr_ptr;
	  arelent **reloc_end;
	  char *out_ptr;
	  bfd_size_type amt;

	  if (current->reloc_count == 0)
	    continue;

	  amt = current->reloc_count * external_reloc_size;
	  reloc_buff = bfd_alloc (abfd, amt);
	  if (reloc_buff == NULL)
	    goto error_return;

	  reloc_ptr_ptr = current->orelocation;
	  reloc_end = reloc_ptr_ptr + current->reloc_count;
	  out_ptr = (char *) reloc_buff;

	  for (;
	       reloc_ptr_ptr < reloc_end;
	       reloc_ptr_ptr++, out_ptr += external_reloc_size)
	    {
	      arelent *reloc;
	      asymbol *sym;
	      struct internal_reloc in;

	      memset ((void *) &in, 0, sizeof in);

	      reloc = *reloc_ptr_ptr;
	      sym = *reloc->sym_ptr_ptr;

	      /* If the howto field has not been initialised then skip this reloc.
		 This assumes that an error message has been issued elsewhere.  */
	      if (reloc->howto == NULL)
		continue;

	      in.r_vaddr = (reloc->address
			    + bfd_get_section_vma (abfd, current));
	      in.r_type = reloc->howto->type;

	      if ((sym->flags & BSF_SECTION_SYM) == 0)
		{
		  in.r_symndx = ecoff_get_sym_index (*reloc->sym_ptr_ptr);
		  in.r_extern = 1;
		}
	      else
		{
		  const char *name;
		  unsigned int j;
		  static struct
		  {
		    const char * name;
		    long r_symndx;
		  }
		  section_symndx [] =
		  {
		    { _TEXT,   RELOC_SECTION_TEXT   },
		    { _RDATA,  RELOC_SECTION_RDATA  },
		    { _DATA,   RELOC_SECTION_DATA   },
		    { _SDATA,  RELOC_SECTION_SDATA  },
		    { _SBSS,   RELOC_SECTION_SBSS   },
		    { _BSS,    RELOC_SECTION_BSS    },
		    { _INIT,   RELOC_SECTION_INIT   },
		    { _LIT8,   RELOC_SECTION_LIT8   },
		    { _LIT4,   RELOC_SECTION_LIT4   },
		    { _XDATA,  RELOC_SECTION_XDATA  },
		    { _PDATA,  RELOC_SECTION_PDATA  },
		    { _FINI,   RELOC_SECTION_FINI   },
		    { _LITA,   RELOC_SECTION_LITA   },
		    { "*ABS*", RELOC_SECTION_ABS    },
		    { _RCONST, RELOC_SECTION_RCONST }
		  };

		  name = bfd_get_section_name (abfd, bfd_get_section (sym));

		  for (j = 0; j < ARRAY_SIZE (section_symndx); j++)
		    if (streq (name, section_symndx[j].name))
		      {
			in.r_symndx = section_symndx[j].r_symndx;
			break;
		      }

		  if (j == ARRAY_SIZE (section_symndx))
		    abort ();
		  in.r_extern = 0;
		}

	      (*adjust_reloc_out) (abfd, reloc, &in);

	      (*swap_reloc_out) (abfd, &in, (void *) out_ptr);
	    }

	  if (bfd_seek (abfd, current->rel_filepos, SEEK_SET) != 0)
	    goto error_return;
	  amt = current->reloc_count * external_reloc_size;
	  if (bfd_bwrite (reloc_buff, amt, abfd) != amt)
	    goto error_return;
	  bfd_release (abfd, reloc_buff);
	  reloc_buff = NULL;
	}

      /* Write out the symbolic debugging information.  */
      if (bfd_get_symcount (abfd) > 0)
	{
	  /* Write out the debugging information.  */
	  if (! bfd_ecoff_write_debug (abfd, debug, &backend->debug_swap,
				       ecoff_data (abfd)->sym_filepos))
	    goto error_return;
	}
    }

  /* The .bss section of a demand paged executable must receive an
     entire page.  If there are symbols, the symbols will start on the
     next page.  If there are no symbols, we must fill out the page by
     hand.  */
  if (bfd_get_symcount (abfd) == 0
      && (abfd->flags & EXEC_P) != 0
      && (abfd->flags & D_PAGED) != 0)
    {
      char c;

      if (bfd_seek (abfd, (file_ptr) ecoff_data (abfd)->sym_filepos - 1,
		    SEEK_SET) != 0)
	goto error_return;
      if (bfd_bread (&c, (bfd_size_type) 1, abfd) == 0)
	c = 0;
      if (bfd_seek (abfd, (file_ptr) ecoff_data (abfd)->sym_filepos - 1,
		    SEEK_SET) != 0)
	goto error_return;
      if (bfd_bwrite (&c, (bfd_size_type) 1, abfd) != 1)
	goto error_return;
    }

  if (reloc_buff != NULL)
    bfd_release (abfd, reloc_buff);
  if (buff != NULL)
    free (buff);
  return TRUE;
 error_return:
  if (reloc_buff != NULL)
    bfd_release (abfd, reloc_buff);
  if (buff != NULL)
    free (buff);
  return FALSE;
}

/* Archive handling.  ECOFF uses what appears to be a unique type of
   archive header (armap).  The byte ordering of the armap and the
   contents are encoded in the name of the armap itself.  At least for
   now, we only support archives with the same byte ordering in the
   armap and the contents.

   The first four bytes in the armap are the number of symbol
   definitions.  This is always a power of two.

   This is followed by the symbol definitions.  Each symbol definition
   occupies 8 bytes.  The first four bytes are the offset from the
   start of the armap strings to the null-terminated string naming
   this symbol.  The second four bytes are the file offset to the
   archive member which defines this symbol.  If the second four bytes
   are 0, then this is not actually a symbol definition, and it should
   be ignored.

   The symbols are hashed into the armap with a closed hashing scheme.
   See the functions below for the details of the algorithm.

   After the symbol definitions comes four bytes holding the size of
   the string table, followed by the string table itself.  */

/* The name of an archive headers looks like this:
   __________E[BL]E[BL]_ (with a trailing space).
   The trailing space is changed to an X if the archive is changed to
   indicate that the armap is out of date.

   The Alpha seems to use ________64E[BL]E[BL]_.  */

#define ARMAP_BIG_ENDIAN 		'B'
#define ARMAP_LITTLE_ENDIAN 		'L'
#define ARMAP_MARKER 			'E'
#define ARMAP_START_LENGTH 		10
#define ARMAP_HEADER_MARKER_INDEX	10
#define ARMAP_HEADER_ENDIAN_INDEX 	11
#define ARMAP_OBJECT_MARKER_INDEX 	12
#define ARMAP_OBJECT_ENDIAN_INDEX 	13
#define ARMAP_END_INDEX 		14
#define ARMAP_END 			"_ "

/* This is a magic number used in the hashing algorithm.  */
#define ARMAP_HASH_MAGIC 		0x9dd68ab5

/* This returns the hash value to use for a string.  It also sets
   *REHASH to the rehash adjustment if the first slot is taken.  SIZE
   is the number of entries in the hash table, and HLOG is the log
   base 2 of SIZE.  */

static unsigned int
ecoff_armap_hash (const char *s,
		  unsigned int *rehash,
		  unsigned int size,
		  unsigned int hlog)
{
  unsigned int hash;

  if (hlog == 0)
    return 0;
  hash = *s++;
  while (*s != '\0')
    hash = ((hash >> 27) | (hash << 5)) + *s++;
  hash *= ARMAP_HASH_MAGIC;
  *rehash = (hash & (size - 1)) | 1;
  return hash >> (32 - hlog);
}

/* Read in the armap.  */

bfd_boolean
_bfd_ecoff_slurp_armap (bfd *abfd)
{
  char nextname[17];
  unsigned int i;
  struct areltdata *mapdata;
  bfd_size_type parsed_size;
  char *raw_armap;
  struct artdata *ardata;
  unsigned int count;
  char *raw_ptr;
  carsym *symdef_ptr;
  char *stringbase;
  bfd_size_type amt;

  /* Get the name of the first element.  */
  i = bfd_bread ((void *) nextname, (bfd_size_type) 16, abfd);
  if (i == 0)
      return TRUE;
  if (i != 16)
      return FALSE;

  if (bfd_seek (abfd, (file_ptr) -16, SEEK_CUR) != 0)
    return FALSE;

  /* Irix 4.0.5F apparently can use either an ECOFF armap or a
     standard COFF armap.  We could move the ECOFF armap stuff into
     bfd_slurp_armap, but that seems inappropriate since no other
     target uses this format.  Instead, we check directly for a COFF
     armap.  */
  if (CONST_STRNEQ (nextname, "/               "))
    return bfd_slurp_armap (abfd);

  /* See if the first element is an armap.  */
  if (! strneq (nextname, ecoff_backend (abfd)->armap_start, ARMAP_START_LENGTH)
      || nextname[ARMAP_HEADER_MARKER_INDEX] != ARMAP_MARKER
      || (nextname[ARMAP_HEADER_ENDIAN_INDEX] != ARMAP_BIG_ENDIAN
	  && nextname[ARMAP_HEADER_ENDIAN_INDEX] != ARMAP_LITTLE_ENDIAN)
      || nextname[ARMAP_OBJECT_MARKER_INDEX] != ARMAP_MARKER
      || (nextname[ARMAP_OBJECT_ENDIAN_INDEX] != ARMAP_BIG_ENDIAN
	  && nextname[ARMAP_OBJECT_ENDIAN_INDEX] != ARMAP_LITTLE_ENDIAN)
      || ! strneq (nextname + ARMAP_END_INDEX, ARMAP_END, sizeof ARMAP_END - 1))
    {
      bfd_has_map (abfd) = FALSE;
      return TRUE;
    }

  /* Make sure we have the right byte ordering.  */
  if (((nextname[ARMAP_HEADER_ENDIAN_INDEX] == ARMAP_BIG_ENDIAN)
       ^ (bfd_header_big_endian (abfd)))
      || ((nextname[ARMAP_OBJECT_ENDIAN_INDEX] == ARMAP_BIG_ENDIAN)
	  ^ (bfd_big_endian (abfd))))
    {
      bfd_set_error (bfd_error_wrong_format);
      return FALSE;
    }

  /* Read in the armap.  */
  ardata = bfd_ardata (abfd);
  mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
  if (mapdata == NULL)
    return FALSE;
  parsed_size = mapdata->parsed_size;
  free (mapdata);

  raw_armap = (char *) bfd_alloc (abfd, parsed_size);
  if (raw_armap == NULL)
    return FALSE;

  if (bfd_bread ((void *) raw_armap, parsed_size, abfd) != parsed_size)
    {
      if (bfd_get_error () != bfd_error_system_call)
	bfd_set_error (bfd_error_malformed_archive);
      bfd_release (abfd, (void *) raw_armap);
      return FALSE;
    }

  ardata->tdata = (void *) raw_armap;

  count = H_GET_32 (abfd, raw_armap);

  ardata->symdef_count = 0;
  ardata->cache = NULL;

  /* This code used to overlay the symdefs over the raw archive data,
     but that doesn't work on a 64 bit host.  */
  stringbase = raw_armap + count * 8 + 8;

#ifdef CHECK_ARMAP_HASH
  {
    unsigned int hlog;

    /* Double check that I have the hashing algorithm right by making
       sure that every symbol can be looked up successfully.  */
    hlog = 0;
    for (i = 1; i < count; i <<= 1)
      hlog++;
    BFD_ASSERT (i == count);

    raw_ptr = raw_armap + 4;
    for (i = 0; i < count; i++, raw_ptr += 8)
      {
	unsigned int name_offset, file_offset;
	unsigned int hash, rehash, srch;

	name_offset = H_GET_32 (abfd, raw_ptr);
	file_offset = H_GET_32 (abfd, (raw_ptr + 4));
	if (file_offset == 0)
	  continue;
	hash = ecoff_armap_hash (stringbase + name_offset, &rehash, count,
				 hlog);
	if (hash == i)
	  continue;

	/* See if we can rehash to this location.  */
	for (srch = (hash + rehash) & (count - 1);
	     srch != hash && srch != i;
	     srch = (srch + rehash) & (count - 1))
	  BFD_ASSERT (H_GET_32 (abfd, (raw_armap + 8 + srch * 8)) != 0);
	BFD_ASSERT (srch == i);
      }
  }

#endif /* CHECK_ARMAP_HASH */

  raw_ptr = raw_armap + 4;
  for (i = 0; i < count; i++, raw_ptr += 8)
    if (H_GET_32 (abfd, (raw_ptr + 4)) != 0)
      ++ardata->symdef_count;

  amt = ardata->symdef_count;
  amt *= sizeof (carsym);
  symdef_ptr = (carsym *) bfd_alloc (abfd, amt);
  if (!symdef_ptr)
    return FALSE;

  ardata->symdefs = symdef_ptr;

  raw_ptr = raw_armap + 4;
  for (i = 0; i < count; i++, raw_ptr += 8)
    {
      unsigned int name_offset, file_offset;

      file_offset = H_GET_32 (abfd, (raw_ptr + 4));
      if (file_offset == 0)
	continue;
      name_offset = H_GET_32 (abfd, raw_ptr);
      symdef_ptr->name = stringbase + name_offset;
      symdef_ptr->file_offset = file_offset;
      ++symdef_ptr;
    }

  ardata->first_file_filepos = bfd_tell (abfd);
  /* Pad to an even boundary.  */
  ardata->first_file_filepos += ardata->first_file_filepos % 2;

  bfd_has_map (abfd) = TRUE;

  return TRUE;
}

/* Write out an armap.  */

bfd_boolean
_bfd_ecoff_write_armap (bfd *abfd,
			unsigned int elength,
			struct orl *map,
			unsigned int orl_count,
			int stridx)
{
  unsigned int hashsize, hashlog;
  bfd_size_type symdefsize;
  int padit;
  unsigned int stringsize;
  unsigned int mapsize;
  file_ptr firstreal;
  struct ar_hdr hdr;
  struct stat statbuf;
  unsigned int i;
  bfd_byte temp[4];
  bfd_byte *hashtable;
  bfd *current;
  bfd *last_elt;

  /* Ultrix appears to use as a hash table size the least power of two
     greater than twice the number of entries.  */
  for (hashlog = 0; ((unsigned int) 1 << hashlog) <= 2 * orl_count; hashlog++)
    ;
  hashsize = 1 << hashlog;

  symdefsize = hashsize * 8;
  padit = stridx % 2;
  stringsize = stridx + padit;

  /* Include 8 bytes to store symdefsize and stringsize in output.  */
  mapsize = symdefsize + stringsize + 8;

  firstreal = SARMAG + sizeof (struct ar_hdr) + mapsize + elength;

  memset ((void *) &hdr, 0, sizeof hdr);

  /* Work out the ECOFF armap name.  */
  strcpy (hdr.ar_name, ecoff_backend (abfd)->armap_start);
  hdr.ar_name[ARMAP_HEADER_MARKER_INDEX] = ARMAP_MARKER;
  hdr.ar_name[ARMAP_HEADER_ENDIAN_INDEX] =
    (bfd_header_big_endian (abfd)
     ? ARMAP_BIG_ENDIAN
     : ARMAP_LITTLE_ENDIAN);
  hdr.ar_name[ARMAP_OBJECT_MARKER_INDEX] = ARMAP_MARKER;
  hdr.ar_name[ARMAP_OBJECT_ENDIAN_INDEX] =
    bfd_big_endian (abfd) ? ARMAP_BIG_ENDIAN : ARMAP_LITTLE_ENDIAN;
  memcpy (hdr.ar_name + ARMAP_END_INDEX, ARMAP_END, sizeof ARMAP_END - 1);

  /* Write the timestamp of the archive header to be just a little bit
     later than the timestamp of the file, otherwise the linker will
     complain that the index is out of date.  Actually, the Ultrix
     linker just checks the archive name; the GNU linker may check the
     date.  */
  stat (abfd->filename, &statbuf);
  _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
		    (long) (statbuf.st_mtime + 60));

  /* The DECstation uses zeroes for the uid, gid and mode of the
     armap.  */
  hdr.ar_uid[0] = '0';
  hdr.ar_gid[0] = '0';
  /* Building gcc ends up extracting the armap as a file - twice.  */
  hdr.ar_mode[0] = '6';
  hdr.ar_mode[1] = '4';
  hdr.ar_mode[2] = '4';

  _bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld", mapsize);

  hdr.ar_fmag[0] = '`';
  hdr.ar_fmag[1] = '\012';

  /* Turn all null bytes in the header into spaces.  */
  for (i = 0; i < sizeof (struct ar_hdr); i++)
   if (((char *) (&hdr))[i] == '\0')
     (((char *) (&hdr))[i]) = ' ';

  if (bfd_bwrite ((void *) &hdr, (bfd_size_type) sizeof (struct ar_hdr), abfd)
      != sizeof (struct ar_hdr))
    return FALSE;

  H_PUT_32 (abfd, hashsize, temp);
  if (bfd_bwrite ((void *) temp, (bfd_size_type) 4, abfd) != 4)
    return FALSE;

  hashtable = (bfd_byte *) bfd_zalloc (abfd, symdefsize);
  if (!hashtable)
    return FALSE;

  current = abfd->archive_head;
  last_elt = current;
  for (i = 0; i < orl_count; i++)
    {
      unsigned int hash, rehash = 0;

      /* Advance firstreal to the file position of this archive
	 element.  */
      if (map[i].u.abfd != last_elt)
	{
	  do
	    {
	      firstreal += arelt_size (current) + sizeof (struct ar_hdr);
	      firstreal += firstreal % 2;
	      current = current->archive_next;
	    }
	  while (current != map[i].u.abfd);
	}

      last_elt = current;

      hash = ecoff_armap_hash (*map[i].name, &rehash, hashsize, hashlog);
      if (H_GET_32 (abfd, (hashtable + (hash * 8) + 4)) != 0)
	{
	  unsigned int srch;

	  /* The desired slot is already taken.  */
	  for (srch = (hash + rehash) & (hashsize - 1);
	       srch != hash;
	       srch = (srch + rehash) & (hashsize - 1))
	    if (H_GET_32 (abfd, (hashtable + (srch * 8) + 4)) == 0)
	      break;

	  BFD_ASSERT (srch != hash);

	  hash = srch;
	}

      H_PUT_32 (abfd, map[i].namidx, (hashtable + hash * 8));
      H_PUT_32 (abfd, firstreal, (hashtable + hash * 8 + 4));
    }

  if (bfd_bwrite ((void *) hashtable, symdefsize, abfd) != symdefsize)
    return FALSE;

  bfd_release (abfd, hashtable);

  /* Now write the strings.  */
  H_PUT_32 (abfd, stringsize, temp);
  if (bfd_bwrite ((void *) temp, (bfd_size_type) 4, abfd) != 4)
    return FALSE;
  for (i = 0; i < orl_count; i++)
    {
      bfd_size_type len;

      len = strlen (*map[i].name) + 1;
      if (bfd_bwrite ((void *) (*map[i].name), len, abfd) != len)
	return FALSE;
    }

  /* The spec sez this should be a newline.  But in order to be
     bug-compatible for DECstation ar we use a null.  */
  if (padit)
    {
      if (bfd_bwrite ("", (bfd_size_type) 1, abfd) != 1)
	return FALSE;
    }

  return TRUE;
}

/* ECOFF linker code.  */

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

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

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

  /* Call the allocation method of the superclass.  */
  ret = ((struct ecoff_link_hash_entry *)
	 _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
				 table, string));

  if (ret)
    {
      /* Set local fields.  */
      ret->indx = -1;
      ret->abfd = NULL;
      ret->written = 0;
      ret->small = 0;
    }
  memset ((void *) &ret->esym, 0, sizeof ret->esym);

  return (struct bfd_hash_entry *) ret;
}

/* Create an ECOFF link hash table.  */

struct bfd_link_hash_table *
_bfd_ecoff_bfd_link_hash_table_create (bfd *abfd)
{
  struct ecoff_link_hash_table *ret;
  bfd_size_type amt = sizeof (struct ecoff_link_hash_table);

  ret = (struct ecoff_link_hash_table *) bfd_malloc (amt);
  if (ret == NULL)
    return NULL;
  if (!_bfd_link_hash_table_init (&ret->root, abfd,
				  ecoff_link_hash_newfunc,
				  sizeof (struct ecoff_link_hash_entry)))
    {
      free (ret);
      return NULL;
    }
  return &ret->root;
}

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

#define ecoff_link_hash_lookup(table, string, create, copy, follow) \
  ((struct ecoff_link_hash_entry *) \
   bfd_link_hash_lookup (&(table)->root, (string), (create), (copy), (follow)))

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

#define ecoff_hash_table(p) ((struct ecoff_link_hash_table *) ((p)->hash))

/* Add the external symbols of an object file to the global linker
   hash table.  The external symbols and strings we are passed are
   just allocated on the stack, and will be discarded.  We must
   explicitly save any information we may need later on in the link.
   We do not want to read the external symbol information again.  */

static bfd_boolean
ecoff_link_add_externals (bfd *abfd,
			  struct bfd_link_info *info,
			  void * external_ext,
			  char *ssext)
{
  const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
  void (* const swap_ext_in) (bfd *, void *, EXTR *)
    = backend->debug_swap.swap_ext_in;
  bfd_size_type external_ext_size = backend->debug_swap.external_ext_size;
  unsigned long ext_count;
  struct bfd_link_hash_entry **sym_hash;
  char *ext_ptr;
  char *ext_end;
  bfd_size_type amt;

  ext_count = ecoff_data (abfd)->debug_info.symbolic_header.iextMax;

  amt = ext_count;
  amt *= sizeof (struct bfd_link_hash_entry *);
  sym_hash = (struct bfd_link_hash_entry **) bfd_alloc (abfd, amt);
  if (!sym_hash)
    return FALSE;
  ecoff_data (abfd)->sym_hashes = (struct ecoff_link_hash_entry **) sym_hash;

  ext_ptr = (char *) external_ext;
  ext_end = ext_ptr + ext_count * external_ext_size;
  for (; ext_ptr < ext_end; ext_ptr += external_ext_size, sym_hash++)
    {
      EXTR esym;
      bfd_boolean skip;
      bfd_vma value;
      asection *section;
      const char *name;
      struct ecoff_link_hash_entry *h;

      *sym_hash = NULL;

      (*swap_ext_in) (abfd, (void *) ext_ptr, &esym);

      /* Skip debugging symbols.  */
      skip = FALSE;
      switch (esym.asym.st)
	{
	case stGlobal:
	case stStatic:
	case stLabel:
	case stProc:
	case stStaticProc:
	  break;
	default:
	  skip = TRUE;
	  break;
	}

      if (skip)
	continue;

      /* Get the information for this symbol.  */
      value = esym.asym.value;
      switch (esym.asym.sc)
	{
	default:
	case scNil:
	case scRegister:
	case scCdbLocal:
	case scBits:
	case scCdbSystem:
	case scRegImage:
	case scInfo:
	case scUserStruct:
	case scVar:
	case scVarRegister:
	case scVariant:
	case scBasedVar:
	case scXData:
	case scPData:
	  section = NULL;
	  break;
	case scText:
	  section = bfd_make_section_old_way (abfd, _TEXT);
	  value -= section->vma;
	  break;
	case scData:
	  section = bfd_make_section_old_way (abfd, _DATA);
	  value -= section->vma;
	  break;
	case scBss:
	  section = bfd_make_section_old_way (abfd, _BSS);
	  value -= section->vma;
	  break;
	case scAbs:
	  section = bfd_abs_section_ptr;
	  break;
	case scUndefined:
	  section = bfd_und_section_ptr;
	  break;
	case scSData:
	  section = bfd_make_section_old_way (abfd, _SDATA);
	  value -= section->vma;
	  break;
	case scSBss:
	  section = bfd_make_section_old_way (abfd, _SBSS);
	  value -= section->vma;
	  break;
	case scRData:
	  section = bfd_make_section_old_way (abfd, _RDATA);
	  value -= section->vma;
	  break;
	case scCommon:
	  if (value > ecoff_data (abfd)->gp_size)
	    {
	      section = bfd_com_section_ptr;
	      break;
	    }
	  /* Fall through.  */
	case scSCommon:
	  if (ecoff_scom_section.name == NULL)
	    {
	      /* Initialize the small common section.  */
	      ecoff_scom_section.name = SCOMMON;
	      ecoff_scom_section.flags = SEC_IS_COMMON;
	      ecoff_scom_section.output_section = &ecoff_scom_section;
	      ecoff_scom_section.symbol = &ecoff_scom_symbol;
	      ecoff_scom_section.symbol_ptr_ptr = &ecoff_scom_symbol_ptr;
	      ecoff_scom_symbol.name = SCOMMON;
	      ecoff_scom_symbol.flags = BSF_SECTION_SYM;
	      ecoff_scom_symbol.section = &ecoff_scom_section;
	      ecoff_scom_symbol_ptr = &ecoff_scom_symbol;
	    }
	  section = &ecoff_scom_section;
	  break;
	case scSUndefined:
	  section = bfd_und_section_ptr;
	  break;
	case scInit:
	  section = bfd_make_section_old_way (abfd, _INIT);
	  value -= section->vma;
	  break;
	case scFini:
	  section = bfd_make_section_old_way (abfd, _FINI);
	  value -= section->vma;
	  break;
	case scRConst:
	  section = bfd_make_section_old_way (abfd, _RCONST);
	  value -= section->vma;
	  break;
	}

      if (section == NULL)
	continue;

      name = ssext + esym.asym.iss;

      if (! (_bfd_generic_link_add_one_symbol
	     (info, abfd, name,
	      (flagword) (esym.weakext ? BSF_WEAK : BSF_GLOBAL),
	      section, value, NULL, TRUE, TRUE, sym_hash)))
	return FALSE;

      h = (struct ecoff_link_hash_entry *) *sym_hash;

      /* If we are building an ECOFF hash table, save the external
	 symbol information.  */
      if (bfd_get_flavour (info->output_bfd) == bfd_get_flavour (abfd))
	{
	  if (h->abfd == NULL
	      || (! bfd_is_und_section (section)
		  && (! bfd_is_com_section (section)
		      || (h->root.type != bfd_link_hash_defined
			  && h->root.type != bfd_link_hash_defweak))))
	    {
	      h->abfd = abfd;
	      h->esym = esym;
	    }

	  /* Remember whether this symbol was small undefined.  */
	  if (esym.asym.sc == scSUndefined)
	    h->small = 1;

	  /* If this symbol was ever small undefined, it needs to wind
	     up in a GP relative section.  We can't control the
	     section of a defined symbol, but we can control the
	     section of a common symbol.  This case is actually needed
	     on Ultrix 4.2 to handle the symbol cred in -lckrb.  */
	  if (h->small
	      && h->root.type == bfd_link_hash_common
	      && streq (h->root.u.c.p->section->name, SCOMMON))
	    {
	      h->root.u.c.p->section = bfd_make_section_old_way (abfd,
								 SCOMMON);
	      h->root.u.c.p->section->flags = SEC_ALLOC;
	      if (h->esym.asym.sc == scCommon)
		h->esym.asym.sc = scSCommon;
	    }
	}
    }

  return TRUE;
}

/* Add symbols from an ECOFF object file to the global linker hash
   table.  */

static bfd_boolean
ecoff_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
{
  HDRR *symhdr;
  bfd_size_type external_ext_size;
  void * external_ext = NULL;
  bfd_size_type esize;
  char *ssext = NULL;
  bfd_boolean result;

  if (! ecoff_slurp_symbolic_header (abfd))
    return FALSE;

  /* If there are no symbols, we don't want it.  */
  if (bfd_get_symcount (abfd) == 0)
    return TRUE;

  symhdr = &ecoff_data (abfd)->debug_info.symbolic_header;

  /* Read in the external symbols and external strings.  */
  external_ext_size = ecoff_backend (abfd)->debug_swap.external_ext_size;
  esize = symhdr->iextMax * external_ext_size;
  external_ext = bfd_malloc (esize);
  if (external_ext == NULL && esize != 0)
    goto error_return;

  if (bfd_seek (abfd, (file_ptr) symhdr->cbExtOffset, SEEK_SET) != 0
      || bfd_bread (external_ext, esize, abfd) != esize)
    goto error_return;

  ssext = (char *) bfd_malloc ((bfd_size_type) symhdr->issExtMax);
  if (ssext == NULL && symhdr->issExtMax != 0)
    goto error_return;

  if (bfd_seek (abfd, (file_ptr) symhdr->cbSsExtOffset, SEEK_SET) != 0
      || (bfd_bread (ssext, (bfd_size_type) symhdr->issExtMax, abfd)
	  != (bfd_size_type) symhdr->issExtMax))
    goto error_return;

  result = ecoff_link_add_externals (abfd, info, external_ext, ssext);

  if (ssext != NULL)
    free (ssext);
  if (external_ext != NULL)
    free (external_ext);
  return result;

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

/* This is called if we used _bfd_generic_link_add_archive_symbols
   because we were not dealing with an ECOFF archive.  */

static bfd_boolean
ecoff_link_check_archive_element (bfd *abfd,
				  struct bfd_link_info *info,
				  struct bfd_link_hash_entry *h,
				  const char *name,
				  bfd_boolean *pneeded)
{
  *pneeded = FALSE;

  /* Unlike the generic linker, we do not pull in elements because
     of common symbols.  */
  if (h->type != bfd_link_hash_undefined)
    return TRUE;

  /* Include this element?  */
  if (!(*info->callbacks->add_archive_element) (info, abfd, name, &abfd))
    return TRUE;
  *pneeded = TRUE;

  return ecoff_link_add_object_symbols (abfd, info);
}

/* Add the symbols from an archive file to the global hash table.
   This looks through the undefined symbols, looks each one up in the
   archive hash table, and adds any associated object file.  We do not
   use _bfd_generic_link_add_archive_symbols because ECOFF archives
   already have a hash table, so there is no reason to construct
   another one.  */

static bfd_boolean
ecoff_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
{
  const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
  const bfd_byte *raw_armap;
  struct bfd_link_hash_entry **pundef;
  unsigned int armap_count;
  unsigned int armap_log;
  unsigned int i;
  const bfd_byte *hashtable;
  const char *stringbase;

  if (! bfd_has_map (abfd))
    {
      /* An empty archive is a special case.  */
      if (bfd_openr_next_archived_file (abfd, NULL) == NULL)
	return TRUE;
      bfd_set_error (bfd_error_no_armap);
      return FALSE;
    }

  /* If we don't have any raw data for this archive, as can happen on
     Irix 4.0.5F, we call the generic routine.
     FIXME: We should be more clever about this, since someday tdata
     may get to something for a generic archive.  */
  raw_armap = (const bfd_byte *) bfd_ardata (abfd)->tdata;
  if (raw_armap == NULL)
    return (_bfd_generic_link_add_archive_symbols
	    (abfd, info, ecoff_link_check_archive_element));

  armap_count = H_GET_32 (abfd, raw_armap);

  armap_log = 0;
  for (i = 1; i < armap_count; i <<= 1)
    armap_log++;
  BFD_ASSERT (i == armap_count);

  hashtable = raw_armap + 4;
  stringbase = (const char *) raw_armap + armap_count * 8 + 8;

  /* Look through the list of undefined symbols.  */
  pundef = &info->hash->undefs;
  while (*pundef != NULL)
    {
      struct bfd_link_hash_entry *h;
      unsigned int hash, rehash = 0;
      unsigned int file_offset;
      const char *name;
      bfd *element;

      h = *pundef;

      /* When a symbol is defined, it is not necessarily removed from
	 the list.  */
      if (h->type != bfd_link_hash_undefined
	  && h->type != bfd_link_hash_common)
	{
	  /* Remove this entry from the list, for general cleanliness
	     and because we are going to look through the list again
	     if we search any more libraries.  We can't remove the
	     entry if it is the tail, because that would lose any
	     entries we add to the list later on.  */
	  if (*pundef != info->hash->undefs_tail)
	    *pundef = (*pundef)->u.undef.next;
	  else
	    pundef = &(*pundef)->u.undef.next;
	  continue;
	}

      /* Native ECOFF linkers do not pull in archive elements merely
	 to satisfy common definitions, so neither do we.  We leave
	 them on the list, though, in case we are linking against some
	 other object format.  */
      if (h->type != bfd_link_hash_undefined)
	{
	  pundef = &(*pundef)->u.undef.next;
	  continue;
	}

      /* Look for this symbol in the archive hash table.  */
      hash = ecoff_armap_hash (h->root.string, &rehash, armap_count,
			       armap_log);

      file_offset = H_GET_32 (abfd, hashtable + (hash * 8) + 4);
      if (file_offset == 0)
	{
	  /* Nothing in this slot.  */
	  pundef = &(*pundef)->u.undef.next;
	  continue;
	}

      name = stringbase + H_GET_32 (abfd, hashtable + (hash * 8));
      if (name[0] != h->root.string[0]
	  || ! streq (name, h->root.string))
	{
	  unsigned int srch;
	  bfd_boolean found;

	  /* That was the wrong symbol.  Try rehashing.  */
	  found = FALSE;
	  for (srch = (hash + rehash) & (armap_count - 1);
	       srch != hash;
	       srch = (srch + rehash) & (armap_count - 1))
	    {
	      file_offset = H_GET_32 (abfd, hashtable + (srch * 8) + 4);
	      if (file_offset == 0)
		break;
	      name = stringbase + H_GET_32 (abfd, hashtable + (srch * 8));
	      if (name[0] == h->root.string[0]
		  && streq (name, h->root.string))
		{
		  found = TRUE;
		  break;
		}
	    }

	  if (! found)
	    {
	      pundef = &(*pundef)->u.undef.next;
	      continue;
	    }

	  hash = srch;
	}

      element = (*backend->get_elt_at_filepos) (abfd, (file_ptr) file_offset);
      if (element == NULL)
	return FALSE;

      if (! bfd_check_format (element, bfd_object))
	return FALSE;

      /* Unlike the generic linker, we know that this element provides
	 a definition for an undefined symbol and we know that we want
	 to include it.  We don't need to check anything.  */
      if (!(*info->callbacks
	    ->add_archive_element) (info, element, name, &element))
	return FALSE;
      if (! ecoff_link_add_object_symbols (element, info))
	return FALSE;

      pundef = &(*pundef)->u.undef.next;
    }

  return TRUE;
}

/* Given an ECOFF BFD, add symbols to the global hash table as
   appropriate.  */

bfd_boolean
_bfd_ecoff_bfd_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
{
  switch (bfd_get_format (abfd))
    {
    case bfd_object:
      return ecoff_link_add_object_symbols (abfd, info);
    case bfd_archive:
      return ecoff_link_add_archive_symbols (abfd, info);
    default:
      bfd_set_error (bfd_error_wrong_format);
      return FALSE;
    }
}


/* ECOFF final link routines.  */

/* Structure used to pass information to ecoff_link_write_external.  */

struct extsym_info
{
  bfd *abfd;
  struct bfd_link_info *info;
};

/* Accumulate the debugging information for an input BFD into the
   output BFD.  This must read in the symbolic information of the
   input BFD.  */

static bfd_boolean
ecoff_final_link_debug_accumulate (bfd *output_bfd,
				   bfd *input_bfd,
				   struct bfd_link_info *info,
				   void * handle)
{
  struct ecoff_debug_info * const debug = &ecoff_data (input_bfd)->debug_info;
  const struct ecoff_debug_swap * const swap =
    &ecoff_backend (input_bfd)->debug_swap;
  HDRR *symhdr = &debug->symbolic_header;
  bfd_boolean ret;

#define READ(ptr, offset, count, size, type)				 \
  if (symhdr->count == 0)						 \
    debug->ptr = NULL;							 \
  else									 \
    {									 \
      bfd_size_type amt = (bfd_size_type) size * symhdr->count;		 \
      debug->ptr = (type) bfd_malloc (amt);                              \
      if (debug->ptr == NULL)						 \
	{								 \
          ret = FALSE;							 \
          goto return_something;					 \
	}								 \
      if (bfd_seek (input_bfd, (file_ptr) symhdr->offset, SEEK_SET) != 0 \
	  || bfd_bread (debug->ptr, amt, input_bfd) != amt)		 \
	{								 \
          ret = FALSE;							 \
          goto return_something;					 \
	}								 \
    }

  /* If raw_syments is not NULL, then the data was already by read by
     _bfd_ecoff_slurp_symbolic_info.  */
  if (ecoff_data (input_bfd)->raw_syments == NULL)
    {
      READ (line, cbLineOffset, cbLine, sizeof (unsigned char),
	    unsigned char *);
      READ (external_dnr, cbDnOffset, idnMax, swap->external_dnr_size, void *);
      READ (external_pdr, cbPdOffset, ipdMax, swap->external_pdr_size, void *);
      READ (external_sym, cbSymOffset, isymMax, swap->external_sym_size, void *);
      READ (external_opt, cbOptOffset, ioptMax, swap->external_opt_size, void *);
      READ (external_aux, cbAuxOffset, iauxMax, sizeof (union aux_ext),
	    union aux_ext *);
      READ (ss, cbSsOffset, issMax, sizeof (char), char *);
      READ (external_fdr, cbFdOffset, ifdMax, swap->external_fdr_size, void *);
      READ (external_rfd, cbRfdOffset, crfd, swap->external_rfd_size, void *);
    }
#undef READ

  /* We do not read the external strings or the external symbols.  */

  ret = (bfd_ecoff_debug_accumulate
	 (handle, output_bfd, &ecoff_data (output_bfd)->debug_info,
	  &ecoff_backend (output_bfd)->debug_swap,
	  input_bfd, debug, swap, info));

 return_something:
  if (ecoff_data (input_bfd)->raw_syments == NULL)
    {
      if (debug->line != NULL)
	free (debug->line);
      if (debug->external_dnr != NULL)
	free (debug->external_dnr);
      if (debug->external_pdr != NULL)
	free (debug->external_pdr);
      if (debug->external_sym != NULL)
	free (debug->external_sym);
      if (debug->external_opt != NULL)
	free (debug->external_opt);
      if (debug->external_aux != NULL)
	free (debug->external_aux);
      if (debug->ss != NULL)
	free (debug->ss);
      if (debug->external_fdr != NULL)
	free (debug->external_fdr);
      if (debug->external_rfd != NULL)
	free (debug->external_rfd);

      /* Make sure we don't accidentally follow one of these pointers
	 into freed memory.  */
      debug->line = NULL;
      debug->external_dnr = NULL;
      debug->external_pdr = NULL;
      debug->external_sym = NULL;
      debug->external_opt = NULL;
      debug->external_aux = NULL;
      debug->ss = NULL;
      debug->external_fdr = NULL;
      debug->external_rfd = NULL;
    }

  return ret;
}

/* Relocate and write an ECOFF section into an ECOFF output file.  */

static bfd_boolean
ecoff_indirect_link_order (bfd *output_bfd,
			   struct bfd_link_info *info,
			   asection *output_section,
			   struct bfd_link_order *link_order)
{
  asection *input_section;
  bfd *input_bfd;
  bfd_byte *contents = NULL;
  bfd_size_type external_reloc_size;
  bfd_size_type external_relocs_size;
  void * external_relocs = NULL;

  BFD_ASSERT ((output_section->flags & SEC_HAS_CONTENTS) != 0);

  input_section = link_order->u.indirect.section;
  input_bfd = input_section->owner;
  if (input_section->size == 0)
    return TRUE;

  BFD_ASSERT (input_section->output_section == output_section);
  BFD_ASSERT (input_section->output_offset == link_order->offset);
  BFD_ASSERT (input_section->size == link_order->size);

  /* Get the section contents.  */
  if (!bfd_malloc_and_get_section (input_bfd, input_section, &contents))
    goto error_return;

  /* Get the relocs.  If we are relaxing MIPS code, they will already
     have been read in.  Otherwise, we read them in now.  */
  external_reloc_size = ecoff_backend (input_bfd)->external_reloc_size;
  external_relocs_size = external_reloc_size * input_section->reloc_count;

  external_relocs = bfd_malloc (external_relocs_size);
  if (external_relocs == NULL && external_relocs_size != 0)
    goto error_return;

  if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
      || (bfd_bread (external_relocs, external_relocs_size, input_bfd)
	  != external_relocs_size))
    goto error_return;

  /* Relocate the section contents.  */
  if (! ((*ecoff_backend (input_bfd)->relocate_section)
	 (output_bfd, info, input_bfd, input_section, contents,
	  external_relocs)))
    goto error_return;

  /* Write out the relocated section.  */
  if (! bfd_set_section_contents (output_bfd,
				  output_section,
				  contents,
				  input_section->output_offset,
				  input_section->size))
    goto error_return;

  /* If we are producing relocatable output, the relocs were
     modified, and we write them out now.  We use the reloc_count
     field of output_section to keep track of the number of relocs we
     have output so far.  */
  if (bfd_link_relocatable (info))
    {
      file_ptr pos = (output_section->rel_filepos
		      + output_section->reloc_count * external_reloc_size);
      if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
	  || (bfd_bwrite (external_relocs, external_relocs_size, output_bfd)
	      != external_relocs_size))
	goto error_return;
      output_section->reloc_count += input_section->reloc_count;
    }

  if (contents != NULL)
    free (contents);
  if (external_relocs != NULL)
    free (external_relocs);
  return TRUE;

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

/* Generate a reloc when linking an ECOFF file.  This is a reloc
   requested by the linker, and does come from any input file.  This
   is used to build constructor and destructor tables when linking
   with -Ur.  */

static bfd_boolean
ecoff_reloc_link_order (bfd *output_bfd,
			struct bfd_link_info *info,
			asection *output_section,
			struct bfd_link_order *link_order)
{
  enum bfd_link_order_type type;
  asection *section;
  bfd_vma addend;
  arelent rel;
  struct internal_reloc in;
  bfd_size_type external_reloc_size;
  bfd_byte *rbuf;
  bfd_boolean ok;
  file_ptr pos;

  type = link_order->type;
  section = NULL;
  addend = link_order->u.reloc.p->addend;

  /* We set up an arelent to pass to the backend adjust_reloc_out
     routine.  */
  rel.address = link_order->offset;

  rel.howto = bfd_reloc_type_lookup (output_bfd, link_order->u.reloc.p->reloc);
  if (rel.howto == 0)
    {
      bfd_set_error (bfd_error_bad_value);
      return FALSE;
    }

  if (type == bfd_section_reloc_link_order)
    {
      section = link_order->u.reloc.p->u.section;
      rel.sym_ptr_ptr = section->symbol_ptr_ptr;
    }
  else
    {
      struct bfd_link_hash_entry *h;

      /* Treat a reloc against a defined symbol as though it were
         actually against the section.  */
      h = bfd_wrapped_link_hash_lookup (output_bfd, info,
					link_order->u.reloc.p->u.name,
					FALSE, FALSE, FALSE);
      if (h != NULL
	  && (h->type == bfd_link_hash_defined
	      || h->type == bfd_link_hash_defweak))
	{
	  type = bfd_section_reloc_link_order;
	  section = h->u.def.section->output_section;
	  /* It seems that we ought to add the symbol value to the
             addend here, but in practice it has already been added
             because it was passed to constructor_callback.  */
	  addend += section->vma + h->u.def.section->output_offset;
	}
      else
	{
	  /* We can't set up a reloc against a symbol correctly,
	     because we have no asymbol structure.  Currently no
	     adjust_reloc_out routine cares.  */
	  rel.sym_ptr_ptr = NULL;
	}
    }

  /* All ECOFF relocs are in-place.  Put the addend into the object
     file.  */

  BFD_ASSERT (rel.howto->partial_inplace);
  if (addend != 0)
    {
      bfd_size_type size;
      bfd_reloc_status_type rstat;
      bfd_byte *buf;

      size = bfd_get_reloc_size (rel.howto);
      buf = (bfd_byte *) bfd_zmalloc (size);
      if (buf == NULL && size != 0)
	return FALSE;
      rstat = _bfd_relocate_contents (rel.howto, output_bfd,
				      (bfd_vma) addend, buf);
      switch (rstat)
	{
	case bfd_reloc_ok:
	  break;
	default:
	case bfd_reloc_outofrange:
	  abort ();
	case bfd_reloc_overflow:
	  (*info->callbacks->reloc_overflow)
	    (info, NULL,
	     (link_order->type == bfd_section_reloc_link_order
	      ? bfd_section_name (output_bfd, section)
	      : link_order->u.reloc.p->u.name),
	     rel.howto->name, addend, NULL, NULL, (bfd_vma) 0);
	  break;
	}
      ok = bfd_set_section_contents (output_bfd, output_section, (void *) buf,
				     (file_ptr) link_order->offset, size);
      free (buf);
      if (! ok)
	return FALSE;
    }

  rel.addend = 0;

  /* Move the information into an internal_reloc structure.  */
  in.r_vaddr = (rel.address
		+ bfd_get_section_vma (output_bfd, output_section));
  in.r_type = rel.howto->type;

  if (type == bfd_symbol_reloc_link_order)
    {
      struct ecoff_link_hash_entry *h;

      h = ((struct ecoff_link_hash_entry *)
	   bfd_wrapped_link_hash_lookup (output_bfd, info,
					 link_order->u.reloc.p->u.name,
					 FALSE, FALSE, TRUE));
      if (h != NULL
	  && h->indx != -1)
	in.r_symndx = h->indx;
      else
	{
	  (*info->callbacks->unattached_reloc)
	    (info, link_order->u.reloc.p->u.name, NULL, NULL, (bfd_vma) 0);
	  in.r_symndx = 0;
	}
      in.r_extern = 1;
    }
  else
    {
      const char *name;
      unsigned int i;
      static struct
      {
	const char * name;
	long r_symndx;
      }
      section_symndx [] =
      {
	{ _TEXT,   RELOC_SECTION_TEXT   },
	{ _RDATA,  RELOC_SECTION_RDATA  },
	{ _DATA,   RELOC_SECTION_DATA   },
	{ _SDATA,  RELOC_SECTION_SDATA  },
	{ _SBSS,   RELOC_SECTION_SBSS   },
	{ _BSS,    RELOC_SECTION_BSS    },
	{ _INIT,   RELOC_SECTION_INIT   },
	{ _LIT8,   RELOC_SECTION_LIT8   },
	{ _LIT4,   RELOC_SECTION_LIT4   },
	{ _XDATA,  RELOC_SECTION_XDATA  },
	{ _PDATA,  RELOC_SECTION_PDATA  },
	{ _FINI,   RELOC_SECTION_FINI   },
	{ _LITA,   RELOC_SECTION_LITA   },
	{ "*ABS*", RELOC_SECTION_ABS    },
	{ _RCONST, RELOC_SECTION_RCONST }
      };

      name = bfd_get_section_name (output_bfd, section);

      for (i = 0; i < ARRAY_SIZE (section_symndx); i++)
	if (streq (name, section_symndx[i].name))
	  {
	    in.r_symndx = section_symndx[i].r_symndx;
	    break;
	  }

      if (i == ARRAY_SIZE (section_symndx))
	abort ();

      in.r_extern = 0;
    }

  /* Let the BFD backend adjust the reloc.  */
  (*ecoff_backend (output_bfd)->adjust_reloc_out) (output_bfd, &rel, &in);

  /* Get some memory and swap out the reloc.  */
  external_reloc_size = ecoff_backend (output_bfd)->external_reloc_size;
  rbuf = (bfd_byte *) bfd_malloc (external_reloc_size);
  if (rbuf == NULL)
    return FALSE;

  (*ecoff_backend (output_bfd)->swap_reloc_out) (output_bfd, &in, (void *) rbuf);

  pos = (output_section->rel_filepos
	 + output_section->reloc_count * external_reloc_size);
  ok = (bfd_seek (output_bfd, pos, SEEK_SET) == 0
	&& (bfd_bwrite ((void *) rbuf, external_reloc_size, output_bfd)
	    == external_reloc_size));

  if (ok)
    ++output_section->reloc_count;

  free (rbuf);

  return ok;
}

/* Put out information for an external symbol.  These come only from
   the hash table.  */

static bfd_boolean
ecoff_link_write_external (struct bfd_hash_entry *bh, void * data)
{
  struct ecoff_link_hash_entry *h = (struct ecoff_link_hash_entry *) bh;
  struct extsym_info *einfo = (struct extsym_info *) data;
  bfd *output_bfd = einfo->abfd;
  bfd_boolean strip;

  if (h->root.type == bfd_link_hash_warning)
    {
      h = (struct ecoff_link_hash_entry *) h->root.u.i.link;
      if (h->root.type == bfd_link_hash_new)
	return TRUE;
    }

  /* We need to check if this symbol is being stripped.  */
  if (h->root.type == bfd_link_hash_undefined
      || h->root.type == bfd_link_hash_undefweak)
    strip = FALSE;
  else if (einfo->info->strip == strip_all
	   || (einfo->info->strip == strip_some
	       && bfd_hash_lookup (einfo->info->keep_hash,
				   h->root.root.string,
				   FALSE, FALSE) == NULL))
    strip = TRUE;
  else
    strip = FALSE;

  if (strip || h->written)
    return TRUE;

  if (h->abfd == NULL)
    {
      h->esym.jmptbl = 0;
      h->esym.cobol_main = 0;
      h->esym.weakext = 0;
      h->esym.reserved = 0;
      h->esym.ifd = ifdNil;
      h->esym.asym.value = 0;
      h->esym.asym.st = stGlobal;

      if (h->root.type != bfd_link_hash_defined
	  && h->root.type != bfd_link_hash_defweak)
	h->esym.asym.sc = scAbs;
      else
	{
	  asection *output_section;
	  const char *name;
	  unsigned int i;
	  static struct
	  {
	    const char * name;
	    int sc;
	  }
	  section_storage_classes [] =
	  {
	    { _TEXT,   scText   },
	    { _DATA,   scData   },
	    { _SDATA,  scSData  },
	    { _RDATA,  scRData  },
	    { _BSS,    scBss    },
	    { _SBSS,   scSBss   },
	    { _INIT,   scInit   },
	    { _FINI,   scFini   },
	    { _PDATA,  scPData  },
	    { _XDATA,  scXData  },
	    { _RCONST, scRConst }
	  };

	  output_section = h->root.u.def.section->output_section;
	  name = bfd_section_name (output_section->owner, output_section);

	  for (i = 0; i < ARRAY_SIZE (section_storage_classes); i++)
	    if (streq (name, section_storage_classes[i].name))
	      {
		h->esym.asym.sc = section_storage_classes[i].sc;
		break;
	      }

	  if (i == ARRAY_SIZE (section_storage_classes))
	    h->esym.asym.sc = scAbs;
	}

      h->esym.asym.reserved = 0;
      h->esym.asym.index = indexNil;
    }
  else if (h->esym.ifd != -1)
    {
      struct ecoff_debug_info *debug;

      /* Adjust the FDR index for the symbol by that used for the
	 input BFD.  */
      debug = &ecoff_data (h->abfd)->debug_info;
      BFD_ASSERT (h->esym.ifd >= 0
		  && h->esym.ifd < debug->symbolic_header.ifdMax);
      h->esym.ifd = debug->ifdmap[h->esym.ifd];
    }

  switch (h->root.type)
    {
    default:
    case bfd_link_hash_warning:
    case bfd_link_hash_new:
      abort ();
    case bfd_link_hash_undefined:
    case bfd_link_hash_undefweak:
      if (h->esym.asym.sc != scUndefined
	  && h->esym.asym.sc != scSUndefined)
	h->esym.asym.sc = scUndefined;
      break;
    case bfd_link_hash_defined:
    case bfd_link_hash_defweak:
      if (h->esym.asym.sc == scUndefined
	  || h->esym.asym.sc == scSUndefined)
	h->esym.asym.sc = scAbs;
      else if (h->esym.asym.sc == scCommon)
	h->esym.asym.sc = scBss;
      else if (h->esym.asym.sc == scSCommon)
	h->esym.asym.sc = scSBss;
      h->esym.asym.value = (h->root.u.def.value
			    + h->root.u.def.section->output_section->vma
			    + h->root.u.def.section->output_offset);
      break;
    case bfd_link_hash_common:
      if (h->esym.asym.sc != scCommon
	  && h->esym.asym.sc != scSCommon)
	h->esym.asym.sc = scCommon;
      h->esym.asym.value = h->root.u.c.size;
      break;
    case bfd_link_hash_indirect:
      /* We ignore these symbols, since the indirected symbol is
	 already in the hash table.  */
      return TRUE;
    }

  /* bfd_ecoff_debug_one_external uses iextMax to keep track of the
     symbol number.  */
  h->indx = ecoff_data (output_bfd)->debug_info.symbolic_header.iextMax;
  h->written = 1;

  return (bfd_ecoff_debug_one_external
	  (output_bfd, &ecoff_data (output_bfd)->debug_info,
	   &ecoff_backend (output_bfd)->debug_swap, h->root.root.string,
	   &h->esym));
}

/* ECOFF final link routine.  This looks through all the input BFDs
   and gathers together all the debugging information, and then
   processes all the link order information.  This may cause it to
   close and reopen some input BFDs; I'll see how bad this is.  */

bfd_boolean
_bfd_ecoff_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
{
  const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
  struct ecoff_debug_info * const debug = &ecoff_data (abfd)->debug_info;
  HDRR *symhdr;
  void * handle;
  bfd *input_bfd;
  asection *o;
  struct bfd_link_order *p;
  struct extsym_info einfo;

  /* We accumulate the debugging information counts in the symbolic
     header.  */
  symhdr = &debug->symbolic_header;
  symhdr->vstamp = 0;
  symhdr->ilineMax = 0;
  symhdr->cbLine = 0;
  symhdr->idnMax = 0;
  symhdr->ipdMax = 0;
  symhdr->isymMax = 0;
  symhdr->ioptMax = 0;
  symhdr->iauxMax = 0;
  symhdr->issMax = 0;
  symhdr->issExtMax = 0;
  symhdr->ifdMax = 0;
  symhdr->crfd = 0;
  symhdr->iextMax = 0;

  /* We accumulate the debugging information itself in the debug_info
     structure.  */
  debug->line = NULL;
  debug->external_dnr = NULL;
  debug->external_pdr = NULL;
  debug->external_sym = NULL;
  debug->external_opt = NULL;
  debug->external_aux = NULL;
  debug->ss = NULL;
  debug->ssext = debug->ssext_end = NULL;
  debug->external_fdr = NULL;
  debug->external_rfd = NULL;
  debug->external_ext = debug->external_ext_end = NULL;

  handle = bfd_ecoff_debug_init (abfd, debug, &backend->debug_swap, info);
  if (handle == NULL)
    return FALSE;

  /* Accumulate the debugging symbols from each input BFD.  */
  for (input_bfd = info->input_bfds;
       input_bfd != NULL;
       input_bfd = input_bfd->link.next)
    {
      bfd_boolean ret;

      if (bfd_get_flavour (input_bfd) == bfd_target_ecoff_flavour)
	{
	  /* Arbitrarily set the symbolic header vstamp to the vstamp
	     of the first object file in the link.  */
	  if (symhdr->vstamp == 0)
	    symhdr->vstamp
	      = ecoff_data (input_bfd)->debug_info.symbolic_header.vstamp;
	  ret = ecoff_final_link_debug_accumulate (abfd, input_bfd, info,
						   handle);
	}
      else
	ret = bfd_ecoff_debug_accumulate_other (handle, abfd,
						debug, &backend->debug_swap,
						input_bfd, info);
      if (! ret)
	return FALSE;

      /* Combine the register masks.  */
      ecoff_data (abfd)->gprmask |= ecoff_data (input_bfd)->gprmask;
      ecoff_data (abfd)->fprmask |= ecoff_data (input_bfd)->fprmask;
      ecoff_data (abfd)->cprmask[0] |= ecoff_data (input_bfd)->cprmask[0];
      ecoff_data (abfd)->cprmask[1] |= ecoff_data (input_bfd)->cprmask[1];
      ecoff_data (abfd)->cprmask[2] |= ecoff_data (input_bfd)->cprmask[2];
      ecoff_data (abfd)->cprmask[3] |= ecoff_data (input_bfd)->cprmask[3];
    }

  /* Write out the external symbols.  */
  einfo.abfd = abfd;
  einfo.info = info;
  bfd_hash_traverse (&info->hash->table, ecoff_link_write_external, &einfo);

  if (bfd_link_relocatable (info))
    {
      /* We need to make a pass over the link_orders to count up the
	 number of relocations we will need to output, so that we know
	 how much space they will take up.  */
      for (o = abfd->sections; o != NULL; o = o->next)
	{
	  o->reloc_count = 0;
	  for (p = o->map_head.link_order;
	       p != NULL;
	       p = p->next)
	    if (p->type == bfd_indirect_link_order)
	      o->reloc_count += p->u.indirect.section->reloc_count;
	    else if (p->type == bfd_section_reloc_link_order
		     || p->type == bfd_symbol_reloc_link_order)
	      ++o->reloc_count;
	}
    }

  /* Compute the reloc and symbol file positions.  */
  ecoff_compute_reloc_file_positions (abfd);

  /* Write out the debugging information.  */
  if (! bfd_ecoff_write_accumulated_debug (handle, abfd, debug,
					   &backend->debug_swap, info,
					   ecoff_data (abfd)->sym_filepos))
    return FALSE;

  bfd_ecoff_debug_free (handle, abfd, debug, &backend->debug_swap, info);

  if (bfd_link_relocatable (info))
    {
      /* Now reset the reloc_count field of the sections in the output
	 BFD to 0, so that we can use them to keep track of how many
	 relocs we have output thus far.  */
      for (o = abfd->sections; o != NULL; o = o->next)
	o->reloc_count = 0;
    }

  /* Get a value for the GP register.  */
  if (ecoff_data (abfd)->gp == 0)
    {
      struct bfd_link_hash_entry *h;

      h = bfd_link_hash_lookup (info->hash, "_gp", FALSE, FALSE, TRUE);
      if (h != NULL
	  && h->type == bfd_link_hash_defined)
	ecoff_data (abfd)->gp = (h->u.def.value
				 + h->u.def.section->output_section->vma
				 + h->u.def.section->output_offset);
      else if (bfd_link_relocatable (info))
	{
	  bfd_vma lo;

	  /* Make up a value.  */
	  lo = (bfd_vma) -1;
	  for (o = abfd->sections; o != NULL; o = o->next)
	    {
	      if (o->vma < lo
		  && (streq (o->name, _SBSS)
		      || streq (o->name, _SDATA)
		      || streq (o->name, _LIT4)
		      || streq (o->name, _LIT8)
		      || streq (o->name, _LITA)))
		lo = o->vma;
	    }
	  ecoff_data (abfd)->gp = lo + 0x8000;
	}
      else
	{
	  /* If the relocate_section function needs to do a reloc
	     involving the GP value, it should make a reloc_dangerous
	     callback to warn that GP is not defined.  */
	}
    }

  for (o = abfd->sections; o != NULL; o = o->next)
    {
      for (p = o->map_head.link_order;
	   p != NULL;
	   p = p->next)
	{
	  if (p->type == bfd_indirect_link_order
	      && (bfd_get_flavour (p->u.indirect.section->owner)
		  == bfd_target_ecoff_flavour))
	    {
	      if (! ecoff_indirect_link_order (abfd, info, o, p))
		return FALSE;
	    }
	  else if (p->type == bfd_section_reloc_link_order
		   || p->type == bfd_symbol_reloc_link_order)
	    {
	      if (! ecoff_reloc_link_order (abfd, info, o, p))
		return FALSE;
	    }
	  else
	    {
	      if (! _bfd_default_link_order (abfd, info, o, p))
		return FALSE;
	    }
	}
    }

  bfd_get_symcount (abfd) = symhdr->iextMax + symhdr->isymMax;

  ecoff_data (abfd)->linker = TRUE;

  return TRUE;
}
