/* * シンボルテーブルエントリの書式 */ 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; /* アドレスまたはオフセットまたは行 */ };
Fa n_type フィールドの下位ビットは、シンボルをたかだか 1 つのセグメントに置くため に使用します。どのセグメントに置くかは In 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 して使う) */
シンボルの Fa n_value フィールドは、リンカ ld(1) によって、正しいセグメント内のアドレスに再配置されます。 どのセグメントにも入っていないシンボルの Fa n_value フィールドは、リンカによって変更されません。 さらに、 Fa 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 エントリ */
ここで、コメントには 与えられた Fa n_type の Fa n_name , Fa n_other , Fa n_desc , Fa n_value フィールド と .stab Fa s の典型的な利用法が書かれています。 sdb は、ポータブル C コンパイラ cc(1) によって使われる形式の型の指定子を持っている Fa n_desc フィールドを使います。これらの型の値のフォーマットの詳細はヘッダファイル pcc.h を参照して下さい。
Berkeley パスカルコンパイラ pc(1) は、以下の Fa n_type 値をつかいます:
#define N_PC 0x30 /* グローバルなパスカルシンボル: name,,0,subtype,line */
と、以下のサブ型を使い、別々のコンパイルファイルにまたがる型チェックを 行います。
1 ソースファイル名 2 インクルードされたファイル名 3 グローバルなラベル 4 グローバルな定数 5 グローバルな型 6 グローバルな変数 7 グローバルな関数 8 グローバルな手続き 9 外部関数 10 外部手続き 11 ライブラリ変数 12 ライブラリルーチン