リンカーとライブラリ

シンボルテーブルセクション

オブジェクトファイルのシンボルテーブルには、プログラムのシンボル定義とシンボル参照の検索と再配置に必要となる情報が格納されます。シンボルテーブルインデックスは、この配列への添字です。インデックス 0 はシンボルテーブルの先頭エントリを指定し、また未定義シンボルインデックスとして機能します。表 7–21 を参照してください。

シンボルテーブルエントリの形式は、次のとおりです。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;
st_name

オブジェクトファイルのシンボル文字列テーブルへのインデックス (シンボル名の文字表現を保持)。値が 0 以外の場合、その値はシンボル名を与える文字列テーブルインデックスを表します。値が 0 の場合、シンボルテーブルエントリに名前は存在しません。

st_value

関連付けられているシンボルの値。この値は、状況に応じて絶対値またはアドレスを表します。「シンボル値」を参照してください。

st_size

多くのシンボルは、関連付けられているサイズを持っています。たとえば、データオブジェクトのサイズは、オブジェクトに存在するバイト数です。このメンバーは、シンボルがサイズを持っていない場合またはサイズが不明な場合、値 0 を保持します。

st_info

シンボルの種類および結び付けられる属性。値と意味のリストを、表 7–18 に示します。次のコードは、値の処理方法を示します。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))
st_other

シンボルの可視性。値と意味のリストを、表 7–20 に示します。次のコードは、32 ビットオブジェクトと 64 ビットオブジェクトの両方の値を操作する方法を示しています。その他のビットは 0 に設定され、特に意味はありません。

#define ELF32_ST_VISIBILITY(o)       ((o)&0x3)
#define ELF64_ST_VISIBILITY(o)       ((o)&0x3)
st_shndx

すべてのシンボルテーブルエントリは、何らかのセクションに関して定義されます。このメンバーは、該当するセクションヘッダーテーブルインデックスを保持します。いくつかのセクションインデックスは、特別な意味を示します。表 7–4 を参照してください。

このメンバーに SHN_XINDEX が含まれる場合は、実際のセクションヘッダーインデックスが大きすぎてこのフィールドに入りません。実際の値は、タイプ SHT_SYMTAB_SHNDX の関連するセクション内に存在します。

シンボルのバインディングは、st_info フィールドで決定されますが、これにより、リンクの可視性と動作が決定します。

表 7–18 ELF シンボルのバインディング、(ELF32_ST_BINDELF64_ST_BIND)

名前 

値 

STB_LOCAL

0

STB_GLOBAL

1

STB_WEAK

2

STB_LOOS

10

STB_HIOS

12

STB_LOPROC

13

STB_HIPROC

15

STB_LOCAL

局所シンボル。局所シンボルは、局所シンボルの定義が存在するオブジェクトファイルの外部では見えません。同じ名前の局所シンボルは、互いに干渉することなく複数のファイルに存在できます。

STB_GLOBAL

大域シンボル。大域シンボルは、結合されるすべてのオブジェクトファイルで見ることができます。あるファイルの大域シンボルの定義は、その大域シンボルへの別ファイルの未定義参照を解決します。

STB_WEAK

ウィークシンボル。ウィークシンボルは大域シンボルに似ていますが、ウィークシンボルの定義の優先順位は大域シンボルの定義より低いです。

STB_LOOS - STB_HIOS

この範囲の値 (両端の値を含む) は、オペレーティングシステム固有のセマンティクスのために予約されています。

STB_LOPROC - STB_HIPROC

この範囲の値は、プロセッサ固有のセマンティクスのために予約されています。

大域シンボルとウィークシンボルは、主に 2 つの点で異なります。


注 –

ウィークシンボルは、主にシステムソフトウェアでの使用を意図したものです。アプリケーションプログラムでの使用は推奨されません。


各シンボルテーブルにおいて、STB_LOCAL 結合を持つすべてのシンボルは、ウィークシンボルと大域シンボルの前に存在します。「セクション」に記述されているとおり、シンボルテーブルセクションの sh_info セクションヘッダーメンバーは、最初のローカルではないシンボルに対するシンボルテーブルインデックスを保持します。

シンボルのタイプは st_info フィールドで指定され、これにより、関連付けられた実体の一般的な分類が決定されます。

表 7–19 ELF シンボルのタイプ (ELF32_ST_TYPEELF64_ST_TYPE)

名前 

値 

STT_NOTYPE

0

STT_OBJECT

1

STT_FUNC

2

STT_SECTION

3

STT_FILE

4

STT_COMMON

5

STT_TLS

6

STT_LOOS

10

STT_HIOS

12

STT_LOPROC

13

STT_SPARC_REGISTER

13

STT_HIPROC

15

STT_NOTYPE

シンボルの種類は指定されません。

STT_OBJECT

シンボルは、データオブジェクト (変数や配列など) と関連付けられています。

STT_FUNC

シンボルは、関数またはほかの実行可能コードに関連付けられています。

STT_SECTION

シンボルは、セクションに関連付けられています。この種類のシンボルテーブルエントリは主に再配置を行うために存在しており、通常、STB_LOCAL に結び付けられています。

STT_FILE

慣例により、シンボルの名前はオブジェクトファイルに対応するソースファイルの名前を与えます。ファイルシンボルは STB_LOCAL に結び付けられており、セクションインデックスは SHN_ABS です。このシンボルは、存在する場合、ファイルのほかの STB_LOCAL シンボルの前に存在します。

SHT_SYMTAB のシンボルインデックス 1 は、そのオブジェクトファイルを表す STT_FILE シンボルです。慣例により、このシンボルの後にはファイル STT_SECTION シンボルが続きます。これらのセクションシンボルの後には、ローカルになった大域シンボルが続きます。

STT_COMMON

このシンボルは、初期設定されていない共通ブロックを表します。このシンボルは、STT_OBJECT とまったく同じに扱われます。

STT_TLS

シンボルは、スレッド固有領域の実体を指定します。定義されている場合、実際のアドレスではなく、シンボルに割り当てられたオフセットを提供します。

スレッドローカルストレージの再配置では、タイプが STT_TLS のシンボルしか参照できません。割り当て可能なセクションからタイプが STT_TLS のシンボルを参照するには、特別なスレッドローカルストレージ再配置を使用するしか方法がありません。詳細は、第 8 章スレッド固有領域 (TLS)を参照してください。割り当てができないセクションからタイプが STT_TLS のシンボルを参照する際には、この制限はありません。

STT_LOOS - STT_HIOS

この範囲の値 (両端の値を含む) は、オペレーティングシステム固有のセマンティクスのために予約されています。

STT_LOPROC - STT_HIPROC

この範囲の値は、プロセッサ固有のセマンティクスのために予約されています。

シンボルの可視性は、その st_other フィールドで決まります。この可視性は、再配置可能オブジェクトで指定できます。シンボルの可視性により、シンボルが実行可能ファイルまたは共有オブジェクトの一部になった後のシンボルへのアクセス方法が定義されます。

表 7–20 ELF シンボルの可視性

名前 

値 

STV_DEFAULT

0

STV_INTERNAL

1

STV_HIDDEN

2

STV_PROTECTED

3

STV_DEFAULT

STV_DEFAULT 属性を持つシンボルの可視性は、シンボルの結合タイプで指定されたものになります。大域シンボルおよびウィークシンボルは、それらの定義するコンポーネント (実行可能ファイルまたは共有オブジェクト) の外から見ることができます。局所シンボルは、「隠されて」います。大域シンボルおよびウィークシンボルは、横取りすることもできます。別のコンポーネントの同じ名前の定義によってこれらのシンボルに割り込むこともできます。

STV_PROTECTED

現在のコンポーネント内で定義されたシンボルは、それがほかのコンポーネント内で参照可能であるが横取り可能ではない場合、保護されています。定義コンポーネント内からシンボルへの参照など、あらゆる参照について、コンポーネント内の定義に解決する必要があります。この解決は、シンボル定義がデフォルト規則によって割り込みを行う別のコンポーネント内に存在する場合も、実行する必要があります。STB_LOCAL 結合を持つシンボルは、STV_PROTECTED 可視性を持ちません。

STV_HIDDEN

現在のコンポーネント内で定義されたシンボルは、その名前がほかのコンポーネントから参照することができない場合、「隠されて」います。そのようなシンボルは、保護される必要があります。この属性は、コンポーネントの外部インタフェースの管理に使用されます。そのようなシンボルによって指定されたオブジェクトは、そのアドレスが外部に渡された場合でも、ほかのコンポーネントから参照可能です。

再配置可能オブジェクトに含まれた「隠された」シンボルは、そのオブジェクトが実行可能ファイルまたは共有オブジェクトに含まれる時には、削除されるか STB_LOCAL 結合に変換されます。

STV_INTERNAL

この可視性の属性は、現在予約されています。

可視性の属性は、リンク編集中、実行可能ファイルまたは共有オブジェクト内のシンボルの解決にはまったく影響をおよぼしません。このような解決は、結合タイプによって制御されます。いったんリンカーがその解決を選択すると、これらの属性は次の 2 つの必要条件を課します。どちらの必要条件も、リンクされるコード内の参照は、属性の利点を利用するために最適化されるという事実に基づくものです。

シンボル値がセクション内の特定位置を参照すると、セクションインデックスメンバー st_shndx は、セクションヘッダーテーブルへのインデックスを保持します。再配置時にセクションが移動すると、シンボル値も変化します。シンボルへの参照はプログラム内の同じ位置を指し示し続けます。いくつかの特別なセクションインデックス値は、ほかのセマンティクスが付けられています。

SHN_ABS

このシンボルは、再配置が行われても変わらない絶対値を持ちます。

SHN_COMMON および SHN_AMD64_LCOMMON

このシンボルは、まだ割り当てられていない共通ブロックを示します。シンボル値は、セクションの sh_addralign メンバーに類似した整列制約を与えます。リンカーは st_value の倍数のアドレスにシンボル記憶領域を割り当てます。シンボルのサイズは、必要なバイト数を示します。

SHN_UNDEF

このセクションテーブルインデックスは、シンボルが未定義であることを示します。リンカーがこのオブジェクトファイルを、示されたシンボルを定義するほかのオブジェクトファイルに結合すると、このシンボルに対するこのファイルの参照は定義に結び付けられます。

前述したとおり、インデックス 0 (STN_UNDEF) のシンボルテーブルエントリは予約されています。このエントリは次の値を保持します。

表 7–21 ELF シンボルテーブルエントリ: インデックス 0

名前 

値 

注意 

st_name

0

名前が存在しない 

st_value

0

値は 0 

st_size

0

サイズが存在しない 

st_info

0

種類はない。ローカル結合 

st_other

0

 

st_shndx

SHN_UNDEF

セクションは存在しない 

シンボル値

異なる複数のオブジェクトファイル型のシンボルテーブルエントリは、st_value メンバーに対してわずかに異なる解釈を持ちます。

シンボルテーブル値は、異なる種類のオブジェクトファイルでも似た意味を持ちますが、適切なプログラムはデータに効率的にアクセスできます。

シンボルテーブルのレイアウトと規則

シンボルテーブル内のシンボルは、次の順序で書き込まれます。

Solaris OS には、2 つ の特別なシンボルテーブルがあります。

.symtab (SHT_SYMTAB)

このシンボルテーブルには、関連する ELF ファイルを示すあらゆるシンボルが入っています。このシンボルテーブルは、通常は割り当てることができないため、プロセスのメモリーイメージ内では使用できません。

ELIMINATE キーワードと一緒に mapfile を使用すると、.symtab から大域シンボルを削除できます。mapfile を使用した追加シンボルの定義」を参照してください。リンカーの -z redlocsym オプションを使用して、ローカルシンボルを削除することもできます。

.dynsym (SHT_DYNSYM)

このテーブルには、.symtab テーブルのシンボルのうち、動的リンクをサポートするために必要なシンボルだけが入っています。このシンボルテーブルは、割り当てることができるため、プロセスのメモリーイメージ内で使用できます。

.dynsym テーブルは標準 NULL シンボルで始まり、そのあとに大域シンボルが続きます。STT_FILE シンボルは通常、このシンボルテーブルにはありません。STT_SECTION シンボルは、再配置エントリが必要とする場合に存在する可能性があります。

レジスタシンボル

SPARC アーキテクチャーは、レジスタシンボル (大域レジスタを初期化するシンボル) をサポートします。レジスタシンボルに対するシンボルテーブルエントリには、次の値が入ります。

表 7–22 SPARC: ELF シンボルテーブルエントリ: レジスタシンボル

フィールド 

意味 

st_name

シンボル名文字列テーブルへのインデックス。または 0 (スク ラッチレジスタ)。

st_value

レジスタ番号。整数レジスタの割り当てについては、ABI マニュアルを参照してください。

st_size

未使用 (0)。

st_info

結合は標準的には STB_GLOBAL です。種類は STT_SPARC_REGISTER でなければなりません。

st_other

未使用 (0)。

st_shndx

このオブジェクトがこのレジスタシンボルを初期化する場合は、SHN_ABS。それ以外の場合は、SHN_UNDEF

定義済みの SPARC 用レジスタ値を、次に示します。

表 7–23 SPARC: ELF レジスタ番号

名前 

値 

意味 

STO_SPARC_REGISTER_G2

0x2

%g2

STO_SPARC_REGISTER_G3

0x3

%g3

特定の大域レジスタのエントリが存在しないことは、その特定の大域レジスタがオブジェクトで使用されないことを意味します。