This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH, ARM] Work around Cortex-A8 erratum in linker
- From: Richard Earnshaw <rearnsha at arm dot com>
- To: Julian Brown <julian at codesourcery dot com>
- Cc: binutils at sourceware dot org
- Date: Thu, 21 May 2009 15:46:19 +0100
- Subject: Re: [PATCH, ARM] Work around Cortex-A8 erratum in linker
- References: <20090519170626.2bad6189@rex.config>
On Tue, 2009-05-19 at 17:06 +0100, Julian Brown wrote:
> Hi,
>
> This patch contains a workaround for an erratum in ARM Cortex-A8
> processors. The (position-dependent) nature of the erratum is such that
> it is necessary to interoperate with the relaxation pass performed at
> the end of linking which inserts long branch/interworking stubs.
>
> The erratum (657417: A 32-bit branch instruction that spans two 4K
> regions can result in an incorrect operation) affects only Thumb-2
> code. The method used to work around the problem is to insert a stub
> (in a different page) and branch to that, then have the stub jump back
> to the original destination.
>
> The workaround is enabled by default if the link targets the ARMv7 (-A
> or unspecified) architecture. It can be enabled otherwise by passing
> --fix-cortex-a8 to the linker, or disabled unconditionally by passing
> --no-fix-cortex-a8.
>
> Tested with cross to arm-linux-gnueabi, with new test cases. OK to
> apply?
>
> Thanks,
>
> Julian
>
> ChangeLog
>
> ld/
> * emultempl/armelf.em (fix_cortex_a8): New.
> (arm_elf_before_allocation): Call bfd_elf32_arm_set_cortex_a8_fix.
> (arm_elf_create_output_section_statements): Add fix_cortex_a8 to
> bfd_elf32_arm_set_target_relocs.
> (OPTION_FIX_CORTEX_A8, OPTION_NO_FIX_CORTEX_A8): New.
> (PARSE_AND_LIST_LONGOPTS): Add [no-]fix-cortex-a8 options.
> (PARSE_AND_LIST_OPTIONS): Add [no-]fix-cortex-a8 options.
> (PARSE_AND_LIST_ARGS_CASES): Handle OPTION_[NO_]FIX_CORTEX_A8.
> * ld.texinfo (--[no-]fix-cortex-a8): Briefly document new options.
>
> bfd/
> * elf32-arm.c (THUMB16_BCOND_INSN, THUMB32_INSN, THUMB32_B_INSN):
> New macros.
> (elf32_arm_stub_a8_veneer_b_cond, elf32_arm_stub_a8_veneer_b)
> (elf32_arm_stub_a8_veneer_blx): New stub sequences.
> (elf32_arm_stub_type): Add arm_stub_a8_veneer_b_cond,
> arm_stub_a8_veneer_b and arm_stub_a8_veneer_blx.
> (elf32_arm_stub_hash_entry): Add target_addend, orig_insn fields.
> (a8_erratum_fix, a8_erratum_reloc): New structs.
> (elf32_arm_link_hash_table): Add a8_erratum_fixes,
> num_a8_erratum_fixes, fix_cortex_a8 fields.
> (elf32_arm_link_hash_table_create): Zero fix_cortex_a8.
> (elf32_arm_add_stub): Split into two parts, creating...
> (elf32_arm_create_or_find_stub_sec): New function.
> (elf32_arm_final_link_relocate): Add forward declaration.
> (arm_build_one_stub): Add support for THUMB32_TYPE, Thumb-2
> relocations, multiple relocations per stub.
> (find_stub_size_and_template): New (using parts of
> arm_size_one_stub).
> (arm_size_one_stub): Use find_stub_size_and_template.
> (a8_reloc_compare): New.
> (find_thumb_glue): Add forward declaration.
> (cortex_a8_erratum_scan): New.
> (elf32_arm_size_stubs): Add Cortex-A8 erratum workaround support.
> (bfd_elf32_arm_set_cortex_a8_fix): New.
> (bfd_elf32_arm_set_target_relocs): Add fix_cortex_a8 argument.
> (arm_map_one_stub): Add THUMB32_TYPE support.
> (a8_branch_to_stub_data): New.
> (make_branch_to_a8_stub): New.
> (elf32_arm_write_section): Add Cortex-A8 erratum workaround support.
> * bfd-in.h (bfd_elf32_arm_set_cortex_a8_fix): New.
> (bfd_elf32_arm_set_target_relocs): Add argument for controlling
> Cortex-A8 erratum workaround.
> * bfd-in2.h: Regenerate.
>
> ld/testsuite/
> * ld-arm/cortex-a8-arm-target.s: New.
> * ld-arm/cortex-a8-thumb-target.s: New.
> * ld-arm/cortex-a8-fix-b-rel.s: New.
> * ld-arm/cortex-a8-fix-b-rel-arm.d: New.
> * ld-arm/cortex-a8-fix-b-rel-thumb.d: New.
> * ld-arm/cortex-a8-fix-b.s: New.
> * ld-arm/cortex-a8-fix-b.d: New.
> * ld-arm/cortex-a8-fix-bl-rel.s: New.
> * ld-arm/cortex-a8-fix-bl-rel-arm.d: New.
> * ld-arm/cortex-a8-fix-bl-rel-thumb.d: New.
> * ld-arm/cortex-a8-fix-bl.s: New.
> * ld-arm/cortex-a8-fix-bl.d: New.
> * ld-arm/cortex-a8-fix-bcc-rel.s: New.
> * ld-arm/cortex-a8-fix-bcc-rel-thumb.d: New.
> * ld-arm/cortex-a8-fix-bcc.s: New.
> * ld-arm/cortex-a8-fix-bcc.d: New.
> * ld-arm/cortex-a8-fix-blx-rel.s: New.
> * ld-arm/cortex-a8-fix-blx-rel-arm.d: New.
> * ld-arm/cortex-a8-fix-blx-rel-thumb.d: New.
> * ld-arm/cortex-a8-fix-blx.s: New.
> * ld-arm/cortex-a8-fix-blx.d: New.
> * ld-arm/arm-elf.exp: Add new tests.
OK.
For the record, I think I can identify a way of constructing a
potentially failing example that the fixer won't catch, but it involves
a fairly high degree of ingenuity and is unlikely to occur in real code.
R.