См:
$ cat foo.c
int mysym __attribute__((section(".mysection"))) = 42;
$ gcc -c foo.c
Дело 1
$ cat foo_1.lds
SECTIONS
{
. = 0x10004;
.mysection ALIGN(8): {
*(.mysection)
}
}
$ ld -T foo_1.lds foo.o -o foo1.out
$ readelf -s foo1.out
Symbol table '.symtab' contains 5 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 foo.c
4: 0000000000010008 4 OBJECT GLOBAL DEFAULT 1 mysym
$ readelf -t foo1.out | grep -A3 '.mysection'
[ 1] .mysection
PROGBITS PROGBITS 0000000000010008 0000000000010008 0
0000000000000004 0000000000000000 0 4
[0000000000000003]: WRITE, ALLOC
Дело 2
$ cat foo_2.lds
SECTIONS
{
. = 0x10004;
. = ALIGN(8);
.mysection : {
*(.mysection)
}
}
$ ld -T foo_2.lds foo.o -o foo2.out
$ readelf -s foo2.out
Symbol table '.symtab' contains 5 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 foo.c
4: 0000000000010008 4 OBJECT GLOBAL DEFAULT 1 mysym
$ readelf -t foo2.out | grep -A3 '.mysection'
[ 1] .mysection
PROGBITS PROGBITS 0000000000010008 0000000000010008 0
0000000000000004 0000000000000000 0 4
[0000000000000003]: WRITE, ALLOC
Дело 3
$ cat foo_3.lds
SECTIONS
{
. = 0x10004;
.mysection : {
. = ALIGN(8);
*(.mysection)
}
}
$ ld -T foo_3.lds foo.o -o foo3.out
$ readelf -s foo3.out
Symbol table '.symtab' contains 5 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000010004 0 SECTION LOCAL DEFAULT 1
2: 0000000000000000 0 SECTION LOCAL DEFAULT 2
3: 0000000000000000 0 FILE LOCAL DEFAULT ABS foo.c
4: 0000000000010008 4 OBJECT GLOBAL DEFAULT 1 mysym
$ readelf -t foo3.out | grep -A3 '.mysection'
[ 1] .mysection
PROGBITS PROGBITS 0000000000010004 0000000000010004 0
0000000000000008 0000000000000000 0 4
[0000000000000003]: WRITE, ALLOC
Итак, Дело 1 эквивалентно Дело 2 . Они оба выравнивают .mysection
по
следующая 8-байтовая граница, 0x10008, после 0x10004 и mysym
находится по тому же адресу.
Но Случай 3 делает не выравнивание .mysection
по 0x10008. Остается на 0x10004
.
Затем счетчик местоположения выравнивается по 0x10008 после начала .mysection
,
и mysym
находится по этому адресу.
Во всех случаях адрес первого символа в .mysection
равен 0x10008, но
только в случае 1 и случае 2 это адрес .mysection
Позже
Как влияет случай 2, если несколько разделов помещены в разные области памяти?
Всякий раз, когда скрипт вызывает:
. = ALIGN(N);
просто устанавливает счетчик местоположения на следующую N
-байтную выровненную границу после
его текущее положение. Это все. Итак:
Дело 4
$ cat bar.c
char aa __attribute__((section(".section_a"))) = 0;
char bb __attribute__((section(".section_b"))) = 0;
$ cat bar.lds
SECTIONS
{
. = 0x10004;
. = ALIGN(8);
.section_a : {
*(.section_a)
}
. = 0x20004;
.section_b : {
*(.section_b)
}
}
$ gcc -c bar.c
$ ld -T bar.lds bar.o -o bar.out
$ readelf -s bar.out
Symbol table '.symtab' contains 7 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000010008 0 SECTION LOCAL DEFAULT 1
2: 0000000000020004 0 SECTION LOCAL DEFAULT 2
3: 0000000000000000 0 SECTION LOCAL DEFAULT 3
4: 0000000000000000 0 FILE LOCAL DEFAULT ABS bar.c
5: 0000000000020004 1 OBJECT GLOBAL DEFAULT 2 bb
6: 0000000000010008 1 OBJECT GLOBAL DEFAULT 1 aa
$ readelf -t bar.out | egrep -A3 '(section_a|section_b)'
[ 1] .section_a
PROGBITS PROGBITS 0000000000010008 0000000000010008 0
0000000000000001 0000000000000000 0 1
[0000000000000003]: WRITE, ALLOC
[ 2] .section_b
PROGBITS PROGBITS 0000000000020004 0000000000020004 0
0000000000000001 0000000000000000 0 1
[0000000000000003]: WRITE, ALLOC
Здесь . = ALIGN(8);
имеет эффект .section_a
, и первый объект внутри него,
aa
, выровнены по первой 8-байтовой границе, 0x10008, после 0x10004. Но . = 0x20004;
перемещает счетчик местоположения на адрес, который не выровнен по 8 байтов, поэтому .section_b
и его первый объект bb
не выровнен по 8 байтов. Действительно, если мы удалили . = 0x20004;
, то
.section_b
и объект bb
будет размещен сразу после aa
, в 0x10009
.