SUBALIGN
специально для регулировки выравнивания входных секций в выходных секциях.
Для иллюстрации:
$ cat one.c
char a_one __attribute__((section(".mysection"))) = 0;
char b_one __attribute__((section(".mysection"))) = 0;
$ cat two.c
char a_two __attribute__((section(".mysection"))) = 0;
char b_two __attribute__((section(".mysection"))) = 0;
$ gcc -c one.c two.c
Дело 1
$ cat foo_1.lds
SECTIONS
{
. = 0x10004;
.mysection ALIGN(8) : {
*(.mysection)
}
}
$ ld -T foo_1.lds one.o two.o -o foo1.out
$ readelf -s foo1.out
Symbol table '.symtab' contains 9 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000010008 0 SECTION LOCAL DEFAULT 1
2: 0000000000000000 0 SECTION LOCAL DEFAULT 2
3: 0000000000000000 0 FILE LOCAL DEFAULT ABS one.c
4: 0000000000000000 0 FILE LOCAL DEFAULT ABS two.c
5: 000000000001000b 1 OBJECT GLOBAL DEFAULT 1 b_two
6: 0000000000010008 1 OBJECT GLOBAL DEFAULT 1 a_one
7: 0000000000010009 1 OBJECT GLOBAL DEFAULT 1 b_one
8: 000000000001000a 1 OBJECT GLOBAL DEFAULT 1 a_two
$ readelf -t foo1.out | grep -A3 mysection
[ 1] .mysection
PROGBITS PROGBITS 0000000000010008 0000000000010008 0
0000000000000004 0000000000000000 0 1
[0000000000000003]: WRITE, ALLOC
Здесь ALIGN(8)
выравнивает .mysection
со следующей 8-байтовой границей, 0x10008,
после 0x10004.
Символ char
a_one
, поступающий из секции ввода one.o(.mysection)
, находится в начале .mysection
за следующим байтом следует b_two
, также поступающий из секции ввода one.o(.mysection)
. На следующем байте
a_two
, из секции ввода two.o(.mysection)
, затем b_two
, также из two.o(.mysection)
. Все 4
объекты из всех входных секций *(.mysection)
просто помещаются вплотную от начала выходной секции .mysection
.
Дело 2
$ cat foo_2.lds
SECTIONS
{
. = 0x10004;
.mysection ALIGN(8) : SUBALIGN(16) {
*(.mysection)
}
}
$ ld -T foo_2.lds one.o two.o -o foo2.out
$ readelf -s foo2.out
Symbol table '.symtab' contains 9 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000010008 0 SECTION LOCAL DEFAULT 1
2: 0000000000000000 0 SECTION LOCAL DEFAULT 2
3: 0000000000000000 0 FILE LOCAL DEFAULT ABS one.c
4: 0000000000000000 0 FILE LOCAL DEFAULT ABS two.c
5: 0000000000010021 1 OBJECT GLOBAL DEFAULT 1 b_two
6: 0000000000010010 1 OBJECT GLOBAL DEFAULT 1 a_one
7: 0000000000010011 1 OBJECT GLOBAL DEFAULT 1 b_one
8: 0000000000010020 1 OBJECT GLOBAL DEFAULT 1 a_two
$ readelf -t foo2.out | grep -A3 mysection
[ 1] .mysection
PROGBITS PROGBITS 0000000000010008 0000000000010008 0
000000000000001a 0000000000000000 0 16
[0000000000000003]: WRITE, ALLOC
На этот раз 8-байтовый выровненный адрес .mysection
не изменяется. Но
Эффект SUBALIGN(16)
- это символ a_one
, поступающий с входа
секция one.o(.mysection)
размещается на следующем 16-байтовом
граница , 0x10010, после начала .mysection
и символ b_one
, идущий от
такая же секция ввода находится на следующем байте. Но символ a_two
, поступающий из секции ввода
two.o(.mysection)
находится на следующей 16-байтовой границе, 0x10020; и b_two
, ближайшие
также от two.o(.mysection)
, после этого 1 байт.