summaryrefslogtreecommitdiffstats
path: root/binutils-2.25/ld
diff options
context:
space:
mode:
authorMarcus Shawcroft <marcus.shawcroft@arm.com>2015-03-30 18:06:22 -0700
committerAndrew Hsieh <andrewhsieh@google.com>2015-03-30 21:39:14 -0700
commita9dedea652b5198bebf99d646ffa6b698f1980e5 (patch)
treeb4fdc548b28f096c8882644d16f244c4cfb04101 /binutils-2.25/ld
parent15c4812b1a1343236166916189c7159be84a5327 (diff)
downloadtoolchain_binutils-a9dedea652b5198bebf99d646ffa6b698f1980e5.tar.gz
toolchain_binutils-a9dedea652b5198bebf99d646ffa6b698f1980e5.tar.bz2
toolchain_binutils-a9dedea652b5198bebf99d646ffa6b698f1980e5.zip
[AArch64] Workaround for cortex-a53 erratum 843419
Some early revisions of the Cortex-A53 have an erratum (843419). The details of the erratum are quite complex and involve dynamic conditions. For the purposes of the workaround we have simplified the static conditions to an ADRP in the last two instructions of a 4KByte page, followed within four instructions by a load/store dependent on the ADRP. This patch adds support to conservatively scan for and workaround the erratum. There are two different workaround strategies used. The first is to rewrite ADRP instructions which form part of an erratum sequence with an ADR instruction. In situations where the ADR provides insufficient offset the dependent load or store instruction from the sequence is moved to a stub section and branches are inserted from the original sequence to the relocated instruction and back again. Stub section sizes are rounded up to a multiple of 4096 in order to ensure that the act of inserting work around stubs does not create more errata sequences. Workaround stubs are always inserted into the stub section associated with the input section containing the erratum sequence. This ensures that the fully relocated form of the veneered load store instruction is available at the point in time when the stub section is written. 2015-03-30 Tejas Belagod <tejas.belagod@arm.com> Marcus Shawcroft <marcus.shawcroft@arm.com> Jiong Wang <jiong.wang@arm.com> * bfd-in.h (bfd_elf64_aarch64_set_options) (bfd_elf32_aarch64_set_options): Add parameter. * bfd-in2.h: Regenerated. * elfnn-aarch64.c (aarch64_erratum_843419_stub) (_bfd_aarch64_adrp_p, _bfd_aarch64_erratum_843419_sequence_p) (_bfd_aarch64_erratum_843419_stub_name) (_bfd_aarch64_erratum_843419_fixup) (_bfd_aarch64_erratum_843419_scan) (_bfd_aarch64_erratum_843419_branch_to_stub) (_bfd_aarch64_erratum_843419_p): Define. (enum elf_aarch64_stub_type): Define aarch64_stub_erratum_843419_veneer. (struct elf_aarch64_stub_hash_entry): Define adrp_offset. (struct elf_aarch64_link_hash_table): Define fix_erratum_843419 and fix_erratum_843419_adr. (stub_hash_newfunc): Initialize adrp_offset; (_bfd_aarch64_add_stub_entry_after): Define. (aarch64_map_one_stub, aarch64_build_one_stub) (aarch64_size_one_stub): Handle aarch64_stub_erratum_843419_veneer. (_bfd_aarch64_resize_stubs): Round stub section size. (elfNN_aarch64_size_stubs): Add scan for 843419. (bfd_elfNN_aarch64_set_options): Add parameter. Initialize fix_erratum_843419 and fix_erratum_843419_adr. (struct erratum_835769_branch_to_stub_data): Add info. (elfNN_aarch64_write_section): Initialise info. Handle 843419. (elfNN_aarch64_size_dynamic_sections): Handle 843419. * elfxx-aarch64.c (_bfd_aarch64_decode_adrp_imm) (_bfd_aarch64_sign_extend): Define. (reencode_adr_imm): Remove static. Rename to: (_bfd_aarch64_reencode_adr_imm): Define. (_bfd_aarch64_elf_put_addend): Call _bfd_aarch64_reencode_adr_imm. * elfxx-aarch64.h (AARCH64_ADR_OP, AARCH64_ADRP_OP) (AARCH64_ADRP_OP_MASK, _bfd_aarch64_sign_extend) (_bfd_aarch64_decode_adrp_imm, _bfd_aarch64_reencode_adr_imm): Define. ld/testsuite: 2015-03-24 Tejas Belagod <tejas.belagod@arm.com> * emultempl/aarch64elf.em (aarch64_elf_create_output_section_statements): Add parameter in bfd_elf${ELFSIZE}_aarch64_set_options call. (OPTION_FIX_ERRATUM_843419): Define. (PARSE_AND_LIST_LONGOPTS): Add fix-cortex-a53-843419. (PARSE_AND_LIST_ARGS_CASES): Add OPTION_FIX_ERRATUM_843419. Change-Id: I758b04c90d431f4e72a978871d5a66676c413d92
Diffstat (limited to 'binutils-2.25/ld')
-rw-r--r--binutils-2.25/ld/emultempl/aarch64elf.em11
-rw-r--r--binutils-2.25/ld/testsuite/ld-aarch64/aarch64-elf.exp1
-rw-r--r--binutils-2.25/ld/testsuite/ld-aarch64/erratum843419.d69
-rw-r--r--binutils-2.25/ld/testsuite/ld-aarch64/erratum843419.s84
4 files changed, 164 insertions, 1 deletions
diff --git a/binutils-2.25/ld/emultempl/aarch64elf.em b/binutils-2.25/ld/emultempl/aarch64elf.em
index 8572e5e5..a573a8d7 100644
--- a/binutils-2.25/ld/emultempl/aarch64elf.em
+++ b/binutils-2.25/ld/emultempl/aarch64elf.em
@@ -31,6 +31,7 @@ static int no_enum_size_warning = 0;
static int no_wchar_size_warning = 0;
static int pic_veneer = 0;
static int fix_erratum_835769 = 0;
+static int fix_erratum_843419 = 0;
static void
gld${EMULATION_NAME}_before_parse (void)
@@ -303,7 +304,8 @@ aarch64_elf_create_output_section_statements (void)
bfd_elf${ELFSIZE}_aarch64_set_options (link_info.output_bfd, &link_info,
no_enum_size_warning,
no_wchar_size_warning,
- pic_veneer, fix_erratum_835769);
+ pic_veneer,
+ fix_erratum_835769, fix_erratum_843419);
stub_file = lang_add_input_file ("linker stubs",
lang_input_file_is_fake_enum,
@@ -353,6 +355,7 @@ PARSE_AND_LIST_PROLOGUE='
#define OPTION_STUBGROUP_SIZE 311
#define OPTION_NO_WCHAR_SIZE_WARNING 312
#define OPTION_FIX_ERRATUM_835769 313
+#define OPTION_FIX_ERRATUM_843419 314
'
PARSE_AND_LIST_SHORTOPTS=p
@@ -364,6 +367,7 @@ PARSE_AND_LIST_LONGOPTS='
{ "stub-group-size", required_argument, NULL, OPTION_STUBGROUP_SIZE },
{ "no-wchar-size-warning", no_argument, NULL, OPTION_NO_WCHAR_SIZE_WARNING},
{ "fix-cortex-a53-835769", no_argument, NULL, OPTION_FIX_ERRATUM_835769},
+ { "fix-cortex-a53-843419", no_argument, NULL, OPTION_FIX_ERRATUM_843419},
'
PARSE_AND_LIST_OPTIONS='
@@ -382,6 +386,7 @@ PARSE_AND_LIST_OPTIONS='
the linker should choose suitable defaults.\n"
));
fprintf (file, _(" --fix-cortex-a53-835769 Fix erratum 835769\n"));
+ fprintf (file, _(" --fix-cortex-a53-843419 Fix erratum 843419\n"));
'
PARSE_AND_LIST_ARGS_CASES='
@@ -405,6 +410,10 @@ PARSE_AND_LIST_ARGS_CASES='
fix_erratum_835769 = 1;
break;
+ case OPTION_FIX_ERRATUM_843419:
+ fix_erratum_843419 = 1;
+ break;
+
case OPTION_STUBGROUP_SIZE:
{
const char *end;
diff --git a/binutils-2.25/ld/testsuite/ld-aarch64/aarch64-elf.exp b/binutils-2.25/ld/testsuite/ld-aarch64/aarch64-elf.exp
index a75e0703..d0f557d6 100644
--- a/binutils-2.25/ld/testsuite/ld-aarch64/aarch64-elf.exp
+++ b/binutils-2.25/ld/testsuite/ld-aarch64/aarch64-elf.exp
@@ -46,6 +46,7 @@ set aarch64elftests {
}
run_ld_link_tests $aarch64elftests
+run_dump_test "erratum843419"
# Relocation Tests
run_dump_test "weak-undefined"
diff --git a/binutils-2.25/ld/testsuite/ld-aarch64/erratum843419.d b/binutils-2.25/ld/testsuite/ld-aarch64/erratum843419.d
new file mode 100644
index 00000000..4be8f9e5
--- /dev/null
+++ b/binutils-2.25/ld/testsuite/ld-aarch64/erratum843419.d
@@ -0,0 +1,69 @@
+#source: erratum843419.s
+#as:
+#ld: --fix-cortex-a53-835769 --fix-cortex-a53-843419 -e0 --section-start .e843419=0x20000000 --section-start .e835769=0x3000000 -Ttext=0x400000 -Tdata=0x40000000
+#objdump: -dr
+#...
+
+Disassembly of section .e843419:
+
+0000000020000000 <e843419>:
+ 20000000: d10043ff sub sp, sp, #0x10
+ 20000004: d28001a7 mov x7, #0xd // #13
+ 20000008: b9000fe7 str w7, \[sp,#12\]
+ 2000000c: 140003fb b 20000ff8 <e843419_1>
+ ...
+
+0000000020000ff8 <e843419_1>:
+ 20000ff8: 90100000 adrp x0, 40000000 <[_a-zA-z0-9]+>
+ 20000ffc: f800c007 stur x7, \[x0,#12\]
+ 20001000: d2800128 mov x8, #0x9 // #9
+ 20001004: 14000008 b 20001024 <e843419@0002_00000013_1004>
+ 20001008: 8b050020 add x0, x1, x5
+ 2000100c: b9400fe7 ldr w7, \[sp,#12\]
+ 20001010: 0b0700e0 add w0, w7, w7
+ 20001014: 910043ff add sp, sp, #0x10
+ 20001018: 14000005 b 2000102c <__e835769_veneer>
+ 2000101c: d65f03c0 ret
+ 20001020: 14000400 b 20002020 <__e835769_veneer\+0xff4>
+
+0000000020001024 <e843419@0002_00000013_1004>:
+ 20001024: f9000008 str x8, \[x0\]
+ 20001028: 17fffff8 b 20001008 <e843419_1\+0x10>
+
+000000002000102c <__e835769_veneer>:
+ 2000102c: f0f17ff0 adrp x16, 3000000 <e835769>
+ 20001030: 91000210 add x16, x16, #0x0
+ 20001034: d61f0200 br x16
+ ...
+
+Disassembly of section .e835769:
+
+0000000003000000 <e835769>:
+ 3000000: b8408c87 ldr w7, \[x4,#8\]!
+ 3000004: 1b017c06 mul w6, w0, w1
+ 3000008: f9400084 ldr x4, \[x4\]
+ 300000c: 14000004 b 300001c <__erratum_835769_veneer_0>
+ 3000010: aa0503e0 mov x0, x5
+ 3000014: d65f03c0 ret
+ 3000018: 14000400 b 3001018 <__erratum_835769_veneer_0\+0xffc>
+
+000000000300001c <__erratum_835769_veneer_0>:
+ 300001c: 9b031845 madd x5, x2, x3, x6
+ 3000020: 17fffffc b 3000010 <e835769\+0x10>
+ ...
+
+Disassembly of section .text:
+
+0000000000400000 <main>:
+ 400000: d10043ff sub sp, sp, #0x10
+ 400004: d28001a7 mov x7, #0xd // #13
+ 400008: b9000fe7 str w7, \[sp,#12\]
+ 40000c: 14000003 b 400018 <__e843419_veneer>
+ 400010: d65f03c0 ret
+ 400014: 14000400 b 401014 <__e843419_veneer\+0xffc>
+
+0000000000400018 <__e843419_veneer>:
+ 400018: 900fe010 adrp x16, 20000000 <e843419>
+ 40001c: 91000210 add x16, x16, #0x0
+ 400020: d61f0200 br x16
+ ...
diff --git a/binutils-2.25/ld/testsuite/ld-aarch64/erratum843419.s b/binutils-2.25/ld/testsuite/ld-aarch64/erratum843419.s
new file mode 100644
index 00000000..35c21ae9
--- /dev/null
+++ b/binutils-2.25/ld/testsuite/ld-aarch64/erratum843419.s
@@ -0,0 +1,84 @@
+
+ .comm data0,4,4
+ .text
+ .align 2
+ .global main
+ .type main, %function
+main:
+ sub sp, sp, #16
+ mov x7, 13
+ str w7, [sp,12]
+ b e843419
+ ret
+ .size main, .-main
+
+ .section .e843419, "xa"
+ .align 2
+ .global e843419
+ .type e843419, %function
+e843419:
+ sub sp, sp, #16
+ mov x7, 13
+ str w7, [sp,12]
+ b e843419_1
+ .fill 4072,1,0
+e843419_1:
+ adrp x0, data0
+ str x7, [x0,12]
+ mov x8, 9
+ str x8, [x0, :lo12:data0]
+
+ add x0, x1, x5
+ ldr w7, [sp,12]
+ add w0, w7, w7
+ add sp, sp, 16
+ b e835769
+ ret
+ .size e843419, .-e843419
+
+ .section .e835769, "xa"
+ .align 2
+ .global e835769
+ .type e835769, %function
+e835769:
+ ldr w7, [x4,8]!
+ mul w6, w0, w1
+ ldr x4, [x4]
+ madd x5, x2, x3, x6
+ mov x0, x5
+ ret
+ .size e835769, .-e835769
+
+# ---
+
+
+
+
+
+# ---
+
+ .data
+data0:
+ .fill 8,1,255
+ .balign 512
+ .fill 4,1,255
+ # double word access that crosses a 64 bit boundary
+data1:
+ .fill 2,1,255
+
+ # word access that crosses a 64 boundary
+data2:
+ .fill 2,1,255
+
+data5:
+ .fill 4,1,255
+
+ # double word access that crosses a 128 boundary
+data3:
+ .fill 2,1,255
+
+ # word access that crosses a 128 bit boundary
+data4:
+ .fill 2,1,255
+data6:
+ .fill 496,1,255