x86: Add _bfd_x86_elf_mkobject
[binutils-gdb.git] / bfd / elfxx-x86.h
index 480189bfd40eacb4ba773be16f517dd526f6bfa3..bc01ad979e9ba76abc111164a67ea1ba4476f05d 100644 (file)
 #include "libbfd.h"
 #include "elf-bfd.h"
 #include "bfd_stdint.h"
-#include "objalloc.h"
 #include "hashtab.h"
 
+#define ABI_64_P(abfd) \
+  (get_elf_backend_data (abfd)->s->elfclass == ELFCLASS64)
+
 /* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid
    copying dynamic variables from a shared lib into an app's dynbss
    section, and instead use a dynamic relocation to point into the
@@ -118,6 +120,104 @@ struct elf_x86_link_hash_entry
   bfd_vma tlsdesc_got;
 };
 
+struct elf_x86_lazy_plt_layout
+{
+  /* The first entry in an absolute lazy procedure linkage table looks
+     like this.  */
+  const bfd_byte *plt0_entry;
+  unsigned int plt0_entry_size;          /* Size of PLT0 entry.  */
+
+  /* Later entries in an absolute lazy procedure linkage table look
+     like this.  */
+  const bfd_byte *plt_entry;
+  unsigned int plt_entry_size;          /* Size of each PLT entry.  */
+
+  /* Offsets into plt0_entry that are to be replaced with GOT[1] and
+     GOT[2].  */
+  unsigned int plt0_got1_offset;
+  unsigned int plt0_got2_offset;
+
+  /* Offset of the end of the PC-relative instruction containing
+     plt0_got2_offset.  This is for x86-64 only.  */
+  unsigned int plt0_got2_insn_end;
+
+  /* Offsets into plt_entry that are to be replaced with...  */
+  unsigned int plt_got_offset;    /* ... address of this symbol in .got. */
+  unsigned int plt_reloc_offset;  /* ... offset into relocation table. */
+  unsigned int plt_plt_offset;    /* ... offset to start of .plt. */
+
+  /* Length of the PC-relative instruction containing plt_got_offset.
+     This is used for x86-64 only.  */
+  unsigned int plt_got_insn_size;
+
+  /* Offset of the end of the PC-relative jump to plt0_entry.  This is
+     used for x86-64 only.  */
+  unsigned int plt_plt_insn_end;
+
+  /* Offset into plt_entry where the initial value of the GOT entry
+     points.  */
+  unsigned int plt_lazy_offset;
+
+  /* The first entry in a PIC lazy procedure linkage table looks like
+     this.  */
+  const bfd_byte *pic_plt0_entry;
+
+  /* Subsequent entries in a PIC lazy procedure linkage table look
+     like this.  */
+  const bfd_byte *pic_plt_entry;
+
+  /* .eh_frame covering the lazy .plt section.  */
+  const bfd_byte *eh_frame_plt;
+  unsigned int eh_frame_plt_size;
+};
+
+struct elf_x86_non_lazy_plt_layout
+{
+  /* Entries in an absolute non-lazy procedure linkage table look like
+     this.  */
+  const bfd_byte *plt_entry;
+  /* Entries in a PIC non-lazy procedure linkage table look like this.  */
+  const bfd_byte *pic_plt_entry;
+
+  unsigned int plt_entry_size;          /* Size of each PLT entry.  */
+
+  /* Offsets into plt_entry that are to be replaced with...  */
+  unsigned int plt_got_offset;    /* ... address of this symbol in .got. */
+
+  /* Length of the PC-relative instruction containing plt_got_offset.
+     This is used for x86-64 only.  */
+  unsigned int plt_got_insn_size;
+
+  /* .eh_frame covering the non-lazy .plt section.  */
+  const bfd_byte *eh_frame_plt;
+  unsigned int eh_frame_plt_size;
+};
+
+struct elf_x86_plt_layout
+{
+  /* The first entry in a lazy procedure linkage table looks like this.
+     This is only used for i386 where absolute PLT0 and PIC PLT0 are
+     different.  */
+  const bfd_byte *plt0_entry;
+  /* Entries in a procedure linkage table look like this.  */
+  const bfd_byte *plt_entry;
+  unsigned int plt_entry_size;          /* Size of each PLT entry.  */
+
+  /* 1 has PLT0.  */
+  unsigned int has_plt0;
+
+  /* Offsets into plt_entry that are to be replaced with...  */
+  unsigned int plt_got_offset;    /* ... address of this symbol in .got. */
+
+  /* Length of the PC-relative instruction containing plt_got_offset.
+     This is only used for x86-64.  */
+  unsigned int plt_got_insn_size;
+
+  /* .eh_frame covering the .plt section.  */
+  const bfd_byte *eh_frame_plt;
+  unsigned int eh_frame_plt_size;
+};
+
 /* The first 3 values in tls_type of x86 ELF linker hash entry.  */
 #define GOT_UNKNOWN    0
 #define GOT_NORMAL     1
@@ -140,6 +240,15 @@ struct elf_x86_link_hash_table
   asection *plt_got;
   asection *plt_got_eh_frame;
 
+  /* Parameters describing PLT generation, lazy or non-lazy.  */
+  struct elf_x86_plt_layout plt;
+
+  /* Parameters describing lazy PLT generation.  */
+  const struct elf_x86_lazy_plt_layout *lazy_plt;
+
+  /* Parameters describing non-lazy PLT generation.  */
+  const struct elf_x86_non_lazy_plt_layout *non_lazy_plt;
+
   union
   {
     bfd_signed_vma refcount;
@@ -178,6 +287,14 @@ struct elf_x86_link_hash_table
      to read-only sections.  */
   bfd_boolean readonly_dynrelocs_against_ifunc;
 
+  /* The (unloaded but important) .rel.plt.unloaded section on VxWorks.
+     This is used for i386 only.  */
+  asection *srelplt2;
+
+  /* The index of the next unused R_386_TLS_DESC slot in .rel.plt.  This
+     is used for i386 only.  */
+  bfd_vma next_tls_desc_index;
+
   bfd_vma (*r_info) (bfd_vma, bfd_vma);
   bfd_vma (*r_sym) (bfd_vma);
   unsigned int pointer_r_type;
@@ -186,6 +303,27 @@ struct elf_x86_link_hash_table
   const char *tls_get_addr;
 };
 
+struct elf_x86_plt_layout_table
+{
+  /* The lazy PLT layout.  */
+  const struct elf_x86_lazy_plt_layout *lazy_plt;
+
+  /* The non-lazy PLT layout.  */
+  const struct elf_x86_non_lazy_plt_layout *non_lazy_plt;
+
+  /* The lazy PLT layout for IBT.  */
+  const struct elf_x86_lazy_plt_layout *lazy_ibt_plt;
+
+  /* The non-lazy PLT layout for IBT.  */
+  const struct elf_x86_non_lazy_plt_layout *non_lazy_ibt_plt;
+
+  /* TRUE if this is an normal x86 target.  */
+  bfd_boolean normal_target;
+
+  /* TRUE if this is a VxWorks x86 target.  */
+  bfd_boolean is_vxworks;
+};
+
 struct elf_x86_obj_tdata
 {
   struct elf_obj_tdata root;
@@ -197,6 +335,27 @@ struct elf_x86_obj_tdata
   bfd_vma *local_tlsdesc_gotent;
 };
 
+enum elf_x86_plt_type
+{
+  plt_non_lazy = 0,
+  plt_lazy = 1 << 0,
+  plt_pic = 1 << 1,
+  plt_second = 1 << 2,
+  plt_unknown = -1
+};
+
+struct elf_x86_plt
+{
+  const char *name;
+  asection *sec;
+  bfd_byte *contents;
+  enum elf_x86_plt_type type;
+  unsigned int plt_got_offset;
+  unsigned int plt_entry_size;
+  unsigned int plt_got_insn_size;      /* Only used for x86-64.  */
+  long count;
+};
+
 #define elf_x86_tdata(abfd) \
   ((struct elf_x86_obj_tdata *) (abfd)->tdata.any)
 
@@ -206,6 +365,9 @@ struct elf_x86_obj_tdata
 #define elf_x86_local_tlsdesc_gotent(abfd) \
   (elf_x86_tdata (abfd)->local_tlsdesc_gotent)
 
+extern bfd_boolean _bfd_x86_elf_mkobject
+  (bfd *);
+
 extern void _bfd_x86_elf_set_tls_module_base
   (struct bfd_link_info *);
 
@@ -228,7 +390,7 @@ extern int _bfd_x86_elf_local_htab_eq
 extern struct bfd_hash_entry * _bfd_x86_elf_link_hash_newfunc
   (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
 
-extern void _bfd_x86_elf_link_hash_table_free
+extern struct bfd_link_hash_table * _bfd_x86_elf_link_hash_table_create
   (bfd *);
 
 extern int _bfd_x86_elf_compare_relocs
@@ -254,12 +416,27 @@ extern bfd_boolean _bfd_x86_elf_fixup_symbol
 extern bfd_boolean _bfd_x86_elf_hash_symbol
   (struct elf_link_hash_entry *);
 
+extern long _bfd_x86_elf_get_synthetic_symtab
+  (bfd *, long, long, bfd_vma, struct elf_x86_plt [], asymbol **,
+   asymbol **);
+
 extern enum elf_property_kind _bfd_x86_elf_parse_gnu_properties
   (bfd *, unsigned int, bfd_byte *, unsigned int);
 
 extern bfd_boolean _bfd_x86_elf_merge_gnu_properties
   (struct bfd_link_info *, bfd *, elf_property *, elf_property *);
 
+extern bfd * _bfd_x86_elf_link_setup_gnu_properties
+  (struct bfd_link_info *, struct elf_x86_plt_layout_table *);
+
+#define bfd_elf64_mkobject \
+  _bfd_x86_elf_mkobject
+#define bfd_elf32_mkobject \
+  _bfd_x86_elf_mkobject
+#define bfd_elf64_bfd_link_hash_table_create \
+  _bfd_x86_elf_link_hash_table_create
+#define bfd_elf32_bfd_link_hash_table_create \
+  _bfd_x86_elf_link_hash_table_create
 #define bfd_elf64_bfd_link_check_relocs        \
   _bfd_x86_elf_link_check_relocs
 #define bfd_elf32_bfd_link_check_relocs \