リンカーとライブラリ

動的セクション

オブジェクトファイルが動的リンクに関係している場合、このオブジェクトファイルのプログラムヘッダーテーブルには、PT_DYNAMIC 型の要素が存在します。このセグメントには、.dynamic セクションが存在します。特殊なシンボル _DYNAMIC は、このセクションを示します。このセクションには、以下の構造体 (sys/link.h で定義される) の配列が存在します。


typedef struct {
        Elf32_Sword d_tag;
        union {
                Elf32_Word      d_val;
                Elf32_Addr      d_ptr;
                Elf32_Off       d_off;
        } d_un;
} Elf32_Dyn;typedef struct {
        Elf64_Xword d_tag;
        union {
                Elf64_Xword     d_val;
                Elf64_Addr      d_ptr;
        } d_un;
} Elf64_Dyn;

このタイプの各オブジェクトの場合、d_tagd_un の解釈に影響します。

d_val

この Elf32_Word オブジェクトは、さまざまに解釈される整数値を表します。

d_ptr

この Elf32_Addr オブジェクトは、プログラムの仮想アドレスを表わします。すでに述べたように、ファイルの仮想アドレスは、実行時にメモリーの仮想アドレスに一致しないことがあります。実行時リンカーは、動的構造体に存在するアドレスを解釈するとき、元のファイル値とメモリーの基底アドレスに基づいて実際のアドレスを計算します。整合性のため、ファイルには動的構造体内のアドレスを補正するための再配置エントリは存在しません。

以下の表は、実行可能オブジェクトファイルと共有オブジェクトファイルのタグ要求についてまとめています。タグに「必須」という印が付いている場合、動的リンク配列にはその型のエントリが存在しなければなりません。また、「任意」は、タグのエントリが表われてもよいですが必須ではないことを意味します

表 7-41 動的配列タグ、d_tag

名前 

値 

d_un 

実行可能ファイル 

共有オブジェクトファイル 

DT_NULL

0

無視される 

必須 

必須 

DT_NEEDED

1

d_val

任意 

任意 

DT_PLTRELSZ

2

d_val

任意 

任意 

DT_PLTGOT

3

d_ptr

任意 

任意 

DT_HASH

4

d_ptr

必須 

必須 

DT_STRTAB

5

d_ptr

必須 

必須 

DT_SYMTAB

6

d_ptr

必須 

必須 

DT_RELA

7

d_ptr

必須 

任意 

DT_RELASZ

8

d_val

必須 

任意 

DT_RELAENT

9

d_val

必須 

任意 

DT_STRSZ

10

d_val

必須 

必須 

DT_SYMENT

11

d_val

必須 

必須 

DT_INIT

12

d_ptr

任意 

任意 

DT_FINI

13

d_ptr

任意 

任意 

DT_SONAME

14

d_val

無視される 

任意 

DT_RPATH

15

d_val

任意 

無視される 

DT_SYMBOLIC

16

無視される 

無視される 

任意 

DT_REL

17

d_ptr

必須 

任意 

DT_RELSZ

18

d_val

必須 

任意 

DT_RELENT

19

d_val

必須 

任意 

DT_PLTREL

20

d_val

任意 

任意 

DT_DEBUG

21

d_ptr

任意 

無視される 

DT_TEXTREL

22

無視される

任意 

任意 

DT_JMPREL

23

d_ptr

任意 

任意 

DT_VALRNGLO

0x6ffffd00

未規定

未規定

未規定

DT_MOVEENT

0x6ffffdfa

d_val

任意 

任意 

DT_MOVESZ

0x6ffffdfb

d_val

任意 

任意 

DT_FEATURE

0x6ffffdfc

d_val

任意 

任意 

DT_POSFLAG_1

0x6ffffdfd

d_val

任意 

任意 

DT_SYMINSZ

0x6ffffdfe

d_val

任意 

任意 

DT_SYMINENT

0x6ffffdff

d_val

任意 

任意 

DT_VALRNGHI

0x6ffffdff

未規定

未規定

未規定

DT_ADDRRNGLO

0x6ffffe00

未規定

未規定

未規定

DT_MOVETAB

0x6ffffefe

d_ptr

任意 

任意 

DT_SYMINFO

0x6ffffeff

d_ptr

任意 

任意 

DT_ADDRRNGHI

0x6ffffeff

未規定

未規定

未規定

DT_RELACOUNT

0x6ffffff9

d_val

任意 

任意 

DT_RELCOUNT

0x6ffffffa

d_val

任意 

任意 

DT_FLAGS_1

0x6ffffffb

d_val

任意 

任意 

DT_VERDEF

0x6ffffffc

d_ptr

任意 

任意 

DT_VERDEFNUM

0x6ffffffd

d_val

任意 

任意 

DT_VERNEED

0x6ffffffe

d_ptr

任意 

任意 

DT_VERNEEDNUM

0x6fffffff

d_val

任意 

任意 

DT_AUXILIARY

0x7ffffffd

d_val

未規定 

任意 

DT_USED

0x7ffffffe

d_val

任意 

任意 

DT_FILTER

0x7fffffff

d_val

未規定 

任意 

DT_LOPROC

0x70000000

未指定 

未規定 

未規定 

DT_SPARC_REGISTER

0x70000001

d_val

任意 

任意 

DT_HIPROC

0x7fffffff

未指定 

未規定 

未規定 

DT_NULL

DT_NULL タグが付けられたエントリは、_DYNAMIC 配列の終わりを示します。

DT_NEEDED

この要素は、空文字 で終わっている文字列の文字列テーブルオフセットを保持し、必要な依存性の名前を与えます。オフセットは、DT_STRTAB エントリに記録されるテーブルへのインデックスです。これらの名前については、「共有オブジェクトの依存性」を参照してください。動的配列には、この型の複数のエントリが存在できます。これらのエントリの相対順序は意味がありますが、他の型のエントリに対するこれらのエントリの相対順序には意味がありません。

DT_PLTRELSZ

この要素は、手続きリンクテーブルに関連付けられている再配置エントリの合計サイズ (単位: バイト) を保持します。DT_JMPREL 型のエントリが存在する場合、DT_PLTRELSZ 型のエントリも必要です。

DT_PLTGOT

この要素は、手続きリンクテーブルおよび/または大域オフセットテーブルに関連付けられているアドレスを保持します。

DT_HASH

この要素は、シンボルハッシュテーブル (「ハッシュテーブル」に記述されている) を指し示します。ハッシュテーブルは、DT_SYMTAB 要素で示されるシンボルテーブルを参照します。

DT_STRTAB

この要素は、文字列テーブル (この章の前半部分に記述されている) のアドレスを保持します。文字列テーブルには、実行時リンカーが必要とするシンボル名、依存性名、および他の文字列が存在します。

DT_SYMTAB

この要素は、再配置テーブル (この章の前半部分に記述されている) のアドレスを保持します。32 ビットクラスのファイルに対しては、Elf32_Sym エントリが存在します。

DT_RELA

この要素は、再配置テーブル (この章の前半部分に記述されている) のアドレスを保持します。再配置テーブルのエントリ (32 ビットファイルクラス用の Elf32_Rela など) には、明示的加数が存在します。

オブジェクトファイルには、複数の再配置セクションが存在できます。リンカーは、実行可能オブジェクトファイルまたは共有オブジェクトファイルの再配置テーブルを作成するとき、これらのセクションを連結して単一のテーブルを作成します。これらの各セクションはオブジェクトファイル内で個々に独立したままですが、実行時リンカーは単一のテーブルとして扱います。実行時リンカーは、実行可能ファイルのプロセスイメージを作成したりまたはプロセスイメージに共有オブジェクトを付加したりするとき、再配置テーブルを読み取り、関連付けられている動作を実行します。

この要素が存在する場合、動的構造体には DT_RELASZ 要素と DT_RELAENT 要素も存在しなければなりません。再配置がファイルに対して「必須」の場合、DT_RELA または DT_REL が使用可能です (これらは両方とも使用可能ですが、必要ではありません)。

DT_RELASZ

この要素は、DT_RELA 再配置テーブルの合計サイズ (単位: バイト) を保持します。

DT_RELAENT

この要素は、DT_RELA 再配置エントリのサイズ (単位: バイト) を保持します。

DT_STRSZ

この要素は、文字列テーブルのサイズ (単位: バイト) を保持します。

DT_SYMENT

この要素は、シンボルテーブルエントリのサイズ (単位: バイト) を保持します。

DT_SYMINFO

この要素は、SHT_SUNW_syminfo セクションのアドレスを保持します。

DT_SYMINENT

この要素は、SHT_SUNW_syminfo テーブルエントリのサイズ (単位: バイト) を保持します。

DT_SYMINSZ

この要素は、SHT_SUNW_syminfo セクションのサイズ (単位: バイト) を保持します。

DT_INIT

この要素は、初期化関数のアドレスを保持します (初期化関数については、「初期化および終了関数」に記述されています)。

DT_FINI

この要素は、終了関数のアドレスを保持します (終了関数については、「初期化および終了関数」に記述されています)。

DT_SONAME

この要素は、空文字で終わっている文字列の文字列テーブルオフセットを保持し、共有オブジェクトの名前を与えます。このオフセットは、DT_STRTAB エントリに記録されているテーブルへのインデックスです。これらの名前については、「共有オブジェクトの依存性」を参照してください。

DT_RPATH

この要素は、ライブラリ検索パス (空文字で終わっている文字列) 文字列テーブルオフセットを保持します (ライブラリ検索パスについては、「依存関係を持つ共有オブジェクト」に記述されています)。このオフセットは、DT_STRTAB エントリに記録されているテーブルへのインデックスです。

DT_SYMBOLIC

この要素が共有オブジェクトライブラリに存在する場合、この共有オブジェクトライブラリ内の参照に対する、実行時リンカーのシンボル解決アルゴリズムが変わります。実行時リンカーは、シンボル探索を実行可能ファイルから開始する代わりに、共有オブジェクト自身から開始します。共有オブジェクトに参照されているシンボルが存在しない場合、実行時リンカーは通常どおり、実行可能ファイルと他の共有オブジェクトを探索します。

DT_REL

この要素は DT_RELA に似ていますが、テーブルに暗黙の加数 (32 ビットファイルクラス用の Elf32_Rel など) が存在する点が異なります。この要素が存在する場合、動的構造体には DT_RELSZ 要素と DT_RELENT 要素も存在しなければなりません。

DT_RELSZ

この要素は、DT_REL 再配置テーブルの合計サイズ (単位: バイト) を保持します。

DT_RELENT

この要素は、DT_REL 再配置エントリのサイズ (単位: バイト) を保持します。

DT_PLTREL

この要素は、手続きリンクテーブルが参照する再配置エントリの型を指定します。d_val 要素は、必要に応じて DT_REL または DT_RELA を保持します。ひとつの手続きリンクテーブルでは、すべての再配置は、同じ再配置を使用しなければなりません。

DT_DEBUG

この要素は、デバッグ時に使用されます。

DT_TEXTREL

この構成要素が存在しない場合、再配置エントリが書き込み不能セグメント (プログラムヘッダーテーブルのセグメント許可で指定されます) に対する変更を発生させてはならないことを意味します。この構成要素が存在する場合、1 つまたは複数の再配置エントリが書き込み不能セグメントに対する変更を要求するかもしれません。また、実行時リンカーはしかるべく対応します。

DT_FLAGS_1

このエントリが存在する場合、このエントリの d_val 要素は、さまざまな状態フラグを保持します。表 7-42 を参照してください。

DT_POSFLAG_1

このエントリが存在する場合、このエントリの d_val 要素は、さまざまな状態フラグを保持します。これらのフラグは、.dynamic セクション内の直後の DT_* エントリに適用されます。

DT_JMPREL

このエントリが存在する場合、このエントリの d_ptr 要素は、手続きリンクテーブルにのみ関連付けられている再配置エントリのアドレスを保持します。これらの再配置エントリを分離しておくと、遅延結合が有効の場合、実行時リンカーはプロセス初期化時にこれらの再配置エントリを無視します。このエントリが存在する場合、DT_PLTRELSZ 型と DT_PLTREL 型の関連エントリも存在しなければなりません。

DT_VERDEF

この要素は、バージョン定義テーブル (この章の前半部分に記述されている) のアドレスを保持します。32 ビットクラスのファイルに対しては、Elf32_Verdef エントリが存在します。詳細は、「バージョン定義セクション」を参照してください。これらのエントリ内の要素には、DT_STRTAB エントリに記録されているテーブルへのインデックスが存在します。

DT_VERDEFNUM

この要素は、バージョン定義テーブルのエントリ数を指定します。

DT_VERNEED

この要素は、バージョン依存性テーブル (この章の前半部分に記述されている) のアドレスを保持します。32 ビットクラスのファイルに対しては、Elf32_Verneed エントリが存在します。詳細は、「バージョン依存セクション」を参照してください。これらのエントリ内の要素には、DT_STRTAB エントリに記録されているテーブルへのインデックスが存在します。

DT_VERNEEDNUM

この要素は、バージョン依存性テーブルのエントリ数を指定します。

DT_RELACOUNT

すべての Elf32_Rela R_*_RELATIVE 再配置は単一のブロックに入っており、このエントリ はそのブロックのエントリ数を指定します。これにより、ld.so.1RELATIVE 再配置の処理を合理化できます。

DT_RELCOUNT

すべての Elf32_Rel R_*_RELATIVE 再配置は単一のブロックに入っており、このエントリはそのブロックのエントリ数を指定します。これにより、ld.so.1RELATIVE 再配置の処理を合理化できます。

DT_AUXILIARY

この要素は、空文字で終わっている文字列 (オブジェクトに命名している) の文字列テーブルオフセットを保持します。このオフセットは、DT_STRTAB エントリに記録されているテーブルへのインデックスです。補助オブジェクト内のシンボルは、このオブジェクト内のシンボルに優先して使用されます。

DT_FILTER

この要素は、オブジェクトを示す文字列 (空文字で終わっている文字列) の文字列テーブルオフセットを保持します。このオフセットは、DT_STRTAB エントリに記録されているテーブルへのインデックスです。このオブジェクトのシンボルテーブルは、命名されたオブジェクトのシンボルテーブルのフィルタとして使用されます。

DT_MOVEENT

この要素は、SHT_SUNW_move で定義されるセクションの合計サイズを保持します。「移動セクション」を参照してください。

DT_MOVESZ

この要素は、DT_MOVETAB 移動エントリのサイズ (単位: バイト) を保持します。

DT_MOVETAB

この要素は、移動テーブル (この章の前半部分に記述されている) のアドレスを保持します。移動テーブルのエントリには、32 ビットクラスのファイルに対する Elf32_Move エントリが存在します。

DT_FEATURE_1

このエントリが存在する場合、このエントリの d_val 要素は、DTF_1_* で定義されるさまざまな機能フラグを保持します。機能値は、check_rtld_feature() 関数で使用されます (この機能は、必要な機能がサポートされているかどうかを調べるためにアプリケーションが実行時に呼び出します)。

DT_VALRNGLO - DT_VALRNGHI

この範囲の値は、動的構造体内の Dyn.d_un.d_val フィールドで使用されます。

DT_ADDRRNGLO - DT_ADDRRNGHI

この範囲の値は、動的構造体内の Dyn.d_un.d_ptr フィールドで使用されます。ELF オブジェクトが作成後に調整された場合、これらのエントリを調整する必要があります。

DT_SPARC_REGISTER

この要素には、STT_SPARC_REGISTER シンボルのインデックスが存在します。シンボルテーブルの各 STT_SPARC_REGISTER シンボルテーブルエントリには、これらのエントリの 1 つが存在します。

DT_LOPROC - DT_HIPROC

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

以下の動的状態フラグが現在、使用可能です。

表 7-42 動的タグ、DT_FLAGS_1

名前 

値 

意味 

DF_1_NOW

0x1

完全な再配置処理を行います 

DT_1_GLOBAL

0x2

未使用 

DT_1_GROUP

0x4

オブジェクトがグループの構成要素であることを示します 

DT_1_NODELETE

0x8

オブジェクトがプロセスから削除できないことを示します 

DT_1_LOADFLTR

0x10

フィルティー (1 つまたは複数)の即時読み込みを保証します

DT_1_INITFIRST

0x20

オブジェクトの初期化を最初に実行します 

DT_1_NOOPEN

0x40

オブジェクトを dlopen(3X) で使用できません

DT_1_DIRECT

0x100

直接結合が有効です。 

DT_1_INTERPOSE

0x400

オブジェクトのシンボルは優先されます。 

DF_1_NOW

オブジェクトが読み込まれると、すべての再配置処理が行われます。「再配置が実行されるとき」を参照してください。この状態フラグは、リンカーの -z now オプションを使うことによって有効になります。

DF_1_GROUP

オブジェクトがグループの構成要素であることを示します。「シンボル検索」を参照してください。この状態フラグは、リンカーの -B group オプションを使うことによって有効になります。

DF_1_NODELETE

オブジェクトがプロセスから削除できないことを示します。したがってオブジェクトは、dlopen(3X) で直接または依存性としてプロセスに読み込みされた場合、dlclose(3X) で読み込み解除できません。この状態フラグは、リンカーの -z nodelete オプションを使うことによってオブジェクトに有効になります。

DF_1_LOADFLTR

この状態フラグは、「フィルタ」に対してのみ意味があります (「フィルタとしての共有オブジェクト」を参照してください)。フィルタが読み込まれると、関連付けられているすべてのフィルティーが直ちに処理されます (「フィルタ対象の処理」を参照してください)。この状態フラグは、リンカーの -z loadfltr オプションを使うことによってオブジェクトに有効になります。

DF_1_INITFIRST

オブジェクトが読み込まれると、このオブジェクトと共に読み込まれた他のオブジェクトより先に、このオブジェクトの初期化セクションが実行されます。「初期設定および終了ルーチン」を参照してください。この特殊な状態フラグは、libthread.so.1 で使用されることを意図しています。この状態フラグは、リンカーの -z initfirst オプションを使うことによって有効になります。

DF_1_NOOPEN

dlopen(3X) を使ってオブジェクトを実行中プロセスに追加できないことを示します。この状態フラグは、リンカーの -z nodlopen オプションを使うことによってオブジェクトに有効になります。

DF_1_DIRECT

オブジェクトには、直接結合情報が存在します。この状態フラグは、リンカーの -B direct オプションを使うことによってオブジェクトに有効になります。

DF_1_INTERPOSE

オブジェクトシンボルテーブルは、起動性実行可能プログラム以外のすべてのシンボルの前に挿入されます。この状態フラグは、リンカーの -z interpose オプションを使うことによって有効になります。

表 7-43 動的タグ、DT_POSFLAG_1

名前 

値 

意味 

DF_P1_LAZYLOAD

0x1

後続のオブジェクトは、遅延読み込みされる 

DT_P1_GROUPPERM

0x2

後続のオブジェクトに対する参照が制限される 

DF_P1_LAZYLOAD

後続の DT_* エントリは、読み込まれるオブジェクトを示します。このオブジェクトのローディングは、Syminfo テーブルエントリで示されるシンボル結合がこのオブジェクトを明確に参照するまで遅延されます。

DF_P1_GROUPPERM

後続の DT_* エントリは、読み込まれるオブジェクトを示します。このオブジェクト内のシンボルは、一般的なシンボル解決に対しては使用できません。このオブジェクト内のシンボルは、このオブジェクトを読み込ませたオブジェクト (1 つまたは複数) に対してのみ使用可能です。

以下の動的機能フラグが現在、使用可能です。

表 7-44 動的機能フラグDT_FEATURE

名前 

値 

意味 

DTF_1_PARINIT

0x1

部分的に初期化された機能が必要 

動的配列の終わりの DT_NULL 要素と、DT_NEEDED 要素と DT_POSFLAG_1 要素の相対順序を除き、エントリは任意の順序で現れることができます。テーブルに示されていないタグ値は、保留されます。