From 230a788eb28a64d628e623068c44add2a24aa5d3 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Tue, 18 Feb 2025 08:54:06 +1030 Subject: 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. --- 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 4aa814a..c29ff2b 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 df6eb25..f65b6bf 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 1c466e5..e7f0c1a 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 -- cgit v1.1