kallsyms(8) デバッグ用に全てのカーネルシンボルを抽出する

書式

kallsyms [-Vh] kernel_filename

説明

kallsyms はカーネルからスタック以外のシンボルをすべて抽出し、 オブジェクトデータをビルドする。このデータは そのカーネルからリンクすることができ、デバッガから利用できる。

通常のカーネルはモジュールから利用されるシンボルしかエクスポートしない。 デバッグするときには、このエクスポートされたリストだけでなく、 スタックシンボル以外の全てのリストがほしい場合があるかもしれない。 kallsyms はカーネルから全てのセクションとシンボルを抽出し、 セクション・シンボル及びそれらのアドレスのリストを構築し、 __kallsyms セクションのみからなるリロケータブルなオブジェクトを書きだす。 __kallsyms セクションをカーネルにリンクし、 そのカーネルをブートすると、 デバッガは __kallsyms セクションのデータを利用して より多くのシンボルを解決できるようになる。

例えば、デバッガは __kallsyms データを用いて、 以下のようなもののカーネルアドレスを求めることができる:

*
__kallsyms セクションが所属するカーネルまたはモジュール
*
__kallsyms セクションの所属するコード内部のセクション
*
一番近いシンボル

オプション

-h, --help
オプションの一覧を表示して終了する。
-V, --version
kallsyms のバージョンを表示する。

リンク作業

正しく __kallsyms セクションを含んだカーネルを作成するには、 4 段階のリンク作業を行わなければならない (通常は 1 段階のみ)。 kallsyms とリンカは高速だから、P200 なら余分の 3 段階には数秒しかかからない。
1
__kallsyms データがない状態での、カーネルの最初のビルド。 kallsyms をこのリンクの出力に対して実行し、 生カーネルの全てのセクションと全てのシンボルを含む、 リロケータブルなオブジェクトを作成する。
2
再びカーネルをリンクする。今回は (1) での kallsyms の出力も含める。 __kallsyms セクションを追加すると、セクション数や多くのカーネルシンボルの オフセットが変更されるので、もう一度 kallsyms をこの二番目のリンクに実行し、 再びリロケータブルな出力をセーブする。
3
再びカーネルをリンクする。今回は (2) での kallsyms の出力を含める。 kallsyms を一番新しいカーネルに対して実行する。 この段階で __kallsyms セクションのサイズと位置は安定し、 これ以降はカーネルの各セクション・シンボルは変わらない。 kallsyms の出力にはカーネルシンボルの最終値が含まれる。
4
(3) での kallsyms の出力を含め、最終的なカーネルをリンクする。

データフォーマット

__kallsyms セクションは通常と少々異なる。 これはリロケータブルなデータを故意に持たず、 全ての「ポインタ」はセクションへのバイトオフセットか、 あるいは絶対値として表される。 すなわちこのセクションはどこにでも置くことができ、 リロケーションの問題を気にしなくてよい。 これはカーネルイメージの内部に置くことができ、 カーネルイメージの外部にも置くことができ、 ロード直前のモジュールに追加することもでき、 別の領域に置くこともできる、などなど。

/usr/include/sys/kallsyms.h には __kallsyms データのマッピングが記述されている。

ヘッダ

*
ヘッダのサイズ。
*
__kallsyms データ全体のサイズ。文字列も含む。
*
セクション数。メモリにロードされたセクションのみ。
*
__kallsyms ヘッダのスタートから、最初のセクションエントリまでのオフセット。
*
各セクションエントリのサイズ。名前文字列は除く。
*
シンボルの数。
*
__kallsyms ヘッダのスタートから先頭のシンボルエントリまでのオフセット。
*
各シンボルエントリのサイズ。名前文字列は除く。
*
__kallsyms ヘッダのスタートから先頭の文字列までのオフセット。
*
最初のセクションの開始アドレス(注[1])。
*
最後のセクションの終了アドレス(注[1])。

セクションエントリ

ロードされたセクションごとにひとつ。 _kallsyms はロードされるセクションなので、 入力ファイルに __kallsyms セクションが含まれていれば、 このリストに含まれる。
*
カーネル内部でのそのセクションのスタート(注[1])。
*
セクションのサイズ。
*
セクションの名前への、 __kallsyms 文字列のスタートからのオフセット。
*
オリジナルの Elf セクションからのセクションフラグ。

シンボルエントリ

入力ファイルでのシンボルごとにひとつ。 ロードされたセクションにあったシンボルだけが保存される。
*
このシンボルが属する __kallsyms のセクションエントリに対するオフセット。 オフセットは __kallsyms のセクションエントリのスタートからとる。
*
カーネル内部のシンボルのアドレス(注[1])。 シンボルはこのフィールドの昇順で保存される。
*
シンボル名への、 __kallsyms 文字列のスタートからのオフセット。

文字列

NUL 終端文字列のセット。 各名前は __kallsyms の文字列領域のスタートからのオフセットで参照される。

注[1]

これらのフィールドは「全てはオフセット」ルールからは除外されている。 これらはカーネル内部での絶対アドレスである。

履歴

最初のバージョンは 2000 年に Keith Owens <[email protected]> によって 作成された。