[binutils-gdb] aarch64: segv on aarch64_stub_erratum_843419_veneer
Alan Modra via Binutils-cvs <[email protected]> Sun, 28 Jun 2026 02:53:21 +0000 (GMT)
| Newsgroups | gmane.comp.gnu.binutils.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=11f57b156514211af29b93588c0fee2f8b3e66e4 commit 11f57b156514211af29b93588c0fee2f8b3e66e4 Author: Alan Modra <[email protected]> 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); }