* elflink.h (elf_gc_mark): Pass in the section whose relocs we are
[deliverable/binutils-gdb.git] / bfd / elf32-arm.h
index 217666f9abc7ab1af48f47a36c58172707df2261..d1b8fa7926e0dce0154b3dd30a908117a43c879f 100644 (file)
@@ -58,7 +58,7 @@ static boolean elf32_arm_relocate_section
   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
           Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
 static asection * elf32_arm_gc_mark_hook
-  PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *,
+  PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *,
           struct elf_link_hash_entry *, Elf_Internal_Sym *));
 static boolean elf32_arm_gc_sweep_hook
   PARAMS ((bfd *, struct bfd_link_info *, asection *,
@@ -547,31 +547,22 @@ record_thumb_to_arm_glue (link_info, h)
   return;
 }
 
-/* Select a BFD to be used to hold the sections used by the glue code.
-   This function is called from the linker scripts in ld/emultempl/
-   {armelf/pe}.em  */
+/* Add the glue sections to ABFD.  This function is called from the
+   linker scripts in ld/emultempl/{armelf}.em.  */
 
 boolean
-bfd_elf32_arm_get_bfd_for_interworking (abfd, info)
+bfd_elf32_arm_add_glue_sections_to_bfd (abfd, info)
      bfd *abfd;
      struct bfd_link_info *info;
 {
-  struct elf32_arm_link_hash_table *globals;
   flagword flags;
   asection *sec;
 
-  /* If we are only performing a partial link do not bother
-     getting a bfd to hold the glue.  */
+  /* If we are only performing a partial
+     link do not bother adding the glue.  */
   if (info->relocateable)
     return true;
 
-  globals = elf32_arm_hash_table (info);
-
-  BFD_ASSERT (globals != NULL);
-
-  if (globals->bfd_of_glue_owner != NULL)
-    return true;
-
   sec = bfd_get_section_by_name (abfd, ARM2THUMB_GLUE_SECTION_NAME);
 
   if (sec == NULL)
@@ -609,6 +600,32 @@ bfd_elf32_arm_get_bfd_for_interworking (abfd, info)
       sec->gc_mark = 1;
     }
 
+  return true;
+}
+
+/* Select a BFD to be used to hold the sections used by the glue code.
+   This function is called from the linker scripts in ld/emultempl/
+   {armelf/pe}.em  */
+
+boolean
+bfd_elf32_arm_get_bfd_for_interworking (abfd, info)
+     bfd *abfd;
+     struct bfd_link_info *info;
+{
+  struct elf32_arm_link_hash_table *globals;
+
+  /* If we are only performing a partial link
+     do not bother getting a bfd to hold the glue.  */
+  if (info->relocateable)
+    return true;
+
+  globals = elf32_arm_hash_table (info);
+
+  BFD_ASSERT (globals != NULL);
+
+  if (globals->bfd_of_glue_owner != NULL)
+    return true;
+
   /* Save the bfd for later use.  */
   globals->bfd_of_glue_owner = abfd;
 
@@ -1390,7 +1407,7 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
        boolean        overflow = false;
        bfd_vma        upper_insn = bfd_get_16 (input_bfd, hit_data);
        bfd_vma        lower_insn = bfd_get_16 (input_bfd, hit_data + 2);
-       bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
+       bfd_signed_vma reloc_signed_max = ((1 << (howto->bitsize - 1)) - 1) >> howto->rightshift;
        bfd_signed_vma reloc_signed_min = ~ reloc_signed_max;
        bfd_vma        check;
        bfd_signed_vma signed_check;
@@ -1471,22 +1488,19 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
        if (signed_check > reloc_signed_max || signed_check < reloc_signed_min)
          overflow = true;
 
-       /* Put RELOCATION back into the insn.  */
-       upper_insn = (upper_insn & ~(bfd_vma) 0x7ff) | ((relocation >> 12) & 0x7ff);
-       lower_insn = (lower_insn & ~(bfd_vma) 0x7ff) | ((relocation >> 1) & 0x7ff);
-
 #ifndef OLD_ARM_ABI
        if (r_type == R_ARM_THM_XPC22
            && ((lower_insn & 0x1800) == 0x0800))
-         /* Remove bit zero of the adjusted offset.  Bit zero can only be
-            set if the upper insn is at a half-word boundary, since the
-            destination address, an ARM instruction, must always be on a
-            word boundary.  The semantics of the BLX (1) instruction, however,
-            are that bit zero in the offset must always be zero, and the
-            corresponding bit one in the target address will be set from bit
-            one of the source address.  */
-         lower_insn &= ~1;
+         /* For a BLX instruction, make sure that the relocation is rounded up
+            to a word boundary.  This follows the semantics of the instruction
+            which specifies that bit 1 of the target address will come from bit
+            1 of the base address.  */
+         relocation = (relocation + 2) & ~ 3;
 #endif
+       /* Put RELOCATION back into the insn.  */
+       upper_insn = (upper_insn & ~(bfd_vma) 0x7ff) | ((relocation >> 12) & 0x7ff);
+       lower_insn = (lower_insn & ~(bfd_vma) 0x7ff) | ((relocation >> 1) & 0x7ff);
+
        /* Put the relocated value back in the object file:  */
        bfd_put_16 (input_bfd, upper_insn, hit_data);
        bfd_put_16 (input_bfd, lower_insn, hit_data + 2);
@@ -1526,7 +1540,7 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
          signed_check = check | ~((bfd_vma) -1 >> howto->rightshift);
 
        relocation |= (bfd_get_16 (input_bfd, hit_data) & (~ howto->dst_mask));
+
        bfd_put_16 (input_bfd, relocation, hit_data);
 
        /* Assumes two's complement.  */
@@ -1535,7 +1549,7 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
 
        return bfd_reloc_ok;
       }
-      
+
     case R_ARM_GNU_VTINHERIT:
     case R_ARM_GNU_VTENTRY:
       return bfd_reloc_ok;
@@ -1560,7 +1574,7 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
       if (sgot == NULL)
         return bfd_reloc_notsupported;
 
-      /* If we are addressing a Thumb function, we need to adjust the 
+      /* If we are addressing a Thumb function, we need to adjust the
         address by one, so that attempts to call the function pointer will
         correctly interpret it as Thumb code.  */
       if (sym_flags == STT_ARM_TFUNC)
@@ -1830,6 +1844,11 @@ elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section,
   Elf_Internal_Rela *           relend;
   const char *                  name;
 
+#ifndef USE_REL
+  if (info->relocateable)
+    return true;
+#endif
+
   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
 
@@ -1862,6 +1881,7 @@ elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section,
 #endif
       howto = bfd_reloc.howto;
 
+#ifdef USE_REL
       if (info->relocateable)
        {
          /* This is a relocateable link.  We don't have to change
@@ -1874,19 +1894,16 @@ elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section,
              if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
                {
                  sec = local_sections[r_symndx];
-#ifdef USE_REL
                  arm_add_to_rel (input_bfd, contents + rel->r_offset,
                                  howto,
                                  (bfd_signed_vma) (sec->output_offset
                                                    + sym->st_value));
-#else
-                 rel->r_addend += (sec->output_offset + sym->st_value);
-#endif
                }
            }
 
          continue;
        }
+#endif
 
       /* This is a final link.  */
       h = NULL;
@@ -2206,7 +2223,7 @@ elf32_arm_merge_private_bfd_data (ibfd, obfd)
   asection *sec;
 
   /* Check if we have the same endianess.  */
-  if (_bfd_generic_verify_endian_match (ibfd, obfd) == false)
+  if (! _bfd_generic_verify_endian_match (ibfd, obfd))
     return false;
 
   if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
@@ -2357,7 +2374,7 @@ ERROR: %s uses hardware FP, whereas %s uses software FP"),
              _bfd_error_handler (_("\
 Warning: %s supports interworking, whereas %s does not"),
                                  bfd_archive_filename (ibfd),
-                                 bfd_get_filename (obfd));    
+                                 bfd_get_filename (obfd));
            }
          else
            {
@@ -2512,8 +2529,8 @@ elf32_arm_get_symbol_type (elf_sym, type)
 }
 
 static asection *
-elf32_arm_gc_mark_hook (abfd, info, rel, h, sym)
-       bfd *abfd;
+elf32_arm_gc_mark_hook (sec, info, rel, h, sym)
+       asection *sec;
        struct bfd_link_info *info ATTRIBUTE_UNUSED;
        Elf_Internal_Rela *rel;
        struct elf_link_hash_entry *h;
@@ -2543,9 +2560,7 @@ elf32_arm_gc_mark_hook (abfd, info, rel, h, sym)
        }
      }
    else
-     {
-       return bfd_section_from_elf_index (abfd, sym->st_shndx);
-     }
+     return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
 
   return NULL;
 }
@@ -3637,6 +3652,9 @@ elf32_arm_reloc_type_class (rela)
 #define elf_backend_plt_readonly    1
 #define elf_backend_want_got_plt    1
 #define elf_backend_want_plt_sym    0
+#ifndef USE_REL
+#define elf_backend_rela_normal     1
+#endif
 
 #define elf_backend_got_header_size    12
 #define elf_backend_plt_header_size    PLT_ENTRY_SIZE
This page took 0.058293 seconds and 4 git commands to generate.