リンカーとライブラリ

動的リンク

このセクションは、オブジェクトファイル情報と、プログラムの実行イメージを作成するシステム動作を記述します。ここで説明する情報の大半は、すべてのシステムに適用されます。プロセッサに固有の情報はその旨が示されたセクションに存在します。

実行可能オブジェクトファイルと共有オブジェクトファイルは、アプリケーションプログラムを静的に表現します。このようなプログラムを実行するためには、システムはこれらのファイルを使用して動的なプログラムの表現、すなわちプロセスイメージを作成します。プロセスイメージには、テキスト、データ、スタックなどがあるセグメントが存在します。次の主な細目があります。

プログラムヘッダー

実行可能オブジェクトファイルまたは共有オブジェクトファイルのプログラムヘッダーテーブルは、構造体の配列です。各構造体は、実行されるプログラムを準備するためにシステムが必要とするセグメントなどの情報を記述します。各オブジェクトファイルセグメントには、「セグメントの内容」で説明しているように、1 つ以上のセクションが存在します。

プログラムヘッダーは、実行可能オブジェクトファイルと共有オブジェクトファイルに対してのみ意味があります。プログラムヘッダーサイズは、ELF ヘッダーの e_phentsize メンバーと e_phnum メンバーで指定されます。

プログラムヘッダーの構造体は、次のとおりです。sys/elf.h を参照してください。

typedef struct {
        Elf32_Word      p_type;
        Elf32_Off       p_offset;
        Elf32_Addr      p_vaddr;
        Elf32_Addr      p_paddr;
        Elf32_Word      p_filesz;
        Elf32_Word      p_memsz;
        Elf32_Word      p_flags;
        Elf32_Word      p_align;
} Elf32_Phdr;

typedef struct {
        Elf64_Word      p_type;
        Elf64_Word      p_flags;
        Elf64_Off       p_offset;
        Elf64_Addr      p_vaddr;
        Elf64_Addr      p_paddr;
        Elf64_Xword     p_filesz;
        Elf64_Xword     p_memsz;
        Elf64_Xword     p_align;
} Elf64_Phdr;
p_type

この配列要素が記述するセグメント型、または配列要素情報の解釈方法。型の値とその意味は、表 7–25 を参照してください。

p_offset

ファイルの先頭から、セグメントの先頭バイトが存在する位置までのオフセット。

p_vaddr

セグメントの先頭バイトが存在するメモリー内の仮想アドレス。

p_paddr

セグメントの物理アドレス (物理アドレス指定が適切なシステムの場合)。本システムはアプリケーションプログラムに対して物理アドレス指定を無視するので、このメンバーには実行可能ファイルと共有オブジェクトに対する指定されていない内容が存在します。

p_filesz

セグメントのファイルイメージのバイト数 (0 の場合もある)。

p_memsz

セグメントのメモリーイメージのバイト数 (0 の場合もある)。

p_flags

セグメントに関係するフラグ。型の値とその意味は、表 7–26 を参照してください。

p_align

読み込み可能なプロセスセグメントは、ページサイズを基にして、p_vaddrp_offset に対して同じ値を保持する必要があります。このメンバーは、セグメントがメモリーとファイルにおいて整列される値を与えます。値 01 は、整列が必要ないことを意味します。その他の値の場合、p_align2 の正整数累乗でなければならず、また p_vaddrp_align を法として p_offset に等しくなければなりません。「プログラムの読み込み (プロセッサ固有)」を参照してください。

エントリの中には、プロセスセグメントを記述するものもあります。それ以外のエントリは補足情報を与え、プロセスイメージには関与しません。セグメントエントリが現れる順序は、明示されている場合を除き任意です。定義されている型の値を、次の表に示します。

表 7–25 ELF セグメント型

名前 

値 

PT_NULL

0

PT_LOAD

1

PT_DYNAMIC

2

PT_INTERP

3

PT_NOTE

4

PT_SHLIB

5

PT_PHDR

6

PT_TLS

7

PT_LOOS

0x60000000

PT_SUNW_UNWIND

0x6464e550

PT_LOSUNW

0x6ffffffa

PT_SUNWBSS

0x6ffffffa

PT_SUNWSTACK

0x6ffffffb

PT_SUNWDTRACE

0x6ffffffc

PT_SUNWCAP

0x6ffffffd

PT_HISUNW

0x6fffffff

PT_HIOS

0x6fffffff

PT_LOPROC

0x70000000

PT_HIPROC

0x7fffffff

PT_NULL

未使用メンバーの値は不定です。この型を使用すると、プログラムヘッダーテーブルに、無視されるエントリを入れることができます。

PT_LOAD

p_fileszp_memsz により記述される読み込み可能セグメントを指定します。ファイルのバイト列は、メモリーセグメントの先頭に対応付けられます。セグメントのメモリーサイズ (p_memsz) がファイルサイズ (p_filesz) より大きい場合、不足するバイトは、値 0 を保持するように定義されます。これらのバイトはセグメントの初期化領域に続きます。ファイルサイズがメモリーサイズより大きくなることは許可されません。プログラムヘッダーテーブルの読み込み可能セグメントエントリは昇順に現れ、p_vaddr メンバーでソートされます。

PT_DYNAMIC

動的リンクに関する情報を指定します。「動的セクション」を参照してください。

PT_INTERP

インタプリタとして呼び出される、ヌル文字で終了しているパス名の位置とサイズを指定します。動的実行可能ファイルの場合、この型は必須です。共有オブジェクトの場合は、この型を指定することができます。この型は、ファイル内で複数指定することはできません。この型が存在する場合、この型はすべての読み込み可能セグメントエントリの前に存在しなければなりません。詳細は、「プログラムインタプリタ」を参照してください。

PT_NOTE

補助情報の位置とサイズを指定します。詳細は、「注釈セクション」を参照してください。

PT_SHLIB

このセグメント型は、予約済みですが、セマンティクスは定義されていません。

PT_PHDR

プログラムヘッダーテーブルの、ファイル、およびプログラムのメモリーイメージにおける位置とサイズを指定します。このセグメント型を、ファイル内に複数指定することはできません。また、このセグメント型は、プログラムヘッダーテーブルがプログラムのメモリーイメージの一部になる場合にかぎり指定できます。この型が存在する場合、この型はすべての読み込み可能セグメントエントリの前に存在しなければなりません。詳細は、「プログラムインタプリタ」を参照してください。

PT_TLS

スレッド固有領域のテンプレートを指定します。詳細は、「スレッド固有領域 (TLS) セクション」を参照してください。

PT_LOOS - PT_HIOS

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

PT_SUNW_UNWIND

このセグメントは、スタック巻き戻し (unwind) テーブルを含んでいます。

PT_LOSUNW - PT_HISUNW

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

PT_SUNWBSS

PT_LOAD 要素と同じ属性で、.SUNW_bss セクションの記述に使用します。

PT_SUNWSTACK

プロセススタックを記述します。PT_SUNWSTACK 要素は 1 つのみ存在できます。p_flags フィールドで定義されたアクセス権のみが意味を持ちます。

PT_SUNWDTRACE

dtrace(1M) の内部使用のため予約されています。

PT_SUNWCAP

ハードウェア機能要件を指定します。詳細は、「ハードウェアおよびソフトウェア機能に関するセクション」を参照してください。

PT_LOPROC - PT_HIPROC

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


注 –

ほかの箇所で特に要求されないかぎり、すべてのプログラムヘッダーセグメントタイプはそれぞれ存在することもありますし、存在しないこともあります。ファイルのプログラムヘッダーテーブルには、このプログラムの内容に関係する要素のみが存在できます。


ベースアドレス

実行可能オブジェクトファイルと共有オブジェクトファイルには、ベースアドレス (プログラムのオブジェクトファイルのメモリーイメージに関連付けられている最下位仮想アドレス) が存在します。ベースアドレスは、たとえば動的リンク時にプログラムのメモリーイメージを再配置するために使用されます。

実行可能オブジェクトファイルと共有オブジェクトファイルのベースアドレスは、実行時に 3 つの値 (プログラムの読み込み可能セグメントのメモリー読み込みアドレス、最大ページサイズ、最下位仮想アドレス) から計算されます。プログラムヘッダーの仮想アドレスは、プログラムのメモリーイメージの実際の仮想アドレスを表さないことがあります。「プログラムの読み込み (プロセッサ固有)」を参照してください。

ベースアドレスを計算するには、PT_LOAD セグメントの最下位 p_vaddr 値に関連付けられているメモリーアドレスを判定します。次に、メモリーアドレスを最大ページサイズの最近倍数に切り捨てることで、ベースアドレスが求められます。メモリーに読み込まれるファイルの型によって、メモリーアドレスは p_vaddr 値に一致しない場合もあります。

セグメントへのアクセス権

システムで読み込まれるプログラムには、少なくとも 1 つの読み込み可能セグメントが存在しなければなりません (ただし、この制限はファイル形式による要件ではありません)。システムは、読み込み可能セグメントのメモリーイメージを作成するとき、p_flags メンバーで指定されるアクセス権を与えます。PF_MASKPROC マスクのすべてのビットは、プロセッサ固有のセマンティクスのために予約されます。

表 7–26 ELF セグメントフラグ

名前 

値 

意味 

PF_X

0x1

実行 

PF_W

0x2

書き込み 

PF_R

0x4

読み取り 

PF_MASKPROC

0xf0000000

指定なし 

アクセス権ビットが 0 の場合、そのビットのアクセスは拒否されます。実際のメモリーアクセス権は、メモリー管理ユニット (システムによって異なることがある) に依存します。すべてのフラグ組み合わせが有効ですが、システムは要求以上のアクセスを与えることがあります。ただしどんな場合も、特に断りが明示的に記述されていないかぎり、セグメントは書き込み権を持ちません。次の表に、正確なフラグ解釈と許容されるフラグ解釈を示します。

表 7–27 ELF セグメントへのアクセス権

フラグ 

値 

正確なフラグ解釈 

許容されるフラグ解釈 

None

0

すべてのアクセスが拒否される 

すべてのアクセスが拒否される 

PF_X

1

実行のみ 

読み取り、実行 

PF_W

2

書き込みのみ 

読み取り、書き込み、実行 

PF_W+PF_X

3

書き込み、実行 

読み取り、書き込み、実行 

PF_R

4

読み取りのみ 

読み取り、実行 

PF_R + PF_X

5

読み取り、実行 

読み取り、実行 

PF_R+PF_W

6

読み取り、書き込み 

読み取り、書き込み、実行 

PF_R + PF_W + PF_X

7

読み取り、書き込み、実行 

読み取り、書き込み、実行 

たとえば、標準的なテキストセグメントは読み取り権と実行権を持っていますが、書き込み権は持っていません。データセグメントは通常、読み取り権、書き込み権、および実行権を持っています。

セグメントの内容

オブジェクトファイルセグメントは、1 つまたは複数のセクションで構成されます。ただし、プログラムヘッダーはこの事実には関与しません。ファイルセグメントに 1 つのセクションが存在するか複数のセクションが存在するかもまた、プログラム読み込み時に重要ではありません。しかし、さまざまなデータが、プログラム実行時や動的リンク時などには存在しなければなりません。次に、セグメントの内容を一般的な言葉で説明します。セグメント内のセクションの順序と帰属関係は、異なることがあります。

テキストセグメントには、読み取り専用の命令/データが存在します。データセグメントには、書き込み可能のデータ/命令が存在します。すべての特殊セクションの一覧については、表 7–10 を参照してください。

PT_DYNAMIC プログラムヘッダー要素は、.dynamic セクションを指し示します。さらに、.got セクションと .plt セクションには、位置独立のコードと動的リンクに関係する情報が存在します。

.plt は、テキストセグメントまたはデータセグメントに存在できます (どちらのセグメントに存在するかはプロセッサに依存します)。詳細は、「大域オフセットテーブル (プロセッサ固有)」「プロシージャーのリンクテーブル (プロセッサ固有)」を参照してください。

タイプ SHT_NOBITS のセクションは、ファイル内の領域を占有しませんが、セグメントのメモリーイメージには反映されます。通常、これらの初期化されていないデータはセグメントの終わりに存在し、その結果、関連付けられているプログラムヘッダー要素において p_memszp_filesz より大きくなります。

プログラムの読み込み (プロセッサ固有)

システムは、プロセスイメージを作成または拡張するとき、ファイルのセグメントを仮想メモリーセグメントに論理的にコピーします。システムがファイルをいつ物理的に読み取るかは、プログラムの挙動やシステムの負荷などに依存します。

プロセスは実行時に論理ページを参照しないかぎり物理ページを必要としません。プロセスは一般に多くのページを未参照状態のままにします。したがって、物理読み取りを遅延させると、システム性能を向上させることができます。この効率性を実現するには、実行可能ファイルと共有オブジェクトファイルには、ファイルオフセットと仮想アドレスがページサイズを法として同じであるセグメントイメージが存在する必要があります。

32 ビットのセグメントの仮想アドレスとファイルオフセットは、64K (0x10000) を法として同じです。64 ビットのセグメントの仮想アドレスとファイルオフセットは、1M バイト (0x100000) を法として同じです。セグメントを最大ページサイズに整列すると、ファイルは物理ページサイズには関係なくページング処理に対して適切になります。

デフォルトでは 64 ビット SPARC プログラムは開始アドレス (0x100000000) にリンクされます。プログラム全体は、テキスト、データ、ヒープ、スタック、および共用オブジェクト依存関係を含めて、4G バイトより上に存在します。そうすることにより、プログラムがポインタを切り捨てると、アドレス空間の最下位 4G バイトでフォルトが発生することになるので、64 ビットプログラムが正しいことをより簡単に確認できます。64 ビットプログラムは 4G バイトより上でリンクされていますが、リンカーに mapfile および -M オプションを使用することにより、プログラムを 4G バイト未満でリンクすることも可能です。詳細は、/usr/lib/ld/sparcv9/map.below4G を参照してください。

次の図に、SPARC バージョンの実行可能ファイルの例を示します。

図 7–8 SPARC: 実行可能ファイル (64K に整列)

SPARC 実行ファイルのレイアウト例

次の表に、前の図に示した読み込み可能セグメント要素の定義を示します。

表 7–28 SPARC: ELF プログラムヘッダーセグメント (64K に整列)

メンバー 

テキスト 

データ 

p_type

PT_LOAD

PT_LOAD

p_offset

0x0

0x4000

p_vaddr

0x10000

0x24000

p_paddr

指定なし 

指定なし 

p_filesize

0x3a82

0x4f5

p_memsz

0x3a82

0x10a4

p_flags

PF_R + PF_X

PF_R + PF_W + PF_X

p_align

0x10000

0x10000

次の図に、x86 バージョンの実行可能ファイルの例を示します。

図 7–9 32 ビット x86: 実行可能ファイル (64K に整列)

x86 実行可能ファイルのレイアウトの例。

次の表に、前の図に示した読み込み可能セグメント要素の定義を示します。

表 7–29 32 ビット x86: ELF プログラムヘッダーセグメント (64K に整列)

メンバー 

テキスト 

データ 

p_type

PT_LOAD

PT_LOAD

p_offset

0x0

0x4000

p_vaddr

0x8050000

0x8064000

p_paddr

指定なし 

指定なし 

p_filesize

0x32fd

0x3a0

p_memsz

0x32fd

0xdc4

p_flags

PF_R + PF_X

PF_R + PF_W + PF_X

p_align

0x10000

0x10000

例に示したファイルオフセットと仮想アドレスは、テキストとデータの両方に対して最大ページサイズを法として同じですが、最大 4 ファイルページ (ページサイズとファイルシステムブロックサイズに依存) に、純粋ではないテキストやデータが含まれます。


注 –

前の例は、テキストセグメントを丸めた、典型的な Solaris OS のバイナリを反映したものです。


データセグメントの終わりは、初期化されていないデータに対して特別な処理を必要とします (初期値が 0 になるようにシステムで定義されている)。ファイルの最後のデータページに、論理メモリーページに存在しない情報が存在する場合、これらのデータは 0 に設定しなければなりません (実行可能ファイルの未知の内容のままにしてはならない)。

ほかの 3 ページに含まれる純粋でないテキストまたはデータは、論理的にはプロセスイメージの一部ではありません。システムがこれらの純粋でないテキストまたはデータを除去するかどうかについては、規定されていません。このプログラムのメモリーイメージが 4K バイト (0x1000) ページを使用する例を、次の図に示します。単純化するために次の図では、1 ページのサイズのみを示しています。

図 7–10 32 ビット SPARC: プロセスイメージセグメント

SPARC プロセスイメージセグメントの例

図 7–11 x86: プロセスイメージセグメント

x86 プロセスイメージセグメントの例

セグメント読み込みは、実行可能ファイルと共有オブジェクトでは異なる側面が 1 つ存在します。実行可能ファイルのセグメントには、標準的には絶対コードが存在します。プロセスを正しく実行するには、セグメントは実行可能ファイルを作成するために使用された仮想アドレスに存在しなければなりません。システムは変化しない p_vaddr 値を仮想アドレスとして使用します。

一方、通常は共有オブジェクトのセグメントには、位置独立のコードが存在します。したがって、セグメントの仮想アドレスは、実行動作を無効にすることなくプロセス間で変化させることができます。

システムは個々のプロセスごとに仮想アドレスを選択しますが、セグメントの相対位置は維持します。位置独立のコードはセグメント間で相対アドレス指定を使用するので、メモリーの仮想アドレス間の差は、ファイルの仮想アドレス間の差に一致しなければなりません。

次の表は、いくつかのプロセスに対する共有オブジェクト仮想アドレスの割り当ての例で、一定の相対位置になることを示しています。これらの表は、ベースアドレスの計算も示しています。

表 7–30 32 ビット SPARC: ELF 共有オブジェクトセグメントアドレスの例

送信元 

テキスト 

データ 

ベースアドレス 

ファイル 

0x0

0x4000

0x0

プロセス 1 

0xc0000000

0xc0024000

0xc0000000

プロセス 2 

0xc0010000

0xc0034000

0xc0010000

プロセス 3 

0xd0020000

0xd0024000

0xd0020000

プロセス 4 

0xd0030000

0xd0034000

0xd0030000

表 7–31 32 ビット x86: ELF 共有オブジェクトセグメントアドレスの例

送信元 

テキスト 

データ 

ベースアドレス 

ファイル 

0x0

0x4000

0x0

プロセス 1 

0x8000000

0x8004000

0x80000000

プロセス 2 

0x80081000

0x80085000

0x80081000

プロセス 3 

0x900c0000

0x900c4000

0x900c0000

プロセス 4 

0x900c6000

0x900ca000

0x900c6000

プログラムインタプリタ

動的リンクを開始する動的実行可能ファイルまたは共有オブジェクトは、1 つの PT_INTERP プログラムヘッダー要素を保持できます。システムは exec(2) の実行中に、PT_INTERP セグメントからパス名を取り出し、そのインタプリタファイルのセグメントから初期プロセスイメージを作成します。インタプリタはシステムから制御を受け取り、アプリケーションプログラムに対して環境を提供する必要があります。

Solaris OS では、インタプリタは実行時リンカー ld.so.1(1) として知られています。

実行時リンカー

リンカーは、動的リンクを開始する動的オブジェクトを作成する際、PT_INTERP 型のプログラムヘッダー要素を実行可能ファイルに付加します。この要素は、実行時リンカーをプログラムインタプリタとして呼び出すようにシステムに指示します。exec(2) と実行時リンカーは、協調してプログラムのプロセスイメージを作成します。

リンカーはまた、実行時リンカーを支援する、実行可能ファイルと共有オブジェクトファイル用のさまざまなデータを作成します。これらのデータは読み込み可能セグメントに存在するため、データを実行時に使用できます。これらのセグメントには、次のものが含まれます。

共有オブジェクトは、ファイルのプログラムヘッダーテーブルに記録されているアドレスとは異なる仮想メモリーアドレスを占有することが可能です。実行時リンカーは、アプリケーションが制御を取得する前に、メモリーイメージを再配置して絶対アドレスを更新します。

動的セクション

オブジェクトファイルが動的リンクに関係している場合、このオブジェクトファイルのプログラムヘッダーテーブルには、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

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

d_ptr

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

各動的タグの値 (2 つの特別な互換性範囲を除く) で d_un union の解釈を決定します。この規則は、外部ツールによる動的タグの解釈をよりシンプルにします。偶数の値を持つタグは、d_ptr を使用する動的セクションのエントリを示します。奇数の値を持つタグは、d_val を使用する動的セクションのエントリ、または d_ptrd_val のどちらも使用しない動的セクションのエントリを示します。特殊値 DT_ENCODING より小さい値を持つタグ、および DT_HIOSDT_LOPROC 間の範囲に入る値を持つタグは、これらの規則には従いません。

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

表 7–32 ELF 動的配列タグ

名前 

値 

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_BIND_NOW

24

無視される 

任意 

任意 

DT_INIT_ARRAY

25

d_ptr

任意 

任意 

DT_FINI_ARRAY

26

d_ptr

任意 

任意 

DT_INIT_ARRAYSZ

27

d_val

任意 

任意 

DT_FINI_ARRAYSZ

28

d_val

任意 

任意 

DT_RUNPATH

29

d_val

任意 

任意 

DT_FLAGS

30

d_val

任意 

任意 

DT_ENCODING

32

指定なし 

指定なし 

指定なし 

DT_PREINIT_ARRAY

32

d_ptr

任意 

無視される 

DT_PREINIT_ARRAYSZ

33

d_val

任意 

無視される 

DT_MAXPOSTAGS

34

指定なし 

指定なし 

指定なし 

DT_LOOS

0x6000000d

指定なし 

指定なし 

指定なし 

DT_SUNW_AUXILIARY

0x6000000d

d_ptr

指定なし 

任意 

DT_SUNW_RTLDINF

0x6000000e

d_ptr

任意 

任意 

DT_SUNW_FILTER

0x6000000e

d_ptr

指定なし 

任意 

DT_SUNW_CAP

0x60000010

d_ptr

任意 

任意 

DT_HIOS

0x6ffff000

指定なし 

指定なし 

指定なし 

DT_VALRNGLO

0x6ffffd00

指定なし 

指定なし 

指定なし 

DT_CHECKSUM

0x6ffffdf8

d_val

任意 

任意 

DT_PLTPADSZ

0x6ffffdf9

d_val

任意 

任意 

DT_MOVEENT

0x6ffffdfa

d_val

任意 

任意 

DT_MOVESZ

0x6ffffdfb

d_val

任意 

任意 

DT_FEATURE_1

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_CONFIG

0x6ffffefa

d_ptr

任意 

任意 

DT_DEPAUDIT

0x6ffffefb

d_ptr

任意 

任意 

DT_AUDIT

0x6ffffefc

d_ptr

任意 

任意 

DT_PLTPAD

0x6ffffefd

d_ptr

任意 

任意 

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_LOPROC

0x70000000

指定なし 

指定なし 

指定なし 

DT_SPARC_REGISTER

0x70000001

d_val

任意 

任意 

DT_AUXILIARY

0x7ffffffd

d_val

指定なし 

任意 

DT_USED

0x7ffffffe

d_val

任意 

任意 

DT_FILTER

0x7fffffff

d_val

指定なし 

任意 

DT_HIPROC

0x7fffffff

指定なし 

指定なし 

指定なし 

DT_NULL

_DYNAMIC 配列の終わりを示します。

DT_NEEDED

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

DT_PLTRELSZ

プロシージャーのリンクテーブルに関連付けられている再配置エントリの合計サイズ (単位: バイト)。「プロシージャーのリンクテーブル (プロセッサ固有)」を参照してください。

DT_PLTGOT

プロシージャーのリンクテーブルまたは大域オフセットテーブルに関連付けられるアドレス。「プロシージャーのリンクテーブル (プロセッサ固有)」「大域オフセットテーブル (プロセッサ固有)」を参照してください。

DT_HASH

シンボルハッシュテーブルのアドレス。このテーブルは、DT_SYMTAB 要素で示されるシンボルテーブルを参照します。「ハッシュテーブルセクション」を参照してください。

DT_STRTAB

文字列テーブルのアドレス。文字列テーブルには、実行時リンカーが必要とするシンボル名、依存性名、およびほかの文字列が存在します。「文字列テーブルセクション」を参照してください。

DT_SYMTAB

シンボルテーブルのアドレス。「シンボルテーブルセクション」を参照してください。

DT_RELA

再配置テーブルのアドレス。「再配置セクション」を参照してください。

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

この要素が存在する場合、DT_RELASZ 要素と DT_RELAENT 要素も存在する必要があります。再配置がファイルに対して必須の場合、DT_RELA または DT_REL が使用可能です。

DT_RELASZ

DT_RELA 再配置テーブルの合計サイズ (単位: バイト)。

DT_RELAENT

DT_RELA 再配置エントリのサイズ (単位: バイト)。

DT_STRSZ

DT_STRTAB 文字列テーブルの合計サイズ (単位: バイト)。

DT_SYMENT

DT_SYMTAB シンボルエントリのサイズ (単位: バイト)。

DT_INIT

初期化関数のアドレス。「初期設定および終了セクション」を参照してください。

DT_FINI

終了関数のアドレス。「初期設定および終了セクション」を参照してください。

DT_SONAME

ヌル文字で終わっている文字列の DT_STRTAB 文字列テーブルオフセットで、共有オブジェクトの名前を示します。「共有オブジェクト名の記録」を参照してください。

DT_RPATH

ヌル文字で終わっているライブラリ検索パス文字列の DT_STRTAB 文字列テーブルオフセット。この要素の使用は、DT_RUNPATH に置き換えられました。「実行時リンカーが検索するディレクトリ」を参照してください。

DT_SYMBOLIC

オブジェクトが、リンク編集中に適用されたシンボリック結合を含むことを示します。この要素の使用は、DF_SYMBOLIC フラグに置き換えられました。-B symbolic オプションの使用」を参照してください。

DT_REL

DT_RELA に似ていますが、テーブルに暗黙の加数が存在する点が異なります。この要素が存在する場合、DT_RELSZ 要素と DT_RELENT 要素も存在する必要があります。

DT_RELSZ

DT_REL 再配置テーブルの合計サイズ (単位: バイト)。

DT_RELENT

DT_REL 再配置エントリのサイズ (単位: バイト)。

DT_PLTREL

プロシージャーのリンクテーブルが参照する再配置エントリの型 (DT_REL または DT_RELA) を示します。1 つのプロシージャーのリンクテーブルでは、すべての再配置は、同じ再配置を使用しなければなりません。「プロシージャーのリンクテーブル (プロセッサ固有)」を参照してください。この要素が存在する場合、DT_JMPREL 要素も存在する必要があります。

DT_DEBUG

デバッグに使用されます。

DT_TEXTREL

1 つまたは複数の再配置エントリが書き込み不可セグメントに対する変更を要求する可能性があり、実行時リンカーはそれに応じて対応できることを示します。この要素の使用は、DF_TEXTREL フラグに置き換えられました。「位置独立のコード」を参照してください。

DT_JMPREL

プロシージャーのリンクテーブルにのみ関連付けられている再配置エントリのアドレス。「プロシージャーのリンクテーブル (プロセッサ固有)」を参照してください。これらの再配置エントリを分離しておくと、遅延結合が有効なオブジェクトの読み込み時に、実行時リンカーはこれらのエントリを無視できます。この要素が存在する場合、DT_PLTRELSZ 要素と DT_PLTREL 要素も存在する必要があります。

DT_POSFLAG_1

直後の DT_ 要素に適用されるさまざまな状態フラグ。表 7–35 を参照してください。

DT_BIND_NOW

プログラムに制御を渡す前に、このオブジェクトについてのすべての再配置を処理するよう実行時リンカーに指示します。環境または dlopen(3C) で指定された場合、このエントリは遅延結合の使用指令よりも優先されます。この要素の使用は、DF_BIND_NOW フラグに置き換えられました。詳細は、「再配置が実行されるとき」を参照してください。

DT_INIT_ARRAY

初期設定関数へのポインタの配列のアドレス。この要素が存在する場合、DT_INIT_ARRAYSZ 要素も存在する必要があります。「初期設定および終了セクション」を参照してください。

DT_FINI_ARRAY

終了関数へのポインタの配列のアドレス。この要素が存在する場合、DT_FINI_ARRAYSZ 要素も存在する必要があります。「初期設定および終了セクション」を参照してください。

DT_INIT_ARRAYSZ

DT_INIT_ARRAY 配列の合計サイズ (単位: バイト)。

DT_FINI_ARRAYSZ

DT_FINI_ARRAY 配列の合計サイズ (単位: バイト)。

DT_RUNPATH

ヌル文字で終わっているライブラリ検索パス文字列の DT_STRTAB 文字列テーブルオフセット。「実行時リンカーが検索するディレクトリ」を参照してください。

DT_FLAGS

このオブジェクトに特有のフラグ値。表 7–33 を参照してください。

DT_ENCODING

DT_ENCODING と等しいかそれより大きく、かつ DT_LOOS と等しいかそれより小さい動的タグ値は、 d_un union の解釈の規則に従います。

DT_PREINIT_ARRAY

「初期設定前」関数へのポインタの配列のアドレス。この要素が存在する場合、DT_PREINIT_ARRAYSZ 要素も存在する必要があります。この配列は、実行可能ファイル内でのみ処理されます。共有オブジェクト内に含まれている場合、この配列は無視されます。「初期設定および終了セクション」を参照してください。

DT_PREINIT_ARRAYSZ

DT_PREINIT_ARRAY 配列の合計サイズ (単位: バイト)。

DT_MAXPOSTAGS

値が正である動的配列タグの数。

DT_LOOS - DT_HIOS

この範囲の値 (両端の値を含む) は、オペレーティングシステム固有のセマンティクスのために予約されています。このような値はすべて、d_un union の解釈の規則に従います。

DT_SUNW_AUXILIARY

ヌル文字で終わっている文字列の DT_STRTAB 文字列テーブルオフセットで、シンボル別の補助フィルティーを 1 つ以上指定します。「補助フィルタの生成」を参照してください。

DT_SUNW_RTLDINF

実行時リンカーによる使用のために予約されています。

DT_SUNW_FILTER

ヌル文字で終わっている文字列の DT_STRTAB 文字列テーブルオフセットで、シンボル別の標準フィルティーを 1 つ以上指定します。「標準フィルタの生成」を参照してください。

DT_SUNW_CAP

ハードウェアとソフトウェア機能セクションのアドレス。「ハードウェアおよびソフトウェア機能に関するセクション」を参照してください。

DT_SYMINFO

シンボル情報テーブルのアドレス。この要素が存在する場合、DT_SYMINENT 要素と DT_SYMINSZ 要素も存在する必要があります。「Syminfo テーブルセクション」を参照してください。

DT_SYMINENT

DT_SYMINFO 情報エントリのサイズ (単位: バイト)。

DT_SYMINSZ

DT_SYMINFO テーブルのサイズ (単位: バイト)。

DT_VERDEF

バージョン定義テーブルのアドレス。このテーブル内の要素には、文字列テーブル DT_STRTAB のインデックスが含まれます。この要素が存在する場合、DT_VERDEFNUM 要素も存在する必要があります。「バージョン定義セクション」を参照してください。

DT_VERDEFNUM

DT_VERDEF テーブルのエントリ数。

DT_VERNEED

バージョン依存性テーブルのアドレス。このテーブル内の要素には、文字列テーブル DT_STRTAB のインデックスが含まれます。この要素が存在する場合、DT_VERNEEDNUM 要素も存在する必要があります。「バージョン依存セクション」を参照してください。

DT_VERNEEDNUM

DT_VERNEEDNUM テーブルのエントリ数。

DT_RELACOUNT

すべての Elf32_Rela または Elf64_Rela 再配置の連結から生成される RELATIVE 再配置回数を示します。「再配置セクションの結合」を参照してください。

DT_RELCOUNT

すべての Elf32_Rel 再配置の連結から生成される RELATIVE 再配置回数を示します。「再配置セクションの結合」を参照してください。

DT_AUXILIARY

ヌル文字で終わっている DT_STRTAB 文字列テーブルオフセットで、1 つ以上の補助フィルティーを指定します。「補助フィルタの生成」を参照してください。

DT_FILTER

ヌル文字で終わっている DT_STRTAB 文字列テーブルオフセットで、1 つ以上の標準「フィルティー」を指定します。「標準フィルタの生成」を参照してください。

DT_CHECKSUM

オブジェクトの選択されたセクションの簡単なチェックサム。gelf_checksum(3ELF) のマニュアルページを参照してください。

DT_MOVEENT

DT_MOVETAB 移動エントリのサイズ (単位: バイト)。

DT_MOVESZ

DT_MOVETAB テーブルの合計サイズ (単位: バイト)。

DT_MOVETAB

移動テーブルのアドレス。この要素が存在する場合、DT_MOVEENT 要素と DT_MOVESZ 要素も存在する必要があります。「移動セクション」を参照してください。

DT_CONFIG

ヌル文字で終わっている DT_STRTAB 文字列テーブルオフセットで、構成ファイルを定義します。構成ファイルは、実行可能ファイルでのみ有効であり、通常このオブジェクトに固有のファイルです。「デフォルトの検索パスの設定」を参照してください。

DT_DEPAUDIT

ヌル文字で終わっている DT_STRTAB 文字列テーブルオフセットで、1 つ以上の監査ライブラリを定義します。「実行時リンカーの監査インタフェース」を参照してください。

DT_AUDIT

ヌル文字で終わっている DT_STRTAB 文字列テーブルオフセットで、1 つ以上の監査ライブラリを定義します。「実行時リンカーの監査インタフェース」を参照してください。

DT_FLAGS_1

このオブジェクトに特有のフラグ値。表 7–34 を参照してください。

DT_FEATURE_1

このオブジェクト特有の機能を示す値。表 7–36 を参照してください。

DT_VALRNGLO - DT_VALRNGHI

この範囲の値 (両端の値を含む) は、動的構造体の d_un.d_val フィールドによって使用されます。

DT_ADDRRNGLO - DT_ADDRRNGHI

この範囲の値 (両端の値を含む) は、動的構造体の d_un.d_ptr フィールドによって使用されます。ELF オブジェクトが作成後に調整された場合、これらのエントリも更新する必要があります。

DT_SPARC_REGISTER

DT_SYMTAB シンボルテーブル内の STT_SPARC_REGISTER シンボルのインデックス。シンボルテーブルの各 STT_SPARC_REGISTER シンボルには、1 つの動的エントリが存在します。「レジスタシンボル」を参照してください。

DT_LOPROC - DT_HIPROC

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

動的配列の最後にある DT_NULL 要素と、DT_NEEDEDDT_POSFLAG_1 要素の相対的な順序を除くと、エントリはどの順序で現れてもかまいません。表に示されていないタグ値は予約されています。

表 7–33 ELF 動的フラグ DT_FLAGS

名前 

値 

意味 

DF_ORIGIN

0x1

$ORIGIN 処理が必要です

DF_SYMBOLIC

0x2

シンボリックシンボル解決が必要です 

DF_TEXTREL

0x4

テキストの再配置が存在します 

DF_BIND_NOW

0x8

非遅延結合が必要です 

DF_STATIC_TLS

0x10

オブジェクトは静的なスレッド固有領域方式を使用します 

DF_ORIGIN

オブジェクトに $ORIGIN 処理が必要であることを示します。「関連する依存関係の配置」を参照してください。

DF_SYMBOLIC

オブジェクトが、リンク編集中に適用されたシンボリック結合を含むことを示します。-B symbolic オプションの使用」を参照してください。

DF_TEXTREL

1 つまたは複数の再配置エントリが書き込み不可セグメントに対する変更を要求する可能性があり、実行時リンカーはそれに応じて対応できることを示します。「位置独立のコード」を参照してください。

DF_BIND_NOW

プログラムに制御を渡す前に、このオブジェクトについてのすべての再配置を処理するよう実行時リンカーに指示します。環境または dlopen(3C) で指定された場合、このエントリは遅延結合の使用指令よりも優先されます。詳細は、「再配置が実行されるとき」を参照してください。

DF_STATIC_TLS

静的なスレッド固有領域方式を使用するコードがオブジェクトに含まれていることを示します。静的なスレッド固有領域は、dlopen(3C) または遅延読み込みを使用して動的に読み込まれるオブジェクトでは使用すべきではありません。

表 7–34 ELF 動的フラグ DT_FLAGS_1

名前 

値 

意味 

DF_1_NOW

0x1

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

DF_1_GLOBAL

0x2

未使用 

DF_1_GROUP

0x4

オブジェクトがグループのメンバーであることを示します。 

DF_1_NODELETE

0x8

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

DF_1_LOADFLTR

0x10

フィルティーの即時読み込みを保証します。

DF_1_INITFIRST

0x20

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

DF_1_NOOPEN

0x40

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

DF_1_ORIGIN

0x80

$ORIGIN 処理が必要です。

DF_1_DIRECT

0x100

直接結合が有効です。 

DF_1_INTERPOSE

0x400

オブジェクトは割り込み処理です。 

DF_1_NODEFLIB

0x800

デフォルトのライブラリ検索パスを無視します。 

DF_1_NODUMP

0x1000

オブジェクトを dldump(3C) でダンプできません。

DF_1_CONFALT

0x2000

オブジェクトは代替構成です。 

DF_1_ENDFILTEE

0x4000

「フィルティー」がフィルタの検索を終了します。

DF_1_DISPRELDNE

0x8000

ディスプレイスメント再配置が実行されました。 

DF_1_DISPRELPND

0x10000

ディスプレイスメント再配置の保留。 

DF_1_NODIRECT

0x20000

オブジェクトは間接的な結合を含みます。 

DF_1_IGNMULDEF

0x40000

内部使用。 

DF_1_NOKSYMS

0x80000

内部使用。 

DF_1_NOHDR

0x100000

内部使用。 

DF_1_NORELOC

0x400000

内部使用。 

DF_1_GLOBAUDIT

0x1000000

大域監査を確立します。 

DF_1_NOW

プログラムに制御を渡す前に、このオブジェクトについてのすべての再配置を処理するよう実行時リンカーに指示します。環境または dlopen(3C) で指定された場合、このフラグは遅延結合の使用指令よりも優先されます。詳細は、「再配置が実行されるとき」を参照してください。

DF_1_GROUP

オブジェクトがグループのメンバーであることを示します。このフラグは、リンカーの -B group オプションを使用してオブジェクトに記録されます。「オブジェクト階層」を参照してください。

DF_1_NODELETE

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

DF_1_LOADFLTR

フィルタに対してのみ意味があります。関連付けられているすべてのフィルティーがただちに処理されることを示します。このフラグは、リンカーの -z loadfltr オプションを使用してオブジェクトに記録されます。「「フィルティー」の処理」を参照してください。

DF_1_INITFIRST

読み込まれたほかのオブジェクトよりも先に、このオブジェクトの初期化セクションが実行されることを示します。このフラグは特殊なシステムライブラリでのみ使用するもので、リンカーの -z initfirst オプションを使用してオブジェクトに記録されます。

DF_1_NOOPEN

dlopen(3C) を使ってオブジェクトを実行中のプロセスに追加できないことを示します。このフラグは、リンカーの -z nodlopen オプションを使用してオブジェクトに記録されます。

DF_1_ORIGIN

オブジェクトに $ORIGIN 処理が必要であることを示します。「関連する依存関係の配置」を参照してください。

DF_1_DIRECT

オブジェクトが直接結合情報を使用することを示します。「直接結合」を参照してください。

DF_1_INTERPOSE

オブジェクトシンボルテーブルの割り込みが、一次読み込みオブジェクト (通常は実行可能ファイル) 以外のすべてのシンボルの前で発生します。このフラグは、リンカーの -z interpose オプションを使用して記録されます。「実行時割り込み」を参照してください。

DF_1_NODEFLIB

このオブジェクトの依存関係を検索する際、デフォルトのライブラリ検索パスがすべて無視されることを示します。このフラグは、リンカーの -z nodefaultlib オプションを使用してオブジェクトに記録されます。「実行時リンカーが検索するディレクトリ」を参照してください。

DF_1_NODUMP

このオブジェクトが dldump(3C) によってダンプされないことを示します。このオプションの候補には、再配置を保持しないオブジェクトが含まれ、これらのオブジェクトは、crle(1) を使用して代替オブジェクトを生成する際に含めることができます。このフラグは、リンカーの -z nodump オプションを使用してオブジェクトに記録されます。

DF_1_CONFALT

このオブジェクトが、crle(1) によって生成された代替構成オブジェクトであることを示します。このフラグにより実行時リンカーがトリガーされ、構成ファイル $ORIGIN/ld.config. app-name が検索されます。

DF_1_ENDFILTEE

「フィルティー」に対してのみ意味があります。以降の「フィルティー」に対するフィルタ検索は行われません。このフラグは、リンカーの -z endfiltee オプションを使用してオブジェクトに記録されます。「「フィルティー」検索の縮小」を参照してください。

DF_1_DISPRELDNE

このオブジェクトにディスプレイスメント再配置が適用されたことを示します。再配置が適用されるとレコードは破棄されるため、オブジェクト内のディスプレイスメント再配置レコードはもはや存在しません。「ディスプレイスメント再配置」を参照してください。

DF_1_DISPRELPND

このオブジェクトのディスプレイスメント再配置が保留されていることを示します。ディスプレイスメント再配置はオブジェクト内部で終了するため、再配置は実行時に完了できます。「ディスプレイスメント再配置」を参照してください。

DF_1_NODIRECT

このオブジェクトに、直接結合できないシンボルが含まれることを示します。mapfile を使用した追加シンボルの定義」を参照してください。

DF_1_IGNMULDEF

カーネルの実行時リンカーによる使用のために予約されています。

DF_1_NOKSYMS

カーネルの実行時リンカーによる使用のために予約されています。

DF_1_NOHDR

カーネルの実行時リンカーによる使用のために予約されています。

DF_1_NORELOC

カーネルの実行時リンカーによる使用のために予約されています。

DF_1_GLOBAUDIT

動的実行可能ファイルで大域監査が必要であることを示します。「大域監査の記録」を参照してください。

表 7–35 ELF 動的位置フラグ DT_POSFLAG_1

名前 

値 

意味 

DF_P1_LAZYLOAD

0x1

遅延読み込みされた依存関係を示します。 

DF_P1_GROUPPERM

0x2

グループの依存関係を示します。 

DF_P1_LAZYLOAD

後続の DT_NEEDED エントリが遅延読み込み対象のオブジェクトであることを示します。このフラグは、リンカーの -z lazyload オプションを使用してオブジェクトに記録されます。「動的依存関係の遅延読み込み」を参照してください。

DF_P1_GROUPPERM

後続の DT_NEEDED エントリがグループとして読み込まれるオブジェクトであることを示します。このフラグは、リンカーの -z groupperm オプションを使用してオブジェクトに記録されます。「グループの分離」を参照してください。

表 7–36 ELF 動的機能フラグ DT_FEATURE_1

名前 

値 

意味 

DTF_1_PARINIT

0x1

部分的な初期化機能が必要です。 

DTF_1_CONFEXP

0x2

構成ファイルが必要です。 

DTF_1_PARINIT

オブジェクトが部分的な初期化を必要とすることを示します。「移動セクション」を参照してください。

DTF_1_CONFEXP

このオブジェクトが、crle(1) によって生成された代替構成オブジェクトであることを示します。このフラグにより実行時リンカーがトリガーされ、構成ファイル $ORIGIN/ld.config. app-name が検索されます。このフラグの効果は、DF_1_CONFALT と同じです。

大域オフセットテーブル (プロセッサ固有)

一般に位置独立のコードには絶対仮想アドレスは存在できません。大域オフセットテーブルは、内部で使用するデータ内に絶対アドレスを保持します。このため、位置からの独立性とプログラムのテキストの共有性を低下させることなくアドレスが使用可能になります。プログラムは、位置独立のアドレス指定を使用して GOT を参照し、絶対値を抽出します。この方法により、位置独立の参照を、絶対位置にリダイレクトできます。

最初は、GOT は再配置エントリで要求される情報を保持します。システムが読み込み可能オブジェクトファイルのメモリーセグメントを作成したあと、実行時リンカーが再配置エントリを処理します。これらの再配置のいくつかは、R_xxxx_GLOB_DAT タイプで GOT を参照する場合があります。

実行時リンカーは、関連付けられているシンボル値を判定し、絶対アドレスを計算し、適切なメモリーテーブルエントリに正しい値を設定します。リンカーがオブジェクトファイルを作成するとき、絶対アドレスは認識されていませんが、実行時リンカーはすべてのメモリーセグメントのアドレスを認識しており、したがって、これらのメモリーセグメントに存在するシンボルの絶対アドレスを計算できます。

プログラムがシンボルの絶対アドレスへの直接アクセスを必要とする場合、このシンボルには GOT エントリが存在します。実行可能ファイルと共有オブジェクトには別個の GOT が存在するので、シンボルのアドレスはいくつかのテーブルに現れることがあります。実行時リンカーは、すべての GOT の再配置を処理してから、プロセスイメージ内のいずれかのコードに制御を渡します。この処理により、実行時に絶対アドレスが利用可能になります。

テーブルのエントリ 0 は、_DYNAMIC シンボルで参照される動的構造体のアドレスを保持するために予約されています。このシンボルを利用することにより、実行時リンカーなどのプログラムは、再配置エントリを処理していなくても自身の動的構造体を見つけることができます。この方法は、実行時リンカーにとって特に重要です。なぜなら、実行時リンカーはほかのプログラムに頼ることなく自身を初期化してメモリーイメージを再配置しなければならないからです。

システムは、異なるプログラムの同じ共有オブジェクトに対して、異なるメモリーセグメントアドレスを与えることがあります。さらに、システムはプログラムを実行するごとに異なるライブラリアドレスを与えることさえあります。しかし、プロセスイメージがいったん作成されると、メモリーセグメントのアドレスは変更されません。プロセスが存在するかぎり、そのプロセスのメモリーセグメントは固定仮想されたアドレスに存在します。

GOT の形式と解釈は、プロセッサに固有です。_GLOBAL_OFFSET_TABLE_ シンボルは、テーブルをアクセスするために使用できます。このシンボルは、.got セクションの中央に存在可能であるため、負の添字と負でない添字の両方をアドレスの配列に含めることができます。シンボルタイプは、32 ビットコードの場合、Elf 32_Addr の配列で、64 ビットコードの場合、Elf 64_Addr の配列です。

extern  Elf32_Addr  _GLOBAL_OFFSET_TABLE_[];
extern  Elf64_Addr  _GLOBAL_OFFSET_TABLE_[];

プロシージャーのリンクテーブル (プロセッサ固有)

大域オフセットテーブルは位置独立のアドレスの計算を絶対位置に変換します。同様に、プロシージャーのリンクテーブルは位置独立の関数呼び出しを絶対位置に変換します。リンカーは、異なる動的オブジェクト間の実行転送 (関数呼び出しなど) を解決できません。このため、リンカーはプログラム転送制御をプロシージャーのリンクテーブルのエントリに与えます。このようにして実行時リンカーは、位置からの独立性とプログラムのテキストの共有性を低下させることなくエントリをリダイレクトします。実行可能ファイルと共有オブジェクトファイルには、別個のプロシージャーのリンクテーブルが存在します。

32 ビット SPARC: プロシージャーのリンクテーブル

32 ビット SPARC 動的オブジェクトの場合、プロシージャーのリンクテーブルは専用データ内に存在します。実行時リンカーは、宛先の絶対アドレスを判定し、これらの絶対アドレスに従ってプロシージャーのリンクテーブルのメモリーイメージに変更を加えます。

最初の 4 つのプロシージャーのリンクテーブルエントリは、予約されています。表 7–37 に例示されてはいますが、これらのエントリの元の内容は指定されていません。テーブル内の各エントリは 3 ワード (12 バイト) を占めており、最後のテーブルエントリの後には nop 命令が続きます。

再配置テーブルは、プロシージャーのリンクテーブルに関連付けられています。_DYNAMIC 配列の DT_JMP_REL エントリは、最初の再配置エントリの位置を与えます。再配置テーブルには、予約されていないプロシージャーのリンクテーブルエントリごとに 1 つのエントリが同じ順番で存在します。各エントリの再配置タイプは、R_SPARC_JMP_SLOT です。再配置オフセットは関連付けられているプロシージャーのリンクテーブルエントリの先頭バイトのアドレスを指定します。シンボルテーブルインデックスは適切なシンボルを参照します。

プロシージャーのリンクテーブル機能を説明するため、表 7–37 に 4 つのエントリが示されています。4 つのエントリのうちの 2 つは初期状態で予約されているエントリです。3 番目のエントリは name101 に対する呼び出しです。4 番目のエントリは name102 に対する呼び出しです。この例では、name102 のエントリがテーブルの最後のエントリであることを前提としています。この最後のエントリの後には nop 命令が続きます。左欄は、動的リンクが行われる前のオブジェクトファイルの命令を示しています。右欄は、実行時リンカーがプロシージャーリンクテーブルのエントリを変更するために使用できる命令シーケンスを示しています。

表 7–37 32 ビット SPARC: プロシージャーのリンクテーブルの例

オブジェクトファイル

メモリーセグメント

.PLT0:
    unimp
    unimp
    unimp
.PLT1:
    unimp
    unimp
    unimp
.PLT0:
    save    %sp, -64, %sp
    call    runtime_linker
    nop
.PLT1:
    .word   identification
    unimp
    unimp
.PLT101:
    sethi   (.-.PLT0), %g1
    ba,a    .PLT0
    nop
.PLT102:
    sethi   (.-.PLT0), %g1
    ba,a    .PLT0
    nop

    nop
.PLT101:
    nop
    ba,a    name101
    nop
.PLT102:
    sethi   (.-.PLT0), %g1
    sethi   %hi(name102), %g1
    jmpl    %g1+%lo(name102), %g0
    
    nop

次の手順は、実行時リンカーとプログラムがプロシージャーのリンクテーブルによってシンボル参照をどのように協調して解決するかを示しています。ただし、次に記述されている手順は、単に説明のためのものです。実行時リンカーの正確な実行時動作については、記述されていません。

  1. プログラムのメモリーイメージが最初に作成されると、実行時リンカーはプロシージャーのリンクテーブルの初期エントリを変更します。これらのエントリは、実行時リンカー自身のルーチンの 1 つに制御を渡すように修正されます。実行時リンカーはまた、識別情報 (identification) を 2 番目のエントリに格納します。実行時リンカーが制御を受け取ると、このワードは呼び出したオブジェクトを見つけるために調べられます。

  2. ほかのすべてのプロシージャーのリンクテーブルエントリは、最初は先頭エントリに渡されます。これで、実行時リンカーは各テーブルエントリの最初の実行時に制御を取得します。たとえば、プログラムが name101 を呼び出すと、制御がラベル .PLT101 に渡されます。

  3. sethi 命令は、現在のプロシージャーのリンクテーブルエントリ (.PLT101) と最初のプロシージャーのリンクテーブルエントリ (.PLT0) の距離を計算します。この値は、%g1 レジスタの最上位 22 ビットを占めます。

  4. 次に、ba,a 命令が .PLT0 にジャンプして、スタックフレームを作成し、実行時リンカーを呼び出します。

  5. 実行時リンカーは、識別情報の値を使うことによってオブジェクトのデータ構造体 (再配置テーブルを含む) を取得します。

  6. 実行時リンカーは、%g1 値をシフトしプロシージャーのリンクテーブルエントリのサイズで除算することで、 name101 の再配置エントリのインデックスを計算します。再配置エントリ 101 のタイプは R_SPARC_JMP_SLOT です。再配置オフセットは .PLT101 のアドレスを指定し、また、そのシンボルテーブルインデックスは name101 を参照します。したがって、実行時リンカーはシンボルの実際の値を取得し、スタックを戻し、プロシージャーのリンクテーブルエントリに変更を加え、本来の宛先に制御を渡します。

実行時リンカーは、メモリーセグメント欄に示された命令シーケンスを必ずしも作成するとは限りません。ただし、作成する場合は、いくつかの点でより詳細な説明が必要です。


注 –

.PLT101.PLT102 の命令シーケンスの違いから、関連する宛先に合わせた最適化の方法を知ることができます。


LD_BIND_NOW 環境変数は、動的リンク動作を変更します。この環境変数の値がヌル文字以外の場合、実行時リンカーは、プログラムに制御を渡す前に R_SPARC_JMP_SLOT 再配置エントリを処理します。

64 ビット SPARC: プロシージャーのリンクテーブル

64 ビット SPARC 動的オブジェクトの場合、プロシージャーのリンクテーブルは専用データ内に存在します。実行時リンカーは、宛先の絶対アドレスを判定し、これらの絶対アドレスに従ってプロシージャーのリンクテーブルのメモリーイメージに変更を加えます。

最初の 4 つのプロシージャーのリンクテーブルエントリは、予約されています。表 7–38 に例示されてはいますが、これらのエントリの元の内容は指定されていません。テーブル内の先頭 32,768 エントリは、それぞれ 8 ワード (32 バイト) を占め、32 バイト境界で整列する必要があります。テーブル全体は 256 バイト境界で整列する必要があります。32,768 を超えるエントリが必要な場合、残りのエントリは 6 ワード (24 バイト) および 1 つのポインタ (8 バイト) で構成されます。命令は、160 エントリのブロックにまとめられ、その次に 160 個ポインタが続きます。最後のグループのエントリとポインタは、160 未満でもかまいません。パディングの必要はありません。


注 –

32,768 および 160 という数字は、それぞれ分岐と読み込み置換の制限に基づいており、また、キャッシュの効率を向上させるために、コードとデータの間の区分を 256 バイト境界に合わせています。


再配置テーブルは、プロシージャーのリンクテーブルに関連付けられています。_DYNAMIC 配列の DT_JMP_REL エントリは、最初の再配置エントリの位置を与えます。再配置テーブルには、予約されていないプロシージャーのリンクテーブルエントリごとに 1 つのエントリが同じ順番で存在します。各エントリの再配置タイプは、R_SPARC_JMP_SLOT です。最初の 32,767 スロットでは、再配置オフセットは関連するプロシージャーのリンクテーブルエントリの先頭バイトのアドレスを指定します。加数フィールドはゼロになります。シンボルテーブルインデックスは適切なシンボルを参照します。32,768 以後のスロットでは、再配置オフセットは関連するポインタの先頭バイトのアドレスを指定します。加数フィールドは、再配置されていない値 -(.PLTN + 4) になります。シンボルテーブルインデックスは適切なシンボルを参照します。

プロシージャーのリンクテーブル機能を説明するため、表 7–38 に 4 つのエントリが示されています。最初の 3 つのエントリは、予約済みの初期エントリを示します。続く 3 つのエントリは、32,768 エントリの初期状態と、それぞれ、対象アドレスがエントリの +/- 2G バイト以内の場合、アドレス空間の下位 4G バイト以内の場合、およびその他の場合に適用されると考えられる、変換された状態を示しています。最後の 2 つのエントリは、命令とポインタのペアで構成される、後のエントリの例を示します。左欄は、動的リンクが行われる前のオブジェクトファイルの命令を示しています。右欄は、実行時リンカーがプロシージャーリンクテーブルのエントリを変更するために使用できる命令シーケンスを示しています。

表 7–38 64 ビット SPARC: プロシージャーのリンクテーブルの例

オブジェクトファイル

メモリーセグメント

.PLT0:
    unimp
    unimp
    unimp
    unimp
    unimp
    unimp
    unimp
    unimp
.PLT1:
    unimp
    unimp
    unimp
    unimp
    unimp
    unimp
    unimp
    unimp
.PLT2:
    unimp
.PLT0:
    save    %sp, -176, %sp
    sethi   %hh(runtime_linker_0), %l0
    sethi   %lm(runtime_linker_0), %l1
    or      %l0, %hm(runtime_linker_0), %l0
    sllx    %l0, 32, %l0
    or      %l0, %l1, %l0
    jmpl    %l0+%lo(runtime_linker_0), %o1
    mov     %g1, %o0
.PLT1:
    save    %sp, -176, %sp
    sethi   %hh(runtime_linker_1), %l0
    sethi   %lm(runtime_linker_1), %l1
    or      %l0, %hm(runtime_linker_1), %l0
    sllx    %l0, 32, %l0
    or      %l0, %l1, %l0
    jmpl    %l0+%lo(runtime_linker_0), %o1
    mov     %g1, %o0
.PLT2:
    .xword  identification
.PLT101:
    sethi   (.-.PLT0), %g1
    ba,a    %xcc, .PLT1
    nop
    nop
    nop;    nop
    nop;    nop
.PLT102:
    sethi   (.-.PLT0), %g1
    ba,a    %xcc, .PLT1
    nop
    nop
    nop;    nop
    nop;    nop
.PLT103:
    sethi   (.-.PLT0),  %g1
    ba,a    %xcc, .PLT1
    nop
    nop
    nop
    nop
    nop
    nop
.PLT101:
    nop
    mov     %o7,  %g1
    call    name101
    mov     %g1, %o7
    nop;    nop
    nop;    nop
.PLT102:
    nop
    sethi   %hi(name102), %g1
    jmpl    %g1+%lo(name102), %g0
    nop
    nop;    nop
    nop;    nop
.PLT103:
    nop
    sethi   %hh(name103), %g1
    sethi   %lm(name103), %g5
    or      %hm(name103), %g1
    sllx    %g1, 32, %g1
    or      %g1, %g5, %g5
    jmpl    %g5+%lo(name103), %g0
    nop
.PLT32768:
    mov     %o7, %g5
    call    .+8
    nop
    ldx     [%o7+.PLTP32768 -
              (.PLT32768+4)], %g1
    jmpl    %o7+%g1, %g1
    mov     %g5, %o7

    ...

.PLT32927:
    mov     %o7, %g5
    call    .+8
    nop
    ldx     [%o7+.PLTP32927 -
              (.PLT32927+4)], %g1
    jmpl    %o7+%g1, %g1
    mov     %g5, %o7
.PLT32768:
    <unchanged>
    <unchanged>
    <unchanged>
    <unchanged>

    <unchanged>
    <unchanged>

    ...

.PLT32927:
    <unchanged>
    <unchanged>
    <unchanged>
    <unchanged>

    <unchanged>
    <unchanged>
.PLTP32768
    .xword  .PLT0 -
              (.PLT32768+4)
    ...

.PLTP32927
    .xword  .PLT0 -
              (.PLT32927+4)
.PLTP32768
    .xword  name32768 -
              (.PLT32768+4)
    ...
    
.PLTP32927
    .xword  name32927 -
	      (.PLT32927+4)

次の手順は、実行時リンカーとプログラムがプロシージャーのリンクテーブルによってシンボル参照をどのように協調して解決するかを示しています。ただし、次に記述されている手順は、単に説明のためのものです。実行時リンカーの正確な実行時動作については、記述されていません。

  1. プログラムのメモリーイメージが最初に作成されると、実行時リンカーはプロシージャーのリンクテーブルの初期エントリを変更します。エントリは、実行時リンカー自身のルーチンに制御を渡すように修正されます。実行時リンカーはまた、識別情報 (identification) の拡張ワードを 3 番目のエントリに格納します。実行時リンカーが制御を受け取ると、このワードは呼び出したオブジェクトを見つけるために調べられます。

  2. ほかのすべてのプロシージャーのリンクテーブルエントリは、最初、先頭または 2 番目のエントリに渡されます。これらのエントリは、スタックフレームを確立して、実行時リンカーを呼び出します。

  3. 実行時リンカーは、識別情報の値を使うことによってオブジェクトのデータ構造体 (再配置テーブルを含む) を取得します。

  4. 実行時リンカーは、テーブルスロットの再配置エントリのインデックスを計算します。

  5. インデックス情報に関しては、実行時リンカーはシンボルの実際の値を取得し、スタックを戻し、プロシージャーのリンクテーブルエントリを変更してから、制御を宛先に渡します。

実行時リンカーは、メモリーセグメント欄に示された命令シーケンスを必ずしも作成するとは限りません。ただし、作成する場合は、いくつかの点でより詳細な説明が必要です。

エントリの 2 番目のフォームに示すように、ポインタの変更は、単一の不可分 64 ビットストアを使用して行われます。


注 –

.PLT101.PLT102、および .PLT103 の命令シーケンスの違いから、関連する宛先に合わせた最適化の方法を知ることができます。


LD_BIND_NOW 環境変数は、動的リンク動作を変更します。この環境変数の値がヌル文字以外の場合、実行時リンカーは、プログラムに制御を渡す前に R_SPARC_JMP_SLOT 再配置エントリを処理します。

32 ビット x86: プロシージャーのリンクテーブル

32 ビット x86 動的オブジェクトの場合、プロシージャーリンクテーブルは共有テキスト内に存在しますが、非公開の大域オフセットテーブル内のアドレスを使用します。実行時リンカーは、宛先の絶対アドレスを判定し、これらの絶対アドレスに従って大域オフセットテーブルのメモリーイメージに変更を加えます。このようにして実行時リンカーは、位置からの独立性とプログラムのテキストの共有性を低下させることなくエントリをリダイレクトします。実行可能ファイルと共有オブジェクトファイルには、別個のプロシージャーのリンクテーブルが存在します。

表 7–39 32 ビット x86: 絶対プロシージャーのリンクテーブルの例
.PLT0:
    pushl   got_plus_4
    jmp     *got_plus_8
    nop;    nop
    nop;    nop
.PLT1:
    jmp     *name1_in_GOT
    pushl   $offset
    jmp     .PLT0@PC
.PLT2:
    jmp     *name2_in_GOT
    pushl   $offset
    jmp     .PLT0@PC

表 7–40 32 ビット x86: 位置独立のプロシージャーリンクテーブルの例
.PLT0:
    pushl   4(%ebx)
    jmp     *8(%ebx)
    nop;    nop
    nop;    nop
.PLT1:
    jmp     *name1@GOT(%ebx)
    pushl   $offset
    jmp     .PLT0@PC
.PLT2:
    jmp     *name2@GOT(%ebx)
    pushl   $offset
    jmp     .PLT0@PC


注 –

前述の例が示すとおり、プロシージャーリンクテーブルの命令は、絶対コードと位置独立のコードで異なるオペランドアドレス指定モードを使用します。それでも、実行時リンカーへのインタフェースは同一です。


次の手順は、実行時リンカーとプログラムがプロシージャーのリンクテーブルおよび大域オフセットテーブルによってシンボル参照をどのように協同で解決するかを示しています。

  1. 実行時リンカーは、プログラムのメモリーイメージを最初に作成するとき、大域オフセットテーブルの 2 番目と 3 番目のエントリに特殊な値を設定します。これらの値については、次の手順で説明します。

  2. プロシージャーのリンクテーブルが位置独立の場合、大域オフセットテーブルのアドレスは、%ebx に存在しなければなりません。プロセスイメージにおける各共有オブジェクトファイルには自身のプロシージャーのリンクテーブルが存在しており、制御は同じオブジェクトファイル内からのみプロシージャーのリンクテーブルエントリに渡されます。したがって、呼び出し側関数は、プロシージャーのリンクテーブルエントリを呼び出す前に、大域オフセットテーブルベースレジスタをセットしなければなりません。

  3. たとえば、プログラムが name1 を呼び出すと、制御が .PLT1 に渡されます。

  4. 最初の命令は、name1 の大域オフセットテーブルエントリのアドレスにジャンプします。大域オフセットテーブルは最初は、後続の pushl 命令のアドレスを保持します (name1 の実アドレスは保持しない)。

  5. プログラムは再配置オフセット (offset) をスタックにプッシュします。再配置オフセットは、再配置テーブルへの 32 ビットの負ではないバイトオフセットです。指定された再配置エントリには R_386_JMP_SLOT が存在しており、オフセットは、前の jmp 命令で使用された大域オフセットテーブルエントリを指定します。再配置エントリにはシンボルテーブルインデックスも存在しており、実行時リンカーはこれを使って参照されたシンボル name1 を取得します。

  6. プログラムは、再配置オフセットをプッシュした後、.PLT0 (プロシージャーのリンクテーブルの先頭エントリ) にジャンプします。pushl 命令は、2 番目の大域オフセットテーブルエントリ (got_plus_4 または 4(%ebx)) の値をスタックにプッシュして、実行時リンカーに 1 ワードの識別情報を与えます。プログラムは次に、3 番目の大域オフセットテーブルエントリ (got_plus_8 または 8(%ebx)) のアドレスにジャンプして、実行時リンカーにジャンプします。

  7. 実行時リンカーはスタックを戻し、指定された再配置エントリを調べ、シンボルの値を取得し、name1 の実際のアドレスを大域オフセットテーブルエントリに格納し、そして宛先にジャンプします。

  8. その後のプロシージャーのリンクテーブルエントリに対する実行は、name1 に直接渡されます (実行時リンカーの再呼び出しは行われない)。.PLT1 における jmp 命令は、pushl 命令にジャンプする代わりに、name1 にジャンプします。

LD_BIND_NOW 環境変数は、動的リンク処理の動作を変更します。この環境変数の値がヌル文字以外の場合、実行時リンカーは、プログラムに制御を渡す前に R_386_JMP_SLOT 再配置エントリを処理します。

x64: プロシージャーのリンクテーブル

x64 動的オブジェクトの場合、プロシージャーリンクテーブルは共有テキスト内に存在しますが、非公開の大域オフセットテーブル内のアドレスを使用します。実行時リンカーは、宛先の絶対アドレスを判定し、これらの絶対アドレスに従って大域オフセットテーブルのメモリーイメージに変更を加えます。このようにして実行時リンカーは、位置からの独立性とプログラムのテキストの共有性を低下させることなくエントリをリダイレクトします。実行可能ファイルと共有オブジェクトファイルには、別個のプロシージャーのリンクテーブルが存在します。

表 7–41 x64: プロシージャーのリンクテーブルの例
.PLT0:
    pushq   GOT+8(%rip)                         # GOT[1]
    jmp     *GOT+16(%rip)                       # GOT[2]
    nop;    nop
    nop;    nop
.PLT1:
    jmp     *name1@GOTPCREL(%rip)               # 16 bytes from .PLT0
    pushq   $index1
    jmp     .PLT0
.PLT2:
    jmp     *name2@GOTPCREL(%rip)               # 16 bytes from .PLT1
    pushl   $index2
    jmp     .PLT0

次の手順は、実行時リンカーとプログラムがプロシージャーのリンクテーブルおよび大域オフセットテーブルによってシンボル参照をどのように協同で解決するかを示しています。

  1. 実行時リンカーは、プログラムのメモリーイメージを最初に作成するとき、大域オフセットテーブルの 2 番目と 3 番目のエントリに特殊な値を設定します。これらの値については、次の手順で説明します。

  2. プロセスイメージにおける各共有オブジェクトファイルには自身のプロシージャーのリンクテーブルが存在しており、制御は同じオブジェクトファイル内からのみプロシージャーのリンクテーブルエントリに渡されます。

  3. たとえば、プログラムが name1 を呼び出すと、制御が .PLT1 に渡されます。

  4. 最初の命令は、name1 の大域オフセットテーブルエントリのアドレスにジャンプします。大域オフセットテーブルは最初は、後続の pushq 命令のアドレスを保持します (name1 の実アドレスは保持しない)。

  5. プログラムは再配置インデックス (index1) をスタックにプッシュします。再配置オフセットは、再配置テーブルへの 32 ビットの負ではないインデックスです。再配置テーブルは DT_JUMPREL 動的セクションエントリによって識別されます。指定された再配置エントリには R_AMD64_JMP_SLOT が存在しており、オフセットは、前の jmp 命令で使用された大域オフセットテーブルエントリを指定します。再配置エントリにはシンボルテーブルインデックスも存在しており、実行時リンカーはこれを使って参照されたシンボル name1 を取得します。

  6. プログラムは、再配置インデックスをプッシュした後、.PLT0 (プロシージャーのリンクテーブルの先頭エントリ) にジャンプします。pushq 命令は、2 番目の大域オフセットテーブルエントリ (GOT+8) の値をスタックにプッシュして、実行時リンカーに 1 ワードの識別情報を与えます。プログラムは次に、3 番目の大域オフセットテーブルエントリ (GOT+16) のアドレスにジャンプして、実行時リンカーにジャンプします。

  7. 実行時リンカーはスタックを戻し、指定された再配置エントリを調べ、シンボルの値を取得し、name1 の実際のアドレスを大域オフセットテーブルエントリに格納し、そして宛先にジャンプします。

  8. その後のプロシージャーのリンクテーブルエントリに対する実行は、name1 に直接渡されます (実行時リンカーの再呼び出しは行われない)。.PLT1 における jmp 命令は、pushq 命令にジャンプする代わりに、name1 にジャンプします。

LD_BIND_NOW 環境変数は、動的リンク処理の動作を変更します。この環境変数の値がヌル文字以外の場合、実行時リンカーは、プログラムに制御を渡す前に R_AMD64_JMP_SLOT 再配置エントリを処理します。