リンカーとライブラリ

シンボルテーブル

オブジェクトファイルのシンボルテーブルは、プログラムのシンボル定義または参照の探索と再配置に必要な情報を保持します。シンボルテーブルインデックスは、この配列への添字です。インデックス 0 はシンボルテーブルの先頭エントリを指定し、また未定義シンボルインデックスとして機能します。先頭エントリの内容は、このセクションの後の方で記述します。

表 7-18 シンボルテーブルの先頭エントリ

名前 

値 

STN_UNDEF

0

シンボルテーブルエントリの形式 (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 の場合、シンボルテーブルエントリに名前は存在しません。


注 -

外部 C シンボルは、C とオブジェクトファイルのシンボルテーブルにおいて同じ名前を持ちます。


st_value

この構成要素は、関連付けられているシンボルの値を与えます。この値は、絶対値やアドレスなど (状況に依存する) を表します。「シンボル値」を参照してください。

st_size

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

st_info

この構成要素は、シンボルの種類と結び付けられる属性を指定します。値と意味のリストを以下に示します。次のコードは、値 (sys/elf.h で定義されている) の処理方法を示します。


#define ELF32_ST_BIND(i)             ((i) >> 4)
#define ELF32_ST_TYPE(i)             ((i) & 0xf)
#define ELF32_ST_INFO(b, t)          (((b)<<4)+((t)&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

この構成要素は現在 0 を保持しており、意味は定義されていません。

st_shndx

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

シンボルの結び付けは、リンクの可視性と動作を決定します。

表 7-19 結び付け (ELF32_ST_BINDELF64_ST_BIND)

名前 

値 

STB_LOCAL

0

STB_GLOBAL

1

STB_WEAK

2

STB_LOPROC

13

STB_HIPROC

15

STB_LOCAL

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

STB_GLOBAL

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

STB_WEAK

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

STB_LOPROC - STB_HIPROC

この範囲の値は、プロセッサ固有の使用方法に対して予約されます。

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

各シンボルテーブルにおいて、STB_LOCAL 結び付きが存在するすべてのシンボルは、ウィークシンボルと大域シンボルの前に存在します。「セクション」に記述されているとおり、シンボルテーブルセクションの sh_info セクションヘッダー構成要素は、最初の局所的ではないシンボルに対するシンボルテーブルインデックスを保持します。

シンボルの種類は、関連付けられている実体に関する一般的分類を行います。

表 7-20 シンボルの種類 (ELF32_ST_TYPEELF64_ST_TYPE)

名前 

値 

STT_NOTYPE

0

STT_OBJECT

1

STT_FUNC

2

STT_SECTION

3

STT_FILE

4

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 シンボルと、局所シンボルに短縮されている大域シンボルが続きます (詳細は、「シンボル範囲の縮小」と、第 5 章「バージョンアップ」を参照してください)。

STT_LOPROC - STT_HIPROC

この範囲の値は、プロセッサ固有の使用方法に対して予約されます。

共有オブジェクトファイルの関数シンボル (STT_FUNC タイプが存在する) は、特別な意味を持っています。別のオブジェクトファイルが共有オブジェクトの関数を参照すると、リンカーは参照されるシンボルの手続きリンクテーブルエントリを自動的に作成します。STT_FUNC 以外のタイプの共有オブジェクトシンボルは、手続きリンクテーブルから自動的には参照されません。

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

SHN_ABS

シンボルは、絶対値 (再配置が行われても変化しない) を持ちます。

SHN_COMMON

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

SHN_UNDEF

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

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

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

名前 

値 

注意 

st_name

0

名前はない 

st_value

0

値は 0 

st_size

0

サイズはない 

st_info

0

種類はない。局所結び付き 

st_other

0

 

st_shndx

SHN_UNDEF

セクションは存在しない 

シンボル値

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

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

レジスタシンボル

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

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

フィールド 

意味 

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 (それ以外の場合) 

表 7-23 SPARC: レジスタ番号

名前 

値 

意味  

STO_SPARC_REGISTER_G2

0x2

%g2

STO_SPARC_REGISTER_G3

0x3

%g3

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