AArch64: Implement choice between Cortex-A53 erratum workarounds. (PR ld/24373)
authorTamar Christina <tamar.christina@arm.com>
Tue, 21 May 2019 12:04:08 +0000 (13:04 +0100)
committerTamar Christina <tamar.christina@arm.com>
Tue, 21 May 2019 12:05:22 +0000 (13:05 +0100)
The Cortex-A53 erratum currently has two ways it can resolve the erratum when
using the flag --fix-cortex-a53-843419:

1) If the address is within the range of an ADR instruction it rewrites the ADRP
   into an ADR, and those doesn't need the use of a veneer.

2) If the address is not within range, it adds a branch to a veneer which will
   execute the final bit of the erratum workaround and branch back to the call
   site.

When we do this we always generate the veneers and we always align the size of
the text section to 4KB.  This is because we only know which workaround we can
use after all linking has finished and all addresses are known.  This means even
though the veneers are not used, we still generate the section and we still
change the size of the input section.

This is problematic for small memory devices as this would require the user to
take about a ~4KB hit in memory even though it's not even used.

Since there's no real way to restart the linking process from the final write
phase this patch solves the issue by allowing the user more control over which
erratum workaround gets used.

Concretely this changes the option --fix-cortex-a53-843419 to take optional
arguments --fix-cortex-a53-843419[=full|adr|adrp]

- full (default): Use both ADRP and ADR workaround. This is equivalent to not
  specifying any options and is the default behavior before this
  patch.

- adr: Only use the ADR workaround, this will not cause any increase in binary
       size but linking will fail if the referenced address is out of range of
       an ADR instruction.

- adrp: Use only the ADRP workaround, this will never rewrite your ADRP.

In the cases where the user knows how big their binaries are the `adr` option
would prevent the unneeded overhead.

bfd/ChangeLog:

PR ld/24373
* bfd-in.h (enum erratum_84319_opts): New
(bfd_elf64_aarch64_set_options, bfd_elf32_aarch64_set_options): Change
int to enum erratum_84319_opts.
* bfd-in2.h: Regenerate.
* elfnn-aarch64.c (struct elf_aarch64_link_hash_table): Change
fix_erratum_843419 to use new enum, remove fix_erratum_843419_adr.
(_bfd_aarch64_add_stub_entry_after): Conditionally create erratum stub.
(aarch64_size_one_stub): Conditionally size erratum 843419 stubs.
(_bfd_aarch64_resize_stubs): Amend comment.
(elfNN_aarch64_size_stubs): Don't generate stubs when no workaround
requested.
(bfd_elfNN_aarch64_set_options): Use new fix_erratum_843419 enum.
(_bfd_aarch64_erratum_843419_branch_to_stub): Implement selection of
erratum workaround.
(clear_erratum_843419_entry): Update erratum conditional.

ld/ChangeLog:

PR ld/24373
* emultempl/aarch64elf.em (PARSE_AND_LIST_LONGOPTS): Add optional args
to flags.
* NEWS: Add changes to flag.
(PARSE_AND_LIST_OPTIONS): Update help descriptions.
(PARSE_AND_LIST_ARGS_CASES): Add new options to parser.
* testsuite/ld-aarch64/aarch64-elf.exp: Add new run_dump_tests.
* testsuite/ld-aarch64/erratum843419-adr.d: New test.
* testsuite/ld-aarch64/erratum843419-adrp.d: New test.
* testsuite/ld-aarch64/erratum843419-far-adr.d: New test.
* testsuite/ld-aarch64/erratum843419-far-full.d: New test.
* testsuite/ld-aarch64/erratum843419-far.s: New test.
* testsuite/ld-aarch64/erratum843419-full.d: New test.
* testsuite/ld-aarch64/erratum843419-near.s: New test.
* testsuite/ld-aarch64/erratum843419-no-args.d: New test.

16 files changed:
bfd/ChangeLog
bfd/bfd-in.h
bfd/bfd-in2.h
bfd/elfnn-aarch64.c
ld/ChangeLog
ld/NEWS
ld/emultempl/aarch64elf.em
ld/testsuite/ld-aarch64/aarch64-elf.exp
ld/testsuite/ld-aarch64/erratum843419-adr.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/erratum843419-adrp.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/erratum843419-far-adr.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/erratum843419-far-full.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/erratum843419-far.s [new file with mode: 0644]
ld/testsuite/ld-aarch64/erratum843419-full.d [new file with mode: 0644]
ld/testsuite/ld-aarch64/erratum843419-near.s [new file with mode: 0644]
ld/testsuite/ld-aarch64/erratum843419-no-args.d [new file with mode: 0644]

index 7d22cc03d3edd662c99413e1b5e30820d47beca1..2e7158f5844caddcb0af09e1b6cd2670b9ede88e 100644 (file)
@@ -1,3 +1,22 @@
+2019-05-21  Tamar Christina  <tamar.christina@arm.com>
+
+       PR ld/24373
+       * bfd-in.h (enum erratum_84319_opts): New
+       (bfd_elf64_aarch64_set_options, bfd_elf32_aarch64_set_options): Change
+       int to enum erratum_84319_opts.
+       * bfd-in2.h: Regenerate.
+       * elfnn-aarch64.c (struct elf_aarch64_link_hash_table): Change
+       fix_erratum_843419 to use new enum, remove fix_erratum_843419_adr.
+       (_bfd_aarch64_add_stub_entry_after): Conditionally create erratum stub.
+       (aarch64_size_one_stub): Conditionally size erratum 843419 stubs.
+       (_bfd_aarch64_resize_stubs): Amend comment.
+       (elfNN_aarch64_size_stubs): Don't generate stubs when no workaround
+       requested.
+       (bfd_elfNN_aarch64_set_options): Use new fix_erratum_843419 enum.
+       (_bfd_aarch64_erratum_843419_branch_to_stub): Implement selection of
+       erratum workaround.
+       (clear_erratum_843419_entry): Update erratum conditional.
+
 2019-05-21  Senthil Kumar Selvaraj  <senthilkumar.selvaraj@microchip.com>
 
        PR ld/24571
index b753a9e57c11049a519cbb2b4ab9ef16473db52c..890a79d409e1f404a82720d84a699d03e5267db5 100644 (file)
@@ -1027,12 +1027,21 @@ typedef struct
   aarch64_enable_bti_type bti_type;
 } aarch64_bti_pac_info;
 
+/* An enum to define what kind of erratum fixes we should apply.  This gives the
+   user a bit more control over the sequences we generate.  */
+typedef enum
+{
+  ERRAT_NONE  = (1 << 0),  /* No erratum workarounds allowed.  */
+  ERRAT_ADR   = (1 << 1),  /* Erratum workarounds using ADR allowed.  */
+  ERRAT_ADRP  = (1 << 2),  /* Erratum workarounds using ADRP are allowed.  */
+} erratum_84319_opts;
+
 extern void bfd_elf64_aarch64_set_options
-  (bfd *, struct bfd_link_info *, int, int, int, int, int, int,
+  (bfd *, struct bfd_link_info *, int, int, int, int, erratum_84319_opts, int,
    aarch64_bti_pac_info);
 
 extern void bfd_elf32_aarch64_set_options
-  (bfd *, struct bfd_link_info *, int, int, int, int, int, int,
+  (bfd *, struct bfd_link_info *, int, int, int, int, erratum_84319_opts, int,
    aarch64_bti_pac_info);
 
 /* ELF AArch64 mapping symbol support.  */
index 9f60f57df9aa95ae84932f16b68ebe1517e83d41..65e2e01efe008144e281bc66fc3f4d678ad41982 100644 (file)
@@ -1034,12 +1034,21 @@ typedef struct
   aarch64_enable_bti_type bti_type;
 } aarch64_bti_pac_info;
 
+/* An enum to define what kind of erratum fixes we should apply.  This gives the
+   user a bit more control over the sequences we generate.  */
+typedef enum
+{
+  ERRAT_NONE  = (1 << 0),  /* No erratum workarounds allowed.  */
+  ERRAT_ADR   = (1 << 1),  /* Erratum workarounds using ADR allowed.  */
+  ERRAT_ADRP  = (1 << 2),  /* Erratum workarounds using ADRP are allowed.  */
+} erratum_84319_opts;
+
 extern void bfd_elf64_aarch64_set_options
-  (bfd *, struct bfd_link_info *, int, int, int, int, int, int,
+  (bfd *, struct bfd_link_info *, int, int, int, int, erratum_84319_opts, int,
    aarch64_bti_pac_info);
 
 extern void bfd_elf32_aarch64_set_options
-  (bfd *, struct bfd_link_info *, int, int, int, int, int, int,
+  (bfd *, struct bfd_link_info *, int, int, int, int, erratum_84319_opts, int,
    aarch64_bti_pac_info);
 
 /* ELF AArch64 mapping symbol support.  */
index 8940f4e214af50dc879aced2b86f52d7e9e0e16e..29310184d2a3afd6af4c4c41eb4ddc78aaae0854 100644 (file)
@@ -2628,10 +2628,7 @@ struct elf_aarch64_link_hash_table
   int fix_erratum_835769;
 
   /* Fix erratum 843419.  */
-  int fix_erratum_843419;
-
-  /* Enable ADRP->ADR rewrite for erratum 843419 workaround.  */
-  int fix_erratum_843419_adr;
+  erratum_84319_opts fix_erratum_843419;
 
   /* Don't apply link-time values for dynamic relocations.  */
   int no_apply_dynamic_relocs;
@@ -3229,7 +3226,10 @@ _bfd_aarch64_add_stub_entry_after (const char *stub_name,
   asection *stub_sec;
   struct elf_aarch64_stub_hash_entry *stub_entry;
 
-  stub_sec = _bfd_aarch64_get_stub_for_link_section (link_section, htab);
+  stub_sec = NULL;
+  /* Only create the actual stub if we will end up needing it.  */
+  if (htab->fix_erratum_843419 & ERRAT_ADRP)
+    stub_sec = _bfd_aarch64_get_stub_for_link_section (link_section, htab);
   stub_entry = aarch64_stub_hash_lookup (&htab->stub_hash_table, stub_name,
                                         TRUE, FALSE);
   if (stub_entry == NULL)
@@ -3374,14 +3374,15 @@ aarch64_build_one_stub (struct bfd_hash_entry *gen_entry,
    we know stub section sizes.  */
 
 static bfd_boolean
-aarch64_size_one_stub (struct bfd_hash_entry *gen_entry,
-                      void *in_arg ATTRIBUTE_UNUSED)
+aarch64_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
 {
   struct elf_aarch64_stub_hash_entry *stub_entry;
+  struct elf_aarch64_link_hash_table *htab;
   int size;
 
   /* Massage our args to the form they really have.  */
   stub_entry = (struct elf_aarch64_stub_hash_entry *) gen_entry;
+  htab = (struct elf_aarch64_link_hash_table *) in_arg;
 
   switch (stub_entry->stub_type)
     {
@@ -3395,7 +3396,11 @@ aarch64_size_one_stub (struct bfd_hash_entry *gen_entry,
       size = sizeof (aarch64_erratum_835769_stub);
       break;
     case aarch64_stub_erratum_843419_veneer:
-      size = sizeof (aarch64_erratum_843419_stub);
+      {
+       if (htab->fix_erratum_843419 == ERRAT_ADR)
+         return TRUE;
+       size = sizeof (aarch64_erratum_843419_stub);
+      }
       break;
     default:
       abort ();
@@ -4060,8 +4065,10 @@ _bfd_aarch64_resize_stubs (struct elf_aarch64_link_hash_table *htab)
       /* Ensure all stub sections have a size which is a multiple of
         4096.  This is important in order to ensure that the insertion
         of stub sections does not in itself move existing code around
-        in such a way that new errata sequences are created.  */
-      if (htab->fix_erratum_843419)
+        in such a way that new errata sequences are created.  We only do this
+        when the ADRP workaround is enabled.  If only the ADR workaround is
+        enabled then the stubs workaround won't ever be used.  */
+      if (htab->fix_erratum_843419 & ERRAT_ADRP)
        if (section->size)
          section->size = BFD_ALIGN (section->size, 0x1000);
     }
@@ -4284,7 +4291,7 @@ elfNN_aarch64_size_stubs (bfd *output_bfd,
       (*htab->layout_sections_again) ();
     }
 
-  if (htab->fix_erratum_843419)
+  if (htab->fix_erratum_843419 != ERRAT_NONE)
     {
       bfd *input_bfd;
 
@@ -4755,7 +4762,7 @@ bfd_elfNN_aarch64_set_options (struct bfd *output_bfd,
                               int no_enum_warn,
                               int no_wchar_warn, int pic_veneer,
                               int fix_erratum_835769,
-                              int fix_erratum_843419,
+                              erratum_84319_opts fix_erratum_843419,
                               int no_apply_dynamic_relocs,
                               aarch64_bti_pac_info bp_info)
 {
@@ -4764,8 +4771,10 @@ bfd_elfNN_aarch64_set_options (struct bfd *output_bfd,
   globals = elf_aarch64_hash_table (link_info);
   globals->pic_veneer = pic_veneer;
   globals->fix_erratum_835769 = fix_erratum_835769;
+  /* If the default options are used, then ERRAT_ADR will be set by default
+     which will enable the ADRP->ADR workaround for the erratum 843419
+     workaround.  */
   globals->fix_erratum_843419 = fix_erratum_843419;
-  globals->fix_erratum_843419_adr = TRUE;
   globals->no_apply_dynamic_relocs = no_apply_dynamic_relocs;
 
   BFD_ASSERT (is_aarch64_elf (output_bfd));
@@ -5235,9 +5244,18 @@ _bfd_aarch64_erratum_843419_branch_to_stub (struct bfd_hash_entry *gen_entry,
       || stub_entry->stub_type != aarch64_stub_erratum_843419_veneer)
     return TRUE;
 
-  insn = bfd_getl32 (contents + stub_entry->target_value);
-  bfd_putl32 (insn,
-             stub_entry->stub_sec->contents + stub_entry->stub_offset);
+  BFD_ASSERT (((htab->fix_erratum_843419 & ERRAT_ADRP) && stub_entry->stub_sec)
+             || (htab->fix_erratum_843419 & ERRAT_ADR));
+
+  /* Only update the stub section if we have one.  We should always have one if
+     we're allowed to use the ADRP errata workaround, otherwise it is not
+     required.  */
+  if (stub_entry->stub_sec)
+    {
+      insn = bfd_getl32 (contents + stub_entry->target_value);
+      bfd_putl32 (insn,
+                 stub_entry->stub_sec->contents + stub_entry->stub_offset);
+    }
 
   place = (section->output_section->vma + section->output_offset
           + stub_entry->adrp_offset);
@@ -5251,14 +5269,16 @@ _bfd_aarch64_erratum_843419_branch_to_stub (struct bfd_hash_entry *gen_entry,
      ((bfd_vma) _bfd_aarch64_decode_adrp_imm (insn) << 12, 33)
      - (place & 0xfff));
 
-  if (htab->fix_erratum_843419_adr
+  if ((htab->fix_erratum_843419 & ERRAT_ADR)
       && (imm >= AARCH64_MIN_ADRP_IMM  && imm <= AARCH64_MAX_ADRP_IMM))
     {
       insn = (_bfd_aarch64_reencode_adr_imm (AARCH64_ADR_OP, imm)
              | AARCH64_RT (insn));
       bfd_putl32 (insn, contents + stub_entry->adrp_offset);
+      /* Stub is not needed, don't map it out.  */
+      stub_entry->stub_type = aarch64_stub_none;
     }
-  else
+  else if (htab->fix_erratum_843419 & ERRAT_ADRP)
     {
       bfd_vma veneered_insn_loc;
       bfd_vma veneer_entry_loc;
@@ -5285,6 +5305,21 @@ _bfd_aarch64_erratum_843419_branch_to_stub (struct bfd_hash_entry *gen_entry,
       branch_insn |= branch_offset;
       bfd_putl32 (branch_insn, contents + stub_entry->target_value);
     }
+  else
+    {
+      abfd = stub_entry->target_section->owner;
+      _bfd_error_handler
+       (_("%pB: error: erratum 843419 immediate 0x%lx "
+          "out of range for ADR (input file too large) and "
+          "--fix-cortex-a53-843419=adr used.  Run the linker with "
+          "--fix-cortex-a53-843419=full instead"), abfd, imm);
+      bfd_set_error (bfd_error_bad_value);
+      /* This function is called inside a hashtable traversal and the error
+        handlers called above turn into non-fatal errors.  Which means this
+        case ld returns an exit code 0 and also produces a broken object file.
+        To prevent this, issue a hard abort.  */
+      BFD_FAIL ();
+    }
   return TRUE;
 }
 
@@ -6154,7 +6189,7 @@ static void
 clear_erratum_843419_entry (struct elf_aarch64_link_hash_table *globals,
                            bfd_vma adrp_offset, asection *input_section)
 {
-  if (globals->fix_erratum_843419)
+  if (globals->fix_erratum_843419 & ERRAT_ADRP)
     {
       struct erratum_843419_branch_to_stub_clear_data data;
       data.adrp_offset = adrp_offset;
index e038e400333b9c2128da4aaa9578d67e908a7ce1..77beea096c749eb96ab386f4b1b50028ee8e18d3 100644 (file)
@@ -1,3 +1,21 @@
+2019-05-21  Tamar Christina  <tamar.christina@arm.com>
+
+       PR ld/24373
+       * emultempl/aarch64elf.em (PARSE_AND_LIST_LONGOPTS): Add optional args
+       to flags.
+       * NEWS: Add changes to flag.
+       (PARSE_AND_LIST_OPTIONS): Update help descriptions.
+       (PARSE_AND_LIST_ARGS_CASES): Add new options to parser.
+       * testsuite/ld-aarch64/aarch64-elf.exp: Add new run_dump_tests.
+       * testsuite/ld-aarch64/erratum843419-adr.d: New test.
+       * testsuite/ld-aarch64/erratum843419-adrp.d: New test.
+       * testsuite/ld-aarch64/erratum843419-far-adr.d: New test.
+       * testsuite/ld-aarch64/erratum843419-far-full.d: New test.
+       * testsuite/ld-aarch64/erratum843419-far.s: New test.
+       * testsuite/ld-aarch64/erratum843419-full.d: New test.
+       * testsuite/ld-aarch64/erratum843419-near.s: New test.
+       * testsuite/ld-aarch64/erratum843419-no-args.d: New test.
+
 2019-05-21  Senthil Kumar Selvaraj  <senthilkumar.selvaraj@microchip.com>
 
        PR ld/24571
diff --git a/ld/NEWS b/ld/NEWS
index de2cd16c4ef1bd725a15e447be766a441d598564..3a41e9fbf1654ef04587ce90a047c332af852600 100644 (file)
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -2,6 +2,12 @@
 
 * Add command-line option --no-print-map-discarded.
 
+* The Cortex-A53 Erratum 843419 workaround now supports a choice of which
+  workaround to use.  The option --fix-cortex-a53-843419 now takes an
+  optional argument --fix-cortex-a53-843419[=full|adr|adrp] which can be
+  used to force a particular workaround to be used.  See --help for AArch64
+  for more details.
+
 Changes in 2.33:
 
 * Add target handlers for AArch64 for ELF GNU program properties.
index bfe8d1b179230a6ba32be42b2105180f4cd72446..b59623ec6533952734f400cc0165e59f94ac2b13 100644 (file)
@@ -31,7 +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 erratum_84319_opts fix_erratum_843419 = ERRAT_NONE;
 static int no_apply_dynamic_relocs = 0;
 static aarch64_plt_type plt_type = PLT_NORMAL;
 static aarch64_enable_bti_type bti_type = BTI_NONE;
@@ -385,7 +385,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},
+  { "fix-cortex-a53-843419", optional_argument, NULL, OPTION_FIX_ERRATUM_843419},
   { "no-apply-dynamic-relocs", no_argument, NULL, OPTION_NO_APPLY_DYNAMIC_RELOCS},
   { "force-bti", no_argument, NULL, OPTION_FORCE_BTI},
   { "pac-plt", no_argument, NULL, OPTION_PAC_PLT},
@@ -407,7 +407,17 @@ PARSE_AND_LIST_OPTIONS='
                                 Values of +/-1 indicate the linker should\n\
                                 choose suitable defaults.\n"));
   fprintf (file, _("  --fix-cortex-a53-835769      Fix erratum 835769\n"));
-  fprintf (file, _("  --fix-cortex-a53-843419      Fix erratum 843419\n"));
+  fprintf (file, _("\
+  --fix-cortex-a53-843419[=full|adr|adrp]      Fix erratum 843419 and optionally specify which workaround to use.\n\
+                                               full (default): Use both ADRP and ADR workaround, this will \n\
+                                                 increase the size of your binaries.\n\
+                                               adr: Only use the ADR workaround, this will not cause any increase\n\
+                                                 in binary size but linking will fail if the referenced address is\n\
+                                                 out of range of an ADR instruction.  This will remove the need of using\n\
+                                                 a veneer and results in both performance and size benefits.\n\
+                                               adrp: Use only the ADRP workaround, this will never rewrite your ADRP\n\
+                                                 instruction into an ADR.  As such the workaround will always use a\n\
+                                                 veneer and this will give you both a performance and size overhead.\n"));
   fprintf (file, _("  --no-apply-dynamic-relocs    Do not apply link-time values for dynamic relocations\n"));
   fprintf (file, _("  --force-bti                  Turn on Branch Target Identification mechanism and generate PLTs with BTI. Generate warnings for missing BTI on inputs\n"));
   fprintf (file, _("  --pac-plt                    Protect PLTs with Pointer Authentication.\n"));
@@ -435,7 +445,19 @@ PARSE_AND_LIST_ARGS_CASES='
       break;
 
     case OPTION_FIX_ERRATUM_843419:
-      fix_erratum_843419 = 1;
+      fix_erratum_843419 = ERRAT_ADR | ERRAT_ADRP;
+      if (optarg && *optarg)
+       {
+         if (strcmp ("full", optarg) == 0)
+           fix_erratum_843419 = ERRAT_ADR | ERRAT_ADRP;
+         else if (strcmp ("adrp", optarg) == 0)
+           fix_erratum_843419 = ERRAT_ADRP;
+         else if (strcmp ("adr", optarg) == 0)
+           fix_erratum_843419 = ERRAT_ADR;
+         else
+           einfo (_("%P: error: unrecognized option for "
+                    "--fix-cortex-a53-843419: %s\n"), optarg);
+       }
       break;
 
     case OPTION_NO_APPLY_DYNAMIC_RELOCS:
index e69aedd0d4d1b434b659a9d426cf86c528610608..1e4c38e691d2f45a5d8dea468ed8c3ca05e1033a 100644 (file)
@@ -87,6 +87,12 @@ run_ld_link_tests eh-frame-merge-lp64
 
 run_dump_test "erratum843419"
 run_dump_test "erratum843419_tls_ie"
+run_dump_test "erratum843419-adr"
+run_dump_test "erratum843419-adrp"
+run_dump_test "erratum843419-far-adr"
+run_dump_test "erratum843419-far-full"
+run_dump_test "erratum843419-full"
+run_dump_test "erratum843419-no-args"
 
 # Relocation Tests
 run_dump_test_lp64 "weak-undefined"
diff --git a/ld/testsuite/ld-aarch64/erratum843419-adr.d b/ld/testsuite/ld-aarch64/erratum843419-adr.d
new file mode 100644 (file)
index 0000000..ab4fe27
--- /dev/null
@@ -0,0 +1,15 @@
+#source: erratum843419-near.s
+#as:
+#ld: -Ttext=0x400000 --fix-cortex-a53-843419=adr
+#objdump: -dr
+#...
+
+Disassembly of section \.text:
+
+0*400000 <_start>:
+       ...
+  400ffc:      10038020        adr     x0, 408000 <_start\+0x8000>
+  401000:      f9000042        str     x2, \[x2\]
+  401004:      d2800002        mov     x2, #0x0                        // #0
+  401008:      f9402001        ldr     x1, \[x0, #64\]
+  40100c:      d503201f        nop
diff --git a/ld/testsuite/ld-aarch64/erratum843419-adrp.d b/ld/testsuite/ld-aarch64/erratum843419-adrp.d
new file mode 100644 (file)
index 0000000..371201c
--- /dev/null
@@ -0,0 +1,22 @@
+#source: erratum843419-near.s
+#as:
+#ld: -Ttext=0x400000 --fix-cortex-a53-843419=adrp
+#objdump: -dr
+#...
+
+Disassembly of section \.text:
+
+0*400000 <_start>:
+       ...
+  400ffc:      90000040        adrp    x0, 408000 <e843419@0002_00000010_1008\+0x6fe8>
+  401000:      f9000042        str     x2, \[x2\]
+  401004:      d2800002        mov     x2, #0x0                        // #0
+  401008:      14000004        b       401018 <e843419@0002_00000010_1008>
+  40100c:      d503201f        nop
+  401010:      14000400        b       402010 <e843419@0002_00000010_1008\+0xff8>
+  401014:      d503201f        nop
+
+0*401018 <e843419@0002_00000010_1008>:
+  401018:      f9402001        ldr     x1, \[x0, #64\]
+  40101c:      17fffffc        b       40100c <_start\+0x100c>
+       ...
diff --git a/ld/testsuite/ld-aarch64/erratum843419-far-adr.d b/ld/testsuite/ld-aarch64/erratum843419-far-adr.d
new file mode 100644 (file)
index 0000000..acddea7
--- /dev/null
@@ -0,0 +1,5 @@
+#source: erratum843419-far.s
+#as:
+#ld: -Ttext=0x400000 --fix-cortex-a53-843419=adr
+#error: .*: erratum 843419 immediate 0x7ffff004 out of range for ADR \(input file too large\) and \-\-fix\-cortex\-a53\-843419=adr used\.  Run the linker with \-\-fix\-cortex\-a53\-843419=full instead.*
+#...
diff --git a/ld/testsuite/ld-aarch64/erratum843419-far-full.d b/ld/testsuite/ld-aarch64/erratum843419-far-full.d
new file mode 100644 (file)
index 0000000..24f2be5
--- /dev/null
@@ -0,0 +1,22 @@
+#source: erratum843419-far.s
+#as:
+#ld: -Ttext=0x400000 --fix-cortex-a53-843419=full
+#objdump: -dr
+#...
+
+Disassembly of section \.text:
+
+0*400000 <_start>:
+       ...
+  400ffc:      90400000        adrp    x0, 80400000 <__bss_end__\+0x7ffedff0>
+  401000:      f9000042        str     x2, \[x2\]
+  401004:      d2800002        mov     x2, #0x0                        // #0
+  401008:      14000004        b       401018 <e843419@0002_00000010_1008>
+  40100c:      d503201f        nop
+  401010:      14000400        b       402010 <e843419@0002_00000010_1008\+0xff8>
+  401014:      d503201f        nop
+
+0*401018 <e843419@0002_00000010_1008>:
+  401018:      f9402001        ldr     x1, \[x0, #64\]
+  40101c:      17fffffc        b       40100c <_start\+0x100c>
+       ...
diff --git a/ld/testsuite/ld-aarch64/erratum843419-far.s b/ld/testsuite/ld-aarch64/erratum843419-far.s
new file mode 100644 (file)
index 0000000..21f1b37
--- /dev/null
@@ -0,0 +1,9 @@
+.balign 0x1000
+.globl _start
+_start:
+        .skip 0xffc
+        adrp x0, _start + 0x80000000
+        str x2, [x2]
+        mov x2, #0
+        ldr x1, [x0, #0x40]
+        nop
diff --git a/ld/testsuite/ld-aarch64/erratum843419-full.d b/ld/testsuite/ld-aarch64/erratum843419-full.d
new file mode 100644 (file)
index 0000000..508216d
--- /dev/null
@@ -0,0 +1,20 @@
+#source: erratum843419-near.s
+#as:
+#ld: -Ttext=0x400000 --fix-cortex-a53-843419=full
+#objdump: -dr
+#...
+
+Disassembly of section \.text:
+
+0*400000 <_start>:
+       ...
+  400ffc:      10038020        adr     x0, 408000 <_start\+0x8000>
+  401000:      f9000042        str     x2, \[x2\]
+  401004:      d2800002        mov     x2, #0x0                        // #0
+  401008:      f9402001        ldr     x1, \[x0, #64\]
+  40100c:      d503201f        nop
+  401010:      14000400        b       402010 <_start\+0x2010>
+  401014:      d503201f        nop
+  401018:      f9402001        ldr     x1, \[x0, #64\]
+  40101c:      17fffffc        b       40100c <_start\+0x100c>
+       ...
diff --git a/ld/testsuite/ld-aarch64/erratum843419-near.s b/ld/testsuite/ld-aarch64/erratum843419-near.s
new file mode 100644 (file)
index 0000000..262cd16
--- /dev/null
@@ -0,0 +1,9 @@
+.balign 0x1000
+.globl _start
+_start:
+        .skip 0xffc
+        adrp x0, _start + 0x8000
+        str x2, [x2]
+        mov x2, #0
+        ldr x1, [x0, #0x40]
+        nop
diff --git a/ld/testsuite/ld-aarch64/erratum843419-no-args.d b/ld/testsuite/ld-aarch64/erratum843419-no-args.d
new file mode 100644 (file)
index 0000000..30773f6
--- /dev/null
@@ -0,0 +1,20 @@
+#source: erratum843419-near.s
+#as:
+#ld: -Ttext=0x400000 --fix-cortex-a53-843419
+#objdump: -dr
+#...
+
+Disassembly of section \.text:
+
+0*400000 <_start>:
+       ...
+  400ffc:      10038020        adr     x0, 408000 <_start\+0x8000>
+  401000:      f9000042        str     x2, \[x2\]
+  401004:      d2800002        mov     x2, #0x0                        // #0
+  401008:      f9402001        ldr     x1, \[x0, #64\]
+  40100c:      d503201f        nop
+  401010:      14000400        b       402010 <_start\+0x2010>
+  401014:      d503201f        nop
+  401018:      f9402001        ldr     x1, \[x0, #64\]
+  40101c:      17fffffc        b       40100c <_start\+0x100c>
+       ...