/* Generic BFD support for file formats.
   Copyright (C) 1990-2026 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"
#include "elf-bfd.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;
  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;

  matching_vector = bfd_malloc (sizeof (*matching_vector)
				* 2 * _bfd_target_vector_entries);
  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)
	{
	  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;

	      matching_vector[match_count] = abfd->xvec;
	      match_count++;

	      int match_priority = abfd->xvec->match_priority;
	      if (match_priority == 1
		  && bfd_get_flavour (abfd) == bfd_target_elf_flavour)
		{
		  /* If the object e_ident matches the hint elf_osabi,
		     bump priority up.  */
		  Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
		  elf_backend_data *bed = get_elf_backend_data (abfd);
		  if (bed->elf_osabi != ELFOSABI_NONE
		      && i_ehdrp->e_ident[EI_OSABI] == bed->elf_osabi)
		    match_priority = 0;
		}
	      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;
	      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 (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 (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";
    }
}
