/* Routines to link ECOFF debugging information.
   Copyright (C) 1993-2016 Free Software Foundation, Inc.
   Written by Ian Lance Taylor, Cygnus Support, <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 "objalloc.h"
#include "aout/stab_gnu.h"
#include "coff/internal.h"
#include "coff/sym.h"
#include "coff/symconst.h"
#include "coff/ecoff.h"
#include "libcoff.h"
#include "libecoff.h"

/* Routines to swap auxiliary information in and out.  I am assuming
   that the auxiliary information format is always going to be target
   independent.  */

/* Swap in a type information record.
   BIGEND says whether AUX symbols are big-endian or little-endian; this
   info comes from the file header record (fh-fBigendian).  */

void
_bfd_ecoff_swap_tir_in (int bigend, const struct tir_ext *ext_copy,
			TIR *intern)
{
  struct tir_ext ext[1];

  *ext = *ext_copy;		/* Make it reasonable to do in-place.  */

  /* now the fun stuff...  */
  if (bigend)
    {
      intern->fBitfield   = 0 != (ext->t_bits1[0] & TIR_BITS1_FBITFIELD_BIG);
      intern->continued   = 0 != (ext->t_bits1[0] & TIR_BITS1_CONTINUED_BIG);
      intern->bt          = (ext->t_bits1[0] & TIR_BITS1_BT_BIG)
                          >>                   TIR_BITS1_BT_SH_BIG;
      intern->tq4         = (ext->t_tq45[0] & TIR_BITS_TQ4_BIG)
			  >>		      TIR_BITS_TQ4_SH_BIG;
      intern->tq5         = (ext->t_tq45[0] & TIR_BITS_TQ5_BIG)
			  >>		      TIR_BITS_TQ5_SH_BIG;
      intern->tq0         = (ext->t_tq01[0] & TIR_BITS_TQ0_BIG)
			  >>		      TIR_BITS_TQ0_SH_BIG;
      intern->tq1         = (ext->t_tq01[0] & TIR_BITS_TQ1_BIG)
			  >>		      TIR_BITS_TQ1_SH_BIG;
      intern->tq2         = (ext->t_tq23[0] & TIR_BITS_TQ2_BIG)
			  >>		      TIR_BITS_TQ2_SH_BIG;
      intern->tq3         = (ext->t_tq23[0] & TIR_BITS_TQ3_BIG)
			  >>		      TIR_BITS_TQ3_SH_BIG;
    }
  else
    {
      intern->fBitfield   = 0 != (ext->t_bits1[0] & TIR_BITS1_FBITFIELD_LITTLE);
      intern->continued   = 0 != (ext->t_bits1[0] & TIR_BITS1_CONTINUED_LITTLE);
      intern->bt          = (ext->t_bits1[0] & TIR_BITS1_BT_LITTLE)
			  >>		    TIR_BITS1_BT_SH_LITTLE;
      intern->tq4         = (ext->t_tq45[0] & TIR_BITS_TQ4_LITTLE)
			  >>		    TIR_BITS_TQ4_SH_LITTLE;
      intern->tq5         = (ext->t_tq45[0] & TIR_BITS_TQ5_LITTLE)
			  >>		    TIR_BITS_TQ5_SH_LITTLE;
      intern->tq0         = (ext->t_tq01[0] & TIR_BITS_TQ0_LITTLE)
			  >>		    TIR_BITS_TQ0_SH_LITTLE;
      intern->tq1         = (ext->t_tq01[0] & TIR_BITS_TQ1_LITTLE)
			  >>		    TIR_BITS_TQ1_SH_LITTLE;
      intern->tq2         = (ext->t_tq23[0] & TIR_BITS_TQ2_LITTLE)
			  >>		    TIR_BITS_TQ2_SH_LITTLE;
      intern->tq3         = (ext->t_tq23[0] & TIR_BITS_TQ3_LITTLE)
			  >>		    TIR_BITS_TQ3_SH_LITTLE;
    }

#ifdef TEST
  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
    abort ();
#endif
}

/* Swap out a type information record.
   BIGEND says whether AUX symbols are big-endian or little-endian; this
   info comes from the file header record (fh-fBigendian).  */

void
_bfd_ecoff_swap_tir_out (int bigend,
			 const TIR *intern_copy,
			 struct tir_ext *ext)
{
  TIR intern[1];

  *intern = *intern_copy;	/* Make it reasonable to do in-place.  */

  /* now the fun stuff...  */
  if (bigend)
    {
      ext->t_bits1[0] = ((intern->fBitfield ? TIR_BITS1_FBITFIELD_BIG : 0)
		       | (intern->continued ? TIR_BITS1_CONTINUED_BIG : 0)
		       | ((intern->bt << TIR_BITS1_BT_SH_BIG)
			  & TIR_BITS1_BT_BIG));
      ext->t_tq45[0] = (((intern->tq4 << TIR_BITS_TQ4_SH_BIG)
		       & TIR_BITS_TQ4_BIG)
		      | ((intern->tq5 << TIR_BITS_TQ5_SH_BIG)
			 & TIR_BITS_TQ5_BIG));
      ext->t_tq01[0] = (((intern->tq0 << TIR_BITS_TQ0_SH_BIG)
		       & TIR_BITS_TQ0_BIG)
		      | ((intern->tq1 << TIR_BITS_TQ1_SH_BIG)
			 & TIR_BITS_TQ1_BIG));
      ext->t_tq23[0] = (((intern->tq2 << TIR_BITS_TQ2_SH_BIG)
		       & TIR_BITS_TQ2_BIG)
		      | ((intern->tq3 << TIR_BITS_TQ3_SH_BIG)
			 & TIR_BITS_TQ3_BIG));
    }
  else
    {
      ext->t_bits1[0] = ((intern->fBitfield ? TIR_BITS1_FBITFIELD_LITTLE : 0)
		       | (intern->continued ? TIR_BITS1_CONTINUED_LITTLE : 0)
		       | ((intern->bt << TIR_BITS1_BT_SH_LITTLE)
			  & TIR_BITS1_BT_LITTLE));
      ext->t_tq45[0] = (((intern->tq4 << TIR_BITS_TQ4_SH_LITTLE)
		       & TIR_BITS_TQ4_LITTLE)
		      | ((intern->tq5 << TIR_BITS_TQ5_SH_LITTLE)
			 & TIR_BITS_TQ5_LITTLE));
      ext->t_tq01[0] = (((intern->tq0 << TIR_BITS_TQ0_SH_LITTLE)
		       & TIR_BITS_TQ0_LITTLE)
		      | ((intern->tq1 << TIR_BITS_TQ1_SH_LITTLE)
			 & TIR_BITS_TQ1_LITTLE));
      ext->t_tq23[0] = (((intern->tq2 << TIR_BITS_TQ2_SH_LITTLE)
		       & TIR_BITS_TQ2_LITTLE)
		      | ((intern->tq3 << TIR_BITS_TQ3_SH_LITTLE)
			 & TIR_BITS_TQ3_LITTLE));
    }

#ifdef TEST
  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
    abort ();
#endif
}

/* Swap in a relative symbol record.  BIGEND says whether it is in
   big-endian or little-endian format.*/

void
_bfd_ecoff_swap_rndx_in (int bigend,
			 const struct rndx_ext *ext_copy,
			 RNDXR *intern)
{
  struct rndx_ext ext[1];

  *ext = *ext_copy;		/* Make it reasonable to do in-place.  */

  /* now the fun stuff...  */
  if (bigend)
    {
      intern->rfd   = (ext->r_bits[0] << RNDX_BITS0_RFD_SH_LEFT_BIG)
		  | ((ext->r_bits[1] & RNDX_BITS1_RFD_BIG)
		    		    >> RNDX_BITS1_RFD_SH_BIG);
      intern->index = ((ext->r_bits[1] & RNDX_BITS1_INDEX_BIG)
		    		    << RNDX_BITS1_INDEX_SH_LEFT_BIG)
		  | (ext->r_bits[2] << RNDX_BITS2_INDEX_SH_LEFT_BIG)
		  | (ext->r_bits[3] << RNDX_BITS3_INDEX_SH_LEFT_BIG);
    }
  else
    {
      intern->rfd   = (ext->r_bits[0] << RNDX_BITS0_RFD_SH_LEFT_LITTLE)
		  | ((ext->r_bits[1] & RNDX_BITS1_RFD_LITTLE)
		    		    << RNDX_BITS1_RFD_SH_LEFT_LITTLE);
      intern->index = ((ext->r_bits[1] & RNDX_BITS1_INDEX_LITTLE)
		    		    >> RNDX_BITS1_INDEX_SH_LITTLE)
		  | (ext->r_bits[2] << RNDX_BITS2_INDEX_SH_LEFT_LITTLE)
		  | ((unsigned int) ext->r_bits[3]
		     << RNDX_BITS3_INDEX_SH_LEFT_LITTLE);
    }

#ifdef TEST
  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
    abort ();
#endif
}

/* Swap out a relative symbol record.  BIGEND says whether it is in
   big-endian or little-endian format.*/

void
_bfd_ecoff_swap_rndx_out (int bigend,
			  const RNDXR *intern_copy,
			  struct rndx_ext *ext)
{
  RNDXR intern[1];

  *intern = *intern_copy;	/* Make it reasonable to do in-place.  */

  /* now the fun stuff...  */
  if (bigend)
    {
      ext->r_bits[0] = intern->rfd >> RNDX_BITS0_RFD_SH_LEFT_BIG;
      ext->r_bits[1] = (((intern->rfd << RNDX_BITS1_RFD_SH_BIG)
		       & RNDX_BITS1_RFD_BIG)
		      | ((intern->index >> RNDX_BITS1_INDEX_SH_LEFT_BIG)
			 & RNDX_BITS1_INDEX_BIG));
      ext->r_bits[2] = intern->index >> RNDX_BITS2_INDEX_SH_LEFT_BIG;
      ext->r_bits[3] = intern->index >> RNDX_BITS3_INDEX_SH_LEFT_BIG;
    }
  else
    {
      ext->r_bits[0] = intern->rfd >> RNDX_BITS0_RFD_SH_LEFT_LITTLE;
      ext->r_bits[1] = (((intern->rfd >> RNDX_BITS1_RFD_SH_LEFT_LITTLE)
		       & RNDX_BITS1_RFD_LITTLE)
		      | ((intern->index << RNDX_BITS1_INDEX_SH_LITTLE)
			 & RNDX_BITS1_INDEX_LITTLE));
      ext->r_bits[2] = intern->index >> RNDX_BITS2_INDEX_SH_LEFT_LITTLE;
      ext->r_bits[3] = intern->index >> RNDX_BITS3_INDEX_SH_LEFT_LITTLE;
    }

#ifdef TEST
  if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0)
    abort ();
#endif
}

/* The minimum amount of data to allocate.  */
#define ALLOC_SIZE (4064)

/* Add bytes to a buffer.  Return success.  */

static bfd_boolean
ecoff_add_bytes (char **buf, char **bufend, size_t need)
{
  size_t have;
  size_t want;
  char *newbuf;

  have = *bufend - *buf;
  if (have > need)
    want = ALLOC_SIZE;
  else
    {
      want = need - have;
      if (want < ALLOC_SIZE)
	want = ALLOC_SIZE;
    }
  newbuf = (char *) bfd_realloc (*buf, (bfd_size_type) have + want);
  if (newbuf == NULL)
    return FALSE;
  *buf = newbuf;
  *bufend = *buf + have + want;
  return TRUE;
}

/* We keep a hash table which maps strings to numbers.  We use it to
   map FDR names to indices in the output file, and to map local
   strings when combining stabs debugging information.  */

struct string_hash_entry
{
  struct bfd_hash_entry root;
  /* FDR index or string table offset.  */
  long val;
  /* Next entry in string table.  */
  struct string_hash_entry *next;
};

struct string_hash_table
{
  struct bfd_hash_table table;
};

/* Routine to create an entry in a string hash table.  */

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

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

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

  if (ret)
    {
      /* Initialize the local fields.  */
      ret->val = -1;
      ret->next = NULL;
    }

  return (struct bfd_hash_entry *) ret;
}

/* Look up an entry in an string hash table.  */

#define string_hash_lookup(t, string, create, copy) \
  ((struct string_hash_entry *) \
   bfd_hash_lookup (&(t)->table, (string), (create), (copy)))

/* We can't afford to read in all the debugging information when we do
   a link.  Instead, we build a list of these structures to show how
   different parts of the input file map to the output file.  */

struct shuffle
{
  /* The next entry in this linked list.  */
  struct shuffle *next;
  /* The length of the information.  */
  unsigned long size;
  /* Whether this information comes from a file or not.  */
  bfd_boolean filep;
  union
    {
      struct
	{
	  /* The BFD the data comes from.  */
	  bfd *input_bfd;
	  /* The offset within input_bfd.  */
	  file_ptr offset;
	} file;
      /* The data to be written out.  */
      void * memory;
    } u;
};

/* This structure holds information across calls to
   bfd_ecoff_debug_accumulate.  */

struct accumulate
{
  /* The FDR hash table.  */
  struct string_hash_table fdr_hash;
  /* The strings hash table.  */
  struct string_hash_table str_hash;
  /* Linked lists describing how to shuffle the input debug
     information into the output file.  We keep a pointer to both the
     head and the tail.  */
  struct shuffle *line;
  struct shuffle *line_end;
  struct shuffle *pdr;
  struct shuffle *pdr_end;
  struct shuffle *sym;
  struct shuffle *sym_end;
  struct shuffle *opt;
  struct shuffle *opt_end;
  struct shuffle *aux;
  struct shuffle *aux_end;
  struct shuffle *ss;
  struct shuffle *ss_end;
  struct string_hash_entry *ss_hash;
  struct string_hash_entry *ss_hash_end;
  struct shuffle *fdr;
  struct shuffle *fdr_end;
  struct shuffle *rfd;
  struct shuffle *rfd_end;
  /* The size of the largest file shuffle.  */
  unsigned long largest_file_shuffle;
  /* An objalloc for debugging information.  */
  struct objalloc *memory;
};

/* Add a file entry to a shuffle list.  */

static bfd_boolean
add_file_shuffle (struct accumulate *ainfo,
		  struct shuffle **head,
		  struct shuffle **tail,
		  bfd *input_bfd,
		  file_ptr offset,
		  unsigned long size)
{
  struct shuffle *n;

  if (*tail != (struct shuffle *) NULL
      && (*tail)->filep
      && (*tail)->u.file.input_bfd == input_bfd
      && (*tail)->u.file.offset + (*tail)->size == (unsigned long) offset)
    {
      /* Just merge this entry onto the existing one.  */
      (*tail)->size += size;
      if ((*tail)->size > ainfo->largest_file_shuffle)
	ainfo->largest_file_shuffle = (*tail)->size;
      return TRUE;
    }

  n = (struct shuffle *) objalloc_alloc (ainfo->memory,
					 sizeof (struct shuffle));
  if (!n)
    {
      bfd_set_error (bfd_error_no_memory);
      return FALSE;
    }
  n->next = NULL;
  n->size = size;
  n->filep = TRUE;
  n->u.file.input_bfd = input_bfd;
  n->u.file.offset = offset;
  if (*head == (struct shuffle *) NULL)
    *head = n;
  if (*tail != (struct shuffle *) NULL)
    (*tail)->next = n;
  *tail = n;
  if (size > ainfo->largest_file_shuffle)
    ainfo->largest_file_shuffle = size;
  return TRUE;
}

/* Add a memory entry to a shuffle list.  */

static bfd_boolean
add_memory_shuffle (struct accumulate *ainfo,
		    struct shuffle **head,
		    struct shuffle **tail,
		    bfd_byte *data,
		    unsigned long size)
{
  struct shuffle *n;

  n = (struct shuffle *) objalloc_alloc (ainfo->memory,
					 sizeof (struct shuffle));
  if (!n)
    {
      bfd_set_error (bfd_error_no_memory);
      return FALSE;
    }
  n->next = NULL;
  n->size = size;
  n->filep = FALSE;
  n->u.memory = data;
  if (*head == (struct shuffle *) NULL)
    *head = n;
  if (*tail != (struct shuffle *) NULL)
    (*tail)->next = n;
  *tail = n;
  return TRUE;
}

/* Initialize the FDR hash table.  This returns a handle which is then
   passed in to bfd_ecoff_debug_accumulate, et. al.  */

void *
bfd_ecoff_debug_init (bfd *output_bfd ATTRIBUTE_UNUSED,
		      struct ecoff_debug_info *output_debug,
		      const struct ecoff_debug_swap *output_swap ATTRIBUTE_UNUSED,
		      struct bfd_link_info *info)
{
  struct accumulate *ainfo;
  bfd_size_type amt = sizeof (struct accumulate);

  ainfo = (struct accumulate *) bfd_malloc (amt);
  if (!ainfo)
    return NULL;
  if (!bfd_hash_table_init_n (&ainfo->fdr_hash.table, string_hash_newfunc,
			      sizeof (struct string_hash_entry), 1021))
    return NULL;

  ainfo->line = NULL;
  ainfo->line_end = NULL;
  ainfo->pdr = NULL;
  ainfo->pdr_end = NULL;
  ainfo->sym = NULL;
  ainfo->sym_end = NULL;
  ainfo->opt = NULL;
  ainfo->opt_end = NULL;
  ainfo->aux = NULL;
  ainfo->aux_end = NULL;
  ainfo->ss = NULL;
  ainfo->ss_end = NULL;
  ainfo->ss_hash = NULL;
  ainfo->ss_hash_end = NULL;
  ainfo->fdr = NULL;
  ainfo->fdr_end = NULL;
  ainfo->rfd = NULL;
  ainfo->rfd_end = NULL;

  ainfo->largest_file_shuffle = 0;

  if (! bfd_link_relocatable (info))
    {
      if (!bfd_hash_table_init (&ainfo->str_hash.table, string_hash_newfunc,
				sizeof (struct string_hash_entry)))
	return NULL;

      /* The first entry in the string table is the empty string.  */
      output_debug->symbolic_header.issMax = 1;
    }

  ainfo->memory = objalloc_create ();
  if (ainfo->memory == NULL)
    {
      bfd_set_error (bfd_error_no_memory);
      return NULL;
    }

  return ainfo;
}

/* Free the accumulated debugging information.  */

void
bfd_ecoff_debug_free (void * handle,
		      bfd *output_bfd ATTRIBUTE_UNUSED,
		      struct ecoff_debug_info *output_debug ATTRIBUTE_UNUSED,
		      const struct ecoff_debug_swap *output_swap ATTRIBUTE_UNUSED,
		      struct bfd_link_info *info)
{
  struct accumulate *ainfo = (struct accumulate *) handle;

  bfd_hash_table_free (&ainfo->fdr_hash.table);

  if (! bfd_link_relocatable (info))
    bfd_hash_table_free (&ainfo->str_hash.table);

  objalloc_free (ainfo->memory);

  free (ainfo);
}

/* Accumulate the debugging information from INPUT_BFD into
   OUTPUT_BFD.  The INPUT_DEBUG argument points to some ECOFF
   debugging information which we want to link into the information
   pointed to by the OUTPUT_DEBUG argument.  OUTPUT_SWAP and
   INPUT_SWAP point to the swapping information needed.  INFO is the
   linker information structure.  HANDLE is returned by
   bfd_ecoff_debug_init.  */

bfd_boolean
bfd_ecoff_debug_accumulate (void * handle,
			    bfd *output_bfd,
			    struct ecoff_debug_info *output_debug,
			    const struct ecoff_debug_swap *output_swap,
			    bfd *input_bfd,
			    struct ecoff_debug_info *input_debug,
			    const struct ecoff_debug_swap *input_swap,
			    struct bfd_link_info *info)
{
  struct accumulate *ainfo = (struct accumulate *) handle;
  void (* const swap_sym_in) (bfd *, void *, SYMR *)
    = input_swap->swap_sym_in;
  void (* const swap_rfd_in) (bfd *, void *, RFDT *)
    = input_swap->swap_rfd_in;
  void (* const swap_sym_out) (bfd *, const SYMR *, void *)
    = output_swap->swap_sym_out;
  void (* const swap_fdr_out) (bfd *, const FDR *, void *)
    = output_swap->swap_fdr_out;
  void (* const swap_rfd_out) (bfd *, const RFDT *, void *)
    = output_swap->swap_rfd_out;
  bfd_size_type external_pdr_size = output_swap->external_pdr_size;
  bfd_size_type external_sym_size = output_swap->external_sym_size;
  bfd_size_type external_opt_size = output_swap->external_opt_size;
  bfd_size_type external_fdr_size = output_swap->external_fdr_size;
  bfd_size_type external_rfd_size = output_swap->external_rfd_size;
  HDRR * const output_symhdr = &output_debug->symbolic_header;
  HDRR * const input_symhdr = &input_debug->symbolic_header;
  bfd_vma section_adjust[scMax];
  asection *sec;
  bfd_byte *fdr_start;
  bfd_byte *fdr_ptr;
  bfd_byte *fdr_end;
  bfd_size_type fdr_add;
  unsigned int copied;
  RFDT i;
  unsigned long sz;
  bfd_byte *rfd_out;
  bfd_byte *rfd_in;
  bfd_byte *rfd_end;
  long newrfdbase = 0;
  long oldrfdbase = 0;
  bfd_byte *fdr_out;
  bfd_size_type amt;

  /* Use section_adjust to hold the value to add to a symbol in a
     particular section.  */
  memset (section_adjust, 0, sizeof section_adjust);

#define SET(name, indx) \
  sec = bfd_get_section_by_name (input_bfd, name); \
  if (sec != NULL) \
    section_adjust[indx] = (sec->output_section->vma \
			    + sec->output_offset \
			    - sec->vma);

  SET (".text", scText);
  SET (".data", scData);
  SET (".bss", scBss);
  SET (".sdata", scSData);
  SET (".sbss", scSBss);
  /* scRdata section may be either .rdata or .rodata.  */
  SET (".rdata", scRData);
  SET (".rodata", scRData);
  SET (".init", scInit);
  SET (".fini", scFini);
  SET (".rconst", scRConst);

#undef SET

  /* Find all the debugging information based on the FDR's.  We need
     to handle them whether they are swapped or not.  */
  if (input_debug->fdr != (FDR *) NULL)
    {
      fdr_start = (bfd_byte *) input_debug->fdr;
      fdr_add = sizeof (FDR);
    }
  else
    {
      fdr_start = (bfd_byte *) input_debug->external_fdr;
      fdr_add = input_swap->external_fdr_size;
    }
  fdr_end = fdr_start + input_symhdr->ifdMax * fdr_add;

  amt = input_symhdr->ifdMax;
  amt *= sizeof (RFDT);
  input_debug->ifdmap = (RFDT *) bfd_alloc (input_bfd, amt);

  sz = (input_symhdr->crfd + input_symhdr->ifdMax) * external_rfd_size;
  rfd_out = (bfd_byte *) objalloc_alloc (ainfo->memory, sz);
  if (!input_debug->ifdmap || !rfd_out)
    {
      bfd_set_error (bfd_error_no_memory);
      return FALSE;
    }
  if (!add_memory_shuffle (ainfo, &ainfo->rfd, &ainfo->rfd_end, rfd_out, sz))
    return FALSE;

  copied = 0;

  /* Look through the FDR's to see which ones we are going to include
     in the final output.  We do not want duplicate FDR information
     for header files, because ECOFF debugging is often very large.
     When we find an FDR with no line information which can be merged,
     we look it up in a hash table to ensure that we only include it
     once.  We keep a table mapping FDR numbers to the final number
     they get with the BFD, so that we can refer to it when we write
     out the external symbols.  */
  for (fdr_ptr = fdr_start, i = 0;
       fdr_ptr < fdr_end;
       fdr_ptr += fdr_add, i++, rfd_out += external_rfd_size)
    {
      FDR fdr;

      if (input_debug->fdr != (FDR *) NULL)
	fdr = *(FDR *) fdr_ptr;
      else
	(*input_swap->swap_fdr_in) (input_bfd, fdr_ptr, &fdr);

      /* See if this FDR can be merged with an existing one.  */
      if (fdr.cbLine == 0 && fdr.rss != -1 && fdr.fMerge)
	{
	  const char *name;
	  char *lookup;
	  struct string_hash_entry *fh;

	  /* We look up a string formed from the file name and the
	     number of symbols and aux entries.  Sometimes an include
	     file will conditionally define a typedef or something
	     based on the order of include files.  Using the number of
	     symbols and aux entries as a hash reduces the chance that
	     we will merge symbol information that should not be
	     merged.  */
	  name = input_debug->ss + fdr.issBase + fdr.rss;

	  lookup = (char *) bfd_malloc ((bfd_size_type) strlen (name) + 20);
	  if (lookup == NULL)
	    return FALSE;
	  sprintf (lookup, "%s %lx %lx", name, (unsigned long) fdr.csym,
		   (unsigned long) fdr.caux);

	  fh = string_hash_lookup (&ainfo->fdr_hash, lookup, TRUE, TRUE);
	  free (lookup);
	  if (fh == (struct string_hash_entry *) NULL)
	    return FALSE;

	  if (fh->val != -1)
	    {
	      input_debug->ifdmap[i] = fh->val;
	      (*swap_rfd_out) (output_bfd, input_debug->ifdmap + i, rfd_out);

	      /* Don't copy this FDR.  */
	      continue;
	    }

	  fh->val = output_symhdr->ifdMax + copied;
	}

      input_debug->ifdmap[i] = output_symhdr->ifdMax + copied;
      (*swap_rfd_out) (output_bfd, input_debug->ifdmap + i, rfd_out);
      ++copied;
    }

  newrfdbase = output_symhdr->crfd;
  output_symhdr->crfd += input_symhdr->ifdMax;

  /* Copy over any existing RFD's.  RFD's are only created by the
     linker, so this will only happen for input files which are the
     result of a partial link.  */
  rfd_in = (bfd_byte *) input_debug->external_rfd;
  rfd_end = rfd_in + input_symhdr->crfd * input_swap->external_rfd_size;
  for (;
       rfd_in < rfd_end;
       rfd_in += input_swap->external_rfd_size)
    {
      RFDT rfd;

      (*swap_rfd_in) (input_bfd, rfd_in, &rfd);
      BFD_ASSERT (rfd >= 0 && rfd < input_symhdr->ifdMax);
      rfd = input_debug->ifdmap[rfd];
      (*swap_rfd_out) (output_bfd, &rfd, rfd_out);
      rfd_out += external_rfd_size;
    }

  oldrfdbase = output_symhdr->crfd;
  output_symhdr->crfd += input_symhdr->crfd;

  /* Look through the FDR's and copy over all associated debugging
     information.  */
  sz = copied * external_fdr_size;
  fdr_out = (bfd_byte *) objalloc_alloc (ainfo->memory, sz);
  if (!fdr_out)
    {
      bfd_set_error (bfd_error_no_memory);
      return FALSE;
    }
  if (!add_memory_shuffle (ainfo, &ainfo->fdr, &ainfo->fdr_end, fdr_out, sz))
    return FALSE;
  for (fdr_ptr = fdr_start, i = 0;
       fdr_ptr < fdr_end;
       fdr_ptr += fdr_add, i++)
    {
      FDR fdr;
      bfd_byte *sym_out;
      bfd_byte *lraw_src;
      bfd_byte *lraw_end;
      bfd_boolean fgotfilename;

      if (input_debug->ifdmap[i] < output_symhdr->ifdMax)
	{
	  /* We are not copying this FDR.  */
	  continue;
	}

      if (input_debug->fdr != (FDR *) NULL)
	fdr = *(FDR *) fdr_ptr;
      else
	(*input_swap->swap_fdr_in) (input_bfd, fdr_ptr, &fdr);

      /* FIXME: It is conceivable that this FDR points to the .init or
	 .fini section, in which case this will not do the right
	 thing.  */
      fdr.adr += section_adjust[scText];

      /* Swap in the local symbols, adjust their values, and swap them
	 out again.  */
      fgotfilename = FALSE;
      sz = fdr.csym * external_sym_size;
      sym_out = (bfd_byte *) objalloc_alloc (ainfo->memory, sz);
      if (!sym_out)
	{
	  bfd_set_error (bfd_error_no_memory);
	  return FALSE;
	}
      if (!add_memory_shuffle (ainfo, &ainfo->sym, &ainfo->sym_end, sym_out,
			       sz))
	return FALSE;
      lraw_src = ((bfd_byte *) input_debug->external_sym
		  + fdr.isymBase * input_swap->external_sym_size);
      lraw_end = lraw_src + fdr.csym * input_swap->external_sym_size;
      for (;  lraw_src < lraw_end;  lraw_src += input_swap->external_sym_size)
	{
	  SYMR internal_sym;

	  (*swap_sym_in) (input_bfd, lraw_src, &internal_sym);

	  BFD_ASSERT (internal_sym.sc != scCommon
		      && internal_sym.sc != scSCommon);

	  /* Adjust the symbol value if appropriate.  */
	  switch (internal_sym.st)
	    {
	    case stNil:
	      if (ECOFF_IS_STAB (&internal_sym))
		break;
	      /* Fall through.  */
	    case stGlobal:
	    case stStatic:
	    case stLabel:
	    case stProc:
	    case stStaticProc:
	      internal_sym.value += section_adjust[internal_sym.sc];
	      break;

	    default:
	      break;
	    }

	  /* If we are doing a final link, we hash all the strings in
	     the local symbol table together.  This reduces the amount
	     of space required by debugging information.  We don't do
	     this when performing a relocatable link because it would
	     prevent us from easily merging different FDR's.  */
	  if (! bfd_link_relocatable (info))
	    {
	      bfd_boolean ffilename;
	      const char *name;

	      if (! fgotfilename && internal_sym.iss == fdr.rss)
		ffilename = TRUE;
	      else
		ffilename = FALSE;

	      /* Hash the name into the string table.  */
	      name = input_debug->ss + fdr.issBase + internal_sym.iss;
	      if (*name == '\0')
		internal_sym.iss = 0;
	      else
		{
		  struct string_hash_entry *sh;

		  sh = string_hash_lookup (&ainfo->str_hash, name, TRUE, TRUE);
		  if (sh == (struct string_hash_entry *) NULL)
		    return FALSE;
		  if (sh->val == -1)
		    {
		      sh->val = output_symhdr->issMax;
		      output_symhdr->issMax += strlen (name) + 1;
		      if (ainfo->ss_hash == (struct string_hash_entry *) NULL)
			ainfo->ss_hash = sh;
		      if (ainfo->ss_hash_end
			  != (struct string_hash_entry *) NULL)
			ainfo->ss_hash_end->next = sh;
		      ainfo->ss_hash_end = sh;
		    }
		  internal_sym.iss = sh->val;
		}

	      if (ffilename)
		{
		  fdr.rss = internal_sym.iss;
		  fgotfilename = TRUE;
		}
	    }

	  (*swap_sym_out) (output_bfd, &internal_sym, sym_out);
	  sym_out += external_sym_size;
	}

      fdr.isymBase = output_symhdr->isymMax;
      output_symhdr->isymMax += fdr.csym;

      /* Copy the information that does not need swapping.  */

      /* FIXME: If we are relaxing, we need to adjust the line
	 numbers.  Frankly, forget it.  Anybody using stabs debugging
	 information will not use this line number information, and
	 stabs are adjusted correctly.  */
      if (fdr.cbLine > 0)
	{
	  file_ptr pos = input_symhdr->cbLineOffset + fdr.cbLineOffset;
	  if (!add_file_shuffle (ainfo, &ainfo->line, &ainfo->line_end,
				 input_bfd, pos, (unsigned long) fdr.cbLine))
	    return FALSE;
	  fdr.ilineBase = output_symhdr->ilineMax;
	  fdr.cbLineOffset = output_symhdr->cbLine;
	  output_symhdr->ilineMax += fdr.cline;
	  output_symhdr->cbLine += fdr.cbLine;
	}
      if (fdr.caux > 0)
	{
	  file_ptr pos = (input_symhdr->cbAuxOffset
			  + fdr.iauxBase * sizeof (union aux_ext));
	  if (!add_file_shuffle (ainfo, &ainfo->aux, &ainfo->aux_end,
				 input_bfd, pos,
				 fdr.caux * sizeof (union aux_ext)))
	    return FALSE;
	  fdr.iauxBase = output_symhdr->iauxMax;
	  output_symhdr->iauxMax += fdr.caux;
	}
      if (! bfd_link_relocatable (info))
	{

	  /* When are are hashing strings, we lie about the number of
	     strings attached to each FDR.  We need to set cbSs
	     because some versions of dbx apparently use it to decide
	     how much of the string table to read in.  */
	  fdr.issBase = 0;
	  fdr.cbSs = output_symhdr->issMax;
	}
      else if (fdr.cbSs > 0)
	{
	  file_ptr pos = input_symhdr->cbSsOffset + fdr.issBase;
	  if (!add_file_shuffle (ainfo, &ainfo->ss, &ainfo->ss_end,
				 input_bfd, pos, (unsigned long) fdr.cbSs))
	    return FALSE;
	  fdr.issBase = output_symhdr->issMax;
	  output_symhdr->issMax += fdr.cbSs;
	}

      if (output_bfd->xvec->header_byteorder
	  == input_bfd->xvec->header_byteorder)
	{
	  /* The two BFD's have the same endianness, and we don't have
	     to adjust the PDR addresses, so simply copying the
	     information will suffice.  */
	  BFD_ASSERT (external_pdr_size == input_swap->external_pdr_size);
	  if (fdr.cpd > 0)
	    {
	      file_ptr pos = (input_symhdr->cbPdOffset
			      + fdr.ipdFirst * external_pdr_size);
	      unsigned long size = fdr.cpd * external_pdr_size;
	      if (!add_file_shuffle (ainfo, &ainfo->pdr, &ainfo->pdr_end,
				     input_bfd, pos, size))
		return FALSE;
	    }
	  BFD_ASSERT (external_opt_size == input_swap->external_opt_size);
	  if (fdr.copt > 0)
	    {
	      file_ptr pos = (input_symhdr->cbOptOffset
			      + fdr.ioptBase * external_opt_size);
	      unsigned long size = fdr.copt * external_opt_size;
	      if (!add_file_shuffle (ainfo, &ainfo->opt, &ainfo->opt_end,
				     input_bfd, pos, size))
		return FALSE;
	    }
	}
      else
	{
	  bfd_size_type outsz, insz;
	  bfd_byte *in;
	  bfd_byte *end;
	  bfd_byte *out;

	  /* The two BFD's have different endianness, so we must swap
	     everything in and out.  This code would always work, but
	     it would be unnecessarily slow in the normal case.  */
	  outsz = external_pdr_size;
	  insz = input_swap->external_pdr_size;
	  in = ((bfd_byte *) input_debug->external_pdr
		+ fdr.ipdFirst * insz);
	  end = in + fdr.cpd * insz;
	  sz = fdr.cpd * outsz;
	  out = (bfd_byte *) objalloc_alloc (ainfo->memory, sz);
	  if (!out)
	    {
	      bfd_set_error (bfd_error_no_memory);
	      return FALSE;
	    }
	  if (!add_memory_shuffle (ainfo, &ainfo->pdr, &ainfo->pdr_end, out,
				   sz))
	    return FALSE;
	  for (; in < end; in += insz, out += outsz)
	    {
	      PDR pdr;

	      (*input_swap->swap_pdr_in) (input_bfd, in, &pdr);
	      (*output_swap->swap_pdr_out) (output_bfd, &pdr, out);
	    }

	  /* Swap over the optimization information.  */
	  outsz = external_opt_size;
	  insz = input_swap->external_opt_size;
	  in = ((bfd_byte *) input_debug->external_opt
		+ fdr.ioptBase * insz);
	  end = in + fdr.copt * insz;
	  sz = fdr.copt * outsz;
	  out = (bfd_byte *) objalloc_alloc (ainfo->memory, sz);
	  if (!out)
	    {
	      bfd_set_error (bfd_error_no_memory);
	      return FALSE;
	    }
	  if (!add_memory_shuffle (ainfo, &ainfo->opt, &ainfo->opt_end, out,
				   sz))
	    return FALSE;
	  for (; in < end; in += insz, out += outsz)
	    {
	      OPTR opt;

	      (*input_swap->swap_opt_in) (input_bfd, in, &opt);
	      (*output_swap->swap_opt_out) (output_bfd, &opt, out);
	    }
	}

      fdr.ipdFirst = output_symhdr->ipdMax;
      output_symhdr->ipdMax += fdr.cpd;
      fdr.ioptBase = output_symhdr->ioptMax;
      output_symhdr->ioptMax += fdr.copt;

      if (fdr.crfd <= 0)
	{
	  /* Point this FDR at the table of RFD's we created.  */
	  fdr.rfdBase = newrfdbase;
	  fdr.crfd = input_symhdr->ifdMax;
	}
      else
	{
	  /* Point this FDR at the remapped RFD's.  */
	  fdr.rfdBase += oldrfdbase;
	}

      (*swap_fdr_out) (output_bfd, &fdr, fdr_out);
      fdr_out += external_fdr_size;
      ++output_symhdr->ifdMax;
    }

  return TRUE;
}

/* Add a string to the debugging information we are accumulating.
   Return the offset from the fdr string base.  */

static long
ecoff_add_string (struct accumulate *ainfo,
		  struct bfd_link_info *info,
		  struct ecoff_debug_info *debug,
		  FDR *fdr,
		  const char *string)
{
  HDRR *symhdr;
  size_t len;
  bfd_size_type ret;

  symhdr = &debug->symbolic_header;
  len = strlen (string);
  if (bfd_link_relocatable (info))
    {
      if (!add_memory_shuffle (ainfo, &ainfo->ss, &ainfo->ss_end,
                               (bfd_byte *) string, len + 1))
	return -1;
      ret = symhdr->issMax;
      symhdr->issMax += len + 1;
      fdr->cbSs += len + 1;
    }
  else
    {
      struct string_hash_entry *sh;

      sh = string_hash_lookup (&ainfo->str_hash, string, TRUE, TRUE);
      if (sh == (struct string_hash_entry *) NULL)
	return -1;
      if (sh->val == -1)
	{
	  sh->val = symhdr->issMax;
	  symhdr->issMax += len + 1;
	  if (ainfo->ss_hash == (struct string_hash_entry *) NULL)
	    ainfo->ss_hash = sh;
	  if (ainfo->ss_hash_end
	      != (struct string_hash_entry *) NULL)
	    ainfo->ss_hash_end->next = sh;
	  ainfo->ss_hash_end = sh;
	}
      ret = sh->val;
    }

  return ret;
}

/* Add debugging information from a non-ECOFF file.  */

bfd_boolean
bfd_ecoff_debug_accumulate_other (void * handle,
				  bfd *output_bfd,
				  struct ecoff_debug_info *output_debug,
				  const struct ecoff_debug_swap *output_swap,
				  bfd *input_bfd,
				  struct bfd_link_info *info)
{
  struct accumulate *ainfo = (struct accumulate *) handle;
  void (* const swap_sym_out) (bfd *, const SYMR *, void *)
    = output_swap->swap_sym_out;
  HDRR *output_symhdr = &output_debug->symbolic_header;
  FDR fdr;
  asection *sec;
  asymbol **symbols;
  asymbol **sym_ptr;
  asymbol **sym_end;
  long symsize;
  long symcount;
  void * external_fdr;

  memset (&fdr, 0, sizeof fdr);

  sec = bfd_get_section_by_name (input_bfd, ".text");
  if (sec != NULL)
    fdr.adr = sec->output_section->vma + sec->output_offset;
  else
    {
      /* FIXME: What about .init or .fini?  */
      fdr.adr = 0;
    }

  fdr.issBase = output_symhdr->issMax;
  fdr.cbSs = 0;
  fdr.rss = ecoff_add_string (ainfo, info, output_debug, &fdr,
			      input_bfd->filename);
  if (fdr.rss == -1)
    return FALSE;
  fdr.isymBase = output_symhdr->isymMax;

  /* Get the local symbols from the input BFD.  */
  symsize = bfd_get_symtab_upper_bound (input_bfd);
  if (symsize < 0)
    return FALSE;
  symbols = (asymbol **) bfd_alloc (output_bfd, (bfd_size_type) symsize);
  if (symbols == (asymbol **) NULL)
    return FALSE;
  symcount = bfd_canonicalize_symtab (input_bfd, symbols);
  if (symcount < 0)
    return FALSE;
  sym_end = symbols + symcount;

  /* Handle the local symbols.  Any external symbols are handled
     separately.  */
  fdr.csym = 0;
  for (sym_ptr = symbols; sym_ptr != sym_end; sym_ptr++)
    {
      SYMR internal_sym;
      void * external_sym;

      if (((*sym_ptr)->flags & BSF_EXPORT) != 0)
	continue;
      memset (&internal_sym, 0, sizeof internal_sym);
      internal_sym.iss = ecoff_add_string (ainfo, info, output_debug, &fdr,
					   (*sym_ptr)->name);

      if (internal_sym.iss == -1)
	return FALSE;
      if (bfd_is_com_section ((*sym_ptr)->section)
	  || bfd_is_und_section ((*sym_ptr)->section))
	internal_sym.value = (*sym_ptr)->value;
      else
	internal_sym.value = ((*sym_ptr)->value
			      + (*sym_ptr)->section->output_offset
			      + (*sym_ptr)->section->output_section->vma);
      internal_sym.st = stNil;
      internal_sym.sc = scUndefined;
      internal_sym.index = indexNil;

      external_sym = objalloc_alloc (ainfo->memory,
				     output_swap->external_sym_size);
      if (!external_sym)
	{
	  bfd_set_error (bfd_error_no_memory);
	  return FALSE;
	}
      (*swap_sym_out) (output_bfd, &internal_sym, external_sym);
      add_memory_shuffle (ainfo, &ainfo->sym, &ainfo->sym_end,
			  (bfd_byte *) external_sym,
			  (unsigned long) output_swap->external_sym_size);
      ++fdr.csym;
      ++output_symhdr->isymMax;
    }

  bfd_release (output_bfd, symbols);

  /* Leave everything else in the FDR zeroed out.  This will cause
     the lang field to be langC.  The fBigendian field will
     indicate little endian format, but it doesn't matter because
     it only applies to aux fields and there are none.  */
  external_fdr = objalloc_alloc (ainfo->memory,
				 output_swap->external_fdr_size);
  if (!external_fdr)
    {
      bfd_set_error (bfd_error_no_memory);
      return FALSE;
    }
  (*output_swap->swap_fdr_out) (output_bfd, &fdr, external_fdr);
  add_memory_shuffle (ainfo, &ainfo->fdr, &ainfo->fdr_end,
		      (bfd_byte *) external_fdr,
		      (unsigned long) output_swap->external_fdr_size);

  ++output_symhdr->ifdMax;

  return TRUE;
}

/* Set up ECOFF debugging information for the external symbols.
   FIXME: This is done using a memory buffer, but it should be
   probably be changed to use a shuffle structure.  The assembler uses
   this interface, so that must be changed to do something else.  */

bfd_boolean
bfd_ecoff_debug_externals (bfd *abfd,
			   struct ecoff_debug_info *debug,
			   const struct ecoff_debug_swap *swap,
			   bfd_boolean relocatable,
			   bfd_boolean (*get_extr) (asymbol *, EXTR *),
			   void (*set_index) (asymbol *, bfd_size_type))
{
  HDRR * const symhdr = &debug->symbolic_header;
  asymbol **sym_ptr_ptr;
  size_t c;

  sym_ptr_ptr = bfd_get_outsymbols (abfd);
  if (sym_ptr_ptr == NULL)
    return TRUE;

  for (c = bfd_get_symcount (abfd); c > 0; c--, sym_ptr_ptr++)
    {
      asymbol *sym_ptr;
      EXTR esym;

      sym_ptr = *sym_ptr_ptr;

      /* Get the external symbol information.  */
      if (! (*get_extr) (sym_ptr, &esym))
	continue;

      /* If we're producing an executable, move common symbols into
	 bss.  */
      if (! relocatable)
	{
	  if (esym.asym.sc == scCommon)
	    esym.asym.sc = scBss;
	  else if (esym.asym.sc == scSCommon)
	    esym.asym.sc = scSBss;
	}

      if (bfd_is_com_section (sym_ptr->section)
	  || bfd_is_und_section (sym_ptr->section)
	  || sym_ptr->section->output_section == (asection *) NULL)
	{
	  /* FIXME: gas does not keep the value of a small undefined
	     symbol in the symbol itself, because of relocation
	     problems.  */
	  if (esym.asym.sc != scSUndefined
	      || esym.asym.value == 0
	      || sym_ptr->value != 0)
	    esym.asym.value = sym_ptr->value;
	}
      else
	esym.asym.value = (sym_ptr->value
			   + sym_ptr->section->output_offset
			   + sym_ptr->section->output_section->vma);

      if (set_index)
	(*set_index) (sym_ptr, (bfd_size_type) symhdr->iextMax);

      if (! bfd_ecoff_debug_one_external (abfd, debug, swap,
					  sym_ptr->name, &esym))
	return FALSE;
    }

  return TRUE;
}

/* Add a single external symbol to the debugging information.  */

bfd_boolean
bfd_ecoff_debug_one_external (bfd *abfd,
			      struct ecoff_debug_info *debug,
			      const struct ecoff_debug_swap *swap,
			      const char *name,
			      EXTR *esym)
{
  const bfd_size_type external_ext_size = swap->external_ext_size;
  void (* const swap_ext_out) (bfd *, const EXTR *, void *)
    = swap->swap_ext_out;
  HDRR * const symhdr = &debug->symbolic_header;
  size_t namelen;

  namelen = strlen (name);

  if ((size_t) (debug->ssext_end - debug->ssext)
      < symhdr->issExtMax + namelen + 1)
    {
      if (! ecoff_add_bytes ((char **) &debug->ssext,
			     (char **) &debug->ssext_end,
			     symhdr->issExtMax + namelen + 1))
	return FALSE;
    }
  if ((size_t) ((char *) debug->external_ext_end
		- (char *) debug->external_ext)
      < (symhdr->iextMax + 1) * external_ext_size)
    {
      char *external_ext = (char *) debug->external_ext;
      char *external_ext_end = (char *) debug->external_ext_end;
      if (! ecoff_add_bytes ((char **) &external_ext,
			     (char **) &external_ext_end,
			     (symhdr->iextMax + 1) * (size_t) external_ext_size))
	return FALSE;
      debug->external_ext = external_ext;
      debug->external_ext_end = external_ext_end;
    }

  esym->asym.iss = symhdr->issExtMax;

  (*swap_ext_out) (abfd, esym,
		   ((char *) debug->external_ext
		    + symhdr->iextMax * swap->external_ext_size));

  ++symhdr->iextMax;

  strcpy (debug->ssext + symhdr->issExtMax, name);
  symhdr->issExtMax += namelen + 1;

  return TRUE;
}

/* Align the ECOFF debugging information.  */

static void
ecoff_align_debug (bfd *abfd ATTRIBUTE_UNUSED,
		   struct ecoff_debug_info *debug,
		   const struct ecoff_debug_swap *swap)
{
  HDRR * const symhdr = &debug->symbolic_header;
  bfd_size_type debug_align, aux_align, rfd_align;
  size_t add;

  /* Adjust the counts so that structures are aligned.  */
  debug_align = swap->debug_align;
  aux_align = debug_align / sizeof (union aux_ext);
  rfd_align = debug_align / swap->external_rfd_size;

  add = debug_align - (symhdr->cbLine & (debug_align - 1));
  if (add != debug_align)
    {
      if (debug->line != (unsigned char *) NULL)
	memset ((debug->line + symhdr->cbLine), 0, add);
      symhdr->cbLine += add;
    }

  add = debug_align - (symhdr->issMax & (debug_align - 1));
  if (add != debug_align)
    {
      if (debug->ss != (char *) NULL)
	memset ((debug->ss + symhdr->issMax), 0, add);
      symhdr->issMax += add;
    }

  add = debug_align - (symhdr->issExtMax & (debug_align - 1));
  if (add != debug_align)
    {
      if (debug->ssext != (char *) NULL)
	memset ((debug->ssext + symhdr->issExtMax), 0, add);
      symhdr->issExtMax += add;
    }

  add = aux_align - (symhdr->iauxMax & (aux_align - 1));
  if (add != aux_align)
    {
      if (debug->external_aux != (union aux_ext *) NULL)
	memset ((debug->external_aux + symhdr->iauxMax), 0,
		add * sizeof (union aux_ext));
      symhdr->iauxMax += add;
    }

  add = rfd_align - (symhdr->crfd & (rfd_align - 1));
  if (add != rfd_align)
    {
      if (debug->external_rfd != NULL)
	memset (((char *) debug->external_rfd
		 + symhdr->crfd * swap->external_rfd_size),
		0, (size_t) (add * swap->external_rfd_size));
      symhdr->crfd += add;
    }
}

/* Return the size required by the ECOFF debugging information.  */

bfd_size_type
bfd_ecoff_debug_size (bfd *abfd,
		      struct ecoff_debug_info *debug,
		      const struct ecoff_debug_swap *swap)
{
  bfd_size_type tot;

  ecoff_align_debug (abfd, debug, swap);
  tot = swap->external_hdr_size;

#define ADD(count, size) \
  tot += debug->symbolic_header.count * size

  ADD (cbLine, sizeof (unsigned char));
  ADD (idnMax, swap->external_dnr_size);
  ADD (ipdMax, swap->external_pdr_size);
  ADD (isymMax, swap->external_sym_size);
  ADD (ioptMax, swap->external_opt_size);
  ADD (iauxMax, sizeof (union aux_ext));
  ADD (issMax, sizeof (char));
  ADD (issExtMax, sizeof (char));
  ADD (ifdMax, swap->external_fdr_size);
  ADD (crfd, swap->external_rfd_size);
  ADD (iextMax, swap->external_ext_size);

#undef ADD

  return tot;
}

/* Write out the ECOFF symbolic header, given the file position it is
   going to be placed at.  This assumes that the counts are set
   correctly.  */

static bfd_boolean
ecoff_write_symhdr (bfd *abfd,
		    struct ecoff_debug_info *debug,
		    const struct ecoff_debug_swap *swap,
		    file_ptr where)
{
  HDRR * const symhdr = &debug->symbolic_header;
  char *buff = NULL;

  ecoff_align_debug (abfd, debug, swap);

  /* Go to the right location in the file.  */
  if (bfd_seek (abfd, where, SEEK_SET) != 0)
    return FALSE;

  where += swap->external_hdr_size;

  symhdr->magic = swap->sym_magic;

  /* Fill in the file offsets.  */
#define SET(offset, count, size) \
  if (symhdr->count == 0) \
    symhdr->offset = 0; \
  else \
    { \
      symhdr->offset = where; \
      where += symhdr->count * size; \
    }

  SET (cbLineOffset, cbLine, sizeof (unsigned char));
  SET (cbDnOffset, idnMax, swap->external_dnr_size);
  SET (cbPdOffset, ipdMax, swap->external_pdr_size);
  SET (cbSymOffset, isymMax, swap->external_sym_size);
  SET (cbOptOffset, ioptMax, swap->external_opt_size);
  SET (cbAuxOffset, iauxMax, sizeof (union aux_ext));
  SET (cbSsOffset, issMax, sizeof (char));
  SET (cbSsExtOffset, issExtMax, sizeof (char));
  SET (cbFdOffset, ifdMax, swap->external_fdr_size);
  SET (cbRfdOffset, crfd, swap->external_rfd_size);
  SET (cbExtOffset, iextMax, swap->external_ext_size);
#undef SET

  buff = (char *) bfd_malloc (swap->external_hdr_size);
  if (buff == NULL && swap->external_hdr_size != 0)
    goto error_return;

  (*swap->swap_hdr_out) (abfd, symhdr, buff);
  if (bfd_bwrite (buff, swap->external_hdr_size, abfd)
      != swap->external_hdr_size)
    goto error_return;

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

/* Write out the ECOFF debugging information.  This function assumes
   that the information (the pointers and counts) in *DEBUG have been
   set correctly.  WHERE is the position in the file to write the
   information to.  This function fills in the file offsets in the
   symbolic header.  */

bfd_boolean
bfd_ecoff_write_debug (bfd *abfd,
		       struct ecoff_debug_info *debug,
		       const struct ecoff_debug_swap *swap,
		       file_ptr where)
{
  HDRR * const symhdr = &debug->symbolic_header;

  if (! ecoff_write_symhdr (abfd, debug, swap, where))
    return FALSE;

#define WRITE(ptr, count, size, offset) \
  BFD_ASSERT (symhdr->offset == 0 \
	      || (bfd_vma) bfd_tell (abfd) == symhdr->offset); \
  if (bfd_bwrite (debug->ptr, (bfd_size_type) size * symhdr->count, abfd)\
      != size * symhdr->count) \
    return FALSE;

  WRITE (line, cbLine, sizeof (unsigned char), cbLineOffset);
  WRITE (external_dnr, idnMax, swap->external_dnr_size, cbDnOffset);
  WRITE (external_pdr, ipdMax, swap->external_pdr_size, cbPdOffset);
  WRITE (external_sym, isymMax, swap->external_sym_size, cbSymOffset);
  WRITE (external_opt, ioptMax, swap->external_opt_size, cbOptOffset);
  WRITE (external_aux, iauxMax, (bfd_size_type) sizeof (union aux_ext),
	 cbAuxOffset);
  WRITE (ss, issMax, sizeof (char), cbSsOffset);
  WRITE (ssext, issExtMax, sizeof (char), cbSsExtOffset);
  WRITE (external_fdr, ifdMax, swap->external_fdr_size, cbFdOffset);
  WRITE (external_rfd, crfd, swap->external_rfd_size, cbRfdOffset);
  WRITE (external_ext, iextMax, swap->external_ext_size, cbExtOffset);
#undef WRITE

  return TRUE;
}

/* Write out a shuffle list.  */


static bfd_boolean
ecoff_write_shuffle (bfd *abfd,
		     const struct ecoff_debug_swap *swap,
		     struct shuffle *shuffle,
		     void * space)
{
  struct shuffle *l;
  unsigned long total;

  total = 0;
  for (l = shuffle; l != (struct shuffle *) NULL; l = l->next)
    {
      if (! l->filep)
	{
	  if (bfd_bwrite (l->u.memory, (bfd_size_type) l->size, abfd)
	      != l->size)
	    return FALSE;
	}
      else
	{
	  if (bfd_seek (l->u.file.input_bfd, l->u.file.offset, SEEK_SET) != 0
	      || bfd_bread (space, (bfd_size_type) l->size,
			   l->u.file.input_bfd) != l->size
	      || bfd_bwrite (space, (bfd_size_type) l->size, abfd) != l->size)
	    return FALSE;
	}
      total += l->size;
    }

  if ((total & (swap->debug_align - 1)) != 0)
    {
      unsigned int i;
      bfd_byte *s;

      i = swap->debug_align - (total & (swap->debug_align - 1));
      s = (bfd_byte *) bfd_zmalloc ((bfd_size_type) i);
      if (s == NULL && i != 0)
	return FALSE;

      if (bfd_bwrite (s, (bfd_size_type) i, abfd) != i)
	{
	  free (s);
	  return FALSE;
	}
      free (s);
    }

  return TRUE;
}

/* Write out debugging information using accumulated linker
   information.  */

bfd_boolean
bfd_ecoff_write_accumulated_debug (void * handle,
				   bfd *abfd,
				   struct ecoff_debug_info *debug,
				   const struct ecoff_debug_swap *swap,
				   struct bfd_link_info *info,
				   file_ptr where)
{
  struct accumulate *ainfo = (struct accumulate *) handle;
  void * space = NULL;
  bfd_size_type amt;

  if (! ecoff_write_symhdr (abfd, debug, swap, where))
    goto error_return;

  amt = ainfo->largest_file_shuffle;
  space = bfd_malloc (amt);
  if (space == NULL && ainfo->largest_file_shuffle != 0)
    goto error_return;

  if (! ecoff_write_shuffle (abfd, swap, ainfo->line, space)
      || ! ecoff_write_shuffle (abfd, swap, ainfo->pdr, space)
      || ! ecoff_write_shuffle (abfd, swap, ainfo->sym, space)
      || ! ecoff_write_shuffle (abfd, swap, ainfo->opt, space)
      || ! ecoff_write_shuffle (abfd, swap, ainfo->aux, space))
    goto error_return;

  /* The string table is written out from the hash table if this is a
     final link.  */
  if (bfd_link_relocatable (info))
    {
      BFD_ASSERT (ainfo->ss_hash == (struct string_hash_entry *) NULL);
      if (! ecoff_write_shuffle (abfd, swap, ainfo->ss, space))
	goto error_return;
    }
  else
    {
      unsigned long total;
      bfd_byte null;
      struct string_hash_entry *sh;

      BFD_ASSERT (ainfo->ss == (struct shuffle *) NULL);
      null = 0;
      if (bfd_bwrite (&null, (bfd_size_type) 1, abfd) != 1)
	goto error_return;
      total = 1;
      BFD_ASSERT (ainfo->ss_hash == NULL || ainfo->ss_hash->val == 1);
      for (sh = ainfo->ss_hash;
	   sh != (struct string_hash_entry *) NULL;
	   sh = sh->next)
	{
	  size_t len;

	  len = strlen (sh->root.string);
	  amt = len + 1;
	  if (bfd_bwrite (sh->root.string, amt, abfd) != amt)
	    goto error_return;
	  total += len + 1;
	}

      if ((total & (swap->debug_align - 1)) != 0)
	{
	  unsigned int i;
	  bfd_byte *s;

	  i = swap->debug_align - (total & (swap->debug_align - 1));
	  s = (bfd_byte *) bfd_zmalloc ((bfd_size_type) i);
	  if (s == NULL && i != 0)
	    goto error_return;

	  if (bfd_bwrite (s, (bfd_size_type) i, abfd) != i)
	    {
	      free (s);
	      goto error_return;
	    }
	  free (s);
	}
    }

  /* The external strings and symbol are not converted over to using
     shuffles.  FIXME: They probably should be.  */
  amt = debug->symbolic_header.issExtMax;
  if (bfd_bwrite (debug->ssext, amt, abfd) != amt)
    goto error_return;
  if ((debug->symbolic_header.issExtMax & (swap->debug_align - 1)) != 0)
    {
      unsigned int i;
      bfd_byte *s;

      i = (swap->debug_align
	   - (debug->symbolic_header.issExtMax & (swap->debug_align - 1)));
      s = (bfd_byte *) bfd_zmalloc ((bfd_size_type) i);
      if (s == NULL && i != 0)
	goto error_return;

      if (bfd_bwrite (s, (bfd_size_type) i, abfd) != i)
	{
	  free (s);
	  goto error_return;
	}
      free (s);
    }

  if (! ecoff_write_shuffle (abfd, swap, ainfo->fdr, space)
      || ! ecoff_write_shuffle (abfd, swap, ainfo->rfd, space))
    goto error_return;

  BFD_ASSERT (debug->symbolic_header.cbExtOffset == 0
	      || (debug->symbolic_header.cbExtOffset
		  == (bfd_vma) bfd_tell (abfd)));

  amt = debug->symbolic_header.iextMax * swap->external_ext_size;
  if (bfd_bwrite (debug->external_ext, amt, abfd) != amt)
    goto error_return;

  if (space != NULL)
    free (space);
  return TRUE;

 error_return:
  if (space != NULL)
    free (space);
  return FALSE;
}

/* Handle the find_nearest_line function for both ECOFF and MIPS ELF
   files.  */

/* Compare FDR entries.  This is called via qsort.  */

static int
cmp_fdrtab_entry (const void * leftp, const void * rightp)
{
  const struct ecoff_fdrtab_entry *lp =
    (const struct ecoff_fdrtab_entry *) leftp;
  const struct ecoff_fdrtab_entry *rp =
    (const struct ecoff_fdrtab_entry *) rightp;

  if (lp->base_addr < rp->base_addr)
    return -1;
  if (lp->base_addr > rp->base_addr)
    return 1;
  return 0;
}

/* Each file descriptor (FDR) has a memory address, to simplify
   looking up an FDR by address, we build a table covering all FDRs
   that have a least one procedure descriptor in them.  The final
   table will be sorted by address so we can look it up via binary
   search.  */

static bfd_boolean
mk_fdrtab (bfd *abfd,
	   struct ecoff_debug_info * const debug_info,
	   const struct ecoff_debug_swap * const debug_swap,
	   struct ecoff_find_line *line_info)
{
  struct ecoff_fdrtab_entry *tab;
  FDR *fdr_ptr;
  FDR *fdr_start;
  FDR *fdr_end;
  bfd_boolean stabs;
  long len;
  bfd_size_type amt;

  fdr_start = debug_info->fdr;
  fdr_end = fdr_start + debug_info->symbolic_header.ifdMax;

  /* First, let's see how long the table needs to be.  */
  for (len = 0, fdr_ptr = fdr_start; fdr_ptr < fdr_end; fdr_ptr++)
    {
      if (fdr_ptr->cpd == 0)	/* Skip FDRs that have no PDRs.  */
	continue;
      ++len;
    }

  /* Now, create and fill in the table.  */
  amt = (bfd_size_type) len * sizeof (struct ecoff_fdrtab_entry);
  line_info->fdrtab = (struct ecoff_fdrtab_entry*) bfd_zalloc (abfd, amt);
  if (line_info->fdrtab == NULL)
    return FALSE;
  line_info->fdrtab_len = len;

  tab = line_info->fdrtab;
  for (fdr_ptr = fdr_start; fdr_ptr < fdr_end; fdr_ptr++)
    {
      if (fdr_ptr->cpd == 0)
	continue;

      /* Check whether this file has stabs debugging information.  In
	 a file with stabs debugging information, the second local
	 symbol is named @stabs.  */
      stabs = FALSE;
      if (fdr_ptr->csym >= 2)
	{
	  char *sym_ptr;
	  SYMR sym;

	  sym_ptr = ((char *) debug_info->external_sym
		     + (fdr_ptr->isymBase + 1) * debug_swap->external_sym_size);
	  (*debug_swap->swap_sym_in) (abfd, sym_ptr, &sym);
	  if (strcmp (debug_info->ss + fdr_ptr->issBase + sym.iss,
		      STABS_SYMBOL) == 0)
	    stabs = TRUE;
	}

      if (!stabs)
	{
	  /* eraxxon: There are at least two problems with this computation:
	     1) PDRs do *not* contain offsets but full vma's; and typically the
	     address of the first PDR is the address of the FDR, which will
	     make (most) of the results of the original computation 0!
	     2) Once in a wacky while, the Compaq compiler generated PDR
	     addresses do not equal the FDR vma, but they (the PDR address)
	     are still vma's and not offsets.  Cf. comments in
	     'lookup_line'.  */
	  /* The address of the first PDR is the offset of that
	     procedure relative to the beginning of file FDR.  */
	  tab->base_addr = fdr_ptr->adr;
	}
      else
	{
	  /* XXX I don't know about stabs, so this is a guess
	     (davidm@cs.arizona.edu).  */
	  tab->base_addr = fdr_ptr->adr;
	}
      tab->fdr = fdr_ptr;
      ++tab;
    }

  /* Finally, the table is sorted in increasing memory-address order.
     The table is mostly sorted already, but there are cases (e.g.,
     static functions in include files), where this does not hold.
     Use "odump -PFv" to verify...  */
  qsort (line_info->fdrtab, (size_t) len,
	 sizeof (struct ecoff_fdrtab_entry), cmp_fdrtab_entry);

  return TRUE;
}

/* Return index of first FDR that covers to OFFSET.  */

static long
fdrtab_lookup (struct ecoff_find_line *line_info, bfd_vma offset)
{
  long low, high, len;
  long mid = -1;
  struct ecoff_fdrtab_entry *tab;

  len = line_info->fdrtab_len;
  if (len == 0)
    return -1;

  tab = line_info->fdrtab;
  for (low = 0, high = len - 1 ; low != high ;)
    {
      mid = (high + low) / 2;
      if (offset >= tab[mid].base_addr && offset < tab[mid + 1].base_addr)
	goto find_min;

      if (tab[mid].base_addr > offset)
	high = mid;
      else
	low = mid + 1;
    }

  /* eraxxon: at this point 'offset' is either lower than the lowest entry or
     higher than the highest entry. In the former case high = low = mid = 0;
     we want to return -1.  In the latter case, low = high and mid = low - 1;
     we want to return the index of the highest entry.  Only in former case
     will the following 'catch-all' test be true.  */
  ++mid;

  /* Last entry is catch-all for all higher addresses.  */
  if (offset < tab[mid].base_addr)
    return -1;

 find_min:

  /* eraxxon: There may be multiple FDRs in the table with the
     same base_addr; make sure that we are at the first one.  */
  while (mid > 0 && tab[mid - 1].base_addr == tab[mid].base_addr)
    --mid;

  return mid;
}

/* Look up a line given an address, storing the information in
   LINE_INFO->cache.  */

static bfd_boolean
lookup_line (bfd *abfd,
	     struct ecoff_debug_info * const debug_info,
	     const struct ecoff_debug_swap * const debug_swap,
	     struct ecoff_find_line *line_info)
{
  struct ecoff_fdrtab_entry *tab;
  bfd_vma offset;
  bfd_boolean stabs;
  FDR *fdr_ptr;
  int i;

  /* eraxxon: note that 'offset' is the full vma, not a section offset.  */
  offset = line_info->cache.start;

  /* Build FDR table (sorted by object file's base-address) if we
     don't have it already.  */
  if (line_info->fdrtab == NULL
      && !mk_fdrtab (abfd, debug_info, debug_swap, line_info))
    return FALSE;

  tab = line_info->fdrtab;

  /* Find first FDR for address OFFSET.  */
  i = fdrtab_lookup (line_info, offset);
  if (i < 0)
    return FALSE;		/* no FDR, no fun...  */

  /* eraxxon: 'fdrtab_lookup' doesn't give what we want, at least for Compaq's
     C++ compiler 6.2.  Consider three FDRs with starting addresses of x, y,
     and z, respectively, such that x < y < z.  Assume further that
     y < 'offset' < z.  It is possible at times that the PDR for 'offset' is
     associated with FDR x and *not* with FDR y.  Erg!!

     From a binary dump of my C++ test case 'moo' using Compaq's coffobjanl
     (output format has been edited for our purposes):

     FDR [2]: (main.C): First instruction: 0x12000207c <x>
       PDR [5] for File [2]: LoopTest__Xv                 <0x1200020a0> (a)
       PDR [7] for File [2]: foo__Xv                      <0x120002168>
     FDR [1]: (-1):     First instruction: 0x1200020e8 <y>
       PDR [3] for File [1]:                              <0x120001ad0> (b)
     FDR [6]: (-1):     First instruction: 0x1200026f0 <z>

     (a) In the case of PDR5, the vma is such that the first few instructions
     of the procedure can be found.  But since the size of this procedure is
     160b, the vma will soon cross into the 'address space' of FDR1 and no
     debugging info will be found.  How repugnant!

     (b) It is also possible for a PDR to have a *lower* vma than its associated
     FDR; see FDR1 and PDR3.  Gross!

     Since the FDRs that are causing so much havok (in this case) 1) do not
     describe actual files (fdr.rss == -1), and 2) contain only compiler
     generated routines, I thought a simple fix would be to exclude them from
     the FDR table in 'mk_fdrtab'.  But, besides not knowing for certain
     whether this would be correct, it creates an additional problem.  If we
     happen to ask for source file info on a compiler generated (procedure)
     symbol -- which is still in the symbol table -- the result can be
     information from a real procedure!  This is because compiler generated
     procedures with vma's higher than the last FDR in the fdr table will be
     associated with a PDR from this FDR, specifically the PDR with the
     highest vma.  This wasn't a problem before, because each procedure had a
     PDR.  (Yes, this problem could be eliminated if we kept the size of the
     last PDR around, but things are already getting ugly).

     Probably, a better solution would be to have a sorted PDR table.  Each
     PDR would have a pointer to its FDR so file information could still be
     obtained.  A FDR table could still be constructed if necessary -- since
     it only contains pointers, not much extra memory would be used -- but
     the PDR table would be searched to locate debugging info.

     There is still at least one remaining issue.  Sometimes a FDR can have a
     bogus name, but contain PDRs that should belong to another FDR with a
     real name.  E.g:

     FDR [3]: 0000000120001b50 (/home/.../Array.H~alt~deccxx_5E5A62AD)
       PDR [a] for File [3]: 0000000120001b50
       PDR [b] for File [3]: 0000000120001cf0
       PDR [c] for File [3]: 0000000120001dc8
       PDR [d] for File [3]: 0000000120001e40
       PDR [e] for File [3]: 0000000120001eb8
       PDR [f] for File [3]: 0000000120001f4c
     FDR [4]: 0000000120001b50 (/home/.../Array.H)

     Here, FDR4 has the correct name, but should (seemingly) contain PDRa-f.
     The symbol table for PDR4 does contain symbols for PDRa-f, but so does
     the symbol table for FDR3.  However the former is different; perhaps this
     can be detected easily. (I'm not sure at this point.)  This problem only
     seems to be associated with files with templates.  I am assuming the idea
     is that there is a 'fake' FDR (with PDRs) for each differently typed set
     of templates that must be generated.  Currently, FDR4 is completely
     excluded from the FDR table in 'mk_fdrtab' because it contains no PDRs.

     Since I don't have time to prepare a real fix for this right now, be
     prepared for 'A Horrible Hack' to force the inspection of all non-stabs
     FDRs.  It's coming...  */
  fdr_ptr = tab[i].fdr;

  /* Check whether this file has stabs debugging information.  In a
     file with stabs debugging information, the second local symbol is
     named @stabs.  */
  stabs = FALSE;
  if (fdr_ptr->csym >= 2)
    {
      char *sym_ptr;
      SYMR sym;

      sym_ptr = ((char *) debug_info->external_sym
		 + (fdr_ptr->isymBase + 1) * debug_swap->external_sym_size);
      (*debug_swap->swap_sym_in) (abfd, sym_ptr, &sym);
      if (strcmp (debug_info->ss + fdr_ptr->issBase + sym.iss,
		  STABS_SYMBOL) == 0)
	stabs = TRUE;
    }

  if (!stabs)
    {
      bfd_size_type external_pdr_size;
      char *pdr_ptr;
      char *best_pdr = NULL;
      FDR *best_fdr;
      bfd_signed_vma best_dist = -1;
      PDR pdr;
      unsigned char *line_ptr;
      unsigned char *line_end;
      int lineno;
      /* This file uses ECOFF debugging information.  Each FDR has a
         list of procedure descriptors (PDR).  The address in the FDR
         is the absolute address of the first procedure.  The address
         in the first PDR gives the offset of that procedure relative
         to the object file's base-address.  The addresses in
         subsequent PDRs specify each procedure's address relative to
         the object file's base-address.  To make things more juicy,
         whenever the PROF bit in the PDR is set, the real entry point
         of the procedure may be 16 bytes below what would normally be
         the procedure's entry point.  Instead, DEC came up with a
         wicked scheme to create profiled libraries "on the fly":
         instead of shipping a regular and a profiled version of each
         library, they insert 16 bytes of unused space in front of
         each procedure and set the "prof" bit in the PDR to indicate
         that there is a gap there (this is done automagically by "as"
         when option "-pg" is specified).  Thus, normally, you link
         against such a library and, except for lots of 16 byte gaps
         between functions, things will behave as usual.  However,
         when invoking "ld" with option "-pg", it will fill those gaps
         with code that calls mcount().  It then moves the function's
         entry point down by 16 bytes, and out pops a binary that has
         all functions profiled.

         NOTE: Neither FDRs nor PDRs are strictly sorted in memory
               order.  For example, when including header-files that
               define functions, the FDRs follow behind the including
               file, even though their code may have been generated at
               a lower address.  File coff-alpha.c from libbfd
               illustrates this (use "odump -PFv" to look at a file's
               FDR/PDR).  Similarly, PDRs are sometimes out of order
               as well.  An example of this is OSF/1 v3.0 libc's
               malloc.c.  I'm not sure why this happens, but it could
               be due to optimizations that reorder a function's
               position within an object-file.

         Strategy:

         On the first call to this function, we build a table of FDRs
         that is sorted by the base-address of the object-file the FDR
         is referring to.  Notice that each object-file may contain
         code from multiple source files (e.g., due to code defined in
         include files).  Thus, for any given base-address, there may
         be multiple FDRs (but this case is, fortunately, uncommon).
         lookup(addr) guarantees to return the first FDR that applies
         to address ADDR.  Thus, after invoking lookup(), we have a
         list of FDRs that may contain the PDR for ADDR.  Next, we
         walk through the PDRs of these FDRs and locate the one that
         is closest to ADDR (i.e., for which the difference between
         ADDR and the PDR's entry point is positive and minimal).
         Once, the right FDR and PDR are located, we simply walk
         through the line-number table to lookup the line-number that
         best matches ADDR.  Obviously, things could be sped up by
         keeping a sorted list of PDRs instead of a sorted list of
         FDRs.  However, this would increase space requirements
         considerably, which is undesirable.  */
      external_pdr_size = debug_swap->external_pdr_size;

      /* eraxxon: The Horrible Hack: Because of the problems above, set 'i'
	 to 0 so we look through all FDRs.

	 Because FDR's without any symbols are assumed to be non-stabs,
	 searching through all FDRs may cause the following code to try to
	 read stabs FDRs as ECOFF ones.  However, I don't think this will
	 harm anything.  */
      i = 0;

      /* Search FDR list starting at tab[i] for the PDR that best matches
         OFFSET.  Normally, the FDR list is only one entry long.  */
      best_fdr = NULL;
      do
	{
	  /* eraxxon: 'dist' and 'min_dist' can be negative now
             because we iterate over every FDR rather than just ones
             with a base address less than or equal to 'offset'.  */
	  bfd_signed_vma dist = -1, min_dist = -1;
	  char *pdr_hold;
	  char *pdr_end;

	  fdr_ptr = tab[i].fdr;

	  pdr_ptr = ((char *) debug_info->external_pdr
		     + fdr_ptr->ipdFirst * external_pdr_size);
	  pdr_end = pdr_ptr + fdr_ptr->cpd * external_pdr_size;
	  (*debug_swap->swap_pdr_in) (abfd, pdr_ptr, &pdr);
	  /* Find PDR that is closest to OFFSET.  If pdr.prof is set,
	     the procedure entry-point *may* be 0x10 below pdr.adr.  We
	     simply pretend that pdr.prof *implies* a lower entry-point.
	     This is safe because it just means that may identify 4 NOPs
	     in front of the function as belonging to the function.  */
	  for (pdr_hold = NULL;
	       pdr_ptr < pdr_end;
	       (pdr_ptr += external_pdr_size,
		(*debug_swap->swap_pdr_in) (abfd, pdr_ptr, &pdr)))
	    {
	      if (offset >= (pdr.adr - 0x10 * pdr.prof))
		{
		  dist = offset - (pdr.adr - 0x10 * pdr.prof);

		  /* eraxxon: 'dist' can be negative now.  Note that
                     'min_dist' can be negative if 'pdr_hold' below is NULL.  */
		  if (!pdr_hold || (dist >= 0 && dist < min_dist))
		    {
		      min_dist = dist;
		      pdr_hold = pdr_ptr;
		    }
		}
	    }

	  if (!best_pdr || (min_dist >= 0 && min_dist < best_dist))
	    {
	      best_dist = (bfd_vma) min_dist;
	      best_fdr = fdr_ptr;
	      best_pdr = pdr_hold;
	    }
	  /* Continue looping until base_addr of next entry is different.  */
	}
      /* eraxxon: We want to iterate over all FDRs.
	 See previous comment about 'fdrtab_lookup'.  */
      while (++i < line_info->fdrtab_len);

      if (!best_fdr || !best_pdr)
	return FALSE;			/* Shouldn't happen...  */

      /* Phew, finally we got something that we can hold onto.  */
      fdr_ptr = best_fdr;
      pdr_ptr = best_pdr;
      (*debug_swap->swap_pdr_in) (abfd, pdr_ptr, &pdr);
      /* Now we can look for the actual line number.  The line numbers
         are stored in a very funky format, which I won't try to
         describe.  The search is bounded by the end of the FDRs line
         number entries.  */
      line_end = debug_info->line + fdr_ptr->cbLineOffset + fdr_ptr->cbLine;

      /* Make offset relative to procedure entry.  */
      offset -= pdr.adr - 0x10 * pdr.prof;
      lineno = pdr.lnLow;
      line_ptr = debug_info->line + fdr_ptr->cbLineOffset + pdr.cbLineOffset;
      while (line_ptr < line_end)
	{
	  int delta;
	  unsigned int count;

	  delta = *line_ptr >> 4;
	  if (delta >= 0x8)
	    delta -= 0x10;
	  count = (*line_ptr & 0xf) + 1;
	  ++line_ptr;
	  if (delta == -8)
	    {
	      delta = (((line_ptr[0]) & 0xff) << 8) + ((line_ptr[1]) & 0xff);
	      if (delta >= 0x8000)
		delta -= 0x10000;
	      line_ptr += 2;
	    }
	  lineno += delta;
	  if (offset < count * 4)
	    {
	      line_info->cache.stop += count * 4 - offset;
	      break;
	    }
	  offset -= count * 4;
	}

      /* If fdr_ptr->rss is -1, then this file does not have full
         symbols, at least according to gdb/mipsread.c.  */
      if (fdr_ptr->rss == -1)
	{
	  line_info->cache.filename = NULL;
	  if (pdr.isym == -1)
	    line_info->cache.functionname = NULL;
	  else
	    {
	      EXTR proc_ext;

	      (*debug_swap->swap_ext_in)
		(abfd,
		 ((char *) debug_info->external_ext
		  + pdr.isym * debug_swap->external_ext_size),
		 &proc_ext);
	      line_info->cache.functionname = (debug_info->ssext
					       + proc_ext.asym.iss);
	    }
	}
      else
	{
	  SYMR proc_sym;

	  line_info->cache.filename = (debug_info->ss
				       + fdr_ptr->issBase
				       + fdr_ptr->rss);
	  (*debug_swap->swap_sym_in)
	    (abfd,
	     ((char *) debug_info->external_sym
	      + ((fdr_ptr->isymBase + pdr.isym)
		 * debug_swap->external_sym_size)),
	     &proc_sym);
	  line_info->cache.functionname = (debug_info->ss
					   + fdr_ptr->issBase
					   + proc_sym.iss);
	}
      if (lineno == ilineNil)
	lineno = 0;
      line_info->cache.line_num = lineno;
    }
  else
    {
      bfd_size_type external_sym_size;
      const char *directory_name;
      const char *main_file_name;
      const char *current_file_name;
      const char *function_name;
      const char *line_file_name;
      bfd_vma low_func_vma;
      bfd_vma low_line_vma;
      bfd_boolean past_line;
      bfd_boolean past_fn;
      char *sym_ptr, *sym_ptr_end;
      size_t len, funclen;
      char *buffer = NULL;

      /* This file uses stabs debugging information.  When gcc is not
	 optimizing, it will put the line number information before
	 the function name stabs entry.  When gcc is optimizing, it
	 will put the stabs entry for all the function first, followed
	 by the line number information.  (This appears to happen
	 because of the two output files used by the -mgpopt switch,
	 which is implied by -O).  This means that we must keep
	 looking through the symbols until we find both a line number
	 and a function name which are beyond the address we want.  */

      line_info->cache.filename = NULL;
      line_info->cache.functionname = NULL;
      line_info->cache.line_num = 0;

      directory_name = NULL;
      main_file_name = NULL;
      current_file_name = NULL;
      function_name = NULL;
      line_file_name = NULL;
      low_func_vma = 0;
      low_line_vma = 0;
      past_line = FALSE;
      past_fn = FALSE;

      external_sym_size = debug_swap->external_sym_size;

      sym_ptr = ((char *) debug_info->external_sym
		 + (fdr_ptr->isymBase + 2) * external_sym_size);
      sym_ptr_end = sym_ptr + (fdr_ptr->csym - 2) * external_sym_size;
      for (;
	   sym_ptr < sym_ptr_end && (! past_line || ! past_fn);
	   sym_ptr += external_sym_size)
	{
	  SYMR sym;

	  (*debug_swap->swap_sym_in) (abfd, sym_ptr, &sym);

	  if (ECOFF_IS_STAB (&sym))
	    {
	      switch (ECOFF_UNMARK_STAB (sym.index))
		{
		case N_SO:
		  main_file_name = current_file_name =
		    debug_info->ss + fdr_ptr->issBase + sym.iss;

		  /* Check the next symbol to see if it is also an
                     N_SO symbol.  */
		  if (sym_ptr + external_sym_size < sym_ptr_end)
		    {
		      SYMR nextsym;

		      (*debug_swap->swap_sym_in) (abfd,
						  sym_ptr + external_sym_size,
						  &nextsym);
		      if (ECOFF_IS_STAB (&nextsym)
			  && ECOFF_UNMARK_STAB (nextsym.index) == N_SO)
			{
 			  directory_name = current_file_name;
			  main_file_name = current_file_name =
			    debug_info->ss + fdr_ptr->issBase + nextsym.iss;
			  sym_ptr += external_sym_size;
			}
		    }
		  break;

		case N_SOL:
		  current_file_name =
		    debug_info->ss + fdr_ptr->issBase + sym.iss;
		  break;

		case N_FUN:
		  if (sym.value > offset)
		    past_fn = TRUE;
		  else if (sym.value >= low_func_vma)
		    {
		      low_func_vma = sym.value;
		      function_name =
			debug_info->ss + fdr_ptr->issBase + sym.iss;
		    }
		  break;
		}
	    }
	  else if (sym.st == stLabel && sym.index != indexNil)
	    {
	      if (sym.value > offset)
		past_line = TRUE;
	      else if (sym.value >= low_line_vma)
		{
		  low_line_vma = sym.value;
		  line_file_name = current_file_name;
		  line_info->cache.line_num = sym.index;
		}
	    }
	}

      if (line_info->cache.line_num != 0)
	main_file_name = line_file_name;

      /* We need to remove the stuff after the colon in the function
         name.  We also need to put the directory name and the file
         name together.  */
      if (function_name == NULL)
	len = funclen = 0;
      else
	len = funclen = strlen (function_name) + 1;

      if (main_file_name != NULL
	  && directory_name != NULL
	  && main_file_name[0] != '/')
	len += strlen (directory_name) + strlen (main_file_name) + 1;

      if (len != 0)
	{
	  if (line_info->find_buffer != NULL)
	    free (line_info->find_buffer);
	  buffer = (char *) bfd_malloc ((bfd_size_type) len);
	  if (buffer == NULL)
	    return FALSE;
	  line_info->find_buffer = buffer;
	}

      if (function_name != NULL)
	{
	  char *colon;

	  strcpy (buffer, function_name);
	  colon = strchr (buffer, ':');
	  if (colon != NULL)
	    *colon = '\0';
	  line_info->cache.functionname = buffer;
	}

      if (main_file_name != NULL)
	{
	  if (directory_name == NULL || main_file_name[0] == '/')
	    line_info->cache.filename = main_file_name;
	  else
	    {
	      sprintf (buffer + funclen, "%s%s", directory_name,
		       main_file_name);
	      line_info->cache.filename = buffer + funclen;
	    }
	}
    }

  return TRUE;
}

/* Do the work of find_nearest_line.  */

bfd_boolean
_bfd_ecoff_locate_line (bfd *abfd,
			asection *section,
			bfd_vma offset,
			struct ecoff_debug_info * const debug_info,
			const struct ecoff_debug_swap * const debug_swap,
			struct ecoff_find_line *line_info,
			const char **filename_ptr,
			const char **functionname_ptr,
			unsigned int *retline_ptr)
{
  offset += section->vma;

  if (line_info->cache.sect == NULL
      || line_info->cache.sect != section
      || offset < line_info->cache.start
      || offset >= line_info->cache.stop)
    {
      line_info->cache.sect = section;
      line_info->cache.start = offset;
      line_info->cache.stop = offset;
      if (! lookup_line (abfd, debug_info, debug_swap, line_info))
	{
	  line_info->cache.sect = NULL;
	  return FALSE;
	}
    }

  *filename_ptr = line_info->cache.filename;
  *functionname_ptr = line_info->cache.functionname;
  *retline_ptr = line_info->cache.line_num;

  return TRUE;
}

/* These routines copy symbolic information into a memory buffer.

   FIXME: The whole point of the shuffle code is to avoid storing
   everything in memory, since the linker is such a memory hog.  This
   code makes that effort useless.  It is only called by the MIPS ELF
   code when generating a shared library, so it is not that big a
   deal, but it should be fixed eventually.  */

/* Collect a shuffle into a memory buffer.  */

static bfd_boolean
ecoff_collect_shuffle (struct shuffle *l, bfd_byte *buff)
{
  unsigned long total;

  total = 0;
  for (; l != (struct shuffle *) NULL; l = l->next)
    {
      if (! l->filep)
	memcpy (buff, l->u.memory, l->size);
      else
	{
	  if (bfd_seek (l->u.file.input_bfd, l->u.file.offset, SEEK_SET) != 0
	      || (bfd_bread (buff, (bfd_size_type) l->size, l->u.file.input_bfd)
		  != l->size))
	    return FALSE;
	}
      total += l->size;
      buff += l->size;
    }

  return TRUE;
}

/* Copy PDR information into a memory buffer.  */

bfd_boolean
_bfd_ecoff_get_accumulated_pdr (void * handle,
				bfd_byte *buff)
{
  struct accumulate *ainfo = (struct accumulate *) handle;

  return ecoff_collect_shuffle (ainfo->pdr, buff);
}

/* Copy symbol information into a memory buffer.  */

bfd_boolean
_bfd_ecoff_get_accumulated_sym (void * handle, bfd_byte *buff)
{
  struct accumulate *ainfo = (struct accumulate *) handle;

  return ecoff_collect_shuffle (ainfo->sym, buff);
}

/* Copy the string table into a memory buffer.  */

bfd_boolean
_bfd_ecoff_get_accumulated_ss (void * handle, bfd_byte *buff)
{
  struct accumulate *ainfo = (struct accumulate *) handle;
  struct string_hash_entry *sh;
  unsigned long total;

  /* The string table is written out from the hash table if this is a
     final link.  */
  BFD_ASSERT (ainfo->ss == (struct shuffle *) NULL);
  *buff++ = '\0';
  total = 1;
  BFD_ASSERT (ainfo->ss_hash == NULL || ainfo->ss_hash->val == 1);
  for (sh = ainfo->ss_hash;
       sh != (struct string_hash_entry *) NULL;
       sh = sh->next)
    {
      size_t len;

      len = strlen (sh->root.string);
      memcpy (buff, sh->root.string, len + 1);
      total += len + 1;
      buff += len + 1;
    }

  return TRUE;
}
