From: Alan Modra Date: Mon, 17 Feb 2025 22:24:06 +0000 (+1030) Subject: PR32690, assertion failure in lang_size_relro_segment X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=230a788eb28a64d628e623068c44add2a24aa5d3;p=thirdparty%2Fbinutils-gdb.git 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 --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