From 60856b5cdafc520538688258a8ce4ae8be2a8477 Mon Sep 17 00:00:00 2001 From: Vladislav Belov Date: Wed, 28 Feb 2024 16:36:37 +0000 Subject: Fix implementation of SUBALIGN. --- ld/ldlang.c | 13 ++++++++----- ld/testsuite/ld-scripts/align.exp | 8 ++++++++ ld/testsuite/ld-scripts/subalign.d | 12 ++++++++++++ ld/testsuite/ld-scripts/subalign.s | 20 ++++++++++++++++++++ ld/testsuite/ld-scripts/subalign.t | 20 ++++++++++++++++++++ 5 files changed, 68 insertions(+), 5 deletions(-) create mode 100644 ld/testsuite/ld-scripts/subalign.d create mode 100644 ld/testsuite/ld-scripts/subalign.s create mode 100644 ld/testsuite/ld-scripts/subalign.t (limited to 'ld') diff --git a/ld/ldlang.c b/ld/ldlang.c index 229401c..54d1af6 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -5468,13 +5468,16 @@ size_input_section /* Align this section first to the input sections requirement, then to the output section's requirement. If this alignment is greater than any seen before, then record it too. Perform - the alignment by inserting a magic 'padding' statement. */ + the alignment by inserting a magic 'padding' statement. + We can force input section alignment within an output section + by using SUBALIGN. The value specified overrides any alignment + given by input sections, whether larger or smaller. */ if (output_section_statement->subsection_alignment != NULL) - i->alignment_power - = exp_get_power (output_section_statement->subsection_alignment, - output_section_statement, - "subsection alignment"); + o->alignment_power = i->alignment_power = + exp_get_power (output_section_statement->subsection_alignment, + output_section_statement, + "subsection alignment"); if (o->alignment_power < i->alignment_power) o->alignment_power = i->alignment_power; diff --git a/ld/testsuite/ld-scripts/align.exp b/ld/testsuite/ld-scripts/align.exp index ea0500d..e34825e 100644 --- a/ld/testsuite/ld-scripts/align.exp +++ b/ld/testsuite/ld-scripts/align.exp @@ -48,6 +48,14 @@ if ![is_aout_format] { run_dump_test align5 } run_dump_test align2c + +if { [is_elf_format] } { + # FIXME: Currently this test is only run for ELF targets as other formats + # do not necessarily support these large alignments. It could be tweaked + # to work with other formats. + run_dump_test subalign +} + set LDFLAGS "$saved_LDFLAGS" if { [is_elf_format] && ![uses_genelf] } { diff --git a/ld/testsuite/ld-scripts/subalign.d b/ld/testsuite/ld-scripts/subalign.d new file mode 100644 index 0000000..37483a3 --- /dev/null +++ b/ld/testsuite/ld-scripts/subalign.d @@ -0,0 +1,12 @@ +# ld: -T subalign.t --no-error-rwx-segments -e 0 +# objdump: -h --wide +# Ensure that SUBALIGN fixes the alignment of the output section. +# Check that ALIGN provides a minimum alignment, although allow the target to require a larger value. + +#... + . .mysection1.*2\*\*2.* +#... + . .mysection2.*2\*\*[4-9].* +#... + . .mysection3.*2\*\*[3-9].* +#... diff --git a/ld/testsuite/ld-scripts/subalign.s b/ld/testsuite/ld-scripts/subalign.s new file mode 100644 index 0000000..5589570 --- /dev/null +++ b/ld/testsuite/ld-scripts/subalign.s @@ -0,0 +1,20 @@ + .file "subalign.c" + .text + .globl a_one + .section .mysection1,"aw" + .align 8 +a_one: + .zero 1 + + .globl b_one + .section .mysection2,"aw" + .align 8 +b_one: + .zero 1 + + .globl c_one + .section .mysection3,"aw" + .align 8 +c_one: + .zero 1 + diff --git a/ld/testsuite/ld-scripts/subalign.t b/ld/testsuite/ld-scripts/subalign.t new file mode 100644 index 0000000..36ee259 --- /dev/null +++ b/ld/testsuite/ld-scripts/subalign.t @@ -0,0 +1,20 @@ +SECTIONS +{ + . = 0x10024; + + .mysection1 : SUBALIGN(4) { + *(.mysection1) + } + + .mysection2 : ALIGN(16) { + *(.mysection2) + } + + .mysection3 : { + *(.mysection3) + } + + /DISCARD/ : { + *(*) + } +} -- cgit v1.1