/* Generic ECOFF (Extended-COFF) routines.
   Copyright (C) 1990-2022 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 "ecoff-bfd.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)


/* This stuff is somewhat copied from coffcode.h.  */
static asection bfd_debug_section =
  BFD_FAKE_SECTION (bfd_debug_section, NULL, "*DEBUG*", 0, 0);

/* Create an ECOFF object.  */

bool
_bfd_ecoff_mkobject (bfd *abfd)
{
  size_t 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.  */

bool
_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 | SEC_SMALL_DATA },
    { _RDATA,  SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY},
    { _LIT8,   SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY | SEC_SMALL_DATA},
    { _LIT4,   SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY | SEC_SMALL_DATA},
    { _RCONST, SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY},
    { _PDATA,  SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY},
    { _BSS,    SEC_ALLOC},
    { _SBSS,   SEC_ALLOC | SEC_SMALL_DATA},
    /* 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);
}

void
_bfd_ecoff_set_alignment_hook (bfd *abfd ATTRIBUTE_UNUSED,
			       asection *section ATTRIBUTE_UNUSED,
			       void *scnhdr ATTRIBUTE_UNUSED)
{
}

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

bool
_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);
}

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

bool
_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;
      if (styp_flags & STYP_SDATA)
	sec_flags |= SEC_SMALL_DATA;
    }
  else if (styp_flags & STYP_SBSS)
    sec_flags |= SEC_ALLOC | SEC_SMALL_DATA;
  else if (styp_flags & STYP_BSS)
    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_SMALL_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 bool
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)
    {
      abfd->symcount = 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.  */
  if (bfd_seek (abfd, ecoff_data (abfd)->sym_filepos, SEEK_SET) != 0)
    goto error_return;
  raw = _bfd_malloc_and_read (abfd, external_hdr_size, external_hdr_size);
  if (raw == NULL)
    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.  */
  abfd->symcount = internal_symhdr->isymMax + internal_symhdr->iextMax;

  free (raw);
  return true;
 error_return:
  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.  */

bool
_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;
  size_t amt;

  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)
    {
      abfd->symcount = 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;
    }
  pos = ecoff_data (abfd)->sym_filepos;
  pos += backend->debug_swap.external_hdr_size;
  if (bfd_seek (abfd, pos, SEEK_SET) != 0)
    return false;
  raw = _bfd_alloc_and_read (abfd, raw_size, raw_size);
  if (raw == NULL)
    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.  */
  if (_bfd_mul_overflow ((unsigned long) internal_symhdr->ifdMax,
			 sizeof (struct fdr), &amt))
    {
      bfd_set_error (bfd_error_file_too_big);
      return false;
    }
  debug->fdr = (FDR *) bfd_alloc (abfd, amt);
  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 const asymbol ecoff_scom_symbol =
  GLOBAL_SYM_INIT (SCOMMON, &ecoff_scom_section);
static asection ecoff_scom_section =
  BFD_FAKE_SECTION (ecoff_scom_section, &ecoff_scom_symbol,
		    SCOMMON, 0, SEC_IS_COMMON | SEC_SMALL_DATA);

/* Create an empty symbol.  */

asymbol *
_bfd_ecoff_make_empty_symbol (bfd *abfd)
{
  ecoff_symbol_type *new_symbol;
  size_t 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 bool
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:
      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.  */

bool
_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;
  size_t amt;

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

  if (_bfd_mul_overflow (bfd_get_symcount (abfd),
			 sizeof (ecoff_symbol_type), &amt))
    {
      bfd_set_error (bfd_error_file_too_big);
      return false;
    }
  internal = (ecoff_symbol_type *) bfd_alloc (abfd, amt);
  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))
    {
      abfd->symcount = internal_ptr - internal;
      _bfd_error_handler
	/* xgettext:c-format */
	(_("%pB: warning: isymMax (%ld) is greater than ifdMax (%ld)"),
	 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, char *buff)
{
  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];
  char *p1 = buffer1;
  char *p2 = buff;
  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 (p1);

  /* 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);
    }

  /* 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 buff;
}

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

bool
_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 ");
	  bfd_fprintf_vma (abfd, file, 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 ");
	  bfd_fprintf_vma (abfd, file, 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);
	bfd_fprintf_vma (abfd, file, 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)
		  {
		    char buff[1024];
		    /* 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, buff));
		  }
		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))
		  {
		    char buff[1024];
		    fprintf (file, _("\n      Type: %s"),
			     ecoff_type_to_string (abfd, fdr, indx, buff));
		  }
		break;
	      }
	  }
      }
      break;
    }
}

/* Read in the relocs for a section.  */

static bool
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;
  bfd_byte *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;

  external_reloc_size = backend->external_reloc_size;
  amt = external_reloc_size * section->reloc_count;
  if (bfd_seek (abfd, section->rel_filepos, SEEK_SET) != 0)
    return false;
  external_relocs = _bfd_malloc_and_read (abfd, amt, amt);
  if (external_relocs == NULL)
    return false;

  amt = section->reloc_count;
  amt *= sizeof (arelent);
  internal_relocs = (arelent *) bfd_alloc (abfd, amt);
  if (internal_relocs == NULL)
    {
      free (external_relocs);
      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);
      rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
      rptr->addend = 0;

      if (intern.r_extern)
	{
	  /* r_symndx is an index into the external symbols.  */
	  if (symbols != NULL
	      && intern.r_symndx >= 0
	      && (intern.r_symndx
		  < (ecoff_data (abfd)->debug_info.symbolic_header.iextMax)))
	    rptr->sym_ptr_ptr = symbols + intern.r_symndx;
	}
      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:
	      sec_name = NULL;
	      break;
	    }

	  if (sec_name != NULL)
	    {
	      sec = bfd_get_section_by_name (abfd, sec_name);
	      if (sec != NULL)
		{
		  rptr->sym_ptr_ptr = sec->symbol_ptr_ptr;
		  rptr->addend = - bfd_section_vma (sec);
		}
	    }
	}

      rptr->address = intern.r_vaddr - bfd_section_vma (section);

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

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

bool
_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)
    {
      size_t 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.  */

bool
_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;
  bool 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.  */

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

bool
_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 bool
ecoff_compute_section_file_positions (bfd *abfd)
{
  file_ptr sofar, file_sofar;
  asection **sorted_hdrs;
  asection *current;
  unsigned int i;
  file_ptr old_sofar;
  bool rdata_in_text;
  bool 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.  */

bool
_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;
}

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

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

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

bool
_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;
  bool set_text_start;
  bfd_size_type data_size;
  bfd_vma data_start;
  bool 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_section_vma (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_zalloc (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_section_vma (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_section_name (bfd_asymbol_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);
  free (buff);
  return true;
 error_return:
  if (reloc_buff != NULL)
    bfd_release (abfd, reloc_buff);
  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.  */

bool
_bfd_ecoff_slurp_armap (bfd *abfd)
{
  char nextname[17];
  unsigned int i;
  struct areltdata *mapdata;
  bfd_size_type parsed_size, stringsize;
  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 (startswith (nextname, "/               "))
    return bfd_slurp_armap (abfd);

  /* See if the first element is an armap.  */
  if (strncmp (nextname, ecoff_backend (abfd)->armap_start, ARMAP_START_LENGTH) != 0
      || 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)
      || strncmp (nextname + ARMAP_END_INDEX, ARMAP_END, sizeof ARMAP_END - 1) != 0)
    {
      abfd->has_armap = 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);

  if (parsed_size + 1 < 9)
    {
      bfd_set_error (bfd_error_malformed_archive);
      return false;
    }

  raw_armap = (char *) _bfd_alloc_and_read (abfd, parsed_size + 1, parsed_size);
  if (raw_armap == NULL)
    return false;
  raw_armap[parsed_size] = 0;

  ardata->tdata = (void *) raw_armap;

  count = H_GET_32 (abfd, raw_armap);
  if ((parsed_size - 8) / 8 < count)
    goto error_malformed;

  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;
  stringsize = parsed_size - (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)
    goto error_exit;

  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);
      if (name_offset > stringsize)
	goto error_malformed;
      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;
  abfd->has_armap = true;
  return true;

 error_malformed:
  bfd_set_error (bfd_error_malformed_archive);
 error_exit:
  ardata->symdef_count = 0;
  ardata->symdefs = NULL;
  ardata->tdata = NULL;
  bfd_release (abfd, raw_armap);
  return false;
}

/* Write out an armap.  */

bool
_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 (bfd_get_filename (abfd), &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;
  size_t 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 bool
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;
      bool 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:
	  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 bool
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;
  bool 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.  */
  if (bfd_seek (abfd, symhdr->cbExtOffset, SEEK_SET) != 0)
    return false;
  external_ext_size = ecoff_backend (abfd)->debug_swap.external_ext_size;
  esize = symhdr->iextMax * external_ext_size;
  external_ext = _bfd_malloc_and_read (abfd, esize, esize);
  if (external_ext == NULL && esize != 0)
    goto error_return;

  if (bfd_seek (abfd, symhdr->cbSsExtOffset, SEEK_SET) != 0)
    goto error_return;
  ssext = (char *) _bfd_malloc_and_read (abfd, symhdr->issExtMax,
					 symhdr->issExtMax);
  if (ssext == NULL && symhdr->issExtMax != 0)
    goto error_return;

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

  free (ssext);
  free (external_ext);
  return result;

 error_return:
  free (ssext);
  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 bool
ecoff_link_check_archive_element (bfd *abfd,
				  struct bfd_link_info *info,
				  struct bfd_link_hash_entry *h,
				  const char *name,
				  bool *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 bool
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;
	  bool 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,
						info);
      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.  */

bool
_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 bool
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;
  bool ret;

#define READ(ptr, offset, count, size, type)				\
  do									\
    {									\
      size_t amt;							\
      debug->ptr = NULL;						\
      if (symhdr->count == 0)						\
	break;								\
      if (_bfd_mul_overflow (size, symhdr->count, &amt))		\
	{								\
	  bfd_set_error (bfd_error_file_too_big);			\
	  ret = false;							\
	  goto return_something;					\
	}								\
      if (bfd_seek (input_bfd, symhdr->offset, SEEK_SET) != 0)		\
	{								\
	  ret = false;							\
	  goto return_something;					\
	}								\
      debug->ptr = (type) _bfd_malloc_and_read (input_bfd, amt, amt);	\
      if (debug->ptr == NULL)						\
	{								\
	  ret = false;							\
	  goto return_something;					\
	}								\
    } while (0)

  /* 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)
    {
      free (debug->line);
      free (debug->external_dnr);
      free (debug->external_pdr);
      free (debug->external_sym);
      free (debug->external_opt);
      free (debug->external_aux);
      free (debug->ss);
      free (debug->external_fdr);
      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 bool
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;

  if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0)
    goto error_return;
  external_relocs = _bfd_malloc_and_read (input_bfd, external_relocs_size,
					  external_relocs_size);
  if (external_relocs == NULL && external_relocs_size != 0)
    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;
    }

  free (contents);
  free (external_relocs);
  return true;

 error_return:
  free (contents);
  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 bool
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;
  bool 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 (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_section_vma (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_section_name (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 bool
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;
  bool 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);

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

bool
_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)
    {
      bool 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;
	    }
	}
    }

  abfd->symcount = symhdr->iextMax + symhdr->isymMax;

  ecoff_data (abfd)->linker = true;

  return true;
}
