public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [RFA/ARM]: Patch to workaround ARM1176 BLX (immediate) Thumb to ARM issue
@ 2011-07-27 16:29 Matthew Gretton-Dann
  2011-07-27 16:44 ` Joseph S. Myers
  2011-07-28 16:41 ` Nick Clifton
  0 siblings, 2 replies; 8+ messages in thread
From: Matthew Gretton-Dann @ 2011-07-27 16:29 UTC (permalink / raw)
  To: binutils; +Cc: Richard Earnshaw

[-- Attachment #1: Type: text/plain, Size: 2397 bytes --]

Hi,

Please can someone review and approve the attached patch?

The patch does the following:

      * Adds a command line option to ld --[no-]fix-erratum-760522, which
        is enabled by default.
      * When the option is on the linker will only use BLX if the target
        architecture (derived from the object files) is v6T2, v7, or
        greater.
      * --use-blx keeps its current meaning and will override this
        option.

A description of the issue can be found on the ARM website at:

http://infocenter.arm.com/help/topic/com.arm.doc.uan0002a/UAN002A_1176-pan_use_of_blx.pdf

Alternatively by following:
    http://infocenter.arm.com/
      User Assistance Notes
        ARM11 Processors
          ARM1176JZ-S and ARM1176JFZ-S Programmer Advice Note

The workaround has been applied to more cores than just ARM1176 to 
ensure appropriate forwards compatibility from earlier CPUs.

Thanks,

Matt

bfd/ChangeLog:
2011-07-27  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>

	* bfd-in.h (bfd_elf32_arm_set_target_relocs): Update prototype.
	* bfd-in2.h (bfd_elf32_arm_set_target_relocs): Likewise.
	* elf32-arm.c (elf32_arm_link_hash_table): New field.
	(elf232_arm_link_hash_table_create): Initialise new field.
	(check_use_blx): Change test depending on fix_erratum_760522.
	(bfd_elf32_arm_set_target_relocs): Set fix_erratum_760522 from
	command line options.

ld/ChangeLog:
2011-07-27  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>

	* emultempl/armelf.em (fix_erratum_760522): New variable.
	(arm_elf_create_output_section_statements): Pass
	fix_erratum_760522 option to bfd backend.
	(OPTION_FIX_ERRATUM_760522): New define.
	(OPTION_NO_FIX_ERRATUM_760522): Likewise.
	(PARSE_AND_LIST_LONGOPTS): Add --[no-]fix-erratum-760522
	command line options.
	(PARSE_AND_LIST_OPTIONS): Likewise.
	(PARSE_AND_LIST_ARGS_CASES): Likewise.

ld/testsuite/ChangeLog:
2011-07-27  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>

	* ld-arm/arm-elf.exp (armelftests): Update for new command-line
	options.
	(armeabitests): Update for new command-line options, and add
	new test cases.
	* ld-arm/erratum-760522-off.d: New test case.
	* ld-arm/erratum-760522-on.d: Likewise.
	* ld-arm/erratum-760522.s: Likewise.


Thanks,

Matt

-- 
Matthew Gretton-Dann
Principal Engineer, PD Software - Tools, ARM Ltd

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 1107-fix-erratum-760522.patch --]
[-- Type: text/x-patch; name=1107-fix-erratum-760522.patch, Size: 16539 bytes --]

diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h
index 21b7cc2..f375d2f 100644
--- a/bfd/bfd-in.h
+++ b/bfd/bfd-in.h
@@ -869,7 +869,7 @@ extern bfd_boolean bfd_elf32_arm_process_before_allocation
 
 void bfd_elf32_arm_set_target_relocs
   (bfd *, struct bfd_link_info *, int, char *, int, int, bfd_arm_vfp11_fix,
-   int, int, int, int);
+   int, int, int, int, int);
 
 extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking
   (bfd *, struct bfd_link_info *);
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 6b7be67..3d5759d 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -876,7 +876,7 @@ extern bfd_boolean bfd_elf32_arm_process_before_allocation
 
 void bfd_elf32_arm_set_target_relocs
   (bfd *, struct bfd_link_info *, int, char *, int, int, bfd_arm_vfp11_fix,
-   int, int, int, int);
+   int, int, int, int, int);
 
 extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking
   (bfd *, struct bfd_link_info *);
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index 0ddd0cf..c6370c2 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -2776,6 +2776,9 @@ struct elf32_arm_link_hash_table
   /* Whether we should fix the Cortex-A8 Thumb-2 branch/TLB erratum.  */
   int fix_cortex_a8;
 
+  /* Whether we should fix erratum 760522.  */
+  int fix_erratum_760522;
+
   /* Nonzero if the ARM/Thumb BLX instructions are available for use.  */
   int use_blx;
 
@@ -3315,6 +3318,7 @@ elf32_arm_link_hash_table_create (bfd *abfd)
   ret->vfp11_erratum_glue_size = 0;
   ret->num_vfp11_fixes = 0;
   ret->fix_cortex_a8 = 0;
+  ret->fix_erratum_760522 = 0;
   ret->bfd_of_glue_owner = NULL;
   ret->byteswap_code = 0;
   ret->target1_is_rel = 0;
@@ -5930,9 +5934,21 @@ bfd_elf32_arm_get_bfd_for_interworking (bfd *abfd, struct bfd_link_info *info)
 static void
 check_use_blx (struct elf32_arm_link_hash_table *globals)
 {
-  if (bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
-				Tag_CPU_arch) > 2)
-    globals->use_blx = 1;
+  int cpu_arch;
+
+  cpu_arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC, 
+				       Tag_CPU_arch);
+
+  if (globals->fix_erratum_760522)
+    {
+      if (cpu_arch == 8 || cpu_arch > 9)
+	globals->use_blx = 1;
+    }
+  else
+    {
+      if (cpu_arch > 2)
+	globals->use_blx = 1;
+    }
 }
 
 bfd_boolean
@@ -6786,7 +6802,8 @@ bfd_elf32_arm_set_target_relocs (struct bfd *output_bfd,
 				 int use_blx,
                                  bfd_arm_vfp11_fix vfp11_fix,
 				 int no_enum_warn, int no_wchar_warn,
-				 int pic_veneer, int fix_cortex_a8)
+				 int pic_veneer, int fix_cortex_a8,
+				 int fix_erratum_760522)
 {
   struct elf32_arm_link_hash_table *globals;
 
@@ -6811,6 +6828,7 @@ bfd_elf32_arm_set_target_relocs (struct bfd *output_bfd,
   globals->vfp11_fix = vfp11_fix;
   globals->pic_veneer = pic_veneer;
   globals->fix_cortex_a8 = fix_cortex_a8;
+  globals->fix_erratum_760522 = fix_erratum_760522;
 
   BFD_ASSERT (is_arm_elf (output_bfd));
   elf_arm_tdata (output_bfd)->no_enum_size_warning = no_enum_warn;
diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em
index 948bf8d..b2063d7 100644
--- a/ld/emultempl/armelf.em
+++ b/ld/emultempl/armelf.em
@@ -42,6 +42,7 @@ static int no_enum_size_warning = 0;
 static int no_wchar_size_warning = 0;
 static int pic_veneer = 0;
 static int merge_exidx_entries = -1;
+static int fix_erratum_760522 = 1;
 
 static void
 gld${EMULATION_NAME}_before_parse (void)
@@ -464,7 +465,8 @@ arm_elf_create_output_section_statements (void)
 				   target2_type, fix_v4bx, use_blx,
 				   vfp11_denorm_fix, no_enum_size_warning,
 				   no_wchar_size_warning,
-				   pic_veneer, fix_cortex_a8);
+				   pic_veneer, fix_cortex_a8, 
+				   fix_erratum_760522);
 
   stub_file = lang_add_input_file ("linker stubs",
  				   lang_input_file_is_fake_enum,
@@ -529,6 +531,8 @@ PARSE_AND_LIST_PROLOGUE='
 #define OPTION_FIX_CORTEX_A8		314
 #define OPTION_NO_FIX_CORTEX_A8		315
 #define OPTION_NO_MERGE_EXIDX_ENTRIES   316
+#define OPTION_FIX_ERRATUM_760522	317
+#define OPTION_NO_FIX_ERRATUM_760522	318
 '
 
 PARSE_AND_LIST_SHORTOPTS=p
@@ -551,6 +555,8 @@ PARSE_AND_LIST_LONGOPTS='
   { "fix-cortex-a8", no_argument, NULL, OPTION_FIX_CORTEX_A8 },
   { "no-fix-cortex-a8", no_argument, NULL, OPTION_NO_FIX_CORTEX_A8 },
   { "no-merge-exidx-entries", no_argument, NULL, OPTION_NO_MERGE_EXIDX_ENTRIES },
+  { "fix-erratum-760522", no_argument, NULL, OPTION_FIX_ERRATUM_760522 },
+  { "no-fix-erratum-760522", no_argument, NULL, OPTION_NO_FIX_ERRATUM_760522 },
 '
 
 PARSE_AND_LIST_OPTIONS='
@@ -579,7 +585,7 @@ PARSE_AND_LIST_OPTIONS='
  		   ));
   fprintf (file, _("  --[no-]fix-cortex-a8        Disable/enable Cortex-A8 Thumb-2 branch erratum fix\n"));
   fprintf (file, _("  --no-merge-exidx-entries    Disable merging exidx entries\n"));
- 
+  fprintf (file, _("  --[no-]fix-erratum-760522   Disable/enable Erratum 760522 fix\n"));
 '
 
 PARSE_AND_LIST_ARGS_CASES='
@@ -662,7 +668,15 @@ PARSE_AND_LIST_ARGS_CASES='
 
    case OPTION_NO_MERGE_EXIDX_ENTRIES:
       merge_exidx_entries = 0;
+      break;
 
+   case OPTION_FIX_ERRATUM_760522:
+      fix_erratum_760522 = 1;
+      break;
+
+   case OPTION_NO_FIX_ERRATUM_760522:
+      fix_erratum_760522 = 0;
+      break;
 '
 
 # We have our own before_allocation etc. functions, but they call
diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp
index 8b8495e..4d1002c 100644
--- a/ld/testsuite/ld-arm/arm-elf.exp
+++ b/ld/testsuite/ld-arm/arm-elf.exp
@@ -137,7 +137,7 @@ set armelftests {
     {"arm-rel32" "-shared -T arm-dyn.ld" "" {arm-rel32.s}
      {{objdump -Rsj.data arm-rel32.d}}
      "arm-rel32"}
-    {"arm-call" "-static -T arm.ld" "-meabi=4" {arm-call1.s arm-call2.s}
+    {"arm-call" "--no-fix-erratum-760522 -static -T arm.ld" "-meabi=4" {arm-call1.s arm-call2.s}
      {{objdump -d arm-call.d}}
      "arm-call"}
     {"TLS shared library" "-shared -T arm-lib.ld" "" {tls-lib.s}
@@ -149,16 +149,16 @@ set armelftests {
     {"TLS gnu shared library got" "-shared -T arm-dyn.ld" "" {tls-gdesc-got.s}
      {{objdump "-fDR -j .got" tls-gdesc-got.d}}
      "tls-lib2-got.so"}
-    {"TLS gnu shared library inlined trampoline" "-shared -T arm-dyn.ld" "" {tls-descseq.s}
+    {"TLS gnu shared library inlined trampoline" "--no-fix-erratum-760522 -shared -T arm-dyn.ld" "" {tls-descseq.s}
      {{objdump -fdw tls-descseq.d} {objdump -Rw tls-descseq.r}}
      "tls-lib2inline.so"}
-    {"TLS shared library gdesc local" "-shared -T arm-dyn.ld" "" {tls-lib-loc.s}
+    {"TLS shared library gdesc local" "--no-fix-erratum-760522 -shared -T arm-dyn.ld" "" {tls-lib-loc.s}
      {{objdump -fdw tls-lib-loc.d} {objdump -Rw tls-lib-loc.r}}
      "tls-lib-loc.so"}
     {"TLS gnu GD to IE relaxation" "-static -T arm-dyn.ld" "" {tls-gdierelax.s}
      {{objdump -fdw tls-gdierelax.d}}
      "tls-app-rel-ie"}
-    {"TLS gnu GD to IE shared relaxation" "-shared -T arm-dyn.ld" "" {tls-gdierelax2.s}
+    {"TLS gnu GD to IE shared relaxation" "--no-fix-erratum-760522 -shared -T arm-dyn.ld" "" {tls-gdierelax2.s}
      {{objdump -fdw tls-gdierelax2.d}}
      "tls-app-rel-ie2"}
     {"TLS gnu GD to LE relaxation" "-T arm-dyn.ld" "" {tls-gdlerelax.s}
@@ -507,7 +507,7 @@ set armeabitests {
     {"MOVW/MOVT against shared libraries" "tmpdir/arm-lib.so" "" {arm-app-movw.s}
      {{objdump -Rw arm-app.r}}
      "arm-app-movw"}
-    {"Thumb-2-as-Thumb-1 BL" "-Ttext 0x1000 --section-start .foo=0x100100c" "" {thumb2-bl-as-thumb1-bad.s}
+    {"Thumb-2-as-Thumb-1 BL" "--no-fix-erratum-760522 -Ttext 0x1000 --section-start .foo=0x100100c" "" {thumb2-bl-as-thumb1-bad.s}
      {{objdump -d thumb2-bl-as-thumb1-bad.d}}
      "thumb2-bl-as-thumb1-bad"}
     {"Thumb-2 BL" "-Ttext 0x1000 --section-start .foo=0x100100c" "" {thumb2-bl-bad.s}
@@ -530,7 +530,7 @@ set armeabitests {
     {"ARM-Thumb farcall" "-Ttext 0x1000 --section-start .foo=0x2001014" "" {farcall-arm-thumb.s}
      {{objdump -d farcall-arm-thumb.d}}
      "farcall-arm-thumb"}
-    {"ARM-Thumb farcall with BLX" "-Ttext 0x1000 --section-start .foo=0x2001014" "-march=armv5t" {farcall-arm-thumb.s}
+    {"ARM-Thumb farcall with BLX" "--no-fix-erratum-760522 -Ttext 0x1000 --section-start .foo=0x2001014" "-march=armv5t" {farcall-arm-thumb.s}
      {{objdump -d farcall-arm-thumb-blx.d}}
      "farcall-arm-thumb-blx"}
     {"ARM-Thumb farcall (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "" {farcall-arm-thumb.s}
@@ -540,7 +540,7 @@ set armeabitests {
      {{objdump -d farcall-arm-thumb-blx-pic-veneer.d}}
      "farcall-arm-thumb-blx-pic-veneer"}
 
-    {"Thumb-Thumb farcall with BLX" "-Ttext 0x1000 --section-start .foo=0x2001014" "-march=armv5t" {farcall-thumb-thumb.s}
+    {"Thumb-Thumb farcall with BLX" "--no-fix-erratum-760522 -Ttext 0x1000 --section-start .foo=0x2001014" "-march=armv5t" {farcall-thumb-thumb.s}
      {{objdump -d farcall-thumb-thumb-blx.d}}
      "farcall-thumb-thumb-blx"}
     {"Thumb-Thumb farcall M profile" "-Ttext 0x1000 --section-start .foo=0x2001014" "-march=armv7-m" {farcall-thumb-thumb.s}
@@ -552,7 +552,7 @@ set armeabitests {
     {"Thumb-Thumb farcall" "-Ttext 0x1000 --section-start .foo=0x2001014" "-march=armv4t" {farcall-thumb-thumb.s}
      {{objdump -d farcall-thumb-thumb.d}}
      "farcall-thumb-thumb"}
-    {"Thumb-Thumb farcall with BLX (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-march=armv5t" {farcall-thumb-thumb.s}
+    {"Thumb-Thumb farcall with BLX (PIC veneer)" "--no-fix-erratum-760522 -Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-march=armv5t" {farcall-thumb-thumb.s}
      {{objdump -d farcall-thumb-thumb-blx-pic-veneer.d}}
      "farcall-thumb-thumb-blx-pic-veneer"}
     {"Thumb-Thumb farcall M profile (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-march=armv7-m" {farcall-thumb-thumb.s}
@@ -574,10 +574,10 @@ set armeabitests {
     {"Thumb-ARM (short) call" "-Ttext 0x1000 --section-start .foo=0x0002014" "-W" {farcall-thumb-arm-short.s}
      {{objdump -d farcall-thumb-arm-short.d}}
      "farcall-thumb-arm-short"}
-    {"Thumb-ARM farcall with BLX" "-Ttext 0x1c01010 --section-start .foo=0x2001014" "-W -march=armv5t" {farcall-thumb-arm.s}
+    {"Thumb-ARM farcall with BLX" "--no-fix-erratum-760522 -Ttext 0x1c01010 --section-start .foo=0x2001014" "-W -march=armv5t" {farcall-thumb-arm.s}
      {{objdump -d farcall-thumb-arm-blx.d}}
      "farcall-thumb-arm-blx"}
-    {"Thumb-ARM farcall with BLX (PIC veneer)" "-Ttext 0x1c01010 --section-start .foo=0x2001014 --pic-veneer" "-W -march=armv5t" {farcall-thumb-arm.s}
+    {"Thumb-ARM farcall with BLX (PIC veneer)" "--no-fix-erratum-760522 -Ttext 0x1c01010 --section-start .foo=0x2001014 --pic-veneer" "-W -march=armv5t" {farcall-thumb-arm.s}
      {{objdump -d farcall-thumb-arm-blx-pic-veneer.d}}
      "farcall-thumb-arm-blx-pic-veneer"}
     {"Thumb-ARM farcall (PIC veneer)" "-Ttext 0x1c01010 --section-start .foo=0x2001014 --pic-veneer" "-W" {farcall-thumb-arm.s}
@@ -617,7 +617,7 @@ set armeabitests {
      {{objdump -fdw farcall-mixed-lib-v4t.d}}
      "farcall-mixed-lib.so"}
 
-    {"Mixed ARM/Thumb shared library with long branches (v5t)" "-shared -T arm-lib.ld" "-march=armv5t"
+    {"Mixed ARM/Thumb shared library with long branches (v5t)" "--no-fix-erratum-760522 -shared -T arm-lib.ld" "-march=armv5t"
      {farcall-mixed-lib1.s farcall-mixed-lib2.s}
      {{objdump -fdw farcall-mixed-lib.d}}
      "farcall-mixed-lib.so"}
@@ -627,24 +627,24 @@ set armeabitests {
      "farcall-data"}
 
     {"R_ARM_THM_JUMP24 Relocation veneers: Short 1" 
-     "--section-start destsect=0x00009000 --section-start .text=0x8000" 
+     "--no-fix-erratum-760522 --section-start destsect=0x00009000 --section-start .text=0x8000" 
      "-march=armv7-a -mthumb" 
      {jump-reloc-veneers.s}
      {{objdump -d jump-reloc-veneers-short1.d}}
      "jump-reloc-veneers-short1"}
     {"R_ARM_THM_JUMP24 Relocation veneers: Short 2" 
-     "--section-start destsect=0x00900000 --section-start .text=0x8000" 
+     "--no-fix-erratum-760522 --section-start destsect=0x00900000 --section-start .text=0x8000" 
      "-march=armv7-a -mthumb" 
      {jump-reloc-veneers.s}
      {{objdump -d jump-reloc-veneers-short2.d}}
      "jump-reloc-veneers-short2"}
     {"R_ARM_THM_JUMP24 Relocation veneers: Long" 
-     "--section-start destsect=0x09000000 --section-start .text=0x8000" 
+     "--no-fix-erratum-760522 --section-start destsect=0x09000000 --section-start .text=0x8000" 
      "-march=armv7-a -mthumb" 
      {jump-reloc-veneers.s}
      {{objdump -d jump-reloc-veneers-long.d}}
      "jump-reloc-veneers-long"}
-    {"TLS gnu shared library" "-shared -T arm-dyn.ld" "" {tls-gdesc.s}
+    {"TLS gnu shared library" "--no-fix-erratum-760522 -shared -T arm-dyn.ld" "" {tls-gdesc.s}
      {{objdump -fdw tls-gdesc.d} {objdump -Rw tls-gdesc.r}}
      "tls-lib2.so"}
     {"TLS gnu shared library non-lazy" "-z now -shared -T arm-dyn.ld" "" {tls-gdesc.s}
@@ -659,6 +659,31 @@ set armeabitests {
     {"TLS thumb1" "-shared -T arm-dyn.ld --section-start .foo=0x4001000" "" {tls-thumb1.s}
      {{objdump -fdw tls-thumb1.d}}
      "tls-thumb1"}
+
+    {"erratum 760522 fix (default for v6z)" "--section-start=.foo=0x2001014" 
+     "-march=armv6z" {erratum-760522.s}
+     {{objdump -d erratum-760522-on.d}}
+     "erratum-760522-1"}
+    {"erratum 760522 fix (explicitly on at v6z)" "--section-start=.foo=0x2001014 --fix-erratum-760522" 
+     "-march=armv6z" {erratum-760522.s}
+     {{objdump -d erratum-760522-on.d}}
+     "erratum-760522-2"}
+    {"erratum 760522 fix (explicitly off at v6z)" "--section-start=.foo=0x2001014 --no-fix-erratum-760522" 
+     "-march=armv6z" {erratum-760522.s}
+     {{objdump -d erratum-760522-off.d}}
+     "erratum-760522-3"}
+    {"erratum 760522 fix (default for v5)" "--section-start=.foo=0x2001014 " 
+     "-march=armv5te" {erratum-760522.s}
+     {{objdump -d erratum-760522-on.d}}
+     "erratum-760522-4"}
+    {"erratum 760522 fix (default for v7-a)" "--section-start=.foo=0x2001014 " 
+     "-march=armv7-a" {erratum-760522.s}
+     {{objdump -d erratum-760522-off.d}}
+     "erratum-760522-5"}
+    {"erratum 760522 fix (default for ARM1156)" "--section-start=.foo=0x2001014 " 
+     "-mcpu=arm1156t2f-s" {erratum-760522.s}
+     {{objdump -d erratum-760522-off.d}}
+     "erratum-760522-6"}
 }
 
 run_ld_link_tests $armeabitests
diff --git a/ld/testsuite/ld-arm/erratum-760522-off.d b/ld/testsuite/ld-arm/erratum-760522-off.d
new file mode 100644
index 0000000..3b45a3b
--- /dev/null
+++ b/ld/testsuite/ld-arm/erratum-760522-off.d
@@ -0,0 +1,17 @@
+
+.*:     file format elf32-littlearm
+
+
+Disassembly of section .foo:
+
+[0-9a-f]+ <_start>:
+ [0-9a-f]+:	f000 e800 	blx	2001018 <__func_to_branch_to_veneer>
+
+[0-9a-f]+ <__func_to_branch_to_veneer>:
+ [0-9a-f]+:	e51ff004 	ldr	pc, \[pc, #-4\]	; 200101c <__func_to_branch_to_veneer\+0x4>
+ [0-9a-f]+:	00008000 	.word	0x00008000
+
+Disassembly of section .text:
+
+[0-9a-f]+ <func_to_branch_to>:
+    [0-9a-f]+:	e12fff1e 	bx	lr
diff --git a/ld/testsuite/ld-arm/erratum-760522-on.d b/ld/testsuite/ld-arm/erratum-760522-on.d
new file mode 100644
index 0000000..c4e7870
--- /dev/null
+++ b/ld/testsuite/ld-arm/erratum-760522-on.d
@@ -0,0 +1,20 @@
+
+.+:     file format elf32-littlearm
+
+
+Disassembly of section .foo:
+
+[0-9a-f]+ <_start>:
+ [0-9a-f]+:	f000 f800 	bl	2001018 <__func_to_branch_to_veneer>
+
+[0-9a-f]+ <__func_to_branch_to_veneer>:
+ [0-9a-f]+:	4778      	bx	pc
+ [0-9a-f]+:	46c0      	nop			; \(mov r8, r8\)
+ [0-9a-f]+:	e51ff004 	ldr	pc, \[pc, #-4\]	; 2001020 <__func_to_branch_to_veneer\+0x8>
+ [0-9a-f]+:	00008000 	.word	0x00008000
+ [0-9a-f]+:	00000000 	.word	0x00000000
+
+Disassembly of section .text:
+
+[0-9a-f]+ <func_to_branch_to>:
+    [0-9a-f]+:	e12fff1e 	bx	lr
diff --git a/ld/testsuite/ld-arm/erratum-760522.s b/ld/testsuite/ld-arm/erratum-760522.s
new file mode 100644
index 0000000..96e0328
--- /dev/null
+++ b/ld/testsuite/ld-arm/erratum-760522.s
@@ -0,0 +1,15 @@
+	.syntax unified
+	.globl _start
+	.globl func_to_branch_to
+
+	.arm
+	.text
+func_to_branch_to:
+	bx lr
+
+	.thumb
+	.section .foo, "xa"
+	.thumb_func
+_start:
+	bl func_to_branch_to
+

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFA/ARM]: Patch to workaround ARM1176 BLX (immediate) Thumb to ARM issue
  2011-07-27 16:29 [RFA/ARM]: Patch to workaround ARM1176 BLX (immediate) Thumb to ARM issue Matthew Gretton-Dann
@ 2011-07-27 16:44 ` Joseph S. Myers
  2011-07-28 16:41 ` Nick Clifton
  1 sibling, 0 replies; 8+ messages in thread
From: Joseph S. Myers @ 2011-07-27 16:44 UTC (permalink / raw)
  To: Matthew Gretton-Dann; +Cc: binutils, Richard Earnshaw

On Wed, 27 Jul 2011, Matthew Gretton-Dann wrote:

>      * Adds a command line option to ld --[no-]fix-erratum-760522, which
>        is enabled by default.

I don't see any change to the Texinfo manual to document this new option.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFA/ARM]: Patch to workaround ARM1176 BLX (immediate) Thumb to ARM issue
  2011-07-27 16:29 [RFA/ARM]: Patch to workaround ARM1176 BLX (immediate) Thumb to ARM issue Matthew Gretton-Dann
  2011-07-27 16:44 ` Joseph S. Myers
@ 2011-07-28 16:41 ` Nick Clifton
  2011-07-28 21:33   ` Matthew Gretton-Dann
  1 sibling, 1 reply; 8+ messages in thread
From: Nick Clifton @ 2011-07-28 16:41 UTC (permalink / raw)
  To: Matthew Gretton-Dann; +Cc: binutils, Richard Earnshaw

Hi Matthew,

> * When the option is on the linker will only use BLX if the target
> architecture (derived from the object files) is v6T2, v7, or
> greater.

This does not seem right to me.  The erratum only applies to the 
ARM1176JZ-S and ARM1176JZF-S processors and only to Thumb BLX 
instructions.  Disabling the use of BLX in ARM mode or for pre-ARM11 
cores will generate needlessly larger code.

Also when you check the Tag_CPU_arch value, please use the enum names, 
not the integer values.

Cheers
   Nick



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFA/ARM]: Patch to workaround ARM1176 BLX (immediate) Thumb to ARM issue
  2011-07-28 16:41 ` Nick Clifton
@ 2011-07-28 21:33   ` Matthew Gretton-Dann
  2011-07-29 13:34     ` Matthew Gretton-Dann
  0 siblings, 1 reply; 8+ messages in thread
From: Matthew Gretton-Dann @ 2011-07-28 21:33 UTC (permalink / raw)
  To: Nick Clifton; +Cc: binutils, Richard Earnshaw

On 28/07/11 15:03, Nick Clifton wrote:
> Hi Matthew,
>
>> * When the option is on the linker will only use BLX if the target
>> architecture (derived from the object files) is v6T2, v7, or
>> greater.
>
> This does not seem right to me.  The erratum only applies to the
> ARM1176JZ-S and ARM1176JZF-S processors and only to Thumb BLX
> instructions.  Disabling the use of BLX in ARM mode or for pre-ARM11
> cores will generate needlessly larger code.

The argument for doing it this way is that there are systems where code 
is built for architecture ARMv5TE (for example) yet the devices the code 
is run on is an ARM1176.

The aim of having the fix on by default for architectures before ARMv6T2 
is to catch these cases.

I was also looking for the least disruptive fix to the linker code paths 
so that the changes made would be easily tested.

> Also when you check the Tag_CPU_arch value, please use the enum names,
> not the integer values.

Noted - a patch will be forthcoming with updates following your comments 
and Joseph Myers'.

Thanks,

Matt

-- 
Matthew Gretton-Dann
Principal Engineer, PD Software - Tools, ARM Ltd

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFA/ARM]: Patch to workaround ARM1176 BLX (immediate) Thumb to ARM issue
  2011-07-28 21:33   ` Matthew Gretton-Dann
@ 2011-07-29 13:34     ` Matthew Gretton-Dann
  2011-08-08  9:52       ` [PING] " Matthew Gretton-Dann
  0 siblings, 1 reply; 8+ messages in thread
From: Matthew Gretton-Dann @ 2011-07-29 13:34 UTC (permalink / raw)
  To: binutils; +Cc: nickc, Richard Earnshaw, Joseph S. Myers

[-- Attachment #1: Type: text/plain, Size: 1885 bytes --]

Hi,

Please find an updated patch attached following comments from Joesph 
Myers & Nick Clifton.

The following changes have been made:
  * Command line option name changed to --fix-arm1176
    This carries on the naming scheme use for previous fixes (like 
--fix-cortex-a8)
  * Added documentation for this option[1]
  * Used symbolic constants and not magic numbers

Pleae can someone review, comment, and if appropriate approve.

Thanks,

Matt


ChangeLog:

bfd/ChangeLog:
2011-07-29  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>

	* bfd-in.h (bfd_elf32_arm_set_target_relocs): Update prototype.
	* bfd-in2.h (bfd_elf32_arm_set_target_relocs): Likewise.
	* elf32-arm.c (elf32_arm_link_hash_table): New field.
	(elf232_arm_link_hash_table_create): Initialise new field.
	(check_use_blx): Change test depending on fix_arm1176.
	(bfd_elf32_arm_set_target_relocs): Set fix_arm1176 from
	command line options.

ld/ChangeLog:
2011-07-29  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>

	* emultempl/armelf.em (fix_arm1176): New variable.
	(arm_elf_create_output_section_statements): Pass
	fix_arm1176 option to bfd backend.
	(OPTION_FIX_ARM1176): New define.
	(OPTION_NO_FIX_ARM1176): Likewise.
	(PARSE_AND_LIST_LONGOPTS): Add new command line options.
	(PARSE_AND_LIST_OPTIONS): Likewise.
	(PARSE_AND_LIST_ARGS_CASES): Likewise.
	* ld.texinfo: Document new command line options.

ld/testsuite/ChangeLog:
2011-07-29  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>

	* ld-arm/arm-elf.exp (armelftests): Update for new command-line
	options.
	(armeabitests): Update for new command-line options, and add
	new test cases.
	* ld-arm/fix-arm1176.s: Add test case.
	* ld-arm/fix-arm1176-off.d: Likewise.
	* ld-arm/fix-arm1176-on.d: Likewise.

-- 
Matthew Gretton-Dann
Principal Engineer, PD Software - Tools, ARM Ltd

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: fix-arm1176.patch --]
[-- Type: text/x-patch; name=fix-arm1176.patch, Size: 17224 bytes --]

diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h
index 21b7cc2..f375d2f 100644
--- a/bfd/bfd-in.h
+++ b/bfd/bfd-in.h
@@ -869,7 +869,7 @@ extern bfd_boolean bfd_elf32_arm_process_before_allocation
 
 void bfd_elf32_arm_set_target_relocs
   (bfd *, struct bfd_link_info *, int, char *, int, int, bfd_arm_vfp11_fix,
-   int, int, int, int);
+   int, int, int, int, int);
 
 extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking
   (bfd *, struct bfd_link_info *);
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 6b7be67..3d5759d 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -876,7 +876,7 @@ extern bfd_boolean bfd_elf32_arm_process_before_allocation
 
 void bfd_elf32_arm_set_target_relocs
   (bfd *, struct bfd_link_info *, int, char *, int, int, bfd_arm_vfp11_fix,
-   int, int, int, int);
+   int, int, int, int, int);
 
 extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking
   (bfd *, struct bfd_link_info *);
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index 0ddd0cf..4d407a9 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -2776,6 +2776,9 @@ struct elf32_arm_link_hash_table
   /* Whether we should fix the Cortex-A8 Thumb-2 branch/TLB erratum.  */
   int fix_cortex_a8;
 
+  /* Whether we should fix the ARM1176 BLX immediate issue.  */
+  int fix_arm1176;
+
   /* Nonzero if the ARM/Thumb BLX instructions are available for use.  */
   int use_blx;
 
@@ -3315,6 +3318,7 @@ elf32_arm_link_hash_table_create (bfd *abfd)
   ret->vfp11_erratum_glue_size = 0;
   ret->num_vfp11_fixes = 0;
   ret->fix_cortex_a8 = 0;
+  ret->fix_arm1176 = 0;
   ret->bfd_of_glue_owner = NULL;
   ret->byteswap_code = 0;
   ret->target1_is_rel = 0;
@@ -5930,9 +5934,21 @@ bfd_elf32_arm_get_bfd_for_interworking (bfd *abfd, struct bfd_link_info *info)
 static void
 check_use_blx (struct elf32_arm_link_hash_table *globals)
 {
-  if (bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
-				Tag_CPU_arch) > 2)
-    globals->use_blx = 1;
+  int cpu_arch;
+
+  cpu_arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC, 
+				       Tag_CPU_arch);
+
+  if (globals->fix_arm1176)
+    {
+      if (cpu_arch == TAG_CPU_ARCH_V6T2 || cpu_arch > TAG_CPU_ARCH_V6K)
+	globals->use_blx = 1;
+    }
+  else
+    {
+      if (cpu_arch > TAG_CPU_ARCH_V4T)
+	globals->use_blx = 1;
+    }
 }
 
 bfd_boolean
@@ -6786,7 +6802,8 @@ bfd_elf32_arm_set_target_relocs (struct bfd *output_bfd,
 				 int use_blx,
                                  bfd_arm_vfp11_fix vfp11_fix,
 				 int no_enum_warn, int no_wchar_warn,
-				 int pic_veneer, int fix_cortex_a8)
+				 int pic_veneer, int fix_cortex_a8,
+				 int fix_arm1176)
 {
   struct elf32_arm_link_hash_table *globals;
 
@@ -6811,6 +6828,7 @@ bfd_elf32_arm_set_target_relocs (struct bfd *output_bfd,
   globals->vfp11_fix = vfp11_fix;
   globals->pic_veneer = pic_veneer;
   globals->fix_cortex_a8 = fix_cortex_a8;
+  globals->fix_arm1176 = fix_arm1176;
 
   BFD_ASSERT (is_arm_elf (output_bfd));
   elf_arm_tdata (output_bfd)->no_enum_size_warning = no_enum_warn;
diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em
index 948bf8d..d29da59 100644
--- a/ld/emultempl/armelf.em
+++ b/ld/emultempl/armelf.em
@@ -42,6 +42,7 @@ static int no_enum_size_warning = 0;
 static int no_wchar_size_warning = 0;
 static int pic_veneer = 0;
 static int merge_exidx_entries = -1;
+static int fix_arm1176 = 1;
 
 static void
 gld${EMULATION_NAME}_before_parse (void)
@@ -464,7 +465,8 @@ arm_elf_create_output_section_statements (void)
 				   target2_type, fix_v4bx, use_blx,
 				   vfp11_denorm_fix, no_enum_size_warning,
 				   no_wchar_size_warning,
-				   pic_veneer, fix_cortex_a8);
+				   pic_veneer, fix_cortex_a8, 
+				   fix_arm1176);
 
   stub_file = lang_add_input_file ("linker stubs",
  				   lang_input_file_is_fake_enum,
@@ -529,6 +531,8 @@ PARSE_AND_LIST_PROLOGUE='
 #define OPTION_FIX_CORTEX_A8		314
 #define OPTION_NO_FIX_CORTEX_A8		315
 #define OPTION_NO_MERGE_EXIDX_ENTRIES   316
+#define OPTION_FIX_ARM1176		317
+#define OPTION_NO_FIX_ARM1176		318
 '
 
 PARSE_AND_LIST_SHORTOPTS=p
@@ -551,6 +555,8 @@ PARSE_AND_LIST_LONGOPTS='
   { "fix-cortex-a8", no_argument, NULL, OPTION_FIX_CORTEX_A8 },
   { "no-fix-cortex-a8", no_argument, NULL, OPTION_NO_FIX_CORTEX_A8 },
   { "no-merge-exidx-entries", no_argument, NULL, OPTION_NO_MERGE_EXIDX_ENTRIES },
+  { "fix-arm1176", no_argument, NULL, OPTION_FIX_ARM1176 },
+  { "no-fix-arm1176", no_argument, NULL, OPTION_NO_FIX_ARM1176 },
 '
 
 PARSE_AND_LIST_OPTIONS='
@@ -579,7 +585,7 @@ PARSE_AND_LIST_OPTIONS='
  		   ));
   fprintf (file, _("  --[no-]fix-cortex-a8        Disable/enable Cortex-A8 Thumb-2 branch erratum fix\n"));
   fprintf (file, _("  --no-merge-exidx-entries    Disable merging exidx entries\n"));
- 
+  fprintf (file, _("  --[no-]fix-arm1176          Disable/enable ARM1176 BLX immediate erratum fix\n"));
 '
 
 PARSE_AND_LIST_ARGS_CASES='
@@ -662,7 +668,15 @@ PARSE_AND_LIST_ARGS_CASES='
 
    case OPTION_NO_MERGE_EXIDX_ENTRIES:
       merge_exidx_entries = 0;
+      break;
 
+   case OPTION_FIX_ARM1176:
+      fix_arm1176 = 1;
+      break;
+
+   case OPTION_NO_FIX_ARM1176:
+      fix_arm1176 = 0;
+      break;
 '
 
 # We have our own before_allocation etc. functions, but they call
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index 7547c0a..1555bb5 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -6321,6 +6321,16 @@ instruction. The original instruction is then replaced with a branch to
 the veneer. The extra cycles required to call and return from the veneer
 are sufficient to avoid the erratum in both the scalar and vector cases.
 
+@cindex ARM1176 erratum workaround
+@kindex --fix-arm1176
+@kindex --no-fix-arm1176
+The @samp{--fix-arm1176} switch enables a link-time workaround for an erratum 
+in certain ARM1176 processors.  The workaround is enabled by default if you 
+are targetting ARM v6 (excluding ARM v6T2) or earlier.  It can be disabled 
+unconditionally by specifying @samp{--no-fix-arm1176}.
+
+Please contact ARM for further details.
+
 @cindex NO_ENUM_SIZE_WARNING
 @kindex --no-enum-size-warning
 The @option{--no-enum-size-warning} switch prevents the linker from
diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp
index 8b8495e..fbdfadd 100644
--- a/ld/testsuite/ld-arm/arm-elf.exp
+++ b/ld/testsuite/ld-arm/arm-elf.exp
@@ -137,7 +137,7 @@ set armelftests {
     {"arm-rel32" "-shared -T arm-dyn.ld" "" {arm-rel32.s}
      {{objdump -Rsj.data arm-rel32.d}}
      "arm-rel32"}
-    {"arm-call" "-static -T arm.ld" "-meabi=4" {arm-call1.s arm-call2.s}
+    {"arm-call" "--no-fix-arm1176 -static -T arm.ld" "-meabi=4" {arm-call1.s arm-call2.s}
      {{objdump -d arm-call.d}}
      "arm-call"}
     {"TLS shared library" "-shared -T arm-lib.ld" "" {tls-lib.s}
@@ -149,16 +149,16 @@ set armelftests {
     {"TLS gnu shared library got" "-shared -T arm-dyn.ld" "" {tls-gdesc-got.s}
      {{objdump "-fDR -j .got" tls-gdesc-got.d}}
      "tls-lib2-got.so"}
-    {"TLS gnu shared library inlined trampoline" "-shared -T arm-dyn.ld" "" {tls-descseq.s}
+    {"TLS gnu shared library inlined trampoline" "--no-fix-arm1176 -shared -T arm-dyn.ld" "" {tls-descseq.s}
      {{objdump -fdw tls-descseq.d} {objdump -Rw tls-descseq.r}}
      "tls-lib2inline.so"}
-    {"TLS shared library gdesc local" "-shared -T arm-dyn.ld" "" {tls-lib-loc.s}
+    {"TLS shared library gdesc local" "--no-fix-arm1176 -shared -T arm-dyn.ld" "" {tls-lib-loc.s}
      {{objdump -fdw tls-lib-loc.d} {objdump -Rw tls-lib-loc.r}}
      "tls-lib-loc.so"}
     {"TLS gnu GD to IE relaxation" "-static -T arm-dyn.ld" "" {tls-gdierelax.s}
      {{objdump -fdw tls-gdierelax.d}}
      "tls-app-rel-ie"}
-    {"TLS gnu GD to IE shared relaxation" "-shared -T arm-dyn.ld" "" {tls-gdierelax2.s}
+    {"TLS gnu GD to IE shared relaxation" "--no-fix-arm1176 -shared -T arm-dyn.ld" "" {tls-gdierelax2.s}
      {{objdump -fdw tls-gdierelax2.d}}
      "tls-app-rel-ie2"}
     {"TLS gnu GD to LE relaxation" "-T arm-dyn.ld" "" {tls-gdlerelax.s}
@@ -507,7 +507,7 @@ set armeabitests {
     {"MOVW/MOVT against shared libraries" "tmpdir/arm-lib.so" "" {arm-app-movw.s}
      {{objdump -Rw arm-app.r}}
      "arm-app-movw"}
-    {"Thumb-2-as-Thumb-1 BL" "-Ttext 0x1000 --section-start .foo=0x100100c" "" {thumb2-bl-as-thumb1-bad.s}
+    {"Thumb-2-as-Thumb-1 BL" "--no-fix-arm1176 -Ttext 0x1000 --section-start .foo=0x100100c" "" {thumb2-bl-as-thumb1-bad.s}
      {{objdump -d thumb2-bl-as-thumb1-bad.d}}
      "thumb2-bl-as-thumb1-bad"}
     {"Thumb-2 BL" "-Ttext 0x1000 --section-start .foo=0x100100c" "" {thumb2-bl-bad.s}
@@ -530,7 +530,7 @@ set armeabitests {
     {"ARM-Thumb farcall" "-Ttext 0x1000 --section-start .foo=0x2001014" "" {farcall-arm-thumb.s}
      {{objdump -d farcall-arm-thumb.d}}
      "farcall-arm-thumb"}
-    {"ARM-Thumb farcall with BLX" "-Ttext 0x1000 --section-start .foo=0x2001014" "-march=armv5t" {farcall-arm-thumb.s}
+    {"ARM-Thumb farcall with BLX" "--no-fix-arm1176 -Ttext 0x1000 --section-start .foo=0x2001014" "-march=armv5t" {farcall-arm-thumb.s}
      {{objdump -d farcall-arm-thumb-blx.d}}
      "farcall-arm-thumb-blx"}
     {"ARM-Thumb farcall (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "" {farcall-arm-thumb.s}
@@ -540,7 +540,7 @@ set armeabitests {
      {{objdump -d farcall-arm-thumb-blx-pic-veneer.d}}
      "farcall-arm-thumb-blx-pic-veneer"}
 
-    {"Thumb-Thumb farcall with BLX" "-Ttext 0x1000 --section-start .foo=0x2001014" "-march=armv5t" {farcall-thumb-thumb.s}
+    {"Thumb-Thumb farcall with BLX" "--no-fix-arm1176 -Ttext 0x1000 --section-start .foo=0x2001014" "-march=armv5t" {farcall-thumb-thumb.s}
      {{objdump -d farcall-thumb-thumb-blx.d}}
      "farcall-thumb-thumb-blx"}
     {"Thumb-Thumb farcall M profile" "-Ttext 0x1000 --section-start .foo=0x2001014" "-march=armv7-m" {farcall-thumb-thumb.s}
@@ -552,7 +552,7 @@ set armeabitests {
     {"Thumb-Thumb farcall" "-Ttext 0x1000 --section-start .foo=0x2001014" "-march=armv4t" {farcall-thumb-thumb.s}
      {{objdump -d farcall-thumb-thumb.d}}
      "farcall-thumb-thumb"}
-    {"Thumb-Thumb farcall with BLX (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-march=armv5t" {farcall-thumb-thumb.s}
+    {"Thumb-Thumb farcall with BLX (PIC veneer)" "--no-fix-arm1176 -Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-march=armv5t" {farcall-thumb-thumb.s}
      {{objdump -d farcall-thumb-thumb-blx-pic-veneer.d}}
      "farcall-thumb-thumb-blx-pic-veneer"}
     {"Thumb-Thumb farcall M profile (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-march=armv7-m" {farcall-thumb-thumb.s}
@@ -574,10 +574,10 @@ set armeabitests {
     {"Thumb-ARM (short) call" "-Ttext 0x1000 --section-start .foo=0x0002014" "-W" {farcall-thumb-arm-short.s}
      {{objdump -d farcall-thumb-arm-short.d}}
      "farcall-thumb-arm-short"}
-    {"Thumb-ARM farcall with BLX" "-Ttext 0x1c01010 --section-start .foo=0x2001014" "-W -march=armv5t" {farcall-thumb-arm.s}
+    {"Thumb-ARM farcall with BLX" "--no-fix-arm1176 -Ttext 0x1c01010 --section-start .foo=0x2001014" "-W -march=armv5t" {farcall-thumb-arm.s}
      {{objdump -d farcall-thumb-arm-blx.d}}
      "farcall-thumb-arm-blx"}
-    {"Thumb-ARM farcall with BLX (PIC veneer)" "-Ttext 0x1c01010 --section-start .foo=0x2001014 --pic-veneer" "-W -march=armv5t" {farcall-thumb-arm.s}
+    {"Thumb-ARM farcall with BLX (PIC veneer)" "--no-fix-arm1176 -Ttext 0x1c01010 --section-start .foo=0x2001014 --pic-veneer" "-W -march=armv5t" {farcall-thumb-arm.s}
      {{objdump -d farcall-thumb-arm-blx-pic-veneer.d}}
      "farcall-thumb-arm-blx-pic-veneer"}
     {"Thumb-ARM farcall (PIC veneer)" "-Ttext 0x1c01010 --section-start .foo=0x2001014 --pic-veneer" "-W" {farcall-thumb-arm.s}
@@ -617,7 +617,7 @@ set armeabitests {
      {{objdump -fdw farcall-mixed-lib-v4t.d}}
      "farcall-mixed-lib.so"}
 
-    {"Mixed ARM/Thumb shared library with long branches (v5t)" "-shared -T arm-lib.ld" "-march=armv5t"
+    {"Mixed ARM/Thumb shared library with long branches (v5t)" "--no-fix-arm1176 -shared -T arm-lib.ld" "-march=armv5t"
      {farcall-mixed-lib1.s farcall-mixed-lib2.s}
      {{objdump -fdw farcall-mixed-lib.d}}
      "farcall-mixed-lib.so"}
@@ -627,24 +627,24 @@ set armeabitests {
      "farcall-data"}
 
     {"R_ARM_THM_JUMP24 Relocation veneers: Short 1" 
-     "--section-start destsect=0x00009000 --section-start .text=0x8000" 
+     "--no-fix-arm1176 --section-start destsect=0x00009000 --section-start .text=0x8000" 
      "-march=armv7-a -mthumb" 
      {jump-reloc-veneers.s}
      {{objdump -d jump-reloc-veneers-short1.d}}
      "jump-reloc-veneers-short1"}
     {"R_ARM_THM_JUMP24 Relocation veneers: Short 2" 
-     "--section-start destsect=0x00900000 --section-start .text=0x8000" 
+     "--no-fix-arm1176 --section-start destsect=0x00900000 --section-start .text=0x8000" 
      "-march=armv7-a -mthumb" 
      {jump-reloc-veneers.s}
      {{objdump -d jump-reloc-veneers-short2.d}}
      "jump-reloc-veneers-short2"}
     {"R_ARM_THM_JUMP24 Relocation veneers: Long" 
-     "--section-start destsect=0x09000000 --section-start .text=0x8000" 
+     "--no-fix-arm1176 --section-start destsect=0x09000000 --section-start .text=0x8000" 
      "-march=armv7-a -mthumb" 
      {jump-reloc-veneers.s}
      {{objdump -d jump-reloc-veneers-long.d}}
      "jump-reloc-veneers-long"}
-    {"TLS gnu shared library" "-shared -T arm-dyn.ld" "" {tls-gdesc.s}
+    {"TLS gnu shared library" "--no-fix-arm1176 -shared -T arm-dyn.ld" "" {tls-gdesc.s}
      {{objdump -fdw tls-gdesc.d} {objdump -Rw tls-gdesc.r}}
      "tls-lib2.so"}
     {"TLS gnu shared library non-lazy" "-z now -shared -T arm-dyn.ld" "" {tls-gdesc.s}
@@ -659,6 +659,31 @@ set armeabitests {
     {"TLS thumb1" "-shared -T arm-dyn.ld --section-start .foo=0x4001000" "" {tls-thumb1.s}
      {{objdump -fdw tls-thumb1.d}}
      "tls-thumb1"}
+
+    {"erratum 760522 fix (default for v6z)" "--section-start=.foo=0x2001014" 
+     "-march=armv6z" {fix-arm1176.s}
+     {{objdump -d fix-arm1176-on.d}}
+     "fix-arm1176-1"}
+    {"erratum 760522 fix (explicitly on at v6z)" "--section-start=.foo=0x2001014 --fix-arm1176" 
+     "-march=armv6z" {fix-arm1176.s}
+     {{objdump -d fix-arm1176-on.d}}
+     "fix-arm1176-2"}
+    {"erratum 760522 fix (explicitly off at v6z)" "--section-start=.foo=0x2001014 --no-fix-arm1176" 
+     "-march=armv6z" {fix-arm1176.s}
+     {{objdump -d fix-arm1176-off.d}}
+     "fix-arm1176-3"}
+    {"erratum 760522 fix (default for v5)" "--section-start=.foo=0x2001014 " 
+     "-march=armv5te" {fix-arm1176.s}
+     {{objdump -d fix-arm1176-on.d}}
+     "fix-arm1176-4"}
+    {"erratum 760522 fix (default for v7-a)" "--section-start=.foo=0x2001014 " 
+     "-march=armv7-a" {fix-arm1176.s}
+     {{objdump -d fix-arm1176-off.d}}
+     "fix-arm1176-5"}
+    {"erratum 760522 fix (default for ARM1156)" "--section-start=.foo=0x2001014 " 
+     "-mcpu=arm1156t2f-s" {fix-arm1176.s}
+     {{objdump -d fix-arm1176-off.d}}
+     "fix-arm1176-6"}
 }
 
 run_ld_link_tests $armeabitests
diff --git a/ld/testsuite/ld-arm/fix-arm1176-off.d b/ld/testsuite/ld-arm/fix-arm1176-off.d
new file mode 100644
index 0000000..3b45a3b
--- /dev/null
+++ b/ld/testsuite/ld-arm/fix-arm1176-off.d
@@ -0,0 +1,17 @@
+
+.*:     file format elf32-littlearm
+
+
+Disassembly of section .foo:
+
+[0-9a-f]+ <_start>:
+ [0-9a-f]+:	f000 e800 	blx	2001018 <__func_to_branch_to_veneer>
+
+[0-9a-f]+ <__func_to_branch_to_veneer>:
+ [0-9a-f]+:	e51ff004 	ldr	pc, \[pc, #-4\]	; 200101c <__func_to_branch_to_veneer\+0x4>
+ [0-9a-f]+:	00008000 	.word	0x00008000
+
+Disassembly of section .text:
+
+[0-9a-f]+ <func_to_branch_to>:
+    [0-9a-f]+:	e12fff1e 	bx	lr
diff --git a/ld/testsuite/ld-arm/fix-arm1176-on.d b/ld/testsuite/ld-arm/fix-arm1176-on.d
new file mode 100644
index 0000000..c4e7870
--- /dev/null
+++ b/ld/testsuite/ld-arm/fix-arm1176-on.d
@@ -0,0 +1,20 @@
+
+.+:     file format elf32-littlearm
+
+
+Disassembly of section .foo:
+
+[0-9a-f]+ <_start>:
+ [0-9a-f]+:	f000 f800 	bl	2001018 <__func_to_branch_to_veneer>
+
+[0-9a-f]+ <__func_to_branch_to_veneer>:
+ [0-9a-f]+:	4778      	bx	pc
+ [0-9a-f]+:	46c0      	nop			; \(mov r8, r8\)
+ [0-9a-f]+:	e51ff004 	ldr	pc, \[pc, #-4\]	; 2001020 <__func_to_branch_to_veneer\+0x8>
+ [0-9a-f]+:	00008000 	.word	0x00008000
+ [0-9a-f]+:	00000000 	.word	0x00000000
+
+Disassembly of section .text:
+
+[0-9a-f]+ <func_to_branch_to>:
+    [0-9a-f]+:	e12fff1e 	bx	lr
diff --git a/ld/testsuite/ld-arm/fix-arm1176.s b/ld/testsuite/ld-arm/fix-arm1176.s
new file mode 100644
index 0000000..96e0328
--- /dev/null
+++ b/ld/testsuite/ld-arm/fix-arm1176.s
@@ -0,0 +1,15 @@
+	.syntax unified
+	.globl _start
+	.globl func_to_branch_to
+
+	.arm
+	.text
+func_to_branch_to:
+	bx lr
+
+	.thumb
+	.section .foo, "xa"
+	.thumb_func
+_start:
+	bl func_to_branch_to
+

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PING] [RFA/ARM]: Patch to workaround ARM1176 BLX (immediate) Thumb to ARM issue
  2011-07-29 13:34     ` Matthew Gretton-Dann
@ 2011-08-08  9:52       ` Matthew Gretton-Dann
  2011-08-09 12:17         ` Nick Clifton
  0 siblings, 1 reply; 8+ messages in thread
From: Matthew Gretton-Dann @ 2011-08-08  9:52 UTC (permalink / raw)
  To: binutils; +Cc: nickc, Richard Earnshaw, Joseph S. Myers

Hi,

Please can someone review this patch?

Thanks,

Matt

On 29/07/11 10:27, Matthew Gretton-Dann wrote:
> Hi,
>
> Please find an updated patch attached following comments from Joesph
> Myers&  Nick Clifton.
>
> The following changes have been made:
>    * Command line option name changed to --fix-arm1176
>      This carries on the naming scheme use for previous fixes (like
> --fix-cortex-a8)
>    * Added documentation for this option[1]
>    * Used symbolic constants and not magic numbers
>
> Pleae can someone review, comment, and if appropriate approve.
>
> Thanks,
>
> Matt
>
>
> ChangeLog:
>
> bfd/ChangeLog:
> 2011-07-29  Matthew Gretton-Dann<matthew.gretton-dann@arm.com>
>
> 	* bfd-in.h (bfd_elf32_arm_set_target_relocs): Update prototype.
> 	* bfd-in2.h (bfd_elf32_arm_set_target_relocs): Likewise.
> 	* elf32-arm.c (elf32_arm_link_hash_table): New field.
> 	(elf232_arm_link_hash_table_create): Initialise new field.
> 	(check_use_blx): Change test depending on fix_arm1176.
> 	(bfd_elf32_arm_set_target_relocs): Set fix_arm1176 from
> 	command line options.
>
> ld/ChangeLog:
> 2011-07-29  Matthew Gretton-Dann<matthew.gretton-dann@arm.com>
>
> 	* emultempl/armelf.em (fix_arm1176): New variable.
> 	(arm_elf_create_output_section_statements): Pass
> 	fix_arm1176 option to bfd backend.
> 	(OPTION_FIX_ARM1176): New define.
> 	(OPTION_NO_FIX_ARM1176): Likewise.
> 	(PARSE_AND_LIST_LONGOPTS): Add new command line options.
> 	(PARSE_AND_LIST_OPTIONS): Likewise.
> 	(PARSE_AND_LIST_ARGS_CASES): Likewise.
> 	* ld.texinfo: Document new command line options.
>
> ld/testsuite/ChangeLog:
> 2011-07-29  Matthew Gretton-Dann<matthew.gretton-dann@arm.com>
>
> 	* ld-arm/arm-elf.exp (armelftests): Update for new command-line
> 	options.
> 	(armeabitests): Update for new command-line options, and add
> 	new test cases.
> 	* ld-arm/fix-arm1176.s: Add test case.
> 	* ld-arm/fix-arm1176-off.d: Likewise.
> 	* ld-arm/fix-arm1176-on.d: Likewise.
>
>
>
> fix-arm1176.patch
>
>
> diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h
> index 21b7cc2..f375d2f 100644
> --- a/bfd/bfd-in.h
> +++ b/bfd/bfd-in.h
> @@ -869,7 +869,7 @@ extern bfd_boolean bfd_elf32_arm_process_before_allocation
>
>   void bfd_elf32_arm_set_target_relocs
>     (bfd *, struct bfd_link_info *, int, char *, int, int, bfd_arm_vfp11_fix,
> -   int, int, int, int);
> +   int, int, int, int, int);
>
>   extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking
>     (bfd *, struct bfd_link_info *);
> diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
> index 6b7be67..3d5759d 100644
> --- a/bfd/bfd-in2.h
> +++ b/bfd/bfd-in2.h
> @@ -876,7 +876,7 @@ extern bfd_boolean bfd_elf32_arm_process_before_allocation
>
>   void bfd_elf32_arm_set_target_relocs
>     (bfd *, struct bfd_link_info *, int, char *, int, int, bfd_arm_vfp11_fix,
> -   int, int, int, int);
> +   int, int, int, int, int);
>
>   extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking
>     (bfd *, struct bfd_link_info *);
> diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
> index 0ddd0cf..4d407a9 100644
> --- a/bfd/elf32-arm.c
> +++ b/bfd/elf32-arm.c
> @@ -2776,6 +2776,9 @@ struct elf32_arm_link_hash_table
>     /* Whether we should fix the Cortex-A8 Thumb-2 branch/TLB erratum.  */
>     int fix_cortex_a8;
>
> +  /* Whether we should fix the ARM1176 BLX immediate issue.  */
> +  int fix_arm1176;
> +
>     /* Nonzero if the ARM/Thumb BLX instructions are available for use.  */
>     int use_blx;
>
> @@ -3315,6 +3318,7 @@ elf32_arm_link_hash_table_create (bfd *abfd)
>     ret->vfp11_erratum_glue_size = 0;
>     ret->num_vfp11_fixes = 0;
>     ret->fix_cortex_a8 = 0;
> +  ret->fix_arm1176 = 0;
>     ret->bfd_of_glue_owner = NULL;
>     ret->byteswap_code = 0;
>     ret->target1_is_rel = 0;
> @@ -5930,9 +5934,21 @@ bfd_elf32_arm_get_bfd_for_interworking (bfd *abfd, struct bfd_link_info *info)
>   static void
>   check_use_blx (struct elf32_arm_link_hash_table *globals)
>   {
> -  if (bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
> -				Tag_CPU_arch)>  2)
> -    globals->use_blx = 1;
> +  int cpu_arch;
> +
> +  cpu_arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
> +				       Tag_CPU_arch);
> +
> +  if (globals->fix_arm1176)
> +    {
> +      if (cpu_arch == TAG_CPU_ARCH_V6T2 || cpu_arch>  TAG_CPU_ARCH_V6K)
> +	globals->use_blx = 1;
> +    }
> +  else
> +    {
> +      if (cpu_arch>  TAG_CPU_ARCH_V4T)
> +	globals->use_blx = 1;
> +    }
>   }
>
>   bfd_boolean
> @@ -6786,7 +6802,8 @@ bfd_elf32_arm_set_target_relocs (struct bfd *output_bfd,
>   				 int use_blx,
>                                    bfd_arm_vfp11_fix vfp11_fix,
>   				 int no_enum_warn, int no_wchar_warn,
> -				 int pic_veneer, int fix_cortex_a8)
> +				 int pic_veneer, int fix_cortex_a8,
> +				 int fix_arm1176)
>   {
>     struct elf32_arm_link_hash_table *globals;
>
> @@ -6811,6 +6828,7 @@ bfd_elf32_arm_set_target_relocs (struct bfd *output_bfd,
>     globals->vfp11_fix = vfp11_fix;
>     globals->pic_veneer = pic_veneer;
>     globals->fix_cortex_a8 = fix_cortex_a8;
> +  globals->fix_arm1176 = fix_arm1176;
>
>     BFD_ASSERT (is_arm_elf (output_bfd));
>     elf_arm_tdata (output_bfd)->no_enum_size_warning = no_enum_warn;
> diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em
> index 948bf8d..d29da59 100644
> --- a/ld/emultempl/armelf.em
> +++ b/ld/emultempl/armelf.em
> @@ -42,6 +42,7 @@ static int no_enum_size_warning = 0;
>   static int no_wchar_size_warning = 0;
>   static int pic_veneer = 0;
>   static int merge_exidx_entries = -1;
> +static int fix_arm1176 = 1;
>
>   static void
>   gld${EMULATION_NAME}_before_parse (void)
> @@ -464,7 +465,8 @@ arm_elf_create_output_section_statements (void)
>   				   target2_type, fix_v4bx, use_blx,
>   				   vfp11_denorm_fix, no_enum_size_warning,
>   				   no_wchar_size_warning,
> -				   pic_veneer, fix_cortex_a8);
> +				   pic_veneer, fix_cortex_a8,
> +				   fix_arm1176);
>
>     stub_file = lang_add_input_file ("linker stubs",
>    				   lang_input_file_is_fake_enum,
> @@ -529,6 +531,8 @@ PARSE_AND_LIST_PROLOGUE='
>   #define OPTION_FIX_CORTEX_A8		314
>   #define OPTION_NO_FIX_CORTEX_A8		315
>   #define OPTION_NO_MERGE_EXIDX_ENTRIES   316
> +#define OPTION_FIX_ARM1176		317
> +#define OPTION_NO_FIX_ARM1176		318
>   '
>
>   PARSE_AND_LIST_SHORTOPTS=p
> @@ -551,6 +555,8 @@ PARSE_AND_LIST_LONGOPTS='
>     { "fix-cortex-a8", no_argument, NULL, OPTION_FIX_CORTEX_A8 },
>     { "no-fix-cortex-a8", no_argument, NULL, OPTION_NO_FIX_CORTEX_A8 },
>     { "no-merge-exidx-entries", no_argument, NULL, OPTION_NO_MERGE_EXIDX_ENTRIES },
> +  { "fix-arm1176", no_argument, NULL, OPTION_FIX_ARM1176 },
> +  { "no-fix-arm1176", no_argument, NULL, OPTION_NO_FIX_ARM1176 },
>   '
>
>   PARSE_AND_LIST_OPTIONS='
> @@ -579,7 +585,7 @@ PARSE_AND_LIST_OPTIONS='
>    		   ));
>     fprintf (file, _("  --[no-]fix-cortex-a8        Disable/enable Cortex-A8 Thumb-2 branch erratum fix\n"));
>     fprintf (file, _("  --no-merge-exidx-entries    Disable merging exidx entries\n"));
> -
> +  fprintf (file, _("  --[no-]fix-arm1176          Disable/enable ARM1176 BLX immediate erratum fix\n"));
>   '
>
>   PARSE_AND_LIST_ARGS_CASES='
> @@ -662,7 +668,15 @@ PARSE_AND_LIST_ARGS_CASES='
>
>      case OPTION_NO_MERGE_EXIDX_ENTRIES:
>         merge_exidx_entries = 0;
> +      break;
>
> +   case OPTION_FIX_ARM1176:
> +      fix_arm1176 = 1;
> +      break;
> +
> +   case OPTION_NO_FIX_ARM1176:
> +      fix_arm1176 = 0;
> +      break;
>   '
>
>   # We have our own before_allocation etc. functions, but they call
> diff --git a/ld/ld.texinfo b/ld/ld.texinfo
> index 7547c0a..1555bb5 100644
> --- a/ld/ld.texinfo
> +++ b/ld/ld.texinfo
> @@ -6321,6 +6321,16 @@ instruction. The original instruction is then replaced with a branch to
>   the veneer. The extra cycles required to call and return from the veneer
>   are sufficient to avoid the erratum in both the scalar and vector cases.
>
> +@cindex ARM1176 erratum workaround
> +@kindex --fix-arm1176
> +@kindex --no-fix-arm1176
> +The @samp{--fix-arm1176} switch enables a link-time workaround for an erratum
> +in certain ARM1176 processors.  The workaround is enabled by default if you
> +are targetting ARM v6 (excluding ARM v6T2) or earlier.  It can be disabled
> +unconditionally by specifying @samp{--no-fix-arm1176}.
> +
> +Please contact ARM for further details.
> +
>   @cindex NO_ENUM_SIZE_WARNING
>   @kindex --no-enum-size-warning
>   The @option{--no-enum-size-warning} switch prevents the linker from
> diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp
> index 8b8495e..fbdfadd 100644
> --- a/ld/testsuite/ld-arm/arm-elf.exp
> +++ b/ld/testsuite/ld-arm/arm-elf.exp
> @@ -137,7 +137,7 @@ set armelftests {
>       {"arm-rel32" "-shared -T arm-dyn.ld" "" {arm-rel32.s}
>        {{objdump -Rsj.data arm-rel32.d}}
>        "arm-rel32"}
> -    {"arm-call" "-static -T arm.ld" "-meabi=4" {arm-call1.s arm-call2.s}
> +    {"arm-call" "--no-fix-arm1176 -static -T arm.ld" "-meabi=4" {arm-call1.s arm-call2.s}
>        {{objdump -d arm-call.d}}
>        "arm-call"}
>       {"TLS shared library" "-shared -T arm-lib.ld" "" {tls-lib.s}
> @@ -149,16 +149,16 @@ set armelftests {
>       {"TLS gnu shared library got" "-shared -T arm-dyn.ld" "" {tls-gdesc-got.s}
>        {{objdump "-fDR -j .got" tls-gdesc-got.d}}
>        "tls-lib2-got.so"}
> -    {"TLS gnu shared library inlined trampoline" "-shared -T arm-dyn.ld" "" {tls-descseq.s}
> +    {"TLS gnu shared library inlined trampoline" "--no-fix-arm1176 -shared -T arm-dyn.ld" "" {tls-descseq.s}
>        {{objdump -fdw tls-descseq.d} {objdump -Rw tls-descseq.r}}
>        "tls-lib2inline.so"}
> -    {"TLS shared library gdesc local" "-shared -T arm-dyn.ld" "" {tls-lib-loc.s}
> +    {"TLS shared library gdesc local" "--no-fix-arm1176 -shared -T arm-dyn.ld" "" {tls-lib-loc.s}
>        {{objdump -fdw tls-lib-loc.d} {objdump -Rw tls-lib-loc.r}}
>        "tls-lib-loc.so"}
>       {"TLS gnu GD to IE relaxation" "-static -T arm-dyn.ld" "" {tls-gdierelax.s}
>        {{objdump -fdw tls-gdierelax.d}}
>        "tls-app-rel-ie"}
> -    {"TLS gnu GD to IE shared relaxation" "-shared -T arm-dyn.ld" "" {tls-gdierelax2.s}
> +    {"TLS gnu GD to IE shared relaxation" "--no-fix-arm1176 -shared -T arm-dyn.ld" "" {tls-gdierelax2.s}
>        {{objdump -fdw tls-gdierelax2.d}}
>        "tls-app-rel-ie2"}
>       {"TLS gnu GD to LE relaxation" "-T arm-dyn.ld" "" {tls-gdlerelax.s}
> @@ -507,7 +507,7 @@ set armeabitests {
>       {"MOVW/MOVT against shared libraries" "tmpdir/arm-lib.so" "" {arm-app-movw.s}
>        {{objdump -Rw arm-app.r}}
>        "arm-app-movw"}
> -    {"Thumb-2-as-Thumb-1 BL" "-Ttext 0x1000 --section-start .foo=0x100100c" "" {thumb2-bl-as-thumb1-bad.s}
> +    {"Thumb-2-as-Thumb-1 BL" "--no-fix-arm1176 -Ttext 0x1000 --section-start .foo=0x100100c" "" {thumb2-bl-as-thumb1-bad.s}
>        {{objdump -d thumb2-bl-as-thumb1-bad.d}}
>        "thumb2-bl-as-thumb1-bad"}
>       {"Thumb-2 BL" "-Ttext 0x1000 --section-start .foo=0x100100c" "" {thumb2-bl-bad.s}
> @@ -530,7 +530,7 @@ set armeabitests {
>       {"ARM-Thumb farcall" "-Ttext 0x1000 --section-start .foo=0x2001014" "" {farcall-arm-thumb.s}
>        {{objdump -d farcall-arm-thumb.d}}
>        "farcall-arm-thumb"}
> -    {"ARM-Thumb farcall with BLX" "-Ttext 0x1000 --section-start .foo=0x2001014" "-march=armv5t" {farcall-arm-thumb.s}
> +    {"ARM-Thumb farcall with BLX" "--no-fix-arm1176 -Ttext 0x1000 --section-start .foo=0x2001014" "-march=armv5t" {farcall-arm-thumb.s}
>        {{objdump -d farcall-arm-thumb-blx.d}}
>        "farcall-arm-thumb-blx"}
>       {"ARM-Thumb farcall (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "" {farcall-arm-thumb.s}
> @@ -540,7 +540,7 @@ set armeabitests {
>        {{objdump -d farcall-arm-thumb-blx-pic-veneer.d}}
>        "farcall-arm-thumb-blx-pic-veneer"}
>
> -    {"Thumb-Thumb farcall with BLX" "-Ttext 0x1000 --section-start .foo=0x2001014" "-march=armv5t" {farcall-thumb-thumb.s}
> +    {"Thumb-Thumb farcall with BLX" "--no-fix-arm1176 -Ttext 0x1000 --section-start .foo=0x2001014" "-march=armv5t" {farcall-thumb-thumb.s}
>        {{objdump -d farcall-thumb-thumb-blx.d}}
>        "farcall-thumb-thumb-blx"}
>       {"Thumb-Thumb farcall M profile" "-Ttext 0x1000 --section-start .foo=0x2001014" "-march=armv7-m" {farcall-thumb-thumb.s}
> @@ -552,7 +552,7 @@ set armeabitests {
>       {"Thumb-Thumb farcall" "-Ttext 0x1000 --section-start .foo=0x2001014" "-march=armv4t" {farcall-thumb-thumb.s}
>        {{objdump -d farcall-thumb-thumb.d}}
>        "farcall-thumb-thumb"}
> -    {"Thumb-Thumb farcall with BLX (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-march=armv5t" {farcall-thumb-thumb.s}
> +    {"Thumb-Thumb farcall with BLX (PIC veneer)" "--no-fix-arm1176 -Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-march=armv5t" {farcall-thumb-thumb.s}
>        {{objdump -d farcall-thumb-thumb-blx-pic-veneer.d}}
>        "farcall-thumb-thumb-blx-pic-veneer"}
>       {"Thumb-Thumb farcall M profile (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-march=armv7-m" {farcall-thumb-thumb.s}
> @@ -574,10 +574,10 @@ set armeabitests {
>       {"Thumb-ARM (short) call" "-Ttext 0x1000 --section-start .foo=0x0002014" "-W" {farcall-thumb-arm-short.s}
>        {{objdump -d farcall-thumb-arm-short.d}}
>        "farcall-thumb-arm-short"}
> -    {"Thumb-ARM farcall with BLX" "-Ttext 0x1c01010 --section-start .foo=0x2001014" "-W -march=armv5t" {farcall-thumb-arm.s}
> +    {"Thumb-ARM farcall with BLX" "--no-fix-arm1176 -Ttext 0x1c01010 --section-start .foo=0x2001014" "-W -march=armv5t" {farcall-thumb-arm.s}
>        {{objdump -d farcall-thumb-arm-blx.d}}
>        "farcall-thumb-arm-blx"}
> -    {"Thumb-ARM farcall with BLX (PIC veneer)" "-Ttext 0x1c01010 --section-start .foo=0x2001014 --pic-veneer" "-W -march=armv5t" {farcall-thumb-arm.s}
> +    {"Thumb-ARM farcall with BLX (PIC veneer)" "--no-fix-arm1176 -Ttext 0x1c01010 --section-start .foo=0x2001014 --pic-veneer" "-W -march=armv5t" {farcall-thumb-arm.s}
>        {{objdump -d farcall-thumb-arm-blx-pic-veneer.d}}
>        "farcall-thumb-arm-blx-pic-veneer"}
>       {"Thumb-ARM farcall (PIC veneer)" "-Ttext 0x1c01010 --section-start .foo=0x2001014 --pic-veneer" "-W" {farcall-thumb-arm.s}
> @@ -617,7 +617,7 @@ set armeabitests {
>        {{objdump -fdw farcall-mixed-lib-v4t.d}}
>        "farcall-mixed-lib.so"}
>
> -    {"Mixed ARM/Thumb shared library with long branches (v5t)" "-shared -T arm-lib.ld" "-march=armv5t"
> +    {"Mixed ARM/Thumb shared library with long branches (v5t)" "--no-fix-arm1176 -shared -T arm-lib.ld" "-march=armv5t"
>        {farcall-mixed-lib1.s farcall-mixed-lib2.s}
>        {{objdump -fdw farcall-mixed-lib.d}}
>        "farcall-mixed-lib.so"}
> @@ -627,24 +627,24 @@ set armeabitests {
>        "farcall-data"}
>
>       {"R_ARM_THM_JUMP24 Relocation veneers: Short 1"
> -     "--section-start destsect=0x00009000 --section-start .text=0x8000"
> +     "--no-fix-arm1176 --section-start destsect=0x00009000 --section-start .text=0x8000"
>        "-march=armv7-a -mthumb"
>        {jump-reloc-veneers.s}
>        {{objdump -d jump-reloc-veneers-short1.d}}
>        "jump-reloc-veneers-short1"}
>       {"R_ARM_THM_JUMP24 Relocation veneers: Short 2"
> -     "--section-start destsect=0x00900000 --section-start .text=0x8000"
> +     "--no-fix-arm1176 --section-start destsect=0x00900000 --section-start .text=0x8000"
>        "-march=armv7-a -mthumb"
>        {jump-reloc-veneers.s}
>        {{objdump -d jump-reloc-veneers-short2.d}}
>        "jump-reloc-veneers-short2"}
>       {"R_ARM_THM_JUMP24 Relocation veneers: Long"
> -     "--section-start destsect=0x09000000 --section-start .text=0x8000"
> +     "--no-fix-arm1176 --section-start destsect=0x09000000 --section-start .text=0x8000"
>        "-march=armv7-a -mthumb"
>        {jump-reloc-veneers.s}
>        {{objdump -d jump-reloc-veneers-long.d}}
>        "jump-reloc-veneers-long"}
> -    {"TLS gnu shared library" "-shared -T arm-dyn.ld" "" {tls-gdesc.s}
> +    {"TLS gnu shared library" "--no-fix-arm1176 -shared -T arm-dyn.ld" "" {tls-gdesc.s}
>        {{objdump -fdw tls-gdesc.d} {objdump -Rw tls-gdesc.r}}
>        "tls-lib2.so"}
>       {"TLS gnu shared library non-lazy" "-z now -shared -T arm-dyn.ld" "" {tls-gdesc.s}
> @@ -659,6 +659,31 @@ set armeabitests {
>       {"TLS thumb1" "-shared -T arm-dyn.ld --section-start .foo=0x4001000" "" {tls-thumb1.s}
>        {{objdump -fdw tls-thumb1.d}}
>        "tls-thumb1"}
> +
> +    {"erratum 760522 fix (default for v6z)" "--section-start=.foo=0x2001014"
> +     "-march=armv6z" {fix-arm1176.s}
> +     {{objdump -d fix-arm1176-on.d}}
> +     "fix-arm1176-1"}
> +    {"erratum 760522 fix (explicitly on at v6z)" "--section-start=.foo=0x2001014 --fix-arm1176"
> +     "-march=armv6z" {fix-arm1176.s}
> +     {{objdump -d fix-arm1176-on.d}}
> +     "fix-arm1176-2"}
> +    {"erratum 760522 fix (explicitly off at v6z)" "--section-start=.foo=0x2001014 --no-fix-arm1176"
> +     "-march=armv6z" {fix-arm1176.s}
> +     {{objdump -d fix-arm1176-off.d}}
> +     "fix-arm1176-3"}
> +    {"erratum 760522 fix (default for v5)" "--section-start=.foo=0x2001014 "
> +     "-march=armv5te" {fix-arm1176.s}
> +     {{objdump -d fix-arm1176-on.d}}
> +     "fix-arm1176-4"}
> +    {"erratum 760522 fix (default for v7-a)" "--section-start=.foo=0x2001014 "
> +     "-march=armv7-a" {fix-arm1176.s}
> +     {{objdump -d fix-arm1176-off.d}}
> +     "fix-arm1176-5"}
> +    {"erratum 760522 fix (default for ARM1156)" "--section-start=.foo=0x2001014 "
> +     "-mcpu=arm1156t2f-s" {fix-arm1176.s}
> +     {{objdump -d fix-arm1176-off.d}}
> +     "fix-arm1176-6"}
>   }
>
>   run_ld_link_tests $armeabitests
> diff --git a/ld/testsuite/ld-arm/fix-arm1176-off.d b/ld/testsuite/ld-arm/fix-arm1176-off.d
> new file mode 100644
> index 0000000..3b45a3b
> --- /dev/null
> +++ b/ld/testsuite/ld-arm/fix-arm1176-off.d
> @@ -0,0 +1,17 @@
> +
> +.*:     file format elf32-littlearm
> +
> +
> +Disassembly of section .foo:
> +
> +[0-9a-f]+<_start>:
> + [0-9a-f]+:	f000 e800 	blx	2001018<__func_to_branch_to_veneer>
> +
> +[0-9a-f]+<__func_to_branch_to_veneer>:
> + [0-9a-f]+:	e51ff004 	ldr	pc, \[pc, #-4\]	; 200101c<__func_to_branch_to_veneer\+0x4>
> + [0-9a-f]+:	00008000 	.word	0x00008000
> +
> +Disassembly of section .text:
> +
> +[0-9a-f]+<func_to_branch_to>:
> +    [0-9a-f]+:	e12fff1e 	bx	lr
> diff --git a/ld/testsuite/ld-arm/fix-arm1176-on.d b/ld/testsuite/ld-arm/fix-arm1176-on.d
> new file mode 100644
> index 0000000..c4e7870
> --- /dev/null
> +++ b/ld/testsuite/ld-arm/fix-arm1176-on.d
> @@ -0,0 +1,20 @@
> +
> +.+:     file format elf32-littlearm
> +
> +
> +Disassembly of section .foo:
> +
> +[0-9a-f]+<_start>:
> + [0-9a-f]+:	f000 f800 	bl	2001018<__func_to_branch_to_veneer>
> +
> +[0-9a-f]+<__func_to_branch_to_veneer>:
> + [0-9a-f]+:	4778      	bx	pc
> + [0-9a-f]+:	46c0      	nop			; \(mov r8, r8\)
> + [0-9a-f]+:	e51ff004 	ldr	pc, \[pc, #-4\]	; 2001020<__func_to_branch_to_veneer\+0x8>
> + [0-9a-f]+:	00008000 	.word	0x00008000
> + [0-9a-f]+:	00000000 	.word	0x00000000
> +
> +Disassembly of section .text:
> +
> +[0-9a-f]+<func_to_branch_to>:
> +    [0-9a-f]+:	e12fff1e 	bx	lr
> diff --git a/ld/testsuite/ld-arm/fix-arm1176.s b/ld/testsuite/ld-arm/fix-arm1176.s
> new file mode 100644
> index 0000000..96e0328
> --- /dev/null
> +++ b/ld/testsuite/ld-arm/fix-arm1176.s
> @@ -0,0 +1,15 @@
> +	.syntax unified
> +	.globl _start
> +	.globl func_to_branch_to
> +
> +	.arm
> +	.text
> +func_to_branch_to:
> +	bx lr
> +
> +	.thumb
> +	.section .foo, "xa"
> +	.thumb_func
> +_start:
> +	bl func_to_branch_to
> +


-- 
Matthew Gretton-Dann
Principal Engineer, PD Software - Tools, ARM Ltd

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PING] [RFA/ARM]: Patch to workaround ARM1176 BLX (immediate) Thumb to ARM issue
  2011-08-08  9:52       ` [PING] " Matthew Gretton-Dann
@ 2011-08-09 12:17         ` Nick Clifton
  2011-08-09 13:15           ` Matthew Gretton-Dann
  0 siblings, 1 reply; 8+ messages in thread
From: Nick Clifton @ 2011-08-09 12:17 UTC (permalink / raw)
  To: Matthew Gretton-Dann; +Cc: binutils, Richard Earnshaw, Joseph S. Myers

Hi Matthew,

> Please can someone review this patch?

Sorry for the delay.

>> bfd/ChangeLog:
>> 2011-07-29 Matthew Gretton-Dann<matthew.gretton-dann@arm.com>
>>
>> * bfd-in.h (bfd_elf32_arm_set_target_relocs): Update prototype.
>> * bfd-in2.h (bfd_elf32_arm_set_target_relocs): Likewise.
>> * elf32-arm.c (elf32_arm_link_hash_table): New field.
>> (elf232_arm_link_hash_table_create): Initialise new field.
>> (check_use_blx): Change test depending on fix_arm1176.
>> (bfd_elf32_arm_set_target_relocs): Set fix_arm1176 from
>> command line options.
>>
>> ld/ChangeLog:
>> 2011-07-29 Matthew Gretton-Dann<matthew.gretton-dann@arm.com>
>>
>> * emultempl/armelf.em (fix_arm1176): New variable.
>> (arm_elf_create_output_section_statements): Pass
>> fix_arm1176 option to bfd backend.
>> (OPTION_FIX_ARM1176): New define.
>> (OPTION_NO_FIX_ARM1176): Likewise.
>> (PARSE_AND_LIST_LONGOPTS): Add new command line options.
>> (PARSE_AND_LIST_OPTIONS): Likewise.
>> (PARSE_AND_LIST_ARGS_CASES): Likewise.
>> * ld.texinfo: Document new command line options.
>>
>> ld/testsuite/ChangeLog:
>> 2011-07-29 Matthew Gretton-Dann<matthew.gretton-dann@arm.com>
>>
>> * ld-arm/arm-elf.exp (armelftests): Update for new command-line
>> options.
>> (armeabitests): Update for new command-line options, and add
>> new test cases.
>> * ld-arm/fix-arm1176.s: Add test case.
>> * ld-arm/fix-arm1176-off.d: Likewise.
>> * ld-arm/fix-arm1176-on.d: Likewise.

Approved - please apply.

But ...

>> +@cindex ARM1176 erratum workaround
>> +@kindex --fix-arm1176
>> +@kindex --no-fix-arm1176
>> +The @samp{--fix-arm1176} switch enables a link-time workaround for an
>> erratum
>> +in certain ARM1176 processors. The workaround is enabled by default
>> if you
>> +are targetting ARM v6 (excluding ARM v6T2) or earlier. It can be
>> disabled
>> +unconditionally by specifying @samp{--no-fix-arm1176}.
>> +
>> +Please contact ARM for further details.

It would be nice to include the URL to ARM's Erratum here.

Cheers
   Nick

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PING] [RFA/ARM]: Patch to workaround ARM1176 BLX (immediate) Thumb to ARM issue
  2011-08-09 12:17         ` Nick Clifton
@ 2011-08-09 13:15           ` Matthew Gretton-Dann
  0 siblings, 0 replies; 8+ messages in thread
From: Matthew Gretton-Dann @ 2011-08-09 13:15 UTC (permalink / raw)
  To: Nick Clifton; +Cc: binutils, Richard Earnshaw, Joseph S. Myers

[-- Attachment #1: Type: text/plain, Size: 2437 bytes --]

On 09/08/11 13:17, Nick Clifton wrote:
> Hi Matthew,
>
>> Please can someone review this patch?
>
> Sorry for the delay.
>
>>> bfd/ChangeLog:
>>> 2011-07-29 Matthew Gretton-Dann<matthew.gretton-dann@arm.com>
>>>
>>> * bfd-in.h (bfd_elf32_arm_set_target_relocs): Update prototype.
>>> * bfd-in2.h (bfd_elf32_arm_set_target_relocs): Likewise.
>>> * elf32-arm.c (elf32_arm_link_hash_table): New field.
>>> (elf232_arm_link_hash_table_create): Initialise new field.
>>> (check_use_blx): Change test depending on fix_arm1176.
>>> (bfd_elf32_arm_set_target_relocs): Set fix_arm1176 from
>>> command line options.
>>>
>>> ld/ChangeLog:
>>> 2011-07-29 Matthew Gretton-Dann<matthew.gretton-dann@arm.com>
>>>
>>> * emultempl/armelf.em (fix_arm1176): New variable.
>>> (arm_elf_create_output_section_statements): Pass
>>> fix_arm1176 option to bfd backend.
>>> (OPTION_FIX_ARM1176): New define.
>>> (OPTION_NO_FIX_ARM1176): Likewise.
>>> (PARSE_AND_LIST_LONGOPTS): Add new command line options.
>>> (PARSE_AND_LIST_OPTIONS): Likewise.
>>> (PARSE_AND_LIST_ARGS_CASES): Likewise.
>>> * ld.texinfo: Document new command line options.
>>>
>>> ld/testsuite/ChangeLog:
>>> 2011-07-29 Matthew Gretton-Dann<matthew.gretton-dann@arm.com>
>>>
>>> * ld-arm/arm-elf.exp (armelftests): Update for new command-line
>>> options.
>>> (armeabitests): Update for new command-line options, and add
>>> new test cases.
>>> * ld-arm/fix-arm1176.s: Add test case.
>>> * ld-arm/fix-arm1176-off.d: Likewise.
>>> * ld-arm/fix-arm1176-on.d: Likewise.
>
> Approved - please apply.
>
> But ...
>
>>> +@cindex ARM1176 erratum workaround
>>> +@kindex --fix-arm1176
>>> +@kindex --no-fix-arm1176
>>> +The @samp{--fix-arm1176} switch enables a link-time workaround for an
>>> erratum
>>> +in certain ARM1176 processors. The workaround is enabled by default
>>> if you
>>> +are targetting ARM v6 (excluding ARM v6T2) or earlier. It can be
>>> disabled
>>> +unconditionally by specifying @samp{--no-fix-arm1176}.
>>> +
>>> +Please contact ARM for further details.
>
> It would be nice to include the URL to ARM's Erratum here.

Committed with attached patch - which updates ld/ld.texinfo to provide 
directions to finding more details as suggested.  This is not a direct 
link as I cannot guarantee the URL will not move.

Thanks,

Matt

-- 
Matthew Gretton-Dann
Principal Engineer, PD Software - Tools, ARM Ltd

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: fix-arm1176.patch --]
[-- Type: text/x-patch; name=fix-arm1176.patch, Size: 17361 bytes --]

diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h
index 21b7cc2..f375d2f 100644
--- a/bfd/bfd-in.h
+++ b/bfd/bfd-in.h
@@ -869,7 +869,7 @@ extern bfd_boolean bfd_elf32_arm_process_before_allocation
 
 void bfd_elf32_arm_set_target_relocs
   (bfd *, struct bfd_link_info *, int, char *, int, int, bfd_arm_vfp11_fix,
-   int, int, int, int);
+   int, int, int, int, int);
 
 extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking
   (bfd *, struct bfd_link_info *);
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index af13ca4..63ffd95 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -876,7 +876,7 @@ extern bfd_boolean bfd_elf32_arm_process_before_allocation
 
 void bfd_elf32_arm_set_target_relocs
   (bfd *, struct bfd_link_info *, int, char *, int, int, bfd_arm_vfp11_fix,
-   int, int, int, int);
+   int, int, int, int, int);
 
 extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking
   (bfd *, struct bfd_link_info *);
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index 0ddd0cf..4d407a9 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -2776,6 +2776,9 @@ struct elf32_arm_link_hash_table
   /* Whether we should fix the Cortex-A8 Thumb-2 branch/TLB erratum.  */
   int fix_cortex_a8;
 
+  /* Whether we should fix the ARM1176 BLX immediate issue.  */
+  int fix_arm1176;
+
   /* Nonzero if the ARM/Thumb BLX instructions are available for use.  */
   int use_blx;
 
@@ -3315,6 +3318,7 @@ elf32_arm_link_hash_table_create (bfd *abfd)
   ret->vfp11_erratum_glue_size = 0;
   ret->num_vfp11_fixes = 0;
   ret->fix_cortex_a8 = 0;
+  ret->fix_arm1176 = 0;
   ret->bfd_of_glue_owner = NULL;
   ret->byteswap_code = 0;
   ret->target1_is_rel = 0;
@@ -5930,9 +5934,21 @@ bfd_elf32_arm_get_bfd_for_interworking (bfd *abfd, struct bfd_link_info *info)
 static void
 check_use_blx (struct elf32_arm_link_hash_table *globals)
 {
-  if (bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC,
-				Tag_CPU_arch) > 2)
-    globals->use_blx = 1;
+  int cpu_arch;
+
+  cpu_arch = bfd_elf_get_obj_attr_int (globals->obfd, OBJ_ATTR_PROC, 
+				       Tag_CPU_arch);
+
+  if (globals->fix_arm1176)
+    {
+      if (cpu_arch == TAG_CPU_ARCH_V6T2 || cpu_arch > TAG_CPU_ARCH_V6K)
+	globals->use_blx = 1;
+    }
+  else
+    {
+      if (cpu_arch > TAG_CPU_ARCH_V4T)
+	globals->use_blx = 1;
+    }
 }
 
 bfd_boolean
@@ -6786,7 +6802,8 @@ bfd_elf32_arm_set_target_relocs (struct bfd *output_bfd,
 				 int use_blx,
                                  bfd_arm_vfp11_fix vfp11_fix,
 				 int no_enum_warn, int no_wchar_warn,
-				 int pic_veneer, int fix_cortex_a8)
+				 int pic_veneer, int fix_cortex_a8,
+				 int fix_arm1176)
 {
   struct elf32_arm_link_hash_table *globals;
 
@@ -6811,6 +6828,7 @@ bfd_elf32_arm_set_target_relocs (struct bfd *output_bfd,
   globals->vfp11_fix = vfp11_fix;
   globals->pic_veneer = pic_veneer;
   globals->fix_cortex_a8 = fix_cortex_a8;
+  globals->fix_arm1176 = fix_arm1176;
 
   BFD_ASSERT (is_arm_elf (output_bfd));
   elf_arm_tdata (output_bfd)->no_enum_size_warning = no_enum_warn;
diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em
index 948bf8d..d29da59 100644
--- a/ld/emultempl/armelf.em
+++ b/ld/emultempl/armelf.em
@@ -42,6 +42,7 @@ static int no_enum_size_warning = 0;
 static int no_wchar_size_warning = 0;
 static int pic_veneer = 0;
 static int merge_exidx_entries = -1;
+static int fix_arm1176 = 1;
 
 static void
 gld${EMULATION_NAME}_before_parse (void)
@@ -464,7 +465,8 @@ arm_elf_create_output_section_statements (void)
 				   target2_type, fix_v4bx, use_blx,
 				   vfp11_denorm_fix, no_enum_size_warning,
 				   no_wchar_size_warning,
-				   pic_veneer, fix_cortex_a8);
+				   pic_veneer, fix_cortex_a8, 
+				   fix_arm1176);
 
   stub_file = lang_add_input_file ("linker stubs",
  				   lang_input_file_is_fake_enum,
@@ -529,6 +531,8 @@ PARSE_AND_LIST_PROLOGUE='
 #define OPTION_FIX_CORTEX_A8		314
 #define OPTION_NO_FIX_CORTEX_A8		315
 #define OPTION_NO_MERGE_EXIDX_ENTRIES   316
+#define OPTION_FIX_ARM1176		317
+#define OPTION_NO_FIX_ARM1176		318
 '
 
 PARSE_AND_LIST_SHORTOPTS=p
@@ -551,6 +555,8 @@ PARSE_AND_LIST_LONGOPTS='
   { "fix-cortex-a8", no_argument, NULL, OPTION_FIX_CORTEX_A8 },
   { "no-fix-cortex-a8", no_argument, NULL, OPTION_NO_FIX_CORTEX_A8 },
   { "no-merge-exidx-entries", no_argument, NULL, OPTION_NO_MERGE_EXIDX_ENTRIES },
+  { "fix-arm1176", no_argument, NULL, OPTION_FIX_ARM1176 },
+  { "no-fix-arm1176", no_argument, NULL, OPTION_NO_FIX_ARM1176 },
 '
 
 PARSE_AND_LIST_OPTIONS='
@@ -579,7 +585,7 @@ PARSE_AND_LIST_OPTIONS='
  		   ));
   fprintf (file, _("  --[no-]fix-cortex-a8        Disable/enable Cortex-A8 Thumb-2 branch erratum fix\n"));
   fprintf (file, _("  --no-merge-exidx-entries    Disable merging exidx entries\n"));
- 
+  fprintf (file, _("  --[no-]fix-arm1176          Disable/enable ARM1176 BLX immediate erratum fix\n"));
 '
 
 PARSE_AND_LIST_ARGS_CASES='
@@ -662,7 +668,15 @@ PARSE_AND_LIST_ARGS_CASES='
 
    case OPTION_NO_MERGE_EXIDX_ENTRIES:
       merge_exidx_entries = 0;
+      break;
 
+   case OPTION_FIX_ARM1176:
+      fix_arm1176 = 1;
+      break;
+
+   case OPTION_NO_FIX_ARM1176:
+      fix_arm1176 = 0;
+      break;
 '
 
 # We have our own before_allocation etc. functions, but they call
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index 7547c0a..94079e2 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -6321,6 +6321,18 @@ instruction. The original instruction is then replaced with a branch to
 the veneer. The extra cycles required to call and return from the veneer
 are sufficient to avoid the erratum in both the scalar and vector cases.
 
+@cindex ARM1176 erratum workaround
+@kindex --fix-arm1176
+@kindex --no-fix-arm1176
+The @samp{--fix-arm1176} switch enables a link-time workaround for an erratum 
+in certain ARM1176 processors.  The workaround is enabled by default if you 
+are targetting ARM v6 (excluding ARM v6T2) or earlier.  It can be disabled 
+unconditionally by specifying @samp{--no-fix-arm1176}.
+
+Further information is available in the ``ARM1176JZ-S and ARM1176JZF-S 
+Programmer Advice Notice'' available on the ARM documentaion website at:
+http://infocenter.arm.com/.
+
 @cindex NO_ENUM_SIZE_WARNING
 @kindex --no-enum-size-warning
 The @option{--no-enum-size-warning} switch prevents the linker from
diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp
index 8b8495e..fbdfadd 100644
--- a/ld/testsuite/ld-arm/arm-elf.exp
+++ b/ld/testsuite/ld-arm/arm-elf.exp
@@ -137,7 +137,7 @@ set armelftests {
     {"arm-rel32" "-shared -T arm-dyn.ld" "" {arm-rel32.s}
      {{objdump -Rsj.data arm-rel32.d}}
      "arm-rel32"}
-    {"arm-call" "-static -T arm.ld" "-meabi=4" {arm-call1.s arm-call2.s}
+    {"arm-call" "--no-fix-arm1176 -static -T arm.ld" "-meabi=4" {arm-call1.s arm-call2.s}
      {{objdump -d arm-call.d}}
      "arm-call"}
     {"TLS shared library" "-shared -T arm-lib.ld" "" {tls-lib.s}
@@ -149,16 +149,16 @@ set armelftests {
     {"TLS gnu shared library got" "-shared -T arm-dyn.ld" "" {tls-gdesc-got.s}
      {{objdump "-fDR -j .got" tls-gdesc-got.d}}
      "tls-lib2-got.so"}
-    {"TLS gnu shared library inlined trampoline" "-shared -T arm-dyn.ld" "" {tls-descseq.s}
+    {"TLS gnu shared library inlined trampoline" "--no-fix-arm1176 -shared -T arm-dyn.ld" "" {tls-descseq.s}
      {{objdump -fdw tls-descseq.d} {objdump -Rw tls-descseq.r}}
      "tls-lib2inline.so"}
-    {"TLS shared library gdesc local" "-shared -T arm-dyn.ld" "" {tls-lib-loc.s}
+    {"TLS shared library gdesc local" "--no-fix-arm1176 -shared -T arm-dyn.ld" "" {tls-lib-loc.s}
      {{objdump -fdw tls-lib-loc.d} {objdump -Rw tls-lib-loc.r}}
      "tls-lib-loc.so"}
     {"TLS gnu GD to IE relaxation" "-static -T arm-dyn.ld" "" {tls-gdierelax.s}
      {{objdump -fdw tls-gdierelax.d}}
      "tls-app-rel-ie"}
-    {"TLS gnu GD to IE shared relaxation" "-shared -T arm-dyn.ld" "" {tls-gdierelax2.s}
+    {"TLS gnu GD to IE shared relaxation" "--no-fix-arm1176 -shared -T arm-dyn.ld" "" {tls-gdierelax2.s}
      {{objdump -fdw tls-gdierelax2.d}}
      "tls-app-rel-ie2"}
     {"TLS gnu GD to LE relaxation" "-T arm-dyn.ld" "" {tls-gdlerelax.s}
@@ -507,7 +507,7 @@ set armeabitests {
     {"MOVW/MOVT against shared libraries" "tmpdir/arm-lib.so" "" {arm-app-movw.s}
      {{objdump -Rw arm-app.r}}
      "arm-app-movw"}
-    {"Thumb-2-as-Thumb-1 BL" "-Ttext 0x1000 --section-start .foo=0x100100c" "" {thumb2-bl-as-thumb1-bad.s}
+    {"Thumb-2-as-Thumb-1 BL" "--no-fix-arm1176 -Ttext 0x1000 --section-start .foo=0x100100c" "" {thumb2-bl-as-thumb1-bad.s}
      {{objdump -d thumb2-bl-as-thumb1-bad.d}}
      "thumb2-bl-as-thumb1-bad"}
     {"Thumb-2 BL" "-Ttext 0x1000 --section-start .foo=0x100100c" "" {thumb2-bl-bad.s}
@@ -530,7 +530,7 @@ set armeabitests {
     {"ARM-Thumb farcall" "-Ttext 0x1000 --section-start .foo=0x2001014" "" {farcall-arm-thumb.s}
      {{objdump -d farcall-arm-thumb.d}}
      "farcall-arm-thumb"}
-    {"ARM-Thumb farcall with BLX" "-Ttext 0x1000 --section-start .foo=0x2001014" "-march=armv5t" {farcall-arm-thumb.s}
+    {"ARM-Thumb farcall with BLX" "--no-fix-arm1176 -Ttext 0x1000 --section-start .foo=0x2001014" "-march=armv5t" {farcall-arm-thumb.s}
      {{objdump -d farcall-arm-thumb-blx.d}}
      "farcall-arm-thumb-blx"}
     {"ARM-Thumb farcall (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "" {farcall-arm-thumb.s}
@@ -540,7 +540,7 @@ set armeabitests {
      {{objdump -d farcall-arm-thumb-blx-pic-veneer.d}}
      "farcall-arm-thumb-blx-pic-veneer"}
 
-    {"Thumb-Thumb farcall with BLX" "-Ttext 0x1000 --section-start .foo=0x2001014" "-march=armv5t" {farcall-thumb-thumb.s}
+    {"Thumb-Thumb farcall with BLX" "--no-fix-arm1176 -Ttext 0x1000 --section-start .foo=0x2001014" "-march=armv5t" {farcall-thumb-thumb.s}
      {{objdump -d farcall-thumb-thumb-blx.d}}
      "farcall-thumb-thumb-blx"}
     {"Thumb-Thumb farcall M profile" "-Ttext 0x1000 --section-start .foo=0x2001014" "-march=armv7-m" {farcall-thumb-thumb.s}
@@ -552,7 +552,7 @@ set armeabitests {
     {"Thumb-Thumb farcall" "-Ttext 0x1000 --section-start .foo=0x2001014" "-march=armv4t" {farcall-thumb-thumb.s}
      {{objdump -d farcall-thumb-thumb.d}}
      "farcall-thumb-thumb"}
-    {"Thumb-Thumb farcall with BLX (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-march=armv5t" {farcall-thumb-thumb.s}
+    {"Thumb-Thumb farcall with BLX (PIC veneer)" "--no-fix-arm1176 -Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-march=armv5t" {farcall-thumb-thumb.s}
      {{objdump -d farcall-thumb-thumb-blx-pic-veneer.d}}
      "farcall-thumb-thumb-blx-pic-veneer"}
     {"Thumb-Thumb farcall M profile (PIC veneer)" "-Ttext 0x1000 --section-start .foo=0x2001014 --pic-veneer" "-march=armv7-m" {farcall-thumb-thumb.s}
@@ -574,10 +574,10 @@ set armeabitests {
     {"Thumb-ARM (short) call" "-Ttext 0x1000 --section-start .foo=0x0002014" "-W" {farcall-thumb-arm-short.s}
      {{objdump -d farcall-thumb-arm-short.d}}
      "farcall-thumb-arm-short"}
-    {"Thumb-ARM farcall with BLX" "-Ttext 0x1c01010 --section-start .foo=0x2001014" "-W -march=armv5t" {farcall-thumb-arm.s}
+    {"Thumb-ARM farcall with BLX" "--no-fix-arm1176 -Ttext 0x1c01010 --section-start .foo=0x2001014" "-W -march=armv5t" {farcall-thumb-arm.s}
      {{objdump -d farcall-thumb-arm-blx.d}}
      "farcall-thumb-arm-blx"}
-    {"Thumb-ARM farcall with BLX (PIC veneer)" "-Ttext 0x1c01010 --section-start .foo=0x2001014 --pic-veneer" "-W -march=armv5t" {farcall-thumb-arm.s}
+    {"Thumb-ARM farcall with BLX (PIC veneer)" "--no-fix-arm1176 -Ttext 0x1c01010 --section-start .foo=0x2001014 --pic-veneer" "-W -march=armv5t" {farcall-thumb-arm.s}
      {{objdump -d farcall-thumb-arm-blx-pic-veneer.d}}
      "farcall-thumb-arm-blx-pic-veneer"}
     {"Thumb-ARM farcall (PIC veneer)" "-Ttext 0x1c01010 --section-start .foo=0x2001014 --pic-veneer" "-W" {farcall-thumb-arm.s}
@@ -617,7 +617,7 @@ set armeabitests {
      {{objdump -fdw farcall-mixed-lib-v4t.d}}
      "farcall-mixed-lib.so"}
 
-    {"Mixed ARM/Thumb shared library with long branches (v5t)" "-shared -T arm-lib.ld" "-march=armv5t"
+    {"Mixed ARM/Thumb shared library with long branches (v5t)" "--no-fix-arm1176 -shared -T arm-lib.ld" "-march=armv5t"
      {farcall-mixed-lib1.s farcall-mixed-lib2.s}
      {{objdump -fdw farcall-mixed-lib.d}}
      "farcall-mixed-lib.so"}
@@ -627,24 +627,24 @@ set armeabitests {
      "farcall-data"}
 
     {"R_ARM_THM_JUMP24 Relocation veneers: Short 1" 
-     "--section-start destsect=0x00009000 --section-start .text=0x8000" 
+     "--no-fix-arm1176 --section-start destsect=0x00009000 --section-start .text=0x8000" 
      "-march=armv7-a -mthumb" 
      {jump-reloc-veneers.s}
      {{objdump -d jump-reloc-veneers-short1.d}}
      "jump-reloc-veneers-short1"}
     {"R_ARM_THM_JUMP24 Relocation veneers: Short 2" 
-     "--section-start destsect=0x00900000 --section-start .text=0x8000" 
+     "--no-fix-arm1176 --section-start destsect=0x00900000 --section-start .text=0x8000" 
      "-march=armv7-a -mthumb" 
      {jump-reloc-veneers.s}
      {{objdump -d jump-reloc-veneers-short2.d}}
      "jump-reloc-veneers-short2"}
     {"R_ARM_THM_JUMP24 Relocation veneers: Long" 
-     "--section-start destsect=0x09000000 --section-start .text=0x8000" 
+     "--no-fix-arm1176 --section-start destsect=0x09000000 --section-start .text=0x8000" 
      "-march=armv7-a -mthumb" 
      {jump-reloc-veneers.s}
      {{objdump -d jump-reloc-veneers-long.d}}
      "jump-reloc-veneers-long"}
-    {"TLS gnu shared library" "-shared -T arm-dyn.ld" "" {tls-gdesc.s}
+    {"TLS gnu shared library" "--no-fix-arm1176 -shared -T arm-dyn.ld" "" {tls-gdesc.s}
      {{objdump -fdw tls-gdesc.d} {objdump -Rw tls-gdesc.r}}
      "tls-lib2.so"}
     {"TLS gnu shared library non-lazy" "-z now -shared -T arm-dyn.ld" "" {tls-gdesc.s}
@@ -659,6 +659,31 @@ set armeabitests {
     {"TLS thumb1" "-shared -T arm-dyn.ld --section-start .foo=0x4001000" "" {tls-thumb1.s}
      {{objdump -fdw tls-thumb1.d}}
      "tls-thumb1"}
+
+    {"erratum 760522 fix (default for v6z)" "--section-start=.foo=0x2001014" 
+     "-march=armv6z" {fix-arm1176.s}
+     {{objdump -d fix-arm1176-on.d}}
+     "fix-arm1176-1"}
+    {"erratum 760522 fix (explicitly on at v6z)" "--section-start=.foo=0x2001014 --fix-arm1176" 
+     "-march=armv6z" {fix-arm1176.s}
+     {{objdump -d fix-arm1176-on.d}}
+     "fix-arm1176-2"}
+    {"erratum 760522 fix (explicitly off at v6z)" "--section-start=.foo=0x2001014 --no-fix-arm1176" 
+     "-march=armv6z" {fix-arm1176.s}
+     {{objdump -d fix-arm1176-off.d}}
+     "fix-arm1176-3"}
+    {"erratum 760522 fix (default for v5)" "--section-start=.foo=0x2001014 " 
+     "-march=armv5te" {fix-arm1176.s}
+     {{objdump -d fix-arm1176-on.d}}
+     "fix-arm1176-4"}
+    {"erratum 760522 fix (default for v7-a)" "--section-start=.foo=0x2001014 " 
+     "-march=armv7-a" {fix-arm1176.s}
+     {{objdump -d fix-arm1176-off.d}}
+     "fix-arm1176-5"}
+    {"erratum 760522 fix (default for ARM1156)" "--section-start=.foo=0x2001014 " 
+     "-mcpu=arm1156t2f-s" {fix-arm1176.s}
+     {{objdump -d fix-arm1176-off.d}}
+     "fix-arm1176-6"}
 }
 
 run_ld_link_tests $armeabitests
diff --git a/ld/testsuite/ld-arm/fix-arm1176-off.d b/ld/testsuite/ld-arm/fix-arm1176-off.d
new file mode 100644
index 0000000..3b45a3b
--- /dev/null
+++ b/ld/testsuite/ld-arm/fix-arm1176-off.d
@@ -0,0 +1,17 @@
+
+.*:     file format elf32-littlearm
+
+
+Disassembly of section .foo:
+
+[0-9a-f]+ <_start>:
+ [0-9a-f]+:	f000 e800 	blx	2001018 <__func_to_branch_to_veneer>
+
+[0-9a-f]+ <__func_to_branch_to_veneer>:
+ [0-9a-f]+:	e51ff004 	ldr	pc, \[pc, #-4\]	; 200101c <__func_to_branch_to_veneer\+0x4>
+ [0-9a-f]+:	00008000 	.word	0x00008000
+
+Disassembly of section .text:
+
+[0-9a-f]+ <func_to_branch_to>:
+    [0-9a-f]+:	e12fff1e 	bx	lr
diff --git a/ld/testsuite/ld-arm/fix-arm1176-on.d b/ld/testsuite/ld-arm/fix-arm1176-on.d
new file mode 100644
index 0000000..c4e7870
--- /dev/null
+++ b/ld/testsuite/ld-arm/fix-arm1176-on.d
@@ -0,0 +1,20 @@
+
+.+:     file format elf32-littlearm
+
+
+Disassembly of section .foo:
+
+[0-9a-f]+ <_start>:
+ [0-9a-f]+:	f000 f800 	bl	2001018 <__func_to_branch_to_veneer>
+
+[0-9a-f]+ <__func_to_branch_to_veneer>:
+ [0-9a-f]+:	4778      	bx	pc
+ [0-9a-f]+:	46c0      	nop			; \(mov r8, r8\)
+ [0-9a-f]+:	e51ff004 	ldr	pc, \[pc, #-4\]	; 2001020 <__func_to_branch_to_veneer\+0x8>
+ [0-9a-f]+:	00008000 	.word	0x00008000
+ [0-9a-f]+:	00000000 	.word	0x00000000
+
+Disassembly of section .text:
+
+[0-9a-f]+ <func_to_branch_to>:
+    [0-9a-f]+:	e12fff1e 	bx	lr
diff --git a/ld/testsuite/ld-arm/fix-arm1176.s b/ld/testsuite/ld-arm/fix-arm1176.s
new file mode 100644
index 0000000..96e0328
--- /dev/null
+++ b/ld/testsuite/ld-arm/fix-arm1176.s
@@ -0,0 +1,15 @@
+	.syntax unified
+	.globl _start
+	.globl func_to_branch_to
+
+	.arm
+	.text
+func_to_branch_to:
+	bx lr
+
+	.thumb
+	.section .foo, "xa"
+	.thumb_func
+_start:
+	bl func_to_branch_to
+

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2011-08-09 13:15 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-07-27 16:29 [RFA/ARM]: Patch to workaround ARM1176 BLX (immediate) Thumb to ARM issue Matthew Gretton-Dann
2011-07-27 16:44 ` Joseph S. Myers
2011-07-28 16:41 ` Nick Clifton
2011-07-28 21:33   ` Matthew Gretton-Dann
2011-07-29 13:34     ` Matthew Gretton-Dann
2011-08-08  9:52       ` [PING] " Matthew Gretton-Dann
2011-08-09 12:17         ` Nick Clifton
2011-08-09 13:15           ` Matthew Gretton-Dann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).