diff options
author | Alan Modra <amodra@gmail.com> | 2025-02-18 08:54:06 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2025-02-18 09:16:57 +1030 |
commit | 230a788eb28a64d628e623068c44add2a24aa5d3 (patch) | |
tree | 64230ac1d6ff378737f5c089efe2a556107951e3 | |
parent | db20cb1197cc7c5e94a26aac370267ac69f18ab5 (diff) | |
download | binutils-230a788eb28a64d628e623068c44add2a24aa5d3.zip binutils-230a788eb28a64d628e623068c44add2a24aa5d3.tar.gz binutils-230a788eb28a64d628e623068c44add2a24aa5d3.tar.bz2 |
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.
-rw-r--r-- | bfd/bfd-in2.h | 2 | ||||
-rw-r--r-- | bfd/elflink.c | 9 | ||||
-rw-r--r-- | 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 |