Automatic date update in version.in
[platform/upstream/binutils.git] / bfd / bfd.c
index b1c49aa..2d9397b 100644 (file)
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -1,14 +1,12 @@
 /* Generic BFD library interface and support routines.
-   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
-   Free Software Foundation, Inc.
+   Copyright (C) 1990-2014 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 2 of the License, or
+   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,
 
    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.  */
+   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>>
 
@@ -34,11 +36,16 @@ SECTION
 
 CODE_FRAGMENT
 .
+.enum bfd_direction
+.  {
+.    no_direction = 0,
+.    read_direction = 1,
+.    write_direction = 2,
+.    both_direction = 3
+.  };
+.
 .struct bfd
 .{
-.  {* A unique identifier of the BFD  *}
-.  unsigned int id;
-.
 .  {* The filename the application opened the BFD with.  *}
 .  const char *filename;
 .
@@ -50,15 +57,6 @@ CODE_FRAGMENT
 .  void *iostream;
 .  const struct bfd_iovec *iovec;
 .
-.  {* Is the file descriptor being cached?  That is, can it be closed as
-.     needed, and re-opened when accessed later?  *}
-.  bfd_boolean cacheable;
-.
-.  {* 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.  *}
-.  bfd_boolean target_defaulted;
-.
 .  {* The caching routines use these to maintain a
 .     least-recently-used list of BFDs.  *}
 .  struct bfd *lru_prev, *lru_next;
@@ -67,43 +65,152 @@ CODE_FRAGMENT
 .     state information on the file here...  *}
 .  ufile_ptr where;
 .
-.  {* ... and here: (``once'' means at least once).  *}
-.  bfd_boolean opened_once;
-.
-.  {* Set if we have a locally maintained mtime value, rather than
-.     getting it from the file each time.  *}
-.  bfd_boolean mtime_set;
-.
 .  {* File modified time, if mtime_set is TRUE.  *}
 .  long mtime;
 .
-.  {* Reserved for an unimplemented file locking extension.  *}
-.  int ifd;
+.  {* A unique identifier of the BFD  *}
+.  unsigned int id;
 .
 .  {* The format which belongs to the BFD. (object, core, etc.)  *}
-.  bfd_format format;
+.  ENUM_BITFIELD (bfd_format) format : 3;
 .
 .  {* The direction with which the BFD was opened.  *}
-.  enum bfd_direction
-.    {
-.      no_direction = 0,
-.      read_direction = 1,
-.      write_direction = 2,
-.      both_direction = 3
-.    }
-.  direction;
+.  ENUM_BITFIELD (bfd_direction) direction : 2;
 .
 .  {* Format_specific flags.  *}
-.  flagword flags;
+.  flagword flags : 17;
+.
+.  {* 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  0x00
+.
+.  {* BFD contains relocation entries.  *}
+.#define HAS_RELOC     0x01
+.
+.  {* BFD is directly executable.  *}
+.#define EXEC_P        0x02
+.
+.  {* BFD has line number information (basically used for F_LNNO in a
+.     COFF header).  *}
+.#define HAS_LINENO    0x04
+.
+.  {* 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 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
+.
+.  {* Flags bits to be saved in bfd_preserve_save.  *}
+.#define BFD_FLAGS_SAVED \
+.  (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_PLUGIN)
+.
+.  {* 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)
+.
+.  {* 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 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;
 .
 .  {* Currently my_archive is tested before adding origin to
 .     anything. I believe that this can become always an add of
 .     origin, with origin set to 0 for non archive files.  *}
 .  ufile_ptr origin;
 .
-.  {* Remember when output has begun, to stop strange things
-.     from happening.  *}
-.  bfd_boolean output_has_begun;
+.  {* 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;
@@ -117,38 +224,41 @@ CODE_FRAGMENT
 .  {* The number of sections.  *}
 .  unsigned int section_count;
 .
+.  {* A field used by _bfd_generic_link_add_archive_symbols.  This will
+.     be used only for archive elements.  *}
+.  int archive_pass;
+.
 .  {* 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;
 .
-.  {* Symbol table for output BFD (with symcount entries).  *}
-.  struct bfd_symbol  **outsymbols;
-.
 .  {* Used for slurped dynamic symbol tables.  *}
 .  unsigned int dynsymcount;
 .
 .  {* Pointer to structure which contains architecture information.  *}
 .  const struct bfd_arch_info *arch_info;
 .
-.  {* Flag set if symbols from this BFD should not be exported.  *}
-.  bfd_boolean no_export;
-.
 .  {* 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.  *}
-.  bfd_boolean has_armap;
-.
-.  {* A chain of BFD structures involved in a link.  *}
-.  struct bfd *link_next;
+.  struct bfd *nested_archives; {* List of nested archive in a flattened
+.                                  thin archive.  *}
 .
-.  {* A field used by _bfd_generic_link_add_archive_symbols.  This will
-.     be used only for archive elements.  *}
-.  int archive_pass;
+.  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
@@ -164,6 +274,7 @@ CODE_FRAGMENT
 .      struct ieee_data_struct *ieee_data;
 .      struct ieee_ar_data_struct *ieee_ar_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;
@@ -184,6 +295,7 @@ CODE_FRAGMENT
 .      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;
@@ -200,6 +312,14 @@ CODE_FRAGMENT
 .  void *memory;
 .};
 .
+.{* See note beside bfd_set_section_userdata.  *}
+.static inline bfd_boolean
+.bfd_set_cacheable (bfd * abfd, bfd_boolean val)
+.{
+.  abfd->cacheable = val;
+.  return TRUE;
+.}
+.
 */
 
 #include "sysdep.h"
@@ -230,6 +350,9 @@ CODE_FRAGMENT
    where it is needed.  The typedef's used are defined in bfd.h */
 \f
 /*
+INODE
+Error reporting, Miscellaneous, typedef bfd, BFD front end
+
 SECTION
        Error reporting
 
@@ -264,6 +387,7 @@ CODE_FRAGMENT
 .  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,
@@ -296,6 +420,7 @@ const char *const bfd_errmsgs[] =
   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"),
@@ -351,7 +476,7 @@ bfd_set_error (bfd_error_type error_tag, ...)
 
       va_start (ap, error_tag);
       input_bfd = va_arg (ap, bfd *);
-      input_error = va_arg (ap, int);
+      input_error = (bfd_error_type) va_arg (ap, int);
       if (input_error >= bfd_error_on_input)
        abort ();
       va_end (ap);
@@ -416,10 +541,12 @@ DESCRIPTION
 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);
 }
 
 /*
@@ -475,6 +602,9 @@ _bfd_default_error_handler (const char *fmt, ...)
   size_t avail = 1000;
   char buf[1000];
 
+  /* PR 4992: Don't interrupt output being sent to stdout.  */
+  fflush (stdout);
+
   if (_bfd_error_program_name != NULL)
     fprintf (stderr, "%s: ", _bfd_error_program_name);
   else
@@ -612,7 +742,10 @@ _bfd_default_error_handler (const char *fmt, ...)
   vfprintf (stderr, new_fmt, ap);
   va_end (ap);
 
-  putc ('\n', stderr);
+  /* 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);
 }
 
 /* This is a function pointer to the routine which should handle BFD
@@ -681,8 +814,93 @@ bfd_get_error_handler (void)
 {
   return _bfd_error_handler;
 }
+
+/*
+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.  */
+
+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;
+}
+
+/*
+FUNCTION
+       bfd_get_assert_handler
+
+SYNOPSIS
+       bfd_assert_handler_type bfd_get_assert_handler (void);
+
+DESCRIPTION
+       Return the BFD assert handler function.
+*/
+
+bfd_assert_handler_type
+bfd_get_assert_handler (void)
+{
+  return _bfd_assert_handler;
+}
 \f
 /*
+INODE
+Miscellaneous, Memory Usage, Error reporting, BFD front end
+
 SECTION
        Miscellaneous
 
@@ -826,8 +1044,8 @@ bfd_set_file_flags (bfd *abfd, flagword flags)
 void
 bfd_assert (const char *file, int line)
 {
-  (*_bfd_error_handler) (_("BFD %s assertion fail %s:%d"),
-                        BFD_VERSION_STRING, file, line);
+  (*_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
@@ -856,9 +1074,11 @@ SYNOPSIS
        int bfd_get_arch_size (bfd *abfd);
 
 DESCRIPTION
-       Returns the architecture address size, in bits, as determined
-       by the object file's format.  For ELF, this information is
-       included in the header.
+       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
        Returns the arch size in bits if known, <<-1>> otherwise.
@@ -870,7 +1090,7 @@ bfd_get_arch_size (bfd *abfd)
   if (abfd->xvec->flavour == bfd_target_elf_flavour)
     return get_elf_backend_data (abfd)->s->arch_size;
 
-  return -1;
+  return bfd_arch_bits_per_address (abfd) > 32 ? 64 : 32;
 }
 
 /*
@@ -912,10 +1132,16 @@ bfd_get_sign_extend_vma (bfd *abfd)
   if (CONST_STRNEQ (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-arm-wince-little") == 0
-      || strcmp (name, "pei-arm-wince-little") == 0)
+      || strcmp (name, "pei-arm-wince-little") == 0
+      || strcmp (name, "aixcoff-rs6000") == 0)
     return 1;
 
+  if (CONST_STRNEQ (name, "mach-o"))
+    return 0;
+
   bfd_set_error (bfd_error_wrong_format);
   return -1;
 }
@@ -1019,7 +1245,7 @@ void
 _bfd_set_gp_value (bfd *abfd, bfd_vma v)
 {
   if (! abfd)
-    BFD_FAIL ();
+    abort ();
   if (abfd->format != bfd_object)
     return;
 
@@ -1218,7 +1444,12 @@ DESCRIPTION
 .
 .#define bfd_find_nearest_line(abfd, sec, syms, off, file, func, line) \
 .       BFD_SEND (abfd, _bfd_find_nearest_line, \
-.                 (abfd, sec, syms, off, file, func, line))
+.                 (abfd, syms, sec, off, file, func, line, NULL))
+.
+.#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, \
@@ -1252,6 +1483,9 @@ DESCRIPTION
 .#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_merge_sections(abfd, link_info) \
 .      BFD_SEND (abfd, _bfd_merge_sections, (abfd, link_info))
 .
@@ -1264,9 +1498,6 @@ DESCRIPTION
 .#define bfd_link_hash_table_create(abfd) \
 .      BFD_SEND (abfd, _bfd_link_hash_table_create, (abfd))
 .
-.#define bfd_link_hash_table_free(abfd, hash) \
-.      BFD_SEND (abfd, _bfd_link_hash_table_free, (hash))
-.
 .#define bfd_link_add_symbols(abfd, info) \
 .      BFD_SEND (abfd, _bfd_link_add_symbols, (abfd, info))
 .
@@ -1353,7 +1584,7 @@ bfd_record_phdr (bfd *abfd,
 
   amt = sizeof (struct elf_segment_map);
   amt += ((bfd_size_type) count - 1) * sizeof (asection *);
-  m = bfd_zalloc (abfd, amt);
+  m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
   if (m == NULL)
     return FALSE;
 
@@ -1368,38 +1599,57 @@ bfd_record_phdr (bfd *abfd,
   if (count > 0)
     memcpy (m->sections, secs, count * sizeof (asection *));
 
-  for (pm = &elf_tdata (abfd)->segment_map; *pm != NULL; pm = &(*pm)->next)
+  for (pm = &elf_seg_map (abfd); *pm != NULL; pm = &(*pm)->next)
     ;
   *pm = m;
 
   return TRUE;
 }
 
-void
-bfd_sprintf_vma (bfd *abfd, char *buf, bfd_vma value)
+#ifdef BFD64
+/* Return true iff this target is 32-bit.  */
+
+static bfd_boolean
+is32bit (bfd *abfd)
 {
   if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
-    get_elf_backend_data (abfd)->elf_backend_sprintf_vma (abfd, buf, value);
-  else
-    sprintf_vma (buf, value);
+    {
+      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
+
+/* bfd_sprintf_vma and bfd_fprintf_vma display an address in the
+   target's address size.  */
 
 void
-bfd_fprintf_vma (bfd *abfd, void *stream, bfd_vma value)
+bfd_sprintf_vma (bfd *abfd ATTRIBUTE_UNUSED, char *buf, bfd_vma value)
 {
-  if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
-    get_elf_backend_data (abfd)->elf_backend_fprintf_vma (abfd, stream, value);
 #ifdef BFD64
-  /* fprintf_vma() on a 64-bit enabled host will always print a 64-bit
-     value, but really we want to display the address in the target's
-     address size.  Since we do not have a field in the bfd structure
-     to tell us this, we take a guess, based on the target's name.  */
-  else if (strstr (bfd_get_target (abfd), "64") == NULL
-          && strcmp (bfd_get_target (abfd), "mmo") != 0)
-    fprintf ((FILE *) stream, "%08lx", (unsigned long) (value & 0xffffffff));
+  if (is32bit (abfd))
+    {
+      sprintf (buf, "%08lx", (unsigned long) value & 0xffffffff);
+      return;
+    }
 #endif
-  else
-    fprintf_vma ((FILE *) stream, value);
+  sprintf_vma (buf, value);
+}
+
+void
+bfd_fprintf_vma (bfd *abfd ATTRIBUTE_UNUSED, void *stream, bfd_vma value)
+{
+#ifdef BFD64
+  if (is32bit (abfd))
+    {
+      fprintf ((FILE *) stream, "%08lx", (unsigned long) value & 0xffffffff);
+      return;
+    }
+#endif
+  fprintf_vma ((FILE *) stream, value);
 }
 
 /*
@@ -1456,128 +1706,6 @@ bfd_alt_mach_code (bfd *abfd, int alternative)
 }
 
 /*
-CODE_FRAGMENT
-
-.struct bfd_preserve
-.{
-.  void *marker;
-.  void *tdata;
-.  flagword flags;
-.  const struct bfd_arch_info *arch_info;
-.  struct bfd_section *sections;
-.  struct bfd_section *section_last;
-.  unsigned int section_count;
-.  struct bfd_hash_table section_htab;
-.};
-.
-*/
-
-/*
-FUNCTION
-       bfd_preserve_save
-
-SYNOPSIS
-       bfd_boolean bfd_preserve_save (bfd *, struct bfd_preserve *);
-
-DESCRIPTION
-       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 and
-       reinitializes the bfd.
-
-*/
-
-bfd_boolean
-bfd_preserve_save (bfd *abfd, struct bfd_preserve *preserve)
-{
-  preserve->tdata = abfd->tdata.any;
-  preserve->arch_info = abfd->arch_info;
-  preserve->flags = abfd->flags;
-  preserve->sections = abfd->sections;
-  preserve->section_last = abfd->section_last;
-  preserve->section_count = abfd->section_count;
-  preserve->section_htab = abfd->section_htab;
-
-  if (! bfd_hash_table_init (&abfd->section_htab, bfd_section_hash_newfunc,
-                            sizeof (struct section_hash_entry)))
-    return FALSE;
-
-  abfd->tdata.any = NULL;
-  abfd->arch_info = &bfd_default_arch_struct;
-  abfd->flags &= BFD_IN_MEMORY;
-  abfd->sections = NULL;
-  abfd->section_last = NULL;
-  abfd->section_count = 0;
-
-  return TRUE;
-}
-
-/*
-FUNCTION
-       bfd_preserve_restore
-
-SYNOPSIS
-       void bfd_preserve_restore (bfd *, struct bfd_preserve *);
-
-DESCRIPTION
-       This function restores bfd state saved by bfd_preserve_save.
-       If MARKER is non-NULL in struct bfd_preserve then that block
-       and all subsequently bfd_alloc'd memory is freed.
-
-*/
-
-void
-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;
-  abfd->flags = preserve->flags;
-  abfd->section_htab = preserve->section_htab;
-  abfd->sections = preserve->sections;
-  abfd->section_last = preserve->section_last;
-  abfd->section_count = preserve->section_count;
-
-  /* bfd_release frees all memory more recently bfd_alloc'd than
-     its arg, as well as its arg.  */
-  if (preserve->marker != NULL)
-    {
-      bfd_release (abfd, preserve->marker);
-      preserve->marker = NULL;
-    }
-}
-
-/*
-FUNCTION
-       bfd_preserve_finish
-
-SYNOPSIS
-       void bfd_preserve_finish (bfd *, struct bfd_preserve *);
-
-DESCRIPTION
-       This function should be called when the bfd state saved by
-       bfd_preserve_save is no longer needed.  ie. when the back-end
-       object_p function returns with success.
-
-*/
-
-void
-bfd_preserve_finish (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_preserve *preserve)
-{
-  /* 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);
-}
-
-/*
 FUNCTION
        bfd_emul_get_maxpagesize
 
@@ -1589,8 +1717,7 @@ DESCRIPTION
        emulation.
 
 RETURNS
-       Returns the maximum page size in bytes for ELF, abort
-       otherwise.
+       Returns the maximum page size in bytes for ELF, 0 otherwise.
 */
 
 bfd_vma
@@ -1603,7 +1730,6 @@ bfd_emul_get_maxpagesize (const char *emul)
       && target->flavour == bfd_target_elf_flavour)
     return xvec_get_elf_backend_data (target)->maxpagesize;
 
-  abort ();
   return 0;
 }
 
@@ -1662,7 +1788,7 @@ DESCRIPTION
        emulation.
 
 RETURNS
-       Returns the common page size in bytes for ELF, abort otherwise.
+       Returns the common page size in bytes for ELF, 0 otherwise.
 */
 
 bfd_vma
@@ -1675,7 +1801,6 @@ bfd_emul_get_commonpagesize (const char *emul)
       && target->flavour == bfd_target_elf_flavour)
     return xvec_get_elf_backend_data (target)->commonpagesize;
 
-  abort ();
   return 0;
 }
 
@@ -1725,10 +1850,12 @@ bfd_demangle (bfd *abfd, const char *name, int options)
   char *res, *alloc;
   const char *pre, *suf;
   size_t pre_len;
+  bfd_boolean skip_lead;
 
-  if (abfd != NULL
-      && *name != '\0'
-      && bfd_get_symbol_leading_char (abfd) == *name)
+  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
@@ -1745,7 +1872,7 @@ bfd_demangle (bfd *abfd, const char *name, int options)
   suf = strchr (name, '@');
   if (suf != NULL)
     {
-      alloc = bfd_malloc (suf - name + 1);
+      alloc = (char *) bfd_malloc (suf - name + 1);
       if (alloc == NULL)
        return NULL;
       memcpy (alloc, name, suf - name);
@@ -1759,7 +1886,18 @@ bfd_demangle (bfd *abfd, const char *name, int options)
     free (alloc);
 
   if (res == NULL)
-    return 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)
@@ -1772,13 +1910,13 @@ bfd_demangle (bfd *abfd, const char *name, int options)
       if (suf == NULL)
        suf = res + len;
       suf_len = strlen (suf) + 1;
-      final = bfd_malloc (pre_len + len + suf_len);
-      if (final == NULL)
-       return NULL;
-
-      memcpy (final, pre, pre_len);
-      memcpy (final + pre_len, res, len);
-      memcpy (final + pre_len + len, suf, suf_len);
+      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;
     }