Fix elf_x86_64_reloc_type_class
authorH.J. Lu <hjl.tools@gmail.com>
Tue, 14 Jun 2016 16:21:00 +0000 (09:21 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Tue, 14 Jun 2016 17:10:45 +0000 (10:10 -0700)
bfd/elf64-x86-64.c

index 46f723c5d55c47bca805800403a30f384b288664..f8a7ca39e669f61d267ca122707dbec377faeba0 100644 (file)
@@ -6001,21 +6001,27 @@ elf_x86_64_reloc_type_class (const struct bfd_link_info *info,
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
   struct elf_x86_64_link_hash_table *htab = elf_x86_64_hash_table (info);
 
+  if ((int) ELF32_R_TYPE (rela->r_info) == R_X86_64_IRELATIVE)
+    return reloc_class_ifunc;
+
   if (htab->elf.dynsym != NULL
       && htab->elf.dynsym->contents != NULL)
     {
       /* Check relocation against STT_GNU_IFUNC symbol if there are
          dynamic symbols.  */
       unsigned long r_symndx = htab->r_sym (rela->r_info);
-      Elf_Internal_Sym sym;
-      if (!bed->s->swap_symbol_in (abfd,
-                                  (htab->elf.dynsym->contents
-                                   + r_symndx * bed->s->sizeof_sym),
-                                  0, &sym))
-       abort ();
+      if (r_symndx != STN_UNDEF)
+       {
+         Elf_Internal_Sym sym;
+         if (!bed->s->swap_symbol_in (abfd,
+                                      (htab->elf.dynsym->contents
+                                       + r_symndx * bed->s->sizeof_sym),
+                                      0, &sym))
+           abort ();
 
-      if (ELF_ST_TYPE (sym.st_info) == STT_GNU_IFUNC)
-       return reloc_class_ifunc;
+         if (ELF_ST_TYPE (sym.st_info) == STT_GNU_IFUNC)
+           return reloc_class_ifunc;
+       }
     }
 
   switch ((int) ELF32_R_TYPE (rela->r_info))