[binutils-gdb] aarch64: segv on aarch64_stub_erratum_843419_veneer

Alan Modra amodra@sourceware.org
Sun Jun 28 02:53:21 GMT 2026


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=11f57b156514211af29b93588c0fee2f8b3e66e4

commit 11f57b156514211af29b93588c0fee2f8b3e66e4
Author: Alan Modra <amodra@gmail.com>
Date:   Thu Jun 25 22:43:05 2026 +0930

    aarch64: segv on aarch64_stub_erratum_843419_veneer
    
    With a patch I've had in my tree for a while that makes use of the
    stub bfd for linker generated sections, I saw segfaults in the
    testsuite linking ld-aarch64/erratum843419-adr and
    ld-aarch64/erratum843419-far-adr.  Without my changes (that result in
    stub_file->the_bfd->sections non-NULL), elf64_aarch64_build_stubs is
    not called.  See aarch64elf.em finish function.  However, I believe it
    is possible to hit the segfault with a testcase that generates other
    stub types besides the aarch64_stub_erratum_843419_veneer.
    
    The segfault occurs on the aarch64_build_one_stub assert that
    stub_sec->output_section != NULL.  That happens because
    _bfd_aarch64_add_stub_entry_after creates a stub_entry with stub_sec
    NULL when fix_erratum_843419 is ERRAT_ADR.  Clearly we shouldn't be
    doing anything in aarch64_build_one_stub when stub_sec is NULL, and
    inspecting aarch64_size_one_stub reveals that these stubs are not
    sized.
    
    I found the test in aarch64_size_one_stub to exclude these stubs a
    little obscure, needing to verify the possible values of
    htab->fix_erratum_843419 to convince myself it was correct.  (It is.)
    So I changed the test in both places to stub_entry->stub_sec being
    non-NULL.   Which is how _bfd_aarch64_erratum_843419_branch_to_stub
    distinguishes the variants of the stub.
    
            * elfnn-aarch64.c (aarch64_build_one_stub): Don't segfault on
            NULL stub_sec.
            (aarch64_size_one_stub): Use the same condition here for
            aarch64_stub_erratum_843419_veneer.

Diff:
---
 bfd/elfnn-aarch64.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 96da6d790d9..ffca9048e65 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -3265,6 +3265,10 @@ aarch64_build_one_stub (struct bfd_hash_entry *gen_entry,
   info = (struct bfd_link_info *) in_arg;
   htab = elf_aarch64_hash_table (info);
 
+  if (stub_entry->stub_type == aarch64_stub_erratum_843419_veneer
+      && stub_entry->stub_sec == NULL)
+    return true;
+
   /* Fail if the target section could not be assigned to an output
      section.  The user should fix his linker script.  */
   if (stub_entry->target_section->output_section == NULL
@@ -3410,7 +3414,7 @@ static bool
 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;
+  struct elf_aarch64_link_hash_table *htab ATTRIBUTE_UNUSED;
   int size;
 
   /* Massage our args to the form they really have.  */
@@ -3433,7 +3437,7 @@ aarch64_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
       break;
     case aarch64_stub_erratum_843419_veneer:
       {
-	if (htab->fix_erratum_843419 == ERRAT_ADR)
+	if (stub_entry->stub_sec == NULL)
 	  return true;
 	size = sizeof (aarch64_erratum_843419_stub);
       }


More information about the Binutils-cvs mailing list