bfd/
[binutils-gdb.git] / bfd / elf-bfd.h
index 3798322c89d0cad376dc4b1aee4c11740b93e866..c91af27639e8bdf8aa075ce4715cea78b9fb59be 100644 (file)
@@ -1,13 +1,13 @@
 /* BFD back-end data structures for ELF files.
    Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
 /* BFD back-end data structures for ELF files.
    Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-   2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   2002, 2003, 2004, 2005, 2006, 2007 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
    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,
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -17,7 +17,8 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
 
    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.  */
 
 #ifndef _LIBELF_H_
 #define _LIBELF_H_ 1
 
 #ifndef _LIBELF_H_
 #define _LIBELF_H_ 1
@@ -263,14 +264,32 @@ struct elf_link_loaded_list
 /* Structures used by the eh_frame optimization code.  */
 struct eh_cie_fde
 {
 /* Structures used by the eh_frame optimization code.  */
 struct eh_cie_fde
 {
-  /* For FDEs, this points to the CIE used.  */
-  struct eh_cie_fde *cie_inf;
+  union {
+    struct {
+      /* If REMOVED == 1, this is the CIE that the FDE originally used.
+        The CIE belongs to the same .eh_frame input section as the FDE.
+
+        If REMOVED == 0, this is the CIE that we have chosen to use for
+        the output FDE.  The CIE's REMOVED field is also 0, but the CIE
+        might belong to a different .eh_frame input section from the FDE.  */
+      struct eh_cie_fde *cie_inf;
+    } fde;
+    struct {
+      /* In general, equivalent CIEs are grouped together, with one CIE
+        representing all the others in a group.  If REMOVED == 0,
+        this CIE is the group representative.  If REMOVED == 1,
+        following this pointer brings us "closer" to the CIE's group
+        representative, and reapplying always gives the representative.  */
+      struct eh_cie_fde *merged;
+    } cie;
+  } u;
+  unsigned int reloc_index;
   unsigned int size;
   unsigned int offset;
   unsigned int new_offset;
   unsigned int size;
   unsigned int offset;
   unsigned int new_offset;
-  unsigned char fde_encoding;
-  unsigned char lsda_encoding;
-  unsigned char lsda_offset;
+  unsigned int fde_encoding : 8;
+  unsigned int lsda_encoding : 8;
+  unsigned int lsda_offset : 8;
   unsigned int cie : 1;
   unsigned int removed : 1;
   unsigned int add_augmentation_size : 1;
   unsigned int cie : 1;
   unsigned int removed : 1;
   unsigned int add_augmentation_size : 1;
@@ -302,6 +321,8 @@ struct eh_frame_hdr_info
   asection *hdr_sec;
   unsigned int fde_count, array_count;
   struct eh_frame_array_ent *array;
   asection *hdr_sec;
   unsigned int fde_count, array_count;
   struct eh_frame_array_ent *array;
+  /* TRUE if all .eh_frames have been parsd.  */
+  bfd_boolean parsed_eh_frames;
   /* TRUE if .eh_frame_hdr should contain the sorted search table.
      We build it if we successfully read all .eh_frame input sections
      and recognize them.  */
   /* TRUE if .eh_frame_hdr should contain the sorted search table.
      We build it if we successfully read all .eh_frame input sections
      and recognize them.  */
@@ -422,7 +443,7 @@ struct sym_sec_cache
 {
   bfd *abfd;
   unsigned long indx[LOCAL_SYM_CACHE_SIZE];
 {
   bfd *abfd;
   unsigned long indx[LOCAL_SYM_CACHE_SIZE];
-  asection *sec[LOCAL_SYM_CACHE_SIZE];
+  unsigned int shndx[LOCAL_SYM_CACHE_SIZE];
 };
 \f
 /* Constant information held for an ELF backend.  */
 };
 \f
 /* Constant information held for an ELF backend.  */
@@ -447,6 +468,8 @@ struct elf_size_info {
     (bfd *, const Elf_Internal_Phdr *, unsigned int);
   bfd_boolean
     (*write_shdrs_and_ehdr) (bfd *);
     (bfd *, const Elf_Internal_Phdr *, unsigned int);
   bfd_boolean
     (*write_shdrs_and_ehdr) (bfd *);
+  bfd_boolean (*checksum_contents)
+    (bfd * , void (*) (const void *, size_t, void *), void *);
   void (*write_relocs)
     (bfd *, asection *, void *);
   bfd_boolean (*swap_symbol_in)
   void (*write_relocs)
     (bfd *, asection *, void *);
   bfd_boolean (*swap_symbol_in)
@@ -538,6 +561,10 @@ enum action_discarded
     PRETEND = 2
   };
 
     PRETEND = 2
   };
 
+typedef asection * (*elf_gc_mark_hook_fn)
+  (asection *, struct bfd_link_info *, Elf_Internal_Rela *,
+   struct elf_link_hash_entry *, Elf_Internal_Sym *);
+
 struct elf_backend_data
 {
   /* The architecture for this backend.  */
 struct elf_backend_data
 {
   /* The architecture for this backend.  */
@@ -546,6 +573,9 @@ struct elf_backend_data
   /* The ELF machine code (EM_xxxx) for this backend.  */
   int elf_machine_code;
 
   /* The ELF machine code (EM_xxxx) for this backend.  */
   int elf_machine_code;
 
+  /* EI_OSABI. */
+  int elf_osabi;
+
   /* The maximum page size for this backend.  */
   bfd_vma maxpagesize;
 
   /* The maximum page size for this backend.  */
   bfd_vma maxpagesize;
 
@@ -690,6 +720,10 @@ struct elf_backend_data
   bfd_boolean (*elf_backend_omit_section_dynsym)
     (bfd *output_bfd, struct bfd_link_info *info, asection *osec);
 
   bfd_boolean (*elf_backend_omit_section_dynsym)
     (bfd *output_bfd, struct bfd_link_info *info, asection *osec);
 
+  /* Return TRUE if relocations of targets are compatible to the extent
+     that CHECK_RELOCS will properly process them.  PR 4424.  */
+  bfd_boolean (*relocs_compatible) (const bfd_target *, const bfd_target *);
+
   /* The CHECK_RELOCS function is called by the add_symbols phase of
      the ELF backend linker.  It is called once for each section with
      relocs of an object file, just after the symbols for the object
   /* The CHECK_RELOCS function is called by the add_symbols phase of
      the ELF backend linker.  It is called once for each section with
      relocs of an object file, just after the symbols for the object
@@ -785,8 +819,11 @@ struct elf_backend_data
      STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
      going to be the section symbol corresponding to the output
      section, which means that the addend must be adjusted
      STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
      going to be the section symbol corresponding to the output
      section, which means that the addend must be adjusted
-     accordingly.  */
-  bfd_boolean (*elf_backend_relocate_section)
+     accordingly.
+
+     Returns FALSE on error, TRUE on success, 2 if successful and
+     relocations should be written for this section.  */
+  int (*elf_backend_relocate_section)
     (bfd *output_bfd, struct bfd_link_info *info, bfd *input_bfd,
      asection *input_section, bfd_byte *contents, Elf_Internal_Rela *relocs,
      Elf_Internal_Sym *local_syms, asection **local_sections);
     (bfd *output_bfd, struct bfd_link_info *info, bfd *input_bfd,
      asection *input_section, bfd_byte *contents, Elf_Internal_Rela *relocs,
      Elf_Internal_Sym *local_syms, asection **local_sections);
@@ -843,9 +880,12 @@ struct elf_backend_data
 
   /* This function is called during section gc to discover the section a
      particular relocation refers to.  */
 
   /* This function is called during section gc to discover the section a
      particular relocation refers to.  */
-  asection * (*gc_mark_hook)
-    (asection *sec, struct bfd_link_info *, Elf_Internal_Rela *,
-     struct elf_link_hash_entry *h, Elf_Internal_Sym *);
+  elf_gc_mark_hook_fn gc_mark_hook;
+
+  /* This function, if defined, is called after the first gc marking pass
+     to allow the backend to mark additional sections.  */
+  bfd_boolean (*gc_mark_extra_sections)
+    (struct bfd_link_info *info, elf_gc_mark_hook_fn gc_mark_hook);
 
   /* This function, if defined, is called during the sweep phase of gc
      in order that a backend might update any data structures it might
 
   /* This function, if defined, is called during the sweep phase of gc
      in order that a backend might update any data structures it might
@@ -937,12 +977,6 @@ struct elf_backend_data
   char *(*elf_backend_write_core_note)
     (bfd *abfd, char *buf, int *bufsiz, int note_type, ...);
 
   char *(*elf_backend_write_core_note)
     (bfd *abfd, char *buf, int *bufsiz, int note_type, ...);
 
-  /* Functions to print VMAs.  Special code to handle 64 bit ELF files.  */
-  void (* elf_backend_sprintf_vma)
-    (bfd *, char *, bfd_vma);
-  void (* elf_backend_fprintf_vma)
-    (bfd *, void *, bfd_vma);
-
   /* This function returns class of a reloc type.  */
   enum elf_reloc_type_class (*elf_backend_reloc_type_class)
     (const Elf_Internal_Rela *);
   /* This function returns class of a reloc type.  */
   enum elf_reloc_type_class (*elf_backend_reloc_type_class)
     (const Elf_Internal_Rela *);
@@ -1040,6 +1074,9 @@ struct elf_backend_data
   /* Return TRUE if symbol should be hashed in the `.gnu.hash' section.  */
   bfd_boolean (*elf_hash_symbol) (struct elf_link_hash_entry *);
 
   /* Return TRUE if symbol should be hashed in the `.gnu.hash' section.  */
   bfd_boolean (*elf_hash_symbol) (struct elf_link_hash_entry *);
 
+  /* Return TRUE if type is a function symbol type.  */
+  bfd_boolean (*is_function_type) (unsigned int type);
+
   /* Used to handle bad SHF_LINK_ORDER input.  */
   bfd_error_handler_type link_order_error_handler;
 
   /* Used to handle bad SHF_LINK_ORDER input.  */
   bfd_error_handler_type link_order_error_handler;
 
@@ -1059,6 +1096,19 @@ struct elf_backend_data
      so-called reserved entries on some systems.  */
   bfd_vma got_header_size;
 
      so-called reserved entries on some systems.  */
   bfd_vma got_header_size;
 
+  /* The vendor name to use for a processor-standard attributes section.  */
+  const char *obj_attrs_vendor;
+
+  /* The section name to use for a processor-standard attributes section.  */
+  const char *obj_attrs_section;
+
+  /* Return 1, 2 or 3 to indicate what type of arguments a
+     processor-specific tag takes.  */
+  int (*obj_attrs_arg_type) (int);
+
+  /* The section type to use for an attributes section.  */
+  unsigned int obj_attrs_section_type;
+
   /* This is TRUE if the linker should act like collect and gather
      global constructors and destructors by name.  This is TRUE for
      MIPS ELF because the Irix 5 tools can not handle the .init
   /* This is TRUE if the linker should act like collect and gather
      global constructors and destructors by name.  This is TRUE for
      MIPS ELF because the Irix 5 tools can not handle the .init
@@ -1106,10 +1156,17 @@ struct elf_backend_data
   unsigned can_refcount : 1;
   unsigned want_got_sym : 1;
   unsigned want_dynbss : 1;
   unsigned can_refcount : 1;
   unsigned want_got_sym : 1;
   unsigned want_dynbss : 1;
-    /* Targets which do not support physical addressing often require
-       that the p_paddr field in the section header to be set to zero.
-       This field indicates whether this behavior is required.  */
+
+  /* Targets which do not support physical addressing often require
+     that the p_paddr field in the section header to be set to zero.
+     This field indicates whether this behavior is required.  */
   unsigned want_p_paddr_set_to_zero : 1;
   unsigned want_p_paddr_set_to_zero : 1;
+
+  /* True if an object file lacking a .note.GNU-stack section
+     should be assumed to be requesting exec stack.  At least one
+     other file in the link needs to have a .note.GNU-stack section
+     for a PT_GNU_STACK segment to be created.  */
+  unsigned default_execstack : 1;
 };
 
 /* Information stored for each BFD section in an ELF file.  This
 };
 
 /* Information stored for each BFD section in an ELF file.  This
@@ -1199,15 +1256,8 @@ struct bfd_elf_section_data
 #define elf_next_in_group(sec) (elf_section_data(sec)->next_in_group)
 #define elf_sec_group(sec)     (elf_section_data(sec)->sec_group)
 
 #define elf_next_in_group(sec) (elf_section_data(sec)->next_in_group)
 #define elf_sec_group(sec)     (elf_section_data(sec)->sec_group)
 
-/* Return TRUE if section has been discarded.  */
-#define elf_discarded_section(sec)                             \
-  (!bfd_is_abs_section (sec)                                   \
-   && bfd_is_abs_section ((sec)->output_section)               \
-   && (sec)->sec_info_type != ELF_INFO_TYPE_MERGE              \
-   && (sec)->sec_info_type != ELF_INFO_TYPE_JUST_SYMS)
-
 #define xvec_get_elf_backend_data(xvec) \
 #define xvec_get_elf_backend_data(xvec) \
-  ((struct elf_backend_data *) (xvec)->backend_data)
+  ((const struct elf_backend_data *) (xvec)->backend_data)
 
 #define get_elf_backend_data(abfd) \
    xvec_get_elf_backend_data ((abfd)->xvec)
 
 #define get_elf_backend_data(abfd) \
    xvec_get_elf_backend_data ((abfd)->xvec)
@@ -1252,6 +1302,46 @@ struct elf_find_verdep_info
   bfd_boolean failed;
 };
 
   bfd_boolean failed;
 };
 
+/* The maximum number of known object attributes for any target.  */
+#define NUM_KNOWN_OBJ_ATTRIBUTES 32
+
+/* The value of an object attribute.  type & 1 indicates whether there
+   is an integer value; type & 2 indicates whether there is a string
+   value.  */
+
+typedef struct obj_attribute
+{
+  int type;
+  unsigned int i;
+  char *s;
+} obj_attribute;
+
+typedef struct obj_attribute_list
+{
+  struct obj_attribute_list *next;
+  int tag;
+  obj_attribute attr;
+} obj_attribute_list;
+
+/* Object attributes may either be defined by the processor ABI, index
+   OBJ_ATTR_PROC in the *_obj_attributes arrays, or be GNU-specific
+   (and possibly also processor-specific), index OBJ_ATTR_GNU.  */
+#define OBJ_ATTR_PROC 0
+#define OBJ_ATTR_GNU 1
+#define OBJ_ATTR_FIRST OBJ_ATTR_PROC
+#define OBJ_ATTR_LAST OBJ_ATTR_GNU
+
+/* The following object attribute tags are taken as generic, for all
+   targets and for "gnu" where there is no target standard.  */
+enum
+{
+  Tag_NULL = 0,
+  Tag_File = 1,
+  Tag_Section = 2,
+  Tag_Symbol = 3,
+  Tag_compatibility = 32
+};
+
 /* Some private data is stashed away for future use using the tdata pointer
    in the bfd structure.  */
 
 /* Some private data is stashed away for future use using the tdata pointer
    in the bfd structure.  */
 
@@ -1356,9 +1446,6 @@ struct elf_obj_tdata
   /* Segment flags for the PT_GNU_STACK segment.  */
   unsigned int stack_flags;
 
   /* Segment flags for the PT_GNU_STACK segment.  */
   unsigned int stack_flags;
 
-  /* Should the PT_GNU_RELRO segment be emitted?  */
-  bfd_boolean relro;
-
   /* Symbol version definitions in external objects.  */
   Elf_Internal_Verdef *verdef;
 
   /* Symbol version definitions in external objects.  */
   Elf_Internal_Verdef *verdef;
 
@@ -1392,7 +1479,18 @@ struct elf_obj_tdata
   bfd_boolean flags_init;
 
   /* Symbol buffer.  */
   bfd_boolean flags_init;
 
   /* Symbol buffer.  */
-  Elf_Internal_Sym *symbuf;
+  void *symbuf;
+
+  obj_attribute known_obj_attributes[2][NUM_KNOWN_OBJ_ATTRIBUTES];
+  obj_attribute_list *other_obj_attributes[2];
+
+  /* Called at the end of _bfd_elf_write_object_contents if not NULL.  */
+  bfd_boolean (*after_write_object_contents) (bfd *);
+  void *after_write_object_contents_info;
+
+  /* NT_GNU_BUILD_ID note type.  */
+  bfd_size_type build_id_size;
+  bfd_byte *build_id;
 };
 
 #define elf_tdata(bfd)         ((bfd) -> tdata.elf_obj_data)
 };
 
 #define elf_tdata(bfd)         ((bfd) -> tdata.elf_obj_data)
@@ -1422,6 +1520,12 @@ struct elf_obj_tdata
 #define elf_dyn_lib_class(bfd) (elf_tdata(bfd) -> dyn_lib_class)
 #define elf_bad_symtab(bfd)    (elf_tdata(bfd) -> bad_symtab)
 #define elf_flags_init(bfd)    (elf_tdata(bfd) -> flags_init)
 #define elf_dyn_lib_class(bfd) (elf_tdata(bfd) -> dyn_lib_class)
 #define elf_bad_symtab(bfd)    (elf_tdata(bfd) -> bad_symtab)
 #define elf_flags_init(bfd)    (elf_tdata(bfd) -> flags_init)
+#define elf_known_obj_attributes(bfd) (elf_tdata (bfd) -> known_obj_attributes)
+#define elf_other_obj_attributes(bfd) (elf_tdata (bfd) -> other_obj_attributes)
+#define elf_known_obj_attributes_proc(bfd) \
+  (elf_known_obj_attributes (bfd) [OBJ_ATTR_PROC])
+#define elf_other_obj_attributes_proc(bfd) \
+  (elf_other_obj_attributes (bfd) [OBJ_ATTR_PROC])
 \f
 extern void _bfd_elf_swap_verdef_in
   (bfd *, const Elf_External_Verdef *, Elf_Internal_Verdef *);
 \f
 extern void _bfd_elf_swap_verdef_in
   (bfd *, const Elf_External_Verdef *, Elf_Internal_Verdef *);
@@ -1463,11 +1567,6 @@ extern bfd_boolean _bfd_elf_print_private_bfd_data
 extern void bfd_elf_print_symbol
   (bfd *, void *, asymbol *, bfd_print_symbol_type);
 
 extern void bfd_elf_print_symbol
   (bfd *, void *, asymbol *, bfd_print_symbol_type);
 
-extern void _bfd_elf_sprintf_vma
-  (bfd *, char *, bfd_vma);
-extern void _bfd_elf_fprintf_vma
-  (bfd *, void *, bfd_vma);
-
 extern unsigned int _bfd_elf_eh_frame_address_size
   (bfd *, asection *);
 extern bfd_byte _bfd_elf_encode_eh_address
 extern unsigned int _bfd_elf_eh_frame_address_size
   (bfd *, asection *);
 extern bfd_byte _bfd_elf_encode_eh_address
@@ -1639,6 +1738,13 @@ extern bfd_boolean _bfd_elf_strtab_emit
 extern void _bfd_elf_strtab_finalize
   (struct elf_strtab_hash *);
 
 extern void _bfd_elf_strtab_finalize
   (struct elf_strtab_hash *);
 
+extern void _bfd_elf_begin_eh_frame_parsing
+  (struct bfd_link_info *info);
+extern void _bfd_elf_parse_eh_frame
+  (bfd *, struct bfd_link_info *, asection *, struct elf_reloc_cookie *);
+extern void _bfd_elf_end_eh_frame_parsing
+  (struct bfd_link_info *info);
+
 extern bfd_boolean _bfd_elf_discard_section_eh_frame
   (bfd *, struct bfd_link_info *, asection *,
    bfd_boolean (*) (bfd_vma, void *), struct elf_reloc_cookie *);
 extern bfd_boolean _bfd_elf_discard_section_eh_frame
   (bfd *, struct bfd_link_info *, asection *,
    bfd_boolean (*) (bfd_vma, void *), struct elf_reloc_cookie *);
@@ -1723,6 +1829,9 @@ extern bfd_boolean _bfd_elf_fix_symbol_flags
 extern bfd_boolean _bfd_elf_adjust_dynamic_symbol
   (struct elf_link_hash_entry *, void *);
 
 extern bfd_boolean _bfd_elf_adjust_dynamic_symbol
   (struct elf_link_hash_entry *, void *);
 
+extern bfd_boolean _bfd_elf_adjust_dynamic_copy
+  (struct elf_link_hash_entry *, asection *);
+
 extern bfd_boolean _bfd_elf_link_sec_merge_syms
   (struct elf_link_hash_entry *, void *);
 
 extern bfd_boolean _bfd_elf_link_sec_merge_syms
   (struct elf_link_hash_entry *, void *);
 
@@ -1732,12 +1841,14 @@ extern bfd_boolean _bfd_elf_dynamic_symbol_p
 extern bfd_boolean _bfd_elf_symbol_refs_local_p
   (struct elf_link_hash_entry *, struct bfd_link_info *, bfd_boolean);
 
 extern bfd_boolean _bfd_elf_symbol_refs_local_p
   (struct elf_link_hash_entry *, struct bfd_link_info *, bfd_boolean);
 
-extern bfd_boolean bfd_elf_match_symbols_in_sections
-  (asection *, asection *, struct bfd_link_info *);
+extern bfd_reloc_status_type bfd_elf_perform_complex_relocation
+  (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, bfd_vma);
 
 extern bfd_boolean _bfd_elf_setup_sections
   (bfd *);
 
 
 extern bfd_boolean _bfd_elf_setup_sections
   (bfd *);
 
+extern void _bfd_elf_set_osabi (bfd * , struct bfd_link_info *);
+
 extern const bfd_target *bfd_elf32_object_p
   (bfd *);
 extern const bfd_target *bfd_elf32_core_file_p
 extern const bfd_target *bfd_elf32_object_p
   (bfd *);
 extern const bfd_target *bfd_elf32_core_file_p
@@ -1775,6 +1886,8 @@ extern bfd_boolean bfd_elf32_write_shdrs_and_ehdr
   (bfd *);
 extern int bfd_elf32_write_out_phdrs
   (bfd *, const Elf_Internal_Phdr *, unsigned int);
   (bfd *);
 extern int bfd_elf32_write_out_phdrs
   (bfd *, const Elf_Internal_Phdr *, unsigned int);
+extern bfd_boolean bfd_elf32_checksum_contents
+  (bfd * , void (*) (const void *, size_t, void *), void *);
 extern void bfd_elf32_write_relocs
   (bfd *, asection *, void *);
 extern bfd_boolean bfd_elf32_slurp_reloc_table
 extern void bfd_elf32_write_relocs
   (bfd *, asection *, void *);
 extern bfd_boolean bfd_elf32_slurp_reloc_table
@@ -1817,11 +1930,19 @@ extern bfd_boolean bfd_elf64_write_shdrs_and_ehdr
   (bfd *);
 extern int bfd_elf64_write_out_phdrs
   (bfd *, const Elf_Internal_Phdr *, unsigned int);
   (bfd *);
 extern int bfd_elf64_write_out_phdrs
   (bfd *, const Elf_Internal_Phdr *, unsigned int);
+extern bfd_boolean bfd_elf64_checksum_contents
+  (bfd * , void (*) (const void *, size_t, void *), void *);
 extern void bfd_elf64_write_relocs
   (bfd *, asection *, void *);
 extern bfd_boolean bfd_elf64_slurp_reloc_table
   (bfd *, asection *, asymbol **, bfd_boolean);
 
 extern void bfd_elf64_write_relocs
   (bfd *, asection *, void *);
 extern bfd_boolean bfd_elf64_slurp_reloc_table
   (bfd *, asection *, asymbol **, bfd_boolean);
 
+extern bfd_boolean _bfd_elf_default_relocs_compatible
+  (const bfd_target *, const bfd_target *);
+
+extern bfd_boolean _bfd_elf_relocs_compatible
+  (const bfd_target *, const bfd_target *);
+
 extern struct elf_link_hash_entry *_bfd_elf_archive_symbol_lookup
   (bfd *, struct bfd_link_info *, const char *);
 extern bfd_boolean bfd_elf_link_add_symbols
 extern struct elf_link_hash_entry *_bfd_elf_archive_symbol_lookup
   (bfd *, struct bfd_link_info *, const char *);
 extern bfd_boolean bfd_elf_link_add_symbols
@@ -1877,10 +1998,16 @@ extern asection *_bfd_elf_gc_mark_hook
   (asection *, struct bfd_link_info *, Elf_Internal_Rela *,
    struct elf_link_hash_entry *, Elf_Internal_Sym *);
 
   (asection *, struct bfd_link_info *, Elf_Internal_Rela *,
    struct elf_link_hash_entry *, Elf_Internal_Sym *);
 
+extern asection *_bfd_elf_gc_mark_rsec
+  (struct bfd_link_info *, asection *, elf_gc_mark_hook_fn,
+   struct elf_reloc_cookie *);
+
+extern bfd_boolean _bfd_elf_gc_mark_reloc
+  (struct bfd_link_info *, asection *, elf_gc_mark_hook_fn,
+   struct elf_reloc_cookie *, bfd_boolean);
+
 extern bfd_boolean _bfd_elf_gc_mark
 extern bfd_boolean _bfd_elf_gc_mark
-  (struct bfd_link_info *, asection *,
-   asection * (*) (asection *, struct bfd_link_info *, Elf_Internal_Rela *,
-                  struct elf_link_hash_entry *, Elf_Internal_Sym *));
+  (struct bfd_link_info *, asection *, elf_gc_mark_hook_fn);
 
 extern bfd_boolean bfd_elf_gc_common_finalize_got_offsets
   (bfd *, struct bfd_link_info *);
 
 extern bfd_boolean bfd_elf_gc_common_finalize_got_offsets
   (bfd *, struct bfd_link_info *);
@@ -1897,6 +2024,8 @@ extern struct elf_segment_map * _bfd_elf_make_dynamic_segment
 extern bfd_boolean _bfd_elf_map_sections_to_segments
   (bfd *, struct bfd_link_info *);
 
 extern bfd_boolean _bfd_elf_map_sections_to_segments
   (bfd *, struct bfd_link_info *);
 
+extern bfd_boolean _bfd_elf_is_function_type (unsigned int);
+
 /* Exported interface for writing elf corefile notes. */
 extern char *elfcore_write_note
   (bfd *, char *, int *, const char *, int, const void *, int);
 /* Exported interface for writing elf corefile notes. */
 extern char *elfcore_write_note
   (bfd *, char *, int *, const char *, int, const void *, int);
@@ -1910,6 +2039,8 @@ extern char *elfcore_write_prfpreg
   (bfd *, char *, int *, const void *, int);
 extern char *elfcore_write_prxfpreg
   (bfd *, char *, int *, const void *, int);
   (bfd *, char *, int *, const void *, int);
 extern char *elfcore_write_prxfpreg
   (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_ppc_vmx
+  (bfd *, char *, int *, const void *, int);
 extern char *elfcore_write_lwpstatus
   (bfd *, char *, int *, long, int, const void *);
 
 extern char *elfcore_write_lwpstatus
   (bfd *, char *, int *, long, int, const void *);
 
@@ -1920,6 +2051,26 @@ extern bfd *_bfd_elf64_bfd_from_remote_memory
   (bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep,
    int (*target_read_memory) (bfd_vma, bfd_byte *, int));
 
   (bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep,
    int (*target_read_memory) (bfd_vma, bfd_byte *, int));
 
+extern bfd_vma bfd_elf_obj_attr_size (bfd *);
+extern void bfd_elf_set_obj_attr_contents (bfd *, bfd_byte *, bfd_vma);
+extern int bfd_elf_get_obj_attr_int (bfd *, int, int);
+extern void bfd_elf_add_obj_attr_int (bfd *, int, int, unsigned int);
+#define bfd_elf_add_proc_attr_int(BFD, TAG, VALUE) \
+  bfd_elf_add_obj_attr_int ((BFD), OBJ_ATTR_PROC, (TAG), (VALUE))
+extern void bfd_elf_add_obj_attr_string (bfd *, int, int, const char *);
+#define bfd_elf_add_proc_attr_string(BFD, TAG, VALUE) \
+  bfd_elf_add_obj_attr_string ((BFD), OBJ_ATTR_PROC, (TAG), (VALUE))
+extern void bfd_elf_add_obj_attr_compat (bfd *, int, unsigned int,
+                                        const char *);
+#define bfd_elf_add_proc_attr_compat(BFD, INTVAL, STRVAL) \
+  bfd_elf_add_obj_attr_compat ((BFD), OBJ_ATTR_PROC, (INTVAL), (STRVAL))
+
+extern char *_bfd_elf_attr_strdup (bfd *, const char *);
+extern void _bfd_elf_copy_obj_attributes (bfd *, bfd *);
+extern int _bfd_elf_obj_attrs_arg_type (bfd *, int, int);
+extern void _bfd_elf_parse_attributes (bfd *, Elf_Internal_Shdr *);
+extern bfd_boolean _bfd_elf_merge_object_attributes (bfd *, bfd *);
+
 /* Large common section.  */
 extern asection _bfd_elf_large_com_section;
 
 /* Large common section.  */
 extern asection _bfd_elf_large_com_section;
 
@@ -1979,7 +2130,7 @@ extern bfd_boolean _sh_elf_set_mach_from_flags
       else if (info->unresolved_syms_in_objects == RM_IGNORE           \
               && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)          \
        ;                                                               \
       else if (info->unresolved_syms_in_objects == RM_IGNORE           \
               && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)          \
        ;                                                               \
-      else                                                             \
+      else if (!info->relocatable)                                     \
        {                                                               \
          bfd_boolean err;                                              \
          err = (info->unresolved_syms_in_objects == RM_GENERATE_ERROR  \
        {                                                               \
          bfd_boolean err;                                              \
          err = (info->unresolved_syms_in_objects == RM_GENERATE_ERROR  \