このコードシーケンスは、共有オブジェクトまたは動的実行可能ファイルで使用できます。このシーケンスは、参照として同じオブジェクト内に結合された TLS 変数を参照する場合に使用します。動的な tlsoffset はリンク編集時に結合が可能なため、___tls_get_addr() の呼び出しは、LD コードシーケンスを介して参照されるすべてのシンボルの関数呼び出しごとに 1 回だけですみます。
表 8–9 x86: Local Dynamic スレッド固有変数のアクセスコード
未処理の再配置 |
シンボル |
|
---|---|---|
GOT[n] GOT[n + 1] |
R_386_TLS_DTPMOD32 <なし> |
x |
最初の leal 命令は R_386_TLS_LDM 再配置を生成します。この再配置は、現在のオブジェクトの TLS_index 構造体を保持する領域を大域オフセットテーブル内に割り当てるよう、リンカーに指示します。リンカーは、この新しいリンクテーブルエントリに GOT からの相対オフセットを代入することによって、この再配置を処理します。
読み込みオブジェクトインデックスは実行時まで認識されないため、R_386_TLS_DTPMOD32 再配置が作成され、構造体の ti_tlsoffset フィールドにゼロが埋め込まれます。call 命令には、R_386_TLS_LDM_PLT 再配置によってタグが付けられます。
各ローカルシンボルの TLS オフセットはリンク編集時に認識されるため、リンカーはこれらの値を直接埋め込みます。
手続きが複数のローカルシンボルを参照する場合には、コンパイラは TLS ブロックの基底アドレスを取得するコードを 1 度だけ生成します。以後、各シンボルのアドレスの計算にはこの基底アドレスが使用され、個別にライブラリを呼び出すことはありません。