/* Generic BFD library interface and support routines.
   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.  */

/*
INODE
typedef bfd, Error reporting, BFD front end, BFD front end

SECTION
	<<typedef bfd>>

	A BFD has type <<bfd>>; objects of this type are the
	cornerstone of any application using BFD. Using BFD
	consists of making references though the BFD and to data in the BFD.

	Here is the structure that defines the type <<bfd>>.  It
	contains the major data about the file and pointers
	to the rest of the data.

EXTERNAL
.typedef enum bfd_format
.  {
.    bfd_unknown = 0,	{* File format is unknown.  *}
.    bfd_object,	{* Linker/assembler/compiler output.  *}
.    bfd_archive,	{* Object archive file.  *}
.    bfd_core,		{* Core dump.  *}
.    bfd_type_end	{* Marks the end; don't use it!  *}
.  }
.bfd_format;
.
.enum bfd_direction
.  {
.    no_direction = 0,
.    read_direction = 1,
.    write_direction = 2,
.    both_direction = 3
.  };
.
.enum bfd_last_io
.  {
.    bfd_io_seek = 0,
.    bfd_io_read = 1,
.    bfd_io_write = 2,
.    bfd_io_force = 3
.  };
.
.enum bfd_plugin_format
.  {
.    bfd_plugin_unknown = 0,
.    bfd_plugin_yes = 1,
.    bfd_plugin_yes_unused = 2,
.    bfd_plugin_no = 3
.  };
.
.struct bfd_build_id
.  {
.    bfd_size_type size;
.    bfd_byte data[1];
.  };
.
.enum bfd_lto_object_type
.  {
.    lto_non_object,		{* Not an LTO object.  *}
.    lto_non_ir_object,		{* An object without LTO IR.  *}
.    lto_slim_ir_object,	{* A slim LTO IR object.  *}
.    lto_fat_ir_object,		{* A fat LTO IR object.  *}
.    lto_mixed_object		{* A mixed LTO IR object.  *}
.  };
.
.struct bfd_mmapped_entry
.  {
.    void *addr;
.    size_t size;
.  };
.
.struct bfd_mmapped
.  {
.    struct bfd_mmapped *next;
.    unsigned int max_entry;
.    unsigned int next_entry;
.    struct bfd_mmapped_entry entries[1];
.  };
.

CODE_FRAGMENT
.struct bfd
.{
.  {* The filename the application opened the BFD with.  *}
.  const char *filename;
.
.  {* A pointer to the target jump table.  *}
.  const struct bfd_target *xvec;
.
.  {* The IOSTREAM, and corresponding IO vector that provide access
.     to the file backing the BFD.  *}
.  void *iostream;
.  const struct bfd_iovec *iovec;
.
.  {* The caching routines use these to maintain a
.     least-recently-used list of BFDs.  *}
.  struct bfd *lru_prev, *lru_next;
.
.  {* Track current file position (or current buffer offset for
.     in-memory BFDs).  When a file is closed by the caching routines,
.     BFD retains state information on the file here.  *}
.  ufile_ptr where;
.
.  {* File modified time, if mtime_set is TRUE.  *}
.  long mtime;
.
.  {* A unique identifier of the BFD  *}
.  unsigned int id;
.
.  {* Format_specific flags.  *}
.  flagword flags;
.
.  {* Values that may appear in the flags field of a BFD.  These also
.     appear in the object_flags field of the bfd_target structure, where
.     they indicate the set of flags used by that backend (not all flags
.     are meaningful for all object file formats) (FIXME: at the moment,
.     the object_flags values have mostly just been copied from backend
.     to another, and are not necessarily correct).  *}
.
.#define BFD_NO_FLAGS                0x0
.
.  {* BFD contains relocation entries.  *}
.#define HAS_RELOC                   0x1
.
.  {* BFD is directly executable.  *}
.#define EXEC_P                      0x2
.
.  {* BFD has line number information (basically used for F_LNNO in a
.     COFF header).  *}
.#define HAS_LINENO                  0x4
.
.  {* BFD has debugging information.  *}
.#define HAS_DEBUG                  0x08
.
.  {* BFD has symbols.  *}
.#define HAS_SYMS                   0x10
.
.  {* BFD has local symbols (basically used for F_LSYMS in a COFF
.     header).  *}
.#define HAS_LOCALS                 0x20
.
.  {* BFD is a dynamic object.  *}
.#define DYNAMIC                    0x40
.
.  {* Text section is write protected (if D_PAGED is not set, this is
.     like an a.out NMAGIC file) (the linker sets this by default, but
.     clears it for -r or -N).  *}
.#define WP_TEXT                    0x80
.
.  {* BFD is dynamically paged (this is like an a.out ZMAGIC file) (the
.     linker sets this by default, but clears it for -r or -n or -N).  *}
.#define D_PAGED                   0x100
.
.  {* BFD is relaxable (this means that bfd_relax_section may be able to
.     do something) (sometimes bfd_relax_section can do something even if
.     this is not set).  *}
.#define BFD_IS_RELAXABLE          0x200
.
.  {* This may be set before writing out a BFD to request using a
.     traditional format.  For example, this is used to request that when
.     writing out an a.out object the symbols not be hashed to eliminate
.     duplicates.  *}
.#define BFD_TRADITIONAL_FORMAT    0x400
.
.  {* This flag indicates that the BFD contents are actually cached
.     in memory.  If this is set, iostream points to a malloc'd
.     bfd_in_memory struct.  *}
.#define BFD_IN_MEMORY             0x800
.
.  {* This BFD has been created by the linker and doesn't correspond
.     to any input file.  *}
.#define BFD_LINKER_CREATED       0x1000
.
.  {* This may be set before writing out a BFD to request that it
.     be written using values for UIDs, GIDs, timestamps, etc. that
.     will be consistent from run to run.  *}
.#define BFD_DETERMINISTIC_OUTPUT 0x2000
.
.  {* Compress sections in this BFD.  *}
.#define BFD_COMPRESS             0x4000
.
.  {* Decompress sections in this BFD.  *}
.#define BFD_DECOMPRESS           0x8000
.
.  {* BFD is a dummy, for plugins.  *}
.#define BFD_PLUGIN              0x10000
.
.  {* Compress sections in this BFD with SHF_COMPRESSED from gABI.  *}
.#define BFD_COMPRESS_GABI       0x20000
.
.  {* Convert ELF common symbol type to STT_COMMON or STT_OBJECT in this
.     BFD.  *}
.#define BFD_CONVERT_ELF_COMMON  0x40000
.
.  {* Use the ELF STT_COMMON type in this BFD.  *}
.#define BFD_USE_ELF_STT_COMMON  0x80000
.
.  {* Put pathnames into archives (non-POSIX).  *}
.#define BFD_ARCHIVE_FULL_PATH  0x100000
.
.#define BFD_CLOSED_BY_CACHE    0x200000

.  {* Compress sections in this BFD with SHF_COMPRESSED zstd.  *}
.#define BFD_COMPRESS_ZSTD      0x400000
.
.  {* Don't generate ELF section header.  *}
.#define BFD_NO_SECTION_HEADER	0x800000
.
.  {* Flags bits which are for BFD use only.  *}
.#define BFD_FLAGS_FOR_BFD_USE_MASK \
.  (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_LINKER_CREATED \
.   | BFD_PLUGIN | BFD_TRADITIONAL_FORMAT | BFD_DETERMINISTIC_OUTPUT \
.   | BFD_COMPRESS_GABI | BFD_CONVERT_ELF_COMMON | BFD_USE_ELF_STT_COMMON \
.   | BFD_NO_SECTION_HEADER)
.
.  {* The format which belongs to the BFD. (object, core, etc.)  *}
.  ENUM_BITFIELD (bfd_format) format : 3;
.
.  {* The direction with which the BFD was opened.  *}
.  ENUM_BITFIELD (bfd_direction) direction : 2;
.
.  {* POSIX.1-2017 (IEEE Std 1003.1) says of fopen : "When a file is
.     opened with update mode ('+' as the second or third character in
.     the mode argument), both input and output may be performed on
.     the associated stream.  However, the application shall ensure
.     that output is not directly followed by input without an
.     intervening call to fflush() or to a file positioning function
.     (fseek(), fsetpos(), or rewind()), and input is not directly
.     followed by output without an intervening call to a file
.     positioning function, unless the input operation encounters
.     end-of-file."
.     This field tracks the last IO operation, so that bfd can insert
.     a seek when IO direction changes.  *}
.  ENUM_BITFIELD (bfd_last_io) last_io : 2;
.
.  {* Is the file descriptor being cached?  That is, can it be closed as
.     needed, and re-opened when accessed later?  *}
.  unsigned int cacheable : 1;
.
.  {* Marks whether there was a default target specified when the
.     BFD was opened. This is used to select which matching algorithm
.     to use to choose the back end.  *}
.  unsigned int target_defaulted : 1;
.
.  {* ... and here: (``once'' means at least once).  *}
.  unsigned int opened_once : 1;
.
.  {* Set if we have a locally maintained mtime value, rather than
.     getting it from the file each time.  *}
.  unsigned int mtime_set : 1;
.
.  {* Flag set if symbols from this BFD should not be exported.  *}
.  unsigned int no_export : 1;
.
.  {* Remember when output has begun, to stop strange things
.     from happening.  *}
.  unsigned int output_has_begun : 1;
.
.  {* Have archive map.  *}
.  unsigned int has_armap : 1;
.
.  {* Set if this is a thin archive.  *}
.  unsigned int is_thin_archive : 1;
.
.  {* Set if this archive should not cache element positions.  *}
.  unsigned int no_element_cache : 1;
.
.  {* Set if only required symbols should be added in the link hash table for
.     this object.  Used by VMS linkers.  *}
.  unsigned int selective_search : 1;
.
.  {* Set if this is the linker output BFD.  *}
.  unsigned int is_linker_output : 1;
.
.  {* Set if this is the linker input BFD.  *}
.  unsigned int is_linker_input : 1;
.
.  {* If this is an input for a compiler plug-in library.  *}
.  ENUM_BITFIELD (bfd_plugin_format) plugin_format : 2;
.
.  {* Set if this is a plugin output file.  *}
.  unsigned int lto_output : 1;
.
.  {* Do not attempt to modify this file.  Set when detecting errors
.     that BFD is not prepared to handle for objcopy/strip.  *}
.  unsigned int read_only : 1;
.
.  {* LTO object type.  *}
.  ENUM_BITFIELD (bfd_lto_object_type) lto_type : 3;
.
.  {* Set if this BFD is currently being processed by
.     bfd_check_format_matches.  This is checked by the cache to
.     avoid closing the BFD in this case.  This should only be
.     examined or modified while the BFD lock is held.  *}
.  unsigned int in_format_matches : 1;
.
.  {* Set to dummy BFD created when claimed by a compiler plug-in
.     library.  *}
.  bfd *plugin_dummy_bfd;
.
.  {* The offset of this bfd in the file, typically 0 if it is not
.     contained in an archive.  *}
.  ufile_ptr origin;
.
.  {* The origin in the archive of the proxy entry.  This will
.     normally be the same as origin, except for thin archives,
.     when it will contain the current offset of the proxy in the
.     thin archive rather than the offset of the bfd in its actual
.     container.  *}
.  ufile_ptr proxy_origin;
.
.  {* A hash table for section names.  *}
.  struct bfd_hash_table section_htab;
.
.  {* Pointer to linked list of sections.  *}
.  struct bfd_section *sections;
.
.  {* The last section on the section list.  *}
.  struct bfd_section *section_last;
.
.  {* The object-only section on the section list.  *}
.  struct bfd_section *object_only_section;
.
.  {* The number of sections.  *}
.  unsigned int section_count;
.
.  {* The archive plugin file descriptor.  *}
.  int archive_plugin_fd;
.
.  {* The number of opens on the archive plugin file descriptor.  *}
.  unsigned int archive_plugin_fd_open_count;
.
.  {* A field used by _bfd_generic_link_add_archive_symbols.  This will
.     be used only for archive elements.  *}
.  int archive_pass;
.
.  {* The total size of memory from bfd_alloc.  *}
.  bfd_size_type alloc_size;
.
.  {* Stuff only useful for object files:
.     The start address.  *}
.  bfd_vma start_address;
.
.  {* Symbol table for output BFD (with symcount entries).
.     Also used by the linker to cache input BFD symbols.  *}
.  struct bfd_symbol **outsymbols;
.
.  {* Used for input and output.  *}
.  unsigned int symcount;
.
.  {* Used for slurped dynamic symbol tables.  *}
.  unsigned int dynsymcount;
.
.  {* Pointer to structure which contains architecture information.  *}
.  const struct bfd_arch_info *arch_info;
.
.  {* Cached length of file for bfd_get_size.  0 until bfd_get_size is
.     called, 1 if stat returns an error or the file size is too large to
.     return in ufile_ptr.  Both 0 and 1 should be treated as "unknown".  *}
.  ufile_ptr size;
.
.  {* Stuff only useful for archives.  *}
.  void *arelt_data;
.  struct bfd *my_archive;      {* The containing archive BFD.  *}
.  struct bfd *archive_next;    {* The next BFD in the archive.  *}
.  struct bfd *archive_head;    {* The first BFD in the archive.  *}
.  struct bfd *nested_archives; {* List of nested archive in a flattened
.				   thin archive.  *}
.
.  union {
.    {* For input BFDs, a chain of BFDs involved in a link.  *}
.    struct bfd *next;
.    {* For output BFD, the linker hash table.  *}
.    struct bfd_link_hash_table *hash;
.  } link;
.
.  {* Used by the back end to hold private data.  *}
.  union
.    {
.      struct aout_data_struct *aout_data;
.      struct artdata *aout_ar_data;
.      struct coff_tdata *coff_obj_data;
.      struct pe_tdata *pe_obj_data;
.      struct xcoff_tdata *xcoff_obj_data;
.      struct ecoff_tdata *ecoff_obj_data;
.      struct srec_data_struct *srec_data;
.      struct verilog_data_struct *verilog_data;
.      struct ihex_data_struct *ihex_data;
.      struct tekhex_data_struct *tekhex_data;
.      struct elf_obj_tdata *elf_obj_data;
.      struct mmo_data_struct *mmo_data;
.      struct trad_core_struct *trad_core_data;
.      struct som_data_struct *som_data;
.      struct hpux_core_struct *hpux_core_data;
.      struct hppabsd_core_struct *hppabsd_core_data;
.      struct sgi_core_struct *sgi_core_data;
.      struct lynx_core_struct *lynx_core_data;
.      struct osf_core_struct *osf_core_data;
.      struct cisco_core_struct *cisco_core_data;
.      struct netbsd_core_struct *netbsd_core_data;
.      struct mach_o_data_struct *mach_o_data;
.      struct mach_o_fat_data_struct *mach_o_fat_data;
.      struct plugin_data_struct *plugin_data;
.      struct bfd_pef_data_struct *pef_data;
.      struct bfd_pef_xlib_data_struct *pef_xlib_data;
.      struct bfd_sym_data_struct *sym_data;
.      void *any;
.    }
.  tdata;
.
.  {* Used by the application to hold private data.  *}
.  void *usrdata;
.
.  {* Where all the allocated stuff under this BFD goes.  This is a
.     struct objalloc *, but we use void * to avoid requiring the inclusion
.     of objalloc.h.  *}
.  void *memory;
.
.  {* For input BFDs, the build ID, if the object has one. *}
.  const struct bfd_build_id *build_id;
.
.  {* For input BFDs, mmapped entries. *}
.  struct bfd_mmapped *mmapped;
.};
.

EXTERNAL
.static inline const char *
.bfd_get_filename (const bfd *abfd)
.{
.  return abfd->filename;
.}
.
.static inline bool
.bfd_get_cacheable (const bfd *abfd)
.{
.  return abfd->cacheable;
.}
.
.static inline enum bfd_format
.bfd_get_format (const bfd *abfd)
.{
.  return abfd->format;
.}
.
.static inline enum bfd_lto_object_type
.bfd_get_lto_type (const bfd *abfd)
.{
.  return abfd->lto_type;
.}
.
.static inline bool
.bfd_lto_slim_symbol_p (const bfd *abfd, const char *name)
.{
.  return (bfd_get_lto_type (abfd) != lto_non_ir_object
.	   && name != NULL
.	   && name[0] == '_'
.	   && name[1] == '_'
.	   && strcmp (name + (name[2] == '_'), "__gnu_lto_slim") == 0);
.}
.
.static inline flagword
.bfd_get_file_flags (const bfd *abfd)
.{
.  return abfd->flags;
.}
.
.static inline bfd_vma
.bfd_get_start_address (const bfd *abfd)
.{
.  return abfd->start_address;
.}
.
.static inline unsigned int
.bfd_get_symcount (const bfd *abfd)
.{
.  return abfd->symcount;
.}
.
.static inline unsigned int
.bfd_get_dynamic_symcount (const bfd *abfd)
.{
.  return abfd->dynsymcount;
.}
.
.static inline struct bfd_symbol **
.bfd_get_outsymbols (const bfd *abfd)
.{
.  return abfd->outsymbols;
.}
.
.static inline unsigned int
.bfd_count_sections (const bfd *abfd)
.{
.  return abfd->section_count;
.}
.
.static inline bool
.bfd_has_map (const bfd *abfd)
.{
.  return abfd->has_armap;
.}
.
.static inline bool
.bfd_is_thin_archive (const bfd *abfd)
.{
.  return abfd->is_thin_archive;
.}
.
.static inline void *
.bfd_usrdata (const bfd *abfd)
.{
.  return abfd->usrdata;
.}
.
.{* See note beside bfd_set_section_userdata.  *}
.static inline bool
.bfd_set_cacheable (bfd * abfd, bool val)
.{
.  abfd->cacheable = val;
.  return true;
.}
.
.static inline void
.bfd_set_thin_archive (bfd *abfd, bool val)
.{
.  abfd->is_thin_archive = val;
.}
.
.static inline void
.bfd_set_usrdata (bfd *abfd, void *val)
.{
.  abfd->usrdata = val;
.}
.
.static inline asection *
.bfd_asymbol_section (const asymbol *sy)
.{
.  return sy->section;
.}
.
.static inline bfd_vma
.bfd_asymbol_value (const asymbol *sy)
.{
.  return sy->section->vma + sy->value;
.}
.
.static inline const char *
.bfd_asymbol_name (const asymbol *sy)
.{
.  return sy->name;
.}
.
.static inline struct bfd *
.bfd_asymbol_bfd (const asymbol *sy)
.{
.  return sy->the_bfd;
.}
.
.static inline void
.bfd_set_asymbol_name (asymbol *sy, const char *name)
.{
.  sy->name = name;
.}
.
.{* For input sections return the original size on disk of the
.   section.  For output sections return the current size.  *}
.static inline bfd_size_type
.bfd_get_section_limit_octets (const bfd *abfd, const asection *sec)
.{
.  if (abfd->direction != write_direction && sec->rawsize != 0)
.    return sec->rawsize;
.  return sec->size;
.}
.
.{* Find the address one past the end of SEC.  *}
.static inline bfd_size_type
.bfd_get_section_limit (const bfd *abfd, const asection *sec)
.{
.  return (bfd_get_section_limit_octets (abfd, sec)
.	   / bfd_octets_per_byte (abfd, sec));
.}
.
.{* For input sections return the larger of the current size and the
.   original size on disk of the section.  For output sections return
.   the current size.  *}
.static inline bfd_size_type
.bfd_get_section_alloc_size (const bfd *abfd, const asection *sec)
.{
.  if (abfd->direction != write_direction && sec->rawsize > sec->size)
.    return sec->rawsize;
.  return sec->size;
.}
.
.{* Functions to handle insertion and deletion of a bfd's sections.  These
.   only handle the list pointers, ie. do not adjust section_count,
.   target_index etc.  *}
.static inline void
.bfd_section_list_remove (bfd *abfd, asection *s)
.{
.  asection *next = s->next;
.  asection *prev = s->prev;
.  if (prev)
.    prev->next = next;
.  else
.    abfd->sections = next;
.  if (next)
.    next->prev = prev;
.  else
.    abfd->section_last = prev;
.}
.
.static inline void
.bfd_section_list_append (bfd *abfd, asection *s)
.{
.  s->next = 0;
.  if (abfd->section_last)
.    {
.      s->prev = abfd->section_last;
.      abfd->section_last->next = s;
.    }
.  else
.    {
.      s->prev = 0;
.      abfd->sections = s;
.    }
.  abfd->section_last = s;
.}
.
.static inline void
.bfd_section_list_prepend (bfd *abfd, asection *s)
.{
.  s->prev = 0;
.  if (abfd->sections)
.    {
.      s->next = abfd->sections;
.      abfd->sections->prev = s;
.    }
.  else
.    {
.      s->next = 0;
.      abfd->section_last = s;
.    }
.  abfd->sections = s;
.}
.
.static inline void
.bfd_section_list_insert_after (bfd *abfd, asection *a, asection *s)
.{
.  asection *next = a->next;
.  s->next = next;
.  s->prev = a;
.  a->next = s;
.  if (next)
.    next->prev = s;
.  else
.    abfd->section_last = s;
.}
.
.static inline void
.bfd_section_list_insert_before (bfd *abfd, asection *b, asection *s)
.{
.  asection *prev = b->prev;
.  s->prev = prev;
.  s->next = b;
.  b->prev = s;
.  if (prev)
.    prev->next = s;
.  else
.    abfd->sections = s;
.}
.
.static inline bool
.bfd_section_removed_from_list (const bfd *abfd, const asection *s)
.{
.  return s->next ? s->next->prev != s : abfd->section_last != s;
.}
.
*/

#include "sysdep.h"
#include <stdarg.h>
#include "bfd.h"
#include "bfdver.h"
#include "libiberty.h"
#include "demangle.h"
#include "safe-ctype.h"
#include "bfdlink.h"
#include "libbfd.h"
#include "coff/internal.h"
#include "coff/sym.h"
#include "libcoff.h"
#include "libecoff.h"
#undef obj_symbols
#include "elf-bfd.h"

#ifndef EXIT_FAILURE
#define EXIT_FAILURE 1
#endif

#ifdef TLS
#define THREAD_LOCAL TLS
#else
#define THREAD_LOCAL
#endif


/* provide storage for subsystem, stack and heap data which may have been
   passed in on the command line.  Ld puts this data into a bfd_link_info
   struct which ultimately gets passed in to the bfd.  When it arrives, copy
   it to the following struct so that the data will be available in coffcode.h
   where it is needed.  The typedef's used are defined in bfd.h */

/*
INODE
Error reporting, Initialization, typedef bfd, BFD front end

SECTION
	Error reporting

	Most BFD functions return nonzero on success (check their
	individual documentation for precise semantics).  On an error,
	they call <<bfd_set_error>> to set an error condition that callers
	can check by calling <<bfd_get_error>>.
	If that returns <<bfd_error_system_call>>, then check
	<<errno>>.

	The easiest way to report a BFD error to the user is to
	use <<bfd_perror>>.

	The BFD error is thread-local.

SUBSECTION
	Type <<bfd_error_type>>

	The values returned by <<bfd_get_error>> are defined by the
	enumerated type <<bfd_error_type>>.

CODE_FRAGMENT
.typedef enum bfd_error
.{
.  bfd_error_no_error = 0,
.  bfd_error_system_call,
.  bfd_error_invalid_target,
.  bfd_error_wrong_format,
.  bfd_error_wrong_object_format,
.  bfd_error_invalid_operation,
.  bfd_error_no_memory,
.  bfd_error_no_symbols,
.  bfd_error_no_armap,
.  bfd_error_no_more_archived_files,
.  bfd_error_malformed_archive,
.  bfd_error_missing_dso,
.  bfd_error_file_not_recognized,
.  bfd_error_file_ambiguously_recognized,
.  bfd_error_no_contents,
.  bfd_error_nonrepresentable_section,
.  bfd_error_no_debug_section,
.  bfd_error_bad_value,
.  bfd_error_file_truncated,
.  bfd_error_file_too_big,
.  bfd_error_sorry,
.  bfd_error_on_input,
.  bfd_error_invalid_error_code
.}
.bfd_error_type;
.
*/

const char *const bfd_errmsgs[] =
{
  N_("no error"),
  N_("system call error"),
  N_("invalid bfd target"),
  N_("file in wrong format"),
  N_("archive object file in wrong format"),
  N_("invalid operation"),
  N_("memory exhausted"),
  N_("no symbols"),
  N_("archive has no index; run ranlib to add one"),
  N_("no more archived files"),
  N_("malformed archive"),
  N_("DSO missing from command line"),
  N_("file format not recognized"),
  N_("file format is ambiguous"),
  N_("section has no contents"),
  N_("nonrepresentable section on output"),
  N_("symbol needs debug section which does not exist"),
  N_("bad value"),
  N_("file truncated"),
  N_("file too big"),
  N_("sorry, cannot handle this file"),
  N_("error reading %s: %s"),
  N_("#<invalid error code>")
};

static THREAD_LOCAL bfd_error_type bfd_error;
static THREAD_LOCAL char *_bfd_error_buf;

/* Free any data associated with the BFD error.  */

static void
_bfd_clear_error_data (void)
{
  bfd_error = bfd_error_no_error;
  free (_bfd_error_buf);
  _bfd_error_buf = NULL;
}

/*
FUNCTION
	bfd_get_error

SYNOPSIS
	bfd_error_type bfd_get_error (void);

DESCRIPTION
	Return the current BFD error condition.
*/

bfd_error_type
bfd_get_error (void)
{
  return bfd_error;
}

/*
FUNCTION
	bfd_set_error

SYNOPSIS
	void bfd_set_error (bfd_error_type error_tag);

DESCRIPTION
	Set the BFD error condition to be @var{error_tag}.

	@var{error_tag} must not be bfd_error_on_input.  Use
	bfd_set_input_error for input errors instead.
*/

void
bfd_set_error (bfd_error_type error_tag)
{
  bfd_error = error_tag;
  if (bfd_error >= bfd_error_on_input)
    abort ();
}

/*
FUNCTION
	bfd_set_input_error

SYNOPSIS
	void bfd_set_input_error (bfd *input, bfd_error_type error_tag);

DESCRIPTION

	Set the BFD error condition to be bfd_error_on_input.
	@var{input} is the input bfd where the error occurred, and
	@var{error_tag} the bfd_error_type error.
*/

void
bfd_set_input_error (bfd *input, bfd_error_type error_tag)
{
  /* This is an error that occurred during bfd_close when writing an
     archive, but on one of the input files.  */
  _bfd_clear_error_data ();
  if (error_tag >= bfd_error_on_input)
    abort ();
  if (bfd_asprintf (_(bfd_errmsgs[bfd_error_on_input]),
		    bfd_get_filename (input), bfd_errmsg (error_tag)))
    bfd_error = bfd_error_on_input;
}

/*
FUNCTION
	bfd_errmsg

SYNOPSIS
	const char *bfd_errmsg (bfd_error_type error_tag);

DESCRIPTION
	Return a string describing the error @var{error_tag}, or
	the system error if @var{error_tag} is <<bfd_error_system_call>>.
*/

const char *
bfd_errmsg (bfd_error_type error_tag)
{
#ifndef errno
  extern int errno;
#endif
  if (error_tag == bfd_error_on_input)
    return _bfd_error_buf;

  if (error_tag == bfd_error_system_call)
    return xstrerror (errno);

  if (error_tag > bfd_error_invalid_error_code)
    error_tag = bfd_error_invalid_error_code;	/* sanity check */

  return _(bfd_errmsgs[error_tag]);
}

/*
FUNCTION
	bfd_perror

SYNOPSIS
	void bfd_perror (const char *message);

DESCRIPTION
	Print to the standard error stream a string describing the
	last BFD error that occurred, or the last system error if
	the last BFD error was a system call failure.  If @var{message}
	is non-NULL and non-empty, the error string printed is preceded
	by @var{message}, a colon, and a space.  It is followed by a newline.
*/

void
bfd_perror (const char *message)
{
  fflush (stdout);
  if (message == NULL || *message == '\0')
    fprintf (stderr, "%s\n", bfd_errmsg (bfd_get_error ()));
  else
    fprintf (stderr, "%s: %s\n", message, bfd_errmsg (bfd_get_error ()));
  fflush (stderr);
}

/*
INTERNAL_FUNCTION
	bfd_asprintf

SYNOPSIS
	char *bfd_asprintf (const char *fmt, ...);

DESCRIPTION
	Primarily for error reporting, this function is like
	libiberty's xasprintf except that it can return NULL on no
	memory and the returned string should not be freed.  Uses a
	thread-local malloc'd buffer managed by libbfd, _bfd_error_buf.
	Be aware that a call to this function frees the result of any
	previous call.  bfd_errmsg (bfd_error_on_input) also calls
	this function.
*/

char *
bfd_asprintf (const char *fmt, ...)
{
  free (_bfd_error_buf);
  _bfd_error_buf = NULL;
  va_list ap;
  va_start (ap, fmt);
  int count = vasprintf (&_bfd_error_buf, fmt, ap);
  va_end (ap);
  if (count == -1)
    {
      bfd_set_error (bfd_error_no_memory);
      _bfd_error_buf = NULL;
    }
  return _bfd_error_buf;
}

/*
SUBSECTION
	BFD error handler

	Some BFD functions want to print messages describing the
	problem.  They call a BFD error handler function.  This
	function may be overridden by the program.

	The BFD error handler acts like vprintf.

CODE_FRAGMENT
.typedef void (*bfd_error_handler_type) (const char *, va_list);
.
*/

/* The program name used when printing BFD error messages.  */

static const char *_bfd_error_program_name;

/* Support for positional parameters.  */

union _bfd_doprnt_args
{
  int i;
  long l;
  long long ll;
  double d;
  long double ld;
  void *p;
  enum
  {
    Bad,
    Int,
    Long,
    LongLong,
    Double,
    LongDouble,
    Ptr
  } type;
};

/* Maximum number of _bfd_error_handler args.  Don't increase this
   without changing the code handling positional parameters.  */
#define MAX_ARGS 9

/* This macro and _bfd_doprnt taken from libiberty _doprnt.c, tidied a
   little and extended to handle '%pA', '%pB' and positional parameters.  */

#define PRINT_TYPE(TYPE, FIELD) \
  do								\
    {								\
      TYPE value = (TYPE) args[arg_no].FIELD;			\
      result = print (stream, specifier, value);		\
    } while (0)

/*
CODE_FRAGMENT
.typedef int (*bfd_print_callback) (void *, const char *, ...);
*/

static int
_bfd_doprnt (bfd_print_callback print, void *stream, const char *format,
	     union _bfd_doprnt_args *args)
{
  const char *ptr = format;
  char specifier[128];
  int total_printed = 0;
  unsigned int arg_count = 0;

  while (*ptr != '\0')
    {
      int result;

      if (*ptr != '%')
	{
	  /* While we have regular characters, print them.  */
	  char *end = strchr (ptr, '%');
	  if (end != NULL)
	    result = print (stream, "%.*s", (int) (end - ptr), ptr);
	  else
	    result = print (stream, "%s", ptr);
	  ptr += result;
	}
      else if (ptr[1] == '%')
	{
	  print (stream, "%%");
	  result = 1;
	  ptr += 2;
	}
      else
	{
	  /* We have a format specifier!  */
	  char *sptr = specifier;
	  int wide_width = 0, short_width = 0;
	  unsigned int arg_no;

	  /* Copy the % and move forward.  */
	  *sptr++ = *ptr++;

	  /* Check for a positional parameter.  */
	  arg_no = -1u;
	  if (*ptr != '0' && ISDIGIT (*ptr) && ptr[1] == '$')
	    {
	      arg_no = *ptr - '1';
	      ptr += 2;
	    }

	  /* There is a clash between Microsoft's non-standard I64
	     and I32 integer length modifiers and glibc's
	     non-standard I flag.  */
	  const char *printf_flag_chars
	    = sizeof PRId64 == sizeof "I64d" ? "-+ #0'" : "-+ #0'I";

	  /* Move past flags.  */
	  while (strchr (printf_flag_chars, *ptr))
	    *sptr++ = *ptr++;

	  if (*ptr == '*')
	    {
	      int value;
	      unsigned int arg_index;

	      ptr++;
	      arg_index = arg_count;
	      if (*ptr != '0' && ISDIGIT (*ptr) && ptr[1] == '$')
		{
		  arg_index = *ptr - '1';
		  ptr += 2;
		}
	      value = abs (args[arg_index].i);
	      arg_count++;
	      sptr += sprintf (sptr, "%d", value);
	    }
	  else
	    /* Handle explicit numeric value.  */
	    while (ISDIGIT (*ptr))
	      *sptr++ = *ptr++;

	  /* Precision.  */
	  if (*ptr == '.')
	    {
	      /* Copy and go past the period.  */
	      *sptr++ = *ptr++;
	      if (*ptr == '*')
		{
		  int value;
		  unsigned int arg_index;

		  ptr++;
		  arg_index = arg_count;
		  if (*ptr != '0' && ISDIGIT (*ptr) && ptr[1] == '$')
		    {
		      arg_index = *ptr - '1';
		      ptr += 2;
		    }
		  value = abs (args[arg_index].i);
		  arg_count++;
		  sptr += sprintf (sptr, "%d", value);
		}
	      else
		/* Handle explicit numeric value.  */
		while (ISDIGIT (*ptr))
		  *sptr++ = *ptr++;
	    }
	  if (sizeof PRId64 == sizeof "I64d" && *ptr =='I')
	    {
	      if (ptr[1] == '6' && ptr[2] == '4')
		{
		  wide_width = 3;
		  *sptr++ = *ptr++;
		  *sptr++ = *ptr++;
		  *sptr++ = *ptr++;
		}
	      else if (ptr[1] == '3' && ptr[2] == '2')
		{
		  *sptr++ = *ptr++;
		  *sptr++ = *ptr++;
		  *sptr++ = *ptr++;
		}
	    }
	  while (strchr ("hlL", *ptr))
	    {
	      switch (*ptr)
		{
		case 'h':
		  short_width = 1;
		  break;
		case 'l':
		  wide_width++;
		  break;
		case 'L':
		  wide_width = 2;
		  break;
		default:
		  abort();
		}
	      *sptr++ = *ptr++;
	    }

	  /* Copy the type specifier, and NULL terminate.  */
	  *sptr++ = *ptr++;
	  *sptr = '\0';
	  if ((int) arg_no < 0)
	    arg_no = arg_count;

	  switch (ptr[-1])
	    {
	    case 'd':
	    case 'i':
	    case 'o':
	    case 'u':
	    case 'x':
	    case 'X':
	    case 'c':
	      {
		/* Short values are promoted to int, so just copy it
		   as an int and trust the C library printf to cast it
		   to the right width.  */
		if (short_width)
		  PRINT_TYPE (int, i);
		else
		  {
		    switch (wide_width)
		      {
		      case 0:
			PRINT_TYPE (int, i);
			break;
		      case 1:
			PRINT_TYPE (long, l);
			break;
		      case 2:
			if (sizeof PRId64 == sizeof "I64d")
			  {
			    /* Convert any %ll to %I64.  */
			    sptr[-3] = 'I';
			    sptr[-2] = '6';
			    sptr[-1] = '4';
			    *sptr++ = ptr[-1];
			    *sptr = '\0';
			  }
			/* Fall through.  */
		      default:
			PRINT_TYPE (long long, ll);
			break;
		      }
		  }
	      }
	      break;
	    case 'f':
	    case 'e':
	    case 'E':
	    case 'g':
	    case 'G':
	      {
		if (wide_width == 0)
		  PRINT_TYPE (double, d);
		else
		  PRINT_TYPE (long double, ld);
	      }
	      break;
	    case 's':
	      PRINT_TYPE (char *, p);
	      break;
	    case 'p':
	      if (*ptr == 'A')
		{
		  asection *sec;
		  bfd *abfd;
		  const char *group = NULL;
		  struct coff_comdat_info *ci;

		  ptr++;
		  sec = (asection *) args[arg_no].p;
		  if (sec == NULL)
		    /* Invoking %pA with a null section pointer is an
		       internal error.  */
		    abort ();
		  abfd = sec->owner;
		  if (abfd != NULL
		      && bfd_get_flavour (abfd) == bfd_target_elf_flavour
		      && elf_next_in_group (sec) != NULL
		      && (sec->flags & SEC_GROUP) == 0)
		    group = elf_group_name (sec);
		  else if (abfd != NULL
			   && bfd_get_flavour (abfd) == bfd_target_coff_flavour
			   && (ci = bfd_coff_get_comdat_section (sec->owner,
								 sec)) != NULL)
		    group = ci->name;
		  if (group != NULL)
		    result = print (stream, "%s[%s]", sec->name, group);
		  else
		    result = print (stream, "%s", sec->name);
		}
	      else if (*ptr == 'B')
		{
		  bfd *abfd;

		  ptr++;
		  abfd = (bfd *) args[arg_no].p;
		  if (abfd == NULL)
		    /* Invoking %pB with a null bfd pointer is an
		       internal error.  */
		    abort ();
		  else if (abfd->my_archive
			   && !bfd_is_thin_archive (abfd->my_archive))
		    result = print (stream, "%s(%s)",
				    bfd_get_filename (abfd->my_archive),
				    bfd_get_filename (abfd));
		  else
		    result = print (stream, "%s", bfd_get_filename (abfd));
		}
	      else
		PRINT_TYPE (void *, p);
	      break;
	    default:
	      abort();
	    }
	  arg_count++;
	}
      if (result == -1)
	return -1;
      total_printed += result;
    }

  return total_printed;
}

/* First pass over FORMAT to gather ARGS.  Returns number of args.  */

static unsigned int
_bfd_doprnt_scan (const char *format, va_list ap, union _bfd_doprnt_args *args)
{
  const char *ptr = format;
  unsigned int arg_count = 0;

  for (unsigned int i = 0; i < MAX_ARGS; i++)
    args[i].type = Bad;

  while (*ptr != '\0')
    {
      if (*ptr != '%')
	{
	  ptr = strchr (ptr, '%');
	  if (ptr == NULL)
	    break;
	}
      else if (ptr[1] == '%')
	ptr += 2;
      else
	{
	  int wide_width = 0, short_width = 0;
	  unsigned int arg_no;
	  int arg_type;

	  ptr++;

	  /* Check for a positional parameter.  */
	  arg_no = -1u;
	  if (*ptr != '0' && ISDIGIT (*ptr) && ptr[1] == '$')
	    {
	      arg_no = *ptr - '1';
	      ptr += 2;
	    }

	  /* There is a clash between Microsoft's non-standard I64
	     and I32 integer length modifiers and glibc's
	     non-standard I flag.  */
	  const char *printf_flag_chars
	    = sizeof PRId64 == sizeof "I64d" ? "-+ #0'" : "-+ #0'I";

	  /* Move past flags.  */
	  while (strchr (printf_flag_chars, *ptr))
	    ptr++;

	  if (*ptr == '*')
	    {
	      unsigned int arg_index;

	      ptr++;
	      arg_index = arg_count;
	      if (*ptr != '0' && ISDIGIT (*ptr) && ptr[1] == '$')
		{
		  arg_index = *ptr - '1';
		  ptr += 2;
		}
	      if (arg_index >= MAX_ARGS)
		abort ();
	      args[arg_index].type = Int;
	      arg_count++;
	    }
	  else
	    /* Handle explicit numeric value.  */
	    while (ISDIGIT (*ptr))
	      ptr++;

	  /* Precision.  */
	  if (*ptr == '.')
	    {
	      ptr++;
	      if (*ptr == '*')
		{
		  unsigned int arg_index;

		  ptr++;
		  arg_index = arg_count;
		  if (*ptr != '0' && ISDIGIT (*ptr) && ptr[1] == '$')
		    {
		      arg_index = *ptr - '1';
		      ptr += 2;
		    }
		  if (arg_index >= MAX_ARGS)
		    abort ();
		  args[arg_index].type = Int;
		  arg_count++;
		}
	      else
		/* Handle explicit numeric value.  */
		while (ISDIGIT (*ptr))
		  ptr++;
	    }

	  if (sizeof PRId64 == sizeof "I64d" && *ptr =='I')
	    {
	      if (ptr[1] == '6' && ptr[2] == '4')
		{
		  wide_width = 3;
		  ptr += 3;
		}
	      else if (ptr[1] == '3' && ptr[2] == '2')
		ptr += 3;
	    }
	  while (strchr ("hlL", *ptr))
	    {
	      switch (*ptr)
		{
		case 'h':
		  short_width = 1;
		  break;
		case 'l':
		  wide_width++;
		  break;
		case 'L':
		  wide_width = 2;
		  break;
		default:
		  abort();
		}
	      ptr++;
	    }

	  ptr++;
	  if ((int) arg_no < 0)
	    arg_no = arg_count;

	  arg_type = Bad;
	  switch (ptr[-1])
	    {
	    case 'd':
	    case 'i':
	    case 'o':
	    case 'u':
	    case 'x':
	    case 'X':
	    case 'c':
	      {
		if (short_width)
		  arg_type = Int;
		else
		  {
		    switch (wide_width)
		      {
		      case 0:
			arg_type = Int;
			break;
		      case 1:
			arg_type = Long;
			break;
		      case 2:
		      default:
			arg_type = LongLong;
			break;
		      }
		  }
	      }
	      break;
	    case 'f':
	    case 'e':
	    case 'E':
	    case 'g':
	    case 'G':
	      {
		if (wide_width == 0)
		  arg_type = Double;
		else
		  arg_type = LongDouble;
	      }
	      break;
	    case 's':
	      arg_type = Ptr;
	      break;
	    case 'p':
	      if (*ptr == 'A' || *ptr == 'B')
		ptr++;
	      arg_type = Ptr;
	      break;
	    default:
	      abort();
	    }

	  if (arg_no >= MAX_ARGS)
	    abort ();
	  args[arg_no].type = arg_type;
	  arg_count++;
	}
    }

  for (unsigned int i = 0; i < arg_count; i++)
    {
      switch (args[i].type)
	{
	case Int:
	  args[i].i = va_arg (ap, int);
	  break;
	case Long:
	  args[i].l = va_arg (ap, long);
	  break;
	case LongLong:
	  args[i].ll = va_arg (ap, long long);
	  break;
	case Double:
	  args[i].d = va_arg (ap, double);
	  break;
	case LongDouble:
	  args[i].ld = va_arg (ap, long double);
	  break;
	case Ptr:
	  args[i].p = va_arg (ap, void *);
	  break;
	default:
	  abort ();
	}
    }

  return arg_count;
}

static void
_bfd_print (bfd_print_callback print_func, void *stream,
	    const char *fmt, va_list ap)
{
  union _bfd_doprnt_args args[MAX_ARGS];

  _bfd_doprnt_scan (fmt, ap, args);
  _bfd_doprnt (print_func, stream, fmt, args);
}

/*
FUNCTION
	bfd_print_error

SYNOPSIS
	void bfd_print_error (bfd_print_callback print_func,
	  void *stream, const char *fmt, va_list ap);

DESCRIPTION

	This formats FMT and AP according to BFD "printf" rules,
	sending the output to STREAM by repeated calls to PRINT_FUNC.
	PRINT_FUNC is a printf-like function; it does not need to
	implement the BFD printf format extensions.  This can be used
	in a callback that is set via bfd_set_error_handler to turn
	the error into ordinary output.
*/

void
bfd_print_error (bfd_print_callback print_func, void *stream,
		 const char *fmt, va_list ap)
{
  print_func (stream, "%s: ", _bfd_get_error_program_name ());
  _bfd_print (print_func, stream, fmt, ap);
}

/* The standard error handler that prints to stderr.  */

static void
error_handler_fprintf (const char *fmt, va_list ap)
{
  /* PR 4992: Don't interrupt output being sent to stdout.  */
  fflush (stdout);

  bfd_print_error ((bfd_print_callback) fprintf, stderr, fmt, ap);

  /* On AIX, putc is implemented as a macro that triggers a -Wunused-value
     warning, so use the fputc function to avoid it.  */
  fputc ('\n', stderr);
  fflush (stderr);
}

/* Control printing to a string buffer.  */
struct buf_stream
{
  char *ptr;
  int left;
};

/* An fprintf like function that instead prints to a string buffer.  */

static int
err_sprintf (void *stream, const char *fmt, ...)
{
  struct buf_stream *s = stream;
  va_list ap;

  va_start (ap, fmt);
  int total = vsnprintf (s->ptr, s->left, fmt, ap);
  va_end (ap);
  if (total < 0)
    ;
  else if (total > s->left)
    {
      s->ptr += s->left;
      s->left = 0;
    }
  else
    {
      s->ptr += total;
      s->left -= total;
    }
  return total;
}

/*
INTERNAL
.{* Cached _bfd_check_format messages are put in this.  *}
.struct per_xvec_message
.{
.  struct per_xvec_message *next;
.  char message[];
.};
.
.{* A list of per_xvec_message objects.  The targ field indicates
.   which xvec this list holds; PER_XVEC_NO_TARGET is only set for the
.   root of the list and indicates that the entry isn't yet used.  The
.   abfd field is only needed in the root entry of the list.  *}
.struct per_xvec_messages
.{
.  bfd *abfd;
.  const bfd_target *targ;
.  struct per_xvec_message *messages;
.  struct per_xvec_messages *next;
.};
.
.#define PER_XVEC_NO_TARGET ((const bfd_target *) -1)
*/

/* Helper function to find or allocate the correct per-xvec object
   when emitting a message.  */

static struct per_xvec_message *
_bfd_per_xvec_warn (struct per_xvec_messages *messages, size_t alloc)
{
  const bfd_target *targ = messages->abfd->xvec;

  struct per_xvec_messages *prev = NULL;
  struct per_xvec_messages *iter = messages;

  if (iter->targ == PER_XVEC_NO_TARGET)
    iter->targ = targ;
  else
    for (; iter != NULL; iter = iter->next)
      {
	if (iter->targ == targ)
	  break;
	prev = iter;
      }

  if (iter == NULL)
    {
      iter = bfd_malloc (sizeof (*iter));
      if (iter == NULL)
	return NULL;
      iter->abfd = messages->abfd;
      iter->targ = targ;
      iter->messages = NULL;
      iter->next = NULL;
      prev->next = iter;
    }

  struct per_xvec_message **m = &iter->messages;
  int count = 0;
  while (*m)
    {
      m = &(*m)->next;
      count++;
    }
  /* Anti-fuzzer measure.  Don't cache more than 5 messages.  */
  if (count < 5)
    {
      *m = bfd_malloc (sizeof (**m) + alloc);
      if (*m != NULL)
	(*m)->next = NULL;
    }
  return *m;
}

/* Communicate the error-message container processed by
   bfd_check_format_matches to the error handling function
   error_handler_sprintf.  When non-NULL, _bfd_error_handler will call
   error_handler_sprintf; when NULL, _bfd_error_internal will be used
   instead.  */

static THREAD_LOCAL struct per_xvec_messages *error_handler_messages;

/* A special value for error_handler_messages that indicates that the
   error should simply be ignored.  */
#define IGNORE_ERROR_MESSAGES ((struct per_xvec_messages *) -1)

/* An error handler that prints to a string, then dups that string to
   a per-xvec cache.  */

static void
error_handler_sprintf (const char *fmt, va_list ap)
{
  char error_buf[1024];
  struct buf_stream error_stream;

  error_stream.ptr = error_buf;
  error_stream.left = sizeof (error_buf);

  _bfd_print (err_sprintf, &error_stream, fmt, ap);

  size_t len = error_stream.ptr - error_buf;
  struct per_xvec_message *warn
    = _bfd_per_xvec_warn (error_handler_messages, len + 1);
  if (warn)
    {
      memcpy (warn->message, error_buf, len);
      warn->message[len] = 0;
    }
}

/* This is a function pointer to the routine which should handle BFD
   error messages.  It is called when a BFD routine encounters an
   error for which it wants to print a message.  Going through a
   function pointer permits a program linked against BFD to intercept
   the messages and deal with them itself.  */

static bfd_error_handler_type _bfd_error_internal = error_handler_fprintf;

/*
FUNCTION
	_bfd_error_handler

SYNOPSIS
	void _bfd_error_handler (const char *fmt, ...) ATTRIBUTE_PRINTF_1;

DESCRIPTION
	This is the default routine to handle BFD error messages.
	Like fprintf (stderr, ...), but also handles some extra format
	specifiers.

	%pA section name from section.  For group components, prints
	group name too.
	%pB file name from bfd.  For archive components, prints
	archive too.

	Beware: Only supports a maximum of 9 format arguments.
*/

void
_bfd_error_handler (const char *fmt, ...)
{
  va_list ap;

  va_start (ap, fmt);
  if (error_handler_messages == IGNORE_ERROR_MESSAGES)
    {
      /* Nothing.  */
    }
  else if (error_handler_messages != NULL)
    error_handler_sprintf (fmt, ap);
  else
    _bfd_error_internal (fmt, ap);
  va_end (ap);
}

/*
FUNCTION
	bfd_set_error_handler

SYNOPSIS
	bfd_error_handler_type bfd_set_error_handler (bfd_error_handler_type);

DESCRIPTION
	Set the BFD error handler function.  Returns the previous
	function.
*/

bfd_error_handler_type
bfd_set_error_handler (bfd_error_handler_type pnew)
{
  bfd_error_handler_type pold;

  pold = _bfd_error_internal;
  _bfd_error_internal = pnew;
  return pold;
}

/*
INTERNAL_FUNCTION
	_bfd_set_error_handler_caching

SYNOPSIS
	struct per_xvec_messages *_bfd_set_error_handler_caching (struct per_xvec_messages *);

DESCRIPTION
	Set the BFD error handler function to one that stores messages
	to the per_xvec_messages object.  Returns the previous object
	to which messages are stored.  Note that two sequential calls
	to this with a non-NULL argument will cause output to be
	dropped, rather than gathered.
*/

struct per_xvec_messages *
_bfd_set_error_handler_caching (struct per_xvec_messages *messages)
{
  struct per_xvec_messages *old = error_handler_messages;
  if (old == NULL)
    error_handler_messages = messages;
  else
    error_handler_messages = IGNORE_ERROR_MESSAGES;
  return old;
}

/*
INTERNAL_FUNCTION
	_bfd_restore_error_handler_caching

SYNOPSIS
	void _bfd_restore_error_handler_caching (struct per_xvec_messages *);

DESCRIPTION
	Reset the BFD error handler object to an earlier value.
*/

void
_bfd_restore_error_handler_caching (struct per_xvec_messages *old)
{
  error_handler_messages = old;
}

/*
FUNCTION
	bfd_set_error_program_name

SYNOPSIS
	void bfd_set_error_program_name (const char *);

DESCRIPTION
	Set the program name to use when printing a BFD error.  This
	is printed before the error message followed by a colon and
	space.  The string must not be changed after it is passed to
	this function.
*/

void
bfd_set_error_program_name (const char *name)
{
  _bfd_error_program_name = name;
}

/*
INTERNAL_FUNCTION
	_bfd_get_error_program_name

SYNOPSIS
	const char *_bfd_get_error_program_name (void);

DESCRIPTION
	Get the program name used when printing a BFD error.
*/

const char *
_bfd_get_error_program_name (void)
{
  if (_bfd_error_program_name != NULL)
    return _bfd_error_program_name;
  return "BFD";
}

/*
SUBSECTION
	BFD assert handler

	If BFD finds an internal inconsistency, the bfd assert
	handler is called with information on the BFD version, BFD
	source file and line.  If this happens, most programs linked
	against BFD are expected to want to exit with an error, or mark
	the current BFD operation as failed, so it is recommended to
	override the default handler, which just calls
	_bfd_error_handler and continues.

CODE_FRAGMENT
.typedef void (*bfd_assert_handler_type) (const char *bfd_formatmsg,
.					  const char *bfd_version,
.					  const char *bfd_file,
.					  int bfd_line);
.
*/

/* Note the use of bfd_ prefix on the parameter names above: we want to
   show which one is the message and which is the version by naming the
   parameters, but avoid polluting the program-using-bfd namespace as
   the typedef is visible in the exported headers that the program
   includes.  Below, it's just for consistency.  */

static void
_bfd_default_assert_handler (const char *bfd_formatmsg,
			     const char *bfd_version,
			     const char *bfd_file,
			     int bfd_line)

{
  _bfd_error_handler (bfd_formatmsg, bfd_version, bfd_file, bfd_line);
}

/* Similar to _bfd_error_handler, a program can decide to exit on an
   internal BFD error.  We use a non-variadic type to simplify passing
   on parameters to other functions, e.g. _bfd_error_handler.  */

static bfd_assert_handler_type _bfd_assert_handler = _bfd_default_assert_handler;

/*
FUNCTION
	bfd_set_assert_handler

SYNOPSIS
	bfd_assert_handler_type bfd_set_assert_handler (bfd_assert_handler_type);

DESCRIPTION
	Set the BFD assert handler function.  Returns the previous
	function.
*/

bfd_assert_handler_type
bfd_set_assert_handler (bfd_assert_handler_type pnew)
{
  bfd_assert_handler_type pold;

  pold = _bfd_assert_handler;
  _bfd_assert_handler = pnew;
  return pold;
}

/*
INODE
Initialization, Threading, Error reporting, BFD front end

FUNCTION
	bfd_init

SYNOPSIS
	unsigned int bfd_init (void);

DESCRIPTION
	This routine must be called before any other BFD function to
	initialize magical internal data structures.
	Returns a magic number, which may be used to check
	that the bfd library is configured as expected by users.

.{* Value returned by bfd_init.  *}
.#define BFD_INIT_MAGIC (sizeof (struct bfd_section))
.
*/

unsigned int
bfd_init (void)
{
  _bfd_clear_error_data ();
  _bfd_error_internal = error_handler_fprintf;
  _bfd_assert_handler = _bfd_default_assert_handler;

  return BFD_INIT_MAGIC;
}


/*
INODE
Threading, Miscellaneous, Initialization, BFD front end

SECTION
	Threading

	BFD has limited support for thread-safety.  Most BFD globals
	are protected by locks, while the error-related globals are
	thread-local.  A given BFD cannot safely be used from two
	threads at the same time; it is up to the application to do
	any needed locking.  However, it is ok for different threads
	to work on different BFD objects at the same time.

SUBSECTION
	Thread functions.

CODE_FRAGMENT
.typedef bool (*bfd_lock_unlock_fn_type) (void *);
*/

/* The lock and unlock functions, if set.  */
static bfd_lock_unlock_fn_type lock_fn;
static bfd_lock_unlock_fn_type unlock_fn;
static void *lock_data;

/*
INTERNAL_FUNCTION
	_bfd_threading_enabled

SYNOPSIS
	bool _bfd_threading_enabled (void);

DESCRIPTION
	Return true if threading is enabled, false if not.
*/

bool
_bfd_threading_enabled (void)
{
  return lock_fn != NULL;
}

/*
FUNCTION
	bfd_thread_init

SYNOPSIS
	bool bfd_thread_init
	  (bfd_lock_unlock_fn_type lock,
	  bfd_lock_unlock_fn_type unlock,
	  void *data);

DESCRIPTION

	Initialize BFD threading.  The functions passed in will be
	used to lock and unlock global data structures.  This may only
	be called a single time in a given process.  Returns true on
	success and false on error.  On error, the caller should
	assume that BFD cannot be used by multiple threads.  DATA is
	passed verbatim to the lock and unlock functions.  The lock
	and unlock functions should return true on success, or set the
	BFD error and return false on failure.  Note also that the
	lock must be a recursive lock: BFD may attempt to acquire the
	lock when it is already held by the current thread.
*/

bool
bfd_thread_init (bfd_lock_unlock_fn_type lock, bfd_lock_unlock_fn_type unlock,
		 void *data)
{
#ifdef TLS
  /* Both functions must be set, and this cannot have been called
     before.  */
  if (lock == NULL || unlock == NULL || unlock_fn != NULL)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return false;
    }

  lock_fn = lock;
  unlock_fn = unlock;
  lock_data = data;
  return true;
#else /* TLS */
  /* If thread-local storage wasn't found by configure, we disallow
     threaded operation.  */
  bfd_set_error (bfd_error_invalid_operation);
  return false;
#endif /* TLS */
}

/*
FUNCTION
	bfd_thread_cleanup

SYNOPSIS
	void bfd_thread_cleanup (void);

DESCRIPTION
	Clean up any thread-local state.  This should be called by a
	thread that uses any BFD functions, before the thread exits.
	It is fine to call this multiple times, or to call it and then
	later call BFD functions on the same thread again.
*/

void
bfd_thread_cleanup (void)
{
  _bfd_clear_error_data ();
}

/*
INTERNAL_FUNCTION
	bfd_lock

SYNOPSIS
	bool bfd_lock (void);

DESCRIPTION
	Acquire the global BFD lock, if needed.  Returns true on
	success, false on error.
*/

bool
bfd_lock (void)
{
  if (lock_fn != NULL)
    return lock_fn (lock_data);
  return true;
}

/*
INTERNAL_FUNCTION
	bfd_unlock

SYNOPSIS
	bool bfd_unlock (void);

DESCRIPTION
	Release the global BFD lock, if needed.  Returns true on
	success, false on error.
*/

bool
bfd_unlock (void)
{
  if (unlock_fn != NULL)
    return unlock_fn (lock_data);
  return true;
}


/*
INODE
Miscellaneous, Memory Usage, Threading, BFD front end

SECTION
	Miscellaneous

SUBSECTION
	Miscellaneous functions
*/

/*
FUNCTION
	bfd_get_reloc_upper_bound

SYNOPSIS
	long bfd_get_reloc_upper_bound (bfd *abfd, asection *sect);

DESCRIPTION
	Return the number of bytes required to store the
	relocation information associated with section @var{sect}
	attached to bfd @var{abfd}.  If an error occurs, return -1.

*/

long
bfd_get_reloc_upper_bound (bfd *abfd, sec_ptr asect)
{
  if (abfd->format != bfd_object)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return -1;
    }

  return BFD_SEND (abfd, _get_reloc_upper_bound, (abfd, asect));
}

/*
FUNCTION
	bfd_canonicalize_reloc

SYNOPSIS
	long bfd_canonicalize_reloc
	  (bfd *abfd, asection *sec, arelent **loc, asymbol **syms);

DESCRIPTION
	Call the back end associated with the open BFD
	@var{abfd} and translate the external form of the relocation
	information attached to @var{sec} into the internal canonical
	form.  Place the table into memory at @var{loc}, which has
	been preallocated, usually by a call to
	<<bfd_get_reloc_upper_bound>>.  Returns the number of relocs, or
	-1 on error.

	The @var{syms} table is also needed for horrible internal magic
	reasons.

*/
long
bfd_canonicalize_reloc (bfd *abfd,
			sec_ptr asect,
			arelent **location,
			asymbol **symbols)
{
  if (abfd->format != bfd_object)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return -1;
    }

  return BFD_SEND (abfd, _bfd_canonicalize_reloc,
		   (abfd, asect, location, symbols));
}

/*
FUNCTION
	bfd_set_reloc

SYNOPSIS
	void bfd_set_reloc
	  (bfd *abfd, asection *sec, arelent **rel, unsigned int count);

DESCRIPTION
	Set the relocation pointer and count within
	section @var{sec} to the values @var{rel} and @var{count}.
	The argument @var{abfd} is ignored.

.#define bfd_set_reloc(abfd, asect, location, count) \
.	BFD_SEND (abfd, _bfd_set_reloc, (abfd, asect, location, count))
*/

/*
FUNCTION
	bfd_set_file_flags

SYNOPSIS
	bool bfd_set_file_flags (bfd *abfd, flagword flags);

DESCRIPTION
	Set the flag word in the BFD @var{abfd} to the value @var{flags}.

	Possible errors are:
	o <<bfd_error_wrong_format>> - The target bfd was not of object format.
	o <<bfd_error_invalid_operation>> - The target bfd was open for reading.
	o <<bfd_error_invalid_operation>> -
	The flag word contained a bit which was not applicable to the
	type of file.  E.g., an attempt was made to set the <<D_PAGED>> bit
	on a BFD format which does not support demand paging.

*/

bool
bfd_set_file_flags (bfd *abfd, flagword flags)
{
  if (abfd->format != bfd_object)
    {
      bfd_set_error (bfd_error_wrong_format);
      return false;
    }

  if (bfd_read_p (abfd))
    {
      bfd_set_error (bfd_error_invalid_operation);
      return false;
    }

  abfd->flags = flags;
  if ((flags & bfd_applicable_file_flags (abfd)) != flags)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return false;
    }

  return true;
}

void
bfd_assert (const char *file, int line)
{
  /* xgettext:c-format */
  (*_bfd_assert_handler) (_("BFD %s assertion fail %s:%d"),
			  BFD_VERSION_STRING, file, line);
}

/* A more or less friendly abort message.  In libbfd.h abort is
   defined to call this function.  */

void
_bfd_abort (const char *file, int line, const char *fn)
{
  fflush (stdout);

  if (fn != NULL)
    fprintf (stderr, _("%s: BFD %s internal error, aborting at %s:%d in %s\n"),
	     _bfd_get_error_program_name (), BFD_VERSION_STRING,
	     file, line, fn);
  else
    fprintf (stderr, _("%s: BFD %s internal error, aborting at %s:%d\n"),
	     _bfd_get_error_program_name (), BFD_VERSION_STRING,
	     file, line);
  fprintf (stderr, _("Please report this bug.\n"));
  _exit (EXIT_FAILURE);
}

/*
FUNCTION
	bfd_get_arch_size

SYNOPSIS
	int bfd_get_arch_size (bfd *abfd);

DESCRIPTION
	Returns the normalized architecture address size, in bits, as
	determined by the object file's format.  By normalized, we mean
	either 32 or 64.  For ELF, this information is included in the
	header.  Use bfd_arch_bits_per_address for number of bits in
	the architecture address.

	Returns the arch size in bits if known, <<-1>> otherwise.
*/

int
bfd_get_arch_size (bfd *abfd)
{
  if (abfd->xvec->flavour == bfd_target_elf_flavour)
    return get_elf_backend_data (abfd)->s->arch_size;

  return bfd_arch_bits_per_address (abfd) > 32 ? 64 : 32;
}

/*
FUNCTION
	bfd_get_sign_extend_vma

SYNOPSIS
	int bfd_get_sign_extend_vma (bfd *abfd);

DESCRIPTION
	Indicates if the target architecture "naturally" sign extends
	an address.  Some architectures implicitly sign extend address
	values when they are converted to types larger than the size
	of an address.  For instance, bfd_get_start_address() will
	return an address sign extended to fill a bfd_vma when this is
	the case.

	Returns <<1>> if the target architecture is known to sign
	extend addresses, <<0>> if the target architecture is known to
	not sign extend addresses, and <<-1>> otherwise.
*/

int
bfd_get_sign_extend_vma (bfd *abfd)
{
  const char *name;

  if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
    return get_elf_backend_data (abfd)->sign_extend_vma;

  name = bfd_get_target (abfd);

  /* Return a proper value for DJGPP & PE COFF.
     This function is required for DWARF2 support, but there is
     no place to store this information in the COFF back end.
     Should enough other COFF targets add support for DWARF2,
     a place will have to be found.  Until then, this hack will do.  */
  if (startswith (name, "coff-go32")
      || strcmp (name, "pe-i386") == 0
      || strcmp (name, "pei-i386") == 0
      || strcmp (name, "pe-x86-64") == 0
      || strcmp (name, "pei-x86-64") == 0
      || strcmp (name, "pe-aarch64-little") == 0
      || strcmp (name, "pei-aarch64-little") == 0
      || strcmp (name, "pe-arm-wince-little") == 0
      || strcmp (name, "pei-arm-wince-little") == 0
      || strcmp (name, "pei-loongarch64") == 0
      || strcmp (name, "pei-riscv64-little") == 0
      || strcmp (name, "aixcoff-rs6000") == 0
      || strcmp (name, "aix5coff64-rs6000") == 0)
    return 1;

  if (startswith (name, "mach-o"))
    return 0;

  bfd_set_error (bfd_error_wrong_format);
  return -1;
}

/*
FUNCTION
	bfd_set_start_address

SYNOPSIS
	bool bfd_set_start_address (bfd *abfd, bfd_vma vma);

DESCRIPTION
	Make @var{vma} the entry point of output BFD @var{abfd}.

	Returns <<TRUE>> on success, <<FALSE>> otherwise.
*/

bool
bfd_set_start_address (bfd *abfd, bfd_vma vma)
{
  abfd->start_address = vma;
  return true;
}

/*
FUNCTION
	bfd_get_gp_size

SYNOPSIS
	unsigned int bfd_get_gp_size (bfd *abfd);

DESCRIPTION
	Return the maximum size of objects to be optimized using the GP
	register under MIPS ECOFF.  This is typically set by the <<-G>>
	argument to the compiler, assembler or linker.
*/

unsigned int
bfd_get_gp_size (bfd *abfd)
{
  if (abfd->format == bfd_object)
    {
      if (abfd->xvec->flavour == bfd_target_ecoff_flavour)
	return ecoff_data (abfd)->gp_size;
      else if (abfd->xvec->flavour == bfd_target_elf_flavour)
	return elf_gp_size (abfd);
    }
  return 0;
}

/*
FUNCTION
	bfd_set_gp_size

SYNOPSIS
	void bfd_set_gp_size (bfd *abfd, unsigned int i);

DESCRIPTION
	Set the maximum size of objects to be optimized using the GP
	register under ECOFF or MIPS ELF.  This is typically set by
	the <<-G>> argument to the compiler, assembler or linker.
*/

void
bfd_set_gp_size (bfd *abfd, unsigned int i)
{
  /* Don't try to set GP size on an archive or core file!  */
  if (abfd->format != bfd_object)
    return;

  if (abfd->xvec->flavour == bfd_target_ecoff_flavour)
    ecoff_data (abfd)->gp_size = i;
  else if (abfd->xvec->flavour == bfd_target_elf_flavour)
    elf_gp_size (abfd) = i;
}

/* Get the GP value.  This is an internal function used by some of the
   relocation special_function routines on targets which support a GP
   register.  */

bfd_vma
_bfd_get_gp_value (bfd *abfd)
{
  if (! abfd)
    return 0;
  if (abfd->format != bfd_object)
    return 0;

  if (abfd->xvec->flavour == bfd_target_ecoff_flavour)
    return ecoff_data (abfd)->gp;
  else if (abfd->xvec->flavour == bfd_target_elf_flavour)
    return elf_gp (abfd);

  return 0;
}

/* Set the GP value.  */

void
_bfd_set_gp_value (bfd *abfd, bfd_vma v)
{
  if (! abfd)
    abort ();
  if (abfd->format != bfd_object)
    return;

  if (abfd->xvec->flavour == bfd_target_ecoff_flavour)
    ecoff_data (abfd)->gp = v;
  else if (abfd->xvec->flavour == bfd_target_elf_flavour)
    elf_gp (abfd) = v;
}

/*
FUNCTION
	bfd_set_gp_value

SYNOPSIS
	void bfd_set_gp_value (bfd *abfd, bfd_vma v);

DESCRIPTION
	Allow external access to the fucntion to set the GP value.
	This is specifically added for gdb-compile support.
*/

void
bfd_set_gp_value (bfd *abfd, bfd_vma v)
{
  _bfd_set_gp_value (abfd, v);
}

/*
FUNCTION
	bfd_scan_vma

SYNOPSIS
	bfd_vma bfd_scan_vma (const char *string, const char **end, int base);

DESCRIPTION
	Convert, like <<strtoul>> or <<stdtoull> depending on the size
	of a <<bfd_vma>>, a numerical expression @var{string} into a
	<<bfd_vma>> integer, and return that integer.
*/

bfd_vma
bfd_scan_vma (const char *string, const char **end, int base)
{
  if (sizeof (bfd_vma) <= sizeof (unsigned long))
    return strtoul (string, (char **) end, base);

  if (sizeof (bfd_vma) <= sizeof (unsigned long long))
    return strtoull (string, (char **) end, base);

  abort ();
}

/*
FUNCTION
	bfd_copy_private_header_data

SYNOPSIS
	bool bfd_copy_private_header_data (bfd *ibfd, bfd *obfd);

DESCRIPTION
	Copy private BFD header information from the BFD @var{ibfd} to the
	the BFD @var{obfd}.  This copies information that may require
	sections to exist, but does not require symbol tables.  Return
	<<true>> on success, <<false>> on error.
	Possible error returns are:

	o <<bfd_error_no_memory>> -
	Not enough memory exists to create private data for @var{obfd}.

.#define bfd_copy_private_header_data(ibfd, obfd) \
.	BFD_SEND (obfd, _bfd_copy_private_header_data, \
.		  (ibfd, obfd))

*/

/*
FUNCTION
	bfd_copy_private_bfd_data

SYNOPSIS
	bool bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd);

DESCRIPTION
	Copy private BFD information from the BFD @var{ibfd} to the
	the BFD @var{obfd}.  Return <<TRUE>> on success, <<FALSE>> on error.
	Possible error returns are:

	o <<bfd_error_no_memory>> -
	Not enough memory exists to create private data for @var{obfd}.

.#define bfd_copy_private_bfd_data(ibfd, obfd) \
.	BFD_SEND (obfd, _bfd_copy_private_bfd_data, \
.		  (ibfd, obfd))

*/

/*
FUNCTION
	bfd_set_private_flags

SYNOPSIS
	bool bfd_set_private_flags (bfd *abfd, flagword flags);

DESCRIPTION
	Set private BFD flag information in the BFD @var{abfd}.
	Return <<TRUE>> on success, <<FALSE>> on error.  Possible error
	returns are:

	o <<bfd_error_no_memory>> -
	Not enough memory exists to create private data for @var{obfd}.

.#define bfd_set_private_flags(abfd, flags) \
.	BFD_SEND (abfd, _bfd_set_private_flags, (abfd, flags))

*/

/*
FUNCTION
	Other functions

DESCRIPTION
	The following functions exist but have not yet been documented.

.#define bfd_sizeof_headers(abfd, info) \
.	BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, info))
.
.#define bfd_find_nearest_line(abfd, sec, syms, off, file, func, line) \
.	BFD_SEND (abfd, _bfd_find_nearest_line, \
.		  (abfd, syms, sec, off, file, func, line, NULL))
.
.#define bfd_find_nearest_line_with_alt(abfd, alt_filename, sec, syms, off, \
.					file, func, line, disc) \
.	BFD_SEND (abfd, _bfd_find_nearest_line_with_alt, \
.		  (abfd, alt_filename, syms, sec, off, file, func, line, disc))
.
.#define bfd_find_nearest_line_discriminator(abfd, sec, syms, off, file, func, \
.					    line, disc) \
.	BFD_SEND (abfd, _bfd_find_nearest_line, \
.		  (abfd, syms, sec, off, file, func, line, disc))
.
.#define bfd_find_line(abfd, syms, sym, file, line) \
.	BFD_SEND (abfd, _bfd_find_line, \
.		  (abfd, syms, sym, file, line))
.
.#define bfd_find_inliner_info(abfd, file, func, line) \
.	BFD_SEND (abfd, _bfd_find_inliner_info, \
.		  (abfd, file, func, line))
.
.#define bfd_debug_info_start(abfd) \
.	BFD_SEND (abfd, _bfd_debug_info_start, (abfd))
.
.#define bfd_debug_info_end(abfd) \
.	BFD_SEND (abfd, _bfd_debug_info_end, (abfd))
.
.#define bfd_debug_info_accumulate(abfd, section) \
.	BFD_SEND (abfd, _bfd_debug_info_accumulate, (abfd, section))
.
.#define bfd_stat_arch_elt(abfd, stat) \
.	BFD_SEND (abfd->my_archive ? abfd->my_archive : abfd, \
.		  _bfd_stat_arch_elt, (abfd, stat))
.
.#define bfd_update_armap_timestamp(abfd) \
.	BFD_SEND (abfd, _bfd_update_armap_timestamp, (abfd))
.
.#define bfd_set_arch_mach(abfd, arch, mach)\
.	BFD_SEND ( abfd, _bfd_set_arch_mach, (abfd, arch, mach))
.
.#define bfd_relax_section(abfd, section, link_info, again) \
.	BFD_SEND (abfd, _bfd_relax_section, (abfd, section, link_info, again))
.
.#define bfd_gc_sections(abfd, link_info) \
.	BFD_SEND (abfd, _bfd_gc_sections, (abfd, link_info))
.
.#define bfd_lookup_section_flags(link_info, flag_info, section) \
.	BFD_SEND (abfd, _bfd_lookup_section_flags, (link_info, flag_info, section))
.
.#define bfd_is_group_section(abfd, sec) \
.	BFD_SEND (abfd, _bfd_is_group_section, (abfd, sec))
.
.#define bfd_group_name(abfd, sec) \
.	BFD_SEND (abfd, _bfd_group_name, (abfd, sec))
.
.#define bfd_discard_group(abfd, sec) \
.	BFD_SEND (abfd, _bfd_discard_group, (abfd, sec))
.
.#define bfd_link_hash_table_create(abfd) \
.	BFD_SEND (abfd, _bfd_link_hash_table_create, (abfd))
.
.#define bfd_link_add_symbols(abfd, info) \
.	BFD_SEND (abfd, _bfd_link_add_symbols, (abfd, info))
.
.#define bfd_link_just_syms(abfd, sec, info) \
.	BFD_SEND (abfd, _bfd_link_just_syms, (sec, info))
.
.#define bfd_final_link(abfd, info) \
.	BFD_SEND (abfd, _bfd_final_link, (abfd, info))
.
.#define bfd_free_cached_info(abfd) \
.	BFD_SEND (abfd, _bfd_free_cached_info, (abfd))
.
.#define bfd_get_dynamic_symtab_upper_bound(abfd) \
.	BFD_SEND (abfd, _bfd_get_dynamic_symtab_upper_bound, (abfd))
.
.#define bfd_print_private_bfd_data(abfd, file)\
.	BFD_SEND (abfd, _bfd_print_private_bfd_data, (abfd, file))
.
.#define bfd_canonicalize_dynamic_symtab(abfd, asymbols) \
.	BFD_SEND (abfd, _bfd_canonicalize_dynamic_symtab, (abfd, asymbols))
.
.#define bfd_get_synthetic_symtab(abfd, count, syms, dyncount, dynsyms, ret) \
.	BFD_SEND (abfd, _bfd_get_synthetic_symtab, (abfd, count, syms, \
.						    dyncount, dynsyms, ret))
.
.#define bfd_get_dynamic_reloc_upper_bound(abfd) \
.	BFD_SEND (abfd, _bfd_get_dynamic_reloc_upper_bound, (abfd))
.
.#define bfd_canonicalize_dynamic_reloc(abfd, arels, asyms) \
.	BFD_SEND (abfd, _bfd_canonicalize_dynamic_reloc, (abfd, arels, asyms))
.
*/

/*
FUNCTION
	bfd_get_relocated_section_contents

SYNOPSIS
	bfd_byte *bfd_get_relocated_section_contents
	  (bfd *, struct bfd_link_info *, struct bfd_link_order *, bfd_byte *,
	   bool, asymbol **);

DESCRIPTION
	Read and relocate the indirect link_order section, into DATA
	(if non-NULL) or to a malloc'd buffer.  Return the buffer, or
	NULL on errors.
*/

bfd_byte *
bfd_get_relocated_section_contents (bfd *abfd,
				    struct bfd_link_info *link_info,
				    struct bfd_link_order *link_order,
				    bfd_byte *data,
				    bool relocatable,
				    asymbol **symbols)
{
  bfd *abfd2;
  bfd_byte *(*fn) (bfd *, struct bfd_link_info *, struct bfd_link_order *,
		   bfd_byte *, bool, asymbol **);

  if (link_order->type == bfd_indirect_link_order)
    {
      abfd2 = link_order->u.indirect.section->owner;
      if (abfd2 == NULL)
	abfd2 = abfd;
    }
  else
    abfd2 = abfd;

  fn = abfd2->xvec->_bfd_get_relocated_section_contents;

  return (*fn) (abfd, link_info, link_order, data, relocatable, symbols);
}

/*
FUNCTION
	bfd_record_phdr

SYNOPSIS
	bool bfd_record_phdr
	  (bfd *, unsigned long, bool, flagword, bool, bfd_vma,
	   bool, bool, unsigned int, struct bfd_section **);

DESCRIPTION
	Record information about an ELF program header.
*/

bool
bfd_record_phdr (bfd *abfd,
		 unsigned long type,
		 bool flags_valid,
		 flagword flags,
		 bool at_valid,
		 bfd_vma at,  /* Bytes.  */
		 bool includes_filehdr,
		 bool includes_phdrs,
		 unsigned int count,
		 asection **secs)
{
  struct elf_segment_map *m, **pm;
  size_t amt;
  unsigned int opb = bfd_octets_per_byte (abfd, NULL);

  if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
    return true;

  amt = sizeof (struct elf_segment_map);
  amt += ((bfd_size_type) count - 1) * sizeof (asection *);
  m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
  if (m == NULL)
    return false;

  m->p_type = type;
  m->p_flags = flags;
  m->p_paddr = at * opb;
  m->p_flags_valid = flags_valid;
  m->p_paddr_valid = at_valid;
  m->includes_filehdr = includes_filehdr;
  m->includes_phdrs = includes_phdrs;
  m->count = count;
  if (count > 0)
    memcpy (m->sections, secs, count * sizeof (asection *));

  for (pm = &elf_seg_map (abfd); *pm != NULL; pm = &(*pm)->next)
    ;
  *pm = m;

  return true;
}

#ifdef BFD64
/* Return true iff this target is 32-bit.  */

static bool
is32bit (bfd *abfd)
{
  if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
    {
      const struct elf_backend_data *bed = get_elf_backend_data (abfd);
      return bed->s->elfclass == ELFCLASS32;
    }

  /* For non-ELF targets, use architecture information.  */
  return bfd_arch_bits_per_address (abfd) <= 32;
}
#endif

/*
FUNCTION
	bfd_sprintf_vma
	bfd_fprintf_vma

SYNOPSIS
	void bfd_sprintf_vma (bfd *, char *, bfd_vma);
	void bfd_fprintf_vma (bfd *, void *, bfd_vma);

DESCRIPTION
	bfd_sprintf_vma and bfd_fprintf_vma display an address in the
	target's address size.

EXTERNAL
.#define bfd_printf_vma(abfd,x) bfd_fprintf_vma (abfd, stdout, x)
.
*/

void
bfd_sprintf_vma (bfd *abfd ATTRIBUTE_UNUSED, char *buf, bfd_vma value)
{
#ifdef BFD64
  if (!is32bit (abfd))
    {
      sprintf (buf, "%016" PRIx64, (uint64_t) value);
      return;
    }
#endif
  sprintf (buf, "%08lx", (unsigned long) value & 0xffffffff);
}

void
bfd_fprintf_vma (bfd *abfd ATTRIBUTE_UNUSED, void *stream, bfd_vma value)
{
#ifdef BFD64
  if (!is32bit (abfd))
    {
      fprintf ((FILE *) stream, "%016" PRIx64, (uint64_t) value);
      return;
    }
#endif
  fprintf ((FILE *) stream, "%08lx", (unsigned long) value & 0xffffffff);
}

/*
FUNCTION
	bfd_alt_mach_code

SYNOPSIS
	bool bfd_alt_mach_code (bfd *abfd, int alternative);

DESCRIPTION

	When more than one machine code number is available for the
	same machine type, this function can be used to switch between
	the preferred one (alternative == 0) and any others.  Currently,
	only ELF supports this feature, with up to two alternate
	machine codes.
*/

bool
bfd_alt_mach_code (bfd *abfd, int alternative)
{
  if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
    {
      int code;

      switch (alternative)
	{
	case 0:
	  code = get_elf_backend_data (abfd)->elf_machine_code;
	  break;

	case 1:
	  code = get_elf_backend_data (abfd)->elf_machine_alt1;
	  if (code == 0)
	    return false;
	  break;

	case 2:
	  code = get_elf_backend_data (abfd)->elf_machine_alt2;
	  if (code == 0)
	    return false;
	  break;

	default:
	  return false;
	}

      elf_elfheader (abfd)->e_machine = code;

      return true;
    }

  return false;
}

/*
FUNCTION
	bfd_emul_get_maxpagesize

SYNOPSIS
	bfd_vma bfd_emul_get_maxpagesize (const char *);

DESCRIPTION
	Returns the maximum page size, in bytes, as determined by
	emulation.
*/

bfd_vma
bfd_emul_get_maxpagesize (const char *emul)
{
  const bfd_target *target;

  target = bfd_find_target (emul, NULL);
  if (target != NULL
      && target->flavour == bfd_target_elf_flavour)
    return xvec_get_elf_backend_data (target)->maxpagesize;

  return 0;
}

/*
FUNCTION
	bfd_emul_get_commonpagesize

SYNOPSIS
	bfd_vma bfd_emul_get_commonpagesize (const char *);

DESCRIPTION
	Returns the common page size, in bytes, as determined by
	emulation.
*/

bfd_vma
bfd_emul_get_commonpagesize (const char *emul)
{
  const bfd_target *target;

  target = bfd_find_target (emul, NULL);
  if (target != NULL
      && target->flavour == bfd_target_elf_flavour)
    {
      const struct elf_backend_data *bed;

      bed = xvec_get_elf_backend_data (target);
      return bed->commonpagesize;
    }
  return 0;
}

/*
FUNCTION
	bfd_demangle

SYNOPSIS
	char *bfd_demangle (bfd *, const char *, int);

DESCRIPTION
	Wrapper around cplus_demangle.  Strips leading underscores and
	other such chars that would otherwise confuse the demangler.
	If passed a g++ v3 ABI mangled name, returns a buffer allocated
	with malloc holding the demangled name.  Returns NULL otherwise
	and on memory alloc failure.
*/

char *
bfd_demangle (bfd *abfd, const char *name, int options)
{
  char *res, *alloc;
  const char *pre, *suf;
  size_t pre_len;
  bool skip_lead;

  skip_lead = (abfd != NULL
	       && *name != '\0'
	       && bfd_get_symbol_leading_char (abfd) == *name);
  if (skip_lead)
    ++name;

  /* This is a hack for better error reporting on XCOFF, PowerPC64-ELF
     or the MS PE format.  These formats have a number of leading '.'s
     on at least some symbols, so we remove all dots to avoid
     confusing the demangler.  */
  pre = name;
  while (*name == '.' || *name == '$')
    ++name;
  pre_len = name - pre;

  /* Strip off @plt and suchlike too.  */
  alloc = NULL;
  suf = strchr (name, '@');
  if (suf != NULL)
    {
      alloc = (char *) bfd_malloc (suf - name + 1);
      if (alloc == NULL)
	return NULL;
      memcpy (alloc, name, suf - name);
      alloc[suf - name] = '\0';
      name = alloc;
    }

  res = cplus_demangle (name, options);

  free (alloc);

  if (res == NULL)
    {
      if (skip_lead)
	{
	  size_t len = strlen (pre) + 1;
	  alloc = (char *) bfd_malloc (len);
	  if (alloc == NULL)
	    return NULL;
	  memcpy (alloc, pre, len);
	  return alloc;
	}
      return NULL;
    }

  /* Put back any prefix or suffix.  */
  if (pre_len != 0 || suf != NULL)
    {
      size_t len;
      size_t suf_len;
      char *final;

      len = strlen (res);
      if (suf == NULL)
	suf = res + len;
      suf_len = strlen (suf) + 1;
      final = (char *) bfd_malloc (pre_len + len + suf_len);
      if (final != NULL)
	{
	  memcpy (final, pre, pre_len);
	  memcpy (final + pre_len, res, len);
	  memcpy (final + pre_len + len, suf, suf_len);
	}
      free (res);
      res = final;
    }

  return res;
}

/* Get the linker information.  */

struct bfd_link_info *
_bfd_get_link_info (bfd *abfd)
{
  if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
    return NULL;

  return elf_link_info (abfd);
}

/*
FUNCTION
	bfd_group_signature

SYNOPSIS
	asymbol *bfd_group_signature (asection *group, asymbol **isympp);

DESCRIPTION
	Return a pointer to the symbol used as a signature for GROUP.
*/

asymbol *
bfd_group_signature (asection *group, asymbol **isympp)
{
  bfd *abfd = group->owner;
  Elf_Internal_Shdr *ghdr;

  /* PR 20089: An earlier error may have prevented us from loading the
     symbol table.  */
  if (isympp == NULL)
    return NULL;

  if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
    return NULL;

  ghdr = &elf_section_data (group)->this_hdr;
  if (ghdr->sh_link == elf_onesymtab (abfd))
    {
      const struct elf_backend_data *bed = get_elf_backend_data (abfd);
      Elf_Internal_Shdr *symhdr = &elf_symtab_hdr (abfd);

      if (ghdr->sh_info > 0
	  && ghdr->sh_info < symhdr->sh_size / bed->s->sizeof_sym)
	return isympp[ghdr->sh_info - 1];
    }
  return NULL;
}
