Automatic date update in version.in
[deliverable/binutils-gdb.git] / bfd / elfnn-aarch64.c
index 599b5f8516acbd51cc5123af4550f9d689b5d13d..774364a83aa481c066cd38dfb55500c44e5f77a0 100644 (file)
@@ -339,8 +339,8 @@ static reloc_howto_type elfNN_aarch64_howto_table[] =
 
   /* Basic data relocations.  */
 
-#if ARCH_SIZE == 64
-  HOWTO (R_AARCH64_NULL,       /* type */
+  /* Deprecated, but retained for backwards compatibility.  */
+  HOWTO64 (R_AARCH64_NULL,     /* type */
         0,                     /* rightshift */
         3,                     /* size (0 = byte, 1 = short, 2 = long) */
         0,                     /* bitsize */
@@ -353,7 +353,6 @@ static reloc_howto_type elfNN_aarch64_howto_table[] =
         0,                     /* src_mask */
         0,                     /* dst_mask */
         FALSE),                /* pcrel_offset */
-#else
   HOWTO (R_AARCH64_NONE,       /* type */
         0,                     /* rightshift */
         3,                     /* size (0 = byte, 1 = short, 2 = long) */
@@ -367,7 +366,6 @@ static reloc_howto_type elfNN_aarch64_howto_table[] =
         0,                     /* src_mask */
         0,                     /* dst_mask */
         FALSE),                /* pcrel_offset */
-#endif
 
   /* .xword: (S+A) */
   HOWTO64 (AARCH64_R (ABS64),  /* type */
@@ -2289,6 +2287,9 @@ struct elf_aarch64_link_hash_table
   /* Enable ADRP->ADR rewrite for erratum 843419 workaround.  */
   int fix_erratum_843419_adr;
 
+  /* Don't apply link-time values for dynamic relocations.  */
+  int no_apply_dynamic_relocs;
+
   /* The number of bytes in the initial entry in the PLT.  */
   bfd_size_type plt_header_size;
 
@@ -4334,7 +4335,8 @@ bfd_elfNN_aarch64_set_options (struct bfd *output_bfd,
                               int no_enum_warn,
                               int no_wchar_warn, int pic_veneer,
                               int fix_erratum_835769,
-                              int fix_erratum_843419)
+                              int fix_erratum_843419,
+                              int no_apply_dynamic_relocs)
 {
   struct elf_aarch64_link_hash_table *globals;
 
@@ -4343,6 +4345,7 @@ bfd_elfNN_aarch64_set_options (struct bfd *output_bfd,
   globals->fix_erratum_835769 = fix_erratum_835769;
   globals->fix_erratum_843419 = fix_erratum_843419;
   globals->fix_erratum_843419_adr = TRUE;
+  globals->no_apply_dynamic_relocs = no_apply_dynamic_relocs;
 
   BFD_ASSERT (is_aarch64_elf (output_bfd));
   elf_aarch64_tdata (output_bfd)->no_enum_size_warning = no_enum_warn;
@@ -4890,7 +4893,9 @@ elfNN_aarch64_write_section (bfd *output_bfd  ATTRIBUTE_UNUSED,
   return FALSE;
 }
 
-/* Perform a relocation as part of a final link.  */
+/* Perform a relocation as part of a final link.  The input relocation type
+   should be TLS relaxed.  */
+
 static bfd_reloc_status_type
 elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
                                   bfd *input_bfd,
@@ -4911,7 +4916,6 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
   unsigned int r_type = howto->type;
   bfd_reloc_code_real_type bfd_r_type
     = elfNN_aarch64_bfd_reloc_from_howto (howto);
-  bfd_reloc_code_real_type new_bfd_r_type;
   unsigned long r_symndx;
   bfd_byte *hit_data = contents + rel->r_offset;
   bfd_vma place, off;
@@ -4928,17 +4932,6 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
 
   r_symndx = ELFNN_R_SYM (rel->r_info);
 
-  /* It is possible to have linker relaxations on some TLS access
-     models.  Update our information here.  */
-  new_bfd_r_type = aarch64_tls_transition (input_bfd, info, r_type, h, r_symndx);
-  if (new_bfd_r_type != bfd_r_type)
-    {
-      bfd_r_type = new_bfd_r_type;
-      howto = elfNN_aarch64_howto_from_bfd_reloc (bfd_r_type);
-      BFD_ASSERT (howto != NULL);
-      r_type = howto->type;
-    }
-
   place = input_section->output_section->vma
     + input_section->output_offset + rel->r_offset;
 
@@ -5208,6 +5201,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
                 relocate the text and data segments independently,
                 so the symbol does not matter.  */
              symbol = 0;
+             relocate = globals->no_apply_dynamic_relocs ? FALSE : TRUE;
              outrel.r_info = ELFNN_R_INFO (symbol, AARCH64_R (RELATIVE));
              outrel.r_addend += value;
            }
@@ -6069,13 +6063,10 @@ elfNN_aarch64_relocate_section (bfd *output_bfd,
          if (r_type != R_AARCH64_NONE && r_type != R_AARCH64_NULL
              && bfd_is_und_section (sec)
              && ELF_ST_BIND (sym->st_info) != STB_WEAK)
-           {
-             if (!info->callbacks->undefined_symbol
-                 (info, bfd_elf_string_from_elf_section
-                  (input_bfd, symtab_hdr->sh_link, sym->st_name),
-                  input_bfd, input_section, rel->r_offset, TRUE))
-               return FALSE;
-           }
+           (*info->callbacks->undefined_symbol)
+             (info, bfd_elf_string_from_elf_section
+              (input_bfd, symtab_hdr->sh_link, sym->st_name),
+              input_bfd, input_section, rel->r_offset, TRUE);
 
          relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
 
@@ -6417,10 +6408,9 @@ elfNN_aarch64_relocate_section (bfd *output_bfd,
          switch (r)
            {
            case bfd_reloc_overflow:
-             if (!(*info->callbacks->reloc_overflow)
-                 (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0,
-                  input_bfd, input_section, rel->r_offset))
-               return FALSE;
+             (*info->callbacks->reloc_overflow)
+               (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0,
+                input_bfd, input_section, rel->r_offset);
              if (real_r_type == BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
                  || real_r_type == BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14)
                {
@@ -6462,10 +6452,8 @@ alignment than was declared where it was defined."),
              break;
 
            case bfd_reloc_undefined:
-             if (!((*info->callbacks->undefined_symbol)
-                   (info, name, input_bfd, input_section,
-                    rel->r_offset, TRUE)))
-               return FALSE;
+             (*info->callbacks->undefined_symbol)
+               (info, name, input_bfd, input_section, rel->r_offset, TRUE);
              break;
 
            case bfd_reloc_outofrange:
@@ -6486,10 +6474,8 @@ alignment than was declared where it was defined."),
 
            common_error:
              BFD_ASSERT (error_message != NULL);
-             if (!((*info->callbacks->reloc_dangerous)
-                   (info, error_message, input_bfd, input_section,
-                    rel->r_offset)))
-               return FALSE;
+             (*info->callbacks->reloc_dangerous)
+               (info, error_message, input_bfd, input_section, rel->r_offset);
              break;
            }
        }
@@ -7080,6 +7066,22 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
 
       if (h != NULL)
        {
+         /* If a relocation refers to _GLOBAL_OFFSET_TABLE_, create the .got.
+            This shows up in particular in an R_AARCH64_PREL64 in large model
+            when calculating the pc-relative address to .got section which is
+            used to initialize the gp register.  */
+         if (h->root.root.string
+             && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+           {
+             if (htab->root.dynobj == NULL)
+               htab->root.dynobj = abfd;
+
+             if (! aarch64_elf_create_got_section (htab->root.dynobj, info))
+               return FALSE;
+
+             BFD_ASSERT (h == htab->root.hgot);
+           }
+
          /* Create the ifunc sections for static executables.  If we
             never see an indirect function symbol nor we are building
             a static executable, those sections will be empty and
@@ -8233,6 +8235,7 @@ elfNN_aarch64_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h,
       && h->def_regular)
     return _bfd_elf_allocate_ifunc_dyn_relocs (info, h,
                                               &eh->dyn_relocs,
+                                              NULL,
                                               htab->plt_entry_size,
                                               htab->plt_header_size,
                                               GOT_ENTRY_SIZE);
@@ -9040,7 +9043,8 @@ elfNN_aarch64_finish_dynamic_sections (bfd *output_bfd,
              break;
 
            case DT_JMPREL:
-             dyn.d_un.d_ptr = htab->root.srelplt->output_section->vma;
+             s = htab->root.srelplt;
+             dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
              break;
 
            case DT_PLTRELSZ:
This page took 0.026845 seconds and 4 git commands to generate.