这些有什么区别?
mysection ALIGN(4): {...}
和
mysection: {. = ALIGN(4); ...}
和
. = ALIGN(4);
mysection: {...}
结果是否相同?
答案 0 :(得分:1)
请参阅:
$ 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
。
然后在.mysection
开始之后将位置计数器对准0x10008,
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
与0x10004之后的第一个8字节边界0x10008对齐。但是. = 0x20004;
将位置计数器移到碰巧不是8字节对齐的地址,因此.section_b
及其第一个对象bb
的字节数不为8字节。确实,如果我们删除了. = 0x20004;
,
.section_b
和对象bb
将被放置在aa
之后0x10009
处。
答案 1 :(得分:0)
我根据@Mike Kinghan的案例进行了自己的实验。这些数字与他的情况不太吻合,但是测试了相同的技术,但是使用了多个内存区域。
观察:
迈克的案例1(我的案例2和3)根本无法关联。
迈克的案例2(我的案例1)未能按预期方式对齐变量bb
。
迈克的案例3(我的案例5)成功对齐了变量bb
使用SUBALIGN
(我的情况4)可以正确对齐变量bb
,但也可以对齐该输出节中的每个输入节。
$ cat bar.c
char aa __attribute__((section(".section_a"))) = 0;
char bb __attribute__((section(".section_b"))) = 0;
$ gcc -c bar.c
$ cat bar1.lds
MEMORY {
FLASH (rx) : ORIGIN = 0x00000001, LENGTH = 0x100000
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x10000
}
SECTIONS
{
. = 0x10004;
. = ALIGN(8);
.section_a : {
*(.section_a)
} > RAM
_myvar = .;
. = ALIGN(8);
.section_b : {
*(.section_b)
} > FLASH
}
$ ld -T bar1.lds bar.o -o bar.out
$ readelf -s bar.out
Symbol table '.symtab' contains 8 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000020000000 0 SECTION LOCAL DEFAULT 1
2: 0000000000000001 0 SECTION LOCAL DEFAULT 2
3: 0000000000000000 0 SECTION LOCAL DEFAULT 3
4: 0000000000000000 0 FILE LOCAL DEFAULT ABS bar.c
5: 0000000000000001 1 OBJECT GLOBAL DEFAULT 2 bb
6: 0000000020000000 1 OBJECT GLOBAL DEFAULT 1 aa
7: 0000000020000001 0 NOTYPE GLOBAL DEFAULT 1 _myvar
$ cat bar2.lds
MEMORY {
FLASH (rx) : ORIGIN = 0x00000001, LENGTH = 0x100000
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x10000
}
SECTIONS
{
. = 0x10004;
. = ALIGN(8);
.section_a : {
*(.section_a)
} > RAM
_myvar = .;
.section_b ALIGN(8) : {
*(.section_b)
} > FLASH
}
$ ld -T bar2.lds bar.o -o bar.out
ld: address 0x20000009 of bar.out section `.section_b' is not within region `FLASH'
ld: address 0x20000009 of bar.out section `.section_b' is not within region `FLASH'
$ cat bar3.lds
MEMORY {
FLASH (rx) : ORIGIN = 0x00000001, LENGTH = 0x100000
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x10000
}
SECTIONS
{
. = 0x10004;
. = ALIGN(8);
.section_a : {
*(.section_a)
} > FLASH
_myvar = .;
.section_b ALIGN(8) : {
*(.section_b)
} > RAM
}
$ ld -T bar3.lds bar.o -o bar.out
ld: address 0x9 of bar.out section `.section_b' is not within region `RAM'
ld: address 0x9 of bar.out section `.section_b' is not within region `RAM'
$ cat bar4.lds
MEMORY {
FLASH (rx) : ORIGIN = 0x00000001, LENGTH = 0x100000
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x10000
}
SECTIONS
{
. = 0x10004;
. = ALIGN(8);
.section_a : {
*(.section_a)
} > RAM
_myvar = .;
.section_b : SUBALIGN(8){
*(.section_b)
} > FLASH
}
$ ld -T bar4.lds bar.o -o bar.out
$ readelf -s bar.out
Symbol table '.symtab' contains 8 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000020000000 0 SECTION LOCAL DEFAULT 1
2: 0000000000000008 0 SECTION LOCAL DEFAULT 2
3: 0000000000000000 0 SECTION LOCAL DEFAULT 3
4: 0000000000000000 0 FILE LOCAL DEFAULT ABS bar.c
5: 0000000000000008 1 OBJECT GLOBAL DEFAULT 2 bb
6: 0000000020000000 1 OBJECT GLOBAL DEFAULT 1 aa
7: 0000000020000001 0 NOTYPE GLOBAL DEFAULT 1 _myvar
$ cat bar5.lds
MEMORY {
FLASH (rx) : ORIGIN = 0x00000001, LENGTH = 0x100000
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x10000
}
SECTIONS
{
. = 0x10004;
. = ALIGN(8);
.section_a : {
*(.section_a)
} > RAM
_myvar = .;
.section_b : {
. = ALIGN(8);
*(.section_b)
} > FLASH
}
$ ld -T bar5.lds bar.o -o bar.out
$ readelf -s bar.out
Symbol table '.symtab' contains 8 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000020000000 0 SECTION LOCAL DEFAULT 1
2: 0000000000000001 0 SECTION LOCAL DEFAULT 2
3: 0000000000000000 0 SECTION LOCAL DEFAULT 3
4: 0000000000000000 0 FILE LOCAL DEFAULT ABS bar.c
5: 0000000000000008 1 OBJECT GLOBAL DEFAULT 2 bb
6: 0000000020000000 1 OBJECT GLOBAL DEFAULT 1 aa
7: 0000000020000001 0 NOTYPE GLOBAL DEFAULT 1 _myvar