オブジェクトファイルのシンボルテーブルには、プログラムのシンボル定義とシンボル参照の検索と再配置に必要となる情報が格納されます。シンボルテーブルインデックスは、この配列への添字です。インデックス 0 はシンボルテーブルの先頭エントリを指定し、また未定義シンボルインデックスとして機能します。Table 12–24 を参照してください。
シンボルテーブルエントリの形式は、次のとおりです。sys/elf.h を参照してください。
typedef struct { Elf32_Word st_name; Elf32_Addr st_value; Elf32_Word st_size; unsigned char st_info; unsigned char st_other; Elf32_Half st_shndx; } Elf32_Sym; typedef struct { Elf64_Word st_name; unsigned char st_info; unsigned char st_other; Elf64_Half st_shndx; Elf64_Addr st_value; Elf64_Xword st_size; } Elf64_Sym;
オブジェクトファイルのシンボル文字列テーブルへのインデックス (シンボル名の文字表現を保持)。値が 0 以外の場合、その値はシンボル名を与える文字列テーブルインデックスを表します。値が 0 の場合、シンボルテーブルエントリに名前は存在しません。
関連付けられているシンボルの値。この値は、状況に応じて絶対値またはアドレスを表します。シンボル値 を参照してください。
多くのシンボルは、関連付けられているサイズを持っています。たとえば、データオブジェクトのサイズは、オブジェクトに存在するバイト数です。このメンバーは、シンボルがサイズを持っていない場合またはサイズが不明な場合、値 0 を保持します。
シンボルの種類および結び付けられる属性。値と意味のリストを、Table 12–21 に示します。次のコードは、値の処理方法を示します。sys/elf.h を参照してください。
#define ELF32_ST_BIND(info) ((info) >> 4) #define ELF32_ST_TYPE(info) ((info) & 0xf) #define ELF32_ST_INFO(bind, type) (((bind)<<4)+((type)&0xf)) #define ELF64_ST_BIND(info) ((info) >> 4) #define ELF64_ST_TYPE(info) ((info) & 0xf) #define ELF64_ST_INFO(bind, type) (((bind)<<4)+((type)&0xf))
シンボルの可視性。値と意味のリストを、Table 12–23 に示します。次のコードは、32 ビットオブジェクトと 64 ビットオブジェクトの両方の値を操作する方法を示しています。その他のビットは 0 に設定され、特に意味はありません。
#define ELF32_ST_VISIBILITY(o) ((o)&0x3) #define ELF64_ST_VISIBILITY(o) ((o)&0x3)
すべてのシンボルテーブルエントリは、何らかのセクションに関して定義されます。このメンバーは、該当するセクションヘッダーテーブルインデックスを保持します。いくつかのセクションインデックスは、特別な意味を示します。Table 12–4 を参照してください。
このメンバーに SHN_XINDEX が含まれる場合は、実際のセクションヘッダーインデックスが大きすぎてこのフィールドに入りません。実際の値は、タイプ SHT_SYMTAB_SHNDX の関連するセクション内に存在します。
シンボルのバインディングは、st_info フィールドで決定されますが、これにより、リンクの可視性と動作が決定します。
|
局所シンボル。局所シンボルは、局所シンボルの定義が存在するオブジェクトファイルの外部では見えません。同じ名前の局所シンボルは、互いに干渉することなく複数のファイルに存在できます。
大域シンボル。大域シンボルは、結合されるすべてのオブジェクトファイルで見ることができます。あるファイルの大域シンボルの定義は、その大域シンボルへの別ファイルの未定義参照を解決します。
ウィークシンボル。ウィークシンボルは大域シンボルに似ていますが、ウィークシンボルの定義の優先順位は大域シンボルの定義より低いです。
この範囲の値 (両端の値を含む) は、オペレーティングシステム固有のセマンティクスのために予約されています。
この範囲の値は、プロセッサ固有のセマンティクスのために予約されています。
大域シンボルとウィークシンボルは、主に 2 つの点で異なります。
リンカーがいくつかの再配置可能オブジェクトファイルを結合する場合は、同じ名前を持つ複数の STB_GLOBAL シンボルは定義できません。ただし、定義された大域シンボルが存在している場合、同じ名前のウィークシンボルが現れてもエラーは発生しません。リンカーは大域定義を使用し、ウィーク定義を無視します。
同様に、共有シンボルが存在している場合にそれと同じ名前のウィークシンボルが現れても、エラーは発生しません。リンカーは共通定義を使用し、ウィーク定義を無視します。共通シンボルは、SHN_COMMON を保持する st_shndx フィールドを持ちます。シンボル解決を参照してください。
リンカーがアーカイブライブラリを検索すると、未定義または一時的な大域シンボル定義が存在するアーカイブメンバーが抽出されます。メンバーの定義は、大域シンボルまたはウィークシンボルになります。
リンカーはデフォルトでは、未定義のウィークシンボルを解決するためのアーカイブメンバーを抽出しません。解決されていないウィークシンボルは、値 0 を持ちます。–z weakextract を使用すると、このデフォルトの動作をオーバーライドします。このオプションを使用すると、ウィーク参照がアーカイブメンバーを抽出できます。
各シンボルテーブルにおいて、STB_LOCAL 結合を持つすべてのシンボルは、ウィークシンボルと大域シンボルの前に存在します。セクションに記述されているとおり、シンボルテーブルセクションの sh_info セクションヘッダーメンバーは、最初のローカルではないシンボルに対するシンボルテーブルインデックスを保持します。
シンボルのタイプは st_info フィールドで指定され、これにより、関連付けられた実体の一般的な分類が決定されます。
|
シンボルの種類は指定されません。
シンボルは、データオブジェクト (変数や配列など) と関連付けられています。
シンボルは、関数またはほかの実行可能コードに関連付けられています。
シンボルは、セクションに関連付けられています。この種類のシンボルテーブルエントリは主に再配置を行うために存在しており、通常、STB_LOCAL に結び付けられています。
慣例により、シンボルの名前はオブジェクトファイルに対応するソースファイルの名前を与えます。ファイルシンボルは STB_LOCAL に結び付けられており、セクションインデックスは SHN_ABS です。このシンボルは、存在する場合、ファイルのほかの STB_LOCAL シンボルの前に存在します。
SHT_SYMTAB のシンボルインデックス 1 は、そのオブジェクトファイルを表す STT_FILE シンボルです。慣例により、このシンボルのあとにはファイル STT_SECTION シンボルが続きます。これらのセクションシンボルの後には、ローカルになった大域シンボルが続きます。
このシンボルは、初期設定されていない共通ブロックを表します。このシンボルは、STT_OBJECT とまったく同じに扱われます。
シンボルは、スレッド固有ストレージの実体を指定します。定義されている場合、実際のアドレスではなく、シンボルに割り当てられたオフセットを提供します。
スレッドローカルストレージの再配置では、タイプが STT_TLS のシンボルしか参照できません。割り当て可能なセクションからタイプが STT_TLS のシンボルを参照するには、特別なスレッドローカルストレージ再配置を使用するしか方法がありません。詳細は、Chapter 14, スレッド固有ストレージ (TLS)を参照してください。割り当てができないセクションからタイプが STT_TLS のシンボルを参照する際には、この制限はありません。
この範囲の値 (両端の値を含む) は、オペレーティングシステム固有のセマンティクスのために予約されています。
この範囲の値は、プロセッサ固有のセマンティクスのために予約されています。
シンボルの可視性は、その st_other フィールドで決まります。この可視性は、再配置可能オブジェクトで指定できます。シンボルの可視性により、シンボルが実行可能ファイルまたは共有オブジェクトの一部になった後のシンボルへのアクセス方法が定義されます。
|
STV_DEFAULT 属性を持つシンボルの可視性は、シンボルの結合タイプで指定されたものになります。大域シンボルおよびウィークシンボルは、それらの定義するコンポーネント (実行可能ファイルまたは共有オブジェクト) の外から見ることができます。局所シンボルは、「隠されて」います。大域シンボルおよびウィークシンボルは、横取りすることもできます。別のコンポーネントの同じ名前の定義によってこれらのシンボルに割り込むこともできます。
現在のコンポーネント内で定義されたシンボルは、それがほかのコンポーネント内で参照可能であるが横取り可能ではない場合、保護されています。定義コンポーネント内からシンボルへの参照など、あらゆる参照について、コンポーネント内の定義に解決する必要があります。この解決は、シンボル定義がデフォルト規則によって割り込みを行う別のコンポーネント内に存在する場合も、実行する必要があります。STB_LOCAL 結合を持つシンボルは、STV_PROTECTED 可視性を持ちません。
現在のコンポーネント内で定義されたシンボルは、その名前がほかのコンポーネントから参照することができない場合、「隠されて」います。そのようなシンボルは、保護される必要があります。この属性は、コンポーネントの外部インタフェースの管理に使用されます。そのようなシンボルによって指定されたオブジェクトは、そのアドレスが外部に渡された場合でも、ほかのコンポーネントから参照可能です。
再配置可能オブジェクトに含まれた「隠された」シンボルは、そのオブジェクトが実行可能ファイルまたは共有オブジェクトに含まれる時には、削除されるか STB_LOCAL 結合に変換されます。
この可視性属性は STV_HIDDEN と同じものとして解釈されます。
この可視性属性によって、シンボルのスコープが大域に維持されます。ほかのどのようなシンボル可視性テクニックを使っても、この可視性を降格または削除することはできません。STB_LOCAL 結合を持つシンボルは、STV_EXPORTED 可視性を持ちません。
この可視性属性によって、シンボルのスコープが大域に維持され、プロセス内のすべての参照はシンボル定義の 1 つのインスタンスだけにバインドされます。ほかのどのようなシンボル可視性テクニックを使っても、この可視性を降格または削除することはできません。STB_LOCAL 結合を持つシンボルは、STV_SINGLETON 可視性を持ちません。STV_SINGLETON に直接バインドすることはできません。
この可視性属性は STV_HIDDEN を継承します。現在のコンポーネント内でこの属性が定義されたシンボルは、ほかのコンポーネントから見えません。このシンボルは、そのコンポーネントを使用する動的実行可能ファイルまたは共有オブジェクトのシンボルテーブルには書き込まれません。
STV_SINGLETON 可視性属性は、リンク編集中、実行可能ファイルまたは共有オブジェクト内のシンボルの解決に影響する可能性があります。プロセス内の参照には、シングルトンの 1 つのインスタンスだけをバインドできます。
STV_SINGLETON は STV_DEFAULT 可視性属性と一緒に使用できますが、STV_SINGLETON が優先されます。STV_EXPORT は STV_DEFAULT 可視性属性と一緒に使用できますが、STV_EXPORT が優先されます。STV_SINGLETON または STV_EXPORT 可視性は、それ以外の可視性属性とは一緒に使用できません。そのような場合、リンク編集にとって致命的とみなされます。
ほかの可視性の属性は、リンク編集中、実行可能ファイルまたは共有オブジェクト内のシンボルの解決にはまったく影響をおよぼしません。このような解決は、結合タイプによって制御されます。いったんリンカーがその解決を選択すると、これらの属性は次の 2 つの必要条件を課します。どちらの必要条件も、リンクされるコード内の参照は、属性の利点を利用するために最適化されるという事実に基づくものです。
すべてのデフォルトでない可視性の属性は、シンボルの参照に適用される際、「その参照を満たす定義は、リンクされているオブジェクト内で提供されなければならない」ということを暗黙の条件としています。この種のシンボルの参照がリンクされるオブジェクト内に定義を持たない場合は、その参照は STB_WEAK 結合を持つ必要があります。この場合、参照は 0 に解決されます。
名前への参照または名前の定義がデフォルトでない可視性の属性を持つシンボルである場合、その可視性の属性はリンクされているオブジェクト内の解決シンボルへ伝達されなければなりません。シンボルの特定のインスタンスに対して異なる可視性の属性が指定されている場合は、もっとも制約の厳しい可視性の属性が、リンクされるオブジェクト内の解決シンボルへ伝達されなければなりません。属性は、もっとも制約の少ないものからもっとも制約の厳しいものの順に、STV_PROTECTED、STV_HIDDEN、STV_INTERNAL となります。
シンボル値がセクション内の特定位置を参照すると、セクションインデックスメンバー st_shndx は、セクションヘッダーテーブルへのインデックスを保持します。再配置時にセクションが移動すると、シンボル値も変化します。シンボルへの参照はプログラム内の同じ位置を指し示し続けます。いくつかの特別なセクションインデックス値は、ほかのセマンティクスが付けられています。
このシンボルは、まだ割り当てられていない共通ブロックを示します。シンボル値は、セクションの sh_addralign メンバーに類似した整列制約を与えます。リンカーは st_value の倍数のアドレスにシンボル用のストレージを割り当てます。シンボルのサイズは、必要なバイト数を示します。
このセクションテーブルインデックスは、シンボルが未定義であることを示します。リンカーがこのオブジェクトファイルを、示されたシンボルを定義するほかのオブジェクトファイルに結合すると、このシンボルに対するこのファイルの参照は定義に結び付けられます。
前述したとおり、インデックス 0 (STN_UNDEF) のシンボルテーブルエントリは予約されています。このエントリは次の値を保持します。
|