]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
PR32690, assertion failure in lang_size_relro_segment
authorAlan Modra <amodra@gmail.com>
Mon, 17 Feb 2025 22:24:06 +0000 (08:54 +1030)
committerAlan Modra <amodra@gmail.com>
Mon, 17 Feb 2025 22:46:57 +0000 (09:16 +1030)
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.

bfd/bfd-in2.h
bfd/elflink.c
bfd/linker.c

index 4aa814abe79d4848b54b9ccbb45bdfae93b906b9..c29ff2bbc669f61ec6bc0858133593922e88885c 100644 (file)
@@ -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) \
index df6eb250961cb69002f4e8f250e1e92ba70ba30c..f65b6bf0f9524e030054e830ffbbd196f49d875c 100644 (file)
@@ -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);
index 1c466e501d5063994293baf8047146fe114cbff1..e7f0c1ad40475498f7844056e9f30341ad48eff9 100644 (file)
@@ -1854,7 +1854,47 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
 
   return true;
 }
-\f
+
+/*
+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