Automatic date update in version.in
[deliverable/binutils-gdb.git] / bfd / elfnn-aarch64.c
index 3104de78388cddca01622a450ab1e8757cbdf6d7..3471d7e0948445217ac99b8cdc46a5f27fc52754 100644 (file)
 #endif
 
 #define IS_AARCH64_TLS_RELOC(R_TYPE)                           \
-  ((R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21              \
+  ((R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC             \
+   || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21           \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADR_PREL21           \
-   || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC          \
-   || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1     \
-   || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC  \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21  \
-   || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC        \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC        \
+   || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC        \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19   \
-   || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12       \
+   || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC  \
+   || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1     \
+   || (R_TYPE) == BFD_RELOC_AARCH64_TLSLD_ADR_PREL21           \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12       \
+   || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12       \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC    \
-   || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2                \
-   || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1                \
-   || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC     \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0                \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC     \
+   || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1                \
+   || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC     \
+   || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2                \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLS_DTPMOD                 \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLS_DTPREL                 \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLS_TPREL                  \
    || IS_AARCH64_TLSDESC_RELOC ((R_TYPE)))
 
 #define IS_AARCH64_TLSDESC_RELOC(R_TYPE)                       \
-  ((R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD_PREL19             \
+  ((R_TYPE) == BFD_RELOC_AARCH64_TLSDESC                       \
+   || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD                        \
+   || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC                \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21         \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21         \
-   || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC                \
-   || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC       \
+   || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_CALL               \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC       \
-   || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G1             \
-   || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC          \
+   || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC       \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDR                        \
-   || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD                        \
-   || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_CALL               \
-   || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC)
+   || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD_PREL19          \
+   || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC          \
+   || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G1)
 
 #define ELIMINATE_COPY_RELOCS 0
 
@@ -848,6 +849,21 @@ static reloc_howto_type elfNN_aarch64_howto_table[] =
         0xffc,                 /* dst_mask */
         FALSE),                /* pcrel_offset */
 
+  /* LD64: GOT offset for the symbol.  */
+  HOWTO64 (AARCH64_R (LD64_GOTOFF_LO15),       /* type */
+        3,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        12,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_unsigned,    /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        AARCH64_R_STR (LD64_GOTOFF_LO15),      /* name */
+        FALSE,                 /* partial_inplace */
+        0x7ff8,                        /* src_mask */
+        0x7ff8,                        /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
   /* LD32: GOT offset to the page address of GOT table.
      (G(S) - PAGE (_GLOBAL_OFFSET_TABLE_)) & 0x5ffc.  */
   HOWTO32 (AARCH64_R (LD32_GOTPAGE_LO14),      /* type */
@@ -1009,6 +1025,20 @@ static reloc_howto_type elfNN_aarch64_howto_table[] =
         0x1ffffc,              /* dst_mask */
         FALSE),                /* pcrel_offset */
 
+  HOWTO (AARCH64_R (TLSLD_ADR_PREL21), /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        21,                    /* bitsize */
+        TRUE,                  /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_signed,      /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        AARCH64_R_STR (TLSLD_ADR_PREL21),      /* name */
+        FALSE,                 /* partial_inplace */
+        0x1fffff,              /* src_mask */
+        0x1fffff,              /* dst_mask */
+        TRUE),                 /* pcrel_offset */
+
   HOWTO64 (AARCH64_R (TLSLE_MOVW_TPREL_G2),    /* type */
         32,                    /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
@@ -4067,6 +4097,7 @@ aarch64_reloc_got_type (bfd_reloc_code_real_type r_type)
     {
     case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
     case BFD_RELOC_AARCH64_GOT_LD_PREL19:
+    case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
     case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
     case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
     case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
@@ -4075,6 +4106,7 @@ aarch64_reloc_got_type (bfd_reloc_code_real_type r_type)
     case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
     case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
     case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:
+    case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
       return GOT_TLS_GD;
 
     case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
@@ -4621,6 +4653,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
                                              howto, value);
        case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
        case BFD_RELOC_AARCH64_GOT_LD_PREL19:
+       case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
        case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
        case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
        case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
@@ -4682,7 +4715,8 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
            value = aarch64_calculate_got_entry_vma (h, globals, info,
                                                     value, output_bfd,
                                                     unresolved_reloc_p);
-         if (bfd_r_type == BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15)
+         if (bfd_r_type == BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
+             || bfd_r_type == BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14)
            addend = (globals->root.sgot->output_section->vma
                      + globals->root.sgot->output_offset);
          value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
@@ -4890,6 +4924,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
 
     case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
     case BFD_RELOC_AARCH64_GOT_LD_PREL19:
+    case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
     case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
     case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
     case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
@@ -4902,7 +4937,8 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
          value = aarch64_calculate_got_entry_vma (h, globals, info, value,
                                                   output_bfd,
                                                   unresolved_reloc_p);
-         if (bfd_r_type == BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15)
+         if (bfd_r_type == BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
+             || bfd_r_type == BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14)
            addend = (globals->root.sgot->output_section->vma
                      + globals->root.sgot->output_offset);
          value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
@@ -4960,7 +4996,8 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
           the direct data access into indirect data access through GOT.  */
        value = got_entry_addr;
 
-       if (bfd_r_type == BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15)
+       if (bfd_r_type == BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15
+           || bfd_r_type == BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14)
          addend = base_got->output_section->vma + base_got->output_offset;
 
        value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
@@ -4976,6 +5013,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
     case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
     case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
     case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
+    case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
       if (globals->root.sgot == NULL)
        return bfd_reloc_notsupported;
 
@@ -5460,6 +5498,7 @@ elfNN_aarch64_relocate_section (bfd *output_bfd,
        case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
        case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
        case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:
+       case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
          if (! symbol_got_offset_mark_p (input_bfd, h, r_symndx))
            {
              bfd_boolean need_relocs = FALSE;
@@ -5492,7 +5531,17 @@ elfNN_aarch64_relocate_section (bfd *output_bfd,
                    * RELOC_SIZE (htab);
                  bfd_elfNN_swap_reloca_out (output_bfd, &rela, loc);
 
-                 if (indx == 0)
+                 if (elfNN_aarch64_bfd_reloc_from_type (r_type)
+                     == BFD_RELOC_AARCH64_TLSLD_ADR_PREL21)
+                   {
+                     /* For local dynamic, don't generate DTPREL in any case.
+                        Initialize the DTPREL slot into zero, so we get module
+                        base address when invoke runtime TLS resolver.  */
+                     bfd_put_NN (output_bfd, 0,
+                                 globals->root.sgot->contents + off
+                                 + GOT_ENTRY_SIZE);
+                   }
+                 else if (indx == 0)
                    {
                      bfd_put_NN (output_bfd,
                                  relocation - dtpoff_base (info),
@@ -5959,6 +6008,7 @@ elfNN_aarch64_gc_sweep_hook (bfd *abfd,
        {
        case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
        case BFD_RELOC_AARCH64_GOT_LD_PREL19:
+       case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
        case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
        case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
        case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
@@ -5975,6 +6025,7 @@ elfNN_aarch64_gc_sweep_hook (bfd *abfd,
        case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
        case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
        case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
+       case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
        case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12:
        case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12:
        case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
@@ -6317,6 +6368,7 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
            case BFD_RELOC_AARCH64_CALL26:
            case BFD_RELOC_AARCH64_GOT_LD_PREL19:
            case BFD_RELOC_AARCH64_JUMP26:
+           case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
            case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
            case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
            case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
@@ -6429,6 +6481,7 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
             there are no dangling GOT_PAGE relocs.  */
        case BFD_RELOC_AARCH64_ADR_GOT_PAGE:
        case BFD_RELOC_AARCH64_GOT_LD_PREL19:
+       case BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14:
        case BFD_RELOC_AARCH64_LD32_GOT_LO12_NC:
        case BFD_RELOC_AARCH64_LD64_GOTPAGE_LO15:
        case BFD_RELOC_AARCH64_LD64_GOT_LO12_NC:
@@ -6445,6 +6498,7 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
        case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
        case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
        case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
+       case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
        case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12:
        case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12:
        case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
@@ -7521,6 +7575,32 @@ elfNN_aarch64_allocate_local_ifunc_dynrelocs (void **slot, void *inf)
   return elfNN_aarch64_allocate_ifunc_dynrelocs (h, inf);
 }
 
+/* Find any dynamic relocs that apply to read-only sections.  */
+
+static bfd_boolean
+aarch64_readonly_dynrelocs (struct elf_link_hash_entry * h, void * inf)
+{
+  struct elf_aarch64_link_hash_entry * eh;
+  struct elf_dyn_relocs * p;
+
+  eh = (struct elf_aarch64_link_hash_entry *) h;
+  for (p = eh->dyn_relocs; p != NULL; p = p->next)
+    {
+      asection *s = p->sec;
+
+      if (s != NULL && (s->flags & SEC_READONLY) != 0)
+       {
+         struct bfd_link_info *info = (struct bfd_link_info *) inf;
+
+         info->flags |= DF_TEXTREL;
+
+         /* Not an error, just cut short the traversal.  */
+         return FALSE;
+       }
+    }
+  return TRUE;
+}
+
 /* This is the most important function of all . Innocuosly named
    though !  */
 static bfd_boolean
@@ -7808,6 +7888,10 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
 
          /* If any dynamic relocs apply to a read-only section,
             then we need a DT_TEXTREL entry.  */
+         if ((info->flags & DF_TEXTREL) == 0)
+           elf_link_hash_traverse (& htab->root, aarch64_readonly_dynrelocs,
+                                   info);
+
          if ((info->flags & DF_TEXTREL) != 0)
            {
              if (!add_dynamic_entry (DT_TEXTREL, 0))
This page took 0.030814 seconds and 4 git commands to generate.