Improve "unrecognized relocation" error messages to add the suggestion that the linke...
[binutils-gdb.git] / bfd / elfnn-aarch64.c
index 86bae0eaa8eb1462013f3c58e2a6ddffd43dceab..0d8332e69ce847e0a190ac5cf540eb9345ddb3a0 100644 (file)
@@ -3281,7 +3281,7 @@ aarch64_mem_op_p (uint32_t insn, unsigned int *rt, unsigned int *rt2,
   uint32_t v = 0;
   uint32_t opc_v = 0;
 
-  /* Bail out quickly if INSN doesn't fall into the the load-store
+  /* Bail out quickly if INSN doesn't fall into the load-store
      encoding space.  */
   if (!AARCH64_LDST (insn))
     return FALSE;
@@ -5016,7 +5016,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
              _bfd_error_handler
                /* xgettext:c-format */
                (_("%B: relocation %s against STT_GNU_IFUNC "
-                  "symbol `%s' has non-zero addend: %d"),
+                  "symbol `%s' has non-zero addend: %Ld"),
                 input_bfd, howto->name, name, rel->r_addend);
              bfd_set_error (bfd_error_bad_value);
              return FALSE;
@@ -6072,17 +6072,11 @@ elfNN_aarch64_relocate_section (bfd *output_bfd,
       r_symndx = ELFNN_R_SYM (rel->r_info);
       r_type = ELFNN_R_TYPE (rel->r_info);
 
-      bfd_reloc.howto = elfNN_aarch64_howto_from_type (r_type);
-      howto = bfd_reloc.howto;
+      howto = bfd_reloc.howto = elfNN_aarch64_howto_from_type (r_type);
 
       if (howto == NULL)
-       {
-         /* xgettext:c-format */
-         _bfd_error_handler
-           (_("%B: unrecognized relocation (0x%x) in section `%A'"),
-            input_bfd, r_type, input_section);
-         return FALSE;
-       }
+       return _bfd_unrecognized_reloc (input_bfd, input_section, r_type);
+
       bfd_r_type = elfNN_aarch64_bfd_reloc_from_howto (howto);
 
       h = NULL;
@@ -6162,11 +6156,11 @@ elfNN_aarch64_relocate_section (bfd *output_bfd,
          _bfd_error_handler
            ((sym_type == STT_TLS
              /* xgettext:c-format */
-             ? _("%B(%A+0x%lx): %s used with TLS symbol %s")
+             ? _("%B(%A+%#Lx): %s used with TLS symbol %s")
              /* xgettext:c-format */
-             : _("%B(%A+0x%lx): %s used with non-TLS symbol %s")),
+             : _("%B(%A+%#Lx): %s used with non-TLS symbol %s")),
             input_bfd,
-            input_section, (long) rel->r_offset, howto->name, name);
+            input_section, rel->r_offset, howto->name, name);
        }
 
       /* We relax only if we can see that there can be a valid transition
@@ -6434,8 +6428,8 @@ elfNN_aarch64_relocate_section (bfd *output_bfd,
        {
          _bfd_error_handler
            /* xgettext:c-format */
-           (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
-            input_bfd, input_section, (long) rel->r_offset, howto->name,
+           (_("%B(%A+%#Lx): unresolvable %s relocation against symbol `%s'"),
+            input_bfd, input_section, rel->r_offset, howto->name,
             h->root.root.string);
          return FALSE;
        }
@@ -7101,7 +7095,7 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
   for (rel = relocs; rel < rel_end; rel++)
     {
       struct elf_link_hash_entry *h;
-      unsigned long r_symndx;
+      unsigned int r_symndx;
       unsigned int r_type;
       bfd_reloc_code_real_type bfd_r_type;
       Elf_Internal_Sym *isym;
@@ -7634,8 +7628,39 @@ elfNN_aarch64_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSE
                                const asection *rel_sec ATTRIBUTE_UNUSED,
                                const Elf_Internal_Rela *rela)
 {
+  struct elf_aarch64_link_hash_table *htab = elf_aarch64_hash_table (info);
+
+  if (htab->root.dynsym != NULL
+      && htab->root.dynsym->contents != NULL)
+    {
+      /* Check relocation against STT_GNU_IFUNC symbol if there are
+        dynamic symbols.  */
+      bfd *abfd = info->output_bfd;
+      const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+      unsigned long r_symndx = ELFNN_R_SYM (rela->r_info);
+      if (r_symndx != STN_UNDEF)
+       {
+         Elf_Internal_Sym sym;
+         if (!bed->s->swap_symbol_in (abfd,
+                                      (htab->root.dynsym->contents
+                                       + r_symndx * bed->s->sizeof_sym),
+                                      0, &sym))
+           {
+             /* xgettext:c-format */
+             _bfd_error_handler (_("%B symbol number %lu references"
+                                   " nonexistent SHT_SYMTAB_SHNDX section"),
+                                   abfd, r_symndx);
+             /* Ideally an error class should be returned here.  */
+           }
+         else if (ELF_ST_TYPE (sym.st_info) == STT_GNU_IFUNC)
+           return reloc_class_ifunc;
+       }
+    }
+
   switch ((int) ELFNN_R_TYPE (rela->r_info))
     {
+    case AARCH64_R (IRELATIVE):
+      return reloc_class_ifunc;
     case AARCH64_R (RELATIVE):
       return reloc_class_relative;
     case AARCH64_R (JUMP_SLOT):