daily update
[deliverable/binutils-gdb.git] / bfd / elf32-i386.c
index e33a8c6d5e39a592986e8bb8dc219d042d5ad7a1..7c4b4bb918dfe37172264e8fb11903adfcedf2c9 100644 (file)
@@ -826,7 +826,7 @@ struct elf_i386_link_hash_table
   == I386_ELF_DATA ? ((struct elf_i386_link_hash_table *) ((p)->hash)) : NULL)
 
 #define elf_i386_compute_jump_table_size(htab) \
-  ((htab)->next_tls_desc_index * 4)
+  ((htab)->elf.srelplt->reloc_count * 4)
 
 /* Create an entry in an i386 ELF linker hash table.  */
 
@@ -927,6 +927,21 @@ elf_i386_get_local_sym_hash (struct elf_i386_link_hash_table *htab,
   return &ret->elf;
 }
 
+/* Destroy an i386 ELF linker hash table.  */
+
+static void
+elf_i386_link_hash_table_free (bfd *obfd)
+{
+  struct elf_i386_link_hash_table *htab
+    = (struct elf_i386_link_hash_table *) obfd->link.hash;
+
+  if (htab->loc_hash_table)
+    htab_delete (htab->loc_hash_table);
+  if (htab->loc_hash_memory)
+    objalloc_free ((struct objalloc *) htab->loc_hash_memory);
+  _bfd_elf_link_hash_table_free (obfd);
+}
+
 /* Create an i386 ELF linker hash table.  */
 
 static struct bfd_link_hash_table *
@@ -955,28 +970,14 @@ elf_i386_link_hash_table_create (bfd *abfd)
   ret->loc_hash_memory = objalloc_create ();
   if (!ret->loc_hash_table || !ret->loc_hash_memory)
     {
-      free (ret);
+      elf_i386_link_hash_table_free (abfd);
       return NULL;
     }
+  ret->elf.root.hash_table_free = elf_i386_link_hash_table_free;
 
   return &ret->elf.root;
 }
 
-/* Destroy an i386 ELF linker hash table.  */
-
-static void
-elf_i386_link_hash_table_free (struct bfd_link_hash_table *hash)
-{
-  struct elf_i386_link_hash_table *htab
-    = (struct elf_i386_link_hash_table *) hash;
-
-  if (htab->loc_hash_table)
-    htab_delete (htab->loc_hash_table);
-  if (htab->loc_hash_memory)
-    objalloc_free ((struct objalloc *) htab->loc_hash_memory);
-  _bfd_elf_link_hash_table_free (hash);
-}
-
 /* Create .plt, .rel.plt, .got, .got.plt, .rel.got, .dynbss, and
    .rel.bss sections in DYNOBJ, and set up shortcuts to them in our
    hash table.  */
@@ -4975,14 +4976,46 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd,
   return TRUE;
 }
 
-/* Return address for Ith PLT stub in section PLT, for relocation REL
-   or (bfd_vma) -1 if it should not be included.  */
+/* Return address in section PLT for the Ith GOTPLT relocation, for
+   relocation REL or (bfd_vma) -1 if it should not be included.  */
 
 static bfd_vma
-elf_i386_plt_sym_val (bfd_vma i, const asection *plt,
-                     const arelent *rel ATTRIBUTE_UNUSED)
+elf_i386_plt_sym_val (bfd_vma i, const asection *plt, const arelent *rel)
 {
-  return plt->vma + (i + 1) * GET_PLT_ENTRY_SIZE (plt->owner);
+  bfd *abfd;
+  const struct elf_i386_backend_data *bed;
+  bfd_vma plt_offset;
+
+  /* Only match R_386_JUMP_SLOT and R_386_IRELATIVE.  */
+  if (rel->howto->type != R_386_JUMP_SLOT
+      && rel->howto->type != R_386_IRELATIVE)
+    return (bfd_vma) -1;
+
+  abfd = plt->owner;
+  bed = get_elf_i386_backend_data (abfd);
+  plt_offset = bed->plt->plt_entry_size;
+
+  if (elf_elfheader (abfd)->e_ident[EI_OSABI] != ELFOSABI_GNU)
+    return plt->vma + (i + 1) * plt_offset;
+
+  while (plt_offset < plt->size)
+    {
+      bfd_vma reloc_offset;
+      bfd_byte reloc_offset_raw[4];
+
+      if (!bfd_get_section_contents (abfd, (asection *) plt,
+                                    reloc_offset_raw,
+                                    plt_offset + bed->plt->plt_reloc_offset,
+                                    sizeof (reloc_offset_raw)))
+       return (bfd_vma) -1;
+
+      reloc_offset = H_GET_32 (abfd, reloc_offset_raw);
+      if (reloc_offset == i * sizeof (Elf32_External_Rel))
+       return plt->vma + plt_offset;
+      plt_offset += bed->plt->plt_entry_size;
+    }
+
+  abort ();
 }
 
 /* Return TRUE if symbol should be hashed in the `.gnu.hash' section.  */
@@ -5041,7 +5074,6 @@ elf_i386_add_symbol_hook (bfd * abfd,
 
 #define bfd_elf32_bfd_is_local_label_name     elf_i386_is_local_label_name
 #define bfd_elf32_bfd_link_hash_table_create  elf_i386_link_hash_table_create
-#define bfd_elf32_bfd_link_hash_table_free    elf_i386_link_hash_table_free
 #define bfd_elf32_bfd_reloc_type_lookup              elf_i386_reloc_type_lookup
 #define bfd_elf32_bfd_reloc_name_lookup              elf_i386_reloc_name_lookup
 
This page took 0.024602 seconds and 4 git commands to generate.