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