.bss セクションがディスクに格納されていないことがわかっていますが、メモリ内の .bss セクションはゼロに初期化する必要があります。しかし、メモリのどこに取り込めばよいのでしょうか? ELF ヘッダーに表示される情報はありますか、それとも .bss セクションはデータ セクションの隣に表示される可能性がありますか??
2 に答える
このすばらしい記事で詳しく説明されているように、BSSはデータとヒープの間にあります。
各セクションのサイズは、次を使用して確認できますsize
。
cnicutar@lemon:~$ size try
text data bss dec hex filename
1108 496 16 1620 654 try
bss セグメントがメモリ内のどこにあるかを知るには、 を実行して行のAddr列readelf -S program
を確認するだけで十分です。.bss
.data
ほとんどの場合、初期化されたデータ セクション ( ) が直前に来ることもわかります。つまり、セクションのAddr+Sizeが.data
セクションの開始アドレスと一致することがわかります.bss
。
ただし、必ずしもそうであるとは限りません。これらは歴史的な慣例であり、ELF 仕様(プラットフォーム固有の補足資料と一緒に読む必要があります。たとえば、32 ビット x86 マシンをカバーする章の第 5 章) では、はるかに高度な構成が可能であり、それらのすべてが Linux でサポートされているわけではありません。
たとえば、セクションがまったく呼び出さ.bss
れない場合があります。BSS セクションをそのようなものにする唯一の 2 つのプロパティは次のとおりです。
- セクションは でマークされ
SHT_NOBITS
ます (つまり、メモリ内のスペースを必要としますが、ストレージには必要ありません)。これは、NOBITS
のreadelf
出力のように表示されます。 PT_LOAD
これは、ロード可能 ( )、読み取り可能 (PF_R
)、および書き込み可能 (PF_W
) セグメントにマップされます。このようなセグメントは、メモリ内よりもストレージの方が短くなります (p_filesz
<p_memsz
)。
複数の BSS セクションを持つことができます。PowerPC 実行可能ファイルには、初期化されていないデータ変数用の.sbss
とがある場合があります。.sbss2
最後に、BSS セクションは必ずしもデータ セクションまたはヒープに隣接しているわけではありません。Linux カーネル(より具体的にはload_elf_binary
関数)をチェックすると、BSS セクション (より正確には、BSS がマップされるセグメント) がコードと初期化されたデータでインターリーブされている可能性があることがわかります。Linux カーネルはそれをうまく処理します。