Improve verbose message
[deliverable/binutils-gdb.git] / bfd / elf32-arm.h
index f7ef578a1647cc9d47b0c89084354b67d76b31b9..e655781bde6a60fcd7a20555d19d1f85e3336ac8 100644 (file)
@@ -1,5 +1,5 @@
 /* 32-bit ELF support for ARM
-   Copyright 1998, 1999 Free Software Foundation, Inc.
+   Copyright 1998, 1999, 2000 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -29,7 +29,7 @@ static boolean elf32_arm_merge_private_bfd_data
   PARAMS ((bfd *, bfd *));
 static boolean elf32_arm_print_private_bfd_data
   PARAMS ((bfd *, PTR));
-static int elf32_arm_get_symbol_type 
+static int elf32_arm_get_symbol_type
   PARAMS (( Elf_Internal_Sym *, int));
 static struct bfd_link_hash_table *elf32_arm_link_hash_table_create
   PARAMS ((bfd *));
@@ -50,6 +50,12 @@ static void record_thumb_to_arm_glue
   PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
 static void elf32_arm_post_process_headers
   PARAMS ((bfd *, struct bfd_link_info *));
+static int elf32_arm_to_thumb_stub
+  PARAMS ((struct bfd_link_info *, const char *, bfd *, bfd *, asection *,
+          bfd_byte *, asection *, bfd_vma, bfd_signed_vma, bfd_vma));
+static int elf32_thumb_to_arm_stub
+  PARAMS ((struct bfd_link_info *, const char *, bfd *, bfd *, asection *,
+          bfd_byte *, asection *, bfd_vma, bfd_signed_vma, bfd_vma));
 
 /* The linker script knows the section names for placement.
    The entry_names are used to do simple name mangling on the stubs.
@@ -75,7 +81,7 @@ static void elf32_arm_post_process_headers
 
 /* The first entry in a procedure linkage table looks like
    this.  It is set up so that any shared library function that is
-   called before the relocation has been set up calles the dynamic
+   called before the relocation has been set up calls the dynamic
    linker first */
 
 static const bfd_byte elf32_arm_plt0_entry [PLT_ENTRY_SIZE] =
@@ -83,7 +89,7 @@ static const bfd_byte elf32_arm_plt0_entry [PLT_ENTRY_SIZE] =
   0x04, 0xe0, 0x2d, 0xe5,      /* str   lr, [sp, #-4]!     */
   0x10, 0xe0, 0x9f, 0xe5,      /* ldr   lr, [pc, #16]      */
   0x0e, 0xe0, 0x8f, 0xe0,      /* adr   lr, pc, lr         */
-  0x08, 0xf0, 0xbe, 0xe5       /* ldr   pc, [lr, #-4]      */
+  0x08, 0xf0, 0xbe, 0xe5       /* ldr   pc, [lr, #8]!      */
 };
 
 /* Subsequent entries in a procedure linkage table look like
@@ -321,7 +327,7 @@ static const insn32 a2t3_func_addr_insn = 0x00000001;
    ldmia r13! {r6, lr}
    bx    lr
    __func_addr:
-   .word        func 
+   .word        func
  */
 
 #define THUMB2ARM_GLUE_SIZE 8
@@ -539,7 +545,10 @@ bfd_elf32_arm_get_bfd_for_interworking (abfd, info)
 
   if (sec == NULL)
     {
-      flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
+      /* Note: we do not include the flag SEC_LINKER_CREATED, as this
+        will prevent elf_link_input_bfd() from processing the contents
+        of this section.  */
+      flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_CODE | SEC_READONLY;
 
       sec = bfd_make_section (abfd, ARM2THUMB_GLUE_SECTION_NAME);
 
@@ -547,13 +556,17 @@ bfd_elf32_arm_get_bfd_for_interworking (abfd, info)
          || !bfd_set_section_flags (abfd, sec, flags)
          || !bfd_set_section_alignment (abfd, sec, 2))
        return false;
+      
+      /* Set the gc mark to prevent the section from being removed by garbage
+        collection, despite the fact that no relocs refer to this section.  */
+      sec->gc_mark = 1;
     }
 
   sec = bfd_get_section_by_name (abfd, THUMB2ARM_GLUE_SECTION_NAME);
 
   if (sec == NULL)
     {
-      flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
+      flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_CODE | SEC_READONLY;
 
       sec = bfd_make_section (abfd, THUMB2ARM_GLUE_SECTION_NAME);
 
@@ -561,6 +574,8 @@ bfd_elf32_arm_get_bfd_for_interworking (abfd, info)
          || !bfd_set_section_flags (abfd, sec, flags)
          || !bfd_set_section_alignment (abfd, sec, 2))
        return false;
+      
+      sec->gc_mark = 1;
     }
 
   /* Save the bfd for later use.  */
@@ -600,7 +615,7 @@ bfd_elf32_arm_process_before_allocation (abfd, link_info, no_pipeline_knowledge)
   BFD_ASSERT (globals->bfd_of_glue_owner != NULL);
 
   globals->no_pipeline_knowledge = no_pipeline_knowledge;
-  
+
   /* Rummage around all the relocs and map the glue vectors.  */
   sec = abfd->sections;
 
@@ -625,7 +640,6 @@ bfd_elf32_arm_process_before_allocation (abfd, link_info, no_pipeline_knowledge)
        {
          long r_type;
          unsigned long r_index;
-         unsigned char code;
 
          struct elf_link_hash_entry *h;
 
@@ -700,7 +714,7 @@ bfd_elf32_arm_process_before_allocation (abfd, link_info, no_pipeline_knowledge)
            {
            case R_ARM_PC24:
              /* This one is a call from arm code.  We need to look up
-                the target of the call. If it is a thumb target, we
+                the target of the call.  If it is a thumb target, we
                 insert glue.  */
 
              if (ELF_ST_TYPE(h->type) == STT_ARM_TFUNC)
@@ -708,9 +722,9 @@ bfd_elf32_arm_process_before_allocation (abfd, link_info, no_pipeline_knowledge)
              break;
 
            case R_ARM_THM_PC22:
-             /* This one is a call from thumb code.  We look 
-                up the target of the call. If it is not a thumb
-                 target, we insert glue. */ 
+             /* This one is a call from thumb code.  We look
+                up the target of the call.  If it is not a thumb
+                 target, we insert glue.  */
 
              if (ELF_ST_TYPE (h->type) != STT_ARM_TFUNC)
                record_thumb_to_arm_glue (link_info, h);
@@ -723,6 +737,7 @@ bfd_elf32_arm_process_before_allocation (abfd, link_info, no_pipeline_knowledge)
     }
 
   return true;
+  
 error_return:
   if (free_relocs != NULL)
     free (free_relocs);
@@ -730,22 +745,22 @@ error_return:
     free (free_contents);
   if (free_extsyms != NULL)
     free (free_extsyms);
+  
   return false;
-
 }
 
 /* The thumb form of a long branch is a bit finicky, because the offset
    encoding is split over two fields, each in it's own instruction. They
-   can occur in any order. So given a thumb form of long branch, and an 
+   can occur in any order. So given a thumb form of long branch, and an
    offset, insert the offset into the thumb branch and return finished
-   instruction. 
+   instruction.
 
-   It takes two thumb instructions to encode the target address. Each has 
+   It takes two thumb instructions to encode the target address. Each has
    11 bits to invest. The upper 11 bits are stored in one (identifed by
-   H-0.. see below), the lower 11 bits are stored in the other (identified 
-   by H-1). 
+   H-0.. see below), the lower 11 bits are stored in the other (identified
+   by H-1).
 
-   Combine together and shifted left by 1 (it's a half word address) and 
+   Combine together and shifted left by 1 (it's a half word address) and
    there you have it.
 
    Op: 1111 = F,
@@ -753,17 +768,17 @@ error_return:
    Op: 1111 = F,
    H-1, lower address-0 = 800
 
-   They can be ordered either way, but the arm tools I've seen always put 
+   They can be ordered either way, but the arm tools I've seen always put
    the lower one first. It probably doesn't matter. krk@cygnus.com
 
    XXX:  Actually the order does matter.  The second instruction (H-1)
    moves the computed address into the PC, so it must be the second one
    in the sequence.  The problem, however is that whilst little endian code
    stores the instructions in HI then LOW order, big endian code does the
-   reverse.  nickc@cygnus.com  */
+   reverse.  nickc@cygnus.com.  */
 
-#define LOW_HI_ORDER 0xF800F000
-#define HI_LOW_ORDER 0xF000F800
+#define LOW_HI_ORDER      0xF800F000
+#define HI_LOW_ORDER      0xF000F800
 
 static insn32
 insert_thumb_branch (br_insn, rel_off)
@@ -776,9 +791,9 @@ insert_thumb_branch (br_insn, rel_off)
 
   BFD_ASSERT ((rel_off & 1) != 1);
 
-  rel_off >>= 1;               /* half word aligned address */
-  low_bits = rel_off & 0x000007FF;     /* the bottom 11 bits */
-  high_bits = (rel_off >> 11) & 0x000007FF;    /* the top 11 bits */
+  rel_off >>= 1;                               /* Half word aligned address.  */
+  low_bits = rel_off & 0x000007FF;             /* The bottom 11 bits.  */
+  high_bits = (rel_off >> 11) & 0x000007FF;    /* The top 11 bits.  */
 
   if ((br_insn & LOW_HI_ORDER) == LOW_HI_ORDER)
     br_insn = LOW_HI_ORDER | (low_bits << 16) | high_bits;
@@ -788,7 +803,7 @@ insert_thumb_branch (br_insn, rel_off)
     abort ();                  /* error - not a valid branch instruction form */
 
   /* FIXME: abort is probably not the right call. krk@cygnus.com */
-
+  
   return br_insn;
 }
 
@@ -796,23 +811,23 @@ insert_thumb_branch (br_insn, rel_off)
 static int
 elf32_thumb_to_arm_stub (info, name, input_bfd, output_bfd, input_section,
                         hit_data, sym_sec, offset, addend, val)
-     struct bfd_link_info *info;
-     char *name;
-     bfd *input_bfd;
-     bfd *output_bfd;
-     asection *input_section;
-     bfd_byte *hit_data;
-     asection *sym_sec;
-     int offset;
-     int addend;
-     bfd_vma val;
+     struct bfd_link_info * info;
+     const char *           name;
+     bfd *                  input_bfd;
+     bfd *                  output_bfd;
+     asection *             input_section;
+     bfd_byte *             hit_data;
+     asection *             sym_sec;
+     bfd_vma                offset;
+     bfd_signed_vma         addend;
+     bfd_vma                val;
 {
-  asection *s = 0;
+  asection * s = 0;
   long int my_offset;
   unsigned long int tmp;
   long int ret_offset;
-  struct elf_link_hash_entry *myh;
-  struct elf32_arm_link_hash_table *globals;
+  struct elf_link_hash_entry * myh;
+  struct elf32_arm_link_hash_table * globals;
 
   myh = find_thumb_glue (info, name, input_bfd);
   if (myh == NULL)
@@ -880,7 +895,7 @@ elf32_thumb_to_arm_stub (info, name, input_bfd, output_bfd, input_section,
     + my_offset
     - (input_section->output_offset
        + offset + addend)
-    - 4;
+    - 8;
 
   tmp = bfd_get_32 (input_bfd, hit_data
                    - input_section->vma);
@@ -896,24 +911,23 @@ elf32_thumb_to_arm_stub (info, name, input_bfd, output_bfd, input_section,
 static int
 elf32_arm_to_thumb_stub (info, name, input_bfd, output_bfd, input_section,
                         hit_data, sym_sec, offset, addend, val)
-
-     struct bfd_link_info *info;
-     char *name;
-     bfd *input_bfd;
-     bfd *output_bfd;
-     asection *input_section;
-     bfd_byte *hit_data;
-     asection *sym_sec;
-     int offset;
-     int addend;
-     bfd_vma val;
+     struct bfd_link_info * info;
+     const char *           name;
+     bfd *                  input_bfd;
+     bfd *                  output_bfd;
+     asection *             input_section;
+     bfd_byte *             hit_data;
+     asection *             sym_sec;
+     bfd_vma                offset;
+     bfd_signed_vma         addend;
+     bfd_vma                val;
 {
   unsigned long int tmp;
   long int my_offset;
-  asection *s;
+  asection * s;
   long int ret_offset;
-  struct elf_link_hash_entry *myh;
-  struct elf32_arm_link_hash_table *globals;
+  struct elf_link_hash_entry * myh;
+  struct elf32_arm_link_hash_table * globals;
 
   myh = find_arm_glue (info, name, input_bfd);
   if (myh == NULL)
@@ -971,13 +985,12 @@ elf32_arm_to_thumb_stub (info, name, input_bfd, output_bfd, input_section,
        + input_section->output_section->vma
        + offset + addend)
     - 8;
-
+  
   tmp = tmp | ((ret_offset >> 2) & 0x00FFFFFF);
 
   bfd_put_32 (output_bfd, tmp, hit_data
              - input_section->vma);
 
-
   return true;
 }
 
@@ -1012,9 +1025,9 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
   bfd_vma                       addend;
   bfd_signed_vma                signed_addend;
   struct elf32_arm_link_hash_table * globals;
-  
+
   globals = elf32_arm_hash_table (info);
-    
+
   dynobj = elf_hash_table (info)->dynobj;
   if (dynobj)
     {
@@ -1040,7 +1053,7 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
 #else
   addend = signed_addend = rel->r_addend;
 #endif
-  
+
   switch (r_type)
     {
     case R_ARM_NONE:
@@ -1049,9 +1062,12 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
     case R_ARM_PC24:
     case R_ARM_ABS32:
     case R_ARM_REL32:
+#ifndef OLD_ARM_ABI
+    case R_ARM_XPC25:
+#endif
       /* When generating a shared object, these relocations are copied
         into the output file to be resolved at run time. */
-      
+
       if (info->shared
          && (r_type != R_ARM_PC24
              || (h != NULL
@@ -1062,35 +1078,35 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
        {
          Elf_Internal_Rel outrel;
          boolean skip, relocate;
-         
+
          if (sreloc == NULL)
            {
              const char * name;
-             
+
              name = (bfd_elf_string_from_elf_section
                      (input_bfd,
                       elf_elfheader (input_bfd)->e_shstrndx,
                       elf_section_data (input_section)->rel_hdr.sh_name));
              if (name == NULL)
                return bfd_reloc_notsupported;
-             
+
              BFD_ASSERT (strncmp (name, ".rel", 4) == 0
                          && strcmp (bfd_get_section_name (input_bfd,
                                                           input_section),
                                     name + 4) == 0);
-             
+
              sreloc = bfd_get_section_by_name (dynobj, name);
              BFD_ASSERT (sreloc != NULL);
            }
-         
+
          skip = false;
-         
+
          if (elf_section_data (input_section)->stab_info == NULL)
            outrel.r_offset = rel->r_offset;
          else
            {
              bfd_vma off;
-             
+
              off = (_bfd_stab_section_offset
                     (output_bfd, &elf_hash_table (info)->stab_info,
                      input_section,
@@ -1100,10 +1116,10 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
                skip = true;
              outrel.r_offset = off;
            }
-         
+
          outrel.r_offset += (input_section->output_section->vma
                              + input_section->output_offset);
-         
+
          if (skip)
            {
              memset (&outrel, 0, sizeof outrel);
@@ -1138,34 +1154,53 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
                  outrel.r_info = ELF32_R_INFO (h->dynindx, R_ARM_ABS32);
                }
            }
-         
+
          bfd_elf32_swap_reloc_out (output_bfd, &outrel,
                                    (((Elf32_External_Rel *)
                                      sreloc->contents)
                                     + sreloc->reloc_count));
          ++sreloc->reloc_count;
          
-         /* If this reloc is against an external symbol, we do not want to 
+         /* If this reloc is against an external symbol, we do not want to
             fiddle with the addend.  Otherwise, we need to include the symbol
             value so that it becomes an addend for the dynamic reloc. */
          if (! relocate)
            return bfd_reloc_ok;
+
          
-         return _bfd_final_link_relocate (howto, input_bfd, input_section, 
+         return _bfd_final_link_relocate (howto, input_bfd, input_section,
                                           contents, rel->r_offset, value,
                                           (bfd_vma) 0);
        }
       else switch (r_type)
        {
-       case R_ARM_PC24:
-         /* Arm B/BL instruction */
-         
-         /* Check for arm calling thumb function.  */
-         if (sym_flags == STT_ARM_TFUNC)
+#ifndef OLD_ARM_ABI
+       case R_ARM_XPC25:         /* Arm BLX instruction.  */
+#endif
+       case R_ARM_PC24:          /* Arm B/BL instruction */
+#ifndef OLD_ARM_ABI
+         if (r_type == R_ARM_XPC25)
            {
-             elf32_arm_to_thumb_stub (info, sym_name, input_bfd, output_bfd,
-                                      input_section, hit_data, sym_sec, rel->r_offset, addend, value);
-             return bfd_reloc_ok;
+             /* Check for Arm calling Arm function.  */
+             /* FIXME: Should we translate the instruction into a BL
+                instruction instead ?  */
+             if (sym_flags != STT_ARM_TFUNC)
+               _bfd_error_handler (_("\
+%s: Warning: Arm BLX instruction targets Arm function '%s'."),
+                                   bfd_get_filename (input_bfd),
+                                   h->root.root.string);
+           }
+         else
+#endif
+           {
+             /* Check for Arm calling Thumb function.  */
+             if (sym_flags == STT_ARM_TFUNC)
+               {
+                 elf32_arm_to_thumb_stub (info, sym_name, input_bfd, output_bfd,
+                                          input_section, hit_data, sym_sec, rel->r_offset,
+                                          signed_addend, value);
+                 return bfd_reloc_ok;
+               }
            }
 
          if (   strcmp (bfd_get_target (input_bfd), "elf32-littlearm-oabi") == 0
@@ -1173,12 +1208,12 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
            {
              /* 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;
            }
@@ -1189,7 +1224,7 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
                  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:
@@ -1207,41 +1242,54 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
                        + 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;
                }
            }
-         
-         value >>= howto->rightshift;    
-         value &= howto->dst_mask;
-         value |= (bfd_get_32 (input_bfd, hit_data) & (~ howto->dst_mask));
+
+         /* It is not an error for an undefined weak reference to be
+            out of range.  Any program that branches to such a symbol
+            is going to crash anyway, so there is no point worrying 
+            about getting the destination exactly right.  */        
+         if (! h || h->root.type != bfd_link_hash_undefweak)
+           {
+             /* Perform a signed range check.  */
+             signed_addend = value;
+             signed_addend >>= howto->rightshift;
+             if (signed_addend > ((bfd_signed_vma)(howto->dst_mask >> 1))
+                 || signed_addend < - ((bfd_signed_vma) ((howto->dst_mask + 1) >> 1)))
+               return bfd_reloc_overflow;
+           }
+             
+         value = (signed_addend & howto->dst_mask)
+           | (bfd_get_32 (input_bfd, hit_data) & (~ howto->dst_mask));
          break;
-         
+
        case R_ARM_ABS32:
          value += addend;
          if (sym_flags == STT_ARM_TFUNC)
            value |= 1;
          break;
-         
+
        case R_ARM_REL32:
          value -= (input_section->output_section->vma
                    + input_section->output_offset);
          value += addend;
          break;
        }
-      
+
       bfd_put_32 (input_bfd, value, hit_data);
       return bfd_reloc_ok;
 
@@ -1293,14 +1341,16 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
       bfd_put_16 (input_bfd, value, hit_data);
       return bfd_reloc_ok;
 
+#ifndef OLD_ARM_ABI
+    case R_ARM_THM_XPC22:
+#endif
     case R_ARM_THM_PC22:
-      /* Thumb BL (branch long instruction). */
+      /* Thumb BL (branch long instruction).  */
       {
        bfd_vma        relocation;
        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_vma        src_mask = 0x007FFFFE;
        bfd_signed_vma reloc_signed_max = (1 << (howto->bitsize - 1)) - 1;
        bfd_signed_vma reloc_signed_min = ~ reloc_signed_max;
        bfd_vma        check;
@@ -1317,30 +1367,47 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
          signed_addend = addend;
        }
 #endif
-
-        /* If it's not a call to thumb, assume call to arm */
-       if (sym_flags != STT_ARM_TFUNC)
+#ifndef OLD_ARM_ABI
+       if (r_type == R_ARM_THM_XPC22)
          {
-           if (elf32_thumb_to_arm_stub
-               (info, sym_name, input_bfd, output_bfd, input_section,
-                hit_data, sym_sec, rel->r_offset, addend, value))
-             return bfd_reloc_ok;
-           else
-             return bfd_reloc_dangerous;
+           /* Check for Thumb to Thumb call.  */
+           /* FIXME: Should we translate the instruction into a BL
+              instruction instead ?  */
+           if (sym_flags == STT_ARM_TFUNC)
+             _bfd_error_handler (_("\
+%s: Warning: Thumb BLX instruction targets thumb function '%s'."),
+                                 bfd_get_filename (input_bfd),
+                                 h->root.root.string);
          }
-       
+       else
+#endif
+         {
+           /* If it is not a call to Thumb, assume call to Arm.
+              If it is a call relative to a section name, then it is not a
+              function call at all, but rather a long jump.  */
+           if (sym_flags != STT_ARM_TFUNC && sym_flags != STT_SECTION)
+             {
+               if (elf32_thumb_to_arm_stub
+                   (info, sym_name, input_bfd, output_bfd, input_section,
+                    hit_data, sym_sec, rel->r_offset, signed_addend, value))
+                 return bfd_reloc_ok;
+               else
+                 return bfd_reloc_dangerous;
+             }
+         }
+
        relocation = value + signed_addend;
-       
+
        relocation -= (input_section->output_section->vma
                       + 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);
            
+           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
@@ -1351,7 +1418,7 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
                || i_ehdrp->e_ident[EI_OSABI] == 0)
              relocation += 4;
          }
-       
+
        check = relocation >> howto->rightshift;
 
        /* If this is a signed value, the rightshift just dropped
@@ -1400,15 +1467,15 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
       BFD_ASSERT (sgot != NULL);
       if (sgot == NULL)
         return bfd_reloc_notsupported;
-        
+      
       /* Note that sgot->output_offset is not involved in this
          calculation.  We always want the start of .got.  If we
          define _GLOBAL_OFFSET_TABLE in a different way, as is
          permitted by the ABI, we might have to change this
          calculation. */
-      
+
       value -= sgot->output_section->vma;
-      return _bfd_final_link_relocate (howto, input_bfd, input_section, 
+      return _bfd_final_link_relocate (howto, input_bfd, input_section,
                                       contents, rel->r_offset, value,
                                       (bfd_vma) 0);
 
@@ -1416,28 +1483,28 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
       /* Use global offset table as symbol value. */
 
       BFD_ASSERT (sgot != NULL);
-      
+
       if (sgot == NULL)
         return bfd_reloc_notsupported;
 
       value = sgot->output_section->vma;
-      return _bfd_final_link_relocate (howto, input_bfd, input_section, 
+      return _bfd_final_link_relocate (howto, input_bfd, input_section,
                                       contents, rel->r_offset, value,
                                       (bfd_vma) 0);
-      
+
     case R_ARM_GOT32:
       /* Relocation is to the entry for this symbol in the
          global offset table. */
       if (sgot == NULL)
        return bfd_reloc_notsupported;
-      
+
       if (h != NULL)
        {
          bfd_vma off;
-         
+
          off = h->got.offset;
          BFD_ASSERT (off != (bfd_vma) -1);
-         
+
          if (!elf_hash_table (info)->dynamic_sections_created ||
              (info->shared && (info->symbolic || h->dynindx == -1)
               && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
@@ -1447,11 +1514,11 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
                 entry in the global offset table.  Since the offset must
                 always be a multiple of 4, we use the least significant bit
                 to record whether we have initialized it already.
-                
+
                 When doing a dynamic link, we create a .rel.got relocation
-                entry to initialize the value.  This is done in the 
+                entry to initialize the value.  This is done in the
                 finish_dynamic_symbol routine. */
-             
+
              if ((off & 1) != 0)
                off &= ~1;
              else
@@ -1460,18 +1527,18 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
                  h->got.offset |= 1;
                }
            }
-         
+
          value = sgot->output_offset + off;
        }
       else
        {
          bfd_vma off;
-         
+
          BFD_ASSERT (local_got_offsets != NULL &&
                      local_got_offsets[r_symndx] != (bfd_vma) -1);
-         
+
          off = local_got_offsets[r_symndx];
-         
+
          /* The offset must always be a multiple of 4.  We use the
             least significant bit to record whether we have already
             generated the necessary reloc. */
@@ -1480,17 +1547,17 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
          else
            {
              bfd_put_32 (output_bfd, value, sgot->contents + off);
-             
+
              if (info->shared)
                {
                  asection * srelgot;
                  Elf_Internal_Rel outrel;
-                 
+
                  srelgot = bfd_get_section_by_name (dynobj, ".rel.got");
                  BFD_ASSERT (srelgot != NULL);
-                 
+
                  outrel.r_offset = (sgot->output_section->vma
-                                    + sgot->output_offset 
+                                    + sgot->output_offset
                                     + off);
                  outrel.r_info = ELF32_R_INFO (0, R_ARM_RELATIVE);
                  bfd_elf32_swap_reloc_out (output_bfd, &outrel,
@@ -1499,17 +1566,17 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
                                             + srelgot->reloc_count));
                  ++srelgot->reloc_count;
                }
-             
+
              local_got_offsets[r_symndx] |= 1;
            }
-         
+
          value = sgot->output_offset + off;
        }
       
-      return _bfd_final_link_relocate (howto, input_bfd, input_section, 
+      return _bfd_final_link_relocate (howto, input_bfd, input_section,
                                       contents, rel->r_offset, value,
                                       (bfd_vma) 0);
-      
+
     case R_ARM_PLT32:
       /* Relocation is to the entry for this symbol in the
          procedure linkage table.  */
@@ -1539,7 +1606,7 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
       return _bfd_final_link_relocate (howto, input_bfd, input_section,
                                       contents, rel->r_offset, value,
                                       (bfd_vma) 0);
-      
+
     case R_ARM_SBREL32:
       return bfd_reloc_notsupported;
 
@@ -1569,6 +1636,55 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
     }
 }
 
+#ifdef USE_REL
+/* Add INCREMENT to the reloc (of type HOWTO) at ADDRESS.  */
+static void
+arm_add_to_rel (abfd, address, howto, increment)
+     bfd *              abfd;
+     bfd_byte *         address;
+     reloc_howto_type * howto;
+     bfd_signed_vma     increment;
+{
+  bfd_vma        contents;
+  bfd_signed_vma addend;
+
+  contents = bfd_get_32 (abfd, address);
+
+  /* Get the (signed) value from the instruction.  */
+  addend = contents & howto->src_mask;
+  if (addend & ((howto->src_mask + 1) >> 1))
+    {
+      bfd_signed_vma mask;
+      
+      mask = -1;
+      mask &= ~ howto->src_mask;
+      addend |= mask;
+    }
+
+  /* Add in the increment, (which is a byte value).  */
+  switch (howto->type)
+    {
+    case R_ARM_THM_PC22:
+    default:
+      addend += increment;
+      break;
+      
+    case R_ARM_PC24:
+      addend <<= howto->size;
+      addend +=  increment;
+      
+      /* Should we check for overflow here ?  */
+
+      /* Drop any undesired bits.  */
+      addend >>= howto->rightshift;
+      break;
+    }
+  
+  contents = (contents & ~ howto->dst_mask) | (addend & howto->dst_mask);
+  
+  bfd_put_32 (abfd, contents, address);
+}
+#endif /* USE_REL */
 
 /* Relocate an ARM ELF section.  */
 static boolean
@@ -1605,7 +1721,7 @@ elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section,
       bfd_vma                      relocation;
       bfd_reloc_status_type        r;
       arelent                      bfd_reloc;
-      
+
       r_symndx = ELF32_R_SYM (rel->r_info);
       r_type   = ELF32_R_TYPE (rel->r_info);
 
@@ -1629,18 +1745,8 @@ elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section,
                {
                  sec = local_sections[r_symndx];
 #ifdef USE_REL
-                 {
-                   bfd_vma val;
-                   bfd_vma insn;
-                   
-                   insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
-                   val = insn + ((sec->output_offset + sym->st_value) 
-                                 >> howto->rightshift);
-                   val &= howto->dst_mask;
-                   val |= insn & ~(howto->dst_mask);
-                   
-                   bfd_put_32 (input_bfd, val, contents + rel->r_offset);
-                 }
+                 arm_add_to_rel (input_bfd, contents + rel->r_offset,
+                                 howto, sec->output_offset + sym->st_value);
 #else
                  rel->r_addend += (sec->output_offset + sym->st_value)
                    >> howto->rightshift;
@@ -1673,11 +1779,11 @@ elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section,
              || h->root.type == bfd_link_hash_defweak)
            {
              int relocation_needed = 1;
-             
+
              sec = h->root.u.def.section;
-             
+
              /* In these cases, we don't need the relocation value.
-                We check specially because in some obscure cases 
+                We check specially because in some obscure cases
                 sec->output_section will be NULL. */
              switch (r_type)
                {
@@ -1692,11 +1798,11 @@ elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section,
                      )
                    relocation_needed = 0;
                  break;
-                 
+
                case R_ARM_GOTPC:
                  relocation_needed = 0;
                  break;
-                 
+
                case R_ARM_GOT32:
                  if (elf_hash_table(info)->dynamic_sections_created
                      && (!info->shared
@@ -1706,12 +1812,12 @@ elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section,
                      )
                    relocation_needed = 0;
                  break;
-                 
+
                case R_ARM_PLT32:
                  if (h->plt.offset != (bfd_vma)-1)
                    relocation_needed = 0;
                  break;
-                 
+
                default:
                  if (sec->output_section == NULL)
                    {
@@ -1732,11 +1838,17 @@ elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section,
            }
          else if (h->root.type == bfd_link_hash_undefweak)
            relocation = 0;
+         else if (info->shared && !info->symbolic
+                  && !info->no_undefined
+                  && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
+           relocation = 0;
          else
            {
              if (!((*info->callbacks->undefined_symbol)
                    (info, h->root.root.string, input_bfd,
-                    input_section, rel->r_offset)))
+                    input_section, rel->r_offset,
+                    (!info->shared || info->no_undefined
+                     || ELF_ST_VISIBILITY (h->other)))))
                return false;
              relocation = 0;
            }
@@ -1751,7 +1863,7 @@ elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section,
          if (name == NULL || *name == '\0')
            name = bfd_section_name (input_bfd, sec);
        }
-      
+
       r = elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
                                         input_section, contents, rel,
                                         relocation, info, sec, name,
@@ -1774,7 +1886,7 @@ elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section,
            case bfd_reloc_undefined:
              if (!((*info->callbacks->undefined_symbol)
                    (info, name, input_bfd, input_section,
-                    rel->r_offset)))
+                    rel->r_offset, true)))
                return false;
              break;
 
@@ -1807,7 +1919,7 @@ elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section,
   return true;
 }
 
-/* Function to keep ARM specific flags in the ELF header. */
+/* Function to keep ARM specific flags in the ELF header.  */
 static boolean
 elf32_arm_set_private_flags (abfd, flags)
      bfd *abfd;
@@ -1816,14 +1928,17 @@ elf32_arm_set_private_flags (abfd, flags)
   if (elf_flags_init (abfd)
       && elf_elfheader (abfd)->e_flags != flags)
     {
-      if (flags & EF_INTERWORK)
-       _bfd_error_handler (_ ("\
+      if (EF_ARM_EABI_VERSION (flags) == EF_ARM_EABI_UNKNOWN)
+       {
+         if (flags & EF_INTERWORK)
+           _bfd_error_handler (_ ("\
 Warning: Not setting interwork flag of %s since it has already been specified as non-interworking"),
-                           bfd_get_filename (abfd));
-      else
-       _bfd_error_handler (_ ("\
+                               bfd_get_filename (abfd));
+         else
+           _bfd_error_handler (_ ("\
 Warning: Clearing the interwork flag of %s due to outside request"),
-                           bfd_get_filename (abfd));
+                               bfd_get_filename (abfd));
+       }
     }
   else
     {
@@ -1834,7 +1949,7 @@ Warning: Clearing the interwork flag of %s due to outside request"),
   return true;
 }
 
-/* Copy backend specific data from one object module to another */
+/* Copy backend specific data from one object module to another */
 static boolean
 elf32_arm_copy_private_bfd_data (ibfd, obfd)
      bfd *ibfd;
@@ -1843,14 +1958,16 @@ elf32_arm_copy_private_bfd_data (ibfd, obfd)
   flagword in_flags;
   flagword out_flags;
 
-  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+  if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
     return true;
 
-  in_flags = elf_elfheader (ibfd)->e_flags;
+  in_flags  = elf_elfheader (ibfd)->e_flags;
   out_flags = elf_elfheader (obfd)->e_flags;
 
-  if (elf_flags_init (obfd) && in_flags != out_flags)
+  if (elf_flags_init (obfd)
+      && EF_ARM_EABI_VERSION (out_flags) == EF_ARM_EABI_UNKNOWN
+      && in_flags != out_flags)
     {
       /* Cannot mix PIC and non-PIC code.  */
       if ((in_flags & EF_PIC) != (out_flags & EF_PIC))
@@ -1887,31 +2004,20 @@ Warning: Clearing the interwork flag in %s because non-interworking code in %s h
    object file when linking.  */
 static boolean
 elf32_arm_merge_private_bfd_data (ibfd, obfd)
-     bfd *ibfd;
-     bfd *obfd;
+     bfd * ibfd;
+     bfd * obfd;
 {
   flagword out_flags;
   flagword in_flags;
 
+  /* Check if we have the same endianess */
+  if (_bfd_generic_verify_endian_match (ibfd, obfd) == false)
+    return false;
+
   if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
     return true;
 
-  /* Check if we have the same endianess */
-  if (   ibfd->xvec->byteorder != obfd->xvec->byteorder
-      && obfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN
-      && ibfd->xvec->byteorder != BFD_ENDIAN_UNKNOWN)
-    {
-      (*_bfd_error_handler)
-       (_("%s: compiled for a %s endian system and target is %s endian"),
-        bfd_get_filename (ibfd),
-        bfd_big_endian (ibfd) ? "big" : "little",
-        bfd_big_endian (obfd) ? "big" : "little");
-
-      bfd_set_error (bfd_error_wrong_format);
-      return false;
-    }
-
   /* The input BFD must have had its flags initialised.  */
   /* The following seems bogus to me -- The flags are initialized in
      the assembler but I don't think an elf_flags_init field is
@@ -1947,6 +2053,18 @@ elf32_arm_merge_private_bfd_data (ibfd, obfd)
     return true;
 
   /* Complain about various flag mismatches.  */
+  if (EF_ARM_EABI_VERSION (in_flags) != EF_ARM_EABI_VERSION (out_flags))
+    {
+      _bfd_error_handler (_("\
+Error: %s compiled for EABI version %d, whereas %s is compiled for version %d"),
+                        bfd_get_filename (ibfd),
+                        (in_flags & EF_ARM_EABIMASK) >> 24,
+                        bfd_get_filename (obfd),
+                        (out_flags & EF_ARM_EABIMASK) >> 24);
+    }
+  else if (EF_ARM_EABI_VERSION (in_flags) != EF_ARM_EABI_UNKNOWN)
+    /* Not sure what needs to be checked for EABI versions >= 1.  */
+    return true;
 
   if ((in_flags & EF_APCS_26) != (out_flags & EF_APCS_26))
     _bfd_error_handler (_ ("\
@@ -1992,38 +2110,82 @@ elf32_arm_print_private_bfd_data (abfd, ptr)
      bfd *abfd;
      PTR ptr;
 {
-  FILE *file = (FILE *) ptr;
+  FILE * file = (FILE *) ptr;
+  unsigned long flags;
 
   BFD_ASSERT (abfd != NULL && ptr != NULL);
 
   /* Print normal ELF private data.  */
   _bfd_elf_print_private_bfd_data (abfd, ptr);
 
+  flags = elf_elfheader (abfd)->e_flags;
   /* Ignore init flag - it may not be set, despite the flags field containing valid data.  */
 
   /* xgettext:c-format */
   fprintf (file, _ ("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
 
-  if (elf_elfheader (abfd)->e_flags & EF_INTERWORK)
-    fprintf (file, _ (" [interworking enabled]"));
-  else
-    fprintf (file, _ (" [interworking not enabled]"));
+  switch (EF_ARM_EABI_VERSION (flags))
+    {
+    case EF_ARM_EABI_UNKNOWN:
+      /* The following flag bits are GNU extenstions and not part of the
+        official ARM ELF extended ABI.  Hence they are only decoded if
+        the EABI version is not set.  */
+      if (flags & EF_INTERWORK)
+       fprintf (file, _ (" [interworking enabled]"));
+      
+      if (flags & EF_APCS_26)
+       fprintf (file, _ (" [APCS-26]"));
+      else
+       fprintf (file, _ (" [APCS-32]"));
+      
+      if (flags & EF_APCS_FLOAT)
+       fprintf (file, _ (" [floats passed in float registers]"));
+      
+      if (flags & EF_PIC)
+       fprintf (file, _ (" [position independent]"));
 
-  if (elf_elfheader (abfd)->e_flags & EF_APCS_26)
-    fprintf (file, _ (" [APCS-26]"));
-  else
-    fprintf (file, _ (" [APCS-32]"));
+      if (flags & EF_NEW_ABI)
+       fprintf (file, _ (" [new ABI]"));
+                
+      if (flags & EF_OLD_ABI)
+       fprintf (file, _ (" [old ABI]"));
+                
+      if (flags & EF_SOFT_FLOAT)
+       fprintf (file, _ (" [software FP]"));
+                
+      flags &= ~(EF_INTERWORK | EF_APCS_26 | EF_APCS_FLOAT | EF_PIC
+                | EF_NEW_ABI | EF_OLD_ABI | EF_SOFT_FLOAT);
+      break;
+      
+    case EF_ARM_EABI_VER1:
+      fprintf (file, _ (" [Version1 EABI]"));
+      
+      if (flags & EF_ARM_SYMSARESORTED)
+       fprintf (file, _ (" [sorted symbol table]"));
+      else
+       fprintf (file, _ (" [unsorted symbol table]"));
+      
+      flags &= ~ EF_ARM_SYMSARESORTED;
+      break;
+      
+    default:
+      fprintf (file, _ (" <EABI version unrecognised>"));
+      break;
+    }
 
-  if (elf_elfheader (abfd)->e_flags & EF_APCS_FLOAT)
-    fprintf (file, _ (" [floats passed in float registers]"));
-  else
-    fprintf (file, _ (" [floats passed in integer registers]"));
+  flags &= ~ EF_ARM_EABIMASK;
 
-  if (elf_elfheader (abfd)->e_flags & EF_PIC)
-    fprintf (file, _ (" [position independent]"));
-  else
-    fprintf (file, _ (" [absolute position]"));
+  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);
+
+  if (flags)
+    fprintf (file, _ ("<Unrecognised flag bits set>"));
+  
   fputc ('\n', file);
 
   return true;
@@ -2034,16 +2196,31 @@ elf32_arm_get_symbol_type (elf_sym, type)
      Elf_Internal_Sym * elf_sym;
      int type;
 {
-  if (ELF_ST_TYPE (elf_sym->st_info) == STT_ARM_TFUNC)
-    return ELF_ST_TYPE (elf_sym->st_info);
-  else
-    return type;
+  switch (ELF_ST_TYPE (elf_sym->st_info))
+    {
+    case STT_ARM_TFUNC:
+      return ELF_ST_TYPE (elf_sym->st_info);
+
+    case STT_ARM_16BIT:
+      /* If the symbol is not an object, return the STT_ARM_16BIT flag.
+        This allows us to distinguish between data used by Thumb instructions
+        and non-data (which is probably code) inside Thumb regions of an
+        executable.  */
+      if (type != STT_OBJECT)
+       return ELF_ST_TYPE (elf_sym->st_info);
+      break;
+      
+    default:
+      break;
+    }
+
+  return type;
 }
-    
+
 static asection *
 elf32_arm_gc_mark_hook (abfd, info, rel, h, sym)
        bfd *abfd;
-       struct bfd_link_info *info;
+       struct bfd_link_info *info ATTRIBUTE_UNUSED;
        Elf_Internal_Rela *rel;
        struct elf_link_hash_entry *h;
        Elf_Internal_Sym *sym;
@@ -2065,6 +2242,9 @@ elf32_arm_gc_mark_hook (abfd, info, rel, h, sym)
 
           case bfd_link_hash_common:
             return h->root.u.c.p->section;
+
+         default:
+           break;
           }
        }
      }
@@ -2085,10 +2265,10 @@ elf32_arm_gc_mark_hook (abfd, info, rel, h, sym)
 
 static boolean
 elf32_arm_gc_sweep_hook (abfd, info, sec, relocs)
-     bfd *abfd;
-     struct bfd_link_info *info;
-     asection *sec;
-     const Elf_Internal_Rela *relocs;
+     bfd *abfd ATTRIBUTE_UNUSED;
+     struct bfd_link_info *info ATTRIBUTE_UNUSED;
+     asection *sec ATTRIBUTE_UNUSED;
+     const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED;
 {
   /* We don't support garbage collection of GOT and PLT relocs yet.  */
   return true;
@@ -2111,33 +2291,33 @@ elf32_arm_check_relocs (abfd, info, sec, relocs)
   bfd *                         dynobj;
   asection * sgot, *srelgot, *sreloc;
   bfd_vma * local_got_offsets;
-   
+  
   if (info->relocateable)
     return true;
+  
   sgot = srelgot = sreloc = NULL;
-                                  
+  
   dynobj = elf_hash_table (info)->dynobj;
   local_got_offsets = elf_local_got_offsets (abfd);
-  
+
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (abfd);
   sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf32_External_Sym);
   if (!elf_bad_symtab (abfd))
     sym_hashes_end -= symtab_hdr->sh_info;
+  
   rel_end = relocs + sec->reloc_count;
   for (rel = relocs; rel < rel_end; rel++)
     {
       struct elf_link_hash_entry *h;
       unsigned long r_symndx;
+      
       r_symndx = ELF32_R_SYM (rel->r_info);
       if (r_symndx < symtab_hdr->sh_info)
         h = NULL;
       else
         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+      
       /* Some relocs require a global offset table.  */
       if (dynobj == NULL)
        {
@@ -2171,7 +2351,7 @@ elf32_arm_check_relocs (abfd, info, sec, relocs)
                && (h != NULL || info->shared))
              {
                srelgot = bfd_get_section_by_name (dynobj, ".rel.got");
-             
+               
                /* If no got relocation section, make one and initialize.  */
                if (srelgot == NULL)
                  {
@@ -2194,7 +2374,7 @@ elf32_arm_check_relocs (abfd, info, sec, relocs)
                if (h->got.offset != (bfd_vma) -1)
                  /* We have already allocated space in the .got.  */
                  break;
-               
+
                h->got.offset = sgot->_raw_size;
 
                /* Make sure this symbol is output as a dynamic symbol.  */
@@ -2221,7 +2401,7 @@ elf32_arm_check_relocs (abfd, info, sec, relocs)
                    for (i = 0; i < symtab_hdr->sh_info; i++)
                      local_got_offsets[i] = (bfd_vma) -1;
                  }
-               
+
                if (local_got_offsets[r_symndx] != (bfd_vma) -1)
                  /* We have already allocated space in the .got.  */
                  break;
@@ -2336,7 +2516,7 @@ elf32_arm_check_relocs (abfd, info, sec, relocs)
                      {
                        p = ((struct elf32_arm_pcrel_relocs_copied *)
                             bfd_alloc (dynobj, sizeof * p));
-                       
+
                        if (p == NULL)
                          return false;
                        p->next = eh->pcrel_relocs_copied;
@@ -2356,20 +2536,20 @@ elf32_arm_check_relocs (abfd, info, sec, relocs)
           if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
             return false;
           break;
+         
         /* This relocation describes which C++ vtable entries are actually
            used.  Record for later use during GC.  */
         case R_ARM_GNU_VTENTRY:
-          if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+          if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_offset))
             return false;
           break;
         }
     }
+
   return true;
 }
 
-       
+
 /* Find the nearest line to a particular section and offset, for error
    reporting.   This code is a duplicate of the code in elf.c, except
    that it also accepts STT_ARM_TFUNC as a symbol that names a function. */
@@ -2392,8 +2572,8 @@ elf32_arm_find_nearest_line
   asymbol **   p;
 
   if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
-                                    filename_ptr, functionname_ptr, 
-                                    line_ptr))
+                                    filename_ptr, functionname_ptr,
+                                    line_ptr, 0))
     return true;
 
   if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
@@ -2401,7 +2581,7 @@ elf32_arm_find_nearest_line
                                             functionname_ptr, line_ptr,
                                             &elf_tdata (abfd)->line_info))
     return false;
-  
+
   if (found)
     return true;
 
@@ -2448,7 +2628,7 @@ elf32_arm_find_nearest_line
   *filename_ptr = filename;
   *functionname_ptr = bfd_asymbol_name (func);
   *line_ptr = 0;
-  
+
   return true;
 }
 
@@ -2738,6 +2918,7 @@ elf32_arm_size_dynamic_sections (output_bfd, info)
                  outname = bfd_get_section_name (output_bfd,
                                                  s->output_section);
                  target = bfd_get_section_by_name (output_bfd, outname + 4);
+                 
                  if (target != NULL
                      && (target->flags & SEC_READONLY) != 0
                      && (target->flags & SEC_ALLOC) != 0)
@@ -2826,7 +3007,7 @@ elf32_arm_size_dynamic_sections (output_bfd, info)
 static boolean
 elf32_arm_discard_copies (h, ignore)
      struct elf32_arm_link_hash_entry * h;
-     PTR ignore;
+     PTR ignore ATTRIBUTE_UNUSED;
 {
   struct elf32_arm_pcrel_relocs_copied * s;
 
@@ -2891,7 +3072,7 @@ elf32_arm_finish_dynamic_symbol (output_bfd, info, h, sym)
       bfd_put_32 (output_bfd,
                      (sgot->output_section->vma
                       + sgot->output_offset
-                      + got_offset 
+                      + got_offset
                       - splt->output_section->vma
                       - splt->output_offset
                       - h->plt.offset - 12),
@@ -2928,7 +3109,7 @@ elf32_arm_finish_dynamic_symbol (output_bfd, info, h, sym)
 
       /* This symbol has an entry in the global offset table.  Set it
         up.  */
-      
+
       sgot = bfd_get_section_by_name (dynobj, ".got");
       srel = bfd_get_section_by_name (dynobj, ".rel.got");
       BFD_ASSERT (sgot != NULL && srel != NULL);
@@ -3105,7 +3286,7 @@ elf32_arm_finish_dynamic_sections (output_bfd, info)
 static void
 elf32_arm_post_process_headers (abfd, link_info)
      bfd * abfd;
-     struct bfd_link_info * link_info;
+     struct bfd_link_info * link_info ATTRIBUTE_UNUSED;
 {
   Elf_Internal_Ehdr * i_ehdrp; /* Elf file header, internal form */
 
@@ -3118,7 +3299,7 @@ elf32_arm_post_process_headers (abfd, link_info)
 
 #define ELF_ARCH                       bfd_arch_arm
 #define ELF_MACHINE_CODE               EM_ARM
-#define ELF_MAXPAGE_SIZE               0x8000
+#define ELF_MAXPAGESIZE                        0x8000
 
 
 #define bfd_elf32_bfd_copy_private_bfd_data    elf32_arm_copy_private_bfd_data
@@ -3146,4 +3327,7 @@ elf32_arm_post_process_headers (abfd, link_info)
 #define elf_backend_want_got_plt    1
 #define elf_backend_want_plt_sym    0
 
+#define elf_backend_got_header_size    12
+#define elf_backend_plt_header_size    PLT_ENTRY_SIZE
+
 #include "elf32-target.h"
This page took 0.057536 seconds and 4 git commands to generate.