Revert "Also check e_machine when merging sections"
[deliverable/binutils-gdb.git] / bfd / elf32-arm.c
index e6f4a9f884c74aef8e61aff713aa6b55abedeed9..aa01a59e9a2d787ce4ba40243fdadf752ecca97a 100644 (file)
@@ -1,5 +1,5 @@
 /* 32-bit ELF support for ARM
-   Copyright (C) 1998-2014 Free Software Foundation, Inc.
+   Copyright (C) 1998-2015 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -79,7 +79,7 @@ static reloc_howto_type elf32_arm_howto_table_1[] =
   /* No relocation.  */
   HOWTO (R_ARM_NONE,           /* type */
         0,                     /* rightshift */
-        0,                     /* size (0 = byte, 1 = short, 2 = long) */
+        3,                     /* size (0 = byte, 1 = short, 2 = long) */
         0,                     /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
@@ -1606,7 +1606,7 @@ static reloc_howto_type elf32_arm_howto_table_1[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield,/* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        NULL,                  /* special_function */
         "R_ARM_TLS_LE32",      /* name */
         TRUE,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
@@ -2172,7 +2172,7 @@ static const bfd_vma elf32_thumb2_plt0_entry [] =
      an instruction maybe encoded to one or two array elements.  */
   0xf8dfb500,          /* push    {lr}          */
   0x44fee008,          /* ldr.w   lr, [pc, #8]  */
-                        /* add     lr, pc        */
+                       /* add     lr, pc        */
   0xff08f85e,          /* ldr.w   pc, [lr, #8]! */
   0x00000000,          /* &GOT[0] - .           */
 };
@@ -2187,7 +2187,7 @@ static const bfd_vma elf32_thumb2_plt_entry [] =
   0x0c00f2c0,          /* movt    ip, #0xNNNN    */
   0xf8dc44fc,           /* add     ip, pc         */
   0xbf00f000            /* ldr.w   pc, [ip]       */
-                        /* nop                    */
+                       /* nop                    */
 };
 
 /* The format of the first entry in the procedure linkage table
@@ -2283,6 +2283,8 @@ static const bfd_vma elf32_arm_nacl_plt_entry [] =
 #define THM_MAX_BWD_BRANCH_OFFSET  (-(1 << 22) + 4)
 #define THM2_MAX_FWD_BRANCH_OFFSET (((1 << 24) - 2) + 4)
 #define THM2_MAX_BWD_BRANCH_OFFSET (-(1 << 24) + 4)
+#define THM2_MAX_FWD_COND_BRANCH_OFFSET (((1 << 20) -2) + 4)
+#define THM2_MAX_BWD_COND_BRANCH_OFFSET (-(1 << 20) + 4)
 
 enum stub_insn_type
 {
@@ -3059,11 +3061,11 @@ struct elf32_arm_link_hash_table
   struct map_stub *stub_group;
 
   /* Number of elements in stub_group.  */
-  int top_id;
+  unsigned int top_id;
 
   /* Assorted information used by elf32_arm_size_stubs.  */
   unsigned int bfd_count;
-  int top_index;
+  unsigned int top_index;
   asection **input_list;
 };
 
@@ -3407,7 +3409,7 @@ elf32_arm_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
     return FALSE;
 
   htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
-  if (!info->shared)
+  if (!bfd_link_pic (info))
     htab->srelbss = bfd_get_linker_section (dynobj,
                                            RELOC_SECTION (htab, ".bss"));
 
@@ -3416,7 +3418,7 @@ elf32_arm_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
       if (!elf_vxworks_create_dynamic_sections (dynobj, info, &htab->srelplt2))
        return FALSE;
 
-      if (info->shared)
+      if (bfd_link_pic (info))
        {
          htab->plt_header_size = 0;
          htab->plt_entry_size
@@ -3450,7 +3452,7 @@ elf32_arm_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
   if (!htab->root.splt
       || !htab->root.srelplt
       || !htab->sdynbss
-      || (!info->shared && !htab->srelbss))
+      || (!bfd_link_pic (info) && !htab->srelbss))
     abort ();
 
   return TRUE;
@@ -3667,7 +3669,8 @@ arm_type_of_stub (struct bfd_link_info *info,
 
   /* ST_BRANCH_TO_ARM is nonsense to thumb-only targets when we
      are considering a function call relocation.  */
-  if (thumb_only && (r_type == R_ARM_THM_CALL || r_type == R_ARM_THM_JUMP24)
+  if (thumb_only && (r_type == R_ARM_THM_CALL || r_type == R_ARM_THM_JUMP24
+                     || r_type == R_ARM_THM_JUMP19)
       && branch_type == ST_BRANCH_TO_ARM)
     branch_type = ST_BRANCH_TO_THUMB;
 
@@ -3711,7 +3714,7 @@ arm_type_of_stub (struct bfd_link_info *info,
   branch_offset = (bfd_signed_vma)(destination - location);
 
   if (r_type == R_ARM_THM_CALL || r_type == R_ARM_THM_JUMP24
-      || r_type == R_ARM_THM_TLS_CALL)
+      || r_type == R_ARM_THM_TLS_CALL || r_type == R_ARM_THM_JUMP19)
     {
       /* Handle cases where:
         - this call goes too far (different Thumb/Thumb2 max
@@ -3727,10 +3730,15 @@ arm_type_of_stub (struct bfd_link_info *info,
          || (thumb2
              && (branch_offset > THM2_MAX_FWD_BRANCH_OFFSET
                  || (branch_offset < THM2_MAX_BWD_BRANCH_OFFSET)))
+         || (thumb2
+             && (branch_offset > THM2_MAX_FWD_COND_BRANCH_OFFSET
+                 || (branch_offset < THM2_MAX_BWD_COND_BRANCH_OFFSET))
+             && (r_type == R_ARM_THM_JUMP19))
          || (branch_type == ST_BRANCH_TO_ARM
              && (((r_type == R_ARM_THM_CALL
                    || r_type == R_ARM_THM_TLS_CALL) && !globals->use_blx)
-                 || (r_type == R_ARM_THM_JUMP24))
+                 || (r_type == R_ARM_THM_JUMP24)
+                  || (r_type == R_ARM_THM_JUMP19))
              && !use_plt))
        {
          if (branch_type == ST_BRANCH_TO_THUMB)
@@ -3738,7 +3746,7 @@ arm_type_of_stub (struct bfd_link_info *info,
              /* Thumb to thumb.  */
              if (!thumb_only)
                {
-                 stub_type = (info->shared | globals->pic_veneer)
+                 stub_type = (bfd_link_pic (info) | globals->pic_veneer)
                    /* PIC stubs.  */
                    ? ((globals->use_blx
                        && (r_type == R_ARM_THM_CALL))
@@ -3760,7 +3768,7 @@ arm_type_of_stub (struct bfd_link_info *info,
                }
              else
                {
-                 stub_type = (info->shared | globals->pic_veneer)
+                 stub_type = (bfd_link_pic (info) | globals->pic_veneer)
                    /* PIC stub.  */
                    ? arm_stub_long_branch_thumb_only_pic
                    /* non-PIC stub.  */
@@ -3781,7 +3789,7 @@ arm_type_of_stub (struct bfd_link_info *info,
                }
 
              stub_type =
-               (info->shared | globals->pic_veneer)
+               (bfd_link_pic (info) | globals->pic_veneer)
                /* PIC stubs.  */
                ? (r_type == R_ARM_THM_TLS_CALL
                   /* TLS PIC stubs.  */
@@ -3835,7 +3843,7 @@ arm_type_of_stub (struct bfd_link_info *info,
              || (r_type == R_ARM_JUMP24)
              || (r_type == R_ARM_PLT32))
            {
-             stub_type = (info->shared | globals->pic_veneer)
+             stub_type = (bfd_link_pic (info) | globals->pic_veneer)
                /* PIC stubs.  */
                ? ((globals->use_blx)
                   /* V5T and above.  */
@@ -3858,7 +3866,7 @@ arm_type_of_stub (struct bfd_link_info *info,
              || (branch_offset < ARM_MAX_BWD_BRANCH_OFFSET))
            {
              stub_type =
-               (info->shared | globals->pic_veneer)
+               (bfd_link_pic (info) | globals->pic_veneer)
                /* PIC stubs.  */
                ? (r_type == R_ARM_TLS_CALL
                   /* TLS PIC Stub.  */
@@ -4089,7 +4097,8 @@ elf32_arm_tls_transition (struct bfd_link_info *info, int r_type,
 {
   int is_local = (h == NULL);
 
-  if (info->shared || (h && h->root.type == bfd_link_hash_undefweak))
+  if (bfd_link_pic (info)
+      || (h && h->root.type == bfd_link_hash_undefweak))
     return r_type;
 
   /* We do not support relaxations for Old TLS models.  */
@@ -4423,7 +4432,7 @@ elf32_arm_setup_section_lists (bfd *output_bfd,
 {
   bfd *input_bfd;
   unsigned int bfd_count;
-  int top_id, top_index;
+  unsigned int top_id, top_index;
   asection *section;
   asection **input_list, **list;
   bfd_size_type amt;
@@ -5347,7 +5356,8 @@ elf32_arm_size_stubs (bfd *output_bfd,
                      /* For historical reasons, use the existing names for
                         ARM-to-Thumb and Thumb-to-ARM stubs.  */
                      if ((r_type == (unsigned int) R_ARM_THM_CALL
-                          || r_type == (unsigned int) R_ARM_THM_JUMP24)
+                          || r_type == (unsigned int) R_ARM_THM_JUMP24
+                           || r_type == (unsigned int) R_ARM_THM_JUMP19)
                          && branch_type == ST_BRANCH_TO_ARM)
                        sprintf (stub_entry->output_name,
                                 THUMB2ARM_GLUE_ENTRY_NAME, sym_name);
@@ -5829,7 +5839,8 @@ record_arm_to_thumb_glue (struct bfd_link_info * link_info,
 
   free (tmp_name);
 
-  if (link_info->shared || globals->root.is_relocatable_executable
+  if (bfd_link_pic (link_info)
+      || globals->root.is_relocatable_executable
       || globals->pic_veneer)
     size = ARM2THUMB_PIC_GLUE_SIZE;
   else if (globals->use_blx)
@@ -6101,7 +6112,7 @@ bfd_elf32_arm_add_glue_sections_to_bfd (bfd *abfd,
 {
   /* If we are only performing a partial
      link do not bother adding the glue.  */
-  if (info->relocatable)
+  if (bfd_link_relocatable (info))
     return TRUE;
 
   return arm_make_glue_section (abfd, ARM2THUMB_GLUE_SECTION_NAME)
@@ -6121,7 +6132,7 @@ bfd_elf32_arm_get_bfd_for_interworking (bfd *abfd, struct bfd_link_info *info)
 
   /* If we are only performing a partial link
      do not bother getting a bfd to hold the glue.  */
-  if (info->relocatable)
+  if (bfd_link_relocatable (info))
     return TRUE;
 
   /* Make sure we don't attach the glue sections to a dynamic object.  */
@@ -6173,7 +6184,7 @@ bfd_elf32_arm_process_before_allocation (bfd *abfd,
 
   /* If we are only performing a partial link do not bother
      to construct any glue.  */
-  if (link_info->relocatable)
+  if (bfd_link_relocatable (link_info))
     return TRUE;
 
   /* Here we have a bfd that is to be included on the link.  We have a
@@ -6737,7 +6748,7 @@ bfd_elf32_arm_vfp11_erratum_scan (bfd *abfd, struct bfd_link_info *link_info)
 
   /* If we are only performing a partial link do not bother
      to construct any glue.  */
-  if (link_info->relocatable)
+  if (bfd_link_relocatable (link_info))
     return TRUE;
 
   /* Skip if this bfd does not correspond to an ELF image.  */
@@ -6923,7 +6934,7 @@ bfd_elf32_arm_vfp11_fix_veneer_locations (bfd *abfd,
   struct elf32_arm_link_hash_table *globals;
   char *tmp_name;
 
-  if (link_info->relocatable)
+  if (bfd_link_relocatable (link_info))
     return;
 
   /* Skip if this bfd does not correspond to an ELF image.  */
@@ -7211,7 +7222,8 @@ elf32_arm_create_thumb_stub (struct bfd_link_info * info,
       --my_offset;
       myh->root.u.def.value = my_offset;
 
-      if (info->shared || globals->root.is_relocatable_executable
+      if (bfd_link_pic (info)
+         || globals->root.is_relocatable_executable
          || globals->pic_veneer)
        {
          /* For relocatable objects we can't use absolute addresses,
@@ -7662,7 +7674,7 @@ elf32_arm_populate_plt_entry (bfd *output_bfd, struct bfd_link_info *info,
                     + root_plt->offset);
 
       ptr = splt->contents + root_plt->offset;
-      if (htab->vxworks_p && info->shared)
+      if (htab->vxworks_p && bfd_link_pic (info))
        {
          unsigned int i;
          bfd_vma val;
@@ -7760,7 +7772,7 @@ elf32_arm_populate_plt_entry (bfd *output_bfd, struct bfd_link_info *info,
       else if (using_thumb_only (htab))
        {
          /* PR ld/16017: Generate thumb only PLT entries.  */
-          if (!using_thumb2 (htab))
+         if (!using_thumb2 (htab))
            {
              /* FIXME: We ought to be able to generate thumb-1 PLT
                 instructions...  */
@@ -8225,18 +8237,6 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
   if (r_type != howto->type)
     howto = elf32_arm_howto_from_type (r_type);
 
-  /* If the start address has been set, then set the EF_ARM_HASENTRY
-     flag.  Setting this more than once is redundant, but the cost is
-     not too high, and it keeps the code simple.
-
-     The test is done  here, rather than somewhere else, because the
-     start address is only set just before the final link commences.
-
-     Note - if the user deliberately sets a start address of 0, the
-     flag will not be set.  */
-  if (bfd_get_start_address (output_bfd) != 0)
-    elf_elfheader (output_bfd)->e_flags |= EF_ARM_HASENTRY;
-
   eh = (struct elf32_arm_link_hash_entry *) h;
   sgot = globals->root.sgot;
   local_got_offsets = elf_local_got_offsets (input_bfd);
@@ -8386,7 +8386,8 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
       /* When generating a shared object or relocatable executable, these
         relocations are copied into the output file to be resolved at
         run time.  */
-      if ((info->shared || globals->root.is_relocatable_executable)
+      if ((bfd_link_pic (info)
+          || globals->root.is_relocatable_executable)
          && (input_section->flags & SEC_ALLOC)
          && !(globals->vxworks_p
               && strcmp (input_section->output_section->name,
@@ -8407,6 +8408,21 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
          Elf_Internal_Rela outrel;
          bfd_boolean skip, relocate;
 
+         if ((r_type == R_ARM_REL32 || r_type == R_ARM_REL32_NOI)
+             && !h->def_regular)
+           {
+             char *v = _("shared object");
+
+             if (bfd_link_executable (info))
+               v = _("PIE executable");
+
+             (*_bfd_error_handler)
+               (_("%B: relocation %s against external or undefined symbol `%s'"
+                  " can not be used when making a %s; recompile with -fPIC"), input_bfd,
+                elf32_arm_howto_table_1[r_type].name, h->root.root.string, v);
+             return bfd_reloc_notsupported;
+           }
+
          *unresolved_reloc_p = FALSE;
 
          if (sreloc == NULL && globals->root.dynamic_sections_created)
@@ -8436,8 +8452,8 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
            memset (&outrel, 0, sizeof outrel);
          else if (h != NULL
                   && h->dynindx != -1
-                  && (!info->shared
-                      || !info->symbolic
+                  && (!bfd_link_pic (info)
+                      || !SYMBOLIC_BIND (info, h)
                       || !h->def_regular))
            outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
          else
@@ -8800,7 +8816,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                          + input_section->output_offset
                          + rel->r_offset);
 
-       value = abs (relocation);
+       value = relocation;
 
        if (value >= 0x1000)
          return bfd_reloc_overflow;
@@ -8835,7 +8851,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                          + input_section->output_offset
                          + rel->r_offset);
 
-       value = abs (relocation);
+       value = relocation;
 
        /* We do not check for overflow of this reloc.  Although strictly
           speaking this is incorrect, it appears to be necessary in order
@@ -8872,7 +8888,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                          + input_section->output_offset
                          + rel->r_offset);
 
-       value = abs (relocation);
+       value = relocation;
 
        if (value >= 0x1000)
          return bfd_reloc_overflow;
@@ -9125,6 +9141,9 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
        bfd_signed_vma reloc_signed_max = 0xffffe;
        bfd_signed_vma reloc_signed_min = -0x100000;
        bfd_signed_vma signed_check;
+        enum elf32_arm_stub_type stub_type = arm_stub_none;
+       struct elf32_arm_stub_hash_entry *stub_entry;
+       struct elf32_arm_link_hash_entry *hash;
 
        /* Need to refetch the addend, reconstruct the top three bits,
           and squish the two 11 bit pieces together.  */
@@ -9156,8 +9175,25 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
            *unresolved_reloc_p = FALSE;
          }
 
-       /* ??? Should handle interworking?  GCC might someday try to
-          use this for tail calls.  */
+       hash = (struct elf32_arm_link_hash_entry *)h;
+
+       stub_type = arm_type_of_stub (info, input_section, rel,
+                                     st_type, &branch_type,
+                                     hash, value, sym_sec,
+                                     input_bfd, sym_name);
+       if (stub_type != arm_stub_none)
+         {
+           stub_entry = elf32_arm_get_stub_entry (input_section,
+                                                  sym_sec, h,
+                                                  rel, globals,
+                                                  stub_type);
+           if (stub_entry != NULL)
+             {
+               value = (stub_entry->stub_offset
+                        + stub_entry->stub_sec->output_offset
+                        + stub_entry->stub_sec->output_section->vma);
+             }
+         }
 
        relocation = value + signed_addend;
        relocation -= (input_section->output_section->vma
@@ -9366,7 +9402,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                {
                  if (dynreloc_st_type == STT_GNU_IFUNC)
                    outrel.r_info = ELF32_R_INFO (0, R_ARM_IRELATIVE);
-                 else if (info->shared &&
+                 else if (bfd_link_pic (info) &&
                           (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
                            || h->root.type != bfd_link_hash_undefweak))
                    outrel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE);
@@ -9415,7 +9451,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
              if (globals->use_rel)
                bfd_put_32 (output_bfd, dynreloc_value, sgot->contents + off);
 
-             if (info->shared || dynreloc_st_type == STT_GNU_IFUNC)
+             if (bfd_link_pic (info) || dynreloc_st_type == STT_GNU_IFUNC)
                {
                  Elf_Internal_Rela outrel;
 
@@ -9464,7 +9500,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
          {
            /* If we don't know the module number, create a relocation
               for it.  */
-           if (info->shared)
+           if (bfd_link_pic (info))
              {
                Elf_Internal_Rela outrel;
 
@@ -9514,8 +9550,10 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
          {
            bfd_boolean dyn;
            dyn = globals->root.dynamic_sections_created;
-           if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
-               && (!info->shared
+           if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
+                                                bfd_link_pic (info),
+                                                h)
+               && (!bfd_link_pic (info)
                    || !SYMBOL_REFERENCES_LOCAL (info, h)))
              {
                *unresolved_reloc_p = FALSE;
@@ -9552,7 +9590,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
               now, and emit any relocations.  If both an IE GOT and a
               GD GOT are necessary, we emit the GD first.  */
 
-           if ((info->shared || indx != 0)
+           if ((bfd_link_pic (info) || indx != 0)
                && (h == NULL
                    || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
                    || h->root.type != bfd_link_hash_undefweak))
@@ -9568,7 +9606,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                /* We should have relaxed, unless this is an undefined
                   weak symbol.  */
                BFD_ASSERT ((h && (h->root.type == bfd_link_hash_undefweak))
-                           || info->shared);
+                           || bfd_link_pic (info));
                BFD_ASSERT (globals->sgotplt_jump_table_size + offplt + 8
                            <= globals->root.sgotplt->size);
 
@@ -9843,7 +9881,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
       }
 
     case R_ARM_TLS_LE32:
-      if (info->shared && !info->pie)
+      if (bfd_link_dll (info))
        {
          (*_bfd_error_handler)
            (_("%B(%A+0x%lx): R_ARM_TLS_LE32 relocation not permitted in shared object"),
@@ -10087,8 +10125,8 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
 
        /* Calculate the value of the relevant G_n, in encoded
           constant-with-rotation format.  */
-       g_n = calculate_group_reloc_mask (abs (signed_value), group,
-                                         &residual);
+       g_n = calculate_group_reloc_mask (signed_value < 0 ? - signed_value : signed_value,
+                                         group, &residual);
 
        /* Check for overflow if required.  */
        if ((r_type == R_ARM_ALU_PC_G0
@@ -10101,7 +10139,8 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
            (*_bfd_error_handler)
              (_("%B(%A+0x%lx): Overflow whilst splitting 0x%lx for group relocation %s"),
              input_bfd, input_section,
-             (long) rel->r_offset, abs (signed_value), howto->name);
+              (long) rel->r_offset, signed_value < 0 ? - signed_value : signed_value,
+              howto->name);
            return bfd_reloc_overflow;
          }
 
@@ -10181,15 +10220,16 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
 
        /* Calculate the value of the relevant G_{n-1} to obtain
           the residual at that stage.  */
-       calculate_group_reloc_mask (abs (signed_value), group - 1, &residual);
+       calculate_group_reloc_mask (signed_value < 0 ? - signed_value : signed_value,
+                                   group - 1, &residual);
 
        /* Check for overflow.  */
        if (residual >= 0x1000)
          {
            (*_bfd_error_handler)
              (_("%B(%A+0x%lx): Overflow whilst splitting 0x%lx for group relocation %s"),
-             input_bfd, input_section,
-             (long) rel->r_offset, abs (signed_value), howto->name);
+              input_bfd, input_section,
+              (long) rel->r_offset, labs (signed_value), howto->name);
            return bfd_reloc_overflow;
          }
 
@@ -10265,15 +10305,16 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
 
        /* Calculate the value of the relevant G_{n-1} to obtain
           the residual at that stage.  */
-       calculate_group_reloc_mask (abs (signed_value), group - 1, &residual);
+       calculate_group_reloc_mask (signed_value < 0 ? - signed_value : signed_value,
+                                   group - 1, &residual);
 
        /* Check for overflow.  */
        if (residual >= 0x100)
          {
            (*_bfd_error_handler)
              (_("%B(%A+0x%lx): Overflow whilst splitting 0x%lx for group relocation %s"),
-             input_bfd, input_section,
-             (long) rel->r_offset, abs (signed_value), howto->name);
+              input_bfd, input_section,
+              (long) rel->r_offset, labs (signed_value), howto->name);
            return bfd_reloc_overflow;
          }
 
@@ -10349,7 +10390,8 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
 
        /* Calculate the value of the relevant G_{n-1} to obtain
           the residual at that stage.  */
-       calculate_group_reloc_mask (abs (signed_value), group - 1, &residual);
+       calculate_group_reloc_mask (signed_value < 0 ? - signed_value : signed_value,
+                                   group - 1, &residual);
 
        /* Check for overflow.  (The absolute value to go in the place must be
           divisible by four and, after having been divided by four, must
@@ -10359,7 +10401,7 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
            (*_bfd_error_handler)
              (_("%B(%A+0x%lx): Overflow whilst splitting 0x%lx for group relocation %s"),
              input_bfd, input_section,
-             (long) rel->r_offset, abs (signed_value), howto->name);
+             (long) rel->r_offset, labs (signed_value), howto->name);
            return bfd_reloc_overflow;
          }
 
@@ -10564,7 +10606,7 @@ elf32_arm_relocate_section (bfd *                  output_bfd,
              relocation = (sec->output_section->vma
                            + sec->output_offset
                            + sym->st_value);
-             if (!info->relocatable
+             if (!bfd_link_relocatable (info)
                  && (sec->flags & SEC_MERGE)
                  && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
                {
@@ -10671,7 +10713,7 @@ elf32_arm_relocate_section (bfd *                  output_bfd,
        RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
                                         rel, 1, relend, howto, 0, contents);
 
-      if (info->relocatable)
+      if (bfd_link_relocatable (info))
        {
          /* This is a relocatable link.  We don't have to change
             anything, unless the reloc is against a section symbol,
@@ -11099,7 +11141,7 @@ elf32_arm_final_link (bfd *abfd, struct bfd_link_info *info)
 
   /* Process stub sections (eg BE8 encoding, ...).  */
   struct elf32_arm_link_hash_table *htab = elf32_arm_hash_table (info);
-  int i;
+  unsigned int i;
   for (i=0; i<htab->top_id; i++)
     {
       sec = htab->stub_group[i].stub_sec;
@@ -11671,6 +11713,7 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd)
   static const int order_021[3] = {0, 2, 1};
   int i;
   bfd_boolean result = TRUE;
+  const char *sec_name = get_elf_backend_data (ibfd)->obj_attrs_section;
 
   /* Skip the linker stubs file.  This preserves previous behavior
      of accepting unknown attributes in the first input file - but
@@ -11678,6 +11721,12 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd)
   if (ibfd->flags & BFD_LINKER_CREATED)
     return TRUE;
 
+  /* Skip any input that hasn't attribute section.
+     This enables to link object files without attribute section with
+     any others.  */
+  if (bfd_get_section_by_name (ibfd, sec_name) == NULL)
+    return TRUE;
+
   if (!elf_known_obj_attributes_proc (obfd)[0].i)
     {
       /* This is the first object.  Copy the attributes.  */
@@ -11717,10 +11766,14 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd)
   /* This needs to happen before Tag_ABI_FP_number_model is merged.  */
   if (in_attr[Tag_ABI_VFP_args].i != out_attr[Tag_ABI_VFP_args].i)
     {
-      /* Ignore mismatches if the object doesn't use floating point.  */
-      if (out_attr[Tag_ABI_FP_number_model].i == 0)
+      /* Ignore mismatches if the object doesn't use floating point or is
+        floating point ABI independent.  */
+      if (out_attr[Tag_ABI_FP_number_model].i == AEABI_FP_number_model_none
+         || (in_attr[Tag_ABI_FP_number_model].i != AEABI_FP_number_model_none
+             && out_attr[Tag_ABI_VFP_args].i == AEABI_VFP_args_compatible))
        out_attr[Tag_ABI_VFP_args].i = in_attr[Tag_ABI_VFP_args].i;
-      else if (in_attr[Tag_ABI_FP_number_model].i != 0)
+      else if (in_attr[Tag_ABI_FP_number_model].i != AEABI_FP_number_model_none
+              && in_attr[Tag_ABI_VFP_args].i != AEABI_VFP_args_compatible)
        {
          _bfd_error_handler
            (_("error: %B uses VFP register arguments, %B does not"),
@@ -11749,7 +11802,9 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd)
          {
            int secondary_compat = -1, secondary_compat_out = -1;
            unsigned int saved_out_attr = out_attr[i].i;
-           static const char *name_table[] = {
+           int arch_attr;
+           static const char *name_table[] =
+             {
                /* These aren't real CPU names, but we can't guess
                   that from the architecture version alone.  */
                "Pre v4",
@@ -11771,10 +11826,17 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd)
            /* Merge Tag_CPU_arch and Tag_also_compatible_with.  */
            secondary_compat = get_secondary_compatible_arch (ibfd);
            secondary_compat_out = get_secondary_compatible_arch (obfd);
-           out_attr[i].i = tag_cpu_arch_combine (ibfd, out_attr[i].i,
-                                                 &secondary_compat_out,
-                                                 in_attr[i].i,
-                                                 secondary_compat);
+           arch_attr = tag_cpu_arch_combine (ibfd, out_attr[i].i,
+                                             &secondary_compat_out,
+                                             in_attr[i].i,
+                                             secondary_compat);
+
+           /* Return with error if failed to merge.  */
+           if (arch_attr == -1)
+             return FALSE;
+
+           out_attr[i].i = arch_attr;
+
            set_secondary_compatible_arch (obfd, secondary_compat_out);
 
            /* Merge Tag_CPU_name and Tag_CPU_raw_name.  */
@@ -11908,9 +11970,9 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd)
              /* Tag_ABI_HardFP_use is handled along with Tag_FP_arch since
                 the meaning of Tag_ABI_HardFP_use depends on Tag_FP_arch
                 when it's 0.  It might mean absence of FP hardware if
-                Tag_FP_arch is zero, otherwise it is effectively SP + DP.  */
+                Tag_FP_arch is zero.  */
 
-#define VFP_VERSION_COUNT 8
+#define VFP_VERSION_COUNT 9
              static const struct
              {
                  int ver;
@@ -11924,7 +11986,8 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd)
                  {3, 16},
                  {4, 32},
                  {4, 16},
-                 {8, 32}
+                 {8, 32},
+                 {8, 16}
                };
              int ver;
              int regs;
@@ -11949,7 +12012,7 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd)
                }
 
              /* Both the input and the output have nonzero Tag_FP_arch.
-                So Tag_ABI_HardFP_use is (SP & DP) when it's zero.  */
+                So Tag_ABI_HardFP_use is implied by Tag_FP_arch when it's zero.  */
 
              /* If both the input and the output have zero Tag_ABI_HardFP_use,
                 do nothing.  */
@@ -11957,10 +12020,10 @@ elf32_arm_merge_eabi_attributes (bfd *ibfd, bfd *obfd)
                  && out_attr[Tag_ABI_HardFP_use].i == 0)
                ;
              /* If the input and the output have different Tag_ABI_HardFP_use,
-                the combination of them is 3 (SP & DP).  */
+                the combination of them is 0 (implied by Tag_FP_arch).  */
              else if (in_attr[Tag_ABI_HardFP_use].i
                       != out_attr[Tag_ABI_HardFP_use].i)
-               out_attr[Tag_ABI_HardFP_use].i = 3;
+               out_attr[Tag_ABI_HardFP_use].i = 0;
 
              /* Now we can handle Tag_FP_arch.  */
 
@@ -12329,10 +12392,7 @@ elf32_arm_print_private_bfd_data (bfd *abfd, void * ptr)
   if (flags & EF_ARM_RELEXEC)
     fprintf (file, _(" [relocatable executable]"));
 
-  if (flags & EF_ARM_HASENTRY)
-    fprintf (file, _(" [has entry point]"));
-
-  flags &= ~ (EF_ARM_RELEXEC | EF_ARM_HASENTRY);
+  flags &= ~EF_ARM_RELEXEC;
 
   if (flags)
     fprintf (file, _("<Unrecognised flag bits set>"));
@@ -12398,7 +12458,7 @@ elf32_arm_gc_sweep_hook (bfd *                     abfd,
   const Elf_Internal_Rela *rel, *relend;
   struct elf32_arm_link_hash_table * globals;
 
-  if (info->relocatable)
+  if (bfd_link_relocatable (info))
     return TRUE;
 
   globals = elf32_arm_hash_table (info);
@@ -12496,11 +12556,11 @@ elf32_arm_gc_sweep_hook (bfd *                     abfd,
        case R_ARM_THM_MOVW_PREL_NC:
        case R_ARM_THM_MOVT_PREL:
          /* Should the interworking branches be here also?  */
-         if ((info->shared || globals->root.is_relocatable_executable)
+         if ((bfd_link_pic (info) || globals->root.is_relocatable_executable)
              && (sec->flags & SEC_ALLOC) != 0)
            {
              if (h == NULL
-                 && (r_type == R_ARM_REL32 || r_type == R_ARM_REL32_NOI))
+                 && elf32_arm_howto_from_type (r_type)->pc_relative)
                {
                  call_reloc_p = TRUE;
                  may_need_local_target_p = TRUE;
@@ -12594,7 +12654,7 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
   bfd_boolean may_need_local_target_p;
   unsigned long nsyms;
 
-  if (info->relocatable)
+  if (bfd_link_relocatable (info))
     return TRUE;
 
   BFD_ASSERT (is_arm_elf (abfd));
@@ -12711,7 +12771,7 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
                default: tls_type = GOT_NORMAL; break;
                }
 
-             if (!info->executable && (tls_type & GOT_TLS_IE))
+             if (!bfd_link_executable (info) && (tls_type & GOT_TLS_IE))
                info->flags |= DF_STATIC_TLS;
 
              if (h != NULL)
@@ -12796,7 +12856,7 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
          case R_ARM_MOVT_ABS:
          case R_ARM_THM_MOVW_ABS_NC:
          case R_ARM_THM_MOVT_ABS:
-           if (info->shared)
+           if (bfd_link_pic (info))
              {
                (*_bfd_error_handler)
                  (_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
@@ -12809,7 +12869,7 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
            /* Fall through.  */
          case R_ARM_ABS32:
          case R_ARM_ABS32_NOI:
-           if (h != NULL && info->executable)
+           if (h != NULL && bfd_link_executable (info))
              {
                h->pointer_equality_needed = 1;
              }
@@ -12822,11 +12882,11 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
          case R_ARM_THM_MOVT_PREL:
 
            /* Should the interworking branches be listed here?  */
-           if ((info->shared || htab->root.is_relocatable_executable)
+           if ((bfd_link_pic (info) || htab->root.is_relocatable_executable)
                && (sec->flags & SEC_ALLOC) != 0)
              {
                if (h == NULL
-                   && (r_type == R_ARM_REL32 || r_type == R_ARM_REL32_NOI))
+                   && elf32_arm_howto_from_type (r_type)->pc_relative)
                  {
                    /* In shared libraries and relocatable executables,
                       we treat local relative references as calls;
@@ -12972,7 +13032,7 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
              p->pc_count = 0;
            }
 
-         if (r_type == R_ARM_REL32 || r_type == R_ARM_REL32_NOI)
+         if (elf32_arm_howto_from_type (r_type)->pc_relative)
            p->pc_count += 1;
          p->count += 1;
        }
@@ -13045,8 +13105,8 @@ elf32_arm_is_target_special_symbol (bfd * abfd ATTRIBUTE_UNUSED, asymbol * sym)
 
 static bfd_boolean
 arm_elf_find_function (bfd *         abfd ATTRIBUTE_UNUSED,
-                      asection *    section,
                       asymbol **    symbols,
+                      asection *    section,
                       bfd_vma       offset,
                       const char ** filename_ptr,
                       const char ** functionname_ptr)
@@ -13107,31 +13167,33 @@ arm_elf_find_function (bfd *         abfd ATTRIBUTE_UNUSED,
 
 static bfd_boolean
 elf32_arm_find_nearest_line (bfd *          abfd,
-                            asection *     section,
                             asymbol **     symbols,
+                            asection *     section,
                             bfd_vma        offset,
                             const char **  filename_ptr,
                             const char **  functionname_ptr,
-                            unsigned int * line_ptr)
+                            unsigned int * line_ptr,
+                            unsigned int * discriminator_ptr)
 {
   bfd_boolean found = FALSE;
 
-  /* We skip _bfd_dwarf1_find_nearest_line since no known ARM toolchain uses it.  */
-
-  if (_bfd_dwarf2_find_nearest_line (abfd, dwarf_debug_sections,
-                                    section, symbols, offset,
+  if (_bfd_dwarf2_find_nearest_line (abfd, symbols, NULL, section, offset,
                                     filename_ptr, functionname_ptr,
-                                    line_ptr, NULL, 0,
+                                    line_ptr, discriminator_ptr,
+                                    dwarf_debug_sections, 0,
                                     & elf_tdata (abfd)->dwarf2_find_line_info))
     {
       if (!*functionname_ptr)
-       arm_elf_find_function (abfd, section, symbols, offset,
+       arm_elf_find_function (abfd, symbols, section, offset,
                               *filename_ptr ? NULL : filename_ptr,
                               functionname_ptr);
 
       return TRUE;
     }
 
+  /* Skip _bfd_dwarf1_find_nearest_line since no known ARM toolchain
+     uses DWARF1.  */
+
   if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
                                             & found, filename_ptr,
                                             functionname_ptr, line_ptr,
@@ -13144,7 +13206,7 @@ elf32_arm_find_nearest_line (bfd *          abfd,
   if (symbols == NULL)
     return FALSE;
 
-  if (! arm_elf_find_function (abfd, section, symbols, offset,
+  if (! arm_elf_find_function (abfd, symbols, section, offset,
                               filename_ptr, functionname_ptr))
     return FALSE;
 
@@ -13263,7 +13325,7 @@ elf32_arm_adjust_dynamic_symbol (struct bfd_link_info * info,
      be handled correctly by relocate_section.  Relocatable executables
      can reference data in shared objects directly, so we don't need to
      do anything here.  */
-  if (info->shared || globals->root.is_relocatable_executable)
+  if (bfd_link_pic (info) || globals->root.is_relocatable_executable)
     return TRUE;
 
   /* We must allocate the symbol in our .dynbss section, which will
@@ -13291,7 +13353,7 @@ elf32_arm_adjust_dynamic_symbol (struct bfd_link_info * info,
       h->needs_copy = 1;
     }
 
-  return _bfd_elf_adjust_dynamic_copy (h, s);
+  return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
 /* Allocate space in .plt, .got and associated reloc sections for
@@ -13345,7 +13407,7 @@ allocate_dynrelocs_for_symbol (struct elf_link_hash_entry *h, void * inf)
            h->got.refcount = 0;
        }
 
-      if (info->shared
+      if (bfd_link_pic (info)
          || eh->is_iplt
          || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
        {
@@ -13356,7 +13418,7 @@ allocate_dynrelocs_for_symbol (struct elf_link_hash_entry *h, void * inf)
             location in the .plt.  This is required to make function
             pointers compare as equal between the normal executable and
             the shared library.  */
-         if (! info->shared
+         if (! bfd_link_pic (info)
              && !h->def_regular)
            {
              h->root.u.def.section = htab->root.splt;
@@ -13371,7 +13433,7 @@ allocate_dynrelocs_for_symbol (struct elf_link_hash_entry *h, void * inf)
          /* VxWorks executables have a second set of relocations for
             each PLT entry.  They go in a separate relocation section,
             which is processed by the kernel loader.  */
-         if (htab->vxworks_p && !info->shared)
+         if (htab->vxworks_p && !bfd_link_pic (info))
            {
              /* There is a relocation for the initial PLT entry:
                 an R_ARM_32 relocation for _GLOBAL_OFFSET_TABLE_.  */
@@ -13458,13 +13520,15 @@ allocate_dynrelocs_for_symbol (struct elf_link_hash_entry *h, void * inf)
          dyn = htab->root.dynamic_sections_created;
 
          indx = 0;
-         if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
-             && (!info->shared
+         if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
+                                              bfd_link_pic (info),
+                                              h)
+             && (!bfd_link_pic (info)
                  || !SYMBOL_REFERENCES_LOCAL (info, h)))
            indx = h->dynindx;
 
          if (tls_type != GOT_NORMAL
-             && (info->shared || indx != 0)
+             && (bfd_link_pic (info) || indx != 0)
              && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
                  || h->root.type != bfd_link_hash_undefweak))
            {
@@ -13498,8 +13562,9 @@ allocate_dynrelocs_for_symbol (struct elf_link_hash_entry *h, void * inf)
               they all resolve dynamically instead.  Reserve room for the
               GOT entry's R_ARM_IRELATIVE relocation.  */
            elf32_arm_allocate_irelocs (info, htab->root.srelgot, 1);
-         else if (info->shared && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
-                                   || h->root.type != bfd_link_hash_undefweak))
+         else if (bfd_link_pic (info)
+                  && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+                      || h->root.type != bfd_link_hash_undefweak))
            /* Reserve room for the GOT entry's R_ARM_RELATIVE relocation.  */
            elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1);
        }
@@ -13549,14 +13614,14 @@ allocate_dynrelocs_for_symbol (struct elf_link_hash_entry *h, void * inf)
      space for pc-relative relocs that have become local due to symbol
      visibility changes.  */
 
-  if (info->shared || htab->root.is_relocatable_executable)
+  if (bfd_link_pic (info) || htab->root.is_relocatable_executable)
     {
-      /* The only relocs that use pc_count are R_ARM_REL32 and
-        R_ARM_REL32_NOI, which will appear on something like
-        ".long foo - .".  We want calls to protected symbols to resolve
-        directly to the function rather than going via the plt.  If people
-        want function pointer comparisons to work as expected then they
-        should avoid writing assembly like ".long foo - .".  */
+      /* Relocs that use pc_count are PC-relative forms, which will appear
+        on something like ".long foo - ." or "movw REG, foo - .".  We want
+        calls to protected symbols to resolve directly to the function
+        rather than going via the plt.  If people want function pointer
+        comparisons to work as expected then they should avoid writing
+        assembly like ".long foo - .".  */
       if (SYMBOL_CALLS_LOCAL (info, h))
        {
          struct elf_dyn_relocs **pp;
@@ -13725,7 +13790,7 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
   if (elf_hash_table (info)->dynamic_sections_created)
     {
       /* Set the contents of the .interp section to the interpreter.  */
-      if (info->executable)
+      if (bfd_link_executable (info) && !info->nointerp)
        {
          s = bfd_get_linker_section (dynobj, ".interp");
          BFD_ASSERT (s != NULL);
@@ -13877,13 +13942,13 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
                  && (local_iplt == NULL
                      || local_iplt->arm.noncall_refcount == 0))
                elf32_arm_allocate_irelocs (info, srel, 1);
-             else if (info->shared || output_bfd->flags & DYNAMIC)
+             else if (bfd_link_pic (info) || output_bfd->flags & DYNAMIC)
                {
-                 if ((info->shared && !(*local_tls_type & GOT_TLS_GDESC))
+                 if ((bfd_link_pic (info) && !(*local_tls_type & GOT_TLS_GDESC))
                      || *local_tls_type & GOT_TLS_GD)
                    elf32_arm_allocate_dynrelocs (info, srel, 1);
 
-                 if (info->shared && *local_tls_type & GOT_TLS_GDESC)
+                 if (bfd_link_pic (info) && *local_tls_type & GOT_TLS_GDESC)
                    {
                      elf32_arm_allocate_dynrelocs (info,
                                                    htab->root.srelplt, 1);
@@ -13902,7 +13967,7 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
         for R_ARM_TLS_LDM32 relocations.  */
       htab->tls_ldm_got.offset = htab->root.sgot->size;
       htab->root.sgot->size += 8;
-      if (info->shared)
+      if (bfd_link_pic (info))
        elf32_arm_allocate_dynrelocs (info, htab->root.srelgot, 1);
     }
   else
@@ -14038,7 +14103,7 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
 #define add_dynamic_entry(TAG, VAL) \
   _bfd_elf_add_dynamic_entry (info, TAG, VAL)
 
-     if (info->executable)
+     if (bfd_link_executable (info))
        {
          if (!add_dynamic_entry (DT_DEBUG, 0))
            return FALSE;
@@ -14106,7 +14171,7 @@ elf32_arm_always_size_sections (bfd *output_bfd,
 {
   asection *tls_sec;
 
-  if (info->relocatable)
+  if (bfd_link_relocatable (info))
     return TRUE;
 
   tls_sec = elf_hash_table (info)->tls_sec;
@@ -14171,12 +14236,16 @@ elf32_arm_finish_dynamic_symbol (bfd * output_bfd,
       if (!h->def_regular)
        {
          /* Mark the symbol as undefined, rather than as defined in
-            the .plt section.  Leave the value alone.  */
+            the .plt section.  */
          sym->st_shndx = SHN_UNDEF;
-         /* If the symbol is weak, we do need to clear the value.
+         /* If the symbol is weak we need to clear the value.
             Otherwise, the PLT entry would provide a definition for
             the symbol even if the symbol wasn't defined anywhere,
-            and so the symbol would never be NULL.  */
+            and so the symbol would never be NULL.  Leave the value if
+            there were any relocations where pointer equality matters
+            (this is a clue for the dynamic linker, to make function
+            pointer comparisons work between an application and shared
+            library).  */
          if (!h->ref_regular_nonweak || !h->pointer_equality_needed)
            sym->st_value = 0;
        }
@@ -14593,7 +14662,9 @@ elf32_arm_finish_dynamic_sections (bfd * output_bfd, struct bfd_link_info * info
 #endif
        }
 
-      if (htab->vxworks_p && !info->shared && htab->root.splt->size > 0)
+      if (htab->vxworks_p
+         && !bfd_link_pic (info)
+         && htab->root.splt->size > 0)
        {
          /* Correct the .rel(a).plt.unloaded relocations.  They will have
             incorrect symbol indexes.  */
@@ -14671,7 +14742,7 @@ elf32_arm_post_process_headers (bfd * abfd, struct bfd_link_info * link_info ATT
       && ((i_ehdrp->e_type == ET_DYN) || (i_ehdrp->e_type == ET_EXEC)))
     {
       int abi = bfd_elf_get_obj_attr_int (abfd, OBJ_ATTR_PROC, Tag_ABI_VFP_args);
-      if (abi)
+      if (abi == AEABI_VFP_args_vfp)
        i_ehdrp->e_flags |= EF_ARM_ABI_FLOAT_HARD;
       else
        i_ehdrp->e_flags |= EF_ARM_ABI_FLOAT_SOFT;
@@ -15112,7 +15183,7 @@ elf32_arm_output_arch_local_syms (bfd *output_bfd,
 
       osi.sec_shndx = _bfd_elf_section_from_bfd_section
          (output_bfd, osi.sec->output_section);
-      if (info->shared || htab->root.is_relocatable_executable
+      if (bfd_link_pic (info) || htab->root.is_relocatable_executable
          || htab->pic_veneer)
        size = ARM2THUMB_PIC_GLUE_SIZE;
       else if (htab->use_blx)
@@ -15190,7 +15261,7 @@ elf32_arm_output_arch_local_syms (bfd *output_bfd,
       if (htab->vxworks_p)
        {
          /* VxWorks shared libraries have no PLT header.  */
-         if (!info->shared)
+         if (!bfd_link_pic (info))
            {
              if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, 0))
                return FALSE;
@@ -15868,10 +15939,11 @@ elf32_arm_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
                           Elf_Internal_Sym *sym, const char **namep,
                           flagword *flagsp, asection **secp, bfd_vma *valp)
 {
-  if ((abfd->flags & DYNAMIC) == 0
-      && (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
-         || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE))
-    elf_tdata (info->output_bfd)->has_gnu_symbols = TRUE;
+  if ((ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
+       || ELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE)
+      && (abfd->flags & DYNAMIC) == 0
+      && bfd_get_flavour (info->output_bfd) == bfd_target_elf_flavour)
+    elf_tdata (info->output_bfd)->has_gnu_symbols = elf_gnu_symbol_any;
 
   if (elf32_arm_hash_table (info) == NULL)
     return FALSE;
@@ -15915,6 +15987,26 @@ const struct elf_size_info elf32_arm_size_info =
   bfd_elf32_swap_reloca_out
 };
 
+static bfd_vma
+read_code32 (const bfd *abfd, const bfd_byte *addr)
+{
+  /* V7 BE8 code is always little endian.  */
+  if ((elf_elfheader (abfd)->e_flags & EF_ARM_BE8) != 0)
+    return bfd_getl32 (addr);
+
+  return bfd_get_32 (abfd, addr);
+}
+
+static bfd_vma
+read_code16 (const bfd *abfd, const bfd_byte *addr)
+{
+  /* V7 BE8 code is always little endian.  */
+  if ((elf_elfheader (abfd)->e_flags & EF_ARM_BE8) != 0)
+    return bfd_getl16 (addr);
+
+  return bfd_get_16 (abfd, addr);
+}
+
 /* Return size of plt0 entry starting at ADDR
    or (bfd_vma) -1 if size can not be determined.  */
 
@@ -15924,7 +16016,7 @@ elf32_arm_plt0_size (const bfd *abfd, const bfd_byte *addr)
   bfd_vma first_word;
   bfd_vma plt0_size;
 
-  first_word = H_GET_32 (abfd, addr);
+  first_word = read_code32 (abfd, addr);
 
   if (first_word == elf32_arm_plt0_entry[0])
     plt0_size = 4 * ARRAY_SIZE (elf32_arm_plt0_entry);
@@ -15949,17 +16041,17 @@ elf32_arm_plt_size (const bfd *abfd, const bfd_byte *start, bfd_vma offset)
   const bfd_byte *addr = start + offset;
 
   /* PLT entry size if fixed on Thumb-only platforms.  */
-  if (H_GET_32(abfd, start) == elf32_thumb2_plt0_entry[0])
+  if (read_code32 (abfd, start) == elf32_thumb2_plt0_entry[0])
       return 4 * ARRAY_SIZE (elf32_thumb2_plt_entry);
 
   /* Respect Thumb stub if necessary.  */
-  if (H_GET_16(abfd, addr) == elf32_arm_plt_thumb_stub[0])
+  if (read_code16 (abfd, addr) == elf32_arm_plt_thumb_stub[0])
     {
       plt_size += 2 * ARRAY_SIZE(elf32_arm_plt_thumb_stub);
     }
 
   /* Strip immediate from first add.  */
-  first_insn = H_GET_32(abfd, addr + plt_size) & 0xffffff00;
+  first_insn = read_code32 (abfd, addr + plt_size) & 0xffffff00;
 
 #ifdef FOUR_WORD_PLT
   if (first_insn == elf32_arm_plt_entry[0])
@@ -16159,6 +16251,7 @@ elf32_arm_get_synthetic_symtab (bfd *abfd,
 #define elf_backend_default_use_rela_p 0
 
 #define elf_backend_got_header_size    12
+#define elf_backend_extern_protected_data 1
 
 #undef  elf_backend_obj_attrs_vendor
 #define elf_backend_obj_attrs_vendor           "aeabi"
This page took 0.043465 seconds and 4 git commands to generate.