このコードシーケンスはもっとも一般的であり、共有オブジェクトと動的実行可能ファイルのどちらでも使用できます。このコードシーケンスは、共有オブジェクト内および動的実行可能ファイル内の外部 TLS 変数も参照できます。
表 8–2 SPARC: 32 ビットおよび 64 ビットの General Dynamic スレッド固有変数のアクセスコード
未処理の再配置: 32 ビット |
シンボル |
|
---|---|---|
GOT[n] GOT[n + 1] |
R_SPARC_TLS_DTPMOD32 R_SPARC_TLS_DTPOFF32 |
x x |
未処理の再配置: 64 ビット |
シンボル |
|
---|---|---|
GOT[n] GOT[n + 1] |
R_SPARC_TLS_DTPMOD64 R_SPARC_TLS_DTPOFF64 |
x x |
sethi 命令は R_SPARC_TLS_GD_HI22 再配置を生成し、add 命令は R_SPARC_TLS_GD_LO10 再配置を生成します。これらの再配置は、変数 x への TLS_index 構造体を保持する領域を大域オフセットテーブル内に割り当てるように、リンカーに指示します。リンカーは、この新しい GOT エントリに GOT からの相対オフセットを代入することによって、この再配置を処理します。
読み込みオブジェクトインデックスと x の TLS ブロックインデックスは実行時まで不明なため、リンカーは、実行時リンカーによって処理されるように、GOT に対する R_SPARC_TLS_DTPMOD32 再配置と R_SPARC_TLS_DPTOFF32 再配置を設定します。
add 命令は、R_SPARC_TLS_GD_ADD 再配置を生成します。この再配置が使用されるのは、リンカーによって GD コードシーケンスがほかのシーケンスに変更される場合だけです。
call 命令は、R_SPARC_TLS_GD_CALL 再配置を生成します。この再配置は、__tls_get_addr () 関数の呼び出しを結合するようリンカーに指示し、call 命令を GD コードシーケンスに関連付けます。
add 命令は、call 命令の前に指定する必要があります。この命令を、呼び出しの遅延スロットに配置することはできません。これは、あとで発生するコード変換が既知の順序を必要とするためです。
R_SPARC_TLS_GD_ADD 再配置によってタグが付けられた add 命令の GOT ポインタとして使用されるレジスタは、add 命令内の最初のレジスタでなければなりません。このように指定することで、リンカーはコード変換時に GOT ポインタであるレジスタを識別できるようになります。