* bfd/bin-in.h (bfd_elf32_arm_set_target_relocs): Update prototype.
authorJulian Brown <julian@codesourcery.com>
Fri, 28 Jan 2005 17:24:41 +0000 (17:24 +0000)
committerJulian Brown <julian@codesourcery.com>
Fri, 28 Jan 2005 17:24:41 +0000 (17:24 +0000)
* bfd/bin-in2.h (bfd_elf32_arm_set_target_relocs): Update prototype.
* bfd/elf32-arm.c (elf32_arm_link_hash_table): Add fix_v4bx flag.
(bfd_elf32_arm_set_target_relocs): Add formal parameter fix_v4bx for
passing flag value from ld. Set flag value in global hash table entry.
(elf32_arm_final_link_relocate): Add code to implement R_ARM_V4BX
relocation.
* ld/emultempl/armelf.em (fix_v4bx): New variable.
(arm_elf_create_output_section_statements): Communicate fix_v4bx flag
value to bfd.
(PARSE_AND_LIST_PROLOGUE): Add option token OPTION_FIX_V4BX.
(PARSE_AND_LIST_LONGOPTS): Add option --fix-v4bx.
(PARSE_AND_LIST_OPTIONS): Add option --fix-v4bx.
(PARSE_AND_LIST_ARGS_CASES): Add option OPTION_FIX_V4BX.
* ld/NEWS: Mention --fix-v4bx.
* ld/ld.texinfo: Document --fix-v4bx.

bfd/ChangeLog
bfd/bfd-in.h
bfd/bfd-in2.h
bfd/elf32-arm.c
ld/ChangeLog
ld/NEWS
ld/emultempl/armelf.em
ld/ld.texinfo

index a8f8a335eed087cae8d6bc34a0be21fb29f83677..3b9a9b6bf99a2920f747aadff8953b5a541ddace 100644 (file)
@@ -1,3 +1,13 @@
+2005-01-28  Julian Brown  <julian@codesourcery.com>
+
+       * bin-in.h (bfd_elf32_arm_set_target_relocs): Update prototype.
+       * bin-in2.h (bfd_elf32_arm_set_target_relocs): Update prototype.
+       * elf32-arm.c (elf32_arm_link_hash_table): Add fix_v4bx flag.
+       (bfd_elf32_arm_set_target_relocs): Add formal parameter fix_v4bx for
+       passing flag value from ld. Set flag value in global hash table entry. 
+       (elf32_arm_final_link_relocate): Add code to implement R_ARM_V4BX
+       relocation. 
+
 2005-01-27  Andrew Cagney  <cagney@gnu.org>
 
        * configure: Regenerate to track ../gettext.m4 change.
index ff84516eebc3d5e2cd4014830d991f3a8e71e25d..1ca145008260683cd74dfdaddaf43580c6d5a9d3 100644 (file)
@@ -817,7 +817,7 @@ extern bfd_boolean bfd_elf32_arm_process_before_allocation
   (bfd *, struct bfd_link_info *, int);
 
 void bfd_elf32_arm_set_target_relocs
-  (struct bfd_link_info *, int, char *);
+  (struct bfd_link_info *, int, char *, int);
 
 extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking
   (bfd *, struct bfd_link_info *);
index 6c783a0893c5a4798e62fa3c092f53a76d655ef7..da2d8cc2c10a6dabf881d49c105a0897b808938f 100644 (file)
@@ -824,7 +824,7 @@ extern bfd_boolean bfd_elf32_arm_process_before_allocation
   (bfd *, struct bfd_link_info *, int);
 
 void bfd_elf32_arm_set_target_relocs
-  (struct bfd_link_info *, int, char *);
+  (struct bfd_link_info *, int, char *, int);
 
 extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking
   (bfd *, struct bfd_link_info *);
index 09b47d3cdc85046668cd445ae48112ec4bc5048b..14f46f4342db0b8bd972efd6bd9056521cfcb838 100644 (file)
@@ -1165,6 +1165,9 @@ struct elf32_arm_link_hash_table
     /* The relocation to use for R_ARM_TARGET2 relocations.  */
     int target2_reloc;
 
+    /* Nonzero to fix BX instructions for ARMv4 targets.  */
+    int fix_v4bx;
+
     /* The number of bytes in the initial entry in the PLT.  */
     bfd_size_type plt_header_size;
 
@@ -1931,7 +1934,8 @@ error_return:
 void
 bfd_elf32_arm_set_target_relocs (struct bfd_link_info *link_info,
                                 int target1_is_rel,
-                                char * target2_type)
+                                char * target2_type,
+                                 int fix_v4bx)
 {
   struct elf32_arm_link_hash_table *globals;
 
@@ -1949,6 +1953,7 @@ bfd_elf32_arm_set_target_relocs (struct bfd_link_info *link_info,
       _bfd_error_handler (_("Invalid TARGET2 relocation type '%s'."),
                          target2_type);
     }
+  globals->fix_v4bx = fix_v4bx;
 }
 #endif
 
@@ -2985,6 +2990,22 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
     case R_ARM_RBASE:
       return bfd_reloc_notsupported;
 
+    case R_ARM_V4BX:
+      if (globals->fix_v4bx)
+        {
+          bfd_vma insn = bfd_get_32 (input_bfd, hit_data);
+
+          /* Ensure that we have a BX instruction.  */
+          BFD_ASSERT ((insn & 0x0ffffff0) == 0x012fff10);
+
+          /* Preserve Rm (lowest four bits) and the condition code
+             (highest four bits). Other bits encode MOV PC,Rm.  */
+          insn = (insn & 0xf000000f) | 0x01a0f000;
+
+          bfd_put_32 (input_bfd, insn, hit_data);
+        }
+      return bfd_reloc_ok;
+
     default:
       return bfd_reloc_notsupported;
     }
index 2180c9dfcd5fd2ac7f563549268457c6094ce15b..0972c51259afdd634798264897336e0d9737a48a 100644 (file)
@@ -1,3 +1,15 @@
+2005-01-28  Julian Brown  <julian@codesourcery.com>
+
+       * emultempl/armelf.em (fix_v4bx): New variable.
+       (arm_elf_create_output_section_statements): Communicate fix_v4bx flag
+       value to bfd.
+       (PARSE_AND_LIST_PROLOGUE): Add option token OPTION_FIX_V4BX.
+       (PARSE_AND_LIST_LONGOPTS): Add option --fix-v4bx.
+       (PARSE_AND_LIST_OPTIONS): Add option --fix-v4bx.
+       (PARSE_AND_LIST_ARGS_CASES): Add option OPTION_FIX_V4BX. 
+       * NEWS: Mention --fix-v4bx.
+       * ld.texinfo: Document --fix-v4bx.
+
 2005-01-25  Mark Mitchell  <mark@codesourcery.com>
 
        * emulparams/armsymbian.sh (OTHER_READONLY_SECTIONS): Define, so
diff --git a/ld/NEWS b/ld/NEWS
index e157fbf0ff0ca7f3ada835435dc5feaa49913f85..c30b62c1b1accf7bc305fe2bcd1289959aa93808 100644 (file)
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -1,5 +1,8 @@
 -*- text -*-
 
+* Support for the R_ARM_V4BX relocation as defined in the ARM AAELF
+  specification has been added via the --fix-v4bx command-line option.
+
 * New linker script construct AS_NEEDED(), which sets the --as-needed flag
   for input files listed inside of it.
 
index b292cd13fb5ad230801b5ae684469c283c6470fc..01955f41123276415980467ab2a13d313872da50 100644 (file)
@@ -30,6 +30,7 @@ static bfd *bfd_for_interwork;
 static int byteswap_code = 0;
 static int target1_is_rel = 0${TARGET1_IS_REL};
 static char *target2_type = "${TARGET2_TYPE}";
+static int fix_v4bx = 0;
 
 static void
 gld${EMULATION_NAME}_before_parse (void)
@@ -189,7 +190,8 @@ arm_elf_finish (void)
 static void
 arm_elf_create_output_section_statements (void)
 {
-  bfd_elf32_arm_set_target_relocs (&link_info, target1_is_rel, target2_type);
+  bfd_elf32_arm_set_target_relocs (&link_info, target1_is_rel, target2_type,
+                                   fix_v4bx);
 }
 
 EOF
@@ -203,6 +205,7 @@ PARSE_AND_LIST_PROLOGUE='
 #define OPTION_TARGET1_REL             303
 #define OPTION_TARGET1_ABS             304
 #define OPTION_TARGET2                 305
+#define OPTION_FIX_V4BX                 306
 '
 
 PARSE_AND_LIST_SHORTOPTS=p
@@ -214,6 +217,7 @@ PARSE_AND_LIST_LONGOPTS='
   { "target1-rel", no_argument, NULL, OPTION_TARGET1_REL},
   { "target1-abs", no_argument, NULL, OPTION_TARGET1_ABS},
   { "target2", required_argument, NULL, OPTION_TARGET2},
+  { "fix-v4bx", no_argument, NULL, OPTION_FIX_V4BX},
 '
 
 PARSE_AND_LIST_OPTIONS='
@@ -222,6 +226,7 @@ PARSE_AND_LIST_OPTIONS='
   fprintf (file, _("     --target1=rel            Interpret R_ARM_TARGET1 as R_ARM_REL32\n"));
   fprintf (file, _("     --target1=abs            Interpret R_ARM_TARGET1 as R_ARM_ABS32\n"));
   fprintf (file, _("     --target2=<type>         Specify definition of R_ARM_TARGET2\n"));
+  fprintf (file, _("     --fix-v4bx               Rewrite BX rn as MOV pc, rn for ARMv4\n"));
 '
 
 PARSE_AND_LIST_ARGS_CASES='
@@ -248,6 +253,10 @@ PARSE_AND_LIST_ARGS_CASES='
     case OPTION_TARGET2:
       target2_type = optarg;
       break;
+
+    case OPTION_FIX_V4BX:
+      fix_v4bx = 1;
+      break;
 '
 
 # We have our own after_open and before_allocation functions, but they call
index 5452fe9193bc5a70328bab9118956b69ddbfb502..4511868081ce4e66ff63d6a21810bae452c8746a 100644 (file)
@@ -5139,6 +5139,20 @@ meanings, and target defaults are as follows:
 @samp{R_ARM_GOT_PREL} (arm*-*-linux, arm*-*-*bsd)
 @end table
 
+@cindex FIX_V4BX
+@kindex --fix-v4bx
+The @samp{R_ARM_V4BX} relocation (defined by the ARM AAELF
+specification) enables objects compiled for the ARMv4 architecture to be
+interworking-safe when linked with other objects compiled for ARMv4t, but
+also allows pure ARMv4 binaries to be built from the same ARMv4 objects.
+
+In the latter case, the switch @option{--fix-v4bx} must be passed to the
+linker, which causes v4t @code{BX rM} instructions to be rewritten as
+@code{MOV PC,rM}, since v4 processors do not have a @code{BX} instruction.
+
+In the former case, the switch should not be used, and @samp{R_ARM_V4BX}
+relocations are ignored.
+
 @ifclear GENERIC
 @lowersections
 @end ifclear