Add support for R_ARM_XPC25 and R_ARM_THM_XPC22 relocs
authorNick Clifton <nickc@redhat.com>
Sat, 8 Apr 2000 00:10:49 +0000 (00:10 +0000)
committerNick Clifton <nickc@redhat.com>
Sat, 8 Apr 2000 00:10:49 +0000 (00:10 +0000)
bfd/bfd-in2.h
bfd/elf32-arm.h
bfd/elfarm-nabi.c
bfd/elfarm-oabi.c
bfd/libbfd.h
bfd/reloc.c

index 06276d3ff2ae3c05c68216dd4196af37cfd90dbd..79080cbaad5a1b978285bd29a9a8710769981be4 100644 (file)
@@ -2049,6 +2049,16 @@ It generally does map to one of the other relocation types. */
 not stored in the instruction. */
   BFD_RELOC_ARM_PCREL_BRANCH,
 
+/* ARM 26 bit pc-relative branch.  The lowest bit must be zero and is
+not stored in the instruction.  The 2nd lowest bit comes from a 1 bit
+field in the instruction. */
+  BFD_RELOC_ARM_PCREL_BLX,
+
+/* Thumb 22 bit pc-relative branch.  The lowest bit must be zero and is
+not stored in the instruction.  The 2nd lowest bit comes from a 1 bit
+field in the instruction. */
+  BFD_RELOC_THUMB_PCREL_BLX,
+
 /* These relocs are only used within the ARM assembler.  They are not
 (at present) written to any object files. */
   BFD_RELOC_ARM_IMMEDIATE,
@@ -2305,7 +2315,6 @@ significant 7 bits of a 23-bit extended address are placed into
 the opcode. */
   BFD_RELOC_TIC54X_MS7_OF_23,
 
-
 /* This is a 48 bit reloc for the FR30 that stores 32 bits. */
   BFD_RELOC_FR30_48,
 
index 34371c9181d60de367aaf2ec564846fc043a0f3d..a66629348f12ca06f5d04883a0956e5bb8b4f531 100644 (file)
@@ -775,10 +775,10 @@ error_return:
    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)
@@ -791,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;
@@ -803,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;
 }
 
@@ -1062,6 +1062,9 @@ 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. */
 
@@ -1171,16 +1174,33 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
        }
       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,
-                                      signed_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
@@ -1321,8 +1341,11 @@ 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;
@@ -1344,18 +1367,33 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
          signed_addend = addend;
        }
 #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)
+#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, signed_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;
index 38778b73be3a4bfdd16df7bf76f95dbcbda0dbb9..460b59c947605652335e65b4d7b346883078cd1f 100644 (file)
 static reloc_howto_type * elf32_arm_reloc_type_lookup
   PARAMS ((bfd * abfd, bfd_reloc_code_real_type code));
 
+/* Note: code such as elf32_arm_reloc_type_lookup expect to use e.g.
+   R_ARM_PC24 as an index into this, and find the R_ARM_PC24 HOWTO 
+   in that slot. */
+
 static reloc_howto_type elf32_arm_howto_table[] =
 {
   /* No relocation */
@@ -262,35 +266,35 @@ static reloc_howto_type elf32_arm_howto_table[] =
         0x00000000,            /* dst_mask */
         false),                /* pcrel_offset */
 
-  /* These next two relocs are defined, but I do not know what they do.  */
-  
+  /* BLX instruction for the ARM.  */
   HOWTO (R_ARM_XPC25,          /* type */
-        0,                     /* rightshift */
-        0,                     /* size (0 = byte, 1 = short, 2 = long) */
-        0,                     /* bitsize */
-        false,                 /* pc_relative */
+        2,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        25,                    /* bitsize */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_XPC25",         /* name */
         false,                 /* partial_inplace */
-        0x00000000,            /* src_mask */
-        0x00000000,            /* dst_mask */
-        false),                /* pcrel_offset */
-
+        0x00ffffff,            /* src_mask */
+        0x00ffffff,            /* dst_mask */
+        true),                 /* pcrel_offset */
+  
+  /* BLX instruction for the Thumb.  */
   HOWTO (R_ARM_THM_XPC22,      /* type */
-        0,                     /* rightshift */
-        0,                     /* size (0 = byte, 1 = short, 2 = long) */
-        0,                     /* bitsize */
-        false,                 /* pc_relative */
+        2,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        22,                    /* bitsize */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_THM_XPC22",     /* name */
         false,                 /* partial_inplace */
-        0x00000000,            /* src_mask */
-        0x00000000,            /* dst_mask */
-        false),                /* pcrel_offset */
+        0x07ff07ff,            /* src_mask */
+        0x07ff07ff,            /* dst_mask */
+        true),                 /* pcrel_offset */
   
   /* These next three relocs are not defined, but we need to fill the space.  */
 
@@ -622,6 +626,8 @@ static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] =
 {
   {BFD_RELOC_NONE,                 R_ARM_NONE},
   {BFD_RELOC_ARM_PCREL_BRANCH,     R_ARM_PC24},
+  {BFD_RELOC_ARM_PCREL_BLX,        R_ARM_XPC25},
+  {BFD_RELOC_THUMB_PCREL_BLX,      R_ARM_THM_XPC22},
   {BFD_RELOC_32,                   R_ARM_ABS32},
   {BFD_RELOC_32_PCREL,             R_ARM_REL32},
   {BFD_RELOC_8,                    R_ARM_ABS8},
index 72f62f238095d9808e14dfa2ba49afce332b8701..833f509cb79b19fc7e71c8701dc00236203fd593 100644 (file)
@@ -1,5 +1,5 @@
 /* 32-bit ELF support for ARM old abi option.
-   Copyright 1999 Free Software Foundation, Inc.
+   Copyright 1999, 2000 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -17,7 +17,9 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
-#include "elf/arm-oabi.h"
+#define OLD_ARM_ABI
+
+#include "elf/arm.h"
 #include "bfd.h"
 #include "sysdep.h"
 #include "libbfd.h"
index 44d6205fa109b038da06a83595456a7d215f5184..20ffcdc73b4e2d9a3fdacb889162ffafdd02d5a7 100644 (file)
@@ -765,6 +765,8 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_I370_D12",
   "BFD_RELOC_CTOR",
   "BFD_RELOC_ARM_PCREL_BRANCH",
+  "BFD_RELOC_ARM_PCREL_BLX",
+  "BFD_RELOC_THUMB_PCREL_BLX",
   "BFD_RELOC_ARM_IMMEDIATE",
   "BFD_RELOC_ARM_ADRL_IMMEDIATE",
   "BFD_RELOC_ARM_OFFSET_IMM",
index aafa71a877a59290c2027ea2335285c43389d34a..8823c6ce53e6b4e5271972dc450b7f9f60cfedd2 100644 (file)
@@ -25,7 +25,7 @@ SECTION
 
        BFD maintains relocations in much the same way it maintains
        symbols: they are left alone until required, then read in
-       en-masse and translated into an internal form.  A common
+       en-mass and translated into an internal form.  A common
        routine <<bfd_perform_relocation>> acts upon the
        canonical form to do the fixup.
 
@@ -2201,6 +2201,18 @@ ENUM
 ENUMDOC
   ARM 26 bit pc-relative branch.  The lowest two bits must be zero and are
   not stored in the instruction.
+ENUM
+  BFD_RELOC_ARM_PCREL_BLX
+ENUMDOC
+  ARM 26 bit pc-relative branch.  The lowest bit must be zero and is
+  not stored in the instruction.  The 2nd lowest bit comes from a 1 bit
+  field in the instruction.
+ENUM
+  BFD_RELOC_THUMB_PCREL_BLX
+ENUMDOC
+  Thumb 22 bit pc-relative branch.  The lowest bit must be zero and is
+  not stored in the instruction.  The 2nd lowest bit comes from a 1 bit
+  field in the instruction.
 ENUM
   BFD_RELOC_ARM_IMMEDIATE
 ENUMX
@@ -2539,7 +2551,6 @@ ENUMDOC
   significant 8 bits of a 24 bit word are placed into the least
   significant 8 bits of the opcode.
 
-COMMENT
 ENUM
   BFD_RELOC_TIC54X_PARTLS7
 ENUMDOC
@@ -2572,7 +2583,6 @@ ENUMDOC
   This is a reloc for the tms320c54x, where the most
   significant 7 bits of a 23-bit extended address are placed into 
   the opcode.
-COMMENT
 
 ENUM
   BFD_RELOC_FR30_48