Open2

alignas と bss セクションのアライメント

junkawajunkawa

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 が、セクションのアライメント。

junkawajunkawa
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。

つまり、一番大きいアライメントに合わせられる模様。