[binutils-gdb] PR32690, assertion failure in lang_size_relro_segment

Alan Modra amodra@sourceware.org
Mon Feb 17 23:15:19 GMT 2025


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

commit 230a788eb28a64d628e623068c44add2a24aa5d3
Author: Alan Modra <amodra@gmail.com>
Date:   Tue Feb 18 08:54:06 2025 +1030

    PR32690, assertion failure in lang_size_relro_segment
    
    This introduces a new function which should be used whenever the
    linker needs to increase section alignment after mapping input to
    output sections.
    
            PR ld/32690
            * linker.c (bfd_link_align_section): New function.
            * elflink.c (_bfd_elf_adjust_dynamic_copy): Use it.
            * bfd-in2.h: Regenerate.

Diff:
---
 bfd/bfd-in2.h |  2 ++
 bfd/elflink.c |  9 +++------
 bfd/linker.c  | 42 +++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 46 insertions(+), 7 deletions(-)

diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 4aa814abe79..c29ff2bbc66 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -2964,6 +2964,8 @@ const char *bfd_format_string (bfd_format format);
    && bfd_is_abs_section ((H)->u.def.section) \
    && !(H)->rel_from_abs)
 
+bool bfd_link_align_section (asection *, unsigned int);
+
 bool bfd_link_split_section (bfd *abfd, asection *sec);
 
 #define bfd_link_split_section(abfd, sec) \
diff --git a/bfd/elflink.c b/bfd/elflink.c
index df6eb250961..f65b6bf0f95 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -3384,12 +3384,9 @@ _bfd_elf_adjust_dynamic_copy (struct bfd_link_info *info,
        --power_of_two;
     }
 
-  if (power_of_two > bfd_section_alignment (dynbss))
-    {
-      /* Adjust the section alignment if needed.  */
-      if (!bfd_set_section_alignment (dynbss, power_of_two))
-	return false;
-    }
+  /* Adjust the section alignment if needed.  */
+  if (!bfd_link_align_section (dynbss, power_of_two))
+    return false;
 
   /* We make sure that the symbol will be aligned properly.  */
   dynbss->size = BFD_ALIGN (dynbss->size, mask + 1);
diff --git a/bfd/linker.c b/bfd/linker.c
index 1c466e501d5..e7f0c1ad404 100644
--- a/bfd/linker.c
+++ b/bfd/linker.c
@@ -1854,7 +1854,47 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
 
   return true;
 }
-

+
+/*
+FUNCTION
+	bfd_link_align_section
+
+SYNOPSIS
+	bool bfd_link_align_section (asection *, unsigned int);
+
+DESCRIPTION
+	Increase section alignment if the current section alignment is
+	less than the requested value.  Adjust output section
+	alignment too, so that linker layout adjusts for alignment on
+	the current lang_size_sections pass.  This is important for
+	lang_size_relro_segment.  If the output section alignment
+	isn't adjusted, the linker will place the output section at an
+	address depending on its current alignment.  When sizing the
+	output section, input sections attached transfer any increase
+	in alignment to the output section, which will affect layout
+	for the next sizing pass.  Which is all well and good except
+	that lang_size_relro_segment for the current sizing pass uses
+	that possibly increased alignment with a layout that doesn't
+	suit.
+*/
+
+bool
+bfd_link_align_section (asection *sec, unsigned int align_p2)
+{
+  if (align_p2 > bfd_section_alignment (sec))
+    {
+      if (!bfd_set_section_alignment (sec, align_p2))
+	return false;
+      asection *osec = sec->output_section;
+      if (osec && align_p2 > bfd_section_alignment (osec))
+	{
+	  if (!bfd_set_section_alignment (osec, align_p2))
+	    return false;
+	}
+    }
+  return true;
+}
+
 /* Generic final link routine.  */
 
 bool


More information about the Binutils-cvs mailing list