2004-12-01 Paul Brook <paul@codesourcery.com>
[deliverable/binutils-gdb.git] / bfd / elf32-arm.c
index b3edf6d5b83e8483443ceab0312f91b4d6dd95ba..325d2e86251cb8094b5f6ded7c8d481c7f015231 100644 (file)
@@ -1161,10 +1161,6 @@ struct elf32_arm_link_hash_table
     /* An arbitrary input BFD chosen to hold the glue sections.  */
     bfd * bfd_of_glue_owner;
 
-    /* A boolean indicating whether knowledge of the ARM's pipeline
-       length should be applied by the linker.  */
-    int no_pipeline_knowledge;
-
     /* Nonzero to output a BE8 image.  */
     int byteswap_code;
 
@@ -1382,7 +1378,6 @@ elf32_arm_link_hash_table_create (bfd *abfd)
   ret->thumb_glue_size = 0;
   ret->arm_glue_size = 0;
   ret->bfd_of_glue_owner = NULL;
-  ret->no_pipeline_knowledge = 0;
   ret->byteswap_code = 0;
   ret->target1_is_rel = 0;
   ret->target2_reloc = R_ARM_NONE;
@@ -1771,7 +1766,6 @@ bfd_elf32_arm_get_bfd_for_interworking (bfd *abfd, struct bfd_link_info *info)
 bfd_boolean
 bfd_elf32_arm_process_before_allocation (bfd *abfd,
                                         struct bfd_link_info *link_info,
-                                        int no_pipeline_knowledge,
                                         int byteswap_code)
 {
   Elf_Internal_Shdr *symtab_hdr;
@@ -1794,8 +1788,6 @@ bfd_elf32_arm_process_before_allocation (bfd *abfd,
   BFD_ASSERT (globals != NULL);
   BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
 
-  globals->no_pipeline_knowledge = no_pipeline_knowledge;
-
   if (byteswap_code && !bfd_big_endian (abfd))
     {
       _bfd_error_handler (_("%B: BE8 images only valid in big-endian mode."),
@@ -2494,61 +2486,29 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                }
            }
 
-         if (   strcmp (bfd_get_target (input_bfd), "elf32-littlearm-oabi") == 0
-             || strcmp (bfd_get_target (input_bfd), "elf32-bigarm-oabi") == 0)
-           {
-             /* The old way of doing things.  Trearing the addend as a
-                byte sized field and adding in the pipeline offset.  */
-             value -= (input_section->output_section->vma
-                       + input_section->output_offset);
-             value -= rel->r_offset;
-             value += addend;
-
-             if (! globals->no_pipeline_knowledge)
-               value -= 8;
-           }
-         else
-           {
-             /* The ARM ELF ABI says that this reloc is computed as: S - P + A
-                where:
-                 S is the address of the symbol in the relocation.
-                 P is address of the instruction being relocated.
-                 A is the addend (extracted from the instruction) in bytes.
-
-                S is held in 'value'.
-                P is the base address of the section containing the
-                  instruction plus the offset of the reloc into that
-                  section, ie:
-                    (input_section->output_section->vma +
-                     input_section->output_offset +
-                     rel->r_offset).
-                A is the addend, converted into bytes, ie:
-                    (signed_addend * 4)
-
-                Note: None of these operations have knowledge of the pipeline
-                size of the processor, thus it is up to the assembler to
-                encode this information into the addend.  */
-             value -= (input_section->output_section->vma
-                       + input_section->output_offset);
-             value -= rel->r_offset;
-             value += (signed_addend << howto->size);
-
-             /* Previous versions of this code also used to add in the
-                pipeline offset here.  This is wrong because the linker is
-                not supposed to know about such things, and one day it might
-                change.  In order to support old binaries that need the old
-                behaviour however, so we attempt to detect which ABI was
-                used to create the reloc.  */
-             if (! globals->no_pipeline_knowledge)
-               {
-                 Elf_Internal_Ehdr * i_ehdrp; /* Elf file header, internal form */
-
-                 i_ehdrp = elf_elfheader (input_bfd);
-
-                 if (i_ehdrp->e_ident[EI_OSABI] == 0)
-                   value -= 8;
-               }
-           }
+         /* The ARM ELF ABI says that this reloc is computed as: S - P + A
+            where:
+             S is the address of the symbol in the relocation.
+             P is address of the instruction being relocated.
+             A is the addend (extracted from the instruction) in bytes.
+
+            S is held in 'value'.
+            P is the base address of the section containing the
+              instruction plus the offset of the reloc into that
+              section, ie:
+                (input_section->output_section->vma +
+                 input_section->output_offset +
+                 rel->r_offset).
+            A is the addend, converted into bytes, ie:
+                (signed_addend * 4)
+
+            Note: None of these operations have knowledge of the pipeline
+            size of the processor, thus it is up to the assembler to
+            encode this information into the addend.  */
+         value -= (input_section->output_section->vma
+                   + input_section->output_offset);
+         value -= rel->r_offset;
+         value += (signed_addend << howto->size);
 
          signed_addend = value;
          signed_addend >>= howto->rightshift;
@@ -2733,23 +2693,6 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
                       + input_section->output_offset
                       + rel->r_offset);
 
-       if (! globals->no_pipeline_knowledge)
-         {
-           Elf_Internal_Ehdr * i_ehdrp; /* Elf file header, internal form.  */
-
-           i_ehdrp = elf_elfheader (input_bfd);
-
-           /* Previous versions of this code also used to add in the pipline
-              offset here.  This is wrong because the linker is not supposed
-              to know about such things, and one day it might change.  In order
-              to support old binaries that need the old behaviour however, so
-              we attempt to detect which ABI was used to create the reloc.  */
-           if (   strcmp (bfd_get_target (input_bfd), "elf32-littlearm-oabi") == 0
-               || strcmp (bfd_get_target (input_bfd), "elf32-bigarm-oabi") == 0
-               || i_ehdrp->e_ident[EI_OSABI] == 0)
-             relocation += 4;
-         }
-
        check = relocation >> howto->rightshift;
 
        /* If this is a signed value, the rightshift just dropped
@@ -3485,6 +3428,10 @@ elf32_arm_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
   elf_elfheader (obfd)->e_flags = in_flags;
   elf_flags_init (obfd) = TRUE;
 
+  /* Also copy the EI_OSABI field.  */
+  elf_elfheader (obfd)->e_ident[EI_OSABI] =
+    elf_elfheader (ibfd)->e_ident[EI_OSABI];
+
   return TRUE;
 }
 
@@ -5409,7 +5356,10 @@ elf32_arm_post_process_headers (bfd * abfd, struct bfd_link_info * link_info ATT
 
   i_ehdrp = elf_elfheader (abfd);
 
-  i_ehdrp->e_ident[EI_OSABI]      = ARM_ELF_OS_ABI_VERSION;
+  if (EF_ARM_EABI_VERSION (i_ehdrp->e_flags) == EF_ARM_EABI_UNKNOWN)
+    i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_ARM;
+  else
+    i_ehdrp->e_ident[EI_OSABI] = 0;
   i_ehdrp->e_ident[EI_ABIVERSION] = ARM_ELF_ABI_VERSION;
 
   if (link_info)
@@ -5662,6 +5612,82 @@ elf32_arm_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
     elfsym->symbol.flags |= BSF_FUNCTION;
 }
 
+
+/* Mangle thumb function symbols as we read them in.  */
+
+static void
+elf32_arm_swap_symbol_in (bfd * abfd,
+                         const void *psrc,
+                         const void *pshn,
+                         Elf_Internal_Sym *dst)
+{
+  bfd_elf32_swap_symbol_in (abfd, psrc, pshn, dst);
+
+  /* New EABI objects mark thumb function symbols by setting the low bit of
+     the address.  Turn these into STT_ARM_TFUNC.  */
+  if (ELF_ST_TYPE (dst->st_info) == STT_FUNC
+      && (dst->st_value & 1))
+    {
+      dst->st_info = ELF_ST_INFO (ELF_ST_BIND (dst->st_info), STT_ARM_TFUNC);
+      dst->st_value &= ~(bfd_vma) 1;
+    }
+}
+
+
+/* Mangle thumb function symbols as we write them out.  */
+
+static void
+elf32_arm_swap_symbol_out (bfd *abfd,
+                          const Elf_Internal_Sym *src,
+                          void *cdst,
+                          void *shndx)
+{
+  Elf_Internal_Sym newsym;
+
+  /* We convert STT_ARM_TFUNC symbols into STT_FUNC with the low bit
+     of the address set, as per the new EABI.  We do this unconditionally
+     because objcopy does not set the elf header flags until after
+     it writes out the symbol table.  */
+  if (ELF_ST_TYPE (src->st_info) == STT_ARM_TFUNC)
+    {
+      newsym = *src;
+      newsym.st_info = ELF_ST_INFO (ELF_ST_BIND (src->st_info), STT_FUNC);
+      newsym.st_value |= 1;
+      
+      src = &newsym;
+    }
+  bfd_elf32_swap_symbol_out (abfd, src, cdst, shndx);
+}
+
+/* We use this to override swap_symbol_in and swap_symbol_out.  */
+const struct elf_size_info elf32_arm_size_info = {
+  sizeof (Elf32_External_Ehdr),
+  sizeof (Elf32_External_Phdr),
+  sizeof (Elf32_External_Shdr),
+  sizeof (Elf32_External_Rel),
+  sizeof (Elf32_External_Rela),
+  sizeof (Elf32_External_Sym),
+  sizeof (Elf32_External_Dyn),
+  sizeof (Elf_External_Note),
+  4,
+  1,
+  32, 2,
+  ELFCLASS32, EV_CURRENT,
+  bfd_elf32_write_out_phdrs,
+  bfd_elf32_write_shdrs_and_ehdr,
+  bfd_elf32_write_relocs,
+  elf32_arm_swap_symbol_in,
+  elf32_arm_swap_symbol_out,
+  bfd_elf32_slurp_reloc_table,
+  bfd_elf32_slurp_symbol_table,
+  bfd_elf32_swap_dyn_in,
+  bfd_elf32_swap_dyn_out,
+  bfd_elf32_swap_reloc_in,
+  bfd_elf32_swap_reloc_out,
+  bfd_elf32_swap_reloca_in,
+  bfd_elf32_swap_reloca_out
+};
+
 #define ELF_ARCH                       bfd_arch_arm
 #define ELF_MACHINE_CODE               EM_ARM
 #ifdef __QNXTARGET__
@@ -5701,6 +5727,7 @@ elf32_arm_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
 #define elf_backend_final_write_processing      elf32_arm_final_write_processing
 #define elf_backend_copy_indirect_symbol        elf32_arm_copy_indirect_symbol
 #define elf_backend_symbol_processing          elf32_arm_symbol_processing
+#define elf_backend_size_info                  elf32_arm_size_info
 
 #define elf_backend_can_refcount    1
 #define elf_backend_can_gc_sections 1
This page took 0.026056 seconds and 4 git commands to generate.