Hi, I noticed ld is failing to generate long branch stubs for aarch64 under certain conditions. After debugging the issue to try to understand what was happening, I observed that the function elfNN_aarch64_size_stubs() has a loop to compute the veneers, cache them into a special hash table and then redo layout (calling the layout_sections_again callback), doing this until no new stubs are needed. It then writes the stubs later by traversing the stub hash table with aarch64_build_one_stub() calls in elfNN_aarch64_build_stubs(). The problem is that layout_sections_again may change a symbol value (by changing its containing section's output_offset) but will not update the hash entry containing the stub destination, which was pre-computed with a now outdated value, thus generating a veneer with a bad target. I could reproduce this on ld 2.31, but I wrote the patch for ld 2.36. diff --git a/binutils-2.26.1/bfd/elfnn-aarch64.c b/binutils-2.26.1/bfd/elfnn-aarch64.c --- a/binutils-2.26.1/bfd/elfnn-aarch64.c +++ b/binutils-2.26.1/bfd/elfnn-aarch64.c @@ -4163,6 +4163,9 @@ elfNN_aarch64_size_stubs (bfd *output_bfd, { /* The proper stub has already been created. */ free (stub_name); + /* Always update this stub target since it may have + changed after layout */ + stub_entry->target_value = sym_value + irela->r_addend; continue; }
The master branch has been updated by Nick Clifton <nickc@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=3da64fe404031c093e8b59565d935fed214e28c1 commit 3da64fe404031c093e8b59565d935fed214e28c1 Author: Rafeal Auler <rafaelauler@gmail.com> Date: Wed Aug 22 10:04:09 2018 +0100 Fix AArch64 stub layout algorithm to allow for the fact that section layut might change a stub's target location. PR 23560 * elfnn-aarch64.c (elfNN_aarch64_size_stubs): Always update the stub's target, since it may have been changed after the layout.
Hi Rafael, Thanks for the bug report and patch. I have applied your patch to the mainstream sources. Cheers Nick
The master branch has been updated by Alan Modra <amodra@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=a788aedd86da983faf0afef3cb41461118a2e9f2 commit a788aedd86da983faf0afef3cb41461118a2e9f2 Author: Alan Modra <amodra@gmail.com> Date: Mon Jan 13 22:30:46 2020 +1030 PR23560, PR23561, readelf memory leaks PR 23560 PR 23561 * dwarf.c (display_debug_frames): Move fde_fc earlier. Free fde_fc col_type and col_offset. * readelf.c (apply_relocations): Move symsec check earlier. (free_debug_section): Free reloc_info. (process_notes_at): Free pnotes on error path. (process_object): Free dump_sects here.. (process_archive): ..not here.