From: Richard Earnshaw Date: Tue, 16 Dec 2025 14:08:10 +0000 (+0000) Subject: aarch64: Fix out-of-range branch veneers when --fix-cortex-a53-843419 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d3af4016a645db372ba6812eee651ac5e3eb9159;p=thirdparty%2Fbinutils-gdb.git aarch64: Fix out-of-range branch veneers when --fix-cortex-a53-843419 The erratum mitigation support for the Cortex-A53 843419 erratum inserts a new stub for every possible instance of the erratum. Since each stub ends up inserting 4k of space into the binary, in order to avoid perturbing the alignment of other potential erratum sequences we can end up adding substantially more space than the distance to the next long-branch stub that we've prepared for. The problem is, fundamentally a phase ordering problem, but that's easily resolvable by running the 843419 erratum pass first and then creating the stub groups once that is done. In this way we take into account the additional padding when forming the groups to ensure that they remain within range. --- diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c index a3fd1dd7561..00a4f171cf1 100644 --- a/bfd/elfnn-aarch64.c +++ b/bfd/elfnn-aarch64.c @@ -4772,49 +4772,55 @@ elfNN_aarch64_size_stubs (bfd *output_bfd, stub_group_size = 127 * 1024 * 1024; } - group_sections (htab, stub_group_size, stubs_always_before_branch); - - (*htab->layout_sections_again) (); - - if (htab->fix_erratum_835769) + /* The 843419 erratum fix inserts stub sections in place, not in + the section groups. Running this after we have created the stub + groups can perturb the calculations and cause the stub groups + that have been created to be out of range. Avoid this by running + this pass first and then creating the groups once we know how much + code this mitigation will insert. */ + if (htab->fix_erratum_843419 != ERRAT_NONE) { bfd *input_bfd; for (input_bfd = info->input_bfds; - input_bfd != NULL; input_bfd = input_bfd->link.next) + input_bfd != NULL; + input_bfd = input_bfd->link.next) { + asection *section; + if (!is_aarch64_elf (input_bfd) || (input_bfd->flags & BFD_LINKER_CREATED) != 0) continue; - if (!_bfd_aarch64_erratum_835769_scan (input_bfd, info, - &num_erratum_835769_fixes)) - return false; + for (section = input_bfd->sections; + section != NULL; + section = section->next) + if (!_bfd_aarch64_erratum_843419_scan (input_bfd, section, info)) + return false; } _bfd_aarch64_resize_stubs (htab); (*htab->layout_sections_again) (); } - if (htab->fix_erratum_843419 != ERRAT_NONE) + group_sections (htab, stub_group_size, stubs_always_before_branch); + + (*htab->layout_sections_again) (); + + if (htab->fix_erratum_835769) { bfd *input_bfd; for (input_bfd = info->input_bfds; - input_bfd != NULL; - input_bfd = input_bfd->link.next) + input_bfd != NULL; input_bfd = input_bfd->link.next) { - asection *section; - if (!is_aarch64_elf (input_bfd) || (input_bfd->flags & BFD_LINKER_CREATED) != 0) continue; - for (section = input_bfd->sections; - section != NULL; - section = section->next) - if (!_bfd_aarch64_erratum_843419_scan (input_bfd, section, info)) - return false; + if (!_bfd_aarch64_erratum_835769_scan (input_bfd, info, + &num_erratum_835769_fixes)) + return false; } _bfd_aarch64_resize_stubs (htab);