This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


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

Re: [PATCH, ARM] Work around Cortex-A8 erratum in linker


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.


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