このコードシーケンスは、「スレッド固有領域のアクセスモデル」で説明されている GD モデルを実装します。
表 8–2 SPARC: General Dynamic スレッド固有変数のアクセスコード
sethi 命令は R_SPARC_TLS_GD_HI22 再配置を生成し、add 命令は R_SPARC_TLS_GD_LO10 再配置を生成します。これらの再配置は、変数 x の TLS_index 構造体を保持する領域を GOT 内に割り当てるように、リンカーに指示します。リンカーは、この新しい GOT エントリに GOT からの相対オフセットを代入することによって、この再配置を処理します。
読み込みオブジェクトインデックスと x の TLS ブロックインデックスは実行時まで不明です。したがって、リンカーは、実行時リンカーによって処理されるように、GOT に対する R_SPARC_TLS_DTPMOD32 再配置と R_SPARC_TLS_DPTOFF32 再配置を設定します。
2 番目の add 命令は、R_SPARC_TLS_GD_ADD 再配置を生成します。この再配置が使用されるのは、リンカーによって GD コードシーケンスがほかのシーケンスに変更される場合だけです。
call 命令は特別な構文である x@TLSPLT を使用します。この call 命令は TLS 変数を参照し、R_SPARC_TLS_GD_CALL 再配置を生成します。この再配置は、__tls_get_addr() 関数の呼び出しを結合するようリンカーに指示し、call 命令を GD コードシーケンスに関連付けます。
add 命令は、call 命令の前に指定する必要があります。add 命令を、呼び出しの遅延スロットに配置することはできません。これは、あとで発生するコード変換が既知の順序を必要とするためです。
R_SPARC_TLS_GD_ADD 再配置によってタグが付けられた add 命令の GOT ポインタとして使用されるレジスタは、add 命令内の最初のレジスタでなければなりません。このように指定することで、リンカーはコード変換時に GOT ポインタであるレジスタを識別できるようになります。