This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] Support for R_ARM_CALL and R_ARM_JUMP24


The EABI deprecates the R_ARM_PC24 relocation and introduces two new
ones to replace it (these avoid the need to decode the instruction to
know how to process it correctly for interworking).

This code is a preliminary patch that allows gnu LD to link in objects
that are built the new way; it doesn't change the tools to use the new
reloc codes.  It works by processing both codes exactly as it would if
they were the old relocation (ie, it takes no advantage of the extra
information provided).

The patch was written by Richard Earnshaw, I just did testing and a few minor 
changes.

Tested with cross to arm-none-eabi, built --enable-targets=all and applied.
Paul

2004-10-27  Richard Earnshaw  <rearnsha@arm.com>

bfd/
 * elf32-arm.h (bfd_elf32_arm_process_before_allocation): Handle
 R_ARM_CALL and R_ARM_JUMP24 as aliases of R_ARM_PC24.
 (elf32_arm_final_link_relocate): Ditto.
 (arm_add_to_rel, elf32_arm_relocate_section): Ditto.
 (elf32_arm_gc_sweep_hook, elf32_arm_check_relocs): Ditto
 (elf32_arm_adjust_dynamic_symbol): Ditto.
 * elfarm-nabi.c (elf32_arm_howto_table): Add R_ARM_CALL and
 R_ARM_JUMP32.  Move R_ARM_R{REL32,ABS32,PC24,BASE}...
 (elf32_arm_r_howto): ... To here.
 (elf32_arm_howto_from_type): Use elf32_arm_r_howto.
include/
 * elf/arm.h: Add R_ARM_CALL and R_ARM_JUMP32.

Index: bfd/elf32-arm.h
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arm.h,v
retrieving revision 1.154
diff -u -p -r1.154 elf32-arm.h
--- bfd/elf32-arm.h 21 Oct 2004 15:28:20 -0000 1.154
+++ bfd/elf32-arm.h 27 Oct 2004 19:02:39 -0000
@@ -827,6 +827,10 @@ bfd_elf32_arm_process_before_allocation 
 
    /* These are the only relocation types we care about.  */
    if (   r_type != R_ARM_PC24
+#ifndef OLD_ARM_ABI
+       && r_type != R_ARM_CALL
+       && r_type != R_ARM_JUMP24
+#endif
        && r_type != R_ARM_THM_PC22)
      continue;
 
@@ -864,6 +868,10 @@ bfd_elf32_arm_process_before_allocation 
    switch (r_type)
      {
      case R_ARM_PC24:
+#ifndef OLD_ARM_ABI
+     case R_ARM_CALL:
+     case R_ARM_JUMP24:
+#endif
        /* 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
           insert glue.  */
@@ -1295,6 +1303,8 @@ elf32_arm_final_link_relocate (reloc_how
     case R_ARM_ABS32:
     case R_ARM_REL32:
 #ifndef OLD_ARM_ABI
+    case R_ARM_CALL:
+    case R_ARM_JUMP24:
     case R_ARM_XPC25:
     case R_ARM_PREL31:
 #endif
@@ -1344,6 +1354,10 @@ elf32_arm_final_link_relocate (reloc_how
        || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
        || h->root.type != bfd_link_hash_undefweak)
    && r_type != R_ARM_PC24
+#ifndef OLD_ARM_ABI
+   && r_type != R_ARM_CALL
+   && r_type != R_ARM_JUMP24
+#endif
    && r_type != R_ARM_PLT32)
  {
    Elf_Internal_Rela outrel;
@@ -1416,6 +1430,8 @@ elf32_arm_final_link_relocate (reloc_how
  {
 #ifndef OLD_ARM_ABI
  case R_ARM_XPC25:   /* Arm BLX instruction.  */
+ case R_ARM_CALL:
+ case R_ARM_JUMP24:
 #endif
  case R_ARM_PC24:   /* Arm B/BL instruction */
  case R_ARM_PLT32:
@@ -2028,6 +2044,10 @@ arm_add_to_rel (bfd *              abfd,
    break;
 
  case R_ARM_PC24:
+#ifndef OLD_ARM_ABI
+ case R_ARM_CALL:
+ case R_ARM_JUMP24:
+#endif
    addend <<= howto->size;
    addend += increment;
 
@@ -2188,6 +2208,10 @@ elf32_arm_relocate_section (bfd *       
        switch (r_type)
   {
          case R_ARM_PC24:
+#ifndef OLD_ARM_ABI
+  case R_ARM_CALL:
+  case R_ARM_JUMP24:
+#endif
          case R_ARM_ABS32:
   case R_ARM_THM_PC22:
          case R_ARM_PLT32:
@@ -2861,6 +2885,8 @@ elf32_arm_gc_sweep_hook (bfd *          
  case R_ARM_PC24:
  case R_ARM_PLT32:
 #ifndef OLD_ARM_ABI
+ case R_ARM_CALL:
+ case R_ARM_JUMP24:
  case R_ARM_PREL31:
 #endif
    r_symndx = ELF32_R_SYM (rel->r_info);
@@ -3004,6 +3030,8 @@ elf32_arm_check_relocs (bfd *abfd, struc
    case R_ARM_PC24:
    case R_ARM_PLT32:
 #ifndef OLD_ARM_ABI
+   case R_ARM_CALL:
+   case R_ARM_JUMP24:
    case R_ARM_PREL31:
 #endif
      if (h != NULL)
@@ -3022,6 +3050,10 @@ elf32_arm_check_relocs (bfd *abfd, struc
      sure yet, because something later might force the
      symbol local.  */
   if (r_type == R_ARM_PC24
+#ifndef OLD_ARM_ABI
+      || r_type == R_ARM_CALL
+      || r_type == R_ARM_JUMP24
+#endif
       || r_type == R_ARM_PLT32)
     h->needs_plt = 1;
 
@@ -3047,6 +3079,8 @@ elf32_arm_check_relocs (bfd *abfd, struc
   && ((r_type != R_ARM_PC24
        && r_type != R_ARM_PLT32
 #ifndef OLD_ARM_ABI
+       && r_type != R_ARM_CALL
+       && r_type != R_ARM_JUMP24
        && r_type != R_ARM_PREL31
 #endif
        && r_type != R_ARM_REL32)
@@ -3336,9 +3370,9 @@ elf32_arm_adjust_dynamic_symbol (struct 
     }
   else
     /* It's possible that we incorrectly decided a .plt reloc was
-       needed for an R_ARM_PC24 reloc to a non-function sym in
-       check_relocs.  We can't decide accurately between function and
-       non-function syms in check-relocs;  Objects loaded later in
+       needed for an R_ARM_PC24 or similar reloc to a non-function sym
+       in check_relocs.  We can't decide accurately between function
+       and non-function syms in check-relocs; Objects loaded later in
        the link may change h->type.  So fix it now.  */
     h->plt.offset = (bfd_vma) -1;
 
Index: bfd/elfarm-nabi.c
===================================================================
RCS file: /cvs/src/src/bfd/elfarm-nabi.c,v
retrieving revision 1.25
diff -u -p -r1.25 elfarm-nabi.c
--- bfd/elfarm-nabi.c 19 Oct 2004 06:02:46 -0000 1.25
+++ bfd/elfarm-nabi.c 27 Oct 2004 19:02:40 -0000
@@ -453,37 +453,35 @@ static reloc_howto_type elf32_arm_howto_
          0x00ffffff,  /* dst_mask */
          TRUE),   /* pcrel_offset */
 
-  /* End of relocs used in ARM Linux */
-
-  HOWTO (R_ARM_RREL32,  /* type */
-  0,   /* rightshift */
-  0,   /* size (0 = byte, 1 = short, 2 = long) */
-  0,   /* bitsize */
-  FALSE,   /* pc_relative */
+  HOWTO (R_ARM_CALL,  /* type */
+  2,   /* rightshift */
+  2,   /* size (0 = byte, 1 = short, 2 = long) */
+  24,   /* bitsize */
+  TRUE,   /* pc_relative */
   0,   /* bitpos */
-  complain_overflow_dont,/* complain_on_overflow */
+  complain_overflow_signed,/* complain_on_overflow */
   bfd_elf_generic_reloc, /* special_function */
-  "R_ARM_RREL32", /* name */
+  "R_ARM_CALL",  /* name */
   FALSE,   /* partial_inplace */
-  0,   /* src_mask */
-  0,   /* dst_mask */
-  FALSE),  /* pcrel_offset */
+  0x00ffffff,  /* src_mask */
+  0x00ffffff,  /* dst_mask */
+  TRUE),   /* pcrel_offset */
 
-  HOWTO (R_ARM_RABS32,  /* type */
-  0,   /* rightshift */
-  0,   /* size (0 = byte, 1 = short, 2 = long) */
-  0,   /* bitsize */
-  FALSE,   /* pc_relative */
+  HOWTO (R_ARM_JUMP24,  /* type */
+  2,   /* rightshift */
+  2,   /* size (0 = byte, 1 = short, 2 = long) */
+  24,   /* bitsize */
+  TRUE,   /* pc_relative */
   0,   /* bitpos */
-  complain_overflow_dont,/* complain_on_overflow */
+  complain_overflow_signed,/* complain_on_overflow */
   bfd_elf_generic_reloc, /* special_function */
-  "R_ARM_RABS32", /* name */
+  "R_ARM_JUMP24", /* name */
   FALSE,   /* partial_inplace */
-  0,   /* src_mask */
-  0,   /* dst_mask */
-  FALSE),  /* pcrel_offset */
+  0x00ffffff,  /* src_mask */
+  0x00ffffff,  /* dst_mask */
+  TRUE),   /* pcrel_offset */
 
-  HOWTO (R_ARM_RPC24,  /* type */
+  HOWTO (R_ARM_NONE,  /* type */
   0,   /* rightshift */
   0,   /* size (0 = byte, 1 = short, 2 = long) */
   0,   /* bitsize */
@@ -491,13 +489,13 @@ static reloc_howto_type elf32_arm_howto_
   0,   /* bitpos */
   complain_overflow_dont,/* complain_on_overflow */
   bfd_elf_generic_reloc, /* special_function */
-  "R_ARM_RPC24",  /* name */
+  "R_ARM_unknown_30", /* name */
   FALSE,   /* partial_inplace */
   0,   /* src_mask */
   0,   /* dst_mask */
   FALSE),  /* pcrel_offset */
 
-  HOWTO (R_ARM_RBASE,  /* type */
+  HOWTO (R_ARM_NONE,  /* type */
   0,   /* rightshift */
   0,   /* size (0 = byte, 1 = short, 2 = long) */
   0,   /* bitsize */
@@ -505,7 +503,7 @@ static reloc_howto_type elf32_arm_howto_
   0,   /* bitpos */
   complain_overflow_dont,/* complain_on_overflow */
   bfd_elf_generic_reloc, /* special_function */
-  "R_ARM_RBASE",  /* name */
+  "R_ARM_unknown_31", /* name */
   FALSE,   /* partial_inplace */
   0,   /* src_mask */
   0,   /* dst_mask */
@@ -746,6 +744,66 @@ static reloc_howto_type elf32_arm_got_pr
   0xffffffff,  /* dst_mask */
   TRUE);   /* pcrel_offset */
 
+/* Currently unused relocations.  */
+static reloc_howto_type elf32_arm_r_howto[4] =
+{
+  HOWTO (R_ARM_RREL32,  /* type */
+  0,   /* rightshift */
+  0,   /* size (0 = byte, 1 = short, 2 = long) */
+  0,   /* bitsize */
+  FALSE,   /* pc_relative */
+  0,   /* bitpos */
+  complain_overflow_dont,/* complain_on_overflow */
+  bfd_elf_generic_reloc, /* special_function */
+  "R_ARM_RREL32", /* name */
+  FALSE,   /* partial_inplace */
+  0,   /* src_mask */
+  0,   /* dst_mask */
+  FALSE),  /* pcrel_offset */
+
+  HOWTO (R_ARM_RABS32,  /* type */
+  0,   /* rightshift */
+  0,   /* size (0 = byte, 1 = short, 2 = long) */
+  0,   /* bitsize */
+  FALSE,   /* pc_relative */
+  0,   /* bitpos */
+  complain_overflow_dont,/* complain_on_overflow */
+  bfd_elf_generic_reloc, /* special_function */
+  "R_ARM_RABS32", /* name */
+  FALSE,   /* partial_inplace */
+  0,   /* src_mask */
+  0,   /* dst_mask */
+  FALSE),  /* pcrel_offset */
+
+  HOWTO (R_ARM_RPC24,  /* type */
+  0,   /* rightshift */
+  0,   /* size (0 = byte, 1 = short, 2 = long) */
+  0,   /* bitsize */
+  FALSE,   /* pc_relative */
+  0,   /* bitpos */
+  complain_overflow_dont,/* complain_on_overflow */
+  bfd_elf_generic_reloc, /* special_function */
+  "R_ARM_RPC24",  /* name */
+  FALSE,   /* partial_inplace */
+  0,   /* src_mask */
+  0,   /* dst_mask */
+  FALSE),  /* pcrel_offset */
+
+  HOWTO (R_ARM_RBASE,  /* type */
+  0,   /* rightshift */
+  0,   /* size (0 = byte, 1 = short, 2 = long) */
+  0,   /* bitsize */
+  FALSE,   /* pc_relative */
+  0,   /* bitpos */
+  complain_overflow_dont,/* complain_on_overflow */
+  bfd_elf_generic_reloc, /* special_function */
+  "R_ARM_RBASE",  /* name */
+  FALSE,   /* partial_inplace */
+  0,   /* src_mask */
+  0,   /* dst_mask */
+  FALSE)   /* pcrel_offset */
+};
+
 static reloc_howto_type *
 elf32_arm_howto_from_type (unsigned int r_type)
 {
@@ -769,6 +827,12 @@ elf32_arm_howto_from_type (unsigned int 
     case R_ARM_THM_PC9:
       return &elf32_arm_thm_pc9_howto;
 
+    case R_ARM_RREL32:
+    case R_ARM_RABS32:
+    case R_ARM_RPC24:
+    case R_ARM_RBASE:
+      return &elf32_arm_r_howto[r_type - R_ARM_RREL32];
+
     default:
       return NULL;
     }
Index: include/elf/arm.h
===================================================================
RCS file: /cvs/src/src/include/elf/arm.h,v
retrieving revision 1.18
diff -u -p -r1.18 arm.h
--- include/elf/arm.h 12 Oct 2004 14:17:08 -0000 1.18
+++ include/elf/arm.h 27 Oct 2004 19:02:42 -0000
@@ -123,7 +123,9 @@ START_RELOC_NUMBERS (elf_arm_reloc_type)
   FAKE_RELOC   (FIRST_INVALID_RELOC,   28)
   FAKE_RELOC   (LAST_INVALID_RELOC,   249)
 #else /* not OLD_ARM_ABI */
-  FAKE_RELOC   (FIRST_INVALID_RELOC1,  28)
+  RELOC_NUMBER (R_ARM_CALL,            28)
+  RELOC_NUMBER (R_ARM_JUMP24,          29)
+  FAKE_RELOC   (FIRST_INVALID_RELOC1,  30)
   FAKE_RELOC   (LAST_INVALID_RELOC1,   31)
   RELOC_NUMBER (R_ARM_ALU_PCREL7_0,    32)
   RELOC_NUMBER (R_ARM_ALU_PCREL15_8,   33)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]