Skip to content

Commit

Permalink
changed ld subalign priority
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
vbe-sc authored and ouuleilei-bot committed Feb 27, 2024
1 parent 324998b commit 3f24ef6
Showing 1 changed file with 15 additions and 10 deletions.
25 changes: 15 additions & 10 deletions ld/ldlang.c
Original file line number Diff line number Diff line change
Expand Up @@ -5262,17 +5262,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;

Expand Down

0 comments on commit 3f24ef6

Please sign in to comment.