Enable R_AARCH64_NONE for 64-bit code.
[deliverable/binutils-gdb.git] / bfd / elfnn-aarch64.c
index 7c9310f6842b0d40dedeea31524f740e7d46e9b1..d30983aa88ef37995b90a67d8870b75150f52afb 100644 (file)
@@ -1,5 +1,5 @@
 /* AArch64-specific support for NN-bit ELF.
 /* AArch64-specific support for NN-bit ELF.
-   Copyright (C) 2009-2015 Free Software Foundation, Inc.
+   Copyright (C) 2009-2016 Free Software Foundation, Inc.
    Contributed by ARM Ltd.
 
    This file is part of BFD, the Binary File Descriptor library.
    Contributed by ARM Ltd.
 
    This file is part of BFD, the Binary File Descriptor library.
    || IS_AARCH64_TLSDESC_RELOC ((R_TYPE)))
 
 #define IS_AARCH64_TLS_RELAX_RELOC(R_TYPE)                     \
    || IS_AARCH64_TLSDESC_RELOC ((R_TYPE)))
 
 #define IS_AARCH64_TLS_RELAX_RELOC(R_TYPE)                     \
-  ((R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC           \
+  ((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_CALL               \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD_PREL19          \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC       \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21         \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21         \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_CALL               \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LD_PREL19          \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC       \
+   || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDR                        \
+   || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC          \
+   || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_OFF_G1             \
+   || (R_TYPE) == BFD_RELOC_AARCH64_TLSDESC_LDR                        \
    || (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_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_TLSGD_MOVW_G0_NC           \
+   || (R_TYPE) == BFD_RELOC_AARCH64_TLSGD_MOVW_G1              \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21  \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19   \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC        \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21  \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19   \
    || (R_TYPE) == BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC        \
@@ -332,8 +339,8 @@ static reloc_howto_type elfNN_aarch64_howto_table[] =
 
   /* Basic data relocations.  */
 
 
   /* 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 */
         0,                     /* rightshift */
         3,                     /* size (0 = byte, 1 = short, 2 = long) */
         0,                     /* bitsize */
@@ -346,7 +353,6 @@ static reloc_howto_type elfNN_aarch64_howto_table[] =
         0,                     /* src_mask */
         0,                     /* dst_mask */
         FALSE),                /* pcrel_offset */
         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) */
   HOWTO (R_AARCH64_NONE,       /* type */
         0,                     /* rightshift */
         3,                     /* size (0 = byte, 1 = short, 2 = long) */
@@ -360,7 +366,6 @@ static reloc_howto_type elfNN_aarch64_howto_table[] =
         0,                     /* src_mask */
         0,                     /* dst_mask */
         FALSE),                /* pcrel_offset */
         0,                     /* src_mask */
         0,                     /* dst_mask */
         FALSE),                /* pcrel_offset */
-#endif
 
   /* .xword: (S+A) */
   HOWTO64 (AARCH64_R (ABS64),  /* type */
 
   /* .xword: (S+A) */
   HOWTO64 (AARCH64_R (ABS64),  /* type */
@@ -568,7 +573,7 @@ static reloc_howto_type elfNN_aarch64_howto_table[] =
   HOWTO (AARCH64_R (MOVW_SABS_G0),     /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
   HOWTO (AARCH64_R (MOVW_SABS_G0),     /* type */
         0,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
+        17,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed,      /* complain_on_overflow */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed,      /* complain_on_overflow */
@@ -583,7 +588,7 @@ static reloc_howto_type elfNN_aarch64_howto_table[] =
   HOWTO64 (AARCH64_R (MOVW_SABS_G1),   /* type */
         16,                    /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
   HOWTO64 (AARCH64_R (MOVW_SABS_G1),   /* type */
         16,                    /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
+        17,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed,      /* complain_on_overflow */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed,      /* complain_on_overflow */
@@ -598,7 +603,7 @@ static reloc_howto_type elfNN_aarch64_howto_table[] =
   HOWTO64 (AARCH64_R (MOVW_SABS_G2),   /* type */
         32,                    /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
   HOWTO64 (AARCH64_R (MOVW_SABS_G2),   /* type */
         32,                    /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
+        17,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed,      /* complain_on_overflow */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed,      /* complain_on_overflow */
@@ -1038,34 +1043,6 @@ static reloc_howto_type elfNN_aarch64_howto_table[] =
         0xffff,                /* dst_mask */
         FALSE),                /* pcrel_offset */
 
         0xffff,                /* dst_mask */
         FALSE),                /* pcrel_offset */
 
-  HOWTO64 (AARCH64_R (TLSIE_MOVW_GOTTPREL_G1), /* type */
-        16,                    /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont,        /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
-        AARCH64_R_STR (TLSIE_MOVW_GOTTPREL_G1),        /* name */
-        FALSE,                 /* partial_inplace */
-        0xffff,                /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
-
-  HOWTO64 (AARCH64_R (TLSIE_MOVW_GOTTPREL_G0_NC),      /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        FALSE,                 /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont,        /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
-        AARCH64_R_STR (TLSIE_MOVW_GOTTPREL_G0_NC),     /* name */
-        FALSE,                 /* partial_inplace */
-        0xffff,                /* src_mask */
-        0xffff,                /* dst_mask */
-        FALSE),                /* pcrel_offset */
-
   HOWTO (AARCH64_R (TLSIE_ADR_GOTTPREL_PAGE21),        /* type */
         12,                    /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
   HOWTO (AARCH64_R (TLSIE_ADR_GOTTPREL_PAGE21),        /* type */
         12,                    /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
@@ -1122,6 +1099,34 @@ static reloc_howto_type elfNN_aarch64_howto_table[] =
         0x1ffffc,              /* dst_mask */
         FALSE),                /* pcrel_offset */
 
         0x1ffffc,              /* dst_mask */
         FALSE),                /* pcrel_offset */
 
+  HOWTO64 (AARCH64_R (TLSIE_MOVW_GOTTPREL_G0_NC),      /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_dont,        /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        AARCH64_R_STR (TLSIE_MOVW_GOTTPREL_G0_NC),     /* name */
+        FALSE,                 /* partial_inplace */
+        0xffff,                /* src_mask */
+        0xffff,                /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  HOWTO64 (AARCH64_R (TLSIE_MOVW_GOTTPREL_G1), /* type */
+        16,                    /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_unsigned,    /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        AARCH64_R_STR (TLSIE_MOVW_GOTTPREL_G1),        /* name */
+        FALSE,                 /* partial_inplace */
+        0xffff,                /* src_mask */
+        0xffff,                /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
   /* ADD: bit[23:12] of byte offset to module TLS base address.  */
   HOWTO (AARCH64_R (TLSLD_ADD_DTPREL_HI12),    /* type */
         12,                    /* rightshift */
   /* ADD: bit[23:12] of byte offset to module TLS base address.  */
   HOWTO (AARCH64_R (TLSLD_ADD_DTPREL_HI12),    /* type */
         12,                    /* rightshift */
@@ -1614,7 +1619,7 @@ static reloc_howto_type elfNN_aarch64_howto_table[] =
         12,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         12,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_dont,        /* complain_on_overflow */
+        complain_overflow_unsigned,    /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         AARCH64_R_STR (TLSDESC_OFF_G1),        /* name */
         FALSE,                 /* partial_inplace */
         bfd_elf_generic_reloc, /* special_function */
         AARCH64_R_STR (TLSDESC_OFF_G1),        /* name */
         FALSE,                 /* partial_inplace */
@@ -2282,6 +2287,9 @@ struct elf_aarch64_link_hash_table
   /* Enable ADRP->ADR rewrite for erratum 843419 workaround.  */
   int fix_erratum_843419_adr;
 
   /* 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;
 
   /* The number of bytes in the initial entry in the PLT.  */
   bfd_size_type plt_header_size;
 
@@ -2632,34 +2640,21 @@ aarch64_select_branch_stub (bfd_vma value, bfd_vma place)
 /* Determine the type of stub needed, if any, for a call.  */
 
 static enum elf_aarch64_stub_type
 /* Determine the type of stub needed, if any, for a call.  */
 
 static enum elf_aarch64_stub_type
-aarch64_type_of_stub (struct bfd_link_info *info,
-                     asection *input_sec,
+aarch64_type_of_stub (asection *input_sec,
                      const Elf_Internal_Rela *rel,
                      asection *sym_sec,
                      unsigned char st_type,
                      const Elf_Internal_Rela *rel,
                      asection *sym_sec,
                      unsigned char st_type,
-                     struct elf_aarch64_link_hash_entry *hash,
                      bfd_vma destination)
 {
   bfd_vma location;
   bfd_signed_vma branch_offset;
   unsigned int r_type;
                      bfd_vma destination)
 {
   bfd_vma location;
   bfd_signed_vma branch_offset;
   unsigned int r_type;
-  struct elf_aarch64_link_hash_table *globals;
   enum elf_aarch64_stub_type stub_type = aarch64_stub_none;
   enum elf_aarch64_stub_type stub_type = aarch64_stub_none;
-  bfd_boolean via_plt_p;
 
   if (st_type != STT_FUNC
 
   if (st_type != STT_FUNC
-      && (sym_sec != bfd_abs_section_ptr))
+      && (sym_sec == input_sec))
     return stub_type;
 
     return stub_type;
 
-  globals = elf_aarch64_hash_table (info);
-  via_plt_p = (globals->root.splt != NULL && hash != NULL
-              && hash->root.plt.offset != (bfd_vma) - 1);
-  /* Make sure call to plt stub can fit into the branch range.  */
-  if (via_plt_p)
-    destination = (globals->root.splt->output_section->vma
-                  + globals->root.splt->output_offset
-                  + hash->root.plt.offset);
-
   /* Determine where the call point is.  */
   location = (input_sec->output_offset
              + input_sec->output_section->vma + rel->r_offset);
   /* Determine where the call point is.  */
   location = (input_sec->output_offset
              + input_sec->output_section->vma + rel->r_offset);
@@ -4135,8 +4130,8 @@ elfNN_aarch64_size_stubs (bfd *output_bfd,
                    }
 
                  /* Determine what (if any) linker stub is needed.  */
                    }
 
                  /* Determine what (if any) linker stub is needed.  */
-                 stub_type = aarch64_type_of_stub
-                   (info, section, irela, sym_sec, st_type, hash, destination);
+                 stub_type = aarch64_type_of_stub (section, irela, sym_sec,
+                                                   st_type, destination);
                  if (stub_type == aarch64_stub_none)
                    continue;
 
                  if (stub_type == aarch64_stub_none)
                    continue;
 
@@ -4167,7 +4162,7 @@ elfNN_aarch64_size_stubs (bfd *output_bfd,
                      goto error_ret_free_internal;
                    }
 
                      goto error_ret_free_internal;
                    }
 
-                 stub_entry->target_value = sym_value;
+                 stub_entry->target_value = sym_value + irela->r_addend;
                  stub_entry->target_section = sym_sec;
                  stub_entry->stub_type = stub_type;
                  stub_entry->h = hash;
                  stub_entry->target_section = sym_sec;
                  stub_entry->stub_type = stub_type;
                  stub_entry->h = hash;
@@ -4340,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 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;
 
 {
   struct elf_aarch64_link_hash_table *globals;
 
@@ -4349,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->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;
 
   BFD_ASSERT (is_aarch64_elf (output_bfd));
   elf_aarch64_tdata (output_bfd)->no_enum_size_warning = no_enum_warn;
@@ -4430,6 +4427,21 @@ aarch64_tls_transition_without_check (bfd_reloc_code_real_type r_type,
              ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
              : BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19);
 
              ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1
              : BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19);
 
+    case BFD_RELOC_AARCH64_TLSDESC_LDR:
+      return (is_local
+             ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC
+             : BFD_RELOC_AARCH64_NONE);
+
+    case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC:
+      return (is_local
+             ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
+             : BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC);
+
+    case BFD_RELOC_AARCH64_TLSDESC_OFF_G1:
+      return (is_local
+             ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
+             : BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1);
+
     case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC:
     case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
       return (is_local
     case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC:
     case BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC:
       return (is_local
@@ -4450,6 +4462,7 @@ aarch64_tls_transition_without_check (bfd_reloc_code_real_type r_type,
              ? BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
              : BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19);
 
              ? BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12
              : BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19);
 
+    case BFD_RELOC_AARCH64_TLSDESC_ADD:
     case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
     case BFD_RELOC_AARCH64_TLSDESC_CALL:
       /* Instructions with these relocations will become NOPs.  */
     case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
     case BFD_RELOC_AARCH64_TLSDESC_CALL:
       /* Instructions with these relocations will become NOPs.  */
@@ -4460,6 +4473,18 @@ aarch64_tls_transition_without_check (bfd_reloc_code_real_type r_type,
     case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
       return is_local ? BFD_RELOC_AARCH64_NONE : r_type;
 
     case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
       return is_local ? BFD_RELOC_AARCH64_NONE : r_type;
 
+#if ARCH_SIZE == 64
+    case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC:
+      return is_local
+       ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC
+       : BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC;
+
+    case BFD_RELOC_AARCH64_TLSGD_MOVW_G1:
+      return is_local
+       ? BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2
+       : BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1;
+#endif
+
     default:
       break;
     }
     default:
       break;
     }
@@ -4493,6 +4518,7 @@ aarch64_reloc_got_type (bfd_reloc_code_real_type r_type)
     case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
       return GOT_TLS_GD;
 
     case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
       return GOT_TLS_GD;
 
+    case BFD_RELOC_AARCH64_TLSDESC_ADD:
     case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
     case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
     case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
     case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
     case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
     case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
@@ -4500,12 +4526,17 @@ aarch64_reloc_got_type (bfd_reloc_code_real_type r_type)
     case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
     case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC:
     case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
     case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
     case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC:
     case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
+    case BFD_RELOC_AARCH64_TLSDESC_LDR:
+    case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC:
+    case BFD_RELOC_AARCH64_TLSDESC_OFF_G1:
       return GOT_TLSDESC_GD;
 
     case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
     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:
       return GOT_TLSDESC_GD;
 
     case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
     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_TLSIE_MOVW_GOTTPREL_G0_NC:
+    case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1:
       return GOT_TLS_IE;
 
     default:
       return GOT_TLS_IE;
 
     default:
@@ -4862,7 +4893,9 @@ elfNN_aarch64_write_section (bfd *output_bfd  ATTRIBUTE_UNUSED,
   return FALSE;
 }
 
   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,
 static bfd_reloc_status_type
 elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
                                   bfd *input_bfd,
@@ -4883,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);
   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;
   unsigned long r_symndx;
   bfd_byte *hit_data = contents + rel->r_offset;
   bfd_vma place, off;
@@ -4900,17 +4932,6 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
 
   r_symndx = ELFNN_R_SYM (rel->r_info);
 
 
   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;
 
   place = input_section->output_section->vma
     + input_section->output_offset + rel->r_offset;
 
@@ -5121,7 +5142,9 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
   switch (bfd_r_type)
     {
     case BFD_RELOC_AARCH64_NONE:
   switch (bfd_r_type)
     {
     case BFD_RELOC_AARCH64_NONE:
+    case BFD_RELOC_AARCH64_TLSDESC_ADD:
     case BFD_RELOC_AARCH64_TLSDESC_CALL:
     case BFD_RELOC_AARCH64_TLSDESC_CALL:
+    case BFD_RELOC_AARCH64_TLSDESC_LDR:
       *unresolved_reloc_p = FALSE;
       return bfd_reloc_ok;
 
       *unresolved_reloc_p = FALSE;
       return bfd_reloc_ok;
 
@@ -5178,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 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;
            }
              outrel.r_info = ELFNN_R_INFO (symbol, AARCH64_R (RELATIVE));
              outrel.r_addend += value;
            }
@@ -5237,15 +5261,28 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
        /* Check if a stub has to be inserted because the destination
           is too far away.  */
        struct elf_aarch64_stub_hash_entry *stub_entry = NULL;
        /* Check if a stub has to be inserted because the destination
           is too far away.  */
        struct elf_aarch64_stub_hash_entry *stub_entry = NULL;
-       if (! aarch64_valid_branch_p (value, place))
+
+       /* If the branch destination is directed to plt stub, "value" will be
+          the final destination, otherwise we should plus signed_addend, it may
+          contain non-zero value, for example call to local function symbol
+          which are turned into "sec_sym + sec_off", and sec_off is kept in
+          signed_addend.  */
+       if (! aarch64_valid_branch_p (via_plt_p ? value : value + signed_addend,
+                                     place))
          /* The target is out of reach, so redirect the branch to
             the local stub for this function.  */
        stub_entry = elfNN_aarch64_get_stub_entry (input_section, sym_sec, h,
                                                   rel, globals);
        if (stub_entry != NULL)
          /* The target is out of reach, so redirect the branch to
             the local stub for this function.  */
        stub_entry = elfNN_aarch64_get_stub_entry (input_section, sym_sec, h,
                                                   rel, globals);
        if (stub_entry != NULL)
-         value = (stub_entry->stub_offset
-                  + stub_entry->stub_sec->output_offset
-                  + stub_entry->stub_sec->output_section->vma);
+         {
+           value = (stub_entry->stub_offset
+                    + stub_entry->stub_sec->output_offset
+                    + stub_entry->stub_sec->output_section->vma);
+
+           /* We have redirected the destination to stub entry address,
+              so ignore any addend record in the original rela entry.  */
+           signed_addend = 0;
+         }
       }
       value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
                                                   signed_addend, weak_undef_p);
       }
       value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
                                                   signed_addend, weak_undef_p);
@@ -5476,6 +5513,8 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
 
     case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC:
     case BFD_RELOC_AARCH64_TLSGD_MOVW_G1:
 
     case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC:
     case BFD_RELOC_AARCH64_TLSGD_MOVW_G1:
+    case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC:
+    case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1:
       if (globals->root.sgot == NULL)
        return bfd_reloc_notsupported;
 
       if (globals->root.sgot == NULL)
        return bfd_reloc_notsupported;
 
@@ -5520,13 +5559,11 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
       *unresolved_reloc_p = FALSE;
       break;
 
       *unresolved_reloc_p = FALSE;
       break;
 
-    case BFD_RELOC_AARCH64_TLSDESC_ADD:
     case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
     case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
     case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
     case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
     case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC:
     case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
     case BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21:
     case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
     case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
     case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC:
-    case BFD_RELOC_AARCH64_TLSDESC_LDR:
     case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
       if (globals->root.sgot == NULL)
        return bfd_reloc_notsupported;
     case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
       if (globals->root.sgot == NULL)
        return bfd_reloc_notsupported;
@@ -5540,6 +5577,24 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
       *unresolved_reloc_p = FALSE;
       break;
 
       *unresolved_reloc_p = FALSE;
       break;
 
+    case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC:
+    case BFD_RELOC_AARCH64_TLSDESC_OFF_G1:
+      if (globals->root.sgot == NULL)
+       return bfd_reloc_notsupported;
+
+      value = (symbol_tlsdesc_got_offset (input_bfd, h, r_symndx)
+              + globals->root.sgotplt->output_section->vma
+              + globals->root.sgotplt->output_offset
+              + globals->sgotplt_jump_table_size);
+
+      value -= (globals->root.sgot->output_section->vma
+               + globals->root.sgot->output_offset);
+
+      value = _bfd_aarch64_elf_resolve_relocation (bfd_r_type, place, value,
+                                                  0, weak_undef_p);
+      *unresolved_reloc_p = FALSE;
+      break;
+
     default:
       return bfd_reloc_notsupported;
     }
     default:
       return bfd_reloc_notsupported;
     }
@@ -5688,6 +5743,52 @@ elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
          return bfd_reloc_continue;
        }
 
          return bfd_reloc_continue;
        }
 
+#if ARCH_SIZE == 64
+    case BFD_RELOC_AARCH64_TLSGD_MOVW_G1:
+      BFD_ASSERT (ELFNN_R_TYPE (rel[1].r_info) == AARCH64_R (TLSGD_MOVW_G0_NC));
+      BFD_ASSERT (rel->r_offset + 12 == rel[2].r_offset);
+      BFD_ASSERT (ELFNN_R_TYPE (rel[2].r_info) == AARCH64_R (CALL26));
+
+      if (is_local)
+       {
+         /* Large GD->LE relaxation:
+            movz x0, #:tlsgd_g1:var    => movz x0, #:tprel_g2:var, lsl #32
+            movk x0, #:tlsgd_g0_nc:var => movk x0, #:tprel_g1_nc:var, lsl #16
+            add x0, gp, x0             => movk x0, #:tprel_g0_nc:var
+            bl __tls_get_addr          => mrs x1, tpidr_el0
+            nop                        => add x0, x0, x1
+          */
+         rel[2].r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info),
+                                       AARCH64_R (TLSLE_MOVW_TPREL_G0_NC));
+         rel[2].r_offset = rel->r_offset + 8;
+
+         bfd_putl32 (0xd2c00000, contents + rel->r_offset + 0);
+         bfd_putl32 (0xf2a00000, contents + rel->r_offset + 4);
+         bfd_putl32 (0xf2800000, contents + rel->r_offset + 8);
+         bfd_putl32 (0xd53bd041, contents + rel->r_offset + 12);
+         bfd_putl32 (0x8b000020, contents + rel->r_offset + 16);
+       }
+      else
+       {
+         /* Large GD->IE relaxation:
+            movz x0, #:tlsgd_g1:var    => movz x0, #:gottprel_g1:var, lsl #16
+            movk x0, #:tlsgd_g0_nc:var => movk x0, #:gottprel_g0_nc:var
+            add x0, gp, x0             => ldr x0, [gp, x0]
+            bl __tls_get_addr          => mrs x1, tpidr_el0
+            nop                        => add x0, x0, x1
+          */
+         rel[2].r_info = ELFNN_R_INFO (STN_UNDEF, R_AARCH64_NONE);
+         bfd_putl32 (0xd2a80000, contents + rel->r_offset + 0);
+         bfd_putl32 (0x58000000, contents + rel->r_offset + 8);
+         bfd_putl32 (0xd53bd041, contents + rel->r_offset + 12);
+         bfd_putl32 (0x8b000020, contents + rel->r_offset + 16);
+       }
+      return bfd_reloc_continue;
+
+    case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC:
+      return bfd_reloc_continue;
+#endif
+
     case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
       return bfd_reloc_continue;
 
     case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
       return bfd_reloc_continue;
 
@@ -5753,6 +5854,7 @@ elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
          return bfd_reloc_continue;
        }
 
          return bfd_reloc_continue;
        }
 
+    case BFD_RELOC_AARCH64_TLSDESC_ADD:
     case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
     case BFD_RELOC_AARCH64_TLSDESC_CALL:
       /* GD->IE/LE relaxation:
     case BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC:
     case BFD_RELOC_AARCH64_TLSDESC_CALL:
       /* GD->IE/LE relaxation:
@@ -5762,6 +5864,55 @@ elfNN_aarch64_tls_relax (struct elf_aarch64_link_hash_table *globals,
       bfd_putl32 (INSN_NOP, contents + rel->r_offset);
       return bfd_reloc_ok;
 
       bfd_putl32 (INSN_NOP, contents + rel->r_offset);
       return bfd_reloc_ok;
 
+    case BFD_RELOC_AARCH64_TLSDESC_LDR:
+      if (is_local)
+       {
+         /* GD->LE relaxation:
+            ldr xd, [gp, xn]   =>   movk x0, #:tprel_g0_nc:var
+          */
+         bfd_putl32 (0xf2800000, contents + rel->r_offset);
+         return bfd_reloc_continue;
+       }
+      else
+       {
+         /* GD->IE relaxation:
+            ldr xd, [gp, xn]   =>   ldr x0, [gp, xn]
+          */
+         insn = bfd_getl32 (contents + rel->r_offset);
+         insn &= 0xffffffe0;
+         bfd_putl32 (insn, contents + rel->r_offset);
+         return bfd_reloc_ok;
+       }
+
+    case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC:
+      /* GD->LE relaxation:
+        movk xd, #:tlsdesc_off_g0_nc:var => movk x0, #:tprel_g1_nc:var, lsl #16
+        GD->IE relaxation:
+        movk xd, #:tlsdesc_off_g0_nc:var => movk xd, #:gottprel_g0_nc:var
+      */
+      if (is_local)
+       bfd_putl32 (0xf2a00000, contents + rel->r_offset);
+      return bfd_reloc_continue;
+
+    case BFD_RELOC_AARCH64_TLSDESC_OFF_G1:
+      if (is_local)
+       {
+         /* GD->LE relaxation:
+            movz xd, #:tlsdesc_off_g1:var => movz x0, #:tprel_g2:var, lsl #32
+         */
+         bfd_putl32 (0xd2c00000, contents + rel->r_offset);
+         return bfd_reloc_continue;
+       }
+      else
+       {
+         /*  GD->IE relaxation:
+             movz xd, #:tlsdesc_off_g1:var => movz xd, #:gottprel_g1:var, lsl #16
+         */
+         insn = bfd_getl32 (contents + rel->r_offset);
+         bfd_putl32 (0xd2a00000 | (insn & 0x1f), contents + rel->r_offset);
+         return bfd_reloc_continue;
+       }
+
     case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
       /* IE->LE relaxation:
          adrp xd, :gottprel:var   =>   movz xd, :tprel_g1:var
     case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
       /* IE->LE relaxation:
          adrp xd, :gottprel:var   =>   movz xd, :tprel_g1:var
@@ -6120,6 +6271,8 @@ elfNN_aarch64_relocate_section (bfd *output_bfd,
        case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
        case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC:
        case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
        case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
        case BFD_RELOC_AARCH64_TLSIE_LDNN_GOTTPREL_LO12_NC:
        case BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
+       case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC:
+       case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1:
          if (! symbol_got_offset_mark_p (input_bfd, h, r_symndx))
            {
              bfd_boolean need_relocs = FALSE;
          if (! symbol_got_offset_mark_p (input_bfd, h, r_symndx))
            {
              bfd_boolean need_relocs = FALSE;
@@ -6174,6 +6327,8 @@ elfNN_aarch64_relocate_section (bfd *output_bfd,
        case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
        case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC:
        case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
        case BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21:
        case BFD_RELOC_AARCH64_TLSDESC_LDNN_LO12_NC:
        case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
+       case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC:
+       case BFD_RELOC_AARCH64_TLSDESC_OFF_G1:
          if (! symbol_tlsdesc_got_offset_mark_p (input_bfd, h, r_symndx))
            {
              bfd_boolean need_relocs = FALSE;
          if (! symbol_tlsdesc_got_offset_mark_p (input_bfd, h, r_symndx))
            {
              bfd_boolean need_relocs = FALSE;
@@ -6231,10 +6386,6 @@ elfNN_aarch64_relocate_section (bfd *output_bfd,
          break;
        }
 
          break;
        }
 
-      if (!save_addend)
-       addend = 0;
-
-
       /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
          because such sections are not SEC_ALLOC and thus ld.so will
          not process them.  */
       /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
          because such sections are not SEC_ALLOC and thus ld.so will
          not process them.  */
@@ -6274,6 +6425,34 @@ elfNN_aarch64_relocate_section (bfd *output_bfd,
                     name, input_bfd, input_section, rel->r_offset);
                  return FALSE;
                }
                     name, input_bfd, input_section, rel->r_offset);
                  return FALSE;
                }
+             /* Overflow can occur when a variable is referenced with a type
+                that has a larger alignment than the type with which it was
+                declared. eg:
+                  file1.c: extern int foo; int a (void) { return foo; }
+                  file2.c: char bar, foo, baz;
+                If the variable is placed into a data section at an offset
+                that is incompatible with the larger alignment requirement
+                overflow will occur.  (Strictly speaking this is not overflow
+                but rather an alignment problem, but the bfd_reloc_ error
+                enum does not have a value to cover that situation).
+
+                Try to catch this situation here and provide a more helpful
+                error message to the user.  */
+             if (addend & ((1 << howto->rightshift) - 1)
+                 /* FIXME: Are we testing all of the appropriate reloc
+                    types here ?  */
+                 && (real_r_type == BFD_RELOC_AARCH64_LD_LO19_PCREL
+                     || real_r_type == BFD_RELOC_AARCH64_LDST16_LO12
+                     || real_r_type == BFD_RELOC_AARCH64_LDST32_LO12
+                     || real_r_type == BFD_RELOC_AARCH64_LDST64_LO12
+                     || real_r_type == BFD_RELOC_AARCH64_LDST128_LO12))
+               {
+                 info->callbacks->warning
+                   (info, _("One possible cause of this error is that the \
+symbol is being referenced in the indicated code as if it had a larger \
+alignment than was declared where it was defined."),
+                    name, input_bfd, input_section, rel->r_offset);
+               }
              break;
 
            case bfd_reloc_undefined:
              break;
 
            case bfd_reloc_undefined:
@@ -6308,6 +6487,9 @@ elfNN_aarch64_relocate_section (bfd *output_bfd,
              break;
            }
        }
              break;
            }
        }
+
+      if (!save_addend)
+       addend = 0;
     }
 
   return TRUE;
     }
 
   return TRUE;
@@ -6557,6 +6739,8 @@ elfNN_aarch64_gc_sweep_hook (bfd *abfd,
        case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
        case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC:
        case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
        case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
        case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC:
        case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
+       case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC:
+       case BFD_RELOC_AARCH64_TLSDESC_OFF_G1:
        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_TLSGD_ADD_LO12_NC:
        case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
        case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:
@@ -6566,6 +6750,8 @@ 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_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_TLSIE_MOVW_GOTTPREL_G0_NC:
+       case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1:
        case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC:
        case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21:
        case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
        case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC:
        case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21:
        case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
@@ -6888,6 +7074,22 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
 
       if (h != NULL)
        {
 
       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
          /* 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
@@ -7032,6 +7234,8 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
        case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
        case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC:
        case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
        case BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC:
        case BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC:
        case BFD_RELOC_AARCH64_TLSDESC_LD_PREL19:
+       case BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC:
+       case BFD_RELOC_AARCH64_TLSDESC_OFF_G1:
        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_TLSGD_ADD_LO12_NC:
        case BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21:
        case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:
@@ -7041,9 +7245,14 @@ 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_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_TLSIE_MOVW_GOTTPREL_G0_NC:
+       case BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1:
        case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC:
        case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21:
        case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
        case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC:
        case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21:
        case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
+       case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1:
+       case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
+       case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2:
          {
            unsigned got_type;
            unsigned old_got_type;
          {
            unsigned got_type;
            unsigned old_got_type;
@@ -8034,6 +8243,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,
       && 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);
                                               htab->plt_entry_size,
                                               htab->plt_header_size,
                                               GOT_ENTRY_SIZE);
@@ -8841,7 +9051,8 @@ elfNN_aarch64_finish_dynamic_sections (bfd *output_bfd,
              break;
 
            case DT_JMPREL:
              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:
              break;
 
            case DT_PLTRELSZ:
@@ -9164,3 +9375,22 @@ const struct elf_size_info elfNN_aarch64_size_info =
 #define elf_backend_obj_attrs_section          ".ARM.attributes"
 
 #include "elfNN-target.h"
 #define elf_backend_obj_attrs_section          ".ARM.attributes"
 
 #include "elfNN-target.h"
+
+/* CloudABI support.  */
+
+#undef TARGET_LITTLE_SYM
+#define        TARGET_LITTLE_SYM       aarch64_elfNN_le_cloudabi_vec
+#undef TARGET_LITTLE_NAME
+#define        TARGET_LITTLE_NAME      "elfNN-littleaarch64-cloudabi"
+#undef TARGET_BIG_SYM
+#define        TARGET_BIG_SYM          aarch64_elfNN_be_cloudabi_vec
+#undef TARGET_BIG_NAME
+#define        TARGET_BIG_NAME         "elfNN-bigaarch64-cloudabi"
+
+#undef ELF_OSABI
+#define        ELF_OSABI               ELFOSABI_CLOUDABI
+
+#undef elfNN_bed
+#define        elfNN_bed               elfNN_aarch64_cloudabi_bed
+
+#include "elfNN-target.h"
This page took 0.033705 seconds and 4 git commands to generate.