/* Generic BFD support for file formats.
   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.  */


/*
SECTION
	File formats

	A format is a BFD concept of high level file contents type. The
	formats supported by BFD are:

	o <<bfd_object>>

	The BFD may contain data, symbols, relocations and debug info.

	o <<bfd_archive>>

	The BFD contains other BFDs and an optional index.

	o <<bfd_core>>

	The BFD contains the result of an executable core dump.

SUBSECTION
	File format functions
*/

#include "sysdep.h"
#include "bfd.h"
#include "libbfd.h"
#include "plugin.h"

/* IMPORT from targets.c.  */
extern const size_t _bfd_target_vector_entries;

/*
FUNCTION
	bfd_check_format

SYNOPSIS
	bool bfd_check_format (bfd *abfd, bfd_format format);

DESCRIPTION
	Verify if the file attached to the BFD @var{abfd} is compatible
	with the format @var{format} (i.e., one of <<bfd_object>>,
	<<bfd_archive>> or <<bfd_core>>).

	If the BFD has been set to a specific target before the
	call, only the named target and format combination is
	checked. If the target has not been set, or has been set to
	<<default>>, then all the known target backends is
	interrogated to determine a match.  If the default target
	matches, it is used.  If not, exactly one target must recognize
	the file, or an error results.

	The function returns <<TRUE>> on success, otherwise <<FALSE>>
	with one of the following error codes:

	o <<bfd_error_invalid_operation>> -
	if <<format>> is not one of <<bfd_object>>, <<bfd_archive>> or
	<<bfd_core>>.

	o <<bfd_error_system_call>> -
	if an error occured during a read - even some file mismatches
	can cause bfd_error_system_calls.

	o <<file_not_recognised>> -
	none of the backends recognised the file format.

	o <<bfd_error_file_ambiguously_recognized>> -
	more than one backend recognised the file format.

	When calling bfd_check_format (or bfd_check_format_matches),
	any underlying file descriptor will be kept open for the
	duration of the call.  This is done to avoid races when
	another thread calls bfd_cache_close_all.  In this scenario,
	the thread calling bfd_check_format must call bfd_cache_close
	itself.
*/

bool
bfd_check_format (bfd *abfd, bfd_format format)
{
  return bfd_check_format_matches (abfd, format, NULL);
}

struct bfd_preserve
{
  void *marker;
  void *tdata;
  flagword flags;
  const struct bfd_iovec *iovec;
  void *iostream;
  const struct bfd_arch_info *arch_info;
  const struct bfd_build_id *build_id;
  bfd_cleanup cleanup;
  struct bfd_section *sections;
  struct bfd_section *section_last;
  unsigned int section_count;
  unsigned int section_id;
  unsigned int symcount;
  bool read_only;
  bfd_vma start_address;
  struct bfd_hash_table section_htab;
};

/* When testing an object for compatibility with a particular target
   back-end, the back-end object_p function needs to set up certain
   fields in the bfd on successfully recognizing the object.  This
   typically happens in a piecemeal fashion, with failures possible at
   many points.  On failure, the bfd is supposed to be restored to its
   initial state, which is virtually impossible.  However, restoring a
   subset of the bfd state works in practice.  This function stores
   the subset.  */

static bool
bfd_preserve_save (bfd *abfd, struct bfd_preserve *preserve,
		   bfd_cleanup cleanup)
{
  preserve->tdata = abfd->tdata.any;
  preserve->arch_info = abfd->arch_info;
  preserve->flags = abfd->flags;
  preserve->iovec = abfd->iovec;
  preserve->iostream = abfd->iostream;
  preserve->sections = abfd->sections;
  preserve->section_last = abfd->section_last;
  preserve->section_count = abfd->section_count;
  preserve->section_id = _bfd_section_id;
  preserve->symcount = abfd->symcount;
  preserve->read_only = abfd->read_only;
  preserve->start_address = abfd->start_address;
  preserve->section_htab = abfd->section_htab;
  preserve->marker = bfd_alloc (abfd, 1);
  preserve->build_id = abfd->build_id;
  preserve->cleanup = cleanup;
  if (preserve->marker == NULL)
    return false;

  return bfd_hash_table_init (&abfd->section_htab, bfd_section_hash_newfunc,
			      sizeof (struct section_hash_entry));
}

/* A back-end object_p function may flip a bfd from file backed to
   in-memory, eg. pe_ILF_object_p.  In that case to restore the
   original IO state we need to reopen the file.  Conversely, if we
   are restoring a previously matched pe ILF format and have been
   checking further target matches using file IO then we need to close
   the file and detach the bfd from the cache lru list.  */

static void
io_reinit (bfd *abfd, struct bfd_preserve *preserve)
{
  if (abfd->iovec != preserve->iovec)
    {
      /* Handle file backed to in-memory transition.  bfd_cache_close
	 won't do anything unless abfd->iovec is the cache_iovec.
	 Don't be tempted to call iovec->bclose here.  We don't want
	 to call memory_bclose, which would free the bim.  The bim
	 must be kept if bfd_check_format_matches is going to decide
	 later that the PE format needing it is in fact the correct
	 target match.  */
      bfd_cache_close (abfd);
      abfd->iovec = preserve->iovec;
      abfd->iostream = preserve->iostream;

      /* Handle in-memory to file backed transition.  */
      if ((abfd->flags & BFD_CLOSED_BY_CACHE) != 0
	  && (abfd->flags & BFD_IN_MEMORY) != 0
	  && (preserve->flags & BFD_CLOSED_BY_CACHE) == 0
	  && (preserve->flags & BFD_IN_MEMORY) == 0)
	bfd_open_file (abfd);
    }
  abfd->flags = preserve->flags;
}

/* Clear out a subset of BFD state.  */

static void
bfd_reinit (bfd *abfd, unsigned int section_id,
	    struct bfd_preserve *preserve, bfd_cleanup cleanup)
{
  _bfd_section_id = section_id;
  if (cleanup)
    cleanup (abfd);
  abfd->tdata.any = NULL;
  abfd->arch_info = &bfd_default_arch_struct;
  io_reinit (abfd, preserve);
  abfd->symcount = 0;
  abfd->read_only = 0;
  abfd->start_address = 0;
  abfd->build_id = NULL;
  bfd_section_list_clear (abfd);
}

/* Restores bfd state saved by bfd_preserve_save.  */

static bfd_cleanup
bfd_preserve_restore (bfd *abfd, struct bfd_preserve *preserve)
{
  bfd_hash_table_free (&abfd->section_htab);

  abfd->tdata.any = preserve->tdata;
  abfd->arch_info = preserve->arch_info;
  io_reinit (abfd, preserve);
  abfd->section_htab = preserve->section_htab;
  abfd->sections = preserve->sections;
  abfd->section_last = preserve->section_last;
  abfd->section_count = preserve->section_count;
  _bfd_section_id = preserve->section_id;
  abfd->symcount = preserve->symcount;
  abfd->read_only = preserve->read_only;
  abfd->start_address = preserve->start_address;
  abfd->build_id = preserve->build_id;

  /* bfd_release frees all memory more recently bfd_alloc'd than
     its arg, as well as its arg.  */
  bfd_release (abfd, preserve->marker);
  preserve->marker = NULL;
  return preserve->cleanup;
}

/* Called when the bfd state saved by bfd_preserve_save is no longer
   needed.  */

static void
bfd_preserve_finish (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_preserve *preserve)
{
  if (preserve->cleanup)
    {
      /* Run the cleanup, assuming that all it will need is the
	 tdata at the time the cleanup was returned.  */
      void *tdata = abfd->tdata.any;
      abfd->tdata.any = preserve->tdata;
      preserve->cleanup (abfd);
      abfd->tdata.any = tdata;
    }
  /* It would be nice to be able to free more memory here, eg. old
     tdata, but that's not possible since these blocks are sitting
     inside bfd_alloc'd memory.  The section hash is on a separate
     objalloc.  */
  bfd_hash_table_free (&preserve->section_htab);
  preserve->marker = NULL;
}

static void
print_warnmsg (struct per_xvec_message **list)
{
  for (struct per_xvec_message *warn = *list; warn; warn = warn->next)
    _bfd_error_handler ("%s", warn->message);
}

static void
clear_warnmsg (struct per_xvec_message **list)
{
  struct per_xvec_message *warn = *list;
  while (warn)
    {
      struct per_xvec_message *next = warn->next;
      free (warn);
      warn = next;
    }
  *list = NULL;
}

/* Free all the storage in LIST.  Note that the first element of LIST
   is special and is assumed to be stack-allocated.  TARG is used for
   re-issuing warning messages.  If TARG is PER_XVEC_NO_TARGET, then
   it acts like a sort of wildcard -- messages are reissued if all
   targets with messages have identical messages.  One copy of the
   messages are then reissued.  If TARG is anything else, then only
   messages associated with TARG are emitted.  */

static void
print_and_clear_messages (struct per_xvec_messages *list,
			  const bfd_target *targ)
{
  struct per_xvec_messages *iter;

  if (targ == PER_XVEC_NO_TARGET)
    {
      iter = list->next;
      while (iter != NULL)
	{
	  struct per_xvec_message *msg1 = list->messages;
	  struct per_xvec_message *msg2 = iter->messages;
	  do
	    {
	      if (strcmp (msg1->message, msg2->message))
		break;
	      msg1 = msg1->next;
	      msg2 = msg2->next;
	    } while (msg1 && msg2);
	  if (msg1 || msg2)
	    break;
	  iter = iter->next;
	}
      if (iter == NULL)
	targ = list->targ;
    }

  iter = list;
  while (iter != NULL)
    {
      struct per_xvec_messages *next = iter->next;

      if (iter->targ == targ)
	print_warnmsg (&iter->messages);
      clear_warnmsg (&iter->messages);
      if (iter != list)
	free (iter);
      iter = next;
    }

  /* Don't retain a pointer to free'd memory.  */
  list->next = NULL;
}

/* Discard all messages associated with TARG in LIST.  Unlike
   print_and_clear_messages, PER_XVEC_NO_TARGET is not valid for TARG.  */

static void
clear_messages (struct per_xvec_messages *list,
		const bfd_target *targ)
{
  struct per_xvec_messages *iter;

  for (iter = list; iter != NULL; iter = iter->next)
    {
      if (iter->targ == targ)
	clear_warnmsg (&iter->messages);
    }
}

/* This a copy of lto_section defined in GCC (lto-streamer.h).  */

struct lto_section
{
  int16_t major_version;
  int16_t minor_version;
  unsigned char slim_object;

  /* Flags is a private field that is not defined publicly.  */
  uint16_t flags;
};

/* Set lto_type in ABFD.  */

static void
bfd_set_lto_type (bfd *abfd)
{
  if (abfd->format == bfd_object
      && abfd->lto_type == lto_non_object
      && (abfd->flags
	  & (DYNAMIC
	     | (bfd_get_flavour (abfd) == bfd_target_elf_flavour
		? EXEC_P : 0))) == 0)
    {
      asection *sec = abfd->sections;
      enum bfd_lto_object_type type = lto_non_ir_object;
      if (sec == NULL)
	{
	  /* If there are no sections, check for slim LLVM IR object whose
	     first 4 bytes are: 'B', 'C', 0xc0, 0xde.  */
	  bfd_byte llvm_ir_magic[4];
	  if (bfd_seek (abfd, 0, SEEK_SET) == 0
	      && bfd_read (llvm_ir_magic, 4, abfd) == 4
	      && llvm_ir_magic[0] == 'B'
	      && llvm_ir_magic[1] == 'C'
	      && llvm_ir_magic[2] == 0xc0
	      && llvm_ir_magic[3] == 0xde)
	    type = lto_slim_ir_object;
	}
      else
	{
	  struct lto_section lsection = { 0, 0, 0, 0 };
	  /* GCC uses .gnu.lto_.lto.<some_hash> as a LTO bytecode
	     information section.  */
	  for (; sec != NULL; sec = sec->next)
	    if (strcmp (sec->name, GNU_OBJECT_ONLY_SECTION_NAME) == 0)
	      {
		type = lto_mixed_object;
		abfd->object_only_section = sec;
		break;
	      }
	    else if (strcmp (sec->name, ".llvm.lto") == 0)
	      {
		type = lto_fat_ir_object;
		break;
	      }
	    else if (lsection.major_version == 0
		     && startswith (sec->name, ".gnu.lto_.lto.")
		     && bfd_get_section_contents (abfd, sec, &lsection, 0,
						  sizeof (struct lto_section)))
	      {
		if (lsection.slim_object)
		  type = lto_slim_ir_object;
		else
		  type = lto_fat_ir_object;
	  }
	}

      abfd->lto_type = type;
    }
}

/*
FUNCTION
	bfd_check_format_matches

SYNOPSIS
	bool bfd_check_format_matches
	  (bfd *abfd, bfd_format format, char ***matching);

DESCRIPTION
	Like <<bfd_check_format>>, except when it returns FALSE with
	<<bfd_errno>> set to <<bfd_error_file_ambiguously_recognized>>.
	In that case, if @var{matching} is not NULL, it will be filled
	in with a NULL-terminated list of the names of the formats
	that matched, allocated with <<malloc>>.
	Then the user may choose a format and try again.

	When done with the list that @var{matching} points to, the caller
	should free it.
*/

bool
bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching)
{
  extern const bfd_target binary_vec;
  const bfd_target * const *target;
  const bfd_target **matching_vector = NULL;
  const bfd_target *save_targ, *right_targ, *ar_right_targ, *match_targ;
  const bfd_target *fail_targ;
  int match_count, best_count, best_match;
  int ar_match_index;
  unsigned int initial_section_id = _bfd_section_id;
  struct bfd_preserve preserve, preserve_match;
  bfd_cleanup cleanup = NULL;
  struct per_xvec_messages messages = { abfd, PER_XVEC_NO_TARGET, NULL, NULL };
  struct per_xvec_messages *orig_messages;
  bool old_in_format_matches;

  if (matching != NULL)
    *matching = NULL;

  if (!bfd_read_p (abfd)
      || (unsigned int) abfd->format >= (unsigned int) bfd_type_end)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return false;
    }

  if (abfd->format != bfd_unknown)
    return abfd->format == format;

  if (matching != NULL || *bfd_associated_vector != NULL)
    {
      size_t amt;

      amt = sizeof (*matching_vector) * 2 * _bfd_target_vector_entries;
      matching_vector = (const bfd_target **) bfd_malloc (amt);
      if (!matching_vector)
	return false;
    }

  /* Avoid clashes with bfd_cache_close_all running in another
     thread.  */
  if (!bfd_cache_set_uncloseable (abfd, true, &old_in_format_matches))
    {
      free (matching_vector);
      return false;
    }

  /* Locking is required here in order to manage _bfd_section_id.  */
  if (!bfd_lock ())
    {
      bfd_cache_set_uncloseable (abfd, old_in_format_matches, NULL);
      free (matching_vector);
      return false;
    }

  /* Presume the answer is yes.  */
  abfd->format = format;
  save_targ = abfd->xvec;

  /* Don't report errors on recursive calls checking the first element
     of an archive.  */
  orig_messages = _bfd_set_error_handler_caching (&messages);

  preserve_match.marker = NULL;
  if (!bfd_preserve_save (abfd, &preserve, NULL))
    goto err_ret;

  /* First try matching the plugin target if appropriate.  Next try
     the current target.  The current target may have been set due to
     a user option, or due to the linker trying optimistically to load
     input files for the same target as the output.  Either will
     have target_defaulted false.  Failing that, bfd_find_target will
     have chosen a default target, and target_defaulted will be true.  */
  fail_targ = NULL;
  if (bfd_plugin_enabled ()
      && abfd->format == bfd_object
      && abfd->target_defaulted
      && !abfd->is_linker_input
      && abfd->plugin_format != bfd_plugin_no)
    {
      if (bfd_seek (abfd, 0, SEEK_SET) != 0)
	goto err_ret;

      BFD_ASSERT (save_targ != bfd_plugin_vec ());
      abfd->xvec = bfd_plugin_vec ();
      bfd_set_error (bfd_error_no_error);
      cleanup = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
      if (cleanup)
	goto ok_ret;

      bfd_reinit (abfd, initial_section_id, &preserve, cleanup);
      bfd_release (abfd, preserve.marker);
      preserve.marker = bfd_alloc (abfd, 1);
      abfd->xvec = save_targ;
    }

  /* bfd_plugin_no excluding the plugin target is an optimisation.
     The test can be removed if desired.  */
  if (!(abfd->plugin_format == bfd_plugin_no
	&& bfd_plugin_target_p (save_targ)))
    {
      if (bfd_seek (abfd, 0, SEEK_SET) != 0)
	goto err_ret;

      bfd_set_error (bfd_error_no_error);
      cleanup = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
      if (cleanup)
	{
	  if (abfd->format != bfd_archive
	      /* An archive with object files matching the archive
		 target is OK.  Other archives should be further
		 tested.  */
	      || (bfd_has_map (abfd)
		  && bfd_get_error () != bfd_error_wrong_object_format)
	      /* Empty archives can match the current target.
		 Attempting to read the armap will result in a file
		 truncated error.  */
	      || (!bfd_has_map (abfd)
		  && bfd_get_error () == bfd_error_file_truncated))
	    goto ok_ret;
	}
      else
	{
	  if (!abfd->target_defaulted && !abfd->is_linker_input)
	    goto err_unrecog;
	  fail_targ = save_targ;
	}
    }

  /* Check all targets in the hope that one will be recognized.  */
  right_targ = NULL;
  ar_right_targ = NULL;
  match_targ = NULL;
  best_match = 256;
  best_count = 0;
  match_count = 0;
  ar_match_index = _bfd_target_vector_entries;

  for (target = bfd_target_vector; *target != NULL; target++)
    {
      void **high_water;

      /* The binary target matches anything, so don't return it when
	 searching.  Also, don't check the current target twice when
	 it has failed already.
	 Don't match the plugin target during linking if we have
	 another alternative since we want to properly set the input
	 format before allowing a plugin to claim the file.
	 Also as an optimisation don't match the plugin target when
	 abfd->plugin_format is set to bfd_plugin_no.  (This occurs
	 when LTO sections have been stripped or when we have a
	 recursive call here from the plugin object_p via
	 bfd_plugin_get_symbols_in_object_only.)  */
      if (*target == &binary_vec
	  || *target == fail_targ
	  || (((abfd->is_linker_input && match_count != 0)
	       || abfd->plugin_format == bfd_plugin_no)
	      && bfd_plugin_target_p (*target)))
	continue;

      /* If we already tried a match, the bfd is modified and may
	 have sections attached, which will confuse the next
	 _bfd_check_format call.  */
      bfd_reinit (abfd, initial_section_id, &preserve, cleanup);
      /* Free bfd_alloc memory too.  If we have matched and preserved
	 a target then the high water mark is that much higher.  */
      if (preserve_match.marker)
	high_water = &preserve_match.marker;
      else
	high_water = &preserve.marker;
      bfd_release (abfd, *high_water);
      *high_water = bfd_alloc (abfd, 1);

      /* Change BFD's target temporarily.  */
      abfd->xvec = *target;

      /* It is possible that targets appear multiple times in
	 bfd_target_vector.  If this is the case, then we want to avoid
	 accumulating duplicate messages for a target in MESSAGES, so
	 discard any previous messages associated with this target.  */
      clear_messages (&messages, abfd->xvec);

      if (bfd_seek (abfd, 0, SEEK_SET) != 0)
	goto err_ret;

      bfd_set_error (bfd_error_no_error);
      cleanup = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
      if (cleanup)
	{
	  int match_priority = abfd->xvec->match_priority;

	  if (abfd->format != bfd_archive
	      || (bfd_has_map (abfd)
		  && bfd_get_error () != bfd_error_wrong_object_format))
	    {
	      /* If this is the default target, accept it, even if
		 other targets might match.  People who want those
		 other targets have to set the GNUTARGET variable.  */
	      if (abfd->xvec == bfd_default_vector[0])
		goto ok_ret;

	      if (matching_vector)
		matching_vector[match_count] = abfd->xvec;
	      match_count++;

	      if (match_priority < best_match)
		{
		  best_match = match_priority;
		  best_count = 0;
		}
	      if (match_priority <= best_match)
		{
		  /* This format checks out as ok!  */
		  right_targ = abfd->xvec;
		  best_count++;
		}
	    }
	  else
	    {
	      /* An archive with no armap or objects of the wrong
		 type.  We want this target to match if we get no
		 better matches.  */
	      if (ar_right_targ != bfd_default_vector[0])
		ar_right_targ = *target;
	      if (matching_vector)
		matching_vector[ar_match_index] = *target;
	      ar_match_index++;
	    }

	  if (preserve_match.marker == NULL)
	    {
	      match_targ = abfd->xvec;
	      if (!bfd_preserve_save (abfd, &preserve_match, cleanup))
		goto err_ret;
	      cleanup = NULL;
	    }
	}
    }

  if (best_count == 1)
    match_count = 1;

  if (match_count == 0)
    {
      /* Try partial matches.  */
      right_targ = ar_right_targ;

      if (right_targ == bfd_default_vector[0])
	{
	  match_count = 1;
	}
      else
	{
	  match_count = ar_match_index - _bfd_target_vector_entries;

	  if (matching_vector && match_count > 1)
	    memcpy (matching_vector,
		    matching_vector + _bfd_target_vector_entries,
		    sizeof (*matching_vector) * match_count);
	}
    }

  /* We have more than one equally good match.  If any of the best
     matches is a target in config.bfd targ_defvec or targ_selvecs,
     choose it.  */
  if (match_count > 1)
    {
      const bfd_target * const *assoc = bfd_associated_vector;

      while ((right_targ = *assoc++) != NULL)
	{
	  int i = match_count;

	  while (--i >= 0)
	    if (matching_vector[i] == right_targ
		&& right_targ->match_priority <= best_match)
	      break;

	  if (i >= 0)
	    {
	      match_count = 1;
	      break;
	    }
	}
    }

  /* We still have more than one equally good match, and at least some
     of the targets support match priority.  Choose the first of the
     best matches.  */
  if (matching_vector && match_count > 1 && best_count != match_count)
    {
      int i;

      for (i = 0; i < match_count; i++)
	{
	  right_targ = matching_vector[i];
	  if (right_targ->match_priority <= best_match)
	    break;
	}
      match_count = 1;
    }

  /* There is way too much undoing of half-known state here.  We
     really shouldn't iterate on live bfd's.  Note that saving the
     whole bfd and restoring it would be even worse; the first thing
     you notice is that the cached bfd file position gets out of sync.  */
  if (preserve_match.marker != NULL)
    cleanup = bfd_preserve_restore (abfd, &preserve_match);

  if (match_count == 1)
    {
      abfd->xvec = right_targ;
      /* If we come out of the loop knowing that the last target that
	 matched is the one we want, then ABFD should still be in a usable
	 state (except possibly for XVEC).  This is not just an
	 optimisation.  In the case of plugins a match against the
	 plugin target can result in the bfd being changed such that
	 it no longer matches the plugin target, nor will it match
	 RIGHT_TARG again.  */
      if (match_targ != right_targ)
	{
	  bfd_reinit (abfd, initial_section_id, &preserve, cleanup);
	  bfd_release (abfd, preserve.marker);
	  if (bfd_seek (abfd, 0, SEEK_SET) != 0)
	    goto err_ret;
	  cleanup = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
	  BFD_ASSERT (cleanup != NULL);
	}

    ok_ret:
      /* If the file was opened for update, then `output_has_begun'
	 some time ago when the file was created.  Do not recompute
	 sections sizes or alignments in _bfd_set_section_contents.
	 We can not set this flag until after checking the format,
	 because it will interfere with creation of BFD sections.  */
      if (abfd->direction == both_direction)
	abfd->output_has_begun = true;

      free (matching_vector);
      if (preserve_match.marker != NULL)
	bfd_preserve_finish (abfd, &preserve_match);
      bfd_preserve_finish (abfd, &preserve);
      _bfd_restore_error_handler_caching (orig_messages);

      print_and_clear_messages (&messages, abfd->xvec);

      bfd_set_lto_type (abfd);

      /* File position has moved, BTW.  */
      bool ret = bfd_cache_set_uncloseable (abfd, old_in_format_matches, NULL);
      if (!bfd_unlock ())
	return false;
      return ret;
    }

  if (match_count == 0)
    {
    err_unrecog:
      bfd_set_error (bfd_error_file_not_recognized);
    err_ret:
      if (cleanup)
	cleanup (abfd);
      abfd->xvec = save_targ;
      abfd->format = bfd_unknown;
      free (matching_vector);
      goto out;
    }

  /* Restore original target type and format.  */
  abfd->xvec = save_targ;
  abfd->format = bfd_unknown;
  bfd_set_error (bfd_error_file_ambiguously_recognized);

  if (matching)
    {
      *matching = (char **) matching_vector;
      matching_vector[match_count] = NULL;
      /* Return target names.  This is a little nasty.  Maybe we
	 should do another bfd_malloc?  */
      while (--match_count >= 0)
	{
	  const char *name = matching_vector[match_count]->name;
	  *(const char **) &matching_vector[match_count] = name;
	}
    }
  else
    free (matching_vector);
  if (cleanup)
    cleanup (abfd);
 out:
  if (preserve_match.marker != NULL)
    bfd_preserve_finish (abfd, &preserve_match);
  if (preserve.marker != NULL)
    bfd_preserve_restore (abfd, &preserve);
  _bfd_restore_error_handler_caching (orig_messages);
  print_and_clear_messages (&messages, PER_XVEC_NO_TARGET);
  bfd_cache_set_uncloseable (abfd, old_in_format_matches, NULL);
  bfd_unlock ();
  return false;
}

/*
FUNCTION
	bfd_set_format

SYNOPSIS
	bool bfd_set_format (bfd *abfd, bfd_format format);

DESCRIPTION
	This function sets the file format of the BFD @var{abfd} to the
	format @var{format}. If the target set in the BFD does not
	support the format requested, the format is invalid, or the BFD
	is not open for writing, then an error occurs.
*/

bool
bfd_set_format (bfd *abfd, bfd_format format)
{
  if (bfd_read_p (abfd)
      || (unsigned int) abfd->format >= (unsigned int) bfd_type_end)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return false;
    }

  if (abfd->format != bfd_unknown)
    return abfd->format == format;

  /* Presume the answer is yes.  */
  abfd->format = format;

  if (!BFD_SEND_FMT (abfd, _bfd_set_format, (abfd)))
    {
      abfd->format = bfd_unknown;
      return false;
    }

  return true;
}

/*
FUNCTION
	bfd_format_string

SYNOPSIS
	const char *bfd_format_string (bfd_format format);

DESCRIPTION
	Return a pointer to a const string
	<<invalid>>, <<object>>, <<archive>>, <<core>>, or <<unknown>>,
	depending upon the value of @var{format}.
*/

const char *
bfd_format_string (bfd_format format)
{
  if (((int) format < (int) bfd_unknown)
      || ((int) format >= (int) bfd_type_end))
    return "invalid";

  switch (format)
    {
    case bfd_object:
      return "object";		/* Linker/assembler/compiler output.  */
    case bfd_archive:
      return "archive";		/* Object archive file.  */
    case bfd_core:
      return "core";		/* Core dump.  */
    default:
      return "unknown";
    }
}
