/* BFD back-end for archive files (libraries).
   Copyright (C) 1990-2021 Free Software Foundation, Inc.
   Written by Cygnus Support.  Mostly Gumby Henkel-Wallace's fault.

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

/*
@setfilename archive-info
SECTION
	Archives

DESCRIPTION
	An archive (or library) is just another BFD.  It has a symbol
	table, although there's not much a user program will do with it.

	The big difference between an archive BFD and an ordinary BFD
	is that the archive doesn't have sections.  Instead it has a
	chain of BFDs that are considered its contents.  These BFDs can
	be manipulated like any other.  The BFDs contained in an
	archive opened for reading will all be opened for reading.  You
	may put either input or output BFDs into an archive opened for
	output; they will be handled correctly when the archive is closed.

	Use <<bfd_openr_next_archived_file>> to step through
	the contents of an archive opened for input.  You don't
	have to read the entire archive if you don't want
	to!  Read it until you find what you want.

	A BFD returned by <<bfd_openr_next_archived_file>> can be
	closed manually with <<bfd_close>>.  If you do not close it,
	then a second iteration through the members of an archive may
	return the same BFD.  If you close the archive BFD, then all
	the member BFDs will automatically be closed as well.

	Archive contents of output BFDs are chained through the
	<<archive_next>> pointer in a BFD.  The first one is findable
	through the <<archive_head>> slot of the archive.  Set it with
	<<bfd_set_archive_head>> (q.v.).  A given BFD may be in only
	one open output archive at a time.

	As expected, the BFD archive code is more general than the
	archive code of any given environment.  BFD archives may
	contain files of different formats (e.g., a.out and coff) and
	even different architectures.  You may even place archives
	recursively into archives!

	This can cause unexpected confusion, since some archive
	formats are more expressive than others.  For instance, Intel
	COFF archives can preserve long filenames; SunOS a.out archives
	cannot.  If you move a file from the first to the second
	format and back again, the filename may be truncated.
	Likewise, different a.out environments have different
	conventions as to how they truncate filenames, whether they
	preserve directory names in filenames, etc.  When
	interoperating with native tools, be sure your files are
	homogeneous.

	Beware: most of these formats do not react well to the
	presence of spaces in filenames.  We do the best we can, but
	can't always handle this case due to restrictions in the format of
	archives.  Many Unix utilities are braindead in regards to
	spaces and such in filenames anyway, so this shouldn't be much
	of a restriction.

	Archives are supported in BFD in <<archive.c>>.

SUBSECTION
	Archive functions
*/

/* Assumes:
   o - all archive elements start on an even boundary, newline padded;
   o - all arch headers are char *;
   o - all arch headers are the same size (across architectures).
*/

/* Some formats provide a way to cram a long filename into the short
   (16 chars) space provided by a BSD archive.  The trick is: make a
   special "file" in the front of the archive, sort of like the SYMDEF
   entry.  If the filename is too long to fit, put it in the extended
   name table, and use its index as the filename.  To prevent
   confusion prepend the index with a space.  This means you can't
   have filenames that start with a space, but then again, many Unix
   utilities can't handle that anyway.

   This scheme unfortunately requires that you stand on your head in
   order to write an archive since you need to put a magic file at the
   front, and need to touch every entry to do so.  C'est la vie.

   We support two variants of this idea:
   The SVR4 format (extended name table is named "//"),
   and an extended pseudo-BSD variant (extended name table is named
   "ARFILENAMES/").  The origin of the latter format is uncertain.

   BSD 4.4 uses a third scheme:  It writes a long filename
   directly after the header.  This allows 'ar q' to work.
*/

/* Summary of archive member names:

 Symbol table (must be first):
 "__.SYMDEF       " - Symbol table, Berkeley style, produced by ranlib.
 "/               " - Symbol table, system 5 style.

 Long name table (must be before regular file members):
 "//              " - Long name table, System 5 R4 style.
 "ARFILENAMES/    " - Long name table, non-standard extended BSD (not BSD 4.4).

 Regular file members with short names:
 "filename.o/     " - Regular file, System 5 style (embedded spaces ok).
 "filename.o      " - Regular file, Berkeley style (no embedded spaces).

 Regular files with long names (or embedded spaces, for BSD variants):
 "/18             " - SVR4 style, name at offset 18 in name table.
 "#1/23           " - Long name (or embedded spaces) 23 characters long,
		      BSD 4.4 style, full name follows header.
 " 18             " - Long name 18 characters long, extended pseudo-BSD.
 */

#include "sysdep.h"
#include "bfd.h"
#include "libiberty.h"
#include "libbfd.h"
#include "aout/ar.h"
#include "aout/ranlib.h"
#include "safe-ctype.h"
#include "hashtab.h"
#include "filenames.h"
#include "bfdlink.h"

#ifndef errno
extern int errno;
#endif

/* We keep a cache of archive filepointers to archive elements to
   speed up searching the archive by filepos.  We only add an entry to
   the cache when we actually read one.  We also don't sort the cache;
   it's generally short enough to search linearly.
   Note that the pointers here point to the front of the ar_hdr, not
   to the front of the contents!  */
struct ar_cache
{
  file_ptr ptr;
  bfd *arbfd;
};

#define ar_padchar(abfd) ((abfd)->xvec->ar_pad_char)
#define ar_maxnamelen(abfd) ((abfd)->xvec->ar_max_namelen)

#define arch_eltdata(bfd) ((struct areltdata *) ((bfd)->arelt_data))
#define arch_hdr(bfd) ((struct ar_hdr *) arch_eltdata (bfd)->arch_header)

/* True iff NAME designated a BSD 4.4 extended name.  */

#define is_bsd44_extended_name(NAME) \
  (NAME[0] == '#'  && NAME[1] == '1' && NAME[2] == '/' && ISDIGIT (NAME[3]))

void
_bfd_ar_spacepad (char *p, size_t n, const char *fmt, long val)
{
  char buf[20];
  size_t len;

  snprintf (buf, sizeof (buf), fmt, val);
  len = strlen (buf);
  if (len < n)
    {
      memcpy (p, buf, len);
      memset (p + len, ' ', n - len);
    }
  else
    memcpy (p, buf, n);
}

bool
_bfd_ar_sizepad (char *p, size_t n, bfd_size_type size)
{
  char buf[21];
  size_t len;

  snprintf (buf, sizeof (buf), "%-10" BFD_VMA_FMT "u", size);
  len = strlen (buf);
  if (len > n)
    {
      bfd_set_error (bfd_error_file_too_big);
      return false;
    }
  if (len < n)
    {
      memcpy (p, buf, len);
      memset (p + len, ' ', n - len);
    }
  else
    memcpy (p, buf, n);
  return true;
}

bool
_bfd_generic_mkarchive (bfd *abfd)
{
  size_t amt = sizeof (struct artdata);

  abfd->tdata.aout_ar_data = (struct artdata *) bfd_zalloc (abfd, amt);
  if (bfd_ardata (abfd) == NULL)
    return false;

  /* Already cleared by bfd_zalloc above.
     bfd_ardata (abfd)->cache = NULL;
     bfd_ardata (abfd)->archive_head = NULL;
     bfd_ardata (abfd)->symdefs = NULL;
     bfd_ardata (abfd)->extended_names = NULL;
     bfd_ardata (abfd)->extended_names_size = 0;
     bfd_ardata (abfd)->tdata = NULL;  */

  return true;
}

/*
FUNCTION
	bfd_get_next_mapent

SYNOPSIS
	symindex bfd_get_next_mapent
	  (bfd *abfd, symindex previous, carsym **sym);

DESCRIPTION
	Step through archive @var{abfd}'s symbol table (if it
	has one).  Successively update @var{sym} with the next symbol's
	information, returning that symbol's (internal) index into the
	symbol table.

	Supply <<BFD_NO_MORE_SYMBOLS>> as the @var{previous} entry to get
	the first one; returns <<BFD_NO_MORE_SYMBOLS>> when you've already
	got the last one.

	A <<carsym>> is a canonical archive symbol.  The only
	user-visible element is its name, a null-terminated string.
*/

symindex
bfd_get_next_mapent (bfd *abfd, symindex prev, carsym **entry)
{
  if (!bfd_has_map (abfd))
    {
      bfd_set_error (bfd_error_invalid_operation);
      return BFD_NO_MORE_SYMBOLS;
    }

  if (prev == BFD_NO_MORE_SYMBOLS)
    prev = 0;
  else
    ++prev;
  if (prev >= bfd_ardata (abfd)->symdef_count)
    return BFD_NO_MORE_SYMBOLS;

  *entry = (bfd_ardata (abfd)->symdefs + prev);
  return prev;
}

/* To be called by backends only.  */

bfd *
_bfd_create_empty_archive_element_shell (bfd *obfd)
{
  return _bfd_new_bfd_contained_in (obfd);
}

/*
FUNCTION
	bfd_set_archive_head

SYNOPSIS
	bool bfd_set_archive_head (bfd *output, bfd *new_head);

DESCRIPTION
	Set the head of the chain of
	BFDs contained in the archive @var{output} to @var{new_head}.
*/

bool
bfd_set_archive_head (bfd *output_archive, bfd *new_head)
{
  output_archive->archive_head = new_head;
  return true;
}

bfd *
_bfd_look_for_bfd_in_cache (bfd *arch_bfd, file_ptr filepos)
{
  htab_t hash_table = bfd_ardata (arch_bfd)->cache;
  struct ar_cache m;

  m.ptr = filepos;

  if (hash_table)
    {
      struct ar_cache *entry = (struct ar_cache *) htab_find (hash_table, &m);
      if (!entry)
	return NULL;

      /* Unfortunately this flag is set after checking that we have
	 an archive, and checking for an archive means one element has
	 sneaked into the cache.  */
      entry->arbfd->no_export = arch_bfd->no_export;
      return entry->arbfd;
    }
  else
    return NULL;
}

static hashval_t
hash_file_ptr (const void * p)
{
  return (hashval_t) (((struct ar_cache *) p)->ptr);
}

/* Returns non-zero if P1 and P2 are equal.  */

static int
eq_file_ptr (const void * p1, const void * p2)
{
  struct ar_cache *arc1 = (struct ar_cache *) p1;
  struct ar_cache *arc2 = (struct ar_cache *) p2;
  return arc1->ptr == arc2->ptr;
}

/* The calloc function doesn't always take size_t (e.g. on VMS)
   so wrap it to avoid a compile time warning.   */

static void *
_bfd_calloc_wrapper (size_t a, size_t b)
{
  return calloc (a, b);
}

/* Kind of stupid to call cons for each one, but we don't do too many.  */

bool
_bfd_add_bfd_to_archive_cache (bfd *arch_bfd, file_ptr filepos, bfd *new_elt)
{
  struct ar_cache *cache;
  htab_t hash_table = bfd_ardata (arch_bfd)->cache;

  /* If the hash table hasn't been created, create it.  */
  if (hash_table == NULL)
    {
      hash_table = htab_create_alloc (16, hash_file_ptr, eq_file_ptr,
				      NULL, _bfd_calloc_wrapper, free);
      if (hash_table == NULL)
	return false;
      bfd_ardata (arch_bfd)->cache = hash_table;
    }

  /* Insert new_elt into the hash table by filepos.  */
  cache = (struct ar_cache *) bfd_zalloc (arch_bfd, sizeof (struct ar_cache));
  cache->ptr = filepos;
  cache->arbfd = new_elt;
  *htab_find_slot (hash_table, (const void *) cache, INSERT) = cache;

  /* Provide a means of accessing this from child.  */
  arch_eltdata (new_elt)->parent_cache = hash_table;
  arch_eltdata (new_elt)->key = filepos;

  return true;
}

static bfd *
open_nested_file (const char *filename, bfd *archive)
{
  const char *target;
  bfd *n_bfd;

  target = NULL;
  if (!archive->target_defaulted)
    target = archive->xvec->name;
  n_bfd = bfd_openr (filename, target);
  if (n_bfd != NULL)
    {
      n_bfd->lto_output = archive->lto_output;
      n_bfd->no_export = archive->no_export;
      n_bfd->my_archive = archive;
    }
  return n_bfd;
}

static bfd *
find_nested_archive (const char *filename, bfd *arch_bfd)
{
  bfd *abfd;

  /* PR 15140: Don't allow a nested archive pointing to itself.  */
  if (filename_cmp (filename, bfd_get_filename (arch_bfd)) == 0)
    {
      bfd_set_error (bfd_error_malformed_archive);
      return NULL;
    }

  for (abfd = arch_bfd->nested_archives;
       abfd != NULL;
       abfd = abfd->archive_next)
    {
      if (filename_cmp (filename, bfd_get_filename (abfd)) == 0)
	return abfd;
    }
  abfd = open_nested_file (filename, arch_bfd);
  if (abfd)
    {
      abfd->archive_next = arch_bfd->nested_archives;
      arch_bfd->nested_archives = abfd;
    }
  return abfd;
}

/* The name begins with space.  Hence the rest of the name is an index into
   the string table.  */

static char *
get_extended_arelt_filename (bfd *arch, const char *name, file_ptr *originp)
{
  unsigned long table_index = 0;
  const char *endp;

  /* Should extract string so that I can guarantee not to overflow into
     the next region, but I'm too lazy.  */
  errno = 0;
  /* Skip first char, which is '/' in SVR4 or ' ' in some other variants.  */
  table_index = strtol (name + 1, (char **) &endp, 10);
  if (errno != 0 || table_index >= bfd_ardata (arch)->extended_names_size)
    {
      bfd_set_error (bfd_error_malformed_archive);
      return NULL;
    }
  /* In a thin archive, a member of an archive-within-an-archive
     will have the offset in the inner archive encoded here.  */
  if (bfd_is_thin_archive (arch) && endp != NULL && *endp == ':')
    {
      file_ptr origin = strtol (endp + 1, NULL, 10);

      if (errno != 0)
	{
	  bfd_set_error (bfd_error_malformed_archive);
	  return NULL;
	}
      *originp = origin;
    }
  else
    *originp = 0;

  return bfd_ardata (arch)->extended_names + table_index;
}

/* This functions reads an arch header and returns an areltdata pointer, or
   NULL on error.

   Presumes the file pointer is already in the right place (ie pointing
   to the ar_hdr in the file).   Moves the file pointer; on success it
   should be pointing to the front of the file contents; on failure it
   could have been moved arbitrarily.  */

void *
_bfd_generic_read_ar_hdr (bfd *abfd)
{
  return _bfd_generic_read_ar_hdr_mag (abfd, NULL);
}

/* Alpha ECOFF uses an optional different ARFMAG value, so we have a
   variant of _bfd_generic_read_ar_hdr which accepts a magic string.  */

void *
_bfd_generic_read_ar_hdr_mag (bfd *abfd, const char *mag)
{
  struct ar_hdr hdr;
  char *hdrp = (char *) &hdr;
  bfd_size_type parsed_size;
  struct areltdata *ared;
  char *filename = NULL;
  ufile_ptr filesize;
  bfd_size_type namelen = 0;
  bfd_size_type allocsize = sizeof (struct areltdata) + sizeof (struct ar_hdr);
  char *allocptr = 0;
  file_ptr origin = 0;
  unsigned int extra_size = 0;
  char fmag_save;
  int scan;

  if (bfd_bread (hdrp, sizeof (struct ar_hdr), abfd) != sizeof (struct ar_hdr))
    {
      if (bfd_get_error () != bfd_error_system_call)
	bfd_set_error (bfd_error_no_more_archived_files);
      return NULL;
    }
  if (strncmp (hdr.ar_fmag, ARFMAG, 2) != 0
      && (mag == NULL
	  || strncmp (hdr.ar_fmag, mag, 2) != 0))
    {
      bfd_set_error (bfd_error_malformed_archive);
      return NULL;
    }

  errno = 0;
  fmag_save = hdr.ar_fmag[0];
  hdr.ar_fmag[0] = 0;
  scan = sscanf (hdr.ar_size, "%" BFD_VMA_FMT "u", &parsed_size);
  hdr.ar_fmag[0] = fmag_save;
  if (scan != 1)
    {
      bfd_set_error (bfd_error_malformed_archive);
      return NULL;
    }

  /* Extract the filename from the archive - there are two ways to
     specify an extended name table, either the first char of the
     name is a space, or it's a slash.  */
  if ((hdr.ar_name[0] == '/'
       || (hdr.ar_name[0] == ' '
	   && memchr (hdr.ar_name, '/', ar_maxnamelen (abfd)) == NULL))
      && bfd_ardata (abfd)->extended_names != NULL)
    {
      filename = get_extended_arelt_filename (abfd, hdr.ar_name, &origin);
      if (filename == NULL)
	return NULL;
    }
  /* BSD4.4-style long filename.  */
  else if (is_bsd44_extended_name (hdr.ar_name))
    {
      /* BSD-4.4 extended name */
      namelen = atoi (&hdr.ar_name[3]);
      filesize = bfd_get_file_size (abfd);
      if (namelen > parsed_size
	  || namelen > -allocsize - 2
	  || (filesize != 0 && namelen > filesize))
	{
	  bfd_set_error (bfd_error_malformed_archive);
	  return NULL;
	}
      allocsize += namelen + 1;
      parsed_size -= namelen;
      extra_size = namelen;

      allocptr = (char *) bfd_malloc (allocsize);
      if (allocptr == NULL)
	return NULL;
      filename = (allocptr
		  + sizeof (struct areltdata)
		  + sizeof (struct ar_hdr));
      if (bfd_bread (filename, namelen, abfd) != namelen)
	{
	  free (allocptr);
	  if (bfd_get_error () != bfd_error_system_call)
	    bfd_set_error (bfd_error_no_more_archived_files);
	  return NULL;
	}
      filename[namelen] = '\0';
    }
  else
    {
      /* We judge the end of the name by looking for '/' or ' '.
	 Note:  The SYSV format (terminated by '/') allows embedded
	 spaces, so only look for ' ' if we don't find '/'.  */

      char *e;
      e = (char *) memchr (hdr.ar_name, '\0', ar_maxnamelen (abfd));
      if (e == NULL)
	{
	  e = (char *) memchr (hdr.ar_name, '/', ar_maxnamelen (abfd));
	  if (e == NULL)
	    e = (char *) memchr (hdr.ar_name, ' ', ar_maxnamelen (abfd));
	}

      if (e != NULL)
	namelen = e - hdr.ar_name;
      else
	{
	  /* If we didn't find a termination character, then the name
	     must be the entire field.  */
	  namelen = ar_maxnamelen (abfd);
	}

      allocsize += namelen + 1;
    }

  if (!allocptr)
    {
      allocptr = (char *) bfd_malloc (allocsize);
      if (allocptr == NULL)
	return NULL;
    }

  memset (allocptr, 0, sizeof (struct areltdata));
  ared = (struct areltdata *) allocptr;
  ared->arch_header = allocptr + sizeof (struct areltdata);
  memcpy (ared->arch_header, &hdr, sizeof (struct ar_hdr));
  ared->parsed_size = parsed_size;
  ared->extra_size = extra_size;
  ared->origin = origin;

  if (filename != NULL)
    ared->filename = filename;
  else
    {
      ared->filename = allocptr + (sizeof (struct areltdata) +
				   sizeof (struct ar_hdr));
      if (namelen)
	memcpy (ared->filename, hdr.ar_name, namelen);
      ared->filename[namelen] = '\0';
    }

  return ared;
}

/* Append the relative pathname for a member of the thin archive
   to the pathname of the directory containing the archive.  */

char *
_bfd_append_relative_path (bfd *arch, char *elt_name)
{
  const char *arch_name = bfd_get_filename (arch);
  const char *base_name = lbasename (arch_name);
  size_t prefix_len;
  char *filename;

  if (base_name == arch_name)
    return elt_name;

  prefix_len = base_name - arch_name;
  filename = (char *) bfd_alloc (arch, prefix_len + strlen (elt_name) + 1);
  if (filename == NULL)
    return NULL;

  strncpy (filename, arch_name, prefix_len);
  strcpy (filename + prefix_len, elt_name);
  return filename;
}

/* This is an internal function; it's mainly used when indexing
   through the archive symbol table, but also used to get the next
   element, since it handles the bookkeeping so nicely for us.  */

bfd *
_bfd_get_elt_at_filepos (bfd *archive, file_ptr filepos)
{
  struct areltdata *new_areldata;
  bfd *n_bfd;
  char *filename;

  n_bfd = _bfd_look_for_bfd_in_cache (archive, filepos);
  if (n_bfd)
    return n_bfd;

  if (0 > bfd_seek (archive, filepos, SEEK_SET))
    return NULL;

  if ((new_areldata = (struct areltdata *) _bfd_read_ar_hdr (archive)) == NULL)
    return NULL;

  filename = new_areldata->filename;

  if (bfd_is_thin_archive (archive))
    {
      /* This is a proxy entry for an external file.  */
      if (! IS_ABSOLUTE_PATH (filename))
	{
	  filename = _bfd_append_relative_path (archive, filename);
	  if (filename == NULL)
	    {
	      free (new_areldata);
	      return NULL;
	    }
	}

      if (new_areldata->origin > 0)
	{
	  /* This proxy entry refers to an element of a nested archive.
	     Locate the member of that archive and return a bfd for it.  */
	  bfd *ext_arch = find_nested_archive (filename, archive);

	  if (ext_arch == NULL
	      || ! bfd_check_format (ext_arch, bfd_archive))
	    {
	      free (new_areldata);
	      return NULL;
	    }
	  n_bfd = _bfd_get_elt_at_filepos (ext_arch, new_areldata->origin);
	  if (n_bfd == NULL)
	    {
	      free (new_areldata);
	      return NULL;
	    }
	  n_bfd->proxy_origin = bfd_tell (archive);

	  /* Copy BFD_COMPRESS, BFD_DECOMPRESS and BFD_COMPRESS_GABI
	     flags.  */
	  n_bfd->flags |= archive->flags & (BFD_COMPRESS
					    | BFD_DECOMPRESS
					    | BFD_COMPRESS_GABI);

	  return n_bfd;
	}

      /* It's not an element of a nested archive;
	 open the external file as a bfd.  */
      bfd_set_error (bfd_error_no_error);
      n_bfd = open_nested_file (filename, archive);
      if (n_bfd == NULL && bfd_get_error () == bfd_error_no_error)
	bfd_set_error (bfd_error_malformed_archive);
    }
  else
    {
      n_bfd = _bfd_create_empty_archive_element_shell (archive);
    }

  if (n_bfd == NULL)
    {
      free (new_areldata);
      return NULL;
    }

  n_bfd->proxy_origin = bfd_tell (archive);

  if (bfd_is_thin_archive (archive))
    {
      n_bfd->origin = 0;
    }
  else
    {
      n_bfd->origin = n_bfd->proxy_origin;
      if (!bfd_set_filename (n_bfd, filename))
	goto out;
    }

  n_bfd->arelt_data = new_areldata;

  /* Copy BFD_COMPRESS, BFD_DECOMPRESS and BFD_COMPRESS_GABI flags.  */
  n_bfd->flags |= archive->flags & (BFD_COMPRESS
				    | BFD_DECOMPRESS
				    | BFD_COMPRESS_GABI);

  /* Copy is_linker_input.  */
  n_bfd->is_linker_input = archive->is_linker_input;

  if (archive->no_element_cache
      || _bfd_add_bfd_to_archive_cache (archive, filepos, n_bfd))
    return n_bfd;

 out:
  free (new_areldata);
  n_bfd->arelt_data = NULL;
  bfd_close (n_bfd);
  return NULL;
}

/* Return the BFD which is referenced by the symbol in ABFD indexed by
   SYM_INDEX.  SYM_INDEX should have been returned by bfd_get_next_mapent.  */

bfd *
_bfd_generic_get_elt_at_index (bfd *abfd, symindex sym_index)
{
  carsym *entry;

  entry = bfd_ardata (abfd)->symdefs + sym_index;
  return _bfd_get_elt_at_filepos (abfd, entry->file_offset);
}

bfd *
_bfd_noarchive_get_elt_at_index (bfd *abfd,
				 symindex sym_index ATTRIBUTE_UNUSED)
{
  return (bfd *) _bfd_ptr_bfd_null_error (abfd);
}

/*
FUNCTION
	bfd_openr_next_archived_file

SYNOPSIS
	bfd *bfd_openr_next_archived_file (bfd *archive, bfd *previous);

DESCRIPTION
	Provided a BFD, @var{archive}, containing an archive and NULL, open
	an input BFD on the first contained element and returns that.
	Subsequent calls should pass the archive and the previous return
	value to return a created BFD to the next contained element.  NULL
	is returned when there are no more.
	Note - if you want to process the bfd returned by this call be
	sure to call bfd_check_format() on it first.
*/

bfd *
bfd_openr_next_archived_file (bfd *archive, bfd *last_file)
{
  if ((bfd_get_format (archive) != bfd_archive)
      || (archive->direction == write_direction))
    {
      bfd_set_error (bfd_error_invalid_operation);
      return NULL;
    }

  return BFD_SEND (archive,
		   openr_next_archived_file, (archive, last_file));
}

bfd *
bfd_generic_openr_next_archived_file (bfd *archive, bfd *last_file)
{
  ufile_ptr filestart;

  if (!last_file)
    filestart = bfd_ardata (archive)->first_file_filepos;
  else
    {
      filestart = last_file->proxy_origin;
      if (! bfd_is_thin_archive (archive))
	{
	  bfd_size_type size = arelt_size (last_file);

	  filestart += size;
	  /* Pad to an even boundary...
	     Note that last_file->origin can be odd in the case of
	     BSD-4.4-style element with a long odd size.  */
	  filestart += filestart % 2;
	  if (filestart < last_file->proxy_origin)
	    {
	      /* Prevent looping.  See PR19256.  */
	      bfd_set_error (bfd_error_malformed_archive);
	      return NULL;
	    }
	}
    }

  return _bfd_get_elt_at_filepos (archive, filestart);
}

bfd *
_bfd_noarchive_openr_next_archived_file (bfd *archive,
					 bfd *last_file ATTRIBUTE_UNUSED)
{
  return (bfd *) _bfd_ptr_bfd_null_error (archive);
}

bfd_cleanup
bfd_generic_archive_p (bfd *abfd)
{
  struct artdata *tdata_hold;
  char armag[SARMAG + 1];
  size_t amt;

  if (bfd_bread (armag, SARMAG, abfd) != SARMAG)
    {
      if (bfd_get_error () != bfd_error_system_call)
	bfd_set_error (bfd_error_wrong_format);
      return NULL;
    }

  bfd_set_thin_archive (abfd, strncmp (armag, ARMAGT, SARMAG) == 0);

  if (strncmp (armag, ARMAG, SARMAG) != 0
      && ! bfd_is_thin_archive (abfd))
    {
      bfd_set_error (bfd_error_wrong_format);
      return NULL;
    }

  tdata_hold = bfd_ardata (abfd);

  amt = sizeof (struct artdata);
  bfd_ardata (abfd) = (struct artdata *) bfd_zalloc (abfd, amt);
  if (bfd_ardata (abfd) == NULL)
    {
      bfd_ardata (abfd) = tdata_hold;
      return NULL;
    }

  bfd_ardata (abfd)->first_file_filepos = SARMAG;
  /* Cleared by bfd_zalloc above.
     bfd_ardata (abfd)->cache = NULL;
     bfd_ardata (abfd)->archive_head = NULL;
     bfd_ardata (abfd)->symdefs = NULL;
     bfd_ardata (abfd)->extended_names = NULL;
     bfd_ardata (abfd)->extended_names_size = 0;
     bfd_ardata (abfd)->tdata = NULL;  */

  if (!BFD_SEND (abfd, _bfd_slurp_armap, (abfd))
      || !BFD_SEND (abfd, _bfd_slurp_extended_name_table, (abfd)))
    {
      if (bfd_get_error () != bfd_error_system_call)
	bfd_set_error (bfd_error_wrong_format);
      bfd_release (abfd, bfd_ardata (abfd));
      bfd_ardata (abfd) = tdata_hold;
      return NULL;
    }

  if (abfd->target_defaulted && bfd_has_map (abfd))
    {
      bfd *first;
      unsigned int save;

      /* This archive has a map, so we may presume that the contents
	 are object files.  Make sure that if the first file in the
	 archive can be recognized as an object file, it is for this
	 target.  If not, assume that this is the wrong format.  If
	 the first file is not an object file, somebody is doing
	 something weird, and we permit it so that ar -t will work.

	 This is done because any normal format will recognize any
	 normal archive, regardless of the format of the object files.
	 We do accept an empty archive.  */

      save = abfd->no_element_cache;
      abfd->no_element_cache = 1;
      first = bfd_openr_next_archived_file (abfd, NULL);
      abfd->no_element_cache = save;
      if (first != NULL)
	{
	  first->target_defaulted = false;
	  if (bfd_check_format (first, bfd_object)
	      && first->xvec != abfd->xvec)
	    bfd_set_error (bfd_error_wrong_object_format);
	  bfd_close (first);
	}
    }

  return _bfd_no_cleanup;
}

/* Some constants for a 32 bit BSD archive structure.  We do not
   support 64 bit archives presently; so far as I know, none actually
   exist.  Supporting them would require changing these constants, and
   changing some H_GET_32 to H_GET_64.  */

/* The size of an external symdef structure.  */
#define BSD_SYMDEF_SIZE 8

/* The offset from the start of a symdef structure to the file offset.  */
#define BSD_SYMDEF_OFFSET_SIZE 4

/* The size of the symdef count.  */
#define BSD_SYMDEF_COUNT_SIZE 4

/* The size of the string count.  */
#define BSD_STRING_COUNT_SIZE 4

/* Read a BSD-style archive symbol table.  Returns FALSE on error,
   TRUE otherwise.  */

static bool
do_slurp_bsd_armap (bfd *abfd)
{
  struct areltdata *mapdata;
  size_t counter;
  bfd_byte *raw_armap, *rbase;
  struct artdata *ardata = bfd_ardata (abfd);
  char *stringbase;
  bfd_size_type parsed_size;
  size_t amt, string_size;
  carsym *set;

  mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
  if (mapdata == NULL)
    return false;
  parsed_size = mapdata->parsed_size;
  free (mapdata);
  /* PR 17512: file: 883ff754.  */
  /* PR 17512: file: 0458885f.  */
  if (parsed_size < BSD_SYMDEF_COUNT_SIZE + BSD_STRING_COUNT_SIZE)
    {
      bfd_set_error (bfd_error_malformed_archive);
      return false;
    }

  raw_armap = (bfd_byte *) _bfd_alloc_and_read (abfd, parsed_size, parsed_size);
  if (raw_armap == NULL)
    return false;

  parsed_size -= BSD_SYMDEF_COUNT_SIZE + BSD_STRING_COUNT_SIZE;
  amt = H_GET_32 (abfd, raw_armap);
  if (amt > parsed_size
      || amt % BSD_SYMDEF_SIZE != 0)
    {
      /* Probably we're using the wrong byte ordering.  */
      bfd_set_error (bfd_error_wrong_format);
      goto release_armap;
    }

  rbase = raw_armap + BSD_SYMDEF_COUNT_SIZE;
  stringbase = (char *) rbase + amt + BSD_STRING_COUNT_SIZE;
  string_size = parsed_size - amt;

  ardata->symdef_count = amt / BSD_SYMDEF_SIZE;
  if (_bfd_mul_overflow (ardata->symdef_count, sizeof (carsym), &amt))
    {
      bfd_set_error (bfd_error_no_memory);
      goto release_armap;
    }
  ardata->symdefs = (struct carsym *) bfd_alloc (abfd, amt);
  if (!ardata->symdefs)
    goto release_armap;

  for (counter = 0, set = ardata->symdefs;
       counter < ardata->symdef_count;
       counter++, set++, rbase += BSD_SYMDEF_SIZE)
    {
      unsigned nameoff = H_GET_32 (abfd, rbase);
      if (nameoff >= string_size)
	{
	  bfd_set_error (bfd_error_malformed_archive);
	  goto release_armap;
	}
      set->name = stringbase + nameoff;
      set->file_offset = H_GET_32 (abfd, rbase + BSD_SYMDEF_OFFSET_SIZE);
    }

  ardata->first_file_filepos = bfd_tell (abfd);
  /* Pad to an even boundary if you have to.  */
  ardata->first_file_filepos += (ardata->first_file_filepos) % 2;
  /* FIXME, we should provide some way to free raw_ardata when
     we are done using the strings from it.  For now, it seems
     to be allocated on an objalloc anyway...  */
  abfd->has_armap = true;
  return true;

 release_armap:
  ardata->symdef_count = 0;
  ardata->symdefs = NULL;
  bfd_release (abfd, raw_armap);
  return false;
}

/* Read a COFF archive symbol table.  Returns FALSE on error, TRUE
   otherwise.  */

static bool
do_slurp_coff_armap (bfd *abfd)
{
  struct areltdata *mapdata;
  int *raw_armap, *rawptr;
  struct artdata *ardata = bfd_ardata (abfd);
  char *stringbase;
  char *stringend;
  bfd_size_type stringsize;
  bfd_size_type parsed_size;
  ufile_ptr filesize;
  size_t nsymz, carsym_size, ptrsize, i;
  carsym *carsyms;
  bfd_vma (*swap) (const void *);
  char int_buf[4];
  struct areltdata *tmp;

  mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
  if (mapdata == NULL)
    return false;
  parsed_size = mapdata->parsed_size;
  free (mapdata);

  if (bfd_bread (int_buf, 4, abfd) != 4)
    return false;

  /* It seems that all numeric information in a coff archive is always
     in big endian format, no matter the host or target.  */
  swap = bfd_getb32;
  nsymz = bfd_getb32 (int_buf);

  /* The coff armap must be read sequentially.  So we construct a
     bsd-style one in core all at once, for simplicity.  */

  if (_bfd_mul_overflow (nsymz, sizeof (carsym), &carsym_size))
    {
      bfd_set_error (bfd_error_no_memory);
      return false;
    }

  filesize = bfd_get_file_size (abfd);
  ptrsize = 4 * nsymz;
  if ((filesize != 0 && parsed_size > filesize)
      || parsed_size < 4
      || parsed_size - 4 < ptrsize)
    {
      bfd_set_error (bfd_error_malformed_archive);
      return false;
    }

  stringsize = parsed_size - ptrsize - 4;

  if (carsym_size + stringsize + 1 <= carsym_size)
    {
      bfd_set_error (bfd_error_no_memory);
      return false;
    }

  /* Allocate and read in the raw offsets.  */
  raw_armap = (int *) _bfd_malloc_and_read (abfd, ptrsize, ptrsize);
  if (raw_armap == NULL)
    return false;

  ardata->symdefs = (struct carsym *) bfd_alloc (abfd,
						 carsym_size + stringsize + 1);
  if (ardata->symdefs == NULL)
    goto free_armap;
  carsyms = ardata->symdefs;
  stringbase = ((char *) ardata->symdefs) + carsym_size;

  if (bfd_bread (stringbase, stringsize, abfd) != stringsize)
    goto release_symdefs;

  /* OK, build the carsyms.  */
  stringend = stringbase + stringsize;
  *stringend = 0;
  for (i = 0; i < nsymz; i++)
    {
      rawptr = raw_armap + i;
      carsyms->file_offset = swap ((bfd_byte *) rawptr);
      carsyms->name = stringbase;
      stringbase += strlen (stringbase);
      if (stringbase != stringend)
	++stringbase;
      carsyms++;
    }

  ardata->symdef_count = nsymz;
  ardata->first_file_filepos = bfd_tell (abfd);
  /* Pad to an even boundary if you have to.  */
  ardata->first_file_filepos += (ardata->first_file_filepos) % 2;
  if (bfd_seek (abfd, ardata->first_file_filepos, SEEK_SET) != 0)
    goto release_symdefs;

  abfd->has_armap = true;
  free (raw_armap);

  /* Check for a second archive header (as used by PE).  */
  tmp = (struct areltdata *) _bfd_read_ar_hdr (abfd);
  if (tmp != NULL)
    {
      if (tmp->arch_header[0] == '/'
	  && tmp->arch_header[1] == ' ')
	ardata->first_file_filepos
	  += (tmp->parsed_size + sizeof (struct ar_hdr) + 1) & ~(unsigned) 1;
      free (tmp);
    }

  return true;

 release_symdefs:
  bfd_release (abfd, (ardata)->symdefs);
 free_armap:
  free (raw_armap);
  return false;
}

/* This routine can handle either coff-style or bsd-style armaps
   (archive symbol table).  Returns FALSE on error, TRUE otherwise */

bool
bfd_slurp_armap (bfd *abfd)
{
  char nextname[17];
  int i = bfd_bread (nextname, 16, abfd);

  if (i == 0)
    return true;
  if (i != 16)
    return false;

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

  if (startswith (nextname, "__.SYMDEF       ")
      || startswith (nextname, "__.SYMDEF/      ")) /* Old Linux archives.  */
    return do_slurp_bsd_armap (abfd);
  else if (startswith (nextname, "/               "))
    return do_slurp_coff_armap (abfd);
  else if (startswith (nextname, "/SYM64/         "))
    {
      /* 64bit (Irix 6) archive.  */
#ifdef BFD64
      return _bfd_archive_64_bit_slurp_armap (abfd);
#else
      bfd_set_error (bfd_error_wrong_format);
      return false;
#endif
    }
  else if (startswith (nextname, "#1/20           "))
    {
      /* Mach-O has a special name for armap when the map is sorted by name.
	 However because this name has a space it is slightly more difficult
	 to check it.  */
      struct ar_hdr hdr;
      char extname[21];

      if (bfd_bread (&hdr, sizeof (hdr), abfd) != sizeof (hdr))
	return false;
      /* Read the extended name.  We know its length.  */
      if (bfd_bread (extname, 20, abfd) != 20)
	return false;
      if (bfd_seek (abfd, -(file_ptr) (sizeof (hdr) + 20), SEEK_CUR) != 0)
	return false;
      extname[20] = 0;
      if (startswith (extname, "__.SYMDEF SORTED")
	  || startswith (extname, "__.SYMDEF"))
	return do_slurp_bsd_armap (abfd);
    }

  abfd->has_armap = false;
  return true;
}

/** Extended name table.

  Normally archives support only 14-character filenames.

  Intel has extended the format: longer names are stored in a special
  element (the first in the archive, or second if there is an armap);
  the name in the ar_hdr is replaced by <space><index into filename
  element>.  Index is the P.R. of an int (decimal).  Data General have
  extended the format by using the prefix // for the special element.  */

/* Returns FALSE on error, TRUE otherwise.  */

bool
_bfd_slurp_extended_name_table (bfd *abfd)
{
  char nextname[17];

  /* FIXME:  Formatting sucks here, and in case of failure of BFD_READ,
     we probably don't want to return TRUE.  */
  if (bfd_seek (abfd, bfd_ardata (abfd)->first_file_filepos, SEEK_SET) != 0)
    return false;

  if (bfd_bread (nextname, 16, abfd) == 16)
    {
      struct areltdata *namedata;
      bfd_size_type amt;
      ufile_ptr filesize;

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

      if (! startswith (nextname, "ARFILENAMES/    ")
	  && ! startswith (nextname, "//              "))
	{
	  bfd_ardata (abfd)->extended_names = NULL;
	  bfd_ardata (abfd)->extended_names_size = 0;
	  return true;
	}

      namedata = (struct areltdata *) _bfd_read_ar_hdr (abfd);
      if (namedata == NULL)
	return false;

      filesize = bfd_get_file_size (abfd);
      amt = namedata->parsed_size;
      if (amt + 1 == 0 || (filesize != 0 && amt > filesize))
	{
	  bfd_set_error (bfd_error_malformed_archive);
	  goto byebye;
	}

      bfd_ardata (abfd)->extended_names_size = amt;
      bfd_ardata (abfd)->extended_names = (char *) bfd_alloc (abfd, amt + 1);
      if (bfd_ardata (abfd)->extended_names == NULL)
	{
	byebye:
	  free (namedata);
	  bfd_ardata (abfd)->extended_names = NULL;
	  bfd_ardata (abfd)->extended_names_size = 0;
	  return false;
	}

      if (bfd_bread (bfd_ardata (abfd)->extended_names, amt, abfd) != amt)
	{
	  if (bfd_get_error () != bfd_error_system_call)
	    bfd_set_error (bfd_error_malformed_archive);
	  bfd_release (abfd, (bfd_ardata (abfd)->extended_names));
	  bfd_ardata (abfd)->extended_names = NULL;
	  goto byebye;
	}
      bfd_ardata (abfd)->extended_names[amt] = 0;

      /* Since the archive is supposed to be printable if it contains
	 text, the entries in the list are newline-padded, not null
	 padded. In SVR4-style archives, the names also have a
	 trailing '/'.  DOS/NT created archive often have \ in them
	 We'll fix all problems here.  */
      {
	char *ext_names = bfd_ardata (abfd)->extended_names;
	char *temp = ext_names;
	char *limit = temp + namedata->parsed_size;

	for (; temp < limit; ++temp)
	  {
	    if (*temp == ARFMAG[1])
	      temp[temp > ext_names && temp[-1] == '/' ? -1 : 0] = '\0';
	    if (*temp == '\\')
	      *temp = '/';
	  }
	*limit = '\0';
      }

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

      free (namedata);
    }
  return true;
}

#ifdef VMS

/* Return a copy of the stuff in the filename between any :]> and a
   semicolon.  */

static const char *
normalize (bfd *abfd, const char *file)
{
  const char *first;
  const char *last;
  char *copy;

  if (abfd->flags & BFD_ARCHIVE_FULL_PATH)
    return file;

  first = file + strlen (file) - 1;
  last = first + 1;

  while (first != file)
    {
      if (*first == ';')
	last = first;
      if (*first == ':' || *first == ']' || *first == '>')
	{
	  first++;
	  break;
	}
      first--;
    }

  copy = bfd_alloc (abfd, last - first + 1);
  if (copy == NULL)
    return NULL;

  memcpy (copy, first, last - first);
  copy[last - first] = 0;

  return copy;
}

#else
static const char *
normalize (bfd *abfd, const char *file)
{
  if (abfd->flags & BFD_ARCHIVE_FULL_PATH)
    return file;
  return lbasename (file);
}
#endif

/* Adjust a relative path name based on the reference path.
   For example:

     Relative path  Reference path  Result
     -------------  --------------  ------
     bar.o	    lib.a	    bar.o
     foo/bar.o	    lib.a	    foo/bar.o
     bar.o	    foo/lib.a	    ../bar.o
     foo/bar.o	    baz/lib.a	    ../foo/bar.o
     bar.o	    ../lib.a	    <parent of current dir>/bar.o
   ; ../bar.o	    ../lib.a	    bar.o
   ; ../bar.o	    lib.a	    ../bar.o
     foo/bar.o	    ../lib.a	    <parent of current dir>/foo/bar.o
     bar.o	    ../../lib.a	    <grandparent>/<parent>/bar.o
     bar.o	    foo/baz/lib.a   ../../bar.o

   Note - the semicolons above are there to prevent the BFD chew
   utility from interpreting those lines as prototypes to put into
   the autogenerated bfd.h header...

   Note - the string is returned in a static buffer.  */

static const char *
adjust_relative_path (const char * path, const char * ref_path)
{
  static char *pathbuf = NULL;
  static unsigned int pathbuf_len = 0;
  const char *pathp;
  const char *refp;
  char * lpath;
  char * rpath;
  unsigned int len;
  unsigned int dir_up = 0;
  unsigned int dir_down = 0;
  char *newp;
  char * pwd = getpwd ();
  const char * down;

  /* Remove symlinks, '.' and '..' from the paths, if possible.  */
  lpath = lrealpath (path);
  pathp = lpath == NULL ? path : lpath;

  rpath = lrealpath (ref_path);
  refp = rpath == NULL ? ref_path : rpath;

  /* Remove common leading path elements.  */
  for (;;)
    {
      const char *e1 = pathp;
      const char *e2 = refp;

      while (*e1 && ! IS_DIR_SEPARATOR (*e1))
	++e1;
      while (*e2 && ! IS_DIR_SEPARATOR (*e2))
	++e2;
      if (*e1 == '\0' || *e2 == '\0' || e1 - pathp != e2 - refp
	  || filename_ncmp (pathp, refp, e1 - pathp) != 0)
	break;
      pathp = e1 + 1;
      refp = e2 + 1;
    }

  len = strlen (pathp) + 1;
  /* For each leading path element in the reference path,
     insert "../" into the path.  */
  for (; *refp; ++refp)
    if (IS_DIR_SEPARATOR (*refp))
      {
	/* PR 12710:  If the path element is "../" then instead of
	   inserting "../" we need to insert the name of the directory
	   at the current level.  */
	if (refp > ref_path + 1
	    && refp[-1] == '.'
	    && refp[-2] == '.')
	  dir_down ++;
	else
	  dir_up ++;
      }

  /* If the lrealpath calls above succeeded then we should never
     see dir_up and dir_down both being non-zero.  */

  len += 3 * dir_up;

  if (dir_down)
    {
      down = pwd + strlen (pwd) - 1;

      while (dir_down && down > pwd)
	{
	  if (IS_DIR_SEPARATOR (*down))
	    --dir_down;
	}
      BFD_ASSERT (dir_down == 0);
      len += strlen (down) + 1;
    }
  else
    down = NULL;

  if (len > pathbuf_len)
    {
      free (pathbuf);
      pathbuf_len = 0;
      pathbuf = (char *) bfd_malloc (len);
      if (pathbuf == NULL)
	goto out;
      pathbuf_len = len;
    }

  newp = pathbuf;
  while (dir_up-- > 0)
    {
      /* FIXME: Support Windows style path separators as well.  */
      strcpy (newp, "../");
      newp += 3;
    }

  if (down)
    sprintf (newp, "%s/%s", down, pathp);
  else
    strcpy (newp, pathp);

 out:
  free (lpath);
  free (rpath);
  return pathbuf;
}

/* Build a BFD style extended name table.  */

bool
_bfd_archive_bsd_construct_extended_name_table (bfd *abfd,
						char **tabloc,
						bfd_size_type *tablen,
						const char **name)
{
  *name = "ARFILENAMES/";
  return _bfd_construct_extended_name_table (abfd, false, tabloc, tablen);
}

/* Build an SVR4 style extended name table.  */

bool
_bfd_archive_coff_construct_extended_name_table (bfd *abfd,
						 char **tabloc,
						 bfd_size_type *tablen,
						 const char **name)
{
  *name = "//";
  return _bfd_construct_extended_name_table (abfd, true, tabloc, tablen);
}

bool
_bfd_noarchive_construct_extended_name_table (bfd *abfd ATTRIBUTE_UNUSED,
					      char **tabloc ATTRIBUTE_UNUSED,
					      bfd_size_type *len ATTRIBUTE_UNUSED,
					      const char **name ATTRIBUTE_UNUSED)
{
  return true;
}

/* Follows archive_head and produces an extended name table if
   necessary.  Returns (in tabloc) a pointer to an extended name
   table, and in tablen the length of the table.  If it makes an entry
   it clobbers the filename so that the element may be written without
   further massage.  Returns TRUE if it ran successfully, FALSE if
   something went wrong.  A successful return may still involve a
   zero-length tablen!  */

bool
_bfd_construct_extended_name_table (bfd *abfd,
				    bool trailing_slash,
				    char **tabloc,
				    bfd_size_type *tablen)
{
  unsigned int maxname = ar_maxnamelen (abfd);
  bfd_size_type total_namelen = 0;
  bfd *current;
  char *strptr;
  const char *last_filename;
  long last_stroff;

  *tablen = 0;
  last_filename = NULL;

  /* Figure out how long the table should be.  */
  for (current = abfd->archive_head;
       current != NULL;
       current = current->archive_next)
    {
      const char *normal;
      unsigned int thislen;

      if (bfd_is_thin_archive (abfd))
	{
	  const char *filename = bfd_get_filename (current);

	  /* If the element being added is a member of another archive
	     (i.e., we are flattening), use the containing archive's name.  */
	  if (current->my_archive
	      && ! bfd_is_thin_archive (current->my_archive))
	    filename = bfd_get_filename (current->my_archive);

	  /* If the path is the same as the previous path seen,
	     reuse it.  This can happen when flattening a thin
	     archive that contains other archives.  */
	  if (last_filename && filename_cmp (last_filename, filename) == 0)
	    continue;

	  last_filename = filename;

	  /* If the path is relative, adjust it relative to
	     the containing archive. */
	  if (! IS_ABSOLUTE_PATH (filename)
	      && ! IS_ABSOLUTE_PATH (bfd_get_filename (abfd)))
	    normal = adjust_relative_path (filename, bfd_get_filename (abfd));
	  else
	    normal = filename;

	  /* In a thin archive, always store the full pathname
	     in the extended name table.  */
	  total_namelen += strlen (normal) + 1;
	  if (trailing_slash)
	    /* Leave room for trailing slash.  */
	    ++total_namelen;

	  continue;
	}

      normal = normalize (abfd, bfd_get_filename (current));
      if (normal == NULL)
	return false;

      thislen = strlen (normal);

      if (thislen > maxname
	  && (bfd_get_file_flags (abfd) & BFD_TRADITIONAL_FORMAT) != 0)
	thislen = maxname;

      if (thislen > maxname)
	{
	  /* Add one to leave room for \n.  */
	  total_namelen += thislen + 1;
	  if (trailing_slash)
	    {
	      /* Leave room for trailing slash.  */
	      ++total_namelen;
	    }
	}
      else
	{
	  struct ar_hdr *hdr = arch_hdr (current);
	  if (filename_ncmp (normal, hdr->ar_name, thislen) != 0
	      || (thislen < sizeof hdr->ar_name
		  && hdr->ar_name[thislen] != ar_padchar (current)))
	    {
	      /* Must have been using extended format even though it
		 didn't need to.  Fix it to use normal format.  */
	      memcpy (hdr->ar_name, normal, thislen);
	      if (thislen < maxname
		  || (thislen == maxname && thislen < sizeof hdr->ar_name))
		hdr->ar_name[thislen] = ar_padchar (current);
	    }
	}
    }

  if (total_namelen == 0)
    return true;

  *tabloc = (char *) bfd_alloc (abfd, total_namelen);
  if (*tabloc == NULL)
    return false;

  *tablen = total_namelen;
  strptr = *tabloc;

  last_filename = NULL;
  last_stroff = 0;

  for (current = abfd->archive_head;
       current != NULL;
       current = current->archive_next)
    {
      const char *normal;
      unsigned int thislen;
      long stroff;
      const char *filename = bfd_get_filename (current);

      if (bfd_is_thin_archive (abfd))
	{
	  /* If the element being added is a member of another archive
	     (i.e., we are flattening), use the containing archive's name.  */
	  if (current->my_archive
	      && ! bfd_is_thin_archive (current->my_archive))
	    filename = bfd_get_filename (current->my_archive);
	  /* If the path is the same as the previous path seen,
	     reuse it.  This can happen when flattening a thin
	     archive that contains other archives.
	     If the path is relative, adjust it relative to
	     the containing archive.  */
	  if (last_filename && filename_cmp (last_filename, filename) == 0)
	    normal = last_filename;
	  else if (! IS_ABSOLUTE_PATH (filename)
		   && ! IS_ABSOLUTE_PATH (bfd_get_filename (abfd)))
	    normal = adjust_relative_path (filename, bfd_get_filename (abfd));
	  else
	    normal = filename;
	}
      else
	{
	  normal = normalize (abfd, filename);
	  if (normal == NULL)
	    return false;
	}

      thislen = strlen (normal);
      if (thislen > maxname || bfd_is_thin_archive (abfd))
	{
	  /* Works for now; may need to be re-engineered if we
	     encounter an oddball archive format and want to
	     generalise this hack.  */
	  struct ar_hdr *hdr = arch_hdr (current);
	  if (normal == last_filename)
	    stroff = last_stroff;
	  else
	    {
	      last_filename = filename;
	      stroff = strptr - *tabloc;
	      last_stroff = stroff;
	      memcpy (strptr, normal, thislen);
	      strptr += thislen;
	      if (trailing_slash)
		*strptr++ = '/';
	      *strptr++ = ARFMAG[1];
	    }
	  hdr->ar_name[0] = ar_padchar (current);
	  if (bfd_is_thin_archive (abfd) && current->origin > 0)
	    {
	      int len = snprintf (hdr->ar_name + 1, maxname - 1, "%-ld:",
				  stroff);
	      _bfd_ar_spacepad (hdr->ar_name + 1 + len, maxname - 1 - len,
				"%-ld",
				current->origin - sizeof (struct ar_hdr));
	    }
	  else
	    _bfd_ar_spacepad (hdr->ar_name + 1, maxname - 1, "%-ld", stroff);
	}
    }

  return true;
}

/* Do not construct an extended name table but transforms name field into
   its extended form.  */

bool
_bfd_archive_bsd44_construct_extended_name_table (bfd *abfd,
						  char **tabloc,
						  bfd_size_type *tablen,
						  const char **name)
{
  unsigned int maxname = ar_maxnamelen (abfd);
  bfd *current;

  *tablen = 0;
  *tabloc = NULL;
  *name = NULL;

  for (current = abfd->archive_head;
       current != NULL;
       current = current->archive_next)
    {
      const char *normal = normalize (abfd, bfd_get_filename (current));
      int has_space = 0;
      unsigned int len;

      if (normal == NULL)
	return false;

      for (len = 0; normal[len]; len++)
	if (normal[len] == ' ')
	  has_space = 1;

      if (len > maxname || has_space)
	{
	  struct ar_hdr *hdr = arch_hdr (current);

	  len = (len + 3) & ~3;
	  arch_eltdata (current)->extra_size = len;
	  _bfd_ar_spacepad (hdr->ar_name, maxname, "#1/%lu", len);
	}
    }

  return true;
}

/* Write an archive header.  */

bool
_bfd_generic_write_ar_hdr (bfd *archive, bfd *abfd)
{
  struct ar_hdr *hdr = arch_hdr (abfd);

  if (bfd_bwrite (hdr, sizeof (*hdr), archive) != sizeof (*hdr))
    return false;
  return true;
}

/* Write an archive header using BSD4.4 convention.  */

bool
_bfd_bsd44_write_ar_hdr (bfd *archive, bfd *abfd)
{
  struct ar_hdr *hdr = arch_hdr (abfd);

  if (is_bsd44_extended_name (hdr->ar_name))
    {
      /* This is a BSD 4.4 extended name.  */
      const char *fullname = normalize (abfd, bfd_get_filename (abfd));
      unsigned int len = strlen (fullname);
      unsigned int padded_len = (len + 3) & ~3;

      BFD_ASSERT (padded_len == arch_eltdata (abfd)->extra_size);

      if (!_bfd_ar_sizepad (hdr->ar_size, sizeof (hdr->ar_size),
			    arch_eltdata (abfd)->parsed_size + padded_len))
	return false;

      if (bfd_bwrite (hdr, sizeof (*hdr), archive) != sizeof (*hdr))
	return false;

      if (bfd_bwrite (fullname, len, archive) != len)
	return false;

      if (len & 3)
	{
	  static const char pad[3] = { 0, 0, 0 };

	  len = 4 - (len & 3);
	  if (bfd_bwrite (pad, len, archive) != len)
	    return false;
	}
    }
  else
    {
      if (bfd_bwrite (hdr, sizeof (*hdr), archive) != sizeof (*hdr))
	return false;
    }
  return true;
}

bool
_bfd_noarchive_write_ar_hdr (bfd *archive, bfd *abfd ATTRIBUTE_UNUSED)
{
  return _bfd_bool_bfd_false_error (archive);
}

/* A couple of functions for creating ar_hdrs.  */

#ifdef HPUX_LARGE_AR_IDS
/* Function to encode large UID/GID values according to HP.  */

static void
hpux_uid_gid_encode (char str[6], long int id)
{
  int cnt;

  str[5] = '@' + (id & 3);
  id >>= 2;

  for (cnt = 4; cnt >= 0; --cnt, id >>= 6)
    str[cnt] = ' ' + (id & 0x3f);
}
#endif	/* HPUX_LARGE_AR_IDS */

/* Takes a filename, returns an arelt_data for it, or NULL if it can't
   make one.  The filename must refer to a filename in the filesystem.
   The filename field of the ar_hdr will NOT be initialized.  If member
   is set, and it's an in-memory bfd, we fake it.  */

static struct areltdata *
bfd_ar_hdr_from_filesystem (bfd *abfd, const char *filename, bfd *member)
{
  struct stat status;
  struct areltdata *ared;
  struct ar_hdr *hdr;
  size_t amt;

  if (member && (member->flags & BFD_IN_MEMORY) != 0)
    {
      /* Assume we just "made" the member, and fake it.  */
      struct bfd_in_memory *bim = (struct bfd_in_memory *) member->iostream;
      time (&status.st_mtime);
      status.st_uid = getuid ();
      status.st_gid = getgid ();
      status.st_mode = 0644;
      status.st_size = bim->size;
    }
  else if (stat (filename, &status) != 0)
    {
      bfd_set_error (bfd_error_system_call);
      return NULL;
    }

  /* If the caller requested that the BFD generate deterministic output,
     fake values for modification time, UID, GID, and file mode.  */
  if ((abfd->flags & BFD_DETERMINISTIC_OUTPUT) != 0)
    {
      status.st_mtime = 0;
      status.st_uid = 0;
      status.st_gid = 0;
      status.st_mode = 0644;
    }

  amt = sizeof (struct ar_hdr) + sizeof (struct areltdata);
  ared = (struct areltdata *) bfd_zmalloc (amt);
  if (ared == NULL)
    return NULL;
  hdr = (struct ar_hdr *) (((char *) ared) + sizeof (struct areltdata));

  /* ar headers are space padded, not null padded!  */
  memset (hdr, ' ', sizeof (struct ar_hdr));

  _bfd_ar_spacepad (hdr->ar_date, sizeof (hdr->ar_date), "%-12ld",
		    status.st_mtime);
#ifdef HPUX_LARGE_AR_IDS
  /* HP has a very "special" way to handle UID/GID's with numeric values
     > 99999.  */
  if (status.st_uid > 99999)
    hpux_uid_gid_encode (hdr->ar_uid, (long) status.st_uid);
  else
#endif
    _bfd_ar_spacepad (hdr->ar_uid, sizeof (hdr->ar_uid), "%ld",
		      status.st_uid);
#ifdef HPUX_LARGE_AR_IDS
  /* HP has a very "special" way to handle UID/GID's with numeric values
     > 99999.  */
  if (status.st_gid > 99999)
    hpux_uid_gid_encode (hdr->ar_gid, (long) status.st_gid);
  else
#endif
    _bfd_ar_spacepad (hdr->ar_gid, sizeof (hdr->ar_gid), "%ld",
		      status.st_gid);
  _bfd_ar_spacepad (hdr->ar_mode, sizeof (hdr->ar_mode), "%-8lo",
		    status.st_mode);
  if (status.st_size - (bfd_size_type) status.st_size != 0)
    {
      bfd_set_error (bfd_error_file_too_big);
      free (ared);
      return NULL;
    }
  if (!_bfd_ar_sizepad (hdr->ar_size, sizeof (hdr->ar_size), status.st_size))
    {
      free (ared);
      return NULL;
    }
  memcpy (hdr->ar_fmag, ARFMAG, 2);
  ared->parsed_size = status.st_size;
  ared->arch_header = (char *) hdr;

  return ared;
}

/* Analogous to stat call.  */

int
bfd_generic_stat_arch_elt (bfd *abfd, struct stat *buf)
{
  struct ar_hdr *hdr;
  char *aloser;

  if (abfd->arelt_data == NULL)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return -1;
    }

  hdr = arch_hdr (abfd);
  /* PR 17512: file: 3d9e9fe9.  */
  if (hdr == NULL)
    return -1;
#define foo(arelt, stelt, size)				\
  buf->stelt = strtol (hdr->arelt, &aloser, size);	\
  if (aloser == hdr->arelt)				\
    return -1;

  /* Some platforms support special notations for large IDs.  */
#ifdef HPUX_LARGE_AR_IDS
# define foo2(arelt, stelt, size)					\
  if (hdr->arelt[5] == ' ')						\
    {									\
      foo (arelt, stelt, size);						\
    }									\
  else									\
    {									\
      int cnt;								\
      for (buf->stelt = cnt = 0; cnt < 5; ++cnt)			\
	{								\
	  if (hdr->arelt[cnt] < ' ' || hdr->arelt[cnt] > ' ' + 0x3f)	\
	    return -1;							\
	  buf->stelt <<= 6;						\
	  buf->stelt += hdr->arelt[cnt] - ' ';				\
	}								\
      if (hdr->arelt[5] < '@' || hdr->arelt[5] > '@' + 3)		\
	return -1;							\
      buf->stelt <<= 2;							\
      buf->stelt += hdr->arelt[5] - '@';				\
    }
#else
# define foo2(arelt, stelt, size) foo (arelt, stelt, size)
#endif

  foo (ar_date, st_mtime, 10);
  foo2 (ar_uid, st_uid, 10);
  foo2 (ar_gid, st_gid, 10);
  foo (ar_mode, st_mode, 8);

  buf->st_size = arch_eltdata (abfd)->parsed_size;

  return 0;
}

void
bfd_dont_truncate_arname (bfd *abfd, const char *pathname, char *arhdr)
{
  /* FIXME: This interacts unpleasantly with ar's quick-append option.
     Fortunately ic960 users will never use that option.  Fixing this
     is very hard; fortunately I know how to do it and will do so once
     intel's release is out the door.  */

  struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
  size_t length;
  const char *filename;
  size_t maxlen = ar_maxnamelen (abfd);

  if ((bfd_get_file_flags (abfd) & BFD_TRADITIONAL_FORMAT) != 0)
    {
      bfd_bsd_truncate_arname (abfd, pathname, arhdr);
      return;
    }

  filename = normalize (abfd, pathname);
  if (filename == NULL)
    {
      /* FIXME */
      abort ();
    }

  length = strlen (filename);

  if (length <= maxlen)
    memcpy (hdr->ar_name, filename, length);

  /* Add the padding character if there is room for it.  */
  if (length < maxlen
      || (length == maxlen && length < sizeof hdr->ar_name))
    (hdr->ar_name)[length] = ar_padchar (abfd);
}

void
bfd_bsd_truncate_arname (bfd *abfd, const char *pathname, char *arhdr)
{
  struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
  size_t length;
  const char *filename = lbasename (pathname);
  size_t maxlen = ar_maxnamelen (abfd);

  length = strlen (filename);

  if (length <= maxlen)
    memcpy (hdr->ar_name, filename, length);
  else
    {
      /* pathname: meet procrustes */
      memcpy (hdr->ar_name, filename, maxlen);
      length = maxlen;
    }

  if (length < maxlen)
    (hdr->ar_name)[length] = ar_padchar (abfd);
}

/* Store name into ar header.  Truncates the name to fit.
   1> strip pathname to be just the basename.
   2> if it's short enuf to fit, stuff it in.
   3> If it doesn't end with .o, truncate it to fit
   4> truncate it before the .o, append .o, stuff THAT in.  */

/* This is what gnu ar does.  It's better but incompatible with the
   bsd ar.  */

void
bfd_gnu_truncate_arname (bfd *abfd, const char *pathname, char *arhdr)
{
  struct ar_hdr *hdr = (struct ar_hdr *) arhdr;
  size_t length;
  const char *filename = lbasename (pathname);
  size_t maxlen = ar_maxnamelen (abfd);

  length = strlen (filename);

  if (length <= maxlen)
    memcpy (hdr->ar_name, filename, length);
  else
    {
      /* pathname: meet procrustes.  */
      memcpy (hdr->ar_name, filename, maxlen);
      if ((filename[length - 2] == '.') && (filename[length - 1] == 'o'))
	{
	  hdr->ar_name[maxlen - 2] = '.';
	  hdr->ar_name[maxlen - 1] = 'o';
	}
      length = maxlen;
    }

  if (length < 16)
    (hdr->ar_name)[length] = ar_padchar (abfd);
}

void
_bfd_noarchive_truncate_arname (bfd *abfd ATTRIBUTE_UNUSED,
				const char *pathname ATTRIBUTE_UNUSED,
				char *arhdr ATTRIBUTE_UNUSED)
{
}

/* The BFD is open for write and has its format set to bfd_archive.  */

bool
_bfd_write_archive_contents (bfd *arch)
{
  bfd *current;
  char *etable = NULL;
  bfd_size_type elength = 0;
  const char *ename = NULL;
  bool makemap = bfd_has_map (arch);
  /* If no .o's, don't bother to make a map.  */
  bool hasobjects = false;
  bfd_size_type wrote;
  int tries;
  char *armag;

  /* Verify the viability of all entries; if any of them live in the
     filesystem (as opposed to living in an archive open for input)
     then construct a fresh ar_hdr for them.  */
  for (current = arch->archive_head;
       current != NULL;
       current = current->archive_next)
    {
      /* This check is checking the bfds for the objects we're reading
	 from (which are usually either an object file or archive on
	 disk), not the archive entries we're writing to.  We don't
	 actually create bfds for the archive members, we just copy
	 them byte-wise when we write out the archive.  */
      if (bfd_write_p (current))
	{
	  bfd_set_error (bfd_error_invalid_operation);
	  goto input_err;
	}
      if (!current->arelt_data)
	{
	  current->arelt_data =
	    bfd_ar_hdr_from_filesystem (arch, bfd_get_filename (current),
					current);
	  if (!current->arelt_data)
	    goto input_err;

	  /* Put in the file name.  */
	  BFD_SEND (arch, _bfd_truncate_arname,
		    (arch, bfd_get_filename (current),
		     (char *) arch_hdr (current)));
	}

      if (makemap && ! hasobjects)
	{			/* Don't bother if we won't make a map!  */
	  if ((bfd_check_format (current, bfd_object)))
	    hasobjects = true;
	}
    }

  if (!BFD_SEND (arch, _bfd_construct_extended_name_table,
		 (arch, &etable, &elength, &ename)))
    return false;

  if (bfd_seek (arch, (file_ptr) 0, SEEK_SET) != 0)
    return false;
  armag = ARMAG;
  if (bfd_is_thin_archive (arch))
    armag = ARMAGT;
  wrote = bfd_bwrite (armag, SARMAG, arch);
  if (wrote != SARMAG)
    return false;

  if (makemap && hasobjects)
    {
      if (! _bfd_compute_and_write_armap (arch, (unsigned int) elength))
	return false;
    }

  if (elength != 0)
    {
      struct ar_hdr hdr;

      memset (&hdr, ' ', sizeof (struct ar_hdr));
      memcpy (hdr.ar_name, ename, strlen (ename));
      /* Round size up to even number in archive header.  */
      if (!_bfd_ar_sizepad (hdr.ar_size, sizeof (hdr.ar_size),
			    (elength + 1) & ~(bfd_size_type) 1))
	return false;
      memcpy (hdr.ar_fmag, ARFMAG, 2);
      if ((bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch)
	   != sizeof (struct ar_hdr))
	  || bfd_bwrite (etable, elength, arch) != elength)
	return false;
      if ((elength % 2) == 1)
	{
	  if (bfd_bwrite (&ARFMAG[1], 1, arch) != 1)
	    return false;
	}
    }

  for (current = arch->archive_head;
       current != NULL;
       current = current->archive_next)
    {
      char buffer[DEFAULT_BUFFERSIZE];
      bfd_size_type remaining = arelt_size (current);

      /* Write ar header.  */
      if (!_bfd_write_ar_hdr (arch, current))
	return false;
      if (bfd_is_thin_archive (arch))
	continue;
      if (bfd_seek (current, (file_ptr) 0, SEEK_SET) != 0)
	goto input_err;

      while (remaining)
	{
	  size_t amt = DEFAULT_BUFFERSIZE;

	  if (amt > remaining)
	    amt = remaining;
	  errno = 0;
	  if (bfd_bread (buffer, amt, current) != amt)
	    goto input_err;
	  if (bfd_bwrite (buffer, amt, arch) != amt)
	    return false;
	  remaining -= amt;
	}

      if ((arelt_size (current) % 2) == 1)
	{
	  if (bfd_bwrite (&ARFMAG[1], 1, arch) != 1)
	    return false;
	}
    }

  if (makemap && hasobjects)
    {
      /* Verify the timestamp in the archive file.  If it would not be
	 accepted by the linker, rewrite it until it would be.  If
	 anything odd happens, break out and just return.  (The
	 Berkeley linker checks the timestamp and refuses to read the
	 table-of-contents if it is >60 seconds less than the file's
	 modified-time.  That painful hack requires this painful hack.  */
      tries = 1;
      do
	{
	  if (bfd_update_armap_timestamp (arch))
	    break;
	  _bfd_error_handler
	    (_("warning: writing archive was slow: rewriting timestamp"));
	}
      while (++tries < 6);
    }

  return true;

 input_err:
  bfd_set_input_error (current, bfd_get_error ());
  return false;
}

/* Note that the namidx for the first symbol is 0.  */

bool
_bfd_compute_and_write_armap (bfd *arch, unsigned int elength)
{
  char *first_name = NULL;
  bfd *current;
  file_ptr elt_no = 0;
  struct orl *map = NULL;
  unsigned int orl_max = 1024;		/* Fine initial default.  */
  unsigned int orl_count = 0;
  int stridx = 0;
  asymbol **syms = NULL;
  long syms_max = 0;
  bool ret;
  size_t amt;
  static bool report_plugin_err = true;

  /* Dunno if this is the best place for this info...  */
  if (elength != 0)
    elength += sizeof (struct ar_hdr);
  elength += elength % 2;

  amt = orl_max * sizeof (struct orl);
  map = (struct orl *) bfd_malloc (amt);
  if (map == NULL)
    goto error_return;

  /* We put the symbol names on the arch objalloc, and then discard
     them when done.  */
  first_name = (char *) bfd_alloc (arch, 1);
  if (first_name == NULL)
    goto error_return;

  /* Drop all the files called __.SYMDEF, we're going to make our own.  */
  while (arch->archive_head
	 && strcmp (bfd_get_filename (arch->archive_head), "__.SYMDEF") == 0)
    arch->archive_head = arch->archive_head->archive_next;

  /* Map over each element.  */
  for (current = arch->archive_head;
       current != NULL;
       current = current->archive_next, elt_no++)
    {
      if (bfd_check_format (current, bfd_object)
	  && (bfd_get_file_flags (current) & HAS_SYMS) != 0)
	{
	  long storage;
	  long symcount;
	  long src_count;

	  if (current->lto_slim_object && report_plugin_err)
	    {
	      report_plugin_err = false;
	      _bfd_error_handler
		(_("%pB: plugin needed to handle lto object"),
		 current);
	    }

	  storage = bfd_get_symtab_upper_bound (current);
	  if (storage < 0)
	    goto error_return;

	  if (storage != 0)
	    {
	      if (storage > syms_max)
		{
		  free (syms);
		  syms_max = storage;
		  syms = (asymbol **) bfd_malloc (syms_max);
		  if (syms == NULL)
		    goto error_return;
		}
	      symcount = bfd_canonicalize_symtab (current, syms);
	      if (symcount < 0)
		goto error_return;

	      /* Now map over all the symbols, picking out the ones we
		 want.  */
	      for (src_count = 0; src_count < symcount; src_count++)
		{
		  flagword flags = (syms[src_count])->flags;
		  asection *sec = syms[src_count]->section;

		  if (((flags & (BSF_GLOBAL
				 | BSF_WEAK
				 | BSF_INDIRECT
				 | BSF_GNU_UNIQUE)) != 0
		       || bfd_is_com_section (sec))
		      && ! bfd_is_und_section (sec))
		    {
		      bfd_size_type namelen;
		      struct orl *new_map;

		      /* This symbol will go into the archive header.  */
		      if (orl_count == orl_max)
			{
			  orl_max *= 2;
			  amt = orl_max * sizeof (struct orl);
			  new_map = (struct orl *) bfd_realloc (map, amt);
			  if (new_map == NULL)
			    goto error_return;

			  map = new_map;
			}

		      if (syms[src_count]->name[0] == '_'
			  && syms[src_count]->name[1] == '_'
			  && strcmp (syms[src_count]->name
				     + (syms[src_count]->name[2] == '_'),
				     "__gnu_lto_slim") == 0
			  && report_plugin_err)
			{
			  report_plugin_err = false;
			  _bfd_error_handler
			    (_("%pB: plugin needed to handle lto object"),
			     current);
			}
		      namelen = strlen (syms[src_count]->name);
		      amt = sizeof (char *);
		      map[orl_count].name = (char **) bfd_alloc (arch, amt);
		      if (map[orl_count].name == NULL)
			goto error_return;
		      *(map[orl_count].name) = (char *) bfd_alloc (arch,
								   namelen + 1);
		      if (*(map[orl_count].name) == NULL)
			goto error_return;
		      strcpy (*(map[orl_count].name), syms[src_count]->name);
		      map[orl_count].u.abfd = current;
		      map[orl_count].namidx = stridx;

		      stridx += namelen + 1;
		      ++orl_count;
		    }
		}
	    }

	  /* Now ask the BFD to free up any cached information, so we
	     don't fill all of memory with symbol tables.  */
	  if (! bfd_free_cached_info (current))
	    goto error_return;
	}
    }

  /* OK, now we have collected all the data, let's write them out.  */
  ret = BFD_SEND (arch, write_armap,
		  (arch, elength, map, orl_count, stridx));

  free (syms);
  free (map);
  if (first_name != NULL)
    bfd_release (arch, first_name);

  return ret;

 error_return:
  free (syms);
  free (map);
  if (first_name != NULL)
    bfd_release (arch, first_name);

  return false;
}

bool
_bfd_bsd_write_armap (bfd *arch,
		      unsigned int elength,
		      struct orl *map,
		      unsigned int orl_count,
		      int stridx)
{
  int padit = stridx & 1;
  unsigned int ranlibsize = orl_count * BSD_SYMDEF_SIZE;
  unsigned int stringsize = stridx + padit;
  /* Include 8 bytes to store ranlibsize and stringsize in output.  */
  unsigned int mapsize = ranlibsize + stringsize + 8;
  file_ptr firstreal, first;
  bfd *current;
  bfd *last_elt;
  bfd_byte temp[4];
  unsigned int count;
  struct ar_hdr hdr;
  long uid, gid;

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

#ifdef BFD64
  firstreal = first;
  current = arch->archive_head;
  last_elt = current;	/* Last element arch seen.  */
  for (count = 0; count < orl_count; count++)
    {
      unsigned int offset;

      if (map[count].u.abfd != last_elt)
	{
	  do
	    {
	      struct areltdata *ared = arch_eltdata (current);

	      firstreal += (ared->parsed_size + ared->extra_size
			    + sizeof (struct ar_hdr));
	      firstreal += firstreal % 2;
	      current = current->archive_next;
	    }
	  while (current != map[count].u.abfd);
	}

      /* The archive file format only has 4 bytes to store the offset
	 of the member.  Generate 64-bit archive if an archive is past
	 its 4Gb limit.  */
      offset = (unsigned int) firstreal;
      if (firstreal != (file_ptr) offset)
	return _bfd_archive_64_bit_write_armap (arch, elength, map,
						orl_count, stridx);

      last_elt = current;
    }
#endif

  /* If deterministic, we use 0 as the timestamp in the map.
     Some linkers may require that the archive filesystem modification
     time is less than (or near to) the archive map timestamp.  Those
     linkers should not be used with deterministic mode.  (GNU ld and
     Gold do not have this restriction.)  */
  bfd_ardata (arch)->armap_timestamp = 0;
  uid = 0;
  gid = 0;
  if ((arch->flags & BFD_DETERMINISTIC_OUTPUT) == 0)
    {
      struct stat statbuf;

      if (stat (bfd_get_filename (arch), &statbuf) == 0)
	bfd_ardata (arch)->armap_timestamp = (statbuf.st_mtime
					      + ARMAP_TIME_OFFSET);
      uid = getuid();
      gid = getgid();
    }

  memset (&hdr, ' ', sizeof (struct ar_hdr));
  memcpy (hdr.ar_name, RANLIBMAG, strlen (RANLIBMAG));
  bfd_ardata (arch)->armap_datepos = (SARMAG
				      + offsetof (struct ar_hdr, ar_date[0]));
  _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
		    bfd_ardata (arch)->armap_timestamp);
  _bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", uid);
  _bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", gid);
  if (!_bfd_ar_sizepad (hdr.ar_size, sizeof (hdr.ar_size), mapsize))
    return false;
  memcpy (hdr.ar_fmag, ARFMAG, 2);
  if (bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch)
      != sizeof (struct ar_hdr))
    return false;
  H_PUT_32 (arch, ranlibsize, temp);
  if (bfd_bwrite (temp, sizeof (temp), arch) != sizeof (temp))
    return false;

  firstreal = first;
  current = arch->archive_head;
  last_elt = current;	/* Last element arch seen.  */
  for (count = 0; count < orl_count; count++)
    {
      unsigned int offset;
      bfd_byte buf[BSD_SYMDEF_SIZE];

      if (map[count].u.abfd != last_elt)
	{
	  do
	    {
	      struct areltdata *ared = arch_eltdata (current);

	      firstreal += (ared->parsed_size + ared->extra_size
			    + sizeof (struct ar_hdr));
	      firstreal += firstreal % 2;
	      current = current->archive_next;
	    }
	  while (current != map[count].u.abfd);
	}

      /* The archive file format only has 4 bytes to store the offset
	 of the member.  Check to make sure that firstreal has not grown
	 too big.  */
      offset = (unsigned int) firstreal;
      if (firstreal != (file_ptr) offset)
	{
	  bfd_set_error (bfd_error_file_truncated);
	  return false;
	}

      last_elt = current;
      H_PUT_32 (arch, map[count].namidx, buf);
      H_PUT_32 (arch, firstreal, buf + BSD_SYMDEF_OFFSET_SIZE);
      if (bfd_bwrite (buf, BSD_SYMDEF_SIZE, arch)
	  != BSD_SYMDEF_SIZE)
	return false;
    }

  /* Now write the strings themselves.  */
  H_PUT_32 (arch, stringsize, temp);
  if (bfd_bwrite (temp, sizeof (temp), arch) != sizeof (temp))
    return false;
  for (count = 0; count < orl_count; count++)
    {
      size_t len = strlen (*map[count].name) + 1;

      if (bfd_bwrite (*map[count].name, len, arch) != len)
	return false;
    }

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

  return true;
}

/* At the end of archive file handling, update the timestamp in the
   file, so the linker will accept it.

   Return TRUE if the timestamp was OK, or an unusual problem happened.
   Return FALSE if we updated the timestamp.  */

bool
_bfd_archive_bsd_update_armap_timestamp (bfd *arch)
{
  struct stat archstat;
  struct ar_hdr hdr;

  /* If creating deterministic archives, just leave the timestamp as-is.  */
  if ((arch->flags & BFD_DETERMINISTIC_OUTPUT) != 0)
    return true;

  /* Flush writes, get last-write timestamp from file, and compare it
     to the timestamp IN the file.  */
  bfd_flush (arch);
  if (bfd_stat (arch, &archstat) == -1)
    {
      bfd_perror (_("Reading archive file mod timestamp"));

      /* Can't read mod time for some reason.  */
      return true;
    }
  if (((long) archstat.st_mtime) <= bfd_ardata (arch)->armap_timestamp)
    /* OK by the linker's rules.  */
    return true;

  /* Update the timestamp.  */
  bfd_ardata (arch)->armap_timestamp = archstat.st_mtime + ARMAP_TIME_OFFSET;

  /* Prepare an ASCII version suitable for writing.  */
  memset (hdr.ar_date, ' ', sizeof (hdr.ar_date));
  _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
		    bfd_ardata (arch)->armap_timestamp);

  /* Write it into the file.  */
  bfd_ardata (arch)->armap_datepos = (SARMAG
				      + offsetof (struct ar_hdr, ar_date[0]));
  if (bfd_seek (arch, bfd_ardata (arch)->armap_datepos, SEEK_SET) != 0
      || (bfd_bwrite (hdr.ar_date, sizeof (hdr.ar_date), arch)
	  != sizeof (hdr.ar_date)))
    {
      bfd_perror (_("Writing updated armap timestamp"));

      /* Some error while writing.  */
      return true;
    }

  /* We updated the timestamp successfully.  */
  return false;
}

/* A coff armap looks like :
   lARMAG
   struct ar_hdr with name = '/'
   number of symbols
   offset of file for symbol 0
   offset of file for symbol 1

   offset of file for symbol n-1
   symbol name 0
   symbol name 1

   symbol name n-1  */

bool
_bfd_coff_write_armap (bfd *arch,
		       unsigned int elength,
		       struct orl *map,
		       unsigned int symbol_count,
		       int stridx)
{
  /* The size of the ranlib is the number of exported symbols in the
     archive * the number of bytes in an int, + an int for the count.  */
  unsigned int ranlibsize = (symbol_count * 4) + 4;
  unsigned int stringsize = stridx;
  unsigned int mapsize = stringsize + ranlibsize;
  file_ptr archive_member_file_ptr;
  file_ptr first_archive_member_file_ptr;
  bfd *current = arch->archive_head;
  unsigned int count;
  struct ar_hdr hdr;
  int padit = mapsize & 1;

  if (padit)
    mapsize++;

  /* Work out where the first object file will go in the archive.  */
  first_archive_member_file_ptr = (mapsize
				   + elength
				   + sizeof (struct ar_hdr)
				   + SARMAG);

#ifdef BFD64
  current = arch->archive_head;
  count = 0;
  archive_member_file_ptr = first_archive_member_file_ptr;
  while (current != NULL && count < symbol_count)
    {
      /* For each symbol which is used defined in this object, write
	 out the object file's address in the archive.  */

      while (count < symbol_count && map[count].u.abfd == current)
	{
	  unsigned int offset = (unsigned int) archive_member_file_ptr;

	  /* Generate 64-bit archive if an archive is past its 4Gb
	     limit.  */
	  if (archive_member_file_ptr != (file_ptr) offset)
	    return _bfd_archive_64_bit_write_armap (arch, elength, map,
						    symbol_count, stridx);
	  count++;
	}
      archive_member_file_ptr += sizeof (struct ar_hdr);
      if (! bfd_is_thin_archive (arch))
	{
	  /* Add size of this archive entry.  */
	  archive_member_file_ptr += arelt_size (current);
	  /* Remember about the even alignment.  */
	  archive_member_file_ptr += archive_member_file_ptr % 2;
	}
      current = current->archive_next;
    }
#endif

  memset (&hdr, ' ', sizeof (struct ar_hdr));
  hdr.ar_name[0] = '/';
  if (!_bfd_ar_sizepad (hdr.ar_size, sizeof (hdr.ar_size), mapsize))
    return false;
  _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
		    ((arch->flags & BFD_DETERMINISTIC_OUTPUT) == 0
		     ? time (NULL) : 0));
  /* This, at least, is what Intel coff sets the values to.  */
  _bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", 0);
  _bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", 0);
  _bfd_ar_spacepad (hdr.ar_mode, sizeof (hdr.ar_mode), "%-7lo", 0);
  memcpy (hdr.ar_fmag, ARFMAG, 2);

  /* Write the ar header for this item and the number of symbols.  */
  if (bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch)
      != sizeof (struct ar_hdr))
    return false;

  if (!bfd_write_bigendian_4byte_int (arch, symbol_count))
    return false;

  /* Two passes, first write the file offsets for each symbol -
     remembering that each offset is on a two byte boundary.  */

  /* Write out the file offset for the file associated with each
     symbol, and remember to keep the offsets padded out.  */

  current = arch->archive_head;
  count = 0;
  archive_member_file_ptr = first_archive_member_file_ptr;
  while (current != NULL && count < symbol_count)
    {
      /* For each symbol which is used defined in this object, write
	 out the object file's address in the archive.  */

      while (count < symbol_count && map[count].u.abfd == current)
	{
	  unsigned int offset = (unsigned int) archive_member_file_ptr;

	  /* Catch an attempt to grow an archive past its 4Gb limit.  */
	  if (archive_member_file_ptr != (file_ptr) offset)
	    {
	      bfd_set_error (bfd_error_file_truncated);
	      return false;
	    }
	  if (!bfd_write_bigendian_4byte_int (arch, offset))
	    return false;
	  count++;
	}
      archive_member_file_ptr += sizeof (struct ar_hdr);
      if (! bfd_is_thin_archive (arch))
	{
	  /* Add size of this archive entry.  */
	  archive_member_file_ptr += arelt_size (current);
	  /* Remember about the even alignment.  */
	  archive_member_file_ptr += archive_member_file_ptr % 2;
	}
      current = current->archive_next;
    }

  /* Now write the strings themselves.  */
  for (count = 0; count < symbol_count; count++)
    {
      size_t len = strlen (*map[count].name) + 1;

      if (bfd_bwrite (*map[count].name, len, arch) != len)
	return false;
    }

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

  return true;
}

bool
_bfd_noarchive_write_armap
    (bfd *arch ATTRIBUTE_UNUSED,
     unsigned int elength ATTRIBUTE_UNUSED,
     struct orl *map ATTRIBUTE_UNUSED,
     unsigned int orl_count ATTRIBUTE_UNUSED,
     int stridx ATTRIBUTE_UNUSED)
{
  return true;
}

static int
archive_close_worker (void **slot, void *inf ATTRIBUTE_UNUSED)
{
  struct ar_cache *ent = (struct ar_cache *) *slot;

  bfd_close_all_done (ent->arbfd);
  return 1;
}

void
_bfd_unlink_from_archive_parent (bfd *abfd)
{
  if (arch_eltdata (abfd) != NULL)
    {
      struct areltdata *ared = arch_eltdata (abfd);
      htab_t htab = (htab_t) ared->parent_cache;

      if (htab)
	{
	  struct ar_cache ent;
	  void **slot;

	  ent.ptr = ared->key;
	  slot = htab_find_slot (htab, &ent, NO_INSERT);
	  if (slot != NULL)
	    {
	      BFD_ASSERT (((struct ar_cache *) *slot)->arbfd == abfd);
	      htab_clear_slot (htab, slot);
	    }
	}
    }
}

bool
_bfd_archive_close_and_cleanup (bfd *abfd)
{
  if (bfd_read_p (abfd) && abfd->format == bfd_archive)
    {
      bfd *nbfd;
      bfd *next;
      htab_t htab;

      /* Close nested archives (if this bfd is a thin archive).  */
      for (nbfd = abfd->nested_archives; nbfd; nbfd = next)
	{
	  next = nbfd->archive_next;
	  bfd_close (nbfd);
	}

      htab = bfd_ardata (abfd)->cache;
      if (htab)
	{
	  htab_traverse_noresize (htab, archive_close_worker, NULL);
	  htab_delete (htab);
	  bfd_ardata (abfd)->cache = NULL;
	}

      /* Close the archive plugin file descriptor if needed.  */
      if (abfd->archive_plugin_fd > 0)
	close (abfd->archive_plugin_fd);
    }

  _bfd_unlink_from_archive_parent (abfd);

  if (abfd->is_linker_output)
    (*abfd->link.hash->hash_table_free) (abfd);

  return true;
}
