[binutils-gdb] aarch64: Fix DT_RELR support with discarded sections

Szabolcs Nagy nsz@sourceware.org
Fri Jun 7 07:23:44 GMT 2024


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

commit 961befd69308895bf1dc39737d1598246dc296a8
Author: Szabolcs Nagy <szabolcs.nagy@arm.com>
Date:   Mon Jun 3 17:20:32 2024 +0100

    aarch64: Fix DT_RELR support with discarded sections
    
    In case of discarded sections, via /DISCARD/ or .gnu.linkonce,
    relr relocation accounting was wrong.  This broke building linux.
    
    The issue was that the *_relocate_section logic was copied to
    record_relr_non_got_relocs to find the relative relocs that can
    be packed, however *_relocate_section is not called on sections
    that are discarded, while record_relr_non_got_relocs is called
    for all input sections. The fix is to filter out the discarded
    sections with the same logic that is used to count non-GOT
    relocs in *_late_size_sections for local symbols earlier.
    Use the discarded_section helper in both cases to clarify the
    intent and handle all corner-cases consistently.
    
    GOT relocations are affected too if all sections are discarded
    that reference the GOT entry of a particular symbol, however
    this can cause unused GOT entries independently of DT_RELR, and
    the only difference with DT_RELR is that a relative reloc may be
    emitted instead of a R_AARCH64_NONE for the unused GOT entry
    which is acceptable. A proper fix would require redoing the GOT
    refcounting after we know the discarded sections, see bug 31850.

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

diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 81f1a646125..2221de0a480 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -9327,6 +9327,8 @@ record_relr_non_got_relocs (bfd *input_bfd, struct bfd_link_info *info,
     return true;
   if (sec->alignment_power == 0)
     return true;
+  if (discarded_section (sec))
+    return true;
   sreloc = elf_section_data (sec)->sreloc;
   if (sreloc == NULL)
     return true;
@@ -9602,8 +9604,7 @@ elfNN_aarch64_late_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
 	  for (p = (struct elf_dyn_relocs *)
 	       (elf_section_data (s)->local_dynrel); p != NULL; p = p->next)
 	    {
-	      if (!bfd_is_abs_section (p->sec)
-		  && bfd_is_abs_section (p->sec->output_section))
+	      if (discarded_section (p->sec))
 		{
 		  /* Input section has been discarded, either because
 		     it is a copy of a linkonce section or due to


More information about the Binutils-cvs mailing list