STAB(5)

名称
stab - シンボルテーブルの型

書式
<stab.h>

解説
<stab.h> ファイルは a.out ファイルで使われる、シンボルテーブルのいくつかの n_type フィールド値を定義します。 これらは、恒久的なシンボル形式であり (つまり、ローカルなラベルなどではない)、古いデバッガである sdb や Berkeley パスカルコンパイラ pc(1) で使われます。 シンボルテーブルエントリは .stabs アセンブラディレクティブによって生成することができます。 ここでは、ダブルクォートで区切られた名前、シンボルの型、シンボルに ついての char 1 つと short 1 つ分の情報、 そして (通常はアドレスを示す) unsigned long の整数を指定できます。 アドレスフィールドに明示的なラベルを生成するのを避けるため、 .stabd ディレクティブを使い、現在の場所を指すようにすることができます。 もし名前が必要ない場合、 .stabn ディレクティブを使うことで、シンボルテーブルエントリを生成することができます。 ローダは、 .stab ディレクティブによって生成されたシンボルテーブルのエントリ順を変えないこと を保証します。 a.out(5) に記述されているように、シンボルテーブルの要素は以下の構造を持ちます。

    /*
    * シンボルテーブルエントリの書式
    */
    struct nlist {
    	union {
    		char	*n_name;	/* コア内部 (in-core) で使用 */
    		long	n_strx;		/* ファイル文字列表へのインデックス */
    	} n_un;
    	unsigned char	n_type;		/* 型のフラグ */
    	char		n_other;	/* 使用されていない */
    	short		n_desc;		/* 以下の struct desc 参照 */
    	unsigned	n_value;	/* アドレスまたはオフセットまたは行 */
    };

n_type フィールドの下位ビットは、シンボルをたかだか 1 つのセグメントに置くため に使用します。どのセグメントに置くかは <a.out.h> 内で定義されている以下のマスクに基づきます。 これらのセグメントビットを設定しないようにすることで、シンボルをどの セグメントにも属さないようにすることができます。

    /*
    * n_type の単純な値
    */
    #define	N_UNDF	0x0	/* 定義されていない */
    #define	N_ABS	0x2	/* 絶対指定 */
    #define	N_TEXT	0x4	/* テキスト */
    #define	N_DATA	0x6	/* データ */
    #define	N_BSS	0x8	/* bss */
    #define	N_EXT	01	/* 外部参照を表すビット(or して使う) */

シンボルの n_value フィールドは、リンカ ld(1) によって、正しいセグメント内のアドレスに再配置されます。 どのセグメントにも入っていないシンボルの n_value フィールドは、リンカによって変更されません。 さらに、 n_type フィールドで、以下のビットのいずれもセットされていない場合は、 リンカは自分が持っている規則にしたがって、 いくつかのシンボルを破棄します。

    /*
    * その他の永続的なシンボルテーブルエントリでは、N_STAB のいくつかのビットが
    * セットされています。これらは、<stab.h> 内に記述があります。
    */
    #define	N_STAB	0xe0	/* もしこれらのビットのいずれかがセットされていれば破棄されません */

これで、112 (7 * 16) 個までのシンボルを、さまざまなセグメントで分けて 定義できるようになります。 これらのいくつかについては既に述べられています。 古いシンボリックデバッガ sdb は、以下の n_type 値を使います。

    #define	N_GSYM	0x20	/* グローバルシンボル : name,,0,type,0 */
    #define	N_FNAME	0x22	/* 手続き名 (f77 kludge): name,,0 */
    #define	N_FUN	0x24	/* 手続き: name,,0,linenumber,address */
    #define	N_STSYM	0x26	/* 静的シンボル: name,,0,type,address */
    #define	N_LCSYM	0x28	/* .lcomm シンボルl: name,,0,type,address */
    #define	N_RSYM	0x40	/* レジスタシンボル: name,,0,type,register */
    #define	N_SLINE	0x44	/* ソース行: 0,,0,linenumber,address */
    #define	N_SSYM	0x60	/* structure elt: name,,0,type,struct_offset */
    #define	N_SO	0x64	/* ソースファイル名: name,,0,0,address */
    #define	N_LSYM	0x80	/* ローカルシンボル: name,,0,type,offset */
    #define	N_SOL	0x84	/* #includeされたファイル名: name,,0,0,address */
    #define	N_PSYM	0xa0	/* パラメータ: name,,0,type,offset */
    #define	N_ENTRY	0xa4	/* 別のエントリ: name,linenumber,address */
    #define	N_LBRAC	0xc0	/* 左かっこ: 0,,0,nesting level,address */
    #define	N_RBRAC	0xe0	/* 右かっこ: 0,,0,nesting level,address */
    #define	N_BCOMM	0xe2	/* 共通の開始符号: name,, */
    #define	N_ECOMM	0xe4	/* 共通の終了符号: name,, */
    #define	N_ECOML	0xe8	/* (ローカル名の)共通の終了符号: ,,address */
    #define	N_LENG	0xfe	/* 長さ情報を持った2番目の stab エントリ */

ここで、コメントには 与えられた n_type の n_name, n_other, n_desc, n_value フィールド と .stab s の典型的な利用法が書かれています。 sdb は、ポータブル C コンパイラ cc(1) によって使われる形式の型の指定子を持っている n_desc フィールドを使います。これらの型の値のフォーマットの詳細はヘッダファイル pcc.h を参照して下さい。

Berkeley パスカルコンパイラ pc(1) は、以下の n_type 値をつかいます:

    #define	N_PC	0x30	/* グローバルなパスカルシンボル: name,,0,subtype,line */

と、以下のサブ型を使い、別々のコンパイルファイルにまたがる型チェックを 行います。

    1	ソースファイル名
    2	インクルードされたファイル名
    3	グローバルなラベル
    4	グローバルな定数
    5	グローバルな型
    6	グローバルな変数
    7	グローバルな関数
    8	グローバルな手続き
    9	外部関数
    10	外部手続き
    11	ライブラリ変数
    12	ライブラリルーチン

関連項目
as(1), ld(1), a.out(5)

バグ
もっと基本的な形式が必要でしょう。

歴史
stab ファイルは 4.0BSD から登場しました。