Open2
alignas と bss セクションのアライメント
physboot のソースコードで、.bss セクションが 16 バイトアライメントされていることを仮定している箇所があった。
しかし、明示的に .bss セクションを 16 バイトアライメントしているコードはなかった。
alignas(16) でメンバーをアライメントした構造体を、.bss セクションの変数として定義すると、.bss セクションが 16 バイトアライメントされる。
main.cpp
struct BootStack {
alignas(16) char stack[4096];
};
BootStack boot_stack;
int main(void) {
return 0;
}
$ clang main.cpp
$ readelf -a a.out
(省略)
[23] .bss NOBITS 0000000000404030 00003028
0000000000001010 0000000000000000 WA 0 0 16
最後の 16 が、セクションのアライメント。
alignas(8)の場合
main.cpp
struct BootStack {
alignas(8) char stack[4096];
};
BootStack boot_stack;
int main(void) {
return 0;
}
$ clang main.cpp
$ readelf -a a.out
(省略)
[23] .bss NOBITS 0000000000404028 00003028
0000000000001008 0000000000000000 WA 0 0 8
最後の 8 が、セクションのアライメント。
main.S
.bss
.balign 16
.int 0
$ clang -c main.S
$ readelf -a main.o
[ 3] .bss NOBITS 0000000000000000 00000040
0000000000000004 0000000000000000 WA 0 0 16
.bss セクションのアライメントは 16。
main.S
.bss
.balign 8
.int 0
.balign 16
.int 0
$ clang -c main.S
$ readelf -a main.o
[ 3] .bss NOBITS 0000000000000000 00000040
0000000000000014 0000000000000000 WA 0 0 16
.bss セクションのアライメントは 16。
main.S
.bss
.balign 8
.int 0
.balign 32
.int 0
$ clang -c main.S
$ readelf -a main.o
[ 3] .bss NOBITS 0000000000000000 00000040
0000000000000024 0000000000000000 WA 0 0 32
.bss セクションのアライメントは 32。
つまり、一番大きいアライメントに合わせられる模様。