aarch64: segv on aarch64_stub_erratum_843419_veneer

Alan Modra amodra@gmail.com
Thu Jun 25 23:44:08 GMT 2026


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.

I'll commit this in a day or two if no one NAKs it, to make it into
the next release.

	* 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 --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);
       }

-- 
Alan Modra


More information about the Binutils mailing list