changed ld subalign priority
Checks
Commit Message
Hi,
According to the GNU LD documentation:
<<You 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.>>
However, let's consider the behaviour of GNU ld
Suppose we have the following test:
$ cat one.c
char a_one __attribute__((__aligned__(8))) __attribute__((section(".mysection"))) = 0;
and the following linker script:
$ cat foo.lds
SECTIONS
{
. = 0x10024;
.mysection : SUBALIGN(4) {
*(.mysection)
}
.note.gnu.property ALIGN(8) : {
*(.note.gnu.property)
*(.comment)
}
}
We suppose that the section .mysection would be aligned by 4 despite of alignment attribute 8 in source code.
However, after linking object file "one.o" __ with gnu ld linker the symbol .mysection is aligned by 8
$ gcc -c one.c
$ ld -T foo.lds one.o -o foo.out
$ objdump -h foo.out
foo2.out: file format elf64-x86-64Sections:
Idx Name Size VMA LMA File off Algn
0 .mysection 00000001 0000000000010028 0000000000010028 00001028 2**3
CONTENTS, ALLOC, LOAD, DATA
1 .note.gnu.property 0000004b 0000000000010030 0000000000010030 00001030 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
It seems like this is contrary to documented behavior.
Below you can see the patch fixed this problem.
---
Best regards,
Vladislav
---
ld/ldlang.c | 25 +++++++++++++++----------
1 file changed, 15 insertions(+), 10 deletions(-)
Comments
Hi Vladislav,
Thanks for reporting this problem.
In the future, please could I ask that you use the binutils bug
reporting system, as this allows us to keep track of problems and
to reference them in comments:
https://sourceware.org/bugzilla/
> Below you can see the patch fixed this problem.
Thank you. I have applied a simplified version of your patch
and added your example code as a new test in the linker testsuite.
Cheers
Nick
@@ -5349,17 +5349,22 @@ size_input_section
bfd_size_type alignment_needed;
/* 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. */
-
- if (output_section_statement->subsection_alignment != NULL)
- i->alignment_power
- = exp_get_power (output_section_statement->subsection_alignment,
- "subsection alignment");
+ 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.
+ 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,
+ "subsection alignment");
+ o->alignment_power = i->alignment_power;
+ }
- if (o->alignment_power < i->alignment_power)
- o->alignment_power = i->alignment_power;
+ else if (o->alignment_power < i->alignment_power)
+ o->alignment_power = i->alignment_power;
alignment_needed = align_power (dot, i->alignment_power) - dot;