aarch64: segv on aarch64_stub_erratum_843419_veneer

Alan Modra <[email protected]>
Newsgroups gmane.comp.gnu.binutils
Message-ID <[email protected]>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.