/* Support for the generic parts of COFF, for BFD.
   Copyright (C) 1990-2025 Free Software Foundation, Inc.
   Written by Cygnus Support.

   This file is part of BFD, the Binary File Descriptor library.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

/* Most of this hacked by  Steve Chamberlain, sac@cygnus.com.
   Split out of coffcode.h by Ian Taylor, ian@cygnus.com.  */

/* This file contains COFF code that is not dependent on any
   particular COFF target.  There is only one version of this file in
   libbfd.a, so no target specific code may be put in here.  Or, to
   put it another way,

   ********** DO NOT PUT TARGET SPECIFIC CODE IN THIS FILE **********

   If you need to add some target specific behaviour, add a new hook
   function to bfd_coff_backend_data.

   Some of these functions are also called by the ECOFF routines.
   Those functions may not use any COFF specific information, such as
   coff_data (abfd).  */

#include "sysdep.h"
#include <limits.h>
#include "bfd.h"
#include "libbfd.h"
#include "coff/internal.h"
#include "libcoff.h"
#include "elf-bfd.h"
#include "hashtab.h"
#include "safe-ctype.h"

/* Extract a long section name at STRINDEX and copy it to the bfd objstack.
   Return NULL in case of error.  */

static char *
extract_long_section_name(bfd *abfd, unsigned long strindex)
{
  const char *strings;
  char *name;

  strings = _bfd_coff_read_string_table (abfd);
  if (strings == NULL)
    return NULL;
  if ((bfd_size_type)(strindex + 2) >= obj_coff_strings_len (abfd))
    return NULL;
  strings += strindex;
  name = (char *) bfd_alloc (abfd, (bfd_size_type) strlen (strings) + 1);
  if (name == NULL)
    return NULL;
  strcpy (name, strings);

  return name;
}

/* Decode a base 64 coded string at STR of length LEN, and write the result
   to RES.  Return true on success.
   Return false in case of invalid character or overflow.  */

static bool
decode_base64 (const char *str, unsigned len, uint32_t *res)
{
  unsigned i;
  uint32_t val;

  val = 0;
  for (i = 0; i < len; i++)
    {
      char c = str[i];
      unsigned d;

      if (c >= 'A' && c <= 'Z')
	d = c - 'A';
      else if (c >= 'a' && c <= 'z')
	d = c - 'a' + 26;
      else if (c >= '0' && c <= '9')
	d = c - '0' + 52;
      else if (c == '+')
	d = 62;
      else if (c == '/')
	d = 63;
      else
	return false;

      /* Check for overflow. */
      if ((val >> 26) != 0)
	return false;

      val = (val << 6) + d;
    }

  *res = val;
  return true;
}

/* Take a section header read from a coff file (in HOST byte order),
   and make a BFD "section" out of it.  This is used by ECOFF.  */

static bool
make_a_section_from_file (bfd *abfd,
			  struct internal_scnhdr *hdr,
			  unsigned int target_index)
{
  asection *newsect;
  char *name;
  bool result = true;
  flagword flags;

  name = NULL;

  /* Handle long section names as in PE.  On reading, we want to
    accept long names if the format permits them at all, regardless
    of the current state of the flag that dictates if we would generate
    them in outputs; this construct checks if that is the case by
    attempting to set the flag, without changing its state; the call
    will fail for formats that do not support long names at all.  */
  if (bfd_coff_set_long_section_names (abfd, bfd_coff_long_section_names (abfd))
      && hdr->s_name[0] == '/')
    {
      /* Flag that this BFD uses long names, even though the format might
	 expect them to be off by default.  This won't directly affect the
	 format of any output BFD created from this one, but the information
	 can be used to decide what to do.  */
      bfd_coff_set_long_section_names (abfd, true);

      if (hdr->s_name[1] == '/')
	{
	  /* LLVM extension: the '/' is followed by another '/' and then by
	     the index in the strtab encoded in base64 without NUL at the
	     end.  */
	  uint32_t strindex;

	  /* Decode the index.  No overflow is expected as the string table
	     length is at most 2^32 - 1 (the length is written on the first
	     four bytes).
	     Also, contrary to RFC 4648, all the characters must be decoded,
	     there is no padding.  */
	  if (!decode_base64 (hdr->s_name + 2, SCNNMLEN - 2, &strindex))
	    return false;

	  name = extract_long_section_name (abfd, strindex);
	  if (name == NULL)
	    return false;
	}
      else
	{
	  /* PE classic long section name.  The '/' is followed by the index
	     in the strtab.  The index is formatted as a decimal string.  */
	  char buf[SCNNMLEN];
	  long strindex;
	  char *p;

	  memcpy (buf, hdr->s_name + 1, SCNNMLEN - 1);
	  buf[SCNNMLEN - 1] = '\0';
	  strindex = strtol (buf, &p, 10);
	  if (*p == '\0' && strindex >= 0)
	    {
	      name = extract_long_section_name (abfd, strindex);
	      if (name == NULL)
		return false;
	    }
	}
    }

  if (name == NULL)
    {
      /* Assorted wastage to null-terminate the name, thanks AT&T! */
      name = (char *) bfd_alloc (abfd,
				 (bfd_size_type) sizeof (hdr->s_name) + 1 + 1);
      if (name == NULL)
	return false;
      strncpy (name, (char *) &hdr->s_name[0], sizeof (hdr->s_name));
      name[sizeof (hdr->s_name)] = 0;
    }

  newsect = bfd_make_section_anyway (abfd, name);
  if (newsect == NULL)
    return false;

  newsect->vma = hdr->s_vaddr;
  newsect->lma = hdr->s_paddr;
  newsect->size = hdr->s_size;
  newsect->filepos = hdr->s_scnptr;
  newsect->rel_filepos = hdr->s_relptr;
  newsect->reloc_count = hdr->s_nreloc;

  bfd_coff_set_alignment_hook (abfd, newsect, hdr);

  newsect->line_filepos = hdr->s_lnnoptr;

  newsect->lineno_count = hdr->s_nlnno;
  newsect->userdata = NULL;
  newsect->next = NULL;
  newsect->target_index = target_index;

  if (!bfd_coff_styp_to_sec_flags_hook (abfd, hdr, name, newsect, &flags))
    result = false;

  /* At least on i386-coff, the line number count for a shared library
     section must be ignored.  */
  if ((flags & SEC_COFF_SHARED_LIBRARY) != 0)
    newsect->lineno_count = 0;

  if (hdr->s_nreloc != 0)
    flags |= SEC_RELOC;
  /* FIXME: should this check 'hdr->s_size > 0'.  */
  if (hdr->s_scnptr != 0)
    flags |= SEC_HAS_CONTENTS;

  newsect->flags = flags;

  /* Compress/decompress DWARF debug sections.  */
  if ((flags & SEC_DEBUGGING) != 0
      && (flags & SEC_HAS_CONTENTS) != 0
      && (startswith (name, ".debug_")
	  || startswith (name, ".zdebug_")
	  || startswith (name, ".gnu.debuglto_.debug_")
	  || startswith (name, ".gnu.linkonce.wi.")))
    {
      enum { nothing, compress, decompress } action = nothing;

      if (bfd_is_section_compressed (abfd, newsect))
	{
	  /* Compressed section.  Check if we should decompress.  */
	  if ((abfd->flags & BFD_DECOMPRESS))
	    action = decompress;
	}
      else
	{
	  /* Normal section.  Check if we should compress.  */
	  if ((abfd->flags & BFD_COMPRESS) && newsect->size != 0)
	    action = compress;
	}

      if (action == compress)
	{
	  if (!bfd_init_section_compress_status (abfd, newsect))
	    {
	      _bfd_error_handler
		/* xgettext:c-format */
		(_("%pB: unable to compress section %s"), abfd, name);
	      return false;
	    }
	}
      else if (action == decompress)
	{
	  if (!bfd_init_section_decompress_status (abfd, newsect))
	    {
	      _bfd_error_handler
		/* xgettext:c-format */
		(_("%pB: unable to decompress section %s"), abfd, name);
	      return false;
	    }
	  if (abfd->is_linker_input
	      && name[1] == 'z')
	    {
	      /* Rename section from .zdebug_* to .debug_* so that ld
		 scripts will see this section as a debug section.  */
	      char *new_name = bfd_zdebug_name_to_debug (abfd, name);
	      if (new_name == NULL)
		return false;
	      bfd_rename_section (newsect, new_name);
	    }
	}
    }

  return result;
}

void
coff_object_cleanup (bfd *abfd)
{
  struct coff_tdata *td = coff_data (abfd);
  if (td != NULL)
    {
      if (td->section_by_index)
	htab_delete (td->section_by_index);
      if (td->section_by_target_index)
	htab_delete (td->section_by_target_index);
      if (obj_pe (abfd) && pe_data (abfd)->comdat_hash)
	htab_delete (pe_data (abfd)->comdat_hash);
    }
}

/* Read in a COFF object and make it into a BFD.  This is used by
   ECOFF as well.  */
bfd_cleanup
coff_real_object_p (bfd *abfd,
		    unsigned nscns,
		    struct internal_filehdr *internal_f,
		    struct internal_aouthdr *internal_a)
{
  flagword oflags = abfd->flags;
  bfd_vma ostart = bfd_get_start_address (abfd);
  void * tdata;
  bfd_size_type readsize;	/* Length of file_info.  */
  unsigned int scnhsz;
  char *external_sections;

  if (!(internal_f->f_flags & F_RELFLG))
    abfd->flags |= HAS_RELOC;
  if ((internal_f->f_flags & F_EXEC))
    abfd->flags |= EXEC_P;
  if (!(internal_f->f_flags & F_LNNO))
    abfd->flags |= HAS_LINENO;
  if (!(internal_f->f_flags & F_LSYMS))
    abfd->flags |= HAS_LOCALS;

  /* FIXME: How can we set D_PAGED correctly?  */
  if ((internal_f->f_flags & F_EXEC) != 0)
    abfd->flags |= D_PAGED;

  abfd->symcount = internal_f->f_nsyms;
  if (internal_f->f_nsyms)
    abfd->flags |= HAS_SYMS;

  if (internal_a != (struct internal_aouthdr *) NULL)
    abfd->start_address = internal_a->entry;
  else
    abfd->start_address = 0;

  /* Set up the tdata area.  ECOFF uses its own routine, and overrides
     abfd->flags.  */
  tdata = bfd_coff_mkobject_hook (abfd, (void *) internal_f, (void *) internal_a);
  if (tdata == NULL)
    goto fail2;

  scnhsz = bfd_coff_scnhsz (abfd);
  readsize = (bfd_size_type) nscns * scnhsz;
  external_sections = (char *) _bfd_alloc_and_read (abfd, readsize, readsize);
  if (!external_sections)
    goto fail;

  /* Set the arch/mach *before* swapping in sections; section header swapping
     may depend on arch/mach info.  */
  if (! bfd_coff_set_arch_mach_hook (abfd, (void *) internal_f))
    goto fail;

  /* Now copy data as required; construct all asections etc.  */
  if (nscns != 0)
    {
      unsigned int i;
      for (i = 0; i < nscns; i++)
	{
	  struct internal_scnhdr tmp;
	  bfd_coff_swap_scnhdr_in (abfd,
				   (void *) (external_sections + i * scnhsz),
				   (void *) & tmp);
	  if (! make_a_section_from_file (abfd, &tmp, i + 1))
	    goto fail;
	}
    }

  _bfd_coff_free_symbols (abfd);
  return coff_object_cleanup;

 fail:
  coff_object_cleanup (abfd);
  _bfd_coff_free_symbols (abfd);
  bfd_release (abfd, tdata);
 fail2:
  abfd->flags = oflags;
  abfd->start_address = ostart;
  return NULL;
}

/* Turn a COFF file into a BFD, but fail with bfd_error_wrong_format if it is
   not a COFF file.  This is also used by ECOFF.  */

bfd_cleanup
coff_object_p (bfd *abfd)
{
  bfd_size_type filhsz;
  bfd_size_type aoutsz;
  unsigned int nscns;
  void * filehdr;
  struct internal_filehdr internal_f;
  struct internal_aouthdr internal_a;

  /* Figure out how much to read.  */
  filhsz = bfd_coff_filhsz (abfd);
  aoutsz = bfd_coff_aoutsz (abfd);

  filehdr = _bfd_alloc_and_read (abfd, filhsz, filhsz);
  if (filehdr == NULL)
    {
      if (bfd_get_error () != bfd_error_system_call)
	bfd_set_error (bfd_error_wrong_format);
      return NULL;
    }
  bfd_coff_swap_filehdr_in (abfd, filehdr, &internal_f);
  bfd_release (abfd, filehdr);

  /* The XCOFF format has two sizes for the f_opthdr.  SMALL_AOUTSZ
     (less than aoutsz) used in object files and AOUTSZ (equal to
     aoutsz) in executables.  The bfd_coff_swap_aouthdr_in function
     expects this header to be aoutsz bytes in length, so we use that
     value in the call to bfd_alloc below.  But we must be careful to
     only read in f_opthdr bytes in the call to bfd_read.  We should
     also attempt to catch corrupt or non-COFF binaries with a strange
     value for f_opthdr.  */
  if (! bfd_coff_bad_format_hook (abfd, &internal_f)
      || internal_f.f_opthdr > aoutsz)
    {
      bfd_set_error (bfd_error_wrong_format);
      return NULL;
    }
  nscns = internal_f.f_nscns;

  if (internal_f.f_opthdr)
    {
      void * opthdr;

      opthdr = _bfd_alloc_and_read (abfd, aoutsz, internal_f.f_opthdr);
      if (opthdr == NULL)
	return NULL;
      /* PR 17512: file: 11056-1136-0.004.  */
      if (internal_f.f_opthdr < aoutsz)
	memset (((char *) opthdr) + internal_f.f_opthdr, 0,
		aoutsz - internal_f.f_opthdr);

      bfd_coff_swap_aouthdr_in (abfd, opthdr, (void *) &internal_a);
      bfd_release (abfd, opthdr);
    }

  return coff_real_object_p (abfd, nscns, &internal_f,
			     (internal_f.f_opthdr != 0
			      ? &internal_a
			      : (struct internal_aouthdr *) NULL));
}

static hashval_t
htab_hash_section_target_index (const void * entry)
{
  const struct bfd_section * sec = entry;
  return sec->target_index;
}

static int
htab_eq_section_target_index (const void * e1, const void * e2)
{
  const struct bfd_section * sec1 = e1;
  const struct bfd_section * sec2 = e2;
  return sec1->target_index == sec2->target_index;
}

/* Get the BFD section from a COFF symbol section number.  */

asection *
coff_section_from_bfd_index (bfd *abfd, int section_index)
{
  if (section_index == N_ABS)
    return bfd_abs_section_ptr;
  if (section_index == N_UNDEF)
    return bfd_und_section_ptr;
  if (section_index == N_DEBUG)
    return bfd_abs_section_ptr;

  struct bfd_section *answer;
  htab_t table = coff_data (abfd)->section_by_target_index;

  if (!table)
    {
      table = htab_create (10, htab_hash_section_target_index,
			   htab_eq_section_target_index, NULL);
      if (table == NULL)
	return bfd_und_section_ptr;
      coff_data (abfd)->section_by_target_index = table;
    }

  if (htab_elements (table) == 0)
    {
      for (answer = abfd->sections; answer; answer = answer->next)
	{
	  void **slot = htab_find_slot (table, answer, INSERT);
	  if (slot == NULL)
	    return bfd_und_section_ptr;
	  *slot = answer;
	}
    }

  struct bfd_section needle;
  needle.target_index = section_index;

  answer = htab_find (table, &needle);
  if (answer != NULL)
    return answer;

  /* Cover the unlikely case of sections added after the first call to
     this function.  */
  for (answer = abfd->sections; answer; answer = answer->next)
    if (answer->target_index == section_index)
      {
	void **slot = htab_find_slot (table, answer, INSERT);
	if (slot != NULL)
	  *slot = answer;
	return answer;
      }

  /* We should not reach this point, but the SCO 3.2v4 /lib/libc_s.a
     has a bad symbol table in biglitpow.o.  */
  return bfd_und_section_ptr;
}

/* Get the upper bound of a COFF symbol table.  */

long
coff_get_symtab_upper_bound (bfd *abfd)
{
  if (!bfd_coff_slurp_symbol_table (abfd))
    return -1;

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

/* Canonicalize a COFF symbol table.  */

long
coff_canonicalize_symtab (bfd *abfd, asymbol **alocation)
{
  unsigned int counter;
  coff_symbol_type *symbase;
  coff_symbol_type **location = (coff_symbol_type **) alocation;

  if (!bfd_coff_slurp_symbol_table (abfd))
    return -1;

  symbase = obj_symbols (abfd);
  counter = bfd_get_symcount (abfd);
  while (counter-- > 0)
    *location++ = symbase++;

  *location = NULL;

  return bfd_get_symcount (abfd);
}

/* Get the name of a symbol.  The caller must pass in a buffer of size
   >= SYMNMLEN + 1.  */

const char *
_bfd_coff_internal_syment_name (bfd *abfd,
				const struct internal_syment *sym,
				char *buf)
{
  /* FIXME: It's not clear this will work correctly if sizeof
     (_n_zeroes) != 4.  */
  if (sym->_n._n_n._n_zeroes != 0
      || sym->_n._n_n._n_offset == 0)
    {
      memcpy (buf, sym->_n._n_name, SYMNMLEN);
      buf[SYMNMLEN] = '\0';
      return buf;
    }
  else
    {
      const char *strings;

      BFD_ASSERT (sym->_n._n_n._n_offset >= STRING_SIZE_SIZE);
      strings = obj_coff_strings (abfd);
      if (strings == NULL)
	{
	  strings = _bfd_coff_read_string_table (abfd);
	  if (strings == NULL)
	    return NULL;
	}
      if (sym->_n._n_n._n_offset >= obj_coff_strings_len (abfd))
	return NULL;
      return strings + sym->_n._n_n._n_offset;
    }
}

/* Read in and swap the relocs.  This returns a buffer holding the
   relocs for section SEC in file ABFD.  If CACHE is TRUE and
   INTERNAL_RELOCS is NULL, the relocs read in will be saved in case
   the function is called again.  If EXTERNAL_RELOCS is not NULL, it
   is a buffer large enough to hold the unswapped relocs.  If
   INTERNAL_RELOCS is not NULL, it is a buffer large enough to hold
   the swapped relocs.  If REQUIRE_INTERNAL is TRUE, then the return
   value must be INTERNAL_RELOCS.  The function returns NULL on error.  */

struct internal_reloc *
_bfd_coff_read_internal_relocs (bfd *abfd,
				asection *sec,
				bool cache,
				bfd_byte *external_relocs,
				bool require_internal,
				struct internal_reloc *internal_relocs)
{
  bfd_size_type relsz;
  bfd_byte *free_external = NULL;
  struct internal_reloc *free_internal = NULL;
  bfd_byte *erel;
  bfd_byte *erel_end;
  struct internal_reloc *irel;
  bfd_size_type amt;

  if (sec->reloc_count == 0)
    return internal_relocs;	/* Nothing to do.  */

  if (coff_section_data (abfd, sec) != NULL
      && coff_section_data (abfd, sec)->relocs != NULL)
    {
      if (! require_internal)
	return coff_section_data (abfd, sec)->relocs;
      memcpy (internal_relocs, coff_section_data (abfd, sec)->relocs,
	      sec->reloc_count * sizeof (struct internal_reloc));
      return internal_relocs;
    }

  relsz = bfd_coff_relsz (abfd);

  amt = sec->reloc_count * relsz;
  if (external_relocs == NULL)
    {
      free_external = (bfd_byte *) bfd_malloc (amt);
      if (free_external == NULL)
	goto error_return;
      external_relocs = free_external;
    }

  if (bfd_seek (abfd, sec->rel_filepos, SEEK_SET) != 0
      || bfd_read (external_relocs, amt, abfd) != amt)
    goto error_return;

  if (internal_relocs == NULL)
    {
      amt = sec->reloc_count;
      amt *= sizeof (struct internal_reloc);
      free_internal = (struct internal_reloc *) bfd_malloc (amt);
      if (free_internal == NULL)
	goto error_return;
      internal_relocs = free_internal;
    }

  /* Swap in the relocs.  */
  erel = external_relocs;
  erel_end = erel + relsz * sec->reloc_count;
  irel = internal_relocs;
  for (; erel < erel_end; erel += relsz, irel++)
    bfd_coff_swap_reloc_in (abfd, (void *) erel, (void *) irel);

  free (free_external);
  free_external = NULL;

  if (cache && free_internal != NULL)
    {
      if (coff_section_data (abfd, sec) == NULL)
	{
	  amt = sizeof (struct coff_section_tdata);
	  sec->used_by_bfd = bfd_zalloc (abfd, amt);
	  if (sec->used_by_bfd == NULL)
	    goto error_return;
	  coff_section_data (abfd, sec)->contents = NULL;
	}
      coff_section_data (abfd, sec)->relocs = free_internal;
    }

  return internal_relocs;

 error_return:
  free (free_external);
  free (free_internal);
  return NULL;
}

/* Set lineno_count for the output sections of a COFF file.  */

int
coff_count_linenumbers (bfd *abfd)
{
  unsigned int limit = bfd_get_symcount (abfd);
  unsigned int i;
  int total = 0;
  asymbol **p;
  asection *s;

  if (limit == 0)
    {
      /* This may be from the backend linker, in which case the
	 lineno_count in the sections is correct.  */
      for (s = abfd->sections; s != NULL; s = s->next)
	total += s->lineno_count;
      return total;
    }

  for (s = abfd->sections; s != NULL; s = s->next)
    BFD_ASSERT (s->lineno_count == 0);

  for (p = abfd->outsymbols, i = 0; i < limit; i++, p++)
    {
      asymbol *q_maybe = *p;

      if (bfd_asymbol_bfd (q_maybe) != NULL
	  && bfd_family_coff (bfd_asymbol_bfd (q_maybe)))
	{
	  coff_symbol_type *q = coffsymbol (q_maybe);

	  /* The AIX 4.1 compiler can sometimes generate line numbers
	     attached to debugging symbols.  We try to simply ignore
	     those here.  */
	  if (q->lineno != NULL
	      && q->symbol.section->owner != NULL)
	    {
	      /* This symbol has line numbers.  Increment the owning
		 section's linenumber count.  */
	      alent *l = q->lineno;

	      do
		{
		  asection * sec = q->symbol.section->output_section;

		  /* Do not try to update fields in read-only sections.  */
		  if (! bfd_is_const_section (sec))
		    sec->lineno_count ++;

		  ++total;
		  ++l;
		}
	      while (l->line_number != 0);
	    }
	}
    }

  return total;
}

static void
fixup_symbol_value (bfd *abfd,
		    coff_symbol_type *coff_symbol_ptr,
		    struct internal_syment *syment)
{
  /* Normalize the symbol flags.  */
  if (coff_symbol_ptr->symbol.section
      && bfd_is_com_section (coff_symbol_ptr->symbol.section))
    {
      /* A common symbol is undefined with a value.  */
      syment->n_scnum = N_UNDEF;
      syment->n_value = coff_symbol_ptr->symbol.value;
    }
  else if ((coff_symbol_ptr->symbol.flags & BSF_DEBUGGING) != 0
	   && (coff_symbol_ptr->symbol.flags & BSF_DEBUGGING_RELOC) == 0)
    {
      syment->n_value = coff_symbol_ptr->symbol.value;
    }
  else if (bfd_is_und_section (coff_symbol_ptr->symbol.section))
    {
      syment->n_scnum = N_UNDEF;
      syment->n_value = 0;
    }
  /* FIXME: Do we need to handle the absolute section here?  */
  else
    {
      if (coff_symbol_ptr->symbol.section)
	{
	  syment->n_scnum =
	    coff_symbol_ptr->symbol.section->output_section->target_index;

	  syment->n_value = (coff_symbol_ptr->symbol.value
			     + coff_symbol_ptr->symbol.section->output_offset);
	  if (! obj_pe (abfd))
	    {
	      syment->n_value += (syment->n_sclass == C_STATLAB)
		? coff_symbol_ptr->symbol.section->output_section->lma
		: coff_symbol_ptr->symbol.section->output_section->vma;
	    }
	}
      else
	{
	  BFD_ASSERT (0);
	  /* This can happen, but I don't know why yet (steve@cygnus.com) */
	  syment->n_scnum = N_ABS;
	  syment->n_value = coff_symbol_ptr->symbol.value;
	}
    }
}

/* Run through all the symbols in the symbol table and work out what
   their indexes into the symbol table will be when output.

   Coff requires that each C_FILE symbol points to the next one in the
   chain, and that the last one points to the first external symbol. We
   do that here too.  */

bool
coff_renumber_symbols (bfd *bfd_ptr, int *first_undef)
{
  unsigned int symbol_count = bfd_get_symcount (bfd_ptr);
  asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols;
  unsigned int native_index = 0;
  struct internal_syment *last_file = NULL;
  unsigned int symbol_index;

  /* COFF demands that undefined symbols come after all other symbols.
     Since we don't need to impose this extra knowledge on all our
     client programs, deal with that here.  Sort the symbol table;
     just move the undefined symbols to the end, leaving the rest
     alone.  The O'Reilly book says that defined global symbols come
     at the end before the undefined symbols, so we do that here as
     well.  */
  /* @@ Do we have some condition we could test for, so we don't always
     have to do this?  I don't think relocatability is quite right, but
     I'm not certain.  [raeburn:19920508.1711EST]  */
  {
    asymbol **newsyms;
    unsigned int i;
    bfd_size_type amt;

    amt = sizeof (asymbol *) * ((bfd_size_type) symbol_count + 1);
    newsyms = (asymbol **) bfd_alloc (bfd_ptr, amt);
    if (!newsyms)
      return false;
    bfd_ptr->outsymbols = newsyms;
    for (i = 0; i < symbol_count; i++)
      if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END) != 0
	  || (!bfd_is_und_section (symbol_ptr_ptr[i]->section)
	      && !bfd_is_com_section (symbol_ptr_ptr[i]->section)
	      && ((symbol_ptr_ptr[i]->flags & BSF_FUNCTION) != 0
		  || ((symbol_ptr_ptr[i]->flags & (BSF_GLOBAL | BSF_WEAK))
		      == 0))))
	*newsyms++ = symbol_ptr_ptr[i];

    for (i = 0; i < symbol_count; i++)
      if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END) == 0
	  && !bfd_is_und_section (symbol_ptr_ptr[i]->section)
	  && (bfd_is_com_section (symbol_ptr_ptr[i]->section)
	      || ((symbol_ptr_ptr[i]->flags & BSF_FUNCTION) == 0
		  && ((symbol_ptr_ptr[i]->flags & (BSF_GLOBAL | BSF_WEAK))
		      != 0))))
	*newsyms++ = symbol_ptr_ptr[i];

    *first_undef = newsyms - bfd_ptr->outsymbols;

    for (i = 0; i < symbol_count; i++)
      if ((symbol_ptr_ptr[i]->flags & BSF_NOT_AT_END) == 0
	  && bfd_is_und_section (symbol_ptr_ptr[i]->section))
	*newsyms++ = symbol_ptr_ptr[i];
    *newsyms = (asymbol *) NULL;
    symbol_ptr_ptr = bfd_ptr->outsymbols;
  }

  for (symbol_index = 0; symbol_index < symbol_count; symbol_index++)
    {
      coff_symbol_type *coff_symbol_ptr;

      coff_symbol_ptr = coff_symbol_from (symbol_ptr_ptr[symbol_index]);
      symbol_ptr_ptr[symbol_index]->udata.i = symbol_index;
      if (coff_symbol_ptr && coff_symbol_ptr->native)
	{
	  combined_entry_type *s = coff_symbol_ptr->native;
	  int i;

	  BFD_ASSERT (s->is_sym);
	  if (s->u.syment.n_sclass == C_FILE)
	    {
	      if (last_file != NULL)
		last_file->n_value = native_index;
	      last_file = &(s->u.syment);
	    }
	  else
	    /* Modify the symbol values according to their section and
	       type.  */
	    fixup_symbol_value (bfd_ptr, coff_symbol_ptr, &(s->u.syment));

	  for (i = 0; i < s->u.syment.n_numaux + 1; i++)
	    s[i].offset = native_index++;
	}
      else
	native_index++;
    }

  obj_conv_table_size (bfd_ptr) = native_index;

  return true;
}

/* Run thorough the symbol table again, and fix it so that all
   pointers to entries are changed to the entries' index in the output
   symbol table.  */

void
coff_mangle_symbols (bfd *bfd_ptr)
{
  unsigned int symbol_count = bfd_get_symcount (bfd_ptr);
  asymbol **symbol_ptr_ptr = bfd_ptr->outsymbols;
  unsigned int symbol_index;

  for (symbol_index = 0; symbol_index < symbol_count; symbol_index++)
    {
      coff_symbol_type *coff_symbol_ptr;

      coff_symbol_ptr = coff_symbol_from (symbol_ptr_ptr[symbol_index]);
      if (coff_symbol_ptr && coff_symbol_ptr->native)
	{
	  int i;
	  combined_entry_type *s = coff_symbol_ptr->native;

	  BFD_ASSERT (s->is_sym);
	  if (s->fix_value)
	    {
	      /* FIXME: We should use a union here.  */
	      s->u.syment.n_value =
		(uintptr_t) ((combined_entry_type *)
			     (uintptr_t) s->u.syment.n_value)->offset;
	      s->fix_value = 0;
	    }
	  if (s->fix_line)
	    {
	      /* The value is the offset into the line number entries
		 for the symbol's section.  On output, the symbol's
		 section should be N_DEBUG.  */
	      s->u.syment.n_value =
		(coff_symbol_ptr->symbol.section->output_section->line_filepos
		 + s->u.syment.n_value * bfd_coff_linesz (bfd_ptr));
	      coff_symbol_ptr->symbol.section =
		coff_section_from_bfd_index (bfd_ptr, N_DEBUG);
	      BFD_ASSERT (coff_symbol_ptr->symbol.flags & BSF_DEBUGGING);
	    }
	  for (i = 0; i < s->u.syment.n_numaux; i++)
	    {
	      combined_entry_type *a = s + i + 1;

	      BFD_ASSERT (! a->is_sym);
	      if (a->fix_tag)
		{
		  a->u.auxent.x_sym.x_tagndx.u32 =
		    a->u.auxent.x_sym.x_tagndx.p->offset;
		  a->fix_tag = 0;
		}
	      if (a->fix_end)
		{
		  a->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.u32 =
		    a->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p->offset;
		  a->fix_end = 0;
		}
	      if (a->fix_scnlen)
		{
		  a->u.auxent.x_csect.x_scnlen.u64 =
		    a->u.auxent.x_csect.x_scnlen.p->offset;
		  a->fix_scnlen = 0;
		}
	    }
	}
    }
}

static bool
coff_write_auxent_fname (bfd *abfd,
			 char *str,
			 union internal_auxent *auxent,
			 struct bfd_strtab_hash *strtab,
			 bool hash)
{
  unsigned int str_length = strlen (str);
  unsigned int filnmlen = bfd_coff_filnmlen (abfd);

  if (bfd_coff_long_filenames (abfd))
    {
      if (str_length <= filnmlen)
	strncpy (auxent->x_file.x_n.x_fname, str, filnmlen);
      else
	{
	  bfd_size_type indx = _bfd_stringtab_add (strtab, str, hash, false);

	  if (indx == (bfd_size_type) -1)
	    return false;

	  auxent->x_file.x_n.x_n.x_offset = STRING_SIZE_SIZE + indx;
	  auxent->x_file.x_n.x_n.x_zeroes = 0;
	}
    }
  else
    {
      strncpy (auxent->x_file.x_n.x_fname, str, filnmlen);
      if (str_length > filnmlen)
	str[filnmlen] = '\0';
    }

  return true;
}

static bool
coff_fix_symbol_name (bfd *abfd,
		      asymbol *symbol,
		      combined_entry_type *native,
		      struct bfd_strtab_hash *strtab,
		      bool hash,
		      asection **debug_string_section_p,
		      bfd_size_type *debug_string_size_p)
{
  unsigned int name_length;
  char *name = (char *) (symbol->name);
  bfd_size_type indx;

  if (name == NULL)
    {
      /* COFF symbols always have names, so we'll make one up.  */
      symbol->name = "strange";
      name = (char *) symbol->name;
    }
  name_length = strlen (name);

  BFD_ASSERT (native->is_sym);
  if (native->u.syment.n_sclass == C_FILE
      && native->u.syment.n_numaux > 0)
    {
      if (bfd_coff_force_symnames_in_strings (abfd))
	{
	  indx = _bfd_stringtab_add (strtab, ".file", hash, false);
	  if (indx == (bfd_size_type) -1)
	    return false;

	  native->u.syment._n._n_n._n_offset = STRING_SIZE_SIZE + indx;
	  native->u.syment._n._n_n._n_zeroes = 0;
	}
      else
	strncpy (native->u.syment._n._n_name, ".file", SYMNMLEN);

      BFD_ASSERT (! (native + 1)->is_sym);
      if (!coff_write_auxent_fname (abfd, name, &(native + 1)->u.auxent,
			       strtab, hash))
	return false;
    }
  else
    {
      if (name_length <= SYMNMLEN && !bfd_coff_force_symnames_in_strings (abfd))
	/* This name will fit into the symbol neatly.  */
	strncpy (native->u.syment._n._n_name, symbol->name, SYMNMLEN);

      else if (!bfd_coff_symname_in_debug (abfd, &native->u.syment))
	{
	  indx = _bfd_stringtab_add (strtab, name, hash, false);
	  if (indx == (bfd_size_type) -1)
	    return false;

	  native->u.syment._n._n_n._n_offset = STRING_SIZE_SIZE + indx;
	  native->u.syment._n._n_n._n_zeroes = 0;
	}
      else
	{
	  file_ptr filepos;
	  bfd_byte buf[4];
	  int prefix_len = bfd_coff_debug_string_prefix_length (abfd);

	  /* This name should be written into the .debug section.  For
	     some reason each name is preceded by a two byte length
	     and also followed by a null byte.  FIXME: We assume that
	     the .debug section has already been created, and that it
	     is large enough.  */
	  if (*debug_string_section_p == (asection *) NULL)
	    *debug_string_section_p = bfd_get_section_by_name (abfd, ".debug");
	  filepos = bfd_tell (abfd);
	  if (prefix_len == 4)
	    bfd_put_32 (abfd, (bfd_vma) (name_length + 1), buf);
	  else
	    bfd_put_16 (abfd, (bfd_vma) (name_length + 1), buf);

	  if (!bfd_set_section_contents (abfd,
					 *debug_string_section_p,
					 (void *) buf,
					 (file_ptr) *debug_string_size_p,
					 (bfd_size_type) prefix_len)
	      || !bfd_set_section_contents (abfd,
					    *debug_string_section_p,
					    (void *) symbol->name,
					    (file_ptr) (*debug_string_size_p
							+ prefix_len),
					    (bfd_size_type) name_length + 1))
	    abort ();
	  if (bfd_seek (abfd, filepos, SEEK_SET) != 0)
	    abort ();
	  native->u.syment._n._n_n._n_offset =
	      *debug_string_size_p + prefix_len;
	  native->u.syment._n._n_n._n_zeroes = 0;
	  *debug_string_size_p += name_length + 1 + prefix_len;
	}
    }

  return true;
}

/* We need to keep track of the symbol index so that when we write out
   the relocs we can get the index for a symbol.  This method is a
   hack.  FIXME.  */

#define set_index(symbol, idx)	((symbol)->udata.i = (idx))

/* Write a symbol out to a COFF file.  */

static bool
coff_write_symbol (bfd *abfd,
		   asymbol *symbol,
		   combined_entry_type *native,
		   bfd_vma *written,
		   struct bfd_strtab_hash *strtab,
		   bool hash,
		   asection **debug_string_section_p,
		   bfd_size_type *debug_string_size_p)
{
  unsigned int numaux = native->u.syment.n_numaux;
  int type = native->u.syment.n_type;
  int n_sclass = (int) native->u.syment.n_sclass;
  asection *output_section = symbol->section->output_section
			       ? symbol->section->output_section
			       : symbol->section;
  void * buf;
  bfd_size_type symesz;

  BFD_ASSERT (native->is_sym);

  if (native->u.syment.n_sclass == C_FILE)
    symbol->flags |= BSF_DEBUGGING;

  if (symbol->flags & BSF_DEBUGGING
      && bfd_is_abs_section (symbol->section))
    native->u.syment.n_scnum = N_DEBUG;

  else if (bfd_is_abs_section (symbol->section))
    native->u.syment.n_scnum = N_ABS;

  else if (bfd_is_und_section (symbol->section))
    native->u.syment.n_scnum = N_UNDEF;

  else
    native->u.syment.n_scnum =
      output_section->target_index;

  if (!coff_fix_symbol_name (abfd, symbol, native, strtab, hash,
			     debug_string_section_p, debug_string_size_p))
    return false;

  symesz = bfd_coff_symesz (abfd);
  buf = bfd_alloc (abfd, symesz);
  if (!buf)
    return false;
  bfd_coff_swap_sym_out (abfd, &native->u.syment, buf);
  if (bfd_write (buf, symesz, abfd) != symesz)
    return false;
  bfd_release (abfd, buf);

  if (native->u.syment.n_numaux > 0)
    {
      bfd_size_type auxesz;
      unsigned int j;

      auxesz = bfd_coff_auxesz (abfd);
      buf = bfd_alloc (abfd, auxesz);
      if (!buf)
	return false;
      for (j = 0; j < native->u.syment.n_numaux; j++)
	{
	  BFD_ASSERT (! (native + j + 1)->is_sym);

	  /* Adjust auxent only if this isn't the filename
	     auxiliary entry.  */
	  if (native->u.syment.n_sclass == C_FILE
	      && (native + j + 1)->u.auxent.x_file.x_ftype
	      && (native + j + 1)->extrap)
	    coff_write_auxent_fname (abfd, (char *) (native + j + 1)->extrap,
				     &(native + j + 1)->u.auxent, strtab, hash);

	  bfd_coff_swap_aux_out (abfd,
				 &((native + j + 1)->u.auxent),
				 type, n_sclass, (int) j,
				 native->u.syment.n_numaux,
				 buf);
	  if (bfd_write (buf, auxesz, abfd) != auxesz)
	    return false;
	}
      bfd_release (abfd, buf);
    }

  /* Store the index for use when we write out the relocs.  */
  set_index (symbol, *written);

  *written += numaux + 1;
  return true;
}

/* Write out a symbol to a COFF file that does not come from a COFF
   file originally.  This symbol may have been created by the linker,
   or we may be linking a non COFF file to a COFF file.  */

bool
coff_write_alien_symbol (bfd *abfd,
			 asymbol *symbol,
			 struct internal_syment *isym,
			 bfd_vma *written,
			 struct bfd_strtab_hash *strtab,
			 bool hash,
			 asection **debug_string_section_p,
			 bfd_size_type *debug_string_size_p)
{
  combined_entry_type *native;
  combined_entry_type dummy[2];
  asection *output_section = symbol->section->output_section
			       ? symbol->section->output_section
			       : symbol->section;
  struct bfd_link_info *link_info = coff_data (abfd)->link_info;
  bool ret;

  if ((!link_info || link_info->strip_discarded)
      && !bfd_is_abs_section (symbol->section)
      && symbol->section->output_section == bfd_abs_section_ptr)
    {
      symbol->name = "";
      if (isym != NULL)
	memset (isym, 0, sizeof (*isym));
      return true;
    }
  memset (dummy, 0, sizeof dummy);
  native = dummy;
  native->is_sym = true;
  native[1].is_sym = false;
  native->u.syment.n_type = T_NULL;
  native->u.syment.n_flags = 0;
  native->u.syment.n_numaux = 0;
  if (bfd_is_und_section (symbol->section))
    {
      native->u.syment.n_scnum = N_UNDEF;
      native->u.syment.n_value = symbol->value;
    }
  else if (bfd_is_com_section (symbol->section))
    {
      native->u.syment.n_scnum = N_UNDEF;
      native->u.syment.n_value = symbol->value;
    }
  else if (symbol->flags & BSF_FILE)
    {
      native->u.syment.n_scnum = N_DEBUG;
      native->u.syment.n_numaux = 1;
    }
  else if (symbol->flags & BSF_DEBUGGING)
    {
      /* There isn't much point to writing out a debugging symbol
	 unless we are prepared to convert it into COFF debugging
	 format.  So, we just ignore them.  We must clobber the symbol
	 name to keep it from being put in the string table.  */
      symbol->name = "";
      if (isym != NULL)
	memset (isym, 0, sizeof (*isym));
      return true;
    }
  else
    {
      native->u.syment.n_scnum = output_section->target_index;
      native->u.syment.n_value = (symbol->value
				  + symbol->section->output_offset);
      if (! obj_pe (abfd))
	native->u.syment.n_value += output_section->vma;

      /* Copy the any flags from the file header into the symbol.
	 FIXME: Why?  */
      {
	coff_symbol_type *c = coff_symbol_from (symbol);
	if (c != (coff_symbol_type *) NULL)
	  native->u.syment.n_flags = bfd_asymbol_bfd (&c->symbol)->flags;
      }

      const elf_symbol_type *elfsym = elf_symbol_from (symbol);
      if (elfsym
	  && (symbol->flags & BSF_FUNCTION)
	  && elfsym->internal_elf_sym.st_size)
	{
	  /* coff_data (abfd)->local_n_btshft is what ought to be used here,
	     just that it's set only when reading in COFF objects.  */
	  native->u.syment.n_type = DT_FCN << 4;
	  native->u.syment.n_numaux = 1;
	  native[1].u.auxent.x_sym.x_misc.x_fsize
	    = elfsym->internal_elf_sym.st_size;
	  /* FIXME .u.auxent.x_sym.x_fcnary.x_fcn.x_endndx would better also
	     be set, which would require updating the field once the next
	     function is seen.  */
	}
    }

  if (symbol->flags & BSF_FILE)
    native->u.syment.n_sclass = C_FILE;
  else if (symbol->flags & BSF_LOCAL)
    native->u.syment.n_sclass = C_STAT;
  else if (symbol->flags & BSF_WEAK)
    native->u.syment.n_sclass = obj_pe (abfd) ? C_NT_WEAK : C_WEAKEXT;
  else
    native->u.syment.n_sclass = C_EXT;

  ret = coff_write_symbol (abfd, symbol, native, written, strtab, hash,
			   debug_string_section_p, debug_string_size_p);
  if (isym != NULL)
    *isym = native->u.syment;
  return ret;
}

/* Write a native symbol to a COFF file.  */

static bool
coff_write_native_symbol (bfd *abfd,
			  coff_symbol_type *symbol,
			  bfd_vma *written,
			  struct bfd_strtab_hash *strtab,
			  asection **debug_string_section_p,
			  bfd_size_type *debug_string_size_p)
{
  combined_entry_type *native = symbol->native;
  alent *lineno = symbol->lineno;
  struct bfd_link_info *link_info = coff_data (abfd)->link_info;

  if ((!link_info || link_info->strip_discarded)
      && !bfd_is_abs_section (symbol->symbol.section)
      && symbol->symbol.section->output_section == bfd_abs_section_ptr)
    {
      symbol->symbol.name = "";
      return true;
    }

  BFD_ASSERT (native->is_sym);
  /* If this symbol has an associated line number, we must store the
     symbol index in the line number field.  We also tag the auxent to
     point to the right place in the lineno table.  */
  if (lineno && !symbol->done_lineno && symbol->symbol.section->owner != NULL)
    {
      unsigned int count = 0;

      lineno[count].u.offset = *written;
      if (native->u.syment.n_numaux)
	{
	  union internal_auxent *a = &((native + 1)->u.auxent);

	  a->x_sym.x_fcnary.x_fcn.x_lnnoptr =
	    symbol->symbol.section->output_section->moving_line_filepos;
	}

      /* Count and relocate all other linenumbers.  */
      count++;
      while (lineno[count].line_number != 0)
	{
	  lineno[count].u.offset +=
	    (symbol->symbol.section->output_section->vma
	     + symbol->symbol.section->output_offset);
	  count++;
	}
      symbol->done_lineno = true;

      if (! bfd_is_const_section (symbol->symbol.section->output_section))
	symbol->symbol.section->output_section->moving_line_filepos +=
	  count * bfd_coff_linesz (abfd);
    }

  return coff_write_symbol (abfd, &(symbol->symbol), native, written,
			    strtab, true, debug_string_section_p,
			    debug_string_size_p);
}

static void
null_error_handler (const char *fmt ATTRIBUTE_UNUSED,
		    va_list ap ATTRIBUTE_UNUSED)
{
}

/* Write out the COFF symbols.  */

bool
coff_write_symbols (bfd *abfd)
{
  struct bfd_strtab_hash *strtab;
  asection *debug_string_section;
  bfd_size_type debug_string_size;
  unsigned int i;
  unsigned int limit = bfd_get_symcount (abfd);
  bfd_vma written = 0;
  asymbol **p;

  debug_string_section = NULL;
  debug_string_size = 0;

  strtab = _bfd_stringtab_init ();
  if (strtab == NULL)
    return false;

  /* If this target supports long section names, they must be put into
     the string table.  This is supported by PE.  This code must
     handle section names just as they are handled in
     coff_write_object_contents.  This is why we pass hash as FALSE below.  */
  if (bfd_coff_long_section_names (abfd))
    {
      asection *o;

      for (o = abfd->sections; o != NULL; o = o->next)
	if (strlen (o->name) > SCNNMLEN
	    && _bfd_stringtab_add (strtab, o->name, false, false)
	       == (bfd_size_type) -1)
	  return false;
    }

  /* Seek to the right place.  */
  if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0)
    return false;

  /* Output all the symbols we have.  */
  written = 0;
  for (p = abfd->outsymbols, i = 0; i < limit; i++, p++)
    {
      asymbol *symbol = *p;
      coff_symbol_type *c_symbol = coff_symbol_from (symbol);

      if (c_symbol == (coff_symbol_type *) NULL
	  || c_symbol->native == (combined_entry_type *) NULL)
	{
	  if (!coff_write_alien_symbol (abfd, symbol, NULL, &written,
					strtab, true, &debug_string_section,
					&debug_string_size))
	    return false;
	}
      else
	{
	  if (coff_backend_info (abfd)->_bfd_coff_classify_symbol != NULL)
	    {
	      bfd_error_handler_type current_error_handler;
	      enum coff_symbol_classification sym_class;
	      unsigned char *n_sclass;

	      /* Suppress error reporting by bfd_coff_classify_symbol.
		 Error messages can be generated when we are processing a local
		 symbol which has no associated section and we do not have to
		 worry about this, all we need to know is that it is local.  */
	      current_error_handler = bfd_set_error_handler (null_error_handler);
	      BFD_ASSERT (c_symbol->native->is_sym);
	      sym_class = bfd_coff_classify_symbol (abfd,
						    &c_symbol->native->u.syment);
	      (void) bfd_set_error_handler (current_error_handler);

	      n_sclass = &c_symbol->native->u.syment.n_sclass;

	      /* If the symbol class has been changed (eg objcopy/ld script/etc)
		 we cannot retain the existing sclass from the original symbol.
		 Weak symbols only have one valid sclass, so just set it always.
		 If it is not local class and should be, set it C_STAT.
		 If it is global and not classified as global, or if it is
		 weak (which is also classified as global), set it C_EXT.  */

	      if (symbol->flags & BSF_WEAK)
		*n_sclass = obj_pe (abfd) ? C_NT_WEAK : C_WEAKEXT;
	      else if (symbol->flags & BSF_LOCAL && sym_class != COFF_SYMBOL_LOCAL)
		*n_sclass = C_STAT;
	      else if (symbol->flags & BSF_GLOBAL
		       && (sym_class != COFF_SYMBOL_GLOBAL
#ifdef COFF_WITH_PE
			   || *n_sclass == C_NT_WEAK
#endif
			   || *n_sclass == C_WEAKEXT))
		c_symbol->native->u.syment.n_sclass = C_EXT;
	    }

	  if (!coff_write_native_symbol (abfd, c_symbol, &written,
					 strtab, &debug_string_section,
					 &debug_string_size))
	    return false;
	}
    }

  obj_raw_syment_count (abfd) = written;

  /* Now write out strings.

     We would normally not write anything here if there are no strings, but
     we'll write out 4 so that any stupid coff reader which tries to read the
     string table even when there isn't one won't croak.  */
  {
    bfd_byte buffer[STRING_SIZE_SIZE];

#if STRING_SIZE_SIZE == 4
    H_PUT_32 (abfd, _bfd_stringtab_size (strtab) + STRING_SIZE_SIZE, buffer);
#else
 #error Change H_PUT_32
#endif
    if (bfd_write (buffer, sizeof (buffer), abfd) != sizeof (buffer))
      return false;

    if (! _bfd_stringtab_emit (abfd, strtab))
      return false;
  }

  _bfd_stringtab_free (strtab);

  /* Make sure the .debug section was created to be the correct size.
     We should create it ourselves on the fly, but we don't because
     BFD won't let us write to any section until we know how large all
     the sections are.  We could still do it by making another pass
     over the symbols.  FIXME.  */
  BFD_ASSERT (debug_string_size == 0
	      || (debug_string_section != (asection *) NULL
		  && (BFD_ALIGN (debug_string_size,
				 1 << debug_string_section->alignment_power)
		      == debug_string_section->size)));

  return true;
}

bool
coff_write_linenumbers (bfd *abfd)
{
  asection *s;
  bfd_size_type linesz;
  void * buff;

  linesz = bfd_coff_linesz (abfd);
  buff = bfd_alloc (abfd, linesz);
  if (!buff)
    return false;
  for (s = abfd->sections; s != (asection *) NULL; s = s->next)
    {
      if (s->lineno_count)
	{
	  asymbol **q = abfd->outsymbols;
	  if (bfd_seek (abfd, s->line_filepos, SEEK_SET) != 0)
	    return false;
	  /* Find all the linenumbers in this section.  */
	  while (*q)
	    {
	      asymbol *p = *q;
	      if (p->section->output_section == s)
		{
		  alent *l =
		  BFD_SEND (bfd_asymbol_bfd (p), _get_lineno,
			    (bfd_asymbol_bfd (p), p));
		  if (l)
		    {
		      /* Found a linenumber entry, output.  */
		      struct internal_lineno out;

		      memset ((void *) & out, 0, sizeof (out));
		      out.l_lnno = 0;
		      out.l_addr.l_symndx = l->u.offset;
		      bfd_coff_swap_lineno_out (abfd, &out, buff);
		      if (bfd_write (buff, linesz, abfd) != linesz)
			return false;
		      l++;
		      while (l->line_number)
			{
			  out.l_lnno = l->line_number;
			  out.l_addr.l_symndx = l->u.offset;
			  bfd_coff_swap_lineno_out (abfd, &out, buff);
			  if (bfd_write (buff, linesz, abfd) != linesz)
			    return false;
			  l++;
			}
		    }
		}
	      q++;
	    }
	}
    }
  bfd_release (abfd, buff);
  return true;
}

alent *
coff_get_lineno (bfd *ignore_abfd ATTRIBUTE_UNUSED, asymbol *symbol)
{
  return coffsymbol (symbol)->lineno;
}

/* This function transforms the offsets into the symbol table into
   pointers to syments.  */

static void
coff_pointerize_aux (bfd *abfd,
		     combined_entry_type *table_base,
		     combined_entry_type *symbol,
		     unsigned int indaux,
		     combined_entry_type *auxent)
{
  unsigned int type = symbol->u.syment.n_type;
  unsigned int n_sclass = symbol->u.syment.n_sclass;

  BFD_ASSERT (symbol->is_sym);
  if (coff_backend_info (abfd)->_bfd_coff_pointerize_aux_hook)
    {
      if ((*coff_backend_info (abfd)->_bfd_coff_pointerize_aux_hook)
	  (abfd, table_base, symbol, indaux, auxent))
	return;
    }

  /* Don't bother if this is a file or a section.  */
  if (n_sclass == C_STAT && type == T_NULL)
    return;
  if (n_sclass == C_FILE)
    return;
  if (n_sclass == C_DWARF)
    return;

  BFD_ASSERT (! auxent->is_sym);
  /* Otherwise patch up.  */
#define N_TMASK coff_data  (abfd)->local_n_tmask
#define N_BTSHFT coff_data (abfd)->local_n_btshft

  if ((ISFCN (type) || ISTAG (n_sclass) || n_sclass == C_BLOCK
       || n_sclass == C_FCN)
      && auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.u32 > 0
      && (auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.u32
	  < obj_raw_syment_count (abfd)))
    {
      auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p =
	table_base + auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.u32;
      auxent->fix_end = 1;
    }

  /* A negative tagndx is meaningless, but the SCO 3.2v4 cc can
     generate one, so we must be careful to ignore it.  */
  if (auxent->u.auxent.x_sym.x_tagndx.u32 < obj_raw_syment_count (abfd))
    {
      auxent->u.auxent.x_sym.x_tagndx.p =
	table_base + auxent->u.auxent.x_sym.x_tagndx.u32;
      auxent->fix_tag = 1;
    }
}

/* Allocate space for the ".debug" section, and read it.
   We did not read the debug section until now, because
   we didn't want to go to the trouble until someone needed it.  */

static char *
build_debug_section (bfd *abfd, asection ** sect_return)
{
  char *debug_section;
  file_ptr position;
  bfd_size_type sec_size;

  asection *sect = bfd_get_section_by_name (abfd, ".debug");

  if (!sect)
    {
      bfd_set_error (bfd_error_no_debug_section);
      return NULL;
    }

  /* Seek to the beginning of the `.debug' section and read it.
     Save the current position first; it is needed by our caller.
     Then read debug section and reset the file pointer.  */

  position = bfd_tell (abfd);
  if (bfd_seek (abfd, sect->filepos, SEEK_SET) != 0)
    return NULL;

  sec_size = sect->size;
  debug_section = (char *) _bfd_alloc_and_read (abfd, sec_size + 1, sec_size);
  if (debug_section == NULL)
    return NULL;
  debug_section[sec_size] = 0;

  if (bfd_seek (abfd, position, SEEK_SET) != 0)
    return NULL;

  * sect_return = sect;
  return debug_section;
}

/* Return a pointer to a malloc'd copy of 'name'.  'name' may not be
   \0-terminated, but will not exceed 'maxlen' characters.  The copy *will*
   be \0-terminated.  */

static char *
copy_name (bfd *abfd, char *name, size_t maxlen)
{
  size_t len;
  char *newname;

  for (len = 0; len < maxlen; ++len)
    if (name[len] == '\0')
      break;

  if ((newname = (char *) bfd_alloc (abfd, (bfd_size_type) len + 1)) == NULL)
    return NULL;

  strncpy (newname, name, len);
  newname[len] = '\0';
  return newname;
}

/* Read in the external symbols.  */

bool
_bfd_coff_get_external_symbols (bfd *abfd)
{
  size_t symesz;
  size_t size;
  void * syms;
  ufile_ptr filesize;

  if (obj_coff_external_syms (abfd) != NULL)
    return true;

  symesz = bfd_coff_symesz (abfd);
  if (_bfd_mul_overflow (obj_raw_syment_count (abfd), symesz, &size))
    {
      bfd_set_error (bfd_error_file_truncated);
      return false;
    }

  if (size == 0)
    return true;

  filesize = bfd_get_file_size (abfd);
  if (filesize != 0
      && ((ufile_ptr) obj_sym_filepos (abfd) > filesize
	  || size > filesize - obj_sym_filepos (abfd)))
    {
      bfd_set_error (bfd_error_file_truncated);
      return false;
    }

  if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0)
    return false;
  syms = _bfd_malloc_and_read (abfd, size, size);
  obj_coff_external_syms (abfd) = syms;
  return syms != NULL;
}

/* Read in the external strings.  The strings are not loaded until
   they are needed.  This is because we have no simple way of
   detecting a missing string table in an archive.  If the strings
   are loaded then the STRINGS and STRINGS_LEN fields in the
   coff_tdata structure will be set.  */

const char *
_bfd_coff_read_string_table (bfd *abfd)
{
  char extstrsize[STRING_SIZE_SIZE];
  bfd_size_type strsize;
  char *strings;
  ufile_ptr pos;
  ufile_ptr filesize;
  size_t symesz;
  size_t size;

  if (obj_coff_strings (abfd) != NULL)
    return obj_coff_strings (abfd);

  if (obj_sym_filepos (abfd) == 0)
    {
      bfd_set_error (bfd_error_no_symbols);
      return NULL;
    }

  symesz = bfd_coff_symesz (abfd);
  pos = obj_sym_filepos (abfd);
  if (_bfd_mul_overflow (obj_raw_syment_count (abfd), symesz, &size)
      || pos + size < pos)
    {
      bfd_set_error (bfd_error_file_truncated);
      return NULL;
    }

  if (bfd_seek (abfd, pos + size, SEEK_SET) != 0)
    return NULL;

  if (bfd_read (extstrsize, sizeof extstrsize, abfd) != sizeof extstrsize)
    {
      if (bfd_get_error () != bfd_error_file_truncated)
	return NULL;

      /* There is no string table.  */
      strsize = STRING_SIZE_SIZE;
    }
  else
    {
#if STRING_SIZE_SIZE == 4
      strsize = H_GET_32 (abfd, extstrsize);
#else
 #error Change H_GET_32
#endif
    }

  filesize = bfd_get_file_size (abfd);
  if (strsize < STRING_SIZE_SIZE
      || (filesize != 0 && strsize > filesize))
    {
      _bfd_error_handler
	/* xgettext: c-format */
	(_("%pB: bad string table size %" PRIu64), abfd, (uint64_t) strsize);
      bfd_set_error (bfd_error_bad_value);
      return NULL;
    }

  strings = (char *) bfd_malloc (strsize + 1);
  if (strings == NULL)
    return NULL;

  /* PR 17521 file: 079-54929-0.004.
     A corrupt file could contain an index that points into the first
     STRING_SIZE_SIZE bytes of the string table, so make sure that
     they are zero.  */
  memset (strings, 0, STRING_SIZE_SIZE);

  if (bfd_read (strings + STRING_SIZE_SIZE, strsize - STRING_SIZE_SIZE, abfd)
      != strsize - STRING_SIZE_SIZE)
    {
      free (strings);
      return NULL;
    }

  obj_coff_strings (abfd) = strings;
  obj_coff_strings_len (abfd) = strsize;
  /* Terminate the string table, just in case.  */
  strings[strsize] = 0;
  return strings;
}

/* Free up the external symbols and strings read from a COFF file.  */

bool
_bfd_coff_free_symbols (bfd *abfd)
{
  if (! bfd_family_coff (abfd))
    return false;

  if (obj_coff_external_syms (abfd) != NULL
      && ! obj_coff_keep_syms (abfd))
    {
      free (obj_coff_external_syms (abfd));
      obj_coff_external_syms (abfd) = NULL;
    }

  if (obj_coff_strings (abfd) != NULL
      && ! obj_coff_keep_strings (abfd))
    {
      free (obj_coff_strings (abfd));
      obj_coff_strings (abfd) = NULL;
      obj_coff_strings_len (abfd) = 0;
    }

  return true;
}

/* Read a symbol table into freshly bfd_allocated memory, swap it, and
   knit the symbol names into a normalized form.  By normalized here I
   mean that all symbols have an n_offset pointer that points to a null-
   terminated string.  */

combined_entry_type *
coff_get_normalized_symtab (bfd *abfd)
{
  combined_entry_type *internal;
  combined_entry_type *internal_ptr;
  size_t symesz;
  char *raw_src;
  char *raw_end;
  const char *string_table = NULL;
  asection * debug_sec = NULL;
  char *debug_sec_data = NULL;
  bfd_size_type size;

  if (obj_raw_syments (abfd) != NULL)
    return obj_raw_syments (abfd);

  if (! _bfd_coff_get_external_symbols (abfd))
    return NULL;

  size = obj_raw_syment_count (abfd);
  /* Check for integer overflow.  */
  if (size > (bfd_size_type) -1 / sizeof (combined_entry_type))
    return NULL;
  size *= sizeof (combined_entry_type);
  internal = (combined_entry_type *) bfd_zalloc (abfd, size);
  if (internal == NULL && size != 0)
    return NULL;

  raw_src = (char *) obj_coff_external_syms (abfd);

  /* Mark the end of the symbols.  */
  symesz = bfd_coff_symesz (abfd);
  raw_end = PTR_ADD (raw_src, obj_raw_syment_count (abfd) * symesz);

  /* FIXME SOMEDAY.  A string table size of zero is very weird, but
     probably possible.  If one shows up, it will probably kill us.  */

  /* Swap all the raw entries.  */
  for (internal_ptr = internal;
       raw_src < raw_end;
       raw_src += symesz, internal_ptr++)
    {
      unsigned int i;

      bfd_coff_swap_sym_in (abfd, (void *) raw_src,
			    (void *) & internal_ptr->u.syment);
      internal_ptr->is_sym = true;
      combined_entry_type *sym = internal_ptr;

      /* PR 17512: Prevent buffer overrun.  */
      if (sym->u.syment.n_numaux > ((raw_end - 1) - raw_src) / symesz)
	return NULL;

      for (i = 0; i < sym->u.syment.n_numaux; i++)
	{
	  internal_ptr++;
	  raw_src += symesz;

	  bfd_coff_swap_aux_in (abfd, (void *) raw_src,
				sym->u.syment.n_type,
				sym->u.syment.n_sclass,
				(int) i, sym->u.syment.n_numaux,
				&(internal_ptr->u.auxent));

	  internal_ptr->is_sym = false;
	  coff_pointerize_aux (abfd, internal, sym, i, internal_ptr);
	}

      if (sym->u.syment.n_sclass == C_FILE
	  && sym->u.syment.n_numaux > 0)
	{
	  combined_entry_type * aux = sym + 1;

	  /* Make a file symbol point to the name in the auxent, since
	     the text ".file" is redundant.  */
	  BFD_ASSERT (! aux->is_sym);

	  if (aux->u.auxent.x_file.x_n.x_n.x_zeroes == 0)
	    {
	      /* The filename is a long one, point into the string table.  */
	      if (string_table == NULL)
		{
		  string_table = _bfd_coff_read_string_table (abfd);
		  if (string_table == NULL)
		    return NULL;
		}

	      if ((bfd_size_type) aux->u.auxent.x_file.x_n.x_n.x_offset
		  >= obj_coff_strings_len (abfd))
		sym->u.syment._n._n_n._n_offset =
		  (uintptr_t) bfd_symbol_error_name;
	      else
		sym->u.syment._n._n_n._n_offset =
		  (uintptr_t) (string_table
			       + aux->u.auxent.x_file.x_n.x_n.x_offset);
	    }
	  else
	    {
	      /* Ordinary short filename, put into memory anyway.  The
		 Microsoft PE tools sometimes store a filename in
		 multiple AUX entries.  */
	      size_t len;
	      char *src;
	      if (sym->u.syment.n_numaux > 1 && obj_pe (abfd))
		{
		  len = sym->u.syment.n_numaux * symesz;
		  src = raw_src - (len - symesz);
		}
	      else
		{
		  len = bfd_coff_filnmlen (abfd);
		  src = aux->u.auxent.x_file.x_n.x_fname;
		}
	      sym->u.syment._n._n_n._n_offset =
		(uintptr_t) copy_name (abfd, src, len);
	    }

	  /* Normalize other strings available in C_FILE aux entries.  */
	  if (!obj_pe (abfd))
	    for (int numaux = 1;
		 numaux < sym->u.syment.n_numaux;
		 numaux++)
	      {
		aux = sym + numaux + 1;
		BFD_ASSERT (! aux->is_sym);

		if (aux->u.auxent.x_file.x_n.x_n.x_zeroes == 0)
		  {
		    /* The string information is a long one, point
		       into the string table.  */
		    if (string_table == NULL)
		      {
			string_table = _bfd_coff_read_string_table (abfd);
			if (string_table == NULL)
			  return NULL;
		      }

		    if ((bfd_size_type) aux->u.auxent.x_file.x_n.x_n.x_offset
			>= obj_coff_strings_len (abfd))
		      aux->u.auxent.x_file.x_n.x_n.x_offset =
			(uintptr_t) bfd_symbol_error_name;
		    else
		      aux->u.auxent.x_file.x_n.x_n.x_offset =
			(uintptr_t) (string_table
				     + aux->u.auxent.x_file.x_n.x_n.x_offset);
		  }
		else
		  aux->u.auxent.x_file.x_n.x_n.x_offset =
		    ((uintptr_t)
		     copy_name (abfd,
				aux->u.auxent.x_file.x_n.x_fname,
				bfd_coff_filnmlen (abfd)));
	      }

	}
      else
	{
	  if (sym->u.syment._n._n_n._n_zeroes != 0)
	    {
	      /* This is a "short" name.  Make it long.  */
	      char *newstring;

	      /* Find the length of this string without walking into memory
		 that isn't ours.  */
	      for (i = 0; i < SYMNMLEN; ++i)
		if (sym->u.syment._n._n_name[i] == '\0')
		  break;

	      newstring = bfd_alloc (abfd, i + 1);
	      if (newstring == NULL)
		return NULL;
	      memcpy (newstring, sym->u.syment._n._n_name, i);
	      newstring[i] = 0;
	      sym->u.syment._n._n_n._n_offset = (uintptr_t) newstring;
	      sym->u.syment._n._n_n._n_zeroes = 0;
	    }
	  else if (sym->u.syment._n._n_n._n_offset == 0)
	    sym->u.syment._n._n_n._n_offset = (uintptr_t) "";
	  else if (!bfd_coff_symname_in_debug (abfd, &sym->u.syment))
	    {
	      /* Long name already.  Point symbol at the string in the
		 table.  */
	      if (string_table == NULL)
		{
		  string_table = _bfd_coff_read_string_table (abfd);
		  if (string_table == NULL)
		    return NULL;
		}
	      if (sym->u.syment._n._n_n._n_offset >= obj_coff_strings_len (abfd))
		sym->u.syment._n._n_n._n_offset =
		  (uintptr_t) bfd_symbol_error_name;
	      else
		sym->u.syment._n._n_n._n_offset =
		  (uintptr_t) (string_table
			       + sym->u.syment._n._n_n._n_offset);
	    }
	  else
	    {
	      /* Long name in debug section.  Very similar.  */
	      if (debug_sec_data == NULL)
		{
		  debug_sec_data = build_debug_section (abfd, &debug_sec);
		  if (debug_sec_data == NULL)
		    return NULL;
		}
	      /* PR binutils/17512: Catch out of range offsets into
		 the debug data.  */
	      if (sym->u.syment._n._n_n._n_offset >= debug_sec->size)
		sym->u.syment._n._n_n._n_offset =
		  (uintptr_t) bfd_symbol_error_name;
	      else
		sym->u.syment._n._n_n._n_offset =
		  (uintptr_t) (debug_sec_data
			       + sym->u.syment._n._n_n._n_offset);
	    }
	}
    }

  /* Free the raw symbols.  */
  if (obj_coff_external_syms (abfd) != NULL
      && ! obj_coff_keep_syms (abfd))
    {
      free (obj_coff_external_syms (abfd));
      obj_coff_external_syms (abfd) = NULL;
    }

  obj_raw_syments (abfd) = internal;
  BFD_ASSERT (obj_raw_syment_count (abfd)
	      == (size_t) (internal_ptr - internal));

  return internal;
}

long
coff_get_reloc_upper_bound (bfd *abfd, sec_ptr asect)
{
  size_t count, raw;

  count = asect->reloc_count;
  if (count >= LONG_MAX / sizeof (arelent *)
      || _bfd_mul_overflow (count, bfd_coff_relsz (abfd), &raw))
    {
      bfd_set_error (bfd_error_file_too_big);
      return -1;
    }
  if (!bfd_write_p (abfd))
    {
      ufile_ptr filesize = bfd_get_file_size (abfd);
      if (filesize != 0 && raw > filesize)
	{
	  bfd_set_error (bfd_error_file_truncated);
	  return -1;
	}
    }
  return (count + 1) * sizeof (arelent *);
}

asymbol *
coff_make_empty_symbol (bfd *abfd)
{
  size_t amt = sizeof (coff_symbol_type);
  coff_symbol_type *new_symbol = (coff_symbol_type *) bfd_zalloc (abfd, amt);

  if (new_symbol == NULL)
    return NULL;
  new_symbol->symbol.section = 0;
  new_symbol->native = NULL;
  new_symbol->lineno = NULL;
  new_symbol->done_lineno = false;
  new_symbol->symbol.the_bfd = abfd;

  return & new_symbol->symbol;
}

/* Make a debugging symbol.  */

asymbol *
coff_bfd_make_debug_symbol (bfd *abfd)
{
  size_t amt = sizeof (coff_symbol_type);
  coff_symbol_type *new_symbol = (coff_symbol_type *) bfd_alloc (abfd, amt);

  if (new_symbol == NULL)
    return NULL;
  /* @@ The 10 is a guess at a plausible maximum number of aux entries
     (but shouldn't be a constant).  */
  amt = sizeof (combined_entry_type) * 10;
  new_symbol->native = (combined_entry_type *) bfd_zalloc (abfd, amt);
  if (!new_symbol->native)
    return NULL;
  new_symbol->native->is_sym = true;
  new_symbol->symbol.section = bfd_abs_section_ptr;
  new_symbol->symbol.flags = BSF_DEBUGGING;
  new_symbol->lineno = NULL;
  new_symbol->done_lineno = false;
  new_symbol->symbol.the_bfd = abfd;

  return & new_symbol->symbol;
}

void
coff_get_symbol_info (bfd *abfd, asymbol *symbol, symbol_info *ret)
{
  bfd_symbol_info (symbol, ret);

  if (coffsymbol (symbol)->native != NULL
      && coffsymbol (symbol)->native->fix_value
      && coffsymbol (symbol)->native->is_sym)
    ret->value
      = (((uintptr_t) coffsymbol (symbol)->native->u.syment.n_value
	  - (uintptr_t) obj_raw_syments (abfd))
	 / sizeof (combined_entry_type));
}

/* Print out information about COFF symbol.  */

void
coff_print_symbol (bfd *abfd,
		   void * filep,
		   asymbol *symbol,
		   bfd_print_symbol_type how)
{
  FILE * file = (FILE *) filep;
  const char *symname = (symbol->name != bfd_symbol_error_name
			 ? symbol->name : _("<corrupt>"));

  switch (how)
    {
    case bfd_print_symbol_name:
      fprintf (file, "%s", symname);
      break;

    case bfd_print_symbol_more:
      fprintf (file, "coff %s %s",
	       coffsymbol (symbol)->native ? "n" : "g",
	       coffsymbol (symbol)->lineno ? "l" : " ");
      break;

    case bfd_print_symbol_all:
      if (coffsymbol (symbol)->native)
	{
	  bfd_vma val;
	  unsigned int aux;
	  combined_entry_type *combined = coffsymbol (symbol)->native;
	  combined_entry_type *root = obj_raw_syments (abfd);
	  struct lineno_cache_entry *l = coffsymbol (symbol)->lineno;

	  fprintf (file, "[%3ld]", (long) (combined - root));

	  /* PR 17512: file: 079-33786-0.001:0.1.  */
	  if (combined < obj_raw_syments (abfd)
	      || combined >= obj_raw_syments (abfd) + obj_raw_syment_count (abfd))
	    {
	      fprintf (file, _("<corrupt info> %s"), symname);
	      break;
	    }

	  BFD_ASSERT (combined->is_sym);
	  if (! combined->fix_value)
	    val = (bfd_vma) combined->u.syment.n_value;
	  else
	    val = (((uintptr_t) combined->u.syment.n_value - (uintptr_t) root)
		   / sizeof (combined_entry_type));

	  fprintf (file, "(sec %2d)(fl 0x%02x)(ty %4x)(scl %3d) (nx %d) 0x",
		   combined->u.syment.n_scnum,
		   combined->u.syment.n_flags,
		   combined->u.syment.n_type,
		   combined->u.syment.n_sclass,
		   combined->u.syment.n_numaux);
	  bfd_fprintf_vma (abfd, file, val);
	  fprintf (file, " %s", symname);

	  for (aux = 0; aux < combined->u.syment.n_numaux; aux++)
	    {
	      combined_entry_type *auxp = combined + aux + 1;
	      long tagndx;

	      BFD_ASSERT (! auxp->is_sym);
	      if (auxp->fix_tag)
		tagndx = auxp->u.auxent.x_sym.x_tagndx.p - root;
	      else
		tagndx = auxp->u.auxent.x_sym.x_tagndx.u32;

	      fprintf (file, "\n");

	      if (bfd_coff_print_aux (abfd, file, root, combined, auxp, aux))
		continue;

	      switch (combined->u.syment.n_sclass)
		{
		case C_FILE:
		  fprintf (file, "File ");
		  /* Add additional information if this isn't the filename
		     auxiliary entry.  */
		  if (auxp->u.auxent.x_file.x_ftype)
		    fprintf (file, "ftype %d fname \"%s\"",
			     auxp->u.auxent.x_file.x_ftype,
			     (char *) auxp->u.auxent.x_file.x_n.x_n.x_offset);
		  break;

		case C_DWARF:
		  fprintf (file, "AUX scnlen %#" PRIx64 " nreloc %" PRId64,
			   auxp->u.auxent.x_sect.x_scnlen,
			   auxp->u.auxent.x_sect.x_nreloc);
		  break;

		case C_STAT:
		  if (combined->u.syment.n_type == T_NULL)
		    /* Probably a section symbol ?  */
		    {
		      fprintf (file, "AUX scnlen 0x%lx nreloc %d nlnno %d",
			       (unsigned long) auxp->u.auxent.x_scn.x_scnlen,
			       auxp->u.auxent.x_scn.x_nreloc,
			       auxp->u.auxent.x_scn.x_nlinno);
		      if (auxp->u.auxent.x_scn.x_checksum != 0
			  || auxp->u.auxent.x_scn.x_associated != 0
			  || auxp->u.auxent.x_scn.x_comdat != 0)
			fprintf (file, " checksum 0x%x assoc %d comdat %d",
				 auxp->u.auxent.x_scn.x_checksum,
				 auxp->u.auxent.x_scn.x_associated,
				 auxp->u.auxent.x_scn.x_comdat);
		      break;
		    }
		  /* Fall through.  */
		case C_EXT:
		case C_AIX_WEAKEXT:
		  if (ISFCN (combined->u.syment.n_type))
		    {
		      long next, llnos;

		      if (auxp->fix_end)
			next = (auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p
			       - root);
		      else
			next = auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.u32;
		      llnos = auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_lnnoptr;
		      fprintf (file,
			       "AUX tagndx %ld ttlsiz 0x%lx lnnos %ld next %ld",
			       tagndx,
			       (unsigned long) auxp->u.auxent.x_sym.x_misc.x_fsize,
			       llnos, next);
		      break;
		    }
		  /* Fall through.  */
		default:
		  fprintf (file, "AUX lnno %d size 0x%x tagndx %ld",
			   auxp->u.auxent.x_sym.x_misc.x_lnsz.x_lnno,
			   auxp->u.auxent.x_sym.x_misc.x_lnsz.x_size,
			   tagndx);
		  if (auxp->fix_end)
		    fprintf (file, " endndx %ld",
			     ((long)
			      (auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p
			       - root)));
		  break;
		}
	    }

	  if (l)
	    {
	      fprintf (file, "\n%s :",
		       l->u.sym->name != bfd_symbol_error_name
		       ? l->u.sym->name : _("<corrupt>"));
	      l++;
	      while (l->line_number)
		{
		  if (l->line_number > 0)
		    {
		      fprintf (file, "\n%4d : ", l->line_number);
		      bfd_fprintf_vma (abfd, file, l->u.offset + symbol->section->vma);
		    }
		  l++;
		}
	    }
	}
      else
	{
	  bfd_print_symbol_vandf (abfd, (void *) file, symbol);
	  fprintf (file, " %-5s %s %s %s",
		   symbol->section->name,
		   coffsymbol (symbol)->native ? "n" : "g",
		   coffsymbol (symbol)->lineno ? "l" : " ",
		   symname);
	}
    }
}

/* Return whether a symbol name implies a local symbol.  In COFF,
   local symbols generally start with ``.L''.  Most targets use this
   function for the is_local_label_name entry point, but some may
   override it.  */

bool
_bfd_coff_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED,
			       const char *name)
{
  return name[0] == '.' && name[1] == 'L';
}

/* Provided a BFD, a section and an offset (in bytes, not octets) into the
   section, calculate and return the name of the source file and the line
   nearest to the wanted location.  */

bool
coff_find_nearest_line_with_names (bfd *abfd,
				   asymbol **symbols,
				   asection *section,
				   bfd_vma offset,
				   const char **filename_ptr,
				   const char **functionname_ptr,
				   unsigned int *line_ptr,
				   const struct dwarf_debug_section *debug_sections)
{
  bool found;
  unsigned int i;
  unsigned int line_base;
  coff_data_type *cof = coff_data (abfd);
  /* Run through the raw syments if available.  */
  combined_entry_type *p;
  combined_entry_type *pend;
  alent *l;
  struct coff_section_tdata *sec_data;
  size_t amt;

  /* Before looking through the symbol table, try to use a .stab
     section to find the information.  */
  if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
					     &found, filename_ptr,
					     functionname_ptr, line_ptr,
					     &coff_data(abfd)->line_info))
    return false;

  if (found)
    return true;

  /* Also try examining DWARF2 debugging information.  */
  if (_bfd_dwarf2_find_nearest_line (abfd, symbols, NULL, section, offset,
				     filename_ptr, functionname_ptr,
				     line_ptr, NULL, debug_sections,
				     &coff_data(abfd)->dwarf2_find_line_info))
    return true;

  sec_data = coff_section_data (abfd, section);

  /* If the DWARF lookup failed, but there is DWARF information available
     then the problem might be that the file has been rebased.  This tool
     changes the VMAs of all the sections, but it does not update the DWARF
     information.  So try again, using a bias against the address sought.  */
  if (coff_data (abfd)->dwarf2_find_line_info != NULL)
    {
      bfd_signed_vma bias = 0;

      /* Create a cache of the result for the next call.  */
      if (sec_data == NULL && section->owner == abfd)
	{
	  amt = sizeof (struct coff_section_tdata);
	  section->used_by_bfd = bfd_zalloc (abfd, amt);
	  sec_data = (struct coff_section_tdata *) section->used_by_bfd;
	}

      if (sec_data != NULL && sec_data->saved_bias)
	bias = sec_data->bias;
      else if (symbols)
	{
	  bias = _bfd_dwarf2_find_symbol_bias (symbols,
					       & coff_data (abfd)->dwarf2_find_line_info);

	  if (sec_data)
	    {
	      sec_data->saved_bias = true;
	      sec_data->bias = bias;
	    }
	}

      if (bias
	  && _bfd_dwarf2_find_nearest_line (abfd, symbols, NULL, section,
					    offset + bias,
					    filename_ptr, functionname_ptr,
					    line_ptr, NULL, debug_sections,
					    &coff_data(abfd)->dwarf2_find_line_info))
	return true;
    }

  *filename_ptr = 0;
  *functionname_ptr = 0;
  *line_ptr = 0;

  /* Don't try and find line numbers in a non coff file.  */
  if (!bfd_family_coff (abfd))
    return false;

  if (cof == NULL)
    return false;

  /* Find the first C_FILE symbol.  */
  p = cof->raw_syments;
  if (!p)
    return false;

  pend = p + cof->raw_syment_count;
  while (p < pend)
    {
      BFD_ASSERT (p->is_sym);
      if (p->u.syment.n_sclass == C_FILE)
	break;
      p += 1 + p->u.syment.n_numaux;
    }

  if (p < pend)
    {
      bfd_vma sec_vma;
      bfd_vma maxdiff;

      /* Look through the C_FILE symbols to find the best one.  */
      sec_vma = bfd_section_vma (section);
      *filename_ptr = (char *) p->u.syment._n._n_n._n_offset;
      maxdiff = (bfd_vma) 0 - (bfd_vma) 1;
      while (1)
	{
	  bfd_vma file_addr;
	  combined_entry_type *p2;

	  for (p2 = p + 1 + p->u.syment.n_numaux;
	       p2 < pend;
	       p2 += 1 + p2->u.syment.n_numaux)
	    {
	      BFD_ASSERT (p2->is_sym);
	      if (p2->u.syment.n_scnum > 0
		  && (section
		      == coff_section_from_bfd_index (abfd,
						      p2->u.syment.n_scnum)))
		break;
	      if (p2->u.syment.n_sclass == C_FILE)
		{
		  p2 = pend;
		  break;
		}
	    }
	  if (p2 >= pend)
	    break;

	  file_addr = (bfd_vma) p2->u.syment.n_value;
	  /* PR 11512: Include the section address of the function name symbol.  */
	  if (p2->u.syment.n_scnum > 0)
	    file_addr += coff_section_from_bfd_index (abfd,
						      p2->u.syment.n_scnum)->vma;
	  /* We use <= MAXDIFF here so that if we get a zero length
	     file, we actually use the next file entry.  */
	  if (p2 < pend
	      && offset + sec_vma >= file_addr
	      && offset + sec_vma - file_addr <= maxdiff)
	    {
	      *filename_ptr = (char *) p->u.syment._n._n_n._n_offset;
	      maxdiff = offset + sec_vma - p2->u.syment.n_value;
	    }

	  if (p->u.syment.n_value >= cof->raw_syment_count)
	    break;

	  /* Avoid endless loops on erroneous files by ensuring that
	     we always move forward in the file.  */
	  if (p >= cof->raw_syments + p->u.syment.n_value)
	    break;

	  p = cof->raw_syments + p->u.syment.n_value;
	  if (!p->is_sym || p->u.syment.n_sclass != C_FILE)
	    break;
	}
    }

  if (section->lineno_count == 0)
    {
      *functionname_ptr = NULL;
      *line_ptr = 0;
      return true;
    }

  /* Now wander though the raw linenumbers of the section.
     If we have been called on this section before, and the offset
     we want is further down then we can prime the lookup loop.  */
  if (sec_data != NULL
      && sec_data->i > 0
      && offset >= sec_data->offset)
    {
      i = sec_data->i;
      *functionname_ptr = sec_data->function;
      line_base = sec_data->line_base;
    }
  else
    {
      i = 0;
      line_base = 0;
    }

  if (section->lineno != NULL)
    {
      bfd_vma last_value = 0;

      l = &section->lineno[i];

      for (; i < section->lineno_count; i++)
	{
	  if (l->line_number == 0)
	    {
	      /* Get the symbol this line number points at.  */
	      coff_symbol_type *coff = (coff_symbol_type *) (l->u.sym);
	      if (coff->symbol.value > offset)
		break;

	      *functionname_ptr = coff->symbol.name;
	      last_value = coff->symbol.value;
	      if (coff->native)
		{
		  combined_entry_type *s = coff->native;

		  BFD_ASSERT (s->is_sym);
		  s = s + 1 + s->u.syment.n_numaux;

		  /* In XCOFF a debugging symbol can follow the
		     function symbol.  */
		  if (((size_t) ((char *) s - (char *) obj_raw_syments (abfd))
		       < obj_raw_syment_count (abfd) * sizeof (*s))
		      && s->u.syment.n_scnum == N_DEBUG)
		    s = s + 1 + s->u.syment.n_numaux;

		  /* S should now point to the .bf of the function.  */
		  if (((size_t) ((char *) s - (char *) obj_raw_syments (abfd))
		       < obj_raw_syment_count (abfd) * sizeof (*s))
		      && s->u.syment.n_numaux)
		    {
		      /* The linenumber is stored in the auxent.  */
		      union internal_auxent *a = &((s + 1)->u.auxent);

		      line_base = a->x_sym.x_misc.x_lnsz.x_lnno;
		      *line_ptr = line_base;
		    }
		}
	    }
	  else
	    {
	      if (l->u.offset > offset)
		break;
	      *line_ptr = l->line_number + line_base - 1;
	    }
	  l++;
	}

      /* If we fell off the end of the loop, then assume that this
	 symbol has no line number info.  Otherwise, symbols with no
	 line number info get reported with the line number of the
	 last line of the last symbol which does have line number
	 info.  We use 0x100 as a slop to account for cases where the
	 last line has executable code.  */
      if (i >= section->lineno_count
	  && last_value != 0
	  && offset - last_value > 0x100)
	{
	  *functionname_ptr = NULL;
	  *line_ptr = 0;
	}
    }

  /* Cache the results for the next call.  */
  if (sec_data == NULL && section->owner == abfd)
    {
      amt = sizeof (struct coff_section_tdata);
      section->used_by_bfd = bfd_zalloc (abfd, amt);
      sec_data = (struct coff_section_tdata *) section->used_by_bfd;
    }

  if (sec_data != NULL)
    {
      sec_data->offset = offset;
      sec_data->i = i - 1;
      sec_data->function = *functionname_ptr;
      sec_data->line_base = line_base;
    }

  return true;
}

bool
coff_find_nearest_line (bfd *abfd,
			asymbol **symbols,
			asection *section,
			bfd_vma offset,
			const char **filename_ptr,
			const char **functionname_ptr,
			unsigned int *line_ptr,
			unsigned int *discriminator_ptr)
{
  if (discriminator_ptr)
    *discriminator_ptr = 0;
  return coff_find_nearest_line_with_names (abfd, symbols, section, offset,
					    filename_ptr, functionname_ptr,
					    line_ptr, dwarf_debug_sections);
}

bool
coff_find_inliner_info (bfd *abfd,
			const char **filename_ptr,
			const char **functionname_ptr,
			unsigned int *line_ptr)
{
  bool found;

  found = _bfd_dwarf2_find_inliner_info (abfd, filename_ptr,
					 functionname_ptr, line_ptr,
					 &coff_data(abfd)->dwarf2_find_line_info);
  return (found);
}

int
coff_sizeof_headers (bfd *abfd, struct bfd_link_info *info)
{
  size_t size;

  if (!bfd_link_relocatable (info))
    size = bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd);
  else
    size = bfd_coff_filhsz (abfd);

  size += abfd->section_count * bfd_coff_scnhsz (abfd);
  return size;
}

/* Change the class of a coff symbol held by BFD.  */

bool
bfd_coff_set_symbol_class (bfd *	 abfd,
			   asymbol *	 symbol,
			   unsigned int	 symbol_class)
{
  coff_symbol_type * csym;

  csym = coff_symbol_from (symbol);
  if (csym == NULL)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return false;
    }
  else if (csym->native == NULL)
    {
      /* This is an alien symbol which no native coff backend data.
	 We cheat here by creating a fake native entry for it and
	 then filling in the class.  This code is based on that in
	 coff_write_alien_symbol().  */

      combined_entry_type * native;
      size_t amt = sizeof (* native);

      native = (combined_entry_type *) bfd_zalloc (abfd, amt);
      if (native == NULL)
	return false;

      native->is_sym = true;
      native->u.syment.n_type   = T_NULL;
      native->u.syment.n_sclass = symbol_class;

      if (bfd_is_und_section (symbol->section))
	{
	  native->u.syment.n_scnum = N_UNDEF;
	  native->u.syment.n_value = symbol->value;
	}
      else if (bfd_is_com_section (symbol->section))
	{
	  native->u.syment.n_scnum = N_UNDEF;
	  native->u.syment.n_value = symbol->value;
	}
      else
	{
	  native->u.syment.n_scnum =
	    symbol->section->output_section->target_index;
	  native->u.syment.n_value = (symbol->value
				      + symbol->section->output_offset);
	  if (! obj_pe (abfd))
	    native->u.syment.n_value += symbol->section->output_section->vma;

	  /* Copy the any flags from the file header into the symbol.
	     FIXME: Why?  */
	  native->u.syment.n_flags = bfd_asymbol_bfd (& csym->symbol)->flags;
	}

      csym->native = native;
    }
  else
    csym->native->u.syment.n_sclass = symbol_class;

  return true;
}

bool
_bfd_coff_section_already_linked (bfd *abfd,
				  asection *sec,
				  struct bfd_link_info *info)
{
  flagword flags;
  const char *name, *key;
  struct bfd_section_already_linked *l;
  struct bfd_section_already_linked_hash_entry *already_linked_list;
  struct coff_comdat_info *s_comdat;

  if (sec->output_section == bfd_abs_section_ptr)
    return false;

  flags = sec->flags;
  if ((flags & SEC_LINK_ONCE) == 0)
    return false;

  /* The COFF backend linker doesn't support group sections.  */
  if ((flags & SEC_GROUP) != 0)
    return false;

  name = bfd_section_name (sec);
  s_comdat = bfd_coff_get_comdat_section (abfd, sec);

  if (s_comdat != NULL)
    key = s_comdat->name;
  else
    {
      if (startswith (name, ".gnu.linkonce.")
	  && (key = strchr (name + sizeof (".gnu.linkonce.") - 1, '.')) != NULL)
	key++;
      else
	/* FIXME: gcc as of 2011-09 emits sections like .text$<key>,
	   .xdata$<key> and .pdata$<key> only the first of which has a
	   comdat key.  Should these all match the LTO IR key?  */
	key = name;
    }

  already_linked_list = bfd_section_already_linked_table_lookup (key);
  if (!already_linked_list)
    goto bad;

  for (l = already_linked_list->entry; l != NULL; l = l->next)
    {
      struct coff_comdat_info *l_comdat;

      l_comdat = bfd_coff_get_comdat_section (l->sec->owner, l->sec);

      /* The section names must match, and both sections must be
	 comdat and have the same comdat name, or both sections must
	 be non-comdat.  LTO IR plugin sections are an exception.  They
	 are always named .gnu.linkonce.t.<key> (<key> is some string)
	 and match any comdat section with comdat name of <key>, and
	 any linkonce section with the same suffix, ie.
	 .gnu.linkonce.*.<key>.  */
      if (((s_comdat != NULL) == (l_comdat != NULL)
	   && strcmp (name, l->sec->name) == 0)
	  || (l->sec->owner->flags & BFD_PLUGIN) != 0
	  || (sec->owner->flags & BFD_PLUGIN) != 0)
	{
	  /* The section has already been linked.  See if we should
	     issue a warning.  */
	  return _bfd_handle_already_linked (sec, l, info);
	}
    }

  /* This is the first section with this name.  Record it.  */
  if (!bfd_section_already_linked_table_insert (already_linked_list, sec))
    {
    bad:
      info->callbacks->fatal (_("%P: already_linked_table: %E\n"));
    }
  return false;
}

/* Initialize COOKIE for input bfd ABFD. */

static bool
init_reloc_cookie (struct coff_reloc_cookie *cookie,
		   struct bfd_link_info *info ATTRIBUTE_UNUSED,
		   bfd *abfd)
{
  /* Sometimes the symbol table does not yet have been loaded here.  */
  bfd_coff_slurp_symbol_table (abfd);

  cookie->abfd = abfd;
  cookie->sym_hashes = obj_coff_sym_hashes (abfd);

  cookie->symbols = obj_symbols (abfd);

  return true;
}

/* Free the memory allocated by init_reloc_cookie, if appropriate.  */

static void
fini_reloc_cookie (struct coff_reloc_cookie *cookie ATTRIBUTE_UNUSED,
		   bfd *abfd ATTRIBUTE_UNUSED)
{
  /* Nothing to do.  */
}

/* Initialize the relocation information in COOKIE for input section SEC
   of input bfd ABFD.  */

static bool
init_reloc_cookie_rels (struct coff_reloc_cookie *cookie,
			struct bfd_link_info *info ATTRIBUTE_UNUSED,
			bfd *abfd,
			asection *sec)
{
  if (sec->reloc_count == 0)
    {
      cookie->rels = NULL;
      cookie->relend = NULL;
      cookie->rel = NULL;
      return true;
    }

  cookie->rels = _bfd_coff_read_internal_relocs (abfd, sec, false, NULL,
						 0, NULL);

  if (cookie->rels == NULL)
    return false;

  cookie->rel = cookie->rels;
  cookie->relend = (cookie->rels + sec->reloc_count);
  return true;
}

/* Free the memory allocated by init_reloc_cookie_rels,
   if appropriate.  */

static void
fini_reloc_cookie_rels (struct coff_reloc_cookie *cookie,
			asection *sec)
{
  if (cookie->rels
      /* PR 20401.  The relocs may not have been cached, so check first.
	 If the relocs were loaded by init_reloc_cookie_rels() then this
	 will be the case.  FIXME: Would performance be improved if the
	 relocs *were* cached ?  */
      && coff_section_data (NULL, sec)
      && coff_section_data (NULL, sec)->relocs != cookie->rels)
    free (cookie->rels);
}

/* Initialize the whole of COOKIE for input section SEC.  */

static bool
init_reloc_cookie_for_section (struct coff_reloc_cookie *cookie,
			       struct bfd_link_info *info,
			       asection *sec)
{
  if (!init_reloc_cookie (cookie, info, sec->owner))
    return false;

  if (!init_reloc_cookie_rels (cookie, info, sec->owner, sec))
    {
      fini_reloc_cookie (cookie, sec->owner);
      return false;
    }
  return true;
}

/* Free the memory allocated by init_reloc_cookie_for_section,
   if appropriate.  */

static void
fini_reloc_cookie_for_section (struct coff_reloc_cookie *cookie,
			       asection *sec)
{
  fini_reloc_cookie_rels (cookie, sec);
  fini_reloc_cookie (cookie, sec->owner);
}

static asection *
_bfd_coff_gc_mark_hook (asection *sec,
			struct bfd_link_info *info ATTRIBUTE_UNUSED,
			struct internal_reloc *rel ATTRIBUTE_UNUSED,
			struct coff_link_hash_entry *h,
			struct internal_syment *sym)
{
  if (h != NULL)
    {
      switch (h->root.type)
	{
	case bfd_link_hash_defined:
	case bfd_link_hash_defweak:
	  return h->root.u.def.section;

	case bfd_link_hash_common:
	  return h->root.u.c.p->section;

	case bfd_link_hash_undefweak:
	  if (h->symbol_class == C_NT_WEAK && h->numaux == 1)
	    {
	      /* PE weak externals.  A weak symbol may include an auxiliary
		 record indicating that if the weak symbol is not resolved,
		 another external symbol is used instead.  */
	      struct coff_link_hash_entry *h2 =
		h->auxbfd->tdata.coff_obj_data->sym_hashes
		[h->aux->x_sym.x_tagndx.u32];

	      if (h2 && h2->root.type != bfd_link_hash_undefined)
		return  h2->root.u.def.section;
	    }
	  break;

	case bfd_link_hash_undefined:
	default:
	  break;
	}
      return NULL;
    }

  return coff_section_from_bfd_index (sec->owner, sym->n_scnum);
}

/* COOKIE->rel describes a relocation against section SEC, which is
   a section we've decided to keep.  Return the section that contains
   the relocation symbol, or NULL if no section contains it.  */

static asection *
_bfd_coff_gc_mark_rsec (struct bfd_link_info *info, asection *sec,
			coff_gc_mark_hook_fn gc_mark_hook,
			struct coff_reloc_cookie *cookie)
{
  struct coff_link_hash_entry *h;

  h = cookie->sym_hashes[cookie->rel->r_symndx];
  if (h != NULL)
    {
      while (h->root.type == bfd_link_hash_indirect
	     || h->root.type == bfd_link_hash_warning)
	h = (struct coff_link_hash_entry *) h->root.u.i.link;

      return (*gc_mark_hook) (sec, info, cookie->rel, h, NULL);
    }

  return (*gc_mark_hook) (sec, info, cookie->rel, NULL,
			  &(cookie->symbols
			    + obj_convert (sec->owner)[cookie->rel->r_symndx])->native->u.syment);
}

static bool _bfd_coff_gc_mark
  (struct bfd_link_info *, asection *, coff_gc_mark_hook_fn);

/* COOKIE->rel describes a relocation against section SEC, which is
   a section we've decided to keep.  Mark the section that contains
   the relocation symbol.  */

static bool
_bfd_coff_gc_mark_reloc (struct bfd_link_info *info,
			 asection *sec,
			 coff_gc_mark_hook_fn gc_mark_hook,
			 struct coff_reloc_cookie *cookie)
{
  asection *rsec;

  rsec = _bfd_coff_gc_mark_rsec (info, sec, gc_mark_hook, cookie);
  if (rsec && !rsec->gc_mark)
    {
      if (bfd_get_flavour (rsec->owner) != bfd_target_coff_flavour)
	rsec->gc_mark = 1;
      else if (!_bfd_coff_gc_mark (info, rsec, gc_mark_hook))
	return false;
    }
  return true;
}

/* The mark phase of garbage collection.  For a given section, mark
   it and any sections in this section's group, and all the sections
   which define symbols to which it refers.  */

static bool
_bfd_coff_gc_mark (struct bfd_link_info *info,
		   asection *sec,
		   coff_gc_mark_hook_fn gc_mark_hook)
{
  bool ret = true;

  sec->gc_mark = 1;

  /* Look through the section relocs.  */
  if ((sec->flags & SEC_RELOC) != 0
      && sec->reloc_count > 0)
    {
      struct coff_reloc_cookie cookie;

      if (!init_reloc_cookie_for_section (&cookie, info, sec))
	ret = false;
      else
	{
	  for (; cookie.rel < cookie.relend; cookie.rel++)
	    {
	      if (!_bfd_coff_gc_mark_reloc (info, sec, gc_mark_hook, &cookie))
		{
		  ret = false;
		  break;
		}
	    }
	  fini_reloc_cookie_for_section (&cookie, sec);
	}
    }

  return ret;
}

static bool
_bfd_coff_gc_mark_extra_sections (struct bfd_link_info *info,
				  coff_gc_mark_hook_fn mark_hook ATTRIBUTE_UNUSED)
{
  bfd *ibfd;

  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
    {
      asection *isec;
      bool some_kept;

      if (bfd_get_flavour (ibfd) != bfd_target_coff_flavour)
	continue;

      /* Ensure all linker created sections are kept, and see whether
	 any other section is already marked.  */
      some_kept = false;
      for (isec = ibfd->sections; isec != NULL; isec = isec->next)
	{
	  if ((isec->flags & SEC_LINKER_CREATED) != 0)
	    isec->gc_mark = 1;
	  else if (isec->gc_mark)
	    some_kept = true;
	}

      /* If no section in this file will be kept, then we can
	 toss out debug sections.  */
      if (!some_kept)
	continue;

      /* Keep debug and special sections like .comment when they are
	 not part of a group, or when we have single-member groups.  */
      for (isec = ibfd->sections; isec != NULL; isec = isec->next)
	if ((isec->flags & SEC_DEBUGGING) != 0
	    || (isec->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0)
	  isec->gc_mark = 1;
    }
  return true;
}

/* Sweep symbols in swept sections.  Called via coff_link_hash_traverse.  */

static bool
coff_gc_sweep_symbol (struct coff_link_hash_entry *h,
		      void *data ATTRIBUTE_UNUSED)
{
  if (h->root.type == bfd_link_hash_warning)
    h = (struct coff_link_hash_entry *) h->root.u.i.link;

  if ((h->root.type == bfd_link_hash_defined
       || h->root.type == bfd_link_hash_defweak)
      && !h->root.u.def.section->gc_mark
      && !(h->root.u.def.section->owner->flags & DYNAMIC))
    {
      /* Do our best to hide the symbol.  */
      h->root.u.def.section = bfd_und_section_ptr;
      h->symbol_class = C_HIDDEN;
    }

  return true;
}

/* The sweep phase of garbage collection.  Remove all garbage sections.  */

typedef bool (*gc_sweep_hook_fn)
  (bfd *, struct bfd_link_info *, asection *, const struct internal_reloc *);

static inline bool
is_subsection (const char *str, const char *prefix)
{
  size_t n = strlen (prefix);
  if (strncmp (str, prefix, n) != 0)
    return false;
  if (str[n] == 0)
    return true;
  else if (str[n] != '$')
    return false;
  return ISDIGIT (str[n + 1]) && str[n + 2] == 0;
}

static bool
coff_gc_sweep (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
{
  bfd *sub;

  for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
    {
      asection *o;

      if (bfd_get_flavour (sub) != bfd_target_coff_flavour)
	continue;

      for (o = sub->sections; o != NULL; o = o->next)
	{
	    /* Keep debug and special sections.  */
	  if ((o->flags & (SEC_DEBUGGING | SEC_LINKER_CREATED)) != 0
	      || (o->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0)
	    o->gc_mark = 1;
	  else if (startswith (o->name, ".idata")
		   || startswith (o->name, ".pdata")
		   || startswith (o->name, ".xdata")
		   || is_subsection (o->name, ".didat")
		   || startswith (o->name, ".rsrc"))
	    o->gc_mark = 1;

	  if (o->gc_mark)
	    continue;

	  /* Skip sweeping sections already excluded.  */
	  if (o->flags & SEC_EXCLUDE)
	    continue;

	  /* Since this is early in the link process, it is simple
	     to remove a section from the output.  */
	  o->flags |= SEC_EXCLUDE;

	  if (info->print_gc_sections && o->size != 0)
	    /* xgettext: c-format */
	    _bfd_error_handler (_("removing unused section '%pA' in file '%pB'"),
				o, sub);

#if 0
	  /* But we also have to update some of the relocation
	     info we collected before.  */
	  if (gc_sweep_hook
	      && (o->flags & SEC_RELOC) != 0
	      && o->reloc_count > 0
	      && !bfd_is_abs_section (o->output_section))
	    {
	      struct internal_reloc *internal_relocs;
	      bool r;

	      internal_relocs
		= _bfd_coff_link_read_relocs (o->owner, o, NULL, NULL,
					     info->keep_memory);
	      if (internal_relocs == NULL)
		return false;

	      r = (*gc_sweep_hook) (o->owner, info, o, internal_relocs);

	      if (coff_section_data (o)->relocs != internal_relocs)
		free (internal_relocs);

	      if (!r)
		return false;
	    }
#endif
	}
    }

  /* Remove the symbols that were in the swept sections from the dynamic
     symbol table.  */
  coff_link_hash_traverse (coff_hash_table (info), coff_gc_sweep_symbol,
			   NULL);

  return true;
}

/* Keep all sections containing symbols undefined on the command-line,
   and the section containing the entry symbol.  */

static void
_bfd_coff_gc_keep (struct bfd_link_info *info)
{
  struct bfd_sym_chain *sym;

  for (sym = info->gc_sym_list; sym != NULL; sym = sym->next)
    {
      struct coff_link_hash_entry *h;

      h = coff_link_hash_lookup (coff_hash_table (info), sym->name,
				false, false, false);

      if (h != NULL
	  && (h->root.type == bfd_link_hash_defined
	      || h->root.type == bfd_link_hash_defweak)
	  && !bfd_is_abs_section (h->root.u.def.section))
	h->root.u.def.section->flags |= SEC_KEEP;
    }
}

/* Do mark and sweep of unused sections.  */

bool
bfd_coff_gc_sections (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
{
  bfd *sub;

  /* FIXME: Should we implement this? */
#if 0
  const bfd_coff_backend_data *bed = coff_backend_info (abfd);

  if (!bed->can_gc_sections
      || !is_coff_hash_table (info->hash))
    {
      _bfd_error_handler(_("warning: gc-sections option ignored"));
      return true;
    }
#endif

  _bfd_coff_gc_keep (info);

  /* Grovel through relocs to find out who stays ...  */
  for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
    {
      asection *o;

      if (bfd_get_flavour (sub) != bfd_target_coff_flavour)
	continue;

      for (o = sub->sections; o != NULL; o = o->next)
	{
	  if (((o->flags & (SEC_EXCLUDE | SEC_KEEP)) == SEC_KEEP
	       || startswith (o->name, ".vectors")
	       || startswith (o->name, ".ctors")
	       || startswith (o->name, ".dtors"))
	      && !o->gc_mark)
	    {
	      if (!_bfd_coff_gc_mark (info, o, _bfd_coff_gc_mark_hook))
		return false;
	    }
	}
    }

  /* Allow the backend to mark additional target specific sections.  */
  _bfd_coff_gc_mark_extra_sections (info, _bfd_coff_gc_mark_hook);

  /* ... and mark SEC_EXCLUDE for those that go.  */
  return coff_gc_sweep (abfd, info);
}

/* Return name used to identify a comdat group.  */

const char *
bfd_coff_group_name (bfd *abfd, const asection *sec)
{
  struct coff_comdat_info *ci = bfd_coff_get_comdat_section (abfd, sec);
  if (ci != NULL)
    return ci->name;
  return NULL;
}

bool
_bfd_coff_free_cached_info (bfd *abfd)
{
  struct coff_tdata *tdata;

  if (bfd_family_coff (abfd)
      && (bfd_get_format (abfd) == bfd_object
	  || bfd_get_format (abfd) == bfd_core)
      && (tdata = coff_data (abfd)) != NULL)
    {
      if (tdata->section_by_index)
	{
	  htab_delete (tdata->section_by_index);
	  tdata->section_by_index = NULL;
	}

      if (tdata->section_by_target_index)
	{
	  htab_delete (tdata->section_by_target_index);
	  tdata->section_by_target_index = NULL;
	}

      if (obj_pe (abfd) && pe_data (abfd)->comdat_hash)
	{
	  htab_delete (pe_data (abfd)->comdat_hash);
	  pe_data (abfd)->comdat_hash = NULL;
	}

      _bfd_dwarf2_cleanup_debug_info (abfd, &tdata->dwarf2_find_line_info);
      _bfd_stab_cleanup (abfd, &tdata->line_info);

      /* PR 25447:
	 Do not clear the keep_syms and keep_strings flags.
	 These may have been set by pe_ILF_build_a_bfd() indicating
	 that the syms and strings pointers are not to be freed.  */
      _bfd_coff_free_symbols (abfd);

      /* Free raw syms, and any other data bfd_alloc'd after raw syms
	 are read.  */
      if (!obj_coff_keep_raw_syms (abfd) && obj_raw_syments (abfd))
	{
	  bfd_release (abfd, obj_raw_syments (abfd));
	  obj_raw_syments (abfd) = NULL;
	  obj_symbols (abfd) = NULL;
	  obj_convert (abfd) = NULL;
	}
    }

  return _bfd_generic_bfd_free_cached_info (abfd);
}
