/* Routines to link ECOFF debugging information.
   Copyright (C) 1993-2021 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 "ecoff-bfd.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;
  size_t 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 we 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,
			      bfd_get_filename (input_bfd));
  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;

  free (buff);
  return TRUE;
 error_return:
  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 (symhdr->count != 0					\
      && 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 (amt != 0 && 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 (amt != 0 && bfd_bwrite (debug->external_ext, amt, abfd) != amt)
    goto error_return;

  free (space);
  return TRUE;

 error_return:
  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)
	{
	  free (line_info->find_buffer);
	  buffer = (char *) bfd_malloc ((bfd_size_type) len);
	  line_info->find_buffer = buffer;
	  if (buffer == NULL)
	    return FALSE;
	}

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