Generate aclocal-m4-deps.mk more deterministically and portably.
[deliverable/binutils-gdb.git] / bfd / elfnn-aarch64.c
index dc24df801e20d053912d52344f641a7566a17db6..ee09cd74117c717a399d0de262187b2dff57f5f9 100644 (file)
    || (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_LDST16_TPREL_LO12    \
+   || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12_NC \
+   || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12    \
+   || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12_NC \
+   || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12    \
+   || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12_NC \
+   || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12     \
+   || (R_TYPE) == BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12_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                \
@@ -1635,6 +1643,126 @@ static reloc_howto_type elfNN_aarch64_howto_table[] =
         0xfff,                 /* dst_mask */
         FALSE),                /* pcrel_offset */
 
+  /* LD/ST16: bit[11:1] of byte offset to module TLS base address.  */
+  HOWTO (AARCH64_R (TLSLE_LDST16_TPREL_LO12),  /* type */
+        1,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        11,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_unsigned,    /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        AARCH64_R_STR (TLSLE_LDST16_TPREL_LO12),       /* name */
+        FALSE,                 /* partial_inplace */
+        0x1ffc00,              /* src_mask */
+        0x1ffc00,              /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  /* Same as BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12, but no overflow check.  */
+  HOWTO (AARCH64_R (TLSLE_LDST16_TPREL_LO12_NC),       /* type */
+        1,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        11,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont,        /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        AARCH64_R_STR (TLSLE_LDST16_TPREL_LO12_NC),    /* name */
+        FALSE,                 /* partial_inplace */
+        0x1ffc00,              /* src_mask */
+        0x1ffc00,              /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  /* LD/ST32: bit[11:2] of byte offset to module TLS base address.  */
+  HOWTO (AARCH64_R (TLSLE_LDST32_TPREL_LO12),  /* type */
+        2,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        10,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_unsigned,    /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        AARCH64_R_STR (TLSLE_LDST32_TPREL_LO12),       /* name */
+        FALSE,                 /* partial_inplace */
+        0xffc00,               /* src_mask */
+        0xffc00,               /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  /* Same as BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12, but no overflow check.  */
+  HOWTO (AARCH64_R (TLSLE_LDST32_TPREL_LO12_NC),       /* type */
+        2,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        10,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont,        /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        AARCH64_R_STR (TLSLE_LDST32_TPREL_LO12_NC),    /* name */
+        FALSE,                 /* partial_inplace */
+        0xffc00,               /* src_mask */
+        0xffc00,               /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  /* LD/ST64: bit[11:3] of byte offset to module TLS base address.  */
+  HOWTO (AARCH64_R (TLSLE_LDST64_TPREL_LO12),  /* type */
+        3,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        9,                     /* bitsize */
+        FALSE,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_unsigned,    /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        AARCH64_R_STR (TLSLE_LDST64_TPREL_LO12),       /* name */
+        FALSE,                 /* partial_inplace */
+        0x7fc00,               /* src_mask */
+        0x7fc00,               /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  /* Same as BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12, but no overflow check.  */
+  HOWTO (AARCH64_R (TLSLE_LDST64_TPREL_LO12_NC),       /* type */
+        3,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        9,                     /* bitsize */
+        FALSE,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont,        /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        AARCH64_R_STR (TLSLE_LDST64_TPREL_LO12_NC),    /* name */
+        FALSE,                 /* partial_inplace */
+        0x7fc00,               /* src_mask */
+        0x7fc00,               /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  /* LD/ST8: bit[11:0] of byte offset to module TLS base address.  */
+  HOWTO (AARCH64_R (TLSLE_LDST8_TPREL_LO12),   /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        12,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_unsigned,    /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        AARCH64_R_STR (TLSLE_LDST8_TPREL_LO12),        /* name */
+        FALSE,                 /* partial_inplace */
+        0x3ffc00,              /* src_mask */
+        0x3ffc00,              /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
+  /* Same as BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12, but no overflow check.  */
+  HOWTO (AARCH64_R (TLSLE_LDST8_TPREL_LO12_NC),        /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        12,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        10,                    /* bitpos */
+        complain_overflow_dont,        /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        AARCH64_R_STR (TLSLE_LDST8_TPREL_LO12_NC),     /* name */
+        FALSE,                 /* partial_inplace */
+        0x3ffc00,              /* src_mask */
+        0x3ffc00,              /* dst_mask */
+        FALSE),                /* pcrel_offset */
+
   HOWTO (AARCH64_R (TLSDESC_LD_PREL19),        /* type */
         2,                     /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
@@ -3617,7 +3745,8 @@ _bfd_aarch64_erratum_835769_stub_name (unsigned num_fixes)
 {
   char *stub_name = (char *) bfd_malloc
     (strlen ("__erratum_835769_veneer_") + 16);
-  sprintf (stub_name,"__erratum_835769_veneer_%d", num_fixes);
+  if (stub_name != NULL)
+    sprintf (stub_name,"__erratum_835769_veneer_%d", num_fixes);
   return stub_name;
 }
 
@@ -3864,6 +3993,8 @@ _bfd_aarch64_erratum_843419_fixup (uint32_t insn,
   struct elf_aarch64_stub_hash_entry *stub_entry;
 
   stub_name = _bfd_aarch64_erratum_843419_stub_name (section, ldst_offset);
+  if (stub_name == NULL)
+    return FALSE;
   stub_entry = aarch64_stub_hash_lookup (&htab->stub_hash_table, stub_name,
                                         FALSE, FALSE);
   if (stub_entry)
@@ -3881,8 +4012,7 @@ _bfd_aarch64_erratum_843419_fixup (uint32_t insn,
      If we placed workaround veneers in any other stub section then we
      could not assume that all relocations have been processed on the
      corresponding input section at the point we output the stub
-     section.
-   */
+     section.  */
 
   stub_entry = _bfd_aarch64_add_stub_entry_after (stub_name, section, htab);
   if (stub_entry == NULL)
@@ -4284,6 +4414,9 @@ elfNN_aarch64_size_stubs (bfd *output_bfd,
                    {
                      /* The proper stub has already been created.  */
                      free (stub_name);
+                     /* Always update this stub's target since it may have
+                        changed after layout.  */
+                     stub_entry->target_value = sym_value + irela->r_addend;
                      continue;
                    }
 
@@ -5074,6 +5207,7 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
   asection *base_got;
   bfd_vma orig_value = value;
   bfd_boolean resolved_to_zero;
+  bfd_boolean abs_symbol_p;
 
   globals = elf_aarch64_hash_table (info);
 
@@ -5093,6 +5227,8 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
 
   weak_undef_p = (h ? h->root.type == bfd_link_hash_undefweak
                  : bfd_is_und_section (sym_sec));
+  abs_symbol_p = h != NULL && bfd_is_abs_symbol (&h->root);
+
 
   /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
      it here if it is defined in a non-shared object.  */
@@ -5106,6 +5242,11 @@ elfNN_aarch64_final_link_relocate (reloc_howto_type *howto,
 
       if ((input_section->flags & SEC_ALLOC) == 0)
        {
+         /* If this is a SHT_NOTE section without SHF_ALLOC, treat
+            STT_GNU_IFUNC symbol as STT_FUNC.  */
+         if (elf_section_type (input_section) == SHT_NOTE)
+           goto skip_ifunc;
+
          /* Dynamic relocs are not propagated for SEC_DEBUGGING
             sections because such sections are not SEC_ALLOC and
             thus ld.so will not process them.  */
@@ -5301,6 +5442,7 @@ bad_ifunc_reloc:
        }
     }
 
+ skip_ifunc:
   resolved_to_zero = (h != NULL
                      && UNDEFWEAK_NO_DYNAMIC_RELOC (info, h));
 
@@ -5360,6 +5502,12 @@ bad_ifunc_reloc:
              skip = TRUE;
              relocate = TRUE;
            }
+         else if (abs_symbol_p)
+           {
+             /* Local absolute symbol.  */
+             skip = (h->forced_local || (h->dynindx == -1));
+             relocate = skip;
+           }
 
          outrel.r_offset += (input_section->output_section->vma
                              + input_section->output_offset);
@@ -5369,8 +5517,7 @@ bad_ifunc_reloc:
          else if (h != NULL
                   && h->dynindx != -1
                   && (!bfd_link_pic (info)
-                      || !(bfd_link_pie (info)
-                           || SYMBOLIC_BIND (info, h))
+                      || !(bfd_link_pie (info) || SYMBOLIC_BIND (info, h))
                       || !h->def_regular))
            outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
          else
@@ -5695,6 +5842,14 @@ bad_ifunc_reloc:
     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:
+    case BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12:
+    case BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12_NC:
+    case BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12:
+    case BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12_NC:
+    case BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12:
+    case BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12_NC:
+    case BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12:
+    case BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12_NC:
     case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0:
     case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
     case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1:
@@ -7210,8 +7365,7 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
              if (h != NULL
                  /* This is an absolute symbol.  It represents a value instead
                     of an address.  */
-                 && ((h->root.type == bfd_link_hash_defined
-                      && bfd_is_abs_section (h->root.u.def.section))
+                 && (bfd_is_abs_symbol (&h->root)
                      /* This is an undefined symbol.  */
                      || h->root.type == bfd_link_hash_undefined))
                break;
This page took 0.049537 seconds and 4 git commands to generate.