bfd/elf-ifunc.c: Add header size arg to _bfd_elf_allocate_ifunc_dyn_relocs.
[binutils-gdb.git] / bfd / elf-bfd.h
index c0d8c8a40e564808a54e10258ba952d15dd381ab..4a67d02198bb5bf11453e62c86308469c88adcc4 100644 (file)
@@ -1,7 +1,5 @@
 /* BFD back-end data structures for ELF files.
-   Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-   2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
-   Free Software Foundation, Inc.
+   Copyright 1992-2013 Free Software Foundation, Inc.
    Written by Cygnus Support.
 
    This file is part of BFD, the Binary File Descriptor library.
 
 /* The number of entries in a section is its size divided by the size
    of a single entry.  This is normally only applicable to reloc and
-   symbol table sections.  */
-#define NUM_SHDR_ENTRIES(shdr) ((shdr)->sh_size / (shdr)->sh_entsize)
+   symbol table sections.
+   PR 9934: It is possible to have relocations that do not refer to
+   symbols, thus it is also possible to have a relocation section in
+   an object file, but no symbol table.  */
+#define NUM_SHDR_ENTRIES(shdr) ((shdr)->sh_entsize > 0 ? (shdr)->sh_size / (shdr)->sh_entsize : 0)
 
 /* If size isn't specified as 64 or 32, NAME macro should fail.  */
 #ifndef NAME
@@ -82,6 +83,27 @@ struct elf_strtab_hash;
 struct got_entry;
 struct plt_entry;
 
+union gotplt_union
+  {
+    bfd_signed_vma refcount;
+    bfd_vma offset;
+    struct got_entry *glist;
+    struct plt_entry *plist;
+  };
+
+struct elf_link_virtual_table_entry
+  {
+    /* Virtual table entry use information.  This array is nominally of size
+       size/sizeof(target_void_pointer), though we have to be able to assume
+       and track a size while the symbol is still undefined.  It is indexed
+       via offset/sizeof(target_void_pointer).  */
+    size_t size;
+    bfd_boolean *used;
+
+    /* Virtual table derivation info.  */
+    struct elf_link_hash_entry *parent;
+  };
+
 /* ELF linker hash table entries.  */
 
 struct elf_link_hash_entry
@@ -115,13 +137,7 @@ struct elf_link_hash_entry
      require a global offset table entry.  The second scheme allows
      multiple GOT entries per symbol, managed via a linked list
      pointed to by GLIST.  */
-  union gotplt_union
-    {
-      bfd_signed_vma refcount;
-      bfd_vma offset;
-      struct got_entry *glist;
-      struct plt_entry *plist;
-    } got;
+  union gotplt_union got;
 
   /* Same, but tracks a procedure linkage table entry.  */
   union gotplt_union plt;
@@ -135,7 +151,11 @@ struct elf_link_hash_entry
   /* Symbol st_other value, symbol visibility.  */
   unsigned int other : 8;
 
-  /* Symbol is referenced by a non-shared object.  */
+  /* The symbol's st_target_internal value (see Elf_Internal_Sym).  */
+  unsigned int target_internal : 8;
+
+  /* Symbol is referenced by a non-shared object (other than the object
+     in which it is defined).  */
   unsigned int ref_regular : 1;
   /* Symbol is defined by a non-shared object.  */
   unsigned int def_regular : 1;
@@ -143,7 +163,8 @@ struct elf_link_hash_entry
   unsigned int ref_dynamic : 1;
   /* Symbol is defined by a shared object.  */
   unsigned int def_dynamic : 1;
-  /* Symbol has a non-weak reference from a non-shared object.  */
+  /* Symbol has a non-weak reference from a non-shared object (other than
+     the object in which it is defined).  */
   unsigned int ref_regular_nonweak : 1;
   /* Dynamic symbol has been adjustd.  */
   unsigned int dynamic_adjusted : 1;
@@ -168,11 +189,13 @@ struct elf_link_hash_entry
      FIXME: There is no real need for this field if def_dynamic is never
      cleared and all places that test def_dynamic also test def_regular.  */
   unsigned int dynamic_def : 1;
-  /* Symbol is weak in all shared objects.  */
-  unsigned int dynamic_weak : 1;
+  /* Symbol has a non-weak reference from a shared object.  */
+  unsigned int ref_dynamic_nonweak : 1;
   /* Symbol is referenced with a relocation where C/C++ pointer equality
      matters.  */
   unsigned int pointer_equality_needed : 1;
+  /* Symbol is a unique global symbol.  */
+  unsigned int unique_global : 1;
 
   /* String table index in .dynstr if this is a dynamic symbol.  */
   unsigned long dynstr_index;
@@ -203,26 +226,11 @@ struct elf_link_hash_entry
     struct bfd_elf_version_tree *vertree;
   } verinfo;
 
-  struct
-  {
-    /* Virtual table entry use information.  This array is nominally of size
-       size/sizeof(target_void_pointer), though we have to be able to assume
-       and track a size while the symbol is still undefined.  It is indexed
-       via offset/sizeof(target_void_pointer).  */
-    size_t size;
-    bfd_boolean *used;
-
-    /* Virtual table derivation info.  */
-    struct elf_link_hash_entry *parent;
-  } *vtable;
+  struct elf_link_virtual_table_entry *vtable;
 };
 
 /* Will references to this symbol always reference the symbol
-   in this object?  STV_PROTECTED is excluded from the visibility test
-   here so that function pointer comparisons work properly.  Since
-   function symbols not defined in an app are set to their .plt entry,
-   it's necessary for shared libs to also reference the .plt even
-   though the symbol is really local to the shared lib.  */
+   in this object?  */
 #define SYMBOL_REFERENCES_LOCAL(INFO, H) \
   _bfd_elf_symbol_refs_local_p (H, INFO, 0)
 
@@ -294,6 +302,10 @@ struct eh_cie_fde
        asection *sec;
       } u;
 
+      /* The offset of the personality data from the start of the CIE,
+        or 0 if the CIE doesn't have any.  */
+      unsigned int personality_offset : 8;
+
       /* True if we have marked relocations associated with this CIE.  */
       unsigned int gc_mark : 1;
 
@@ -301,8 +313,13 @@ struct eh_cie_fde
         a PC-relative one.  */
       unsigned int make_lsda_relative : 1;
 
-      /* True if the CIE contains personality data and if that data
-        uses a PC-relative encoding.  */
+      /* True if we have decided to turn an absolute personality
+        encoding into a PC-relative one.  */
+      unsigned int make_per_encoding_relative : 1;
+
+      /* True if the CIE contains personality data and if that
+        data uses a PC-relative encoding.  Always true when
+        make_per_encoding_relative is.  */
       unsigned int per_encoding_relative : 1;
 
       /* True if we need to add an 'R' (FDE encoding) entry to the
@@ -311,6 +328,9 @@ struct eh_cie_fde
 
       /* True if we have merged this CIE with another.  */
       unsigned int merged : 1;
+
+      /* Unused bits.  */
+      unsigned int pad1 : 18;
     } cie;
   } u;
   unsigned int reloc_index;
@@ -373,12 +393,58 @@ struct eh_frame_hdr_info
   bfd_boolean table;
 };
 
+/* Enum used to identify target specific extensions to the elf_obj_tdata
+   and elf_link_hash_table structures.  Note the enums deliberately start
+   from 1 so that we can detect an uninitialized field.  The generic value
+   is last so that additions to this enum do not need to modify more than
+   one line.  */
+enum elf_target_id
+{
+  AARCH64_ELF_DATA = 1,
+  ALPHA_ELF_DATA,
+  ARM_ELF_DATA,
+  AVR_ELF_DATA,
+  BFIN_ELF_DATA,
+  CRIS_ELF_DATA,
+  FRV_ELF_DATA,
+  HPPA32_ELF_DATA,
+  HPPA64_ELF_DATA,
+  I386_ELF_DATA,
+  IA64_ELF_DATA,
+  LM32_ELF_DATA,
+  M32R_ELF_DATA,
+  M68HC11_ELF_DATA,
+  M68K_ELF_DATA,
+  METAG_ELF_DATA,
+  MICROBLAZE_ELF_DATA,
+  MIPS_ELF_DATA,
+  MN10300_ELF_DATA,
+  NIOS2_ELF_DATA,
+  PPC32_ELF_DATA,
+  PPC64_ELF_DATA,
+  S390_ELF_DATA,
+  SH_ELF_DATA,
+  SPARC_ELF_DATA,
+  SPU_ELF_DATA,
+  TIC6X_ELF_DATA,
+  X86_64_ELF_DATA,
+  XTENSA_ELF_DATA,
+  XGATE_ELF_DATA,
+  TILEGX_ELF_DATA,
+  TILEPRO_ELF_DATA,
+  GENERIC_ELF_DATA
+};
+
 /* ELF linker hash table.  */
 
 struct elf_link_hash_table
 {
   struct bfd_link_hash_table root;
 
+  /* An identifier used to distinguish different target
+     specific extensions to this structure.  */
+  enum elf_target_id hash_table_id;
+
   /* Whether we have created the special dynamic sections required
      when linking against or generating a shared object.  */
   bfd_boolean dynamic_sections_created;
@@ -432,6 +498,9 @@ struct elf_link_hash_table
   /* The _PROCEDURE_LINKAGE_TABLE_ symbol.  */
   struct elf_link_hash_entry *hplt;
 
+  /* The _DYNAMIC symbol.  */
+  struct elf_link_hash_entry *hdynamic;
+
   /* A pointer to information used to merge SEC_MERGE sections.  */
   void *merge_info;
 
@@ -454,6 +523,17 @@ struct elf_link_hash_table
 
   /* A linked list of BFD's loaded in the link.  */
   struct elf_link_loaded_list *loaded;
+
+  /* Short-cuts to get to dynamic linker sections.  */
+  asection *sgot;
+  asection *sgotplt;
+  asection *srelgot;
+  asection *splt;
+  asection *srelplt;
+  asection *igotplt;
+  asection *iplt;
+  asection *irelplt;
+  asection *irelifunc;
 };
 
 /* Look up an entry in an ELF linker hash table.  */
@@ -475,18 +555,20 @@ struct elf_link_hash_table
 
 #define elf_hash_table(p) ((struct elf_link_hash_table *) ((p)->hash))
 
+#define elf_hash_table_id(table)       ((table) -> hash_table_id)
+
 /* Returns TRUE if the hash table is a struct elf_link_hash_table.  */
 #define is_elf_hash_table(htab)                                                \
   (((struct bfd_link_hash_table *) (htab))->type == bfd_link_elf_hash_table)
 
-/* Used by bfd_section_from_r_symndx to cache a small number of local
-   symbol to section mappings.  */
+/* Used by bfd_sym_from_r_symndx to cache a small number of local
+   symbols.  */
 #define LOCAL_SYM_CACHE_SIZE 32
-struct sym_sec_cache
+struct sym_cache
 {
   bfd *abfd;
   unsigned long indx[LOCAL_SYM_CACHE_SIZE];
-  unsigned int shndx[LOCAL_SYM_CACHE_SIZE];
+  Elf_Internal_Sym sym[LOCAL_SYM_CACHE_SIZE];
 };
 \f
 /* Constant information held for an ELF backend.  */
@@ -559,7 +641,8 @@ enum elf_reloc_type_class {
   reloc_class_normal,
   reloc_class_relative,
   reloc_class_plt,
-  reloc_class_copy
+  reloc_class_copy,
+  reloc_class_ifunc
 };
 
 struct elf_reloc_cookie
@@ -613,6 +696,10 @@ struct elf_backend_data
   /* The architecture for this backend.  */
   enum bfd_architecture arch;
 
+  /* An identifier used to distinguish different target specific
+     extensions to elf_obj_tdata and elf_link_hash_table structures.  */
+  enum elf_target_id target_id;
+
   /* The ELF machine code (EM_xxxx) for this backend.  */
   int elf_machine_code;
 
@@ -633,6 +720,10 @@ struct elf_backend_data
   /* The BFD flags applied to sections created for dynamic linking.  */
   flagword dynamic_sec_flags;
 
+  /* Architecture-specific data for this backend.
+     This is actually a pointer to some type like struct elf_ARCH_data.  */
+  const void *arch_data;
+
   /* A function to translate an ELF RELA relocation to a BFD arelent
      structure.  */
   void (*elf_info_to_howto)
@@ -742,8 +833,10 @@ struct elf_backend_data
      const char **name, flagword *flags, asection **sec, bfd_vma *value);
 
   /* If this field is not NULL, it is called by the elf_link_output_sym
-     phase of a link for each symbol which will appear in the object file.  */
-  bfd_boolean (*elf_backend_link_output_symbol_hook)
+     phase of a link for each symbol which will appear in the object file.
+     On error, this function returns 0.  1 is returned when the symbol
+     should be output, 2 is returned when the symbol should be discarded.  */
+  int (*elf_backend_link_output_symbol_hook)
     (struct bfd_link_info *info, const char *, Elf_Internal_Sym *,
      asection *, struct elf_link_hash_entry *);
 
@@ -1029,9 +1122,14 @@ struct elf_backend_data
   char *(*elf_backend_write_core_note)
     (bfd *abfd, char *buf, int *bufsiz, int note_type, ...);
 
+  /* This function, if defined, is called to convert target-specific
+     section flag names into hex values.  */
+  flagword (*elf_backend_lookup_section_flags_hook)
+    (char *);
+
   /* This function returns class of a reloc type.  */
   enum elf_reloc_type_class (*elf_backend_reloc_type_class)
-    (const Elf_Internal_Rela *);
+  (const struct bfd_link_info *, const asection *, const Elf_Internal_Rela *);
 
   /* This function, if defined, removes information about discarded functions
      from other sections which mention them.  */
@@ -1093,7 +1191,8 @@ struct elf_backend_data
      see elf.c, elfcode.h.  */
   bfd *(*elf_backend_bfd_from_remote_memory)
      (bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep,
-      int (*target_read_memory) (bfd_vma vma, bfd_byte *myaddr, int len));
+      int (*target_read_memory) (bfd_vma vma, bfd_byte *myaddr,
+                                bfd_size_type len));
 
   /* This function is used by `_bfd_elf_get_synthetic_symtab';
      see elf.c.  */
@@ -1109,19 +1208,10 @@ struct elf_backend_data
   asection *(*common_section) (asection *);
 
   /* Return TRUE if we can merge 2 definitions.  */
-  bfd_boolean (*merge_symbol) (struct bfd_link_info *,
-                              struct elf_link_hash_entry **,
-                              struct elf_link_hash_entry *,
-                              Elf_Internal_Sym *, asection **,
-                              bfd_vma *, unsigned int *,
-                              bfd_boolean *, bfd_boolean *,
-                              bfd_boolean *, bfd_boolean *,
-                              bfd_boolean *, bfd_boolean *,
-                              bfd_boolean *, bfd_boolean *,
-                              bfd *, asection **,
-                              bfd_boolean *, bfd_boolean *,
-                              bfd_boolean *, bfd_boolean *,
-                              bfd *, asection **);
+  bfd_boolean (*merge_symbol) (struct elf_link_hash_entry *,
+                              const Elf_Internal_Sym *, asection **,
+                              bfd_boolean, bfd_boolean,
+                              bfd *, const asection *);
 
   /* Return TRUE if symbol should be hashed in the `.gnu.hash' section.  */
   bfd_boolean (*elf_hash_symbol) (struct elf_link_hash_entry *);
@@ -1129,6 +1219,12 @@ struct elf_backend_data
   /* Return TRUE if type is a function symbol type.  */
   bfd_boolean (*is_function_type) (unsigned int type);
 
+  /* If the ELF symbol SYM might be a function in SEC, return the
+     function size and set *CODE_OFF to the function's entry point,
+     otherwise return zero.  */
+  bfd_size_type (*maybe_function_sym) (const asymbol *sym, asection *sec,
+                                      bfd_vma *code_off);
+
   /* Used to handle bad SHF_LINK_ORDER input.  */
   bfd_error_handler_type link_order_error_handler;
 
@@ -1167,6 +1263,23 @@ struct elf_backend_data
   /* The section type to use for an attributes section.  */
   unsigned int obj_attrs_section_type;
 
+  /* This function determines the order in which any attributes are
+     written.  It must be defined for input in the range
+     LEAST_KNOWN_OBJ_ATTRIBUTE..NUM_KNOWN_OBJ_ATTRIBUTES-1 (this range
+     is used in order to make unity easy).  The returned value is the
+     actual tag number to place in the input position.  */
+  int (*obj_attrs_order) (int);
+
+  /* Handle merging unknown attributes; either warn and return TRUE,
+     or give an error and return FALSE.  */
+  bfd_boolean (*obj_attrs_handle_unknown) (bfd *, int);
+
+  /* This is non-zero if static TLS segments require a special alignment.  */
+  unsigned static_tls_alignment;
+
+  /* Alignment for the PT_GNU_STACK segment. */
+  unsigned stack_align;
+
   /* 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
@@ -1230,6 +1343,23 @@ struct elf_backend_data
   unsigned default_execstack : 1;
 };
 
+/* Information about reloc sections associated with a bfd_elf_section_data
+   structure.  */
+struct bfd_elf_section_reloc_data
+{
+  /* The ELF header for the reloc section associated with this
+     section, if any.  */
+  Elf_Internal_Shdr *hdr;
+  /* The number of relocations currently assigned to HDR.  */
+  unsigned int count;
+  /* The ELF section number of the reloc section.  Only used for an
+     output file.  */
+  int idx;
+  /* Used by the backend linker to store the symbol hash table entries
+     associated with relocs against global symbols.  */
+  struct elf_link_hash_entry **hashes;
+};
+
 /* Information stored for each BFD section in an ELF file.  This
    structure is allocated by elf_new_section_hook.  */
 
@@ -1238,31 +1368,16 @@ struct bfd_elf_section_data
   /* The ELF header for this section.  */
   Elf_Internal_Shdr this_hdr;
 
-  /* The ELF header for the reloc section associated with this
-     section, if any.  */
-  Elf_Internal_Shdr rel_hdr;
-
-  /* If there is a second reloc section associated with this section,
-     as can happen on Irix 6, this field points to the header.  */
-  Elf_Internal_Shdr *rel_hdr2;
+  /* INPUT_SECTION_FLAGS if specified in the linker script.  */
+  struct flag_info *section_flag_info;
 
-  /* The number of relocations currently assigned to REL_HDR.  */
-  unsigned int rel_count;
-
-  /* The number of relocations currently assigned to REL_HDR2.  */
-  unsigned int rel_count2;
+  /* Information about the REL and RELA reloc sections associated
+     with this section, if any.  */
+  struct bfd_elf_section_reloc_data rel, rela;
 
   /* The ELF section number of this section.  */
   int this_idx;
 
-  /* The ELF section number of the reloc section indicated by
-     REL_HDR if any.  Only used for an output file.  */
-  int rel_idx;
-
-  /* The ELF section number of the reloc section indicated by
-     REL_HDR2 if any.  Only used for an output file.  */
-  int rel_idx2;
-
   /* Used by the backend linker when generating a shared library to
      record the dynamic symbol index for a section symbol
      corresponding to this section.  A value of 0 means that there is
@@ -1272,10 +1387,6 @@ struct bfd_elf_section_data
   /* A pointer to the linked-to section for SHF_LINK_ORDER.  */
   asection *linked_to;
 
-  /* Used by the backend linker to store the symbol hash table entries
-     associated with relocs against global symbols.  */
-  struct elf_link_hash_entry **rel_hashes;
-
   /* A pointer to the swapped relocs.  If the section uses REL relocs,
      rather than RELA, all the r_addend fields will be zero.  This
      pointer may be NULL.  It is used by the backend linker.  */
@@ -1312,14 +1423,14 @@ struct bfd_elf_section_data
   void *sec_info;
 };
 
-#define elf_section_data(sec)  ((struct bfd_elf_section_data*)(sec)->used_by_bfd)
+#define elf_section_data(sec) ((struct bfd_elf_section_data*)(sec)->used_by_bfd)
 #define elf_linked_to_section(sec) (elf_section_data(sec)->linked_to)
-#define elf_section_type(sec)  (elf_section_data(sec)->this_hdr.sh_type)
-#define elf_section_flags(sec) (elf_section_data(sec)->this_hdr.sh_flags)
-#define elf_group_name(sec)    (elf_section_data(sec)->group.name)
-#define elf_group_id(sec)      (elf_section_data(sec)->group.id)
-#define elf_next_in_group(sec) (elf_section_data(sec)->next_in_group)
-#define elf_fde_list(sec)      (elf_section_data(sec)->fde_list)
+#define elf_section_type(sec)  (elf_section_data(sec)->this_hdr.sh_type)
+#define elf_section_flags(sec) (elf_section_data(sec)->this_hdr.sh_flags)
+#define elf_group_name(sec)    (elf_section_data(sec)->group.name)
+#define elf_group_id(sec)      (elf_section_data(sec)->group.id)
+#define elf_next_in_group(sec) (elf_section_data(sec)->next_in_group)
+#define elf_fde_list(sec)      (elf_section_data(sec)->fde_list)
 #define elf_sec_group(sec)     (elf_section_data(sec)->sec_group)
 
 #define xvec_get_elf_backend_data(xvec) \
@@ -1328,45 +1439,11 @@ struct bfd_elf_section_data
 #define get_elf_backend_data(abfd) \
    xvec_get_elf_backend_data ((abfd)->xvec)
 
-/* This struct is used to pass information to routines called via
-   elf_link_hash_traverse which must return failure.  */
-
-struct elf_info_failed
-{
-  bfd_boolean failed;
-  struct bfd_link_info *info;
-  struct bfd_elf_version_tree *verdefs;
-};
-
-/* This structure is used to pass information to
-   _bfd_elf_link_assign_sym_version.  */
-
-struct elf_assign_sym_version_info
-{
-  /* Output BFD.  */
-  bfd *output_bfd;
-  /* General link information.  */
-  struct bfd_link_info *info;
-  /* Version tree.  */
-  struct bfd_elf_version_tree *verdefs;
-  /* Whether we had a failure.  */
-  bfd_boolean failed;
-};
-
-/* This structure is used to pass information to
-   _bfd_elf_link_find_version_dependencies.  */
-
-struct elf_find_verdep_info
-{
-  /* Output BFD.  */
-  bfd *output_bfd;
-  /* General link information.  */
-  struct bfd_link_info *info;
-  /* The number of dependencies.  */
-  unsigned int vers;
-  /* Whether we had a failure.  */
-  bfd_boolean failed;
-};
+/* The least object attributes (within an attributes subsection) known
+   for any target.  Some code assumes that the value 0 is not used and
+   the field for that attribute can instead be used as a marker to
+   indicate that attributes have been initialized.  */
+#define LEAST_KNOWN_OBJ_ATTRIBUTE 2
 
 /* The maximum number of known object attributes for any target.  */
 #define NUM_KNOWN_OBJ_ATTRIBUTES 71
@@ -1416,25 +1493,71 @@ enum
   Tag_compatibility = 32
 };
 
-/* Enum used to identify target specific extensions to the elf_obj_tdata
-   structure.  Note the enums deliberately start from 1 so that we can
-   detect an uninitialized field.  The generic value is last so that
-   additions to this enum do not need to modify more than one line.  */
-enum elf_object_id
+/* The following struct stores information about every SystemTap section
+   found in the object file.  */
+struct sdt_note
+{
+  struct sdt_note *next;
+  bfd_size_type size;
+  bfd_byte data[1];
+};
+
+/* NT_GNU_BUILD_ID note type info for input BFDs.  */
+struct elf_build_id
 {
-  ALPHA_ELF_TDATA = 1,
-  ARM_ELF_TDATA,
-  HPPA_ELF_TDATA,
-  I386_ELF_TDATA,
-  MIPS_ELF_TDATA,
-  PPC32_ELF_TDATA,
-  PPC64_ELF_TDATA,
-  S390_ELF_TDATA,
-  SH_ELF_TDATA,
-  SPARC_ELF_TDATA,
-  X86_64_ELF_TDATA,
-  XTENSA_ELF_TDATA,
-  GENERIC_ELF_TDATA
+  size_t size;
+  bfd_byte data[1];
+};
+
+/* tdata information grabbed from an elf core file.  */
+struct core_elf_obj_tdata
+{
+  int signal;
+  int pid;
+  int lwpid;
+  char* program;
+  char* command;
+};
+
+/* Extra tdata information held for output ELF BFDs.  */
+struct output_elf_obj_tdata
+{
+  struct elf_segment_map *seg_map;
+  struct elf_strtab_hash *strtab_ptr;
+
+  /* STT_SECTION symbols for each section */
+  asymbol **section_syms;
+
+  /* Used to determine if PT_GNU_EH_FRAME segment header should be
+     created.  */
+  asection *eh_frame_hdr;
+
+  /* NT_GNU_BUILD_ID note type info.  */
+  struct
+  {
+    bfd_boolean (*after_write_object_contents) (bfd *);
+    const char *style;
+    asection *sec;
+  } build_id;
+
+  /* Records the result of `get_program_header_size'.  */
+  bfd_size_type program_header_size;
+
+  /* Used when laying out sections.  */
+  file_ptr next_file_pos;
+
+  int num_section_syms;
+  unsigned int shstrtab_section, strtab_section;
+
+  /* Segment flags for the PT_GNU_STACK segment.  */
+  unsigned int stack_flags;
+
+  /* This is set to TRUE if the object was created by the backend
+     linker.  */
+  bfd_boolean linker;
+
+  /* Used to determine if the e_flags field has been initialized */
+  bfd_boolean flags_init;
 };
 
 /* Some private data is stashed away for future use using the tdata pointer
@@ -1445,13 +1568,6 @@ struct elf_obj_tdata
   Elf_Internal_Ehdr elf_header[1];     /* Actual data, but ref like ptr */
   Elf_Internal_Shdr **elf_sect_ptr;
   Elf_Internal_Phdr *phdr;
-  struct elf_segment_map *segment_map;
-  struct elf_strtab_hash *strtab_ptr;
-  int num_locals;
-  int num_globals;
-  unsigned int num_elf_sections;       /* elf_sect_ptr size */
-  int num_section_syms;
-  asymbol **section_syms;              /* STT_SECTION symbols for each section */
   Elf_Internal_Shdr symtab_hdr;
   Elf_Internal_Shdr shstrtab_hdr;
   Elf_Internal_Shdr strtab_hdr;
@@ -1461,20 +1577,9 @@ struct elf_obj_tdata
   Elf_Internal_Shdr dynverref_hdr;
   Elf_Internal_Shdr dynverdef_hdr;
   Elf_Internal_Shdr symtab_shndx_hdr;
-  unsigned int symtab_section, shstrtab_section;
-  unsigned int strtab_section, dynsymtab_section;
-  unsigned int symtab_shndx_section;
-  unsigned int dynversym_section, dynverdef_section, dynverref_section;
-  file_ptr next_file_pos;
   bfd_vma gp;                          /* The gp value */
   unsigned int gp_size;                        /* The gp size */
-
-  /* Information grabbed from an elf core file.  */
-  int core_signal;
-  int core_pid;
-  int core_lwpid;
-  char* core_program;
-  char* core_command;
+  unsigned int num_elf_sections;       /* elf_sect_ptr size */
 
   /* A mapping from external symbols to entries in the linker hash
      table, used when linking.  This is indexed by the symbol index
@@ -1501,36 +1606,21 @@ struct elf_obj_tdata
      one.  */
   const char *dt_name;
 
-  /* Records the result of `get_program_header_size'.  */
-  bfd_size_type program_header_size;
+  /* The linker emulation needs to know what audit libs
+     are used by a dynamic object.  */
+  const char *dt_audit;
 
   /* Used by find_nearest_line entry point.  */
   void *line_info;
 
-  /* Used by MIPS ELF find_nearest_line entry point.  The structure
-     could be included directly in this one, but there's no point to
-     wasting the memory just for the infrequently called
-     find_nearest_line.  */
-  struct mips_elf_find_line *find_line_info;
-
   /* A place to stash dwarf1 info for this bfd.  */
   struct dwarf1_debug *dwarf1_find_line_info;
 
   /* A place to stash dwarf2 info for this bfd.  */
   void *dwarf2_find_line_info;
 
-  /* An array of stub sections indexed by symbol number, used by the
-     MIPS ELF linker.  FIXME: We should figure out some way to only
-     include this field for a MIPS ELF target.  */
-  asection **local_stubs;
-  asection **local_call_stubs;
-
-  /* Used to determine if PT_GNU_EH_FRAME segment header should be
-     created.  */
-  asection *eh_frame_hdr;
-
-  Elf_Internal_Shdr **group_sect_ptr;
-  int num_group;
+  /* Stash away info for yet another find line/function variant.  */
+  void *elf_find_function_cache;
 
   /* Number of symbol version definitions we are about to emit.  */
   unsigned int cverdefs;
@@ -1538,34 +1628,44 @@ struct elf_obj_tdata
   /* Number of symbol version references we are about to emit.  */
   unsigned int cverrefs;
 
-  /* Segment flags for the PT_GNU_STACK segment.  */
-  unsigned int stack_flags;
-
   /* Symbol version definitions in external objects.  */
   Elf_Internal_Verdef *verdef;
 
   /* Symbol version references to external objects.  */
   Elf_Internal_Verneed *verref;
 
-  /* The Irix 5 support uses two virtual sections, which represent
-     text/data symbols defined in dynamic objects.  */
-  asymbol *elf_data_symbol;
-  asymbol *elf_text_symbol;
-  asection *elf_data_section;
-  asection *elf_text_section;
-
   /* A pointer to the .eh_frame section.  */
   asection *eh_frame_section;
 
+  /* Symbol buffer.  */
+  void *symbuf;
+
+  obj_attribute known_obj_attributes[2][NUM_KNOWN_OBJ_ATTRIBUTES];
+  obj_attribute_list *other_obj_attributes[2];
+
+  /* NT_GNU_BUILD_ID note type.  */
+  struct elf_build_id *build_id;
+
+  /* Linked-list containing information about every Systemtap section
+     found in the object file.  Each section corresponds to one entry
+     in the list.  */
+  struct sdt_note *sdt_note_head;
+
+  Elf_Internal_Shdr **group_sect_ptr;
+  int num_group;
+
+  unsigned int symtab_section, symtab_shndx_section, dynsymtab_section;
+  unsigned int dynversym_section, dynverdef_section, dynverref_section;
+
+  /* An identifier used to distinguish different target
+     specific extensions to this structure.  */
+  enum elf_target_id object_id;
+
   /* Whether a dyanmic object was specified normally on the linker
      command line, or was specified when --as-needed was in effect,
      or was found via a DT_NEEDED entry.  */
   enum dynamic_lib_link_class dyn_lib_class;
 
-  /* This is set to TRUE if the object was created by the backend
-     linker.  */
-  bfd_boolean linker;
-
   /* Irix 5 often screws up the symbol table, sorting local symbols
      after global symbols.  This flag is set if the symbol table in
      this BFD appears to be screwed up.  If it is, we ignore the
@@ -1573,38 +1673,35 @@ struct elf_obj_tdata
      symbols.  */
   bfd_boolean bad_symtab;
 
-  /* Used to determine if the e_flags field has been initialized */
-  bfd_boolean flags_init;
+  /* True if the bfd contains symbols that have the STT_GNU_IFUNC
+     symbol type or STB_GNU_UNIQUE binding.  Used to set the osabi
+     field in the ELF header structure.  */
+  bfd_boolean has_gnu_symbols;
 
-  /* Symbol buffer.  */
-  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;
+  /* Information grabbed from an elf core file.  */
+  struct core_elf_obj_tdata *core;
 
-  /* An identifier used to distinguish different target
-     specific extensions to this structure.  */
-  enum elf_object_id object_id;
+  /* More information held for output ELF BFDs.  */
+  struct output_elf_obj_tdata *o;
 };
 
 #define elf_tdata(bfd)         ((bfd) -> tdata.elf_obj_data)
 
 #define elf_object_id(bfd)     (elf_tdata(bfd) -> object_id)
-#define elf_program_header_size(bfd) (elf_tdata(bfd) -> program_header_size)
+#define elf_program_header_size(bfd) (elf_tdata(bfd) -> o->program_header_size)
 #define elf_elfheader(bfd)     (elf_tdata(bfd) -> elf_header)
 #define elf_elfsections(bfd)   (elf_tdata(bfd) -> elf_sect_ptr)
 #define elf_numsections(bfd)   (elf_tdata(bfd) -> num_elf_sections)
-#define elf_shstrtab(bfd)      (elf_tdata(bfd) -> strtab_ptr)
+#define elf_seg_map(bfd)       (elf_tdata(bfd) -> o->seg_map)
+#define elf_next_file_pos(bfd) (elf_tdata(bfd) -> o->next_file_pos)
+#define elf_eh_frame_hdr(bfd)  (elf_tdata(bfd) -> o->eh_frame_hdr)
+#define elf_linker(bfd)                (elf_tdata(bfd) -> o->linker)
+#define elf_stack_flags(bfd)   (elf_tdata(bfd) -> o->stack_flags)
+#define elf_shstrtab(bfd)      (elf_tdata(bfd) -> o->strtab_ptr)
 #define elf_onesymtab(bfd)     (elf_tdata(bfd) -> symtab_section)
 #define elf_symtab_shndx(bfd)  (elf_tdata(bfd) -> symtab_shndx_section)
+#define elf_strtab_sec(bfd)    (elf_tdata(bfd) -> o->strtab_section)
+#define elf_shstrtab_sec(bfd)  (elf_tdata(bfd) -> o->shstrtab_section)
 #define elf_symtab_hdr(bfd)    (elf_tdata(bfd) -> symtab_hdr)
 #define elf_dynsymtab(bfd)     (elf_tdata(bfd) -> dynsymtab_section)
 #define elf_dynversym(bfd)     (elf_tdata(bfd) -> dynversym_section)
@@ -1612,10 +1709,8 @@ struct elf_obj_tdata
 #define elf_dynverref(bfd)     (elf_tdata(bfd) -> dynverref_section)
 #define elf_eh_frame_section(bfd) \
                                (elf_tdata(bfd) -> eh_frame_section)
-#define elf_num_locals(bfd)    (elf_tdata(bfd) -> num_locals)
-#define elf_num_globals(bfd)   (elf_tdata(bfd) -> num_globals)
-#define elf_section_syms(bfd)  (elf_tdata(bfd) -> section_syms)
-#define elf_num_section_syms(bfd) (elf_tdata(bfd) -> num_section_syms)
+#define elf_section_syms(bfd)  (elf_tdata(bfd) -> o->section_syms)
+#define elf_num_section_syms(bfd) (elf_tdata(bfd) -> o->num_section_syms)
 #define core_prpsinfo(bfd)     (elf_tdata(bfd) -> prpsinfo)
 #define core_prstatus(bfd)     (elf_tdata(bfd) -> prstatus)
 #define elf_gp(bfd)            (elf_tdata(bfd) -> gp)
@@ -1625,9 +1720,10 @@ struct elf_obj_tdata
 #define elf_local_got_offsets(bfd) (elf_tdata(bfd) -> local_got.offsets)
 #define elf_local_got_ents(bfd) (elf_tdata(bfd) -> local_got.ents)
 #define elf_dt_name(bfd)       (elf_tdata(bfd) -> dt_name)
+#define elf_dt_audit(bfd)      (elf_tdata(bfd) -> dt_audit)
 #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_flags_init(bfd)    (elf_tdata(bfd) -> o->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) \
@@ -1660,8 +1756,6 @@ extern unsigned int _bfd_elf_section_from_bfd_section
   (bfd *, asection *);
 extern char *bfd_elf_string_from_elf_section
   (bfd *, unsigned, unsigned);
-extern char *bfd_elf_get_str_section
-  (bfd *, unsigned);
 extern Elf_Internal_Sym *bfd_elf_get_elf_syms
   (bfd *, Elf_Internal_Shdr *, size_t, size_t, Elf_Internal_Sym *, void *,
    Elf_External_Sym_Shndx *);
@@ -1684,7 +1778,8 @@ extern bfd_boolean _bfd_elf_can_make_relative
   (bfd *input_bfd, struct bfd_link_info *info, asection *eh_frame_section);
 
 extern enum elf_reloc_type_class _bfd_elf_reloc_type_class
-  (const Elf_Internal_Rela *);
+  (const struct bfd_link_info *, const asection *,
+   const Elf_Internal_Rela *);
 extern bfd_vma _bfd_elf_rela_local_sym
   (bfd *, Elf_Internal_Sym *, asection **, Elf_Internal_Rela *);
 extern bfd_vma _bfd_elf_rel_local_sym
@@ -1700,13 +1795,11 @@ extern unsigned long bfd_elf_gnu_hash
 extern bfd_reloc_status_type bfd_elf_generic_reloc
   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
 extern bfd_boolean bfd_elf_allocate_object
-  (bfd *, size_t, enum elf_object_id);
-extern bfd_boolean bfd_elf_make_generic_object
+  (bfd *, size_t, enum elf_target_id);
+extern bfd_boolean bfd_elf_make_object
   (bfd *);
 extern bfd_boolean bfd_elf_mkcorefile
   (bfd *);
-extern Elf_Internal_Shdr *bfd_elf_find_section
-  (bfd *, char *);
 extern bfd_boolean _bfd_elf_make_section_from_shdr
   (bfd *, Elf_Internal_Shdr *, const char *, int);
 extern bfd_boolean _bfd_elf_make_section_from_phdr
@@ -1715,6 +1808,8 @@ extern struct bfd_hash_entry *_bfd_elf_link_hash_newfunc
   (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
 extern struct bfd_link_hash_table *_bfd_elf_link_hash_table_create
   (bfd *);
+extern void _bfd_elf_link_hash_table_free
+  (struct bfd_link_hash_table *);
 extern void _bfd_elf_link_hash_copy_indirect
   (struct bfd_link_info *, struct elf_link_hash_entry *,
    struct elf_link_hash_entry *);
@@ -1726,7 +1821,7 @@ extern bfd_boolean _bfd_elf_link_hash_table_init
   (struct elf_link_hash_table *, bfd *,
    struct bfd_hash_entry *(*)
      (struct bfd_hash_entry *, struct bfd_hash_table *, const char *),
-   unsigned int);
+   unsigned int, enum elf_target_id);
 extern bfd_boolean _bfd_elf_slurp_version_tables
   (bfd *, bfd_boolean);
 extern bfd_boolean _bfd_elf_merge_sections
@@ -1735,14 +1830,19 @@ extern bfd_boolean _bfd_elf_match_sections_by_type
   (bfd *, const asection *, bfd *, const asection *);
 extern bfd_boolean bfd_elf_is_group_section
   (bfd *, const struct bfd_section *);
-extern void _bfd_elf_section_already_linked
-  (bfd *, struct bfd_section *, struct bfd_link_info *);
+extern bfd_boolean _bfd_elf_section_already_linked
+  (bfd *, asection *, struct bfd_link_info *);
 extern void bfd_elf_set_group_contents
   (bfd *, asection *, void *);
 extern asection *_bfd_elf_check_kept_section
   (asection *, struct bfd_link_info *);
-extern void _bfd_elf_link_just_syms
-  (asection *, struct bfd_link_info *);
+#define _bfd_elf_link_just_syms _bfd_generic_link_just_syms
+extern void _bfd_elf_copy_link_hash_symbol_type
+  (bfd *, struct bfd_link_hash_entry *, struct bfd_link_hash_entry *);
+extern bfd_boolean _bfd_elf_size_group_sections
+  (struct bfd_link_info *);
+extern bfd_boolean _bfd_elf_fixup_group_sections
+(bfd *, asection *);
 extern bfd_boolean _bfd_elf_copy_private_header_data
   (bfd *, bfd *);
 extern bfd_boolean _bfd_elf_copy_private_symbol_data
@@ -1794,9 +1894,16 @@ extern bfd_boolean _bfd_elf_set_arch_mach
 extern bfd_boolean _bfd_elf_find_nearest_line
   (bfd *, asection *, asymbol **, bfd_vma, const char **, const char **,
    unsigned int *);
+extern bfd_boolean _bfd_elf_find_nearest_line_discriminator
+  (bfd *, asection *, asymbol **, bfd_vma, const char **, const char **,
+   unsigned int *, unsigned int *);
 extern bfd_boolean _bfd_elf_find_line
   (bfd *, asymbol **, asymbol *, const char **, unsigned int *);
+extern bfd_boolean _bfd_elf_find_line_discriminator
+  (bfd *, asymbol **, asymbol *, const char **, unsigned int *, unsigned int *);
 #define _bfd_generic_find_line _bfd_elf_find_line
+#define _bfd_generic_find_nearest_line_discriminator \
+        _bfd_elf_find_nearest_line_discriminator
 extern bfd_boolean _bfd_elf_find_inliner_info
   (bfd *, const char **, const char **, unsigned int *);
 #define _bfd_elf_read_minisymbols _bfd_generic_read_minisymbols
@@ -1805,8 +1912,6 @@ extern int _bfd_elf_sizeof_headers
   (bfd *, struct bfd_link_info *);
 extern bfd_boolean _bfd_elf_new_section_hook
   (bfd *, asection *);
-extern bfd_boolean _bfd_elf_init_reloc_shdr
-  (bfd *, Elf_Internal_Shdr *, asection *, bfd_boolean);
 extern const struct bfd_elf_special_section *_bfd_elf_get_special_section
   (const char *, const struct bfd_elf_special_section *, unsigned int);
 extern const struct bfd_elf_special_section *_bfd_elf_get_sec_type_attr
@@ -1824,8 +1929,8 @@ extern bfd_boolean bfd_section_from_phdr
 extern int _bfd_elf_symbol_from_bfd_symbol
   (bfd *, asymbol **);
 
-extern asection *bfd_section_from_r_symndx
-  (bfd *, struct sym_sec_cache *, asection *, unsigned long);
+extern Elf_Internal_Sym *bfd_sym_from_r_symndx
+  (struct sym_cache *, bfd *, unsigned long);
 extern asection *bfd_section_from_elf_index
   (bfd *, unsigned int);
 extern struct bfd_strtab_hash *_bfd_elf_stringtab_init
@@ -1841,8 +1946,12 @@ extern void _bfd_elf_strtab_addref
   (struct elf_strtab_hash *, bfd_size_type);
 extern void _bfd_elf_strtab_delref
   (struct elf_strtab_hash *, bfd_size_type);
+extern unsigned int _bfd_elf_strtab_refcount
+  (struct elf_strtab_hash *, bfd_size_type);
 extern void _bfd_elf_strtab_clear_all_refs
-  (struct elf_strtab_hash *);
+  (struct elf_strtab_hash *tab);
+extern void _bfd_elf_strtab_restore_size
+  (struct elf_strtab_hash *, bfd_size_type);
 extern bfd_size_type _bfd_elf_strtab_size
   (struct elf_strtab_hash *);
 extern bfd_size_type _bfd_elf_strtab_offset
@@ -1870,31 +1979,13 @@ extern bfd_boolean _bfd_elf_write_section_eh_frame
   (bfd *, struct bfd_link_info *, asection *, bfd_byte *);
 extern bfd_boolean _bfd_elf_write_section_eh_frame_hdr
   (bfd *, struct bfd_link_info *);
+extern bfd_boolean _bfd_elf_eh_frame_present
+  (struct bfd_link_info *);
 extern bfd_boolean _bfd_elf_maybe_strip_eh_frame_hdr
   (struct bfd_link_info *);
 
-extern bfd_boolean _bfd_elf_merge_symbol
-  (bfd *, struct bfd_link_info *, const char *, Elf_Internal_Sym *,
-   asection **, bfd_vma *, unsigned int *,
-   struct elf_link_hash_entry **, bfd_boolean *,
-   bfd_boolean *, bfd_boolean *, bfd_boolean *);
-
 extern bfd_boolean _bfd_elf_hash_symbol (struct elf_link_hash_entry *);
 
-extern bfd_boolean _bfd_elf_add_default_symbol
-  (bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
-   const char *, Elf_Internal_Sym *, asection **, bfd_vma *,
-   bfd_boolean *, bfd_boolean);
-
-extern bfd_boolean _bfd_elf_export_symbol
-  (struct elf_link_hash_entry *, void *);
-
-extern bfd_boolean _bfd_elf_link_find_version_dependencies
-  (struct elf_link_hash_entry *, void *);
-
-extern bfd_boolean _bfd_elf_link_assign_sym_version
-  (struct elf_link_hash_entry *, void *);
-
 extern long _bfd_elf_link_lookup_local_dynindx
   (struct bfd_link_info *, bfd *, long);
 extern bfd_boolean _bfd_elf_compute_section_file_positions
@@ -1930,25 +2021,13 @@ extern char *_bfd_elfcore_strndup
 extern Elf_Internal_Rela *_bfd_elf_link_read_relocs
   (bfd *, asection *, void *, Elf_Internal_Rela *, bfd_boolean);
 
-extern bfd_boolean _bfd_elf_link_size_reloc_section
-  (bfd *, Elf_Internal_Shdr *, asection *);
-
 extern bfd_boolean _bfd_elf_link_output_relocs
   (bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *,
    struct elf_link_hash_entry **);
 
-extern bfd_boolean _bfd_elf_fix_symbol_flags
-  (struct elf_link_hash_entry *, struct elf_info_failed *);
-
-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_dynamic_symbol_p
   (struct elf_link_hash_entry *, struct bfd_link_info *, bfd_boolean);
 
@@ -1973,6 +2052,8 @@ extern int bfd_elf32_core_file_failing_signal
   (bfd *);
 extern bfd_boolean bfd_elf32_core_file_matches_executable_p
   (bfd *, bfd *);
+extern int bfd_elf32_core_file_pid
+  (bfd *);
 
 extern bfd_boolean bfd_elf32_swap_symbol_in
   (bfd *, const void *, const void *, Elf_Internal_Sym *);
@@ -2017,6 +2098,8 @@ extern int bfd_elf64_core_file_failing_signal
   (bfd *);
 extern bfd_boolean bfd_elf64_core_file_matches_executable_p
   (bfd *, bfd *);
+extern int bfd_elf64_core_file_pid
+  (bfd *);
 
 extern bfd_boolean bfd_elf64_swap_symbol_in
   (bfd *, const void *, const void *, Elf_Internal_Sym *);
@@ -2070,10 +2153,6 @@ extern bfd_boolean bfd_elf_link_record_dynamic_symbol
 extern int bfd_elf_link_record_local_dynamic_symbol
   (struct bfd_link_info *, bfd *, long);
 
-extern void bfd_elf_link_mark_dynamic_symbol
-  (struct bfd_link_info *, struct elf_link_hash_entry *,
-   Elf_Internal_Sym *);
-
 extern bfd_boolean _bfd_elf_close_and_cleanup
   (bfd *);
 
@@ -2086,9 +2165,6 @@ extern unsigned int _bfd_elf_common_section_index
 extern asection *_bfd_elf_common_section
   (asection *);
 
-extern void _bfd_dwarf2_cleanup_debug_info
-  (bfd *);
-
 extern bfd_vma _bfd_elf_default_got_elt_size
 (bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, bfd *,
  unsigned long);
@@ -2134,6 +2210,9 @@ extern bfd_boolean _bfd_elf_gc_mark_fdes
 extern bfd_boolean _bfd_elf_gc_mark
   (struct bfd_link_info *, asection *, elf_gc_mark_hook_fn);
 
+extern bfd_boolean _bfd_elf_gc_mark_extra_sections
+  (struct bfd_link_info *, elf_gc_mark_hook_fn);
+
 extern bfd_boolean bfd_elf_gc_common_finalize_got_offsets
   (bfd *, struct bfd_link_info *);
 
@@ -2151,6 +2230,14 @@ extern bfd_boolean _bfd_elf_map_sections_to_segments
 
 extern bfd_boolean _bfd_elf_is_function_type (unsigned int);
 
+extern bfd_size_type _bfd_elf_maybe_function_sym (const asymbol *, asection *,
+                                                 bfd_vma *);
+
+extern int bfd_elf_get_default_section_type (flagword);
+
+extern bfd_boolean bfd_elf_lookup_section_flags
+  (struct bfd_link_info *, struct flag_info *, asection *);
+
 extern Elf_Internal_Phdr * _bfd_elf_find_segment_containing_section
   (bfd * abfd, asection * section);
 
@@ -2167,21 +2254,83 @@ extern char *elfcore_write_prfpreg
   (bfd *, char *, int *, const void *, int);
 extern char *elfcore_write_prxfpreg
   (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_xstatereg
+  (bfd *, char *, int *, const void *, int);
 extern char *elfcore_write_ppc_vmx
   (bfd *, char *, int *, const void *, int);
 extern char *elfcore_write_ppc_vsx
   (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_s390_timer
+  (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_s390_todcmp
+  (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_s390_todpreg
+  (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_s390_ctrs
+  (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_s390_prefix
+  (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_s390_last_break
+  (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_s390_system_call
+  (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_s390_tdb
+  (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_arm_vfp
+  (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_aarch_tls
+  (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_aarch_hw_break
+  (bfd *, char *, int *, const void *, int);
+extern char *elfcore_write_aarch_hw_watch
+  (bfd *, char *, int *, const void *, int);
 extern char *elfcore_write_lwpstatus
   (bfd *, char *, int *, long, int, const void *);
 extern char *elfcore_write_register_note
   (bfd *, char *, int *, const char *, const void *, int);
 
+/* Internal structure which holds information to be included in the
+   PRPSINFO section of Linux core files.
+
+   This is an "internal" structure in the sense that it should be used
+   to pass information to BFD (via the `elfcore_write_linux_prpsinfo'
+   function), so things like endianess shouldn't be an issue.  This
+   structure will eventually be converted in one of the
+   `elf_external_linux_*' structures and written out to an output bfd
+   by one of the functions declared below.  */
+
+struct elf_internal_linux_prpsinfo
+  {
+    char pr_state;                     /* Numeric process state.  */
+    char pr_sname;                     /* Char for pr_state.  */
+    char pr_zomb;                      /* Zombie.  */
+    char pr_nice;                      /* Nice val.  */
+    unsigned long pr_flag;             /* Flags.  */
+    unsigned int pr_uid;
+    unsigned int pr_gid;
+    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+    char pr_fname[16 + 1];             /* Filename of executable.  */
+    char pr_psargs[80 + 1];            /* Initial part of arg list.  */
+  };
+
+/* Linux/most 32-bit archs.  */
+extern char *elfcore_write_linux_prpsinfo32
+  (bfd *, char *, int *, const struct elf_internal_linux_prpsinfo *);
+
+/* Linux/most 64-bit archs.  */
+extern char *elfcore_write_linux_prpsinfo64
+  (bfd *, char *, int *, const struct elf_internal_linux_prpsinfo *);
+
+/* Linux/PPC32 uses different layout compared to most archs.  */
+extern char *elfcore_write_ppc_linux_prpsinfo32
+  (bfd *, char *, int *, const struct elf_internal_linux_prpsinfo *);
+
 extern bfd *_bfd_elf32_bfd_from_remote_memory
   (bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep,
-   int (*target_read_memory) (bfd_vma, bfd_byte *, int));
+   int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type));
 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));
+   int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type));
 
 extern bfd_vma bfd_elf_obj_attr_size (bfd *);
 extern void bfd_elf_set_obj_attr_contents (bfd *, bfd_byte *, bfd_vma);
@@ -2203,14 +2352,52 @@ 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 *);
+extern bfd_boolean _bfd_elf_merge_unknown_attribute_low (bfd *, bfd *, int);
+extern bfd_boolean _bfd_elf_merge_unknown_attribute_list (bfd *, bfd *);
+extern Elf_Internal_Shdr *_bfd_elf_single_rel_hdr (asection *sec);
+
+/* The linker may need to keep track of the number of relocs that it
+   decides to copy as dynamic relocs in check_relocs for each symbol.
+   This is so that it can later discard them if they are found to be
+   unnecessary.  We can store the information in a field extending the
+   regular ELF linker hash table.  */
+
+struct elf_dyn_relocs
+{
+  struct elf_dyn_relocs *next;
+
+  /* The input section of the reloc.  */
+  asection *sec;
+
+  /* Total number of relocs copied for the input section.  */
+  bfd_size_type count;
+
+  /* Number of pc-relative relocs copied for the input section.  */
+  bfd_size_type pc_count;
+};
+
+extern bfd_boolean _bfd_elf_create_ifunc_sections
+  (bfd *, struct bfd_link_info *);
+extern bfd_boolean _bfd_elf_allocate_ifunc_dyn_relocs
+  (struct bfd_link_info *, struct elf_link_hash_entry *,
+   struct elf_dyn_relocs **, unsigned int, unsigned int, unsigned int);
+
+extern void elf_append_rela (bfd *, asection *, Elf_Internal_Rela *);
+extern void elf_append_rel (bfd *, asection *, Elf_Internal_Rela *);
+
+extern bfd_vma elf64_r_info (bfd_vma, bfd_vma);
+extern bfd_vma elf64_r_sym (bfd_vma);
+extern bfd_vma elf32_r_info (bfd_vma, bfd_vma);
+extern bfd_vma elf32_r_sym (bfd_vma);
 
 /* Large common section.  */
 extern asection _bfd_elf_large_com_section;
 
-/* SH ELF specific routine.  */
-
-extern bfd_boolean _sh_elf_set_mach_from_flags
-  (bfd *);
+/* Hash for local symbol with the first section id, ID, in the input
+   file and the local symbol index, SYM.  */
+#define ELF_LOCAL_SYMBOL_HASH(ID, SYM) \
+  (((((ID) & 0xff) << 24) | (((ID) & 0xff00) << 8)) \
+   ^ (SYM) ^ ((ID) >> 16))
 
 /* This is the condition under which finish_dynamic_symbol will be called.
    If our finish_dynamic_symbol isn't called, we'll need to do something
@@ -2276,12 +2463,66 @@ extern bfd_boolean _sh_elf_set_mach_from_flags
            return FALSE;                                               \
          warned = TRUE;                                                \
        }                                                               \
+      (void) unresolved_reloc;                                         \
+      (void) warned;                                                   \
     }                                                                  \
   while (0)
 
-/* Will a symbol be bound to the the definition within the shared
-   library, if any.  */
+/* This macro is to avoid lots of duplicated code in the body of the
+   loop over relocations in xxx_relocate_section() in the various
+   elfxx-xxxx.c files.
+
+   Handle relocations against symbols from removed linkonce sections,
+   or sections discarded by a linker script.  When doing a relocatable
+   link, we remove such relocations.  Otherwise, we just want the
+   section contents zeroed and avoid any special processing.  */
+#define RELOC_AGAINST_DISCARDED_SECTION(info, input_bfd, input_section,        \
+                                       rel, count, relend,             \
+                                       howto, index, contents)         \
+  {                                                                    \
+    int i_;                                                            \
+    _bfd_clear_contents (howto, input_bfd, input_section,              \
+                        contents + rel[index].r_offset);               \
+                                                                       \
+    if (info->relocatable                                              \
+       && (input_section->flags & SEC_DEBUGGING))                      \
+      {                                                                        \
+       /* Only remove relocations in debug sections since other        \
+          sections may require relocations.  */                        \
+       Elf_Internal_Shdr *rel_hdr;                                     \
+                                                                       \
+       rel_hdr = _bfd_elf_single_rel_hdr (input_section->output_section); \
+                                                                       \
+       /* Avoid empty output section.  */                              \
+       if (rel_hdr->sh_size > rel_hdr->sh_entsize)                     \
+         {                                                             \
+           rel_hdr->sh_size -= rel_hdr->sh_entsize;                    \
+           rel_hdr = _bfd_elf_single_rel_hdr (input_section);          \
+           rel_hdr->sh_size -= rel_hdr->sh_entsize;                    \
+                                                                       \
+           memmove (rel, rel + count,                                  \
+                    (relend - rel - count) * sizeof (*rel));           \
+                                                                       \
+           input_section->reloc_count--;                               \
+           relend -= count;                                            \
+           rel--;                                                      \
+           continue;                                                   \
+         }                                                             \
+      }                                                                        \
+                                                                       \
+    for (i_ = 0; i_ < count; i_++)                                     \
+      {                                                                        \
+       rel[i_].r_info = 0;                                             \
+       rel[i_].r_addend = 0;                                           \
+      }                                                                        \
+    rel += count - 1;                                                  \
+    continue;                                                          \
+  }
+
+/* Will a symbol be bound to the definition within the shared
+   library, if any.  A unique symbol can never be bound locally.  */
 #define SYMBOLIC_BIND(INFO, H) \
-    ((INFO)->symbolic || ((INFO)->dynamic && !(H)->dynamic))
+    (!(H)->unique_global \
+     && ((INFO)->symbolic || ((INFO)->dynamic && !(H)->dynamic)))
 
 #endif /* _LIBELF_H_ */